1/* 2 * Copyright (c) 2021-2022 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 { 20bool Parser::ParseOperands() 21{ 22 std::string_view p; 23 uint64_t number; 24 LOG(DEBUG, ASSEMBLER) << "operand search started (line " << line_stric_ << "): " << context_.tokens[0].whole_line; 25 switch(context_.WaitFor()) 26 { 27% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group| 28% insn = group.first 29% formats = group.map(&:format) 30% operands = insn.operands 31% properties = insn.properties 32% verification = insn.verification 33 case Token::Type::ID_OP_<%= insn.asm_token%>: { 34% if insn.return? && !insn.properties.include?('dynamic') 35% if insn.return_obj? 36 if (!curr_func_->return_type.IsObject()) { 37% elsif insn.return32? 38 if (!curr_func_->return_type.IsPrim32()) { 39% elsif insn.return64? 40 if (!curr_func_->return_type.IsPrim64()) { 41% elsif insn.return_void? 42 if (!curr_func_->return_type.IsVoid()) { 43% end 44 GetWarning("Unexpected return type. Look at the return type in the function definition: " + 45 curr_func_->return_type.GetName(), 46 Error::ErrorType::WAR_UNEXPECTED_RETURN_TYPE); 47 } 48% end 49% required_args = operands.size 50% required_args = 1 if insn.call? 51% required_args = 2 if insn.stripped_mnemonic == 'calli' 52% operands.each_with_index do |op, j| 53% 54% if (j != 0) 55% if j >= required_args 56 if (!context_.Mask()) { 57 ParseOperandComma(); 58 } 59% else 60 if (!context_.Mask()) { 61 ParseOperandComma(); 62 } else { 63 context_.err = GetError("Expected comma.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS); 64 } 65% end 66% end 67% 68 if (!context_.Mask()) { 69% if op.reg? 70 71 if (RegValidName()) { 72 p = context_.GiveToken(); 73 p.remove_prefix(1); 74 number = ToNumber(p); 75 size_t reg_width = curr_func_->ins.back().MaxRegEncodingWidth(); 76 if ((1ull << reg_width) <= number) { 77 context_.err = GetError("Register width mismatch.", Error::ErrorType::ERR_BAD_OPERAND); 78 } 79 } else if (context_.err.err == Error::ErrorType::ERR_NONE) { 80 context_.err = GetError("Invalid name of register.", Error::ErrorType::ERR_BAD_NAME_REG); 81 } 82 83 ParseOperandVreg(); 84% elsif op.imm? 85% if properties.include?("jump") 86 ParseOperandLabel(); 87% else 88% if properties.include?("float") 89 ParseOperandFloat(<%= op.size == 64 ? "true" : "false" %>); 90% else 91 ParseOperandInteger(); 92% end 93% end 94% elsif op.id? 95% if properties.include?("type_id") 96% if (verification.include?("type_id_array")) 97 ParseOperandType(Type::VerificationType::TYPE_ID_ARRAY); 98% elsif (verification.include?("type_id_object")) 99 ParseOperandType(Type::VerificationType::TYPE_ID_OBJECT); 100% elsif (verification.include?("type_id_any_object")) 101 ParseOperandType(Type::VerificationType::TYPE_ID_ANY_OBJECT); 102% end 103% elsif properties.include?("string_id") 104 ParseOperandString(); 105% elsif properties.include?("literalarray_id") 106 ParseOperandLiteralArray(); 107% elsif properties.include?("method_id") 108 ParseOperandCall(); 109% elsif properties.include?("field_id") 110 ParseOperandField(); 111% else 112 ParseOperandId(); 113% end 114% end 115% 116% if (j >= required_args) && (operands.size > 0) 117 } 118% elsif operands.size > 0 119 } else { 120 context_.err = GetError("Expected more arguments.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS); 121 } 122% end 123% end 124 ParseOperandNone(); 125 } break; 126%end 127 default: 128 context_.err = GetError("No such operation.", Error::ErrorType::ERR_BAD_NONEXISTING_OPERATION); 129 return false; 130 } 131 return context_.Mask(); 132} 133} 134