• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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// Autogenerated file -- DO NOT EDIT!
17
18static std::vector<uint8_t> &operator<<(std::vector<uint8_t> &out, Opcode op)
19{
20    if (static_cast<unsigned>(op) >= <%= Panda.instructions.select(&:prefix).map(&:opcode_idx).min %>) {
21        out.push_back(static_cast<uint8_t>(op));
22        out.push_back(static_cast<uint8_t>(static_cast<unsigned>(op) >> 8));
23    } else {
24        out.push_back(static_cast<uint8_t>(op));
25    }
26    return out;
27}
28
29% def get_min(width, is_signed)
30%   if width < 8
31%       if is_signed
32%           return '%d' % ((1 << (width - 1)) - (1 << width))
33%       else
34%           return '%d' % ((1 << (width - 1)))
35%       end
36%   else
37%       if is_signed
38%           return 'std::numeric_limits<int%d_t>::min()' % width
39%       else
40%           return '%s + 1' % get_max(width / 2, false)
41%       end
42%   end
43% end
44%
45% def get_max(width, is_signed)
46%   if width < 8
47%       if is_signed
48%           return '%d' % ((1 << (width - 1)) - 1)
49%       else
50%           return '%d' % ((1 << width) - 1)
51%       end
52%   else
53%       if is_signed
54%           return 'std::numeric_limits<int%d_t>::max()' % width
55%       else
56%           return 'std::numeric_limits<uint%d_t>::max()' % width
57%       end
58%   end
59% end
60%
61% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group|
62%   emitter_name = group.first.emitter_name
63%   formats = group.map(&:format)
64%
65%   if emitter_name == "Jmp"
66%       next
67%   end
68%
69%   i = group.first
70%
71%   if i.operands.empty?
72TEST(BytecodeEmitter, <%= emitter_name %>) {
73    TestNoneFormat(Opcode::<%= i.opcode.upcase %>, [](BytecodeEmitter* emitter){
74        emitter-><%= emitter_name %>();
75    });
76}
77
78%   elsif i.jcmp?
79%     group.each do |group_insn|
80%       pretty_format = group_insn.format.pretty.upcase
81%       opcode = group_insn.opcode.upcase
82TEST(BytecodeEmitter, <%= emitter_name %>Bwd_<%= pretty_format %>) {
83    JcmpBwd_<%= pretty_format %>(Opcode::<%= opcode %>, [](BytecodeEmitter* emitter, uint8_t reg, const Label &label){
84        emitter-><%= emitter_name %>(reg, label);
85    });
86}
87
88TEST(BytecodeEmitter, <%= emitter_name %>Fwd_<%= pretty_format %>) {
89    JcmpFwd_<%= pretty_format %>(Opcode::<%= opcode %>, [](BytecodeEmitter* emitter, uint8_t reg, const Label &label){
90        emitter-><%= emitter_name %>(reg, label);
91    });
92}
93
94%     end
95%   elsif i.jcmpz?
96%     group.each do |group_insn|
97%       pretty_format = group_insn.format.pretty.upcase
98%       opcode = group_insn.opcode.upcase
99TEST(BytecodeEmitter, <%= emitter_name %>_<%= pretty_format %>) {
100    Jcmpz_<%= pretty_format %>(Opcode::<%= opcode %>, [](BytecodeEmitter* emitter, const Label &label){
101        emitter-><%= emitter_name %>(label);
102    });
103}
104%     end
105%   else
106%       group.each do |i|
107TEST(BytecodeEmitter, <%= emitter_name %>_<%= i.format.pretty.upcase %>) {
108%           num_ops = i.operands.length()
109%           ops = format_ops(i.format)
110%           ['min', 'max'].repeated_permutation(num_ops).each do |p|
111%               args = []
112%               vals = []
113%               p.each_with_index do |v, index|
114%                   op = ops[index]
115%                   is_signed = op.name.start_with?('imm')
116%                   arg = v == 'min' ? get_min(op.width, is_signed) : get_max(op.width, is_signed)
117%                   args.push(arg)
118%                   if op.width <= 8
119%                       vals.push(arg)
120%                   elsif op.width == 16
121%                       vals.push('Split16(%s)' % arg)
122%                   elsif op.width == 32
123%                       vals.push('Split32(%s)' % arg)
124%                   else
125%                       vals.push('Split64(%s)' % arg)
126%                   end
127%               end
128%
129%               index = 0
130%               packed_vals = []
131%               while index < num_ops do
132%                   if ops[index].width == 4
133%                       packed_vals.push('(((static_cast<uint8_t>(%s) & 0xF) << 4) | (static_cast<uint8_t>(%s) & 0xF))' % [vals[index + 1], vals[index]])
134%                       index += 2
135%                   else
136%                       packed_vals.push(vals[index])
137%                       index += 1
138%                   end
139%               end
140%
141    {
142        BytecodeEmitter emitter;
143        emitter.<%= emitter_name %>(<%= args.join(', ') %>);
144        std::vector<uint8_t> out;
145        ASSERT_EQ(BytecodeEmitter::ErrorCode::SUCCESS, emitter.Build(&out));
146        std::vector<uint8_t> expected;
147        expected << Opcode::<%= i.opcode.upcase %> << <%= packed_vals.join(' << ') %>;
148        ASSERT_EQ(expected, out);
149    }
150
151%           end
152}
153
154%       end
155%   end
156% end
157