authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-07 12:57:06+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-11 20:05:49+01:00
logbc43cee7756d48064be0dd87f92e24c577788eec
treec188164b61113e528e991cb73ede113e2632d6f7
parentea3b3e94aba405d4364fdb06231208467ac71f87

Get more things passing


7 files changed, 474 insertions(+), 416 deletions(-)

src/arch/x86_64/CodeGen.zig+63-98
...@@ -852,10 +852,10 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {...@@ -852,10 +852,10 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {
852 branch.inst_table.putAssumeCapacity(inst, .dead);852 branch.inst_table.putAssumeCapacity(inst, .dead);
853 switch (prev_value) {853 switch (prev_value) {
854 .register => |reg| {854 .register => |reg| {
855 self.register_manager.freeReg(reg.to64());855 self.register_manager.freeReg(reg);
856 },856 },
857 .register_overflow => |ro| {857 .register_overflow => |ro| {
858 self.register_manager.freeReg(ro.reg.to64());858 self.register_manager.freeReg(ro.reg);
859 self.eflags_inst = null;859 self.eflags_inst = null;
860 },860 },
861 .eflags => {861 .eflags => {
...@@ -1253,7 +1253,13 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1253,7 +1253,13 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1253 };1253 };
1254 defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock);1254 defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock);
12551255
1256 const mask = ~@as(u64, 0);1256 const mask = switch (operand_ty.abiSize(self.target.*)) {
1257 1 => ~@as(u8, 0),
1258 2 => ~@as(u16, 0),
1259 4 => ~@as(u32, 0),
1260 8 => ~@as(u64, 0),
1261 else => unreachable,
1262 };
1257 try self.genBinOpMir(.xor, operand_ty, dst_mcv, .{ .immediate = mask });1263 try self.genBinOpMir(.xor, operand_ty, dst_mcv, .{ .immediate = mask });
12581264
1259 break :result dst_mcv;1265 break :result dst_mcv;
...@@ -2777,15 +2783,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -2777,15 +2783,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
2777 1, 2, 4 => {2783 1, 2, 4 => {
2778 // TODO this is wasteful!2784 // TODO this is wasteful!
2779 // introduce new MIR tag specifically for mov [reg + 0], imm2785 // introduce new MIR tag specifically for mov [reg + 0], imm
2780 const operand = switch (abi_size) {
2781 1 => @truncate(u8, imm),
2782 2 => @truncate(u16, imm),
2783 4 => @truncate(u32, imm),
2784 else => unreachable,
2785 };
2786 const payload = try self.addExtra(Mir.ImmPair{2786 const payload = try self.addExtra(Mir.ImmPair{
2787 .dest_off = 0,2787 .dest_off = 0,
2788 .operand = operand,2788 .operand = @intCast(u32, imm),
2789 });2789 });
2790 _ = try self.addInst(.{2790 _ = try self.addInst(.{
2791 .tag = .mov_mem_imm,2791 .tag = .mov_mem_imm,
...@@ -2896,17 +2896,10 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -2896,17 +2896,10 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
2896 return self.fail("TODO saving imm to memory for abi_size {}", .{abi_size});2896 return self.fail("TODO saving imm to memory for abi_size {}", .{abi_size});
2897 }2897 }
28982898
2899 const operand = switch (abi_size) {
2900 1 => @truncate(u8, imm),
2901 2 => @truncate(u16, imm),
2902 4 => @truncate(u32, imm),
2903 8 => @truncate(u32, imm),
2904 else => unreachable,
2905 };
2906 const payload = try self.addExtra(Mir.ImmPair{2899 const payload = try self.addExtra(Mir.ImmPair{
2907 .dest_off = 0,2900 .dest_off = 0,
2908 // TODO check if this logic is correct2901 // TODO check if this logic is correct
2909 .operand = operand,2902 .operand = @intCast(u32, imm),
2910 });2903 });
2911 const flags: u2 = switch (abi_size) {2904 const flags: u2 = switch (abi_size) {
2912 1 => 0b00,2905 1 => 0b00,
...@@ -3102,8 +3095,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -3102,8 +3095,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
3102 const shift = @intCast(u8, struct_field_offset * @sizeOf(usize));3095 const shift = @intCast(u8, struct_field_offset * @sizeOf(usize));
3103 try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv.register, .{ .immediate = shift });3096 try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv.register, .{ .immediate = shift });
31043097
3105 // Mask with reg.size() - struct_field_size3098 // Mask with reg.bitSize() - struct_field_size
3106 const max_reg_bit_width = Register.rax.size();3099 const max_reg_bit_width = Register.rax.bitSize();
3107 const mask_shift = @intCast(u6, (max_reg_bit_width - struct_field_ty.bitSize(self.target.*)));3100 const mask_shift = @intCast(u6, (max_reg_bit_width - struct_field_ty.bitSize(self.target.*)));
3108 const mask = (~@as(u64, 0)) >> mask_shift;3101 const mask = (~@as(u64, 0)) >> mask_shift;
31093102
...@@ -3631,13 +3624,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu...@@ -3631,13 +3624,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu
3631 _ = try self.addInst(.{3624 _ = try self.addInst(.{
3632 .tag = mir_tag,3625 .tag = mir_tag,
3633 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(dst_reg, abi_size) }),3626 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(dst_reg, abi_size) }),
3634 .data = .{ .imm = switch (abi_size) {3627 .data = .{ .imm = @intCast(u32, imm) },
3635 1 => @truncate(u8, imm),
3636 2 => @truncate(u16, imm),
3637 4 => @truncate(u32, imm),
3638 8 => @truncate(u32, imm),
3639 else => unreachable,
3640 } },
3641 });3628 });
3642 },3629 },
3643 .memory,3630 .memory,
...@@ -3708,16 +3695,9 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu...@@ -3708,16 +3695,9 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu
3708 8 => 0b11,3695 8 => 0b11,
3709 else => unreachable,3696 else => unreachable,
3710 };3697 };
3711 const operand = switch (abi_size) {
3712 1 => @truncate(u8, imm),
3713 2 => @truncate(u16, imm),
3714 4 => @truncate(u32, imm),
3715 8 => @truncate(u32, imm),
3716 else => unreachable,
3717 };
3718 const payload = try self.addExtra(Mir.ImmPair{3698 const payload = try self.addExtra(Mir.ImmPair{
3719 .dest_off = -off,3699 .dest_off = -off,
3720 .operand = operand,3700 .operand = @intCast(u32, imm),
3721 });3701 });
3722 _ = try self.addInst(.{3702 _ = try self.addInst(.{
3723 .tag = tag,3703 .tag = tag,
...@@ -3791,7 +3771,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -3791,7 +3771,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
3791 .reg2 = dst_reg.to32(),3771 .reg2 = dst_reg.to32(),
3792 .flags = 0b10,3772 .flags = 0b10,
3793 }),3773 }),
3794 .data = .{ .imm = @truncate(u32, imm) },3774 .data = .{ .imm = @intCast(u32, imm) },
3795 });3775 });
3796 } else {3776 } else {
3797 // TODO verify we don't spill and assign to the same register as dst_mcv3777 // TODO verify we don't spill and assign to the same register as dst_mcv
...@@ -4899,13 +4879,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u...@@ -4899,13 +4879,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u
4899 _ = try self.addInst(.{4879 _ = try self.addInst(.{
4900 .tag = .xor,4880 .tag = .xor,
4901 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(cond_reg, abi_size) }),4881 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(cond_reg, abi_size) }),
4902 .data = .{ .imm = switch (abi_size) {4882 .data = .{ .imm = @intCast(u32, imm) },
4903 1 => @truncate(u8, imm),
4904 2 => @truncate(u16, imm),
4905 4 => @truncate(u32, imm),
4906 8 => @truncate(u32, imm),
4907 else => unreachable,
4908 } },
4909 });4883 });
4910 },4884 },
4911 .register => |reg| {4885 .register => |reg| {
...@@ -5416,12 +5390,6 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE...@@ -5416,12 +5390,6 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
5416 // We have a positive stack offset value but we want a twos complement negative5390 // We have a positive stack offset value but we want a twos complement negative
5417 // offset from rbp, which is at the top of the stack frame.5391 // offset from rbp, which is at the top of the stack frame.
5418 // mov [rbp+offset], immediate5392 // mov [rbp+offset], immediate
5419 const operand = switch (abi_size) {
5420 1 => @truncate(u8, imm),
5421 2 => @truncate(u16, imm),
5422 4 => @truncate(u32, imm),
5423 else => unreachable,
5424 };
5425 const flags: u2 = switch (abi_size) {5393 const flags: u2 = switch (abi_size) {
5426 1 => 0b00,5394 1 => 0b00,
5427 2 => 0b01,5395 2 => 0b01,
...@@ -5430,7 +5398,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE...@@ -5430,7 +5398,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
5430 };5398 };
5431 const payload = try self.addExtra(Mir.ImmPair{5399 const payload = try self.addExtra(Mir.ImmPair{
5432 .dest_off = -stack_offset,5400 .dest_off = -stack_offset,
5433 .operand = operand,5401 .operand = @intCast(u32, imm),
5434 });5402 });
5435 _ = try self.addInst(.{5403 _ = try self.addInst(.{
5436 .tag = .mov_mem_imm,5404 .tag = .mov_mem_imm,
...@@ -5575,7 +5543,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -5575,7 +5543,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
5575 assert(ty.isError());5543 assert(ty.isError());
5576 const payload = try self.addExtra(Mir.ImmPair{5544 const payload = try self.addExtra(Mir.ImmPair{
5577 .dest_off = -stack_offset,5545 .dest_off = -stack_offset,
5578 .operand = @truncate(u8, x_big),5546 .operand = @intCast(u32, x_big),
5579 });5547 });
5580 _ = try self.addInst(.{5548 _ = try self.addInst(.{
5581 .tag = .mov_mem_imm,5549 .tag = .mov_mem_imm,
...@@ -5587,15 +5555,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -5587,15 +5555,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
5587 });5555 });
5588 },5556 },
5589 1, 2, 4 => {5557 1, 2, 4 => {
5590 const operand = switch (abi_size) {
5591 1 => @truncate(u8, x_big),
5592 2 => @truncate(u16, x_big),
5593 4 => @truncate(u32, x_big),
5594 else => unreachable,
5595 };
5596 const payload = try self.addExtra(Mir.ImmPair{5558 const payload = try self.addExtra(Mir.ImmPair{
5597 .dest_off = -stack_offset,5559 .dest_off = -stack_offset,
5598 .operand = operand,5560 .operand = @intCast(u32, x_big),
5599 });5561 });
5600 _ = try self.addInst(.{5562 _ = try self.addInst(.{
5601 .tag = .mov_mem_imm,5563 .tag = .mov_mem_imm,
...@@ -5724,7 +5686,7 @@ fn genInlineMemcpyRegisterRegister(...@@ -5724,7 +5686,7 @@ fn genInlineMemcpyRegisterRegister(
5724 src_reg: Register,5686 src_reg: Register,
5725 offset: i32,5687 offset: i32,
5726) InnerError!void {5688) InnerError!void {
5727 assert(dst_reg.size() == 64);5689 assert(dst_reg.bitSize() == 64);
57285690
5729 const dst_reg_lock = self.register_manager.lockReg(dst_reg);5691 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
5730 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);5692 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);
...@@ -5823,7 +5785,7 @@ fn genInlineMemcpy(...@@ -5823,7 +5785,7 @@ fn genInlineMemcpy(
5823 _ = try self.addInst(.{5785 _ = try self.addInst(.{
5824 .tag = .mov,5786 .tag = .mov,
5825 .ops = Mir.Inst.Ops.encode(.{5787 .ops = Mir.Inst.Ops.encode(.{
5826 .reg1 = registerAlias(dst_addr_reg, @divExact(reg.size(), 8)),5788 .reg1 = registerAlias(dst_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
5827 .reg2 = reg,5789 .reg2 = reg,
5828 }),5790 }),
5829 .data = undefined,5791 .data = undefined,
...@@ -5852,7 +5814,7 @@ fn genInlineMemcpy(...@@ -5852,7 +5814,7 @@ fn genInlineMemcpy(
5852 _ = try self.addInst(.{5814 _ = try self.addInst(.{
5853 .tag = .mov,5815 .tag = .mov,
5854 .ops = Mir.Inst.Ops.encode(.{5816 .ops = Mir.Inst.Ops.encode(.{
5855 .reg1 = registerAlias(src_addr_reg, @divExact(reg.size(), 8)),5817 .reg1 = registerAlias(src_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
5856 .reg2 = reg,5818 .reg2 = reg,
5857 }),5819 }),
5858 .data = undefined,5820 .data = undefined,
...@@ -5976,7 +5938,7 @@ fn genInlineMemset(...@@ -5976,7 +5938,7 @@ fn genInlineMemset(
5976 _ = try self.addInst(.{5938 _ = try self.addInst(.{
5977 .tag = .mov,5939 .tag = .mov,
5978 .ops = Mir.Inst.Ops.encode(.{5940 .ops = Mir.Inst.Ops.encode(.{
5979 .reg1 = registerAlias(addr_reg, @divExact(reg.size(), 8)),5941 .reg1 = registerAlias(addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
5980 .reg2 = reg,5942 .reg2 = reg,
5981 }),5943 }),
5982 .data = undefined,5944 .data = undefined,
...@@ -5994,8 +5956,11 @@ fn genInlineMemset(...@@ -5994,8 +5956,11 @@ fn genInlineMemset(
5994 // cmp index_reg, -15956 // cmp index_reg, -1
5995 const loop_start = try self.addInst(.{5957 const loop_start = try self.addInst(.{
5996 .tag = .cmp,5958 .tag = .cmp,
5997 .ops = Mir.Inst.Ops.encode(.{ .reg1 = index_reg }),5959 .ops = Mir.Inst.Ops.encode(.{
5998 .data = .{ .imm = @bitCast(u8, @as(i8, -1)) },5960 .reg1 = index_reg,
5961 .flags = 0b11,
5962 }),
5963 .data = .{ .imm_s = -1 },
5999 });5964 });
60005965
6001 // je end5966 // je end
...@@ -6016,8 +5981,14 @@ fn genInlineMemset(...@@ -6016,8 +5981,14 @@ fn genInlineMemset(
6016 // mov byte ptr [rbp + index_reg + stack_offset], imm5981 // mov byte ptr [rbp + index_reg + stack_offset], imm
6017 _ = try self.addInst(.{5982 _ = try self.addInst(.{
6018 .tag = .mov_mem_index_imm,5983 .tag = .mov_mem_index_imm,
6019 .ops = Mir.Inst.Ops.encode(.{ .reg1 = addr_reg }),5984 .ops = Mir.Inst.Ops.encode(.{
6020 .data = .{ .payload = try self.addExtra(Mir.IndexRegisterDispImm.encode(index_reg, 0, @truncate(u32, x))) },5985 .reg1 = addr_reg,
5986 }),
5987 .data = .{ .payload = try self.addExtra(Mir.IndexRegisterDispImm.encode(
5988 index_reg,
5989 0,
5990 @intCast(u32, x),
5991 )) },
6021 });5992 });
6022 },5993 },
6023 else => return self.fail("TODO inline memset for value of type {}", .{value}),5994 else => return self.fail("TODO inline memset for value of type {}", .{value}),
...@@ -6064,7 +6035,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -6064,7 +6035,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
6064 if (!self.wantSafety())6035 if (!self.wantSafety())
6065 return; // The already existing value will do just fine.6036 return; // The already existing value will do just fine.
6066 // Write the debug undefined value.6037 // Write the debug undefined value.
6067 switch (registerAlias(reg, abi_size).size()) {6038 switch (registerAlias(reg, abi_size).bitSize()) {
6068 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }),6039 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }),
6069 16 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaa }),6040 16 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaa }),
6070 32 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa }),6041 32 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa }),
...@@ -6100,13 +6071,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -6100,13 +6071,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
6100 _ = try self.addInst(.{6071 _ = try self.addInst(.{
6101 .tag = .mov,6072 .tag = .mov,
6102 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(reg, abi_size) }),6073 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(reg, abi_size) }),
6103 .data = .{ .imm = switch (abi_size) {6074 .data = .{ .imm = @intCast(u32, x) },
6104 1 => @truncate(u8, x),
6105 2 => @truncate(u16, x),
6106 4 => @truncate(u32, x),
6107 8 => @truncate(u32, x),
6108 else => unreachable,
6109 } },
6110 });6075 });
6111 return;6076 return;
6112 }6077 }
...@@ -6273,13 +6238,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -6273,13 +6238,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
6273 .reg1 = registerAlias(reg, abi_size),6238 .reg1 = registerAlias(reg, abi_size),
6274 .flags = 0b01,6239 .flags = 0b01,
6275 }),6240 }),
6276 .data = .{ .imm = switch (abi_size) {6241 .data = .{ .disp = @intCast(i32, x) },
6277 1 => @truncate(u8, x),
6278 2 => @truncate(u16, x),
6279 4 => @truncate(u32, x),
6280 8 => @truncate(u32, x),
6281 else => unreachable,
6282 } },
6283 });6242 });
6284 } else {6243 } else {
6285 // If this is RAX, we can use a direct load.6244 // If this is RAX, we can use a direct load.
...@@ -6949,7 +6908,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -6949,7 +6908,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6949 if (ret_ty_size == 0) {6908 if (ret_ty_size == 0) {
6950 assert(ret_ty.isError());6909 assert(ret_ty.isError());
6951 result.return_value = .{ .immediate = 0 };6910 result.return_value = .{ .immediate = 0 };
6952 } else if (ret_ty_size <= 8) {6911 } else if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {
6953 const aliased_reg = registerAlias(abi.getCAbiIntReturnRegs(self.target.*)[0], ret_ty_size);6912 const aliased_reg = registerAlias(abi.getCAbiIntReturnRegs(self.target.*)[0], ret_ty_size);
6954 result.return_value = .{ .register = aliased_reg };6913 result.return_value = .{ .register = aliased_reg };
6955 } else {6914 } else {
...@@ -7024,28 +6983,34 @@ fn parseRegName(name: []const u8) ?Register {...@@ -7024,28 +6983,34 @@ fn parseRegName(name: []const u8) ?Register {
70246983
7025/// Returns register wide enough to hold at least `size_bytes`.6984/// Returns register wide enough to hold at least `size_bytes`.
7026fn registerAlias(reg: Register, size_bytes: u32) Register {6985fn registerAlias(reg: Register, size_bytes: u32) Register {
7027 if (size_bytes == 0) {6986 return switch (reg.class()) {
7028 unreachable; // should be comptime-known6987 .general_purpose => if (size_bytes == 0)
7029 } else if (size_bytes <= 1) {6988 unreachable // should be comptime-known
7030 return reg.to8();6989 else if (size_bytes <= 1)
7031 } else if (size_bytes <= 2) {6990 reg.to8()
7032 return reg.to16();6991 else if (size_bytes <= 2)
7033 } else if (size_bytes <= 4) {6992 reg.to16()
7034 return reg.to32();6993 else if (size_bytes <= 4)
7035 } else if (size_bytes <= 8) {6994 reg.to32()
7036 return reg.to64();6995 else if (size_bytes <= 8)
7037 } else if (size_bytes <= 16) {6996 reg.to64()
7038 return reg.to128();6997 else
7039 } else if (size_bytes <= 32) {6998 unreachable,
7040 return reg.to256();6999 .floating_point => if (size_bytes <= 16)
7041 } else unreachable;7000 reg.to128()
7001 else if (size_bytes <= 32)
7002 reg.to256()
7003 else
7004 unreachable,
7005 .segment => unreachable,
7006 };
7042}7007}
70437008
7044/// Truncates the value in the register in place.7009/// Truncates the value in the register in place.
7045/// Clobbers any remaining bits.7010/// Clobbers any remaining bits.
7046fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {7011fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
7047 const int_info = ty.intInfo(self.target.*);7012 const int_info = ty.intInfo(self.target.*);
7048 const max_reg_bit_width = Register.rax.size();7013 const max_reg_bit_width = Register.rax.bitSize();
7049 switch (int_info.signedness) {7014 switch (int_info.signedness) {
7050 .signed => {7015 .signed => {
7051 const shift = @intCast(u6, max_reg_bit_width - int_info.bits);7016 const shift = @intCast(u6, max_reg_bit_width - int_info.bits);
src/arch/x86_64/Emit.zig+39-35
...@@ -21,6 +21,7 @@ const CodeGen = @import("CodeGen.zig");...@@ -21,6 +21,7 @@ const CodeGen = @import("CodeGen.zig");
21const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;21const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
22const Encoder = bits.Encoder;22const Encoder = bits.Encoder;
23const ErrorMsg = Module.ErrorMsg;23const ErrorMsg = Module.ErrorMsg;
24const Immediate = bits.Immediate;
24const Instruction = encoder.Instruction;25const Instruction = encoder.Instruction;
25const MCValue = @import("CodeGen.zig").MCValue;26const MCValue = @import("CodeGen.zig").MCValue;
26const Memory = bits.Memory;27const Memory = bits.Memory;
...@@ -283,7 +284,7 @@ fn mirPushPop(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index)...@@ -283,7 +284,7 @@ fn mirPushPop(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index)
283 0b10 => {284 0b10 => {
284 const imm = emit.mir.instructions.items(.data)[inst].imm;285 const imm = emit.mir.instructions.items(.data)[inst].imm;
285 return emit.encode(.push, .{286 return emit.encode(.push, .{
286 .op1 = .{ .imm = imm },287 .op1 = .{ .imm = Immediate.u(imm) },
287 });288 });
288 },289 },
289 0b11 => unreachable,290 0b11 => unreachable,
...@@ -327,9 +328,7 @@ fn mirJmpCall(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index)...@@ -327,9 +328,7 @@ fn mirJmpCall(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index)
327 const target = emit.mir.instructions.items(.data)[inst].inst;328 const target = emit.mir.instructions.items(.data)[inst].inst;
328 const source = emit.code.items.len;329 const source = emit.code.items.len;
329 try emit.encode(mnemonic, .{330 try emit.encode(mnemonic, .{
330 .op1 = .{331 .op1 = .{ .imm = Immediate.s(0) },
331 .imm = 0,
332 },
333 });332 });
334 try emit.relocs.append(emit.bin_file.allocator, .{333 try emit.relocs.append(emit.bin_file.allocator, .{
335 .source = source,334 .source = source,
...@@ -400,7 +399,7 @@ fn mirCondJmp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -400,7 +399,7 @@ fn mirCondJmp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
400 };399 };
401 const source = emit.code.items.len;400 const source = emit.code.items.len;
402 try emit.encode(mnemonic, .{401 try emit.encode(mnemonic, .{
403 .op1 = .{ .imm = 0 },402 .op1 = .{ .imm = Immediate.s(0) },
404 });403 });
405 try emit.relocs.append(emit.bin_file.allocator, .{404 try emit.relocs.append(emit.bin_file.allocator, .{
406 .source = source,405 .source = source,
...@@ -521,7 +520,7 @@ fn mirTest(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -521,7 +520,7 @@ fn mirTest(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
521 const imm = emit.mir.instructions.items(.data)[inst].imm;520 const imm = emit.mir.instructions.items(.data)[inst].imm;
522 return emit.encode(.@"test", .{521 return emit.encode(.@"test", .{
523 .op1 = .{ .reg = ops.reg1 },522 .op1 = .{ .reg = ops.reg1 },
524 .op2 = .{ .imm = imm },523 .op2 = .{ .imm = Immediate.u(imm) },
525 });524 });
526 }525 }
527 return emit.encode(.@"test", .{526 return emit.encode(.@"test", .{
...@@ -543,7 +542,7 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -543,7 +542,7 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
543 0b10 => {542 0b10 => {
544 const imm = emit.mir.instructions.items(.data)[inst].imm;543 const imm = emit.mir.instructions.items(.data)[inst].imm;
545 return emit.encode(.ret, .{544 return emit.encode(.ret, .{
546 .op1 = .{ .imm = imm },545 .op1 = .{ .imm = Immediate.u(imm) },
547 });546 });
548 },547 },
549 0b11 => {548 0b11 => {
...@@ -560,7 +559,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I...@@ -560,7 +559,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
560 const imm = emit.mir.instructions.items(.data)[inst].imm;559 const imm = emit.mir.instructions.items(.data)[inst].imm;
561 return emit.encode(mnemonic, .{560 return emit.encode(mnemonic, .{
562 .op1 = .{ .reg = ops.reg1 },561 .op1 = .{ .reg = ops.reg1 },
563 .op2 = .{ .imm = imm },562 .op2 = .{ .imm = Immediate.u(imm) },
564 });563 });
565 }564 }
566 return emit.encode(mnemonic, .{565 return emit.encode(mnemonic, .{
...@@ -573,7 +572,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I...@@ -573,7 +572,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
573 const base: ?Register = if (ops.reg2 != .none) ops.reg2 else null;572 const base: ?Register = if (ops.reg2 != .none) ops.reg2 else null;
574 return emit.encode(mnemonic, .{573 return emit.encode(mnemonic, .{
575 .op1 = .{ .reg = ops.reg1 },574 .op1 = .{ .reg = ops.reg1 },
576 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{575 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
577 .base = base,576 .base = base,
578 .disp = disp,577 .disp = disp,
579 }) },578 }) },
...@@ -585,7 +584,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I...@@ -585,7 +584,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
585 }584 }
586 const disp = emit.mir.instructions.items(.data)[inst].disp;585 const disp = emit.mir.instructions.items(.data)[inst].disp;
587 return emit.encode(mnemonic, .{586 return emit.encode(mnemonic, .{
588 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg2.size()), .{587 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg2.bitSize()), .{
589 .base = ops.reg1,588 .base = ops.reg1,
590 .disp = disp,589 .disp = disp,
591 }) },590 }) },
...@@ -593,7 +592,11 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I...@@ -593,7 +592,11 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
593 });592 });
594 },593 },
595 0b11 => {594 0b11 => {
596 return emit.fail("TODO unused variant: mov reg1, reg2, 0b11", .{});595 const imm_s = emit.mir.instructions.items(.data)[inst].imm_s;
596 return emit.encode(mnemonic, .{
597 .op1 = .{ .reg = ops.reg1 },
598 .op2 = .{ .imm = Immediate.s(imm_s) },
599 });
597 },600 },
598 }601 }
599}602}
...@@ -614,7 +617,7 @@ fn mirArithMemImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.In...@@ -614,7 +617,7 @@ fn mirArithMemImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.In
614 .disp = imm_pair.dest_off,617 .disp = imm_pair.dest_off,
615 .base = ops.reg1,618 .base = ops.reg1,
616 }) },619 }) },
617 .op2 = .{ .imm = imm_pair.operand },620 .op2 = .{ .imm = Immediate.u(imm_pair.operand) },
618 });621 });
619}622}
620623
...@@ -629,7 +632,7 @@ fn mirArithScaleSrc(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst....@@ -629,7 +632,7 @@ fn mirArithScaleSrc(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.
629 };632 };
630 return emit.encode(mnemonic, .{633 return emit.encode(mnemonic, .{
631 .op1 = .{ .reg = ops.reg1 },634 .op1 = .{ .reg = ops.reg1 },
632 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{635 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
633 .base = ops.reg2,636 .base = ops.reg2,
634 .scale_index = scale_index,637 .scale_index = scale_index,
635 .disp = index_reg_disp.disp,638 .disp = index_reg_disp.disp,
...@@ -648,7 +651,7 @@ fn mirArithScaleDst(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst....@@ -648,7 +651,7 @@ fn mirArithScaleDst(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.
648 };651 };
649 assert(ops.reg2 != .none);652 assert(ops.reg2 != .none);
650 return emit.encode(mnemonic, .{653 return emit.encode(mnemonic, .{
651 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg2.size()), .{654 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg2.bitSize()), .{
652 .base = ops.reg1,655 .base = ops.reg1,
653 .scale_index = scale_index,656 .scale_index = scale_index,
654 .disp = index_reg_disp.disp,657 .disp = index_reg_disp.disp,
...@@ -672,7 +675,7 @@ fn mirArithScaleImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst....@@ -672,7 +675,7 @@ fn mirArithScaleImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.
672 .disp = index_reg_disp_imm.disp,675 .disp = index_reg_disp_imm.disp,
673 .scale_index = scale_index,676 .scale_index = scale_index,
674 }) },677 }) },
675 .op2 = .{ .imm = index_reg_disp_imm.imm },678 .op2 = .{ .imm = Immediate.u(index_reg_disp_imm.imm) },
676 });679 });
677}680}
678681
...@@ -697,7 +700,7 @@ fn mirArithMemIndexImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.In...@@ -697,7 +700,7 @@ fn mirArithMemIndexImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.In
697 .base = ops.reg1,700 .base = ops.reg1,
698 .scale_index = scale_index,701 .scale_index = scale_index,
699 }) },702 }) },
700 .op2 = .{ .imm = index_reg_disp_imm.imm },703 .op2 = .{ .imm = Immediate.u(index_reg_disp_imm.imm) },
701 });704 });
702}705}
703706
...@@ -708,7 +711,7 @@ fn mirMovSignExtend(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -708,7 +711,7 @@ fn mirMovSignExtend(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
708 const disp = if (ops.flags != 0b00) emit.mir.instructions.items(.data)[inst].disp else undefined;711 const disp = if (ops.flags != 0b00) emit.mir.instructions.items(.data)[inst].disp else undefined;
709 switch (ops.flags) {712 switch (ops.flags) {
710 0b00 => {713 0b00 => {
711 const mnemonic: Instruction.Mnemonic = if (ops.reg2.size() == 32) .movsxd else .movsx;714 const mnemonic: Instruction.Mnemonic = if (ops.reg2.bitSize() == 32) .movsxd else .movsx;
712 return emit.encode(mnemonic, .{715 return emit.encode(mnemonic, .{
713 .op1 = .{ .reg = ops.reg1 },716 .op1 = .{ .reg = ops.reg1 },
714 .op2 = .{ .reg = ops.reg2 },717 .op2 = .{ .reg = ops.reg2 },
...@@ -718,14 +721,15 @@ fn mirMovSignExtend(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -718,14 +721,15 @@ fn mirMovSignExtend(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
718 const ptr_size: Memory.PtrSize = switch (ops.flags) {721 const ptr_size: Memory.PtrSize = switch (ops.flags) {
719 0b01 => .byte,722 0b01 => .byte,
720 0b10 => .word,723 0b10 => .word,
721 0b11 => .qword,724 0b11 => .dword,
722 else => unreachable,725 else => unreachable,
723 };726 };
724 return emit.encode(.movsx, .{727 const mnemonic: Instruction.Mnemonic = if (ops.flags == 0b11) .movsxd else .movsx;
728 return emit.encode(mnemonic, .{
725 .op1 = .{ .reg = ops.reg1 },729 .op1 = .{ .reg = ops.reg1 },
726 .op2 = .{ .mem = Memory.sib(ptr_size, .{730 .op2 = .{ .mem = Memory.sib(ptr_size, .{
727 .disp = disp,
728 .base = ops.reg2,731 .base = ops.reg2,
732 .disp = disp,
729 }) },733 }) },
730 });734 });
731 },735 },
...@@ -770,19 +774,19 @@ fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -770,19 +774,19 @@ fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
770 const ops = emit.mir.instructions.items(.ops)[inst].decode();774 const ops = emit.mir.instructions.items(.ops)[inst].decode();
771 switch (ops.flags) {775 switch (ops.flags) {
772 0b00 => {776 0b00 => {
773 const imm: u64 = if (ops.reg1.size() == 64) blk: {777 const imm: u64 = if (ops.reg1.bitSize() == 64) blk: {
774 const payload = emit.mir.instructions.items(.data)[inst].payload;778 const payload = emit.mir.instructions.items(.data)[inst].payload;
775 const imm = emit.mir.extraData(Mir.Imm64, payload).data;779 const imm = emit.mir.extraData(Mir.Imm64, payload).data;
776 break :blk imm.decode();780 break :blk imm.decode();
777 } else emit.mir.instructions.items(.data)[inst].imm;781 } else emit.mir.instructions.items(.data)[inst].imm;
778 return emit.encode(.mov, .{782 return emit.encode(.mov, .{
779 .op1 = .{ .reg = ops.reg1 },783 .op1 = .{ .reg = ops.reg1 },
780 .op2 = .{ .imm = imm },784 .op2 = .{ .imm = Immediate.u(imm) },
781 });785 });
782 },786 },
783 0b01 => {787 0b01 => {
784 if (ops.reg1 == .none) {788 if (ops.reg1 == .none) {
785 const imm: u64 = if (ops.reg2.size() == 64) blk: {789 const imm: u64 = if (ops.reg2.bitSize() == 64) blk: {
786 const payload = emit.mir.instructions.items(.data)[inst].payload;790 const payload = emit.mir.instructions.items(.data)[inst].payload;
787 const imm = emit.mir.extraData(Mir.Imm64, payload).data;791 const imm = emit.mir.extraData(Mir.Imm64, payload).data;
788 break :blk imm.decode();792 break :blk imm.decode();
...@@ -792,7 +796,7 @@ fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -792,7 +796,7 @@ fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
792 .op2 = .{ .reg = .rax },796 .op2 = .{ .reg = .rax },
793 });797 });
794 }798 }
795 const imm: u64 = if (ops.reg1.size() == 64) blk: {799 const imm: u64 = if (ops.reg1.bitSize() == 64) blk: {
796 const payload = emit.mir.instructions.items(.data)[inst].payload;800 const payload = emit.mir.instructions.items(.data)[inst].payload;
797 const imm = emit.mir.extraData(Mir.Imm64, payload).data;801 const imm = emit.mir.extraData(Mir.Imm64, payload).data;
798 break :blk imm.decode();802 break :blk imm.decode();
...@@ -847,7 +851,7 @@ fn mirShift(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I...@@ -847,7 +851,7 @@ fn mirShift(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
847 0b00 => {851 0b00 => {
848 return emit.encode(mnemonic, .{852 return emit.encode(mnemonic, .{
849 .op1 = .{ .reg = ops.reg1 },853 .op1 = .{ .reg = ops.reg1 },
850 .op2 = .{ .imm = 1 },854 .op2 = .{ .imm = Immediate.u(1) },
851 });855 });
852 },856 },
853 0b01 => {857 0b01 => {
...@@ -860,7 +864,7 @@ fn mirShift(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I...@@ -860,7 +864,7 @@ fn mirShift(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
860 const imm = @truncate(u8, emit.mir.instructions.items(.data)[inst].imm);864 const imm = @truncate(u8, emit.mir.instructions.items(.data)[inst].imm);
861 return emit.encode(mnemonic, .{865 return emit.encode(mnemonic, .{
862 .op1 = .{ .reg = ops.reg1 },866 .op1 = .{ .reg = ops.reg1 },
863 .op2 = .{ .imm = imm },867 .op2 = .{ .imm = Immediate.u(imm) },
864 });868 });
865 },869 },
866 0b11 => {870 0b11 => {
...@@ -920,7 +924,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -920,7 +924,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
920 return emit.encode(.imul, .{924 return emit.encode(.imul, .{
921 .op1 = .{ .reg = ops.reg1 },925 .op1 = .{ .reg = ops.reg1 },
922 .op2 = .{ .reg = ops.reg2 },926 .op2 = .{ .reg = ops.reg2 },
923 .op3 = .{ .imm = imm },927 .op3 = .{ .imm = Immediate.u(imm) },
924 });928 });
925 },929 },
926 0b11 => {930 0b11 => {
...@@ -932,7 +936,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -932,7 +936,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
932 .base = ops.reg2,936 .base = ops.reg2,
933 .disp = imm_pair.dest_off,937 .disp = imm_pair.dest_off,
934 }) },938 }) },
935 .op3 = .{ .imm = imm_pair.operand },939 .op3 = .{ .imm = Immediate.u(imm_pair.operand) },
936 });940 });
937 },941 },
938 }942 }
...@@ -959,7 +963,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -959,7 +963,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
959 const src_reg: ?Register = if (ops.reg2 != .none) ops.reg2 else null;963 const src_reg: ?Register = if (ops.reg2 != .none) ops.reg2 else null;
960 return emit.encode(.lea, .{964 return emit.encode(.lea, .{
961 .op1 = .{ .reg = ops.reg1 },965 .op1 = .{ .reg = ops.reg1 },
962 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{966 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
963 .base = src_reg,967 .base = src_reg,
964 .disp = disp,968 .disp = disp,
965 }) },969 }) },
...@@ -969,7 +973,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -969,7 +973,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
969 const start_offset = emit.code.items.len;973 const start_offset = emit.code.items.len;
970 try emit.encode(.lea, .{974 try emit.encode(.lea, .{
971 .op1 = .{ .reg = ops.reg1 },975 .op1 = .{ .reg = ops.reg1 },
972 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromSize(ops.reg1.size()), 0) },976 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), 0) },
973 });977 });
974 const end_offset = emit.code.items.len;978 const end_offset = emit.code.items.len;
975 // Backpatch the displacement979 // Backpatch the displacement
...@@ -988,7 +992,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -988,7 +992,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
988 };992 };
989 return emit.encode(.lea, .{993 return emit.encode(.lea, .{
990 .op1 = .{ .reg = ops.reg1 },994 .op1 = .{ .reg = ops.reg1 },
991 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{995 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
992 .base = src_reg,996 .base = src_reg,
993 .scale_index = scale_index,997 .scale_index = scale_index,
994 .disp = index_reg_disp.disp,998 .disp = index_reg_disp.disp,
...@@ -1012,7 +1016,7 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1012,7 +1016,7 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
10121016
1013 try emit.encode(.lea, .{1017 try emit.encode(.lea, .{
1014 .op1 = .{ .reg = ops.reg1 },1018 .op1 = .{ .reg = ops.reg1 },
1015 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromSize(ops.reg1.size()), 0) },1019 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), 0) },
1016 });1020 });
10171021
1018 const end_offset = emit.code.items.len;1022 const end_offset = emit.code.items.len;
...@@ -1065,7 +1069,7 @@ fn mirMovFloat(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index...@@ -1065,7 +1069,7 @@ fn mirMovFloat(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index
1065 const disp = emit.mir.instructions.items(.data)[inst].disp;1069 const disp = emit.mir.instructions.items(.data)[inst].disp;
1066 return emit.encode(mnemonic, .{1070 return emit.encode(mnemonic, .{
1067 .op1 = .{ .reg = ops.reg1 },1071 .op1 = .{ .reg = ops.reg1 },
1068 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg2.size()), .{1072 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg2.bitSize()), .{
1069 .base = ops.reg2,1073 .base = ops.reg2,
1070 .disp = disp,1074 .disp = disp,
1071 }) },1075 }) },
...@@ -1074,7 +1078,7 @@ fn mirMovFloat(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index...@@ -1074,7 +1078,7 @@ fn mirMovFloat(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index
1074 0b01 => {1078 0b01 => {
1075 const disp = emit.mir.instructions.items(.data)[inst].disp;1079 const disp = emit.mir.instructions.items(.data)[inst].disp;
1076 return emit.encode(mnemonic, .{1080 return emit.encode(mnemonic, .{
1077 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{1081 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
1078 .base = ops.reg1,1082 .base = ops.reg1,
1079 .disp = disp,1083 .disp = disp,
1080 }) },1084 }) },
...@@ -1127,7 +1131,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1127,7 +1131,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1127 const offset = blk: {1131 const offset = blk: {
1128 // callq1132 // callq
1129 try emit.encode(.call, .{1133 try emit.encode(.call, .{
1130 .op1 = .{ .imm = 0 },1134 .op1 = .{ .imm = Immediate.s(0) },
1131 });1135 });
1132 break :blk @intCast(u32, emit.code.items.len) - 4;1136 break :blk @intCast(u32, emit.code.items.len) - 4;
1133 };1137 };
src/arch/x86_64/Encoding.zig+58-31
...@@ -144,20 +144,20 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct {...@@ -144,20 +144,20 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct {
144 // rex.W mov dil, 0x1144 // rex.W mov dil, 0x1
145 // Here, rex.W is not needed.145 // Here, rex.W is not needed.
146 const rex_w_allowed = blk: {146 const rex_w_allowed = blk: {
147 const bit_size = enc.operandSize();147 const bit_size = enc.operandBitSize();
148 break :blk bit_size == 64 or bit_size == 8;148 break :blk bit_size == 64 or bit_size == 8;
149 };149 };
150 if (rex_w_allowed) return enc;150 if (rex_w_allowed) return enc;
151 },151 },
152 }152 }
153 } else if (prefixes.legacy.prefix_66) {153 } else if (prefixes.legacy.prefix_66) {
154 switch (enc.operandSize()) {154 switch (enc.operandBitSize()) {
155 16 => return enc,155 16 => return enc,
156 else => {},156 else => {},
157 }157 }
158 } else {158 } else {
159 if (enc.mode == .none) {159 if (enc.mode == .none) {
160 switch (enc.operandSize()) {160 switch (enc.operandBitSize()) {
161 16 => {},161 16 => {},
162 else => return enc,162 else => return enc,
163 }163 }
...@@ -187,17 +187,17 @@ pub fn modRmExt(encoding: Encoding) u3 {...@@ -187,17 +187,17 @@ pub fn modRmExt(encoding: Encoding) u3 {
187 };187 };
188}188}
189189
190pub fn operandSize(encoding: Encoding) u32 {190pub fn operandBitSize(encoding: Encoding) u64 {
191 if (encoding.mode == .long) return 64;191 if (encoding.mode == .long) return 64;
192 const bit_size: u32 = switch (encoding.op_en) {192 const bit_size: u64 = switch (encoding.op_en) {
193 .np => switch (encoding.op1) {193 .np => switch (encoding.op1) {
194 .o16 => 16,194 .o16 => 16,
195 .o32 => 32,195 .o32 => 32,
196 .o64 => 64,196 .o64 => 64,
197 else => 32,197 else => 32,
198 },198 },
199 .td => encoding.op2.size(),199 .td => encoding.op2.bitSize(),
200 else => encoding.op1.size(),200 else => encoding.op1.bitSize(),
201 };201 };
202 return bit_size;202 return bit_size;
203}203}
...@@ -244,9 +244,9 @@ pub fn format(...@@ -244,9 +244,9 @@ pub fn format(
244 else => unreachable,244 else => unreachable,
245 };245 };
246 const tag = switch (op) {246 const tag = switch (op) {
247 .imm8 => "ib",247 .imm8, .imm8s => "ib",
248 .imm16 => "iw",248 .imm16, .imm16s => "iw",
249 .imm32 => "id",249 .imm32, .imm32s => "id",
250 .imm64 => "io",250 .imm64 => "io",
251 .rel8 => "cb",251 .rel8 => "cb",
252 .rel16 => "cw",252 .rel16 => "cw",
...@@ -330,6 +330,7 @@ pub const Op = enum {...@@ -330,6 +330,7 @@ pub const Op = enum {
330 o16, o32, o64,330 o16, o32, o64,
331 unity,331 unity,
332 imm8, imm16, imm32, imm64,332 imm8, imm16, imm32, imm64,
333 imm8s, imm16s, imm32s,
333 al, ax, eax, rax,334 al, ax, eax, rax,
334 cl,335 cl,
335 r8, r16, r32, r64,336 r8, r16, r32, r64,
...@@ -349,7 +350,7 @@ pub const Op = enum {...@@ -349,7 +350,7 @@ pub const Op = enum {
349 .reg => |reg| {350 .reg => |reg| {
350 switch (reg.class()) {351 switch (reg.class()) {
351 .segment => return .sreg,352 .segment => return .sreg,
352 .floating_point => return switch (reg.size()) {353 .floating_point => return switch (reg.bitSize()) {
353 128 => .xmm,354 128 => .xmm,
354 else => unreachable,355 else => unreachable,
355 },356 },
...@@ -362,7 +363,7 @@ pub const Op = enum {...@@ -362,7 +363,7 @@ pub const Op = enum {
362 else => unreachable,363 else => unreachable,
363 };364 };
364 if (reg == .cl) return .cl;365 if (reg == .cl) return .cl;
365 return switch (reg.size()) {366 return switch (reg.bitSize()) {
366 8 => .r8,367 8 => .r8,
367 16 => .r16,368 16 => .r16,
368 32 => .r32,369 32 => .r32,
...@@ -376,7 +377,7 @@ pub const Op = enum {...@@ -376,7 +377,7 @@ pub const Op = enum {
376 .mem => |mem| switch (mem) {377 .mem => |mem| switch (mem) {
377 .moffs => return .moffs,378 .moffs => return .moffs,
378 .sib, .rip => {379 .sib, .rip => {
379 const bit_size = mem.size();380 const bit_size = mem.bitSize();
380 return switch (bit_size) {381 return switch (bit_size) {
381 8 => .m8,382 8 => .m8,
382 16 => .m16,383 16 => .m16,
...@@ -389,21 +390,34 @@ pub const Op = enum {...@@ -389,21 +390,34 @@ pub const Op = enum {
389 },390 },
390391
391 .imm => |imm| {392 .imm => |imm| {
392 if (imm == 1) return .unity;393 switch (imm) {
393 if (math.cast(u8, imm)) |_| return .imm8;394 .signed => |x| {
394 if (math.cast(u16, imm)) |_| return .imm16;395 if (x == 1) return .unity;
395 if (math.cast(u32, imm)) |_| return .imm32;396 if (math.cast(i8, x)) |_| return .imm8s;
396 return .imm64;397 if (math.cast(i16, x)) |_| return .imm16s;
398 return .imm32s;
399 },
400 .unsigned => |x| {
401 if (x == 1) return .unity;
402 if (math.cast(i8, x)) |_| return .imm8s;
403 if (math.cast(u8, x)) |_| return .imm8;
404 if (math.cast(i16, x)) |_| return .imm16s;
405 if (math.cast(u16, x)) |_| return .imm16;
406 if (math.cast(i32, x)) |_| return .imm32s;
407 if (math.cast(u32, x)) |_| return .imm32;
408 return .imm64;
409 },
410 }
397 },411 },
398 }412 }
399 }413 }
400414
401 pub fn size(op: Op) u32 {415 pub fn bitSize(op: Op) u64 {
402 return switch (op) {416 return switch (op) {
403 .none, .o16, .o32, .o64, .moffs, .m, .sreg, .unity => unreachable,417 .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
404 .imm8, .al, .cl, .r8, .m8, .rm8, .rel8 => 8,418 .unity, .imm8, .imm8s, .al, .cl, .r8, .m8, .rm8, .rel8 => 8,
405 .imm16, .ax, .r16, .m16, .rm16, .rel16 => 16,419 .imm16, .imm16s, .ax, .r16, .m16, .rm16, .rel16 => 16,
406 .imm32, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32,420 .imm32, .imm32s, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32,
407 .imm64, .rax, .r64, .m64, .rm64, .xmm_m64 => 64,421 .imm64, .rax, .r64, .m64, .rm64, .xmm_m64 => 64,
408 .m80 => 80,422 .m80 => 80,
409 .xmm => 128,423 .xmm => 128,
...@@ -428,6 +442,7 @@ pub const Op = enum {...@@ -428,6 +442,7 @@ pub const Op = enum {
428 // zig fmt: off442 // zig fmt: off
429 return switch (op) {443 return switch (op) {
430 .imm8, .imm16, .imm32, .imm64, 444 .imm8, .imm16, .imm32, .imm64,
445 .imm8s, .imm16s, .imm32s,
431 .rel8, .rel16, .rel32,446 .rel8, .rel16, .rel32,
432 .unity,447 .unity,
433 => true,448 => true,
...@@ -479,28 +494,40 @@ pub const Op = enum {...@@ -479,28 +494,40 @@ pub const Op = enum {
479 .sse, .sse2 => return op.isFloatingPointRegister() and target.isFloatingPointRegister(),494 .sse, .sse2 => return op.isFloatingPointRegister() and target.isFloatingPointRegister(),
480 else => switch (target) {495 else => switch (target) {
481 .cl, .al, .ax, .eax, .rax => return op == target,496 .cl, .al, .ax, .eax, .rax => return op == target,
482 else => return op.size() == target.size(),497 else => return op.bitSize() == target.bitSize(),
483 },498 },
484 }499 }
485 }500 }
486 if (op.isMemory() and target.isMemory()) {501 if (op.isMemory() and target.isMemory()) {
487 switch (target) {502 switch (target) {
488 .m => return true,503 .m => return true,
489 else => return op.size() == target.size(),504 else => return op.bitSize() == target.bitSize(),
490 }505 }
491 }506 }
492 if (op.isImmediate() and target.isImmediate()) {507 if (op.isImmediate() and target.isImmediate()) {
493 switch (target) {508 switch (target) {
494 .imm32, .rel32 => switch (op) {509 .imm32s, .rel32 => switch (op) {
495 .unity, .imm8, .imm16, .imm32 => return true,510 .unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s => return true,
511 else => return op == target,
512 },
513 .imm32 => switch (op) {
514 .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s => return true,
515 else => return op == target,
516 },
517 .imm16s, .rel16 => switch (op) {
518 .unity, .imm8s, .imm8, .imm16s => return true,
519 else => return op == target,
520 },
521 .imm16 => switch (op) {
522 .unity, .imm8, .imm8s, .imm16, .imm16s => return true,
496 else => return op == target,523 else => return op == target,
497 },524 },
498 .imm16, .rel16 => switch (op) {525 .imm8s, .rel8 => switch (op) {
499 .unity, .imm8, .imm16 => return true,526 .unity, .imm8s => return true,
500 else => return op == target,527 else => return op == target,
501 },528 },
502 .imm8, .rel8 => switch (op) {529 .imm8 => switch (op) {
503 .unity, .imm8 => return true,530 .unity, .imm8, .imm8s => return true,
504 else => return op == target,531 else => return op == target,
505 },532 },
506 else => return op == target,533 else => return op == target,
src/arch/x86_64/Mir.zig+3
...@@ -34,6 +34,7 @@ pub const Inst = struct {...@@ -34,6 +34,7 @@ pub const Inst = struct {
34 /// 0b01 reg1, [reg2 + imm32]34 /// 0b01 reg1, [reg2 + imm32]
35 /// 0b01 reg1, [ds:imm32]35 /// 0b01 reg1, [ds:imm32]
36 /// 0b10 [reg1 + imm32], reg236 /// 0b10 [reg1 + imm32], reg2
37 /// 0b11 reg1, imm_s
37 /// Notes:38 /// Notes:
38 /// * If reg2 is `none` then it means Data field `imm` is used as the immediate.39 /// * If reg2 is `none` then it means Data field `imm` is used as the immediate.
39 /// * When two imm32 values are required, Data field `payload` points at `ImmPair`.40 /// * When two imm32 values are required, Data field `payload` points at `ImmPair`.
...@@ -421,6 +422,8 @@ pub const Inst = struct {...@@ -421,6 +422,8 @@ pub const Inst = struct {
421 inst: Index,422 inst: Index,
422 /// A 32-bit immediate value.423 /// A 32-bit immediate value.
423 imm: u32,424 imm: u32,
425 /// A 32-bit signed immediate value.
426 imm_s: i32,
424 /// A 32-bit signed displacement value.427 /// A 32-bit signed displacement value.
425 disp: i32,428 disp: i32,
426 /// A condition code for use with EFLAGS register.429 /// A condition code for use with EFLAGS register.
src/arch/x86_64/bits.zig+60-9
...@@ -207,7 +207,7 @@ pub const Register = enum(u7) {...@@ -207,7 +207,7 @@ pub const Register = enum(u7) {
207 return @intCast(u6, @enumToInt(reg) - base);207 return @intCast(u6, @enumToInt(reg) - base);
208 }208 }
209209
210 pub fn size(reg: Register) u32 {210 pub fn bitSize(reg: Register) u64 {
211 return switch (@enumToInt(reg)) {211 return switch (@enumToInt(reg)) {
212 // zig fmt: off212 // zig fmt: off
213 @enumToInt(Register.rax) ... @enumToInt(Register.r15) => 64,213 @enumToInt(Register.rax) ... @enumToInt(Register.r15) => 64,
...@@ -273,7 +273,7 @@ pub const Register = enum(u7) {...@@ -273,7 +273,7 @@ pub const Register = enum(u7) {
273 return @truncate(u3, reg.enc());273 return @truncate(u3, reg.enc());
274 }274 }
275275
276 pub fn toSize(reg: Register, bit_size: u32) Register {276 pub fn toBitSize(reg: Register, bit_size: u64) Register {
277 return switch (bit_size) {277 return switch (bit_size) {
278 8 => reg.to8(),278 8 => reg.to8(),
279 16 => reg.to16(),279 16 => reg.to16(),
...@@ -334,7 +334,17 @@ pub const Register = enum(u7) {...@@ -334,7 +334,17 @@ pub const Register = enum(u7) {
334334
335 pub fn dwarfLocOp(reg: Register) u8 {335 pub fn dwarfLocOp(reg: Register) u8 {
336 return switch (reg.class()) {336 return switch (reg.class()) {
337 .general_purpose => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.reg0,337 .general_purpose => switch (reg.to64()) {
338 .rax => DW.OP.reg0,
339 .rdx => DW.OP.reg1,
340 .rcx => DW.OP.reg2,
341 .rbx => DW.OP.reg3,
342 .rsi => DW.OP.reg4,
343 .rdi => DW.OP.reg5,
344 .rbp => DW.OP.reg6,
345 .rsp => DW.OP.reg7,
346 else => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.reg0,
347 },
338 .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.reg17,348 .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.reg17,
339 else => unreachable,349 else => unreachable,
340 };350 };
...@@ -345,7 +355,17 @@ pub const Register = enum(u7) {...@@ -345,7 +355,17 @@ pub const Register = enum(u7) {
345 /// register to a given signed offset.355 /// register to a given signed offset.
346 pub fn dwarfLocOpDeref(reg: Register) u8 {356 pub fn dwarfLocOpDeref(reg: Register) u8 {
347 return switch (reg.class()) {357 return switch (reg.class()) {
348 .general_purpose => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.breg0,358 .general_purpose => switch (reg.to64()) {
359 .rax => DW.OP.breg0,
360 .rdx => DW.OP.breg1,
361 .rcx => DW.OP.breg2,
362 .rbx => DW.OP.breg3,
363 .rsi => DW.OP.breg4,
364 .rdi => DW.OP.breg5,
365 .rbp => DW.OP.breg6,
366 .rsp => DW.OP.breg7,
367 else => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.breg0,
368 },
349 .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.breg17,369 .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.breg17,
350 else => unreachable,370 else => unreachable,
351 };371 };
...@@ -397,7 +417,7 @@ pub const Memory = union(enum) {...@@ -397,7 +417,7 @@ pub const Memory = union(enum) {
397 qword,417 qword,
398 tbyte,418 tbyte,
399419
400 pub fn fromSize(bit_size: u32) PtrSize {420 pub fn fromBitSize(bit_size: u64) PtrSize {
401 return switch (bit_size) {421 return switch (bit_size) {
402 8 => .byte,422 8 => .byte,
403 16 => .word,423 16 => .word,
...@@ -408,7 +428,7 @@ pub const Memory = union(enum) {...@@ -408,7 +428,7 @@ pub const Memory = union(enum) {
408 };428 };
409 }429 }
410430
411 pub fn size(s: PtrSize) u32 {431 pub fn bitSize(s: PtrSize) u64 {
412 return switch (s) {432 return switch (s) {
413 .byte => 8,433 .byte => 8,
414 .word => 16,434 .word => 16,
...@@ -481,11 +501,42 @@ pub const Memory = union(enum) {...@@ -481,11 +501,42 @@ pub const Memory = union(enum) {
481 };501 };
482 }502 }
483503
484 pub fn size(mem: Memory) u32 {504 pub fn bitSize(mem: Memory) u64 {
485 return switch (mem) {505 return switch (mem) {
486 .rip => |r| r.ptr_size.size(),506 .rip => |r| r.ptr_size.bitSize(),
487 .sib => |s| s.ptr_size.size(),507 .sib => |s| s.ptr_size.bitSize(),
488 .moffs => unreachable,508 .moffs => unreachable,
489 };509 };
490 }510 }
491};511};
512
513pub const Immediate = union(enum) {
514 signed: i32,
515 unsigned: u64,
516
517 pub fn u(x: u64) Immediate {
518 return .{ .unsigned = x };
519 }
520
521 pub fn s(x: i32) Immediate {
522 return .{ .signed = x };
523 }
524
525 pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 {
526 return switch (imm) {
527 .signed => |x| switch (bit_size) {
528 8 => @bitCast(u8, @intCast(i8, x)),
529 16 => @bitCast(u16, @intCast(i16, x)),
530 32 => @bitCast(u32, @intCast(i32, x)),
531 else => unreachable,
532 },
533 .unsigned => |x| switch (bit_size) {
534 8 => @intCast(u8, x),
535 16 => @intCast(u16, x),
536 32 => @intCast(u32, x),
537 64 => x,
538 else => unreachable,
539 },
540 };
541 }
542};
src/arch/x86_64/encoder.zig+40-33
...@@ -4,6 +4,7 @@ const math = std.math;...@@ -4,6 +4,7 @@ const math = std.math;
44
5const bits = @import("bits.zig");5const bits = @import("bits.zig");
6const Encoding = @import("Encoding.zig");6const Encoding = @import("Encoding.zig");
7const Immediate = bits.Immediate;
7const Memory = bits.Memory;8const Memory = bits.Memory;
8const Moffs = bits.Moffs;9const Moffs = bits.Moffs;
9const PtrSize = bits.PtrSize;10const PtrSize = bits.PtrSize;
...@@ -22,15 +23,14 @@ pub const Instruction = struct {...@@ -22,15 +23,14 @@ pub const Instruction = struct {
22 none,23 none,
23 reg: Register,24 reg: Register,
24 mem: Memory,25 mem: Memory,
25 imm: u64,26 imm: Immediate,
2627
27 /// Returns the bitsize of the operand.28 /// Returns the bitsize of the operand.
28 /// Asserts the operand is either register or memory.29 pub fn bitSize(op: Operand) u64 {
29 pub fn size(op: Operand) u64 {
30 return switch (op) {30 return switch (op) {
31 .none => unreachable,31 .none => unreachable,
32 .reg => |reg| reg.size(),32 .reg => |reg| reg.bitSize(),
33 .mem => |mem| mem.size(),33 .mem => |mem| mem.bitSize(),
34 .imm => unreachable,34 .imm => unreachable,
35 };35 };
36 }36 }
...@@ -47,7 +47,6 @@ pub const Instruction = struct {...@@ -47,7 +47,6 @@ pub const Instruction = struct {
47 }47 }
4848
49 pub fn fmtPrint(op: Operand, enc_op: Encoding.Op, writer: anytype) !void {49 pub fn fmtPrint(op: Operand, enc_op: Encoding.Op, writer: anytype) !void {
50 _ = enc_op;
51 switch (op) {50 switch (op) {
52 .none => {},51 .none => {},
53 .reg => |reg| try writer.writeAll(@tagName(reg)),52 .reg => |reg| try writer.writeAll(@tagName(reg)),
...@@ -92,9 +91,7 @@ pub const Instruction = struct {...@@ -92,9 +91,7 @@ pub const Instruction = struct {
92 },91 },
93 .moffs => |moffs| try writer.print("{s}:0x{x}", .{ @tagName(moffs.seg), moffs.offset }),92 .moffs => |moffs| try writer.print("{s}:0x{x}", .{ @tagName(moffs.seg), moffs.offset }),
94 },93 },
95 .imm => |imm| {94 .imm => |imm| try writer.print("0x{x}", .{imm.asUnsigned(enc_op.bitSize())}),
96 try writer.print("0x{x}", .{imm});
97 },
98 }95 }
99 }96 }
100 };97 };
...@@ -110,8 +107,17 @@ pub const Instruction = struct {...@@ -110,8 +107,17 @@ pub const Instruction = struct {
110 .op2 = args.op2,107 .op2 = args.op2,
111 .op3 = args.op3,108 .op3 = args.op3,
112 .op4 = args.op4,109 .op4 = args.op4,
113 }) orelse return error.InvalidInstruction;110 }) orelse {
114 std.log.warn("{}", .{encoding});111 std.log.debug("{s} {s} {s} {s} {s}", .{
112 @tagName(mnemonic),
113 @tagName(Encoding.Op.fromOperand(args.op1)),
114 @tagName(Encoding.Op.fromOperand(args.op2)),
115 @tagName(Encoding.Op.fromOperand(args.op3)),
116 @tagName(Encoding.Op.fromOperand(args.op4)),
117 });
118 return error.InvalidInstruction;
119 };
120 std.log.debug("{}", .{encoding});
115 return .{121 return .{
116 .op1 = args.op1,122 .op1 = args.op1,
117 .op2 = args.op2,123 .op2 = args.op2,
...@@ -210,7 +216,7 @@ pub const Instruction = struct {...@@ -210,7 +216,7 @@ pub const Instruction = struct {
210216
211 var legacy = LegacyPrefixes{};217 var legacy = LegacyPrefixes{};
212 if (enc.mode == .none) {218 if (enc.mode == .none) {
213 const bit_size = enc.operandSize();219 const bit_size = enc.operandBitSize();
214 if (bit_size == 16) {220 if (bit_size == 16) {
215 legacy.set16BitOverride();221 legacy.set16BitOverride();
216 }222 }
...@@ -380,12 +386,13 @@ pub const Instruction = struct {...@@ -380,12 +386,13 @@ pub const Instruction = struct {
380 }386 }
381 }387 }
382388
383 fn encodeImm(imm: u64, kind: Encoding.Op, encoder: anytype) !void {389 fn encodeImm(imm: Immediate, kind: Encoding.Op, encoder: anytype) !void {
384 switch (kind) {390 const raw = imm.asUnsigned(kind.bitSize());
385 .imm8, .rel8 => try encoder.imm8(@bitCast(i8, @truncate(u8, imm))),391 switch (kind.bitSize()) {
386 .imm16, .rel16 => try encoder.imm16(@bitCast(i16, @truncate(u16, imm))),392 8 => try encoder.imm8(@intCast(u8, raw)),
387 .imm32, .rel32 => try encoder.imm32(@bitCast(i32, @truncate(u32, imm))),393 16 => try encoder.imm16(@intCast(u16, raw)),
388 .imm64 => try encoder.imm64(imm),394 32 => try encoder.imm32(@intCast(u32, raw)),
395 64 => try encoder.imm64(raw),
389 else => unreachable,396 else => unreachable,
390 }397 }
391 }398 }
...@@ -732,39 +739,39 @@ fn Encoder(comptime T: type) type {...@@ -732,39 +739,39 @@ fn Encoder(comptime T: type) type {
732 // Trivial (no bit fiddling)739 // Trivial (no bit fiddling)
733 // -------------------------740 // -------------------------
734741
735 /// Encode an 8 bit immediate742 /// Encode an 8 bit displacement
736 ///743 ///
737 /// It is sign-extended to 64 bits by the cpu.744 /// It is sign-extended to 64 bits by the cpu.
738 pub fn imm8(self: Self, imm: i8) !void {745 pub fn disp8(self: Self, disp: i8) !void {
739 try self.writer.writeByte(@bitCast(u8, imm));746 try self.writer.writeByte(@bitCast(u8, disp));
740 }747 }
741748
742 /// Encode an 8 bit displacement749 /// Encode an 32 bit displacement
743 ///750 ///
744 /// It is sign-extended to 64 bits by the cpu.751 /// It is sign-extended to 64 bits by the cpu.
745 pub fn disp8(self: Self, disp: i8) !void {752 pub fn disp32(self: Self, disp: i32) !void {
746 try self.writer.writeByte(@bitCast(u8, disp));753 try self.writer.writeIntLittle(i32, disp);
747 }754 }
748755
749 /// Encode an 16 bit immediate756 /// Encode an 8 bit immediate
750 ///757 ///
751 /// It is sign-extended to 64 bits by the cpu.758 /// It is sign-extended to 64 bits by the cpu.
752 pub fn imm16(self: Self, imm: i16) !void {759 pub fn imm8(self: Self, imm: u8) !void {
753 try self.writer.writeIntLittle(i16, imm);760 try self.writer.writeByte(imm);
754 }761 }
755762
756 /// Encode an 32 bit immediate763 /// Encode an 16 bit immediate
757 ///764 ///
758 /// It is sign-extended to 64 bits by the cpu.765 /// It is sign-extended to 64 bits by the cpu.
759 pub fn imm32(self: Self, imm: i32) !void {766 pub fn imm16(self: Self, imm: u16) !void {
760 try self.writer.writeIntLittle(i32, imm);767 try self.writer.writeIntLittle(u16, imm);
761 }768 }
762769
763 /// Encode an 32 bit displacement770 /// Encode an 32 bit immediate
764 ///771 ///
765 /// It is sign-extended to 64 bits by the cpu.772 /// It is sign-extended to 64 bits by the cpu.
766 pub fn disp32(self: Self, disp: i32) !void {773 pub fn imm32(self: Self, imm: u32) !void {
767 try self.writer.writeIntLittle(i32, disp);774 try self.writer.writeIntLittle(u32, imm);
768 }775 }
769776
770 /// Encode an 64 bit immediate777 /// Encode an 64 bit immediate
src/arch/x86_64/encodings.zig+211-210
...@@ -13,65 +13,65 @@ const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, opcode_len, u8, u8, u8, m...@@ -13,65 +13,65 @@ const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, opcode_len, u8, u8, u8, m
13// zig fmt: off13// zig fmt: off
14pub const table = &[_]Entry{14pub const table = &[_]Entry{
15 // General-purpose15 // General-purpose
16 .{ .adc, .zi, .al, .imm8, .none, .none, 1, 0x14, 0x00, 0x00, 0, .none },16 .{ .adc, .zi, .al, .imm8, .none, .none, 1, 0x14, 0x00, 0x00, 0, .none },
17 .{ .adc, .zi, .ax, .imm16, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },17 .{ .adc, .zi, .ax, .imm16, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },
18 .{ .adc, .zi, .eax, .imm32, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },18 .{ .adc, .zi, .eax, .imm32, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },
19 .{ .adc, .zi, .rax, .imm32, .none, .none, 1, 0x15, 0x00, 0x00, 0, .long },19 .{ .adc, .zi, .rax, .imm32s, .none, .none, 1, 0x15, 0x00, 0x00, 0, .long },
20 .{ .adc, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 2, .none },20 .{ .adc, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 2, .none },
21 .{ .adc, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },21 .{ .adc, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },
22 .{ .adc, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },22 .{ .adc, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },
23 .{ .adc, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 2, .long },23 .{ .adc, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 2, .long },
24 .{ .adc, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },24 .{ .adc, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },
25 .{ .adc, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },25 .{ .adc, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },
26 .{ .adc, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 2, .long },26 .{ .adc, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .long },
27 .{ .adc, .mr, .rm8, .r8, .none, .none, 1, 0x10, 0x00, 0x00, 0, .none },27 .{ .adc, .mr, .rm8, .r8, .none, .none, 1, 0x10, 0x00, 0x00, 0, .none },
28 .{ .adc, .mr, .rm16, .r16, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },28 .{ .adc, .mr, .rm16, .r16, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },
29 .{ .adc, .mr, .rm32, .r32, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },29 .{ .adc, .mr, .rm32, .r32, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },
30 .{ .adc, .mr, .rm64, .r64, .none, .none, 1, 0x11, 0x00, 0x00, 0, .long },30 .{ .adc, .mr, .rm64, .r64, .none, .none, 1, 0x11, 0x00, 0x00, 0, .long },
31 .{ .adc, .rm, .r8, .rm8, .none, .none, 1, 0x12, 0x00, 0x00, 0, .none },31 .{ .adc, .rm, .r8, .rm8, .none, .none, 1, 0x12, 0x00, 0x00, 0, .none },
32 .{ .adc, .rm, .r16, .rm16, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },32 .{ .adc, .rm, .r16, .rm16, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },
33 .{ .adc, .rm, .r32, .rm32, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },33 .{ .adc, .rm, .r32, .rm32, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },
34 .{ .adc, .rm, .r64, .rm64, .none, .none, 1, 0x13, 0x00, 0x00, 0, .long },34 .{ .adc, .rm, .r64, .rm64, .none, .none, 1, 0x13, 0x00, 0x00, 0, .long },
3535
36 .{ .add, .zi, .al, .imm8, .none, .none, 1, 0x04, 0x00, 0x00, 0, .none },36 .{ .add, .zi, .al, .imm8, .none, .none, 1, 0x04, 0x00, 0x00, 0, .none },
37 .{ .add, .zi, .ax, .imm16, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },37 .{ .add, .zi, .ax, .imm16, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },
38 .{ .add, .zi, .eax, .imm32, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },38 .{ .add, .zi, .eax, .imm32, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },
39 .{ .add, .zi, .rax, .imm32, .none, .none, 1, 0x05, 0x00, 0x00, 0, .long },39 .{ .add, .zi, .rax, .imm32s, .none, .none, 1, 0x05, 0x00, 0x00, 0, .long },
40 .{ .add, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 0, .none },40 .{ .add, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 0, .none },
41 .{ .add, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },41 .{ .add, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },
42 .{ .add, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },42 .{ .add, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },
43 .{ .add, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 0, .long },43 .{ .add, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 0, .long },
44 .{ .add, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },44 .{ .add, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },
45 .{ .add, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },45 .{ .add, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },
46 .{ .add, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 0, .long },46 .{ .add, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .long },
47 .{ .add, .mr, .rm8, .r8, .none, .none, 1, 0x00, 0x00, 0x00, 0, .none },47 .{ .add, .mr, .rm8, .r8, .none, .none, 1, 0x00, 0x00, 0x00, 0, .none },
48 .{ .add, .mr, .rm16, .r16, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },48 .{ .add, .mr, .rm16, .r16, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },
49 .{ .add, .mr, .rm32, .r32, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },49 .{ .add, .mr, .rm32, .r32, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },
50 .{ .add, .mr, .rm64, .r64, .none, .none, 1, 0x01, 0x00, 0x00, 0, .long },50 .{ .add, .mr, .rm64, .r64, .none, .none, 1, 0x01, 0x00, 0x00, 0, .long },
51 .{ .add, .rm, .r8, .rm8, .none, .none, 1, 0x02, 0x00, 0x00, 0, .none },51 .{ .add, .rm, .r8, .rm8, .none, .none, 1, 0x02, 0x00, 0x00, 0, .none },
52 .{ .add, .rm, .r16, .rm16, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },52 .{ .add, .rm, .r16, .rm16, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },
53 .{ .add, .rm, .r32, .rm32, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },53 .{ .add, .rm, .r32, .rm32, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },
54 .{ .add, .rm, .r64, .rm64, .none, .none, 1, 0x03, 0x00, 0x00, 0, .long },54 .{ .add, .rm, .r64, .rm64, .none, .none, 1, 0x03, 0x00, 0x00, 0, .long },
5555
56 .{ .@"and", .zi, .al, .imm8, .none, .none, 1, 0x24, 0x00, 0x00, 0, .none },56 .{ .@"and", .zi, .al, .imm8, .none, .none, 1, 0x24, 0x00, 0x00, 0, .none },
57 .{ .@"and", .zi, .ax, .imm16, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },57 .{ .@"and", .zi, .ax, .imm16, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },
58 .{ .@"and", .zi, .eax, .imm32, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },58 .{ .@"and", .zi, .eax, .imm32, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },
59 .{ .@"and", .zi, .rax, .imm32, .none, .none, 1, 0x25, 0x00, 0x00, 0, .long },59 .{ .@"and", .zi, .rax, .imm32s, .none, .none, 1, 0x25, 0x00, 0x00, 0, .long },
60 .{ .@"and", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 4, .none },60 .{ .@"and", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 4, .none },
61 .{ .@"and", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },61 .{ .@"and", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },
62 .{ .@"and", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },62 .{ .@"and", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },
63 .{ .@"and", .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 4, .long },63 .{ .@"and", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 4, .long },
64 .{ .@"and", .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },64 .{ .@"and", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },
65 .{ .@"and", .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },65 .{ .@"and", .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },
66 .{ .@"and", .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 4, .long },66 .{ .@"and", .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .long },
67 .{ .@"and", .mr, .rm8, .r8, .none, .none, 1, 0x20, 0x00, 0x00, 0, .none },67 .{ .@"and", .mr, .rm8, .r8, .none, .none, 1, 0x20, 0x00, 0x00, 0, .none },
68 .{ .@"and", .mr, .rm16, .r16, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },68 .{ .@"and", .mr, .rm16, .r16, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },
69 .{ .@"and", .mr, .rm32, .r32, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },69 .{ .@"and", .mr, .rm32, .r32, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },
70 .{ .@"and", .mr, .rm64, .r64, .none, .none, 1, 0x21, 0x00, 0x00, 0, .long },70 .{ .@"and", .mr, .rm64, .r64, .none, .none, 1, 0x21, 0x00, 0x00, 0, .long },
71 .{ .@"and", .rm, .r8, .rm8, .none, .none, 1, 0x22, 0x00, 0x00, 0, .none },71 .{ .@"and", .rm, .r8, .rm8, .none, .none, 1, 0x22, 0x00, 0x00, 0, .none },
72 .{ .@"and", .rm, .r16, .rm16, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },72 .{ .@"and", .rm, .r16, .rm16, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },
73 .{ .@"and", .rm, .r32, .rm32, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },73 .{ .@"and", .rm, .r32, .rm32, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },
74 .{ .@"and", .rm, .r64, .rm64, .none, .none, 1, 0x23, 0x00, 0x00, 0, .long },74 .{ .@"and", .rm, .r64, .rm64, .none, .none, 1, 0x23, 0x00, 0x00, 0, .long },
7575
76 // This is M encoding according to Intel, but D makes more sense here.76 // This is M encoding according to Intel, but D makes more sense here.
77 .{ .call, .d, .rel32, .none, .none, .none, 1, 0xe8, 0x00, 0x00, 0, .none },77 .{ .call, .d, .rel32, .none, .none, .none, 1, 0xe8, 0x00, 0x00, 0, .none },
...@@ -176,25 +176,25 @@ pub const table = &[_]Entry{...@@ -176,25 +176,25 @@ pub const table = &[_]Entry{
176 .{ .cmovz, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none },176 .{ .cmovz, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none },
177 .{ .cmovz, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .long },177 .{ .cmovz, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .long },
178178
179 .{ .cmp, .zi, .al, .imm8, .none, .none, 1, 0x3c, 0x00, 0x00, 0, .none },179 .{ .cmp, .zi, .al, .imm8, .none, .none, 1, 0x3c, 0x00, 0x00, 0, .none },
180 .{ .cmp, .zi, .ax, .imm16, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },180 .{ .cmp, .zi, .ax, .imm16, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },
181 .{ .cmp, .zi, .eax, .imm32, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },181 .{ .cmp, .zi, .eax, .imm32, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },
182 .{ .cmp, .zi, .rax, .imm32, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .long },182 .{ .cmp, .zi, .rax, .imm32s, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .long },
183 .{ .cmp, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 7, .none },183 .{ .cmp, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 7, .none },
184 .{ .cmp, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },184 .{ .cmp, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },
185 .{ .cmp, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },185 .{ .cmp, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },
186 .{ .cmp, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 7, .long },186 .{ .cmp, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 7, .long },
187 .{ .cmp, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },187 .{ .cmp, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },
188 .{ .cmp, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },188 .{ .cmp, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },
189 .{ .cmp, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 7, .long },189 .{ .cmp, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .long },
190 .{ .cmp, .mr, .rm8, .r8, .none, .none, 1, 0x38, 0x00, 0x00, 0, .none },190 .{ .cmp, .mr, .rm8, .r8, .none, .none, 1, 0x38, 0x00, 0x00, 0, .none },
191 .{ .cmp, .mr, .rm16, .r16, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },191 .{ .cmp, .mr, .rm16, .r16, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },
192 .{ .cmp, .mr, .rm32, .r32, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },192 .{ .cmp, .mr, .rm32, .r32, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },
193 .{ .cmp, .mr, .rm64, .r64, .none, .none, 1, 0x39, 0x00, 0x00, 0, .long },193 .{ .cmp, .mr, .rm64, .r64, .none, .none, 1, 0x39, 0x00, 0x00, 0, .long },
194 .{ .cmp, .rm, .r8, .rm8, .none, .none, 1, 0x3a, 0x00, 0x00, 0, .none },194 .{ .cmp, .rm, .r8, .rm8, .none, .none, 1, 0x3a, 0x00, 0x00, 0, .none },
195 .{ .cmp, .rm, .r16, .rm16, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },195 .{ .cmp, .rm, .r16, .rm16, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },
196 .{ .cmp, .rm, .r32, .rm32, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },196 .{ .cmp, .rm, .r32, .rm32, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },
197 .{ .cmp, .rm, .r64, .rm64, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .long },197 .{ .cmp, .rm, .r64, .rm64, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .long },
198198
199 .{ .div, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 6, .none },199 .{ .div, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 6, .none },
200 .{ .div, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .none },200 .{ .div, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .none },
...@@ -214,19 +214,19 @@ pub const table = &[_]Entry{...@@ -214,19 +214,19 @@ pub const table = &[_]Entry{
214 .{ .idiv, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .none },214 .{ .idiv, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .none },
215 .{ .idiv, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .long },215 .{ .idiv, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .long },
216216
217 .{ .imul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 5, .none },217 .{ .imul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 5, .none },
218 .{ .imul, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },218 .{ .imul, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },
219 .{ .imul, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },219 .{ .imul, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },
220 .{ .imul, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .long },220 .{ .imul, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .long },
221 .{ .imul, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },221 .{ .imul, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
222 .{ .imul, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },222 .{ .imul, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
223 .{ .imul, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .long },223 .{ .imul, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .long },
224 .{ .imul, .rmi, .r16, .rm16, .imm8, .none, 1, 0x6b, 0x00, 0x00, 0, .none },224 .{ .imul, .rmi, .r16, .rm16, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
225 .{ .imul, .rmi, .r32, .rm32, .imm8, .none, 1, 0x6b, 0x00, 0x00, 0, .none },225 .{ .imul, .rmi, .r32, .rm32, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
226 .{ .imul, .rmi, .r64, .rm64, .imm8, .none, 1, 0x6b, 0x00, 0x00, 0, .long },226 .{ .imul, .rmi, .r64, .rm64, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .long },
227 .{ .imul, .rmi, .r16, .rm16, .imm16, .none, 1, 0x69, 0x00, 0x00, 0, .none },227 .{ .imul, .rmi, .r16, .rm16, .imm16, .none, 1, 0x69, 0x00, 0x00, 0, .none },
228 .{ .imul, .rmi, .r32, .rm32, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .none },228 .{ .imul, .rmi, .r32, .rm32, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .none },
229 .{ .imul, .rmi, .r64, .rm64, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .long },229 .{ .imul, .rmi, .r64, .rm64, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .long },
230230
231 .{ .int3, .np, .none, .none, .none, .none, 1, 0xcc, 0x00, 0x00, 0, .none },231 .{ .int3, .np, .none, .none, .none, .none, 1, 0xcc, 0x00, 0x00, 0, .none },
232232
...@@ -269,34 +269,34 @@ pub const table = &[_]Entry{...@@ -269,34 +269,34 @@ pub const table = &[_]Entry{
269 .{ .lea, .rm, .r32, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .none },269 .{ .lea, .rm, .r32, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .none },
270 .{ .lea, .rm, .r64, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .long },270 .{ .lea, .rm, .r64, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .long },
271271
272 .{ .mov, .mr, .rm8, .r8, .none, .none, 1, 0x88, 0x00, 0x00, 0, .none },272 .{ .mov, .mr, .rm8, .r8, .none, .none, 1, 0x88, 0x00, 0x00, 0, .none },
273 .{ .mov, .mr, .rm16, .r16, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },273 .{ .mov, .mr, .rm16, .r16, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },
274 .{ .mov, .mr, .rm32, .r32, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },274 .{ .mov, .mr, .rm32, .r32, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },
275 .{ .mov, .mr, .rm64, .r64, .none, .none, 1, 0x89, 0x00, 0x00, 0, .long },275 .{ .mov, .mr, .rm64, .r64, .none, .none, 1, 0x89, 0x00, 0x00, 0, .long },
276 .{ .mov, .rm, .r8, .rm8, .none, .none, 1, 0x8a, 0x00, 0x00, 0, .none },276 .{ .mov, .rm, .r8, .rm8, .none, .none, 1, 0x8a, 0x00, 0x00, 0, .none },
277 .{ .mov, .rm, .r16, .rm16, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },277 .{ .mov, .rm, .r16, .rm16, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },
278 .{ .mov, .rm, .r32, .rm32, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },278 .{ .mov, .rm, .r32, .rm32, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },
279 .{ .mov, .rm, .r64, .rm64, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .long },279 .{ .mov, .rm, .r64, .rm64, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .long },
280 .{ .mov, .mr, .rm16, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .none },280 .{ .mov, .mr, .rm16, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .none },
281 .{ .mov, .mr, .rm64, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .long },281 .{ .mov, .mr, .rm64, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .long },
282 .{ .mov, .rm, .sreg, .rm16, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .none },282 .{ .mov, .rm, .sreg, .rm16, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .none },
283 .{ .mov, .rm, .sreg, .rm64, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .long },283 .{ .mov, .rm, .sreg, .rm64, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .long },
284 .{ .mov, .fd, .al, .moffs, .none, .none, 1, 0xa0, 0x00, 0x00, 0, .none },284 .{ .mov, .fd, .al, .moffs, .none, .none, 1, 0xa0, 0x00, 0x00, 0, .none },
285 .{ .mov, .fd, .ax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },285 .{ .mov, .fd, .ax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
286 .{ .mov, .fd, .eax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },286 .{ .mov, .fd, .eax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
287 .{ .mov, .fd, .rax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .long },287 .{ .mov, .fd, .rax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .long },
288 .{ .mov, .td, .moffs, .al, .none, .none, 1, 0xa2, 0x00, 0x00, 0, .none },288 .{ .mov, .td, .moffs, .al, .none, .none, 1, 0xa2, 0x00, 0x00, 0, .none },
289 .{ .mov, .td, .moffs, .ax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },289 .{ .mov, .td, .moffs, .ax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },
290 .{ .mov, .td, .moffs, .eax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },290 .{ .mov, .td, .moffs, .eax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },
291 .{ .mov, .td, .moffs, .rax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .long },291 .{ .mov, .td, .moffs, .rax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .long },
292 .{ .mov, .oi, .r8, .imm8, .none, .none, 1, 0xb0, 0x00, 0x00, 0, .none },292 .{ .mov, .oi, .r8, .imm8, .none, .none, 1, 0xb0, 0x00, 0x00, 0, .none },
293 .{ .mov, .oi, .r16, .imm16, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },293 .{ .mov, .oi, .r16, .imm16, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },
294 .{ .mov, .oi, .r32, .imm32, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },294 .{ .mov, .oi, .r32, .imm32, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },
295 .{ .mov, .oi, .r64, .imm64, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .long },295 .{ .mov, .oi, .r64, .imm64, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .long },
296 .{ .mov, .mi, .rm8, .imm8, .none, .none, 1, 0xc6, 0x00, 0x00, 0, .none },296 .{ .mov, .mi, .rm8, .imm8, .none, .none, 1, 0xc6, 0x00, 0x00, 0, .none },
297 .{ .mov, .mi, .rm16, .imm16, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },297 .{ .mov, .mi, .rm16, .imm16, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },
298 .{ .mov, .mi, .rm32, .imm32, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },298 .{ .mov, .mi, .rm32, .imm32, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },
299 .{ .mov, .mi, .rm64, .imm32, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .long },299 .{ .mov, .mi, .rm64, .imm32s, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .long },
300300
301 .{ .movsx, .rm, .r16, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none },301 .{ .movsx, .rm, .r16, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none },
302 .{ .movsx, .rm, .r32, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none },302 .{ .movsx, .rm, .r32, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none },
...@@ -321,25 +321,25 @@ pub const table = &[_]Entry{...@@ -321,25 +321,25 @@ pub const table = &[_]Entry{
321321
322 .{ .nop, .np, .none, .none, .none, .none, 1, 0x90, 0x00, 0x00, 0, .none },322 .{ .nop, .np, .none, .none, .none, .none, 1, 0x90, 0x00, 0x00, 0, .none },
323323
324 .{ .@"or", .zi, .al, .imm8, .none, .none, 1, 0x0c, 0x00, 0x00, 0, .none },324 .{ .@"or", .zi, .al, .imm8, .none, .none, 1, 0x0c, 0x00, 0x00, 0, .none },
325 .{ .@"or", .zi, .ax, .imm16, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },325 .{ .@"or", .zi, .ax, .imm16, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },
326 .{ .@"or", .zi, .eax, .imm32, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },326 .{ .@"or", .zi, .eax, .imm32, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },
327 .{ .@"or", .zi, .rax, .imm32, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .long },327 .{ .@"or", .zi, .rax, .imm32s, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .long },
328 .{ .@"or", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 1, .none },328 .{ .@"or", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 1, .none },
329 .{ .@"or", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },329 .{ .@"or", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },
330 .{ .@"or", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },330 .{ .@"or", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },
331 .{ .@"or", .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 1, .long },331 .{ .@"or", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 1, .long },
332 .{ .@"or", .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },332 .{ .@"or", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },
333 .{ .@"or", .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },333 .{ .@"or", .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },
334 .{ .@"or", .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 1, .long },334 .{ .@"or", .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .long },
335 .{ .@"or", .mr, .rm8, .r8, .none, .none, 1, 0x08, 0x00, 0x00, 0, .none },335 .{ .@"or", .mr, .rm8, .r8, .none, .none, 1, 0x08, 0x00, 0x00, 0, .none },
336 .{ .@"or", .mr, .rm16, .r16, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },336 .{ .@"or", .mr, .rm16, .r16, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },
337 .{ .@"or", .mr, .rm32, .r32, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },337 .{ .@"or", .mr, .rm32, .r32, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },
338 .{ .@"or", .mr, .rm64, .r64, .none, .none, 1, 0x09, 0x00, 0x00, 0, .long },338 .{ .@"or", .mr, .rm64, .r64, .none, .none, 1, 0x09, 0x00, 0x00, 0, .long },
339 .{ .@"or", .rm, .r8, .rm8, .none, .none, 1, 0x0a, 0x00, 0x00, 0, .none },339 .{ .@"or", .rm, .r8, .rm8, .none, .none, 1, 0x0a, 0x00, 0x00, 0, .none },
340 .{ .@"or", .rm, .r16, .rm16, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },340 .{ .@"or", .rm, .r16, .rm16, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },
341 .{ .@"or", .rm, .r32, .rm32, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },341 .{ .@"or", .rm, .r32, .rm32, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },
342 .{ .@"or", .rm, .r64, .rm64, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .long },342 .{ .@"or", .rm, .r64, .rm64, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .long },
343343
344 .{ .pop, .o, .r16, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },344 .{ .pop, .o, .r16, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },
345 .{ .pop, .o, .r64, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },345 .{ .pop, .o, .r64, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },
...@@ -382,25 +382,25 @@ pub const table = &[_]Entry{...@@ -382,25 +382,25 @@ pub const table = &[_]Entry{
382 .{ .sar, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .none },382 .{ .sar, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .none },
383 .{ .sar, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .long },383 .{ .sar, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .long },
384384
385 .{ .sbb, .zi, .al, .imm8, .none, .none, 1, 0x1c, 0x00, 0x00, 0, .none },385 .{ .sbb, .zi, .al, .imm8, .none, .none, 1, 0x1c, 0x00, 0x00, 0, .none },
386 .{ .sbb, .zi, .ax, .imm16, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },386 .{ .sbb, .zi, .ax, .imm16, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },
387 .{ .sbb, .zi, .eax, .imm32, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },387 .{ .sbb, .zi, .eax, .imm32, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },
388 .{ .sbb, .zi, .rax, .imm32, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .long },388 .{ .sbb, .zi, .rax, .imm32s, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .long },
389 .{ .sbb, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 3, .none },389 .{ .sbb, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 3, .none },
390 .{ .sbb, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },390 .{ .sbb, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },
391 .{ .sbb, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },391 .{ .sbb, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },
392 .{ .sbb, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 3, .long },392 .{ .sbb, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 3, .long },
393 .{ .sbb, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },393 .{ .sbb, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },
394 .{ .sbb, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },394 .{ .sbb, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },
395 .{ .sbb, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 3, .long },395 .{ .sbb, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .long },
396 .{ .sbb, .mr, .rm8, .r8, .none, .none, 1, 0x18, 0x00, 0x00, 0, .none },396 .{ .sbb, .mr, .rm8, .r8, .none, .none, 1, 0x18, 0x00, 0x00, 0, .none },
397 .{ .sbb, .mr, .rm16, .r16, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },397 .{ .sbb, .mr, .rm16, .r16, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },
398 .{ .sbb, .mr, .rm32, .r32, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },398 .{ .sbb, .mr, .rm32, .r32, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },
399 .{ .sbb, .mr, .rm64, .r64, .none, .none, 1, 0x19, 0x00, 0x00, 0, .long },399 .{ .sbb, .mr, .rm64, .r64, .none, .none, 1, 0x19, 0x00, 0x00, 0, .long },
400 .{ .sbb, .rm, .r8, .rm8, .none, .none, 1, 0x1a, 0x00, 0x00, 0, .none },400 .{ .sbb, .rm, .r8, .rm8, .none, .none, 1, 0x1a, 0x00, 0x00, 0, .none },
401 .{ .sbb, .rm, .r16, .rm16, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },401 .{ .sbb, .rm, .r16, .rm16, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },
402 .{ .sbb, .rm, .r32, .rm32, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },402 .{ .sbb, .rm, .r32, .rm32, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },
403 .{ .sbb, .rm, .r64, .rm64, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .long },403 .{ .sbb, .rm, .r64, .rm64, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .long },
404404
405 .{ .seta, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .none },405 .{ .seta, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .none },
406 .{ .setae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none },406 .{ .setae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none },
...@@ -459,62 +459,62 @@ pub const table = &[_]Entry{...@@ -459,62 +459,62 @@ pub const table = &[_]Entry{
459 .{ .shr, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .none },459 .{ .shr, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .none },
460 .{ .shr, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .long },460 .{ .shr, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .long },
461461
462 .{ .sub, .zi, .al, .imm8, .none, .none, 1, 0x2c, 0x00, 0x00, 0, .none },462 .{ .sub, .zi, .al, .imm8, .none, .none, 1, 0x2c, 0x00, 0x00, 0, .none },
463 .{ .sub, .zi, .ax, .imm16, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },463 .{ .sub, .zi, .ax, .imm16, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },
464 .{ .sub, .zi, .eax, .imm32, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },464 .{ .sub, .zi, .eax, .imm32, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },
465 .{ .sub, .zi, .rax, .imm32, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .long },465 .{ .sub, .zi, .rax, .imm32s, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .long },
466 .{ .sub, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 5, .none },466 .{ .sub, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 5, .none },
467 .{ .sub, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },467 .{ .sub, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },
468 .{ .sub, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },468 .{ .sub, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },
469 .{ .sub, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 5, .long },469 .{ .sub, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 5, .long },
470 .{ .sub, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },470 .{ .sub, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },
471 .{ .sub, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },471 .{ .sub, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },
472 .{ .sub, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 5, .long },472 .{ .sub, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .long },
473 .{ .sub, .mr, .rm8, .r8, .none, .none, 1, 0x28, 0x00, 0x00, 0, .none },473 .{ .sub, .mr, .rm8, .r8, .none, .none, 1, 0x28, 0x00, 0x00, 0, .none },
474 .{ .sub, .mr, .rm16, .r16, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },474 .{ .sub, .mr, .rm16, .r16, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },
475 .{ .sub, .mr, .rm32, .r32, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },475 .{ .sub, .mr, .rm32, .r32, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },
476 .{ .sub, .mr, .rm64, .r64, .none, .none, 1, 0x29, 0x00, 0x00, 0, .long },476 .{ .sub, .mr, .rm64, .r64, .none, .none, 1, 0x29, 0x00, 0x00, 0, .long },
477 .{ .sub, .rm, .r8, .rm8, .none, .none, 1, 0x2a, 0x00, 0x00, 0, .none },477 .{ .sub, .rm, .r8, .rm8, .none, .none, 1, 0x2a, 0x00, 0x00, 0, .none },
478 .{ .sub, .rm, .r16, .rm16, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },478 .{ .sub, .rm, .r16, .rm16, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },
479 .{ .sub, .rm, .r32, .rm32, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },479 .{ .sub, .rm, .r32, .rm32, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },
480 .{ .sub, .rm, .r64, .rm64, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .long },480 .{ .sub, .rm, .r64, .rm64, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .long },
481481
482 .{ .syscall, .np, .none, .none, .none, .none, 2, 0x0f, 0x05, 0x00, 0, .none },482 .{ .syscall, .np, .none, .none, .none, .none, 2, 0x0f, 0x05, 0x00, 0, .none },
483483
484 .{ .@"test", .zi, .al, .imm8, .none, .none, 1, 0xa8, 0x00, 0x00, 0, .none },484 .{ .@"test", .zi, .al, .imm8, .none, .none, 1, 0xa8, 0x00, 0x00, 0, .none },
485 .{ .@"test", .zi, .ax, .imm16, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },485 .{ .@"test", .zi, .ax, .imm16, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },
486 .{ .@"test", .zi, .eax, .imm32, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },486 .{ .@"test", .zi, .eax, .imm32, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },
487 .{ .@"test", .zi, .rax, .imm32, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .long },487 .{ .@"test", .zi, .rax, .imm32s, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .long },
488 .{ .@"test", .mi, .rm8, .imm8, .none, .none, 1, 0xf6, 0x00, 0x00, 0, .none },488 .{ .@"test", .mi, .rm8, .imm8, .none, .none, 1, 0xf6, 0x00, 0x00, 0, .none },
489 .{ .@"test", .mi, .rm16, .imm16, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },489 .{ .@"test", .mi, .rm16, .imm16, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },
490 .{ .@"test", .mi, .rm32, .imm32, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },490 .{ .@"test", .mi, .rm32, .imm32, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },
491 .{ .@"test", .mi, .rm64, .imm32, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .long },491 .{ .@"test", .mi, .rm64, .imm32s, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .long },
492 .{ .@"test", .mr, .rm8, .r8, .none, .none, 1, 0x84, 0x00, 0x00, 0, .none },492 .{ .@"test", .mr, .rm8, .r8, .none, .none, 1, 0x84, 0x00, 0x00, 0, .none },
493 .{ .@"test", .mr, .rm16, .r16, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },493 .{ .@"test", .mr, .rm16, .r16, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },
494 .{ .@"test", .mr, .rm32, .r32, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },494 .{ .@"test", .mr, .rm32, .r32, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },
495 .{ .@"test", .mr, .rm64, .r64, .none, .none, 1, 0x85, 0x00, 0x00, 0, .long },495 .{ .@"test", .mr, .rm64, .r64, .none, .none, 1, 0x85, 0x00, 0x00, 0, .long },
496496
497 .{ .ud2, .np, .none, .none, .none, .none, 2, 0x0f, 0x0b, 0x00, 0, .none },497 .{ .ud2, .np, .none, .none, .none, .none, 2, 0x0f, 0x0b, 0x00, 0, .none },
498498
499 .{ .xor, .zi, .al, .imm8, .none, .none, 1, 0x34, 0x00, 0x00, 0, .none },499 .{ .xor, .zi, .al, .imm8, .none, .none, 1, 0x34, 0x00, 0x00, 0, .none },
500 .{ .xor, .zi, .ax, .imm16, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },500 .{ .xor, .zi, .ax, .imm16, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },
501 .{ .xor, .zi, .eax, .imm32, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },501 .{ .xor, .zi, .eax, .imm32, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },
502 .{ .xor, .zi, .rax, .imm32, .none, .none, 1, 0x35, 0x00, 0x00, 0, .long },502 .{ .xor, .zi, .rax, .imm32s, .none, .none, 1, 0x35, 0x00, 0x00, 0, .long },
503 .{ .xor, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 6, .none },503 .{ .xor, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 6, .none },
504 .{ .xor, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },504 .{ .xor, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },
505 .{ .xor, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },505 .{ .xor, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },
506 .{ .xor, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 6, .long },506 .{ .xor, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 6, .long },
507 .{ .xor, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },507 .{ .xor, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },
508 .{ .xor, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },508 .{ .xor, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },
509 .{ .xor, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 6, .long },509 .{ .xor, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .long },
510 .{ .xor, .mr, .rm8, .r8, .none, .none, 1, 0x30, 0x00, 0x00, 0, .none },510 .{ .xor, .mr, .rm8, .r8, .none, .none, 1, 0x30, 0x00, 0x00, 0, .none },
511 .{ .xor, .mr, .rm16, .r16, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },511 .{ .xor, .mr, .rm16, .r16, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },
512 .{ .xor, .mr, .rm32, .r32, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },512 .{ .xor, .mr, .rm32, .r32, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },
513 .{ .xor, .mr, .rm64, .r64, .none, .none, 1, 0x31, 0x00, 0x00, 0, .long },513 .{ .xor, .mr, .rm64, .r64, .none, .none, 1, 0x31, 0x00, 0x00, 0, .long },
514 .{ .xor, .rm, .r8, .rm8, .none, .none, 1, 0x32, 0x00, 0x00, 0, .none },514 .{ .xor, .rm, .r8, .rm8, .none, .none, 1, 0x32, 0x00, 0x00, 0, .none },
515 .{ .xor, .rm, .r16, .rm16, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },515 .{ .xor, .rm, .r16, .rm16, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },
516 .{ .xor, .rm, .r32, .rm32, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },516 .{ .xor, .rm, .r32, .rm32, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },
517 .{ .xor, .rm, .r64, .rm64, .none, .none, 1, 0x33, 0x00, 0x00, 0, .long },517 .{ .xor, .rm, .r64, .rm64, .none, .none, 1, 0x33, 0x00, 0x00, 0, .long },
518518
519 // SSE519 // SSE
520 .{ .addss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x58, 0, .sse },520 .{ .addss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x58, 0, .sse },
...@@ -540,3 +540,4 @@ pub const table = &[_]Entry{...@@ -540,3 +540,4 @@ pub const table = &[_]Entry{
540 .{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0x66, 0x0f, 0x2e, 0, .sse2 },540 .{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0x66, 0x0f, 0x2e, 0, .sse2 },
541};541};
542// zig fmt: on542// zig fmt: on
543