| 1296 | enum class BinOp { ADD, SUB, ANDV, ORV, XORV }; |
| 1297 | |
| 1298 | static void enc_bin(BytecodeBuilder& out, const IRInsn& i, const VMConfig& vm, const Codec* self) { |
| 1299 | out.u8(vm.opcode_for(self->family())); |
| 1300 | const auto& dst = get_op<VirReg>(i, 0); |
| 1301 | enc_slot(out, vm, dst); |
| 1302 | if (std::holds_alternative<VirReg>(i.ops[1])) { |
| 1303 | out.u8(0); |
| 1304 | enc_slot(out, vm, get_op<VirReg>(i, 1)); |
| 1305 | } |
| 1306 | else if (std::holds_alternative<Imm>(i.ops[1])) { |
| 1307 | out.u8(1); |
| 1308 | const auto& im = get_op<Imm>(i, 1); |
| 1309 | enc_imm_n(out, im.value, 8); |
| 1310 | } |
| 1311 | else { |
| 1312 | // mem on RHS: load+op pattern. |
| 1313 | out.u8(2); |
| 1314 | enc_mem(out, vm, get_op<Mem>(i, 1)); |
| 1315 | } |
| 1316 | } |
| 1317 | |
| 1318 | static void emit_bin_handler(X64Emitter& e, const VMConfig& vm, BinOp op, FlagsOp fkind) { |
| 1319 | const auto& r = vm.dispatcher_regs(); |