1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "assembly-parser.h" 17#include "utils/number-utils.h" 18 19namespace panda::pandasm { 20 21bool Parser::ParseOperands() 22{ 23 std::string_view p; 24 uint64_t number; 25 LOG(DEBUG, ASSEMBLER) << "operand search started (line " << line_stric_ << "): " << context_.tokens[0].whole_line; 26 switch(context_.WaitFor()) 27 { 28% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group| 29% insn = group.first 30% formats = group.map(&:format) 31% operands = insn.operands 32% properties = insn.properties 33% verification = insn.verification 34 case Token::Type::ID_OP_<%= insn.asm_token%>: { 35% if insn.return? && !insn.properties.include?('dynamic') 36% if insn.return_obj? 37 if (!curr_func_->return_type.IsObject()) { 38% elsif insn.return32? 39 if (!curr_func_->return_type.IsPrim32()) { 40% elsif insn.return64? 41 if (!curr_func_->return_type.IsPrim64()) { 42% elsif insn.return_void? 43 if (!curr_func_->return_type.IsVoid()) { 44% end 45 GetWarning("Unexpected return type. Correct the return type in the function definition: " + 46 curr_func_->return_type.GetName(), 47 Error::ErrorType::WAR_UNEXPECTED_RETURN_TYPE); 48 } 49% end 50% required_args = operands.size 51% required_args = 1 if insn.call? 52% required_args = 2 if insn.stripped_mnemonic == 'calli' 53% operands.each_with_index do |op, j| 54% 55% if (j != 0) 56% if j >= required_args 57 if (!context_.Mask()) { 58 ParseOperandComma(); 59 } 60% else 61 if (!context_.Mask()) { 62 ParseOperandComma(); 63 } else { 64 context_.err = GetError("Expected comma.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS); 65 } 66% end 67% end 68% 69 if (!context_.Mask()) { 70% if op.reg? 71 72 if (RegValidName()) { 73 p = context_.GiveToken(); 74 p.remove_prefix(1); 75 number = ToNumber(p); 76 size_t reg_width = curr_func_->ins.back().MaxRegEncodingWidth(); 77 if ((1ull << reg_width) <= number) { 78 context_.err = GetError("Register width mismatch.", Error::ErrorType::ERR_BAD_OPERAND); 79 } 80 } else if (context_.err.err == Error::ErrorType::ERR_NONE) { 81 context_.err = GetError("Invalid name of register.", Error::ErrorType::ERR_BAD_NAME_REG); 82 } 83 84 ParseOperandVreg(); 85% elsif op.imm? 86% if properties.include?("jump") 87 ParseOperandLabel(); 88% else 89% if properties.include?("float") 90 ParseOperandFloat(<%= op.size == 64 ? "true" : "false" %>); 91% else 92 ParseOperandInteger(); 93% end 94% end 95% elsif op.id? 96% if properties.include?("type_id") 97% if (verification.include?("type_id_array")) 98 ParseOperandType(Type::VerificationType::TYPE_ID_ARRAY); 99% elsif (verification.include?("type_id_object")) 100 ParseOperandType(Type::VerificationType::TYPE_ID_OBJECT); 101% elsif (verification.include?("type_id_any_object")) 102 ParseOperandType(Type::VerificationType::TYPE_ID_ANY_OBJECT); 103% end 104% elsif properties.include?("string_id") 105 ParseOperandString(); 106% elsif properties.include?("method_id") 107 ParseOperandCall(); 108% elsif properties.include?("field_id") 109 ParseOperandField(); 110% else 111 ParseOperandId(); 112% end 113% end 114% 115% if (j >= required_args) && (operands.size > 0) 116 } 117% elsif operands.size > 0 118 } else { 119 context_.err = GetError("Expected more arguments.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS); 120 } 121% end 122% end 123 ParseOperandNone(); 124 } break; 125%end 126 default: 127 context_.err = GetError("No such operation.", Error::ErrorType::ERR_BAD_NONEXISTING_OPERATION); 128 return false; 129 } 130 return context_.Mask(); 131} 132 133} // namespace panda::pandasm 134