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