• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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