authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-18 11:58:22+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-18 11:58:22+01:00
logaaa641feba8866ac38f2d06a8db2a24fa134e2f5
tree3b528f866b44275ea4762d224bdfc6263c3fd273
parent4938fb8f5ca9551b69036fdb644103ffc9ef49cf

stage2: add inline memset for x86_64 backend

* introduce new Mir tag `mov_mem_index_imm` which selects instruction of the form `OP ptr [reg + rax*1 + imm32], imm32` where the encoded flags select the appropriate ptr width for memory store operation (note that scale is fixed and set at 1)

4 files changed, 181 insertions(+), 9 deletions(-)

src/arch/x86_64/CodeGen.zig+93-2
...@@ -3148,7 +3148,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -3148,7 +3148,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
3148 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),3148 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
3149 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),3149 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
3150 8 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaaaaaaaaaa }),3150 8 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaaaaaaaaaa }),
3151 else => return self.fail("TODO implement memset", .{}),3151 else => return self.genInlineMemset(ty, stack_offset, .{ .immediate = 0xaa }),
3152 }3152 }
3153 },3153 },
3154 .compare_flags_unsigned => |op| {3154 .compare_flags_unsigned => |op| {
...@@ -3398,6 +3398,97 @@ fn genInlineMemcpy(...@@ -3398,6 +3398,97 @@ fn genInlineMemcpy(
3398 try self.performReloc(loop_reloc);3398 try self.performReloc(loop_reloc);
3399}3399}
34003400
3401fn genInlineMemset(self: *Self, ty: Type, stack_offset: u32, value: MCValue) InnerError!void {
3402 try self.register_manager.getReg(.rax, null);
3403 const abi_size = ty.abiSize(self.target.*);
3404 const adj_off = stack_offset + abi_size;
3405 if (adj_off > 128) {
3406 return self.fail("TODO inline memset with large stack offset", .{});
3407 }
3408 const negative_offset = @bitCast(u32, -@intCast(i32, adj_off));
3409
3410 // We are actually counting `abi_size` bytes; however, we reuse the index register
3411 // as both the counter and offset scaler, hence we need to subtract one from `abi_size`
3412 // and count until -1.
3413 if (abi_size > math.maxInt(i32)) {
3414 // movabs rax, abi_size - 1
3415 const payload = try self.addExtra(Mir.Imm64.encode(abi_size - 1));
3416 _ = try self.addInst(.{
3417 .tag = .movabs,
3418 .ops = (Mir.Ops{
3419 .reg1 = .rax,
3420 }).encode(),
3421 .data = .{ .payload = payload },
3422 });
3423 } else {
3424 // mov rax, abi_size - 1
3425 _ = try self.addInst(.{
3426 .tag = .mov,
3427 .ops = (Mir.Ops{
3428 .reg1 = .rax,
3429 }).encode(),
3430 .data = .{ .imm = @truncate(u32, abi_size - 1) },
3431 });
3432 }
3433
3434 // loop:
3435 // cmp rax, -1
3436 const loop_start = try self.addInst(.{
3437 .tag = .cmp,
3438 .ops = (Mir.Ops{
3439 .reg1 = .rax,
3440 }).encode(),
3441 .data = .{ .imm = @bitCast(u32, @as(i32, -1)) },
3442 });
3443
3444 // je end
3445 const loop_reloc = try self.addInst(.{
3446 .tag = .cond_jmp_eq_ne,
3447 .ops = (Mir.Ops{ .flags = 0b01 }).encode(),
3448 .data = .{ .inst = undefined },
3449 });
3450
3451 switch (value) {
3452 .immediate => |x| {
3453 if (x > math.maxInt(i32)) {
3454 return self.fail("TODO inline memset for value immediate larger than 32bits", .{});
3455 }
3456 // mov byte ptr [rbp + rax + stack_offset], imm
3457 const payload = try self.addExtra(Mir.ImmPair{
3458 .dest_off = negative_offset,
3459 .operand = @truncate(u32, x),
3460 });
3461 _ = try self.addInst(.{
3462 .tag = .mov_mem_index_imm,
3463 .ops = (Mir.Ops{
3464 .reg1 = .rbp,
3465 }).encode(),
3466 .data = .{ .payload = payload },
3467 });
3468 },
3469 else => return self.fail("TODO inline memset for value of type {}", .{value}),
3470 }
3471
3472 // sub rax, 1
3473 _ = try self.addInst(.{
3474 .tag = .sub,
3475 .ops = (Mir.Ops{
3476 .reg1 = .rax,
3477 }).encode(),
3478 .data = .{ .imm = 1 },
3479 });
3480
3481 // jmp loop
3482 _ = try self.addInst(.{
3483 .tag = .jmp,
3484 .ops = (Mir.Ops{ .flags = 0b00 }).encode(),
3485 .data = .{ .inst = loop_start },
3486 });
3487
3488 // end:
3489 try self.performReloc(loop_reloc);
3490}
3491
3401fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {3492fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
3402 switch (mcv) {3493 switch (mcv) {
3403 .dead => unreachable,3494 .dead => unreachable,
...@@ -3639,7 +3730,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -3639,7 +3730,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
3639 const stack_offset = try self.allocMem(inst, 16, 16);3730 const stack_offset = try self.allocMem(inst, 16, 16);
3640 const array_ty = ptr_ty.childType();3731 const array_ty = ptr_ty.childType();
3641 const array_len = array_ty.arrayLenIncludingSentinel();3732 const array_len = array_ty.arrayLenIncludingSentinel();
3642 try self.genSetStack(Type.initTag(.usize), stack_offset + 8, ptr);3733 try self.genSetStack(ptr_ty, stack_offset + 8, ptr);
3643 try self.genSetStack(Type.initTag(.u64), stack_offset + 16, .{ .immediate = array_len });3734 try self.genSetStack(Type.initTag(.u64), stack_offset + 16, .{ .immediate = array_len });
3644 break :blk .{ .stack_offset = stack_offset };3735 break :blk .{ .stack_offset = stack_offset };
3645 };3736 };
src/arch/x86_64/Emit.zig+33
...@@ -115,6 +115,16 @@ pub fn lowerMir(emit: *Emit) InnerError!void {...@@ -115,6 +115,16 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
115 .cmp_scale_imm => try emit.mirArithScaleImm(.cmp, inst),115 .cmp_scale_imm => try emit.mirArithScaleImm(.cmp, inst),
116 .mov_scale_imm => try emit.mirArithScaleImm(.mov, inst),116 .mov_scale_imm => try emit.mirArithScaleImm(.mov, inst),
117117
118 .adc_mem_index_imm => try emit.mirArithMemIndexImm(.adc, inst),
119 .add_mem_index_imm => try emit.mirArithMemIndexImm(.add, inst),
120 .sub_mem_index_imm => try emit.mirArithMemIndexImm(.sub, inst),
121 .xor_mem_index_imm => try emit.mirArithMemIndexImm(.xor, inst),
122 .and_mem_index_imm => try emit.mirArithMemIndexImm(.@"and", inst),
123 .or_mem_index_imm => try emit.mirArithMemIndexImm(.@"or", inst),
124 .sbb_mem_index_imm => try emit.mirArithMemIndexImm(.sbb, inst),
125 .cmp_mem_index_imm => try emit.mirArithMemIndexImm(.cmp, inst),
126 .mov_mem_index_imm => try emit.mirArithMemIndexImm(.mov, inst),
127
118 .movabs => try emit.mirMovabs(inst),128 .movabs => try emit.mirMovabs(inst),
119129
120 .lea => try emit.mirLea(inst),130 .lea => try emit.mirLea(inst),
...@@ -549,6 +559,29 @@ fn mirArithScaleImm(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void...@@ -549,6 +559,29 @@ fn mirArithScaleImm(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void
549 }), imm_pair.operand, emit.code) catch |err| emit.failWithLoweringError(err);559 }), imm_pair.operand, emit.code) catch |err| emit.failWithLoweringError(err);
550}560}
551561
562fn mirArithMemIndexImm(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
563 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
564 assert(ops.reg2 == .none);
565 const payload = emit.mir.instructions.items(.data)[inst].payload;
566 const imm_pair = emit.mir.extraData(Mir.ImmPair, payload).data;
567 const ptr_size: Memory.PtrSize = switch (ops.flags) {
568 0b00 => .byte_ptr,
569 0b01 => .word_ptr,
570 0b10 => .dword_ptr,
571 0b11 => .qword_ptr,
572 };
573 const scale_index = ScaleIndex{
574 .scale = 0,
575 .index = .rax,
576 };
577 // OP ptr [reg1 + rax*1 + imm32], imm32
578 return lowerToMiEnc(tag, RegisterOrMemory.mem(ptr_size, .{
579 .disp = imm_pair.dest_off,
580 .base = ops.reg1,
581 .scale_index = scale_index,
582 }), imm_pair.operand, emit.code) catch |err| emit.failWithLoweringError(err);
583}
584
552fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {585fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
553 const tag = emit.mir.instructions.items(.tag)[inst];586 const tag = emit.mir.instructions.items(.tag)[inst];
554 assert(tag == .movabs);587 assert(tag == .movabs);
src/arch/x86_64/Mir.zig+23
...@@ -79,6 +79,13 @@ pub const Inst = struct {...@@ -79,6 +79,13 @@ pub const Inst = struct {
79 /// * Data field `payload` points at `ImmPair`.79 /// * Data field `payload` points at `ImmPair`.
80 adc_scale_imm,80 adc_scale_imm,
8181
82 /// ops flags: form:
83 /// 0b00 byte ptr [reg1 + rax + imm32], imm8
84 /// 0b01 word ptr [reg1 + rax + imm32], imm16
85 /// 0b10 dword ptr [reg1 + rax + imm32], imm32
86 /// 0b11 qword ptr [reg1 + rax + imm32], imm32 (sign-extended to imm64)
87 adc_mem_index_imm,
88
82 // The following instructions all have the same encoding as `adc`.89 // The following instructions all have the same encoding as `adc`.
8390
84 add,91 add,
...@@ -86,81 +93,97 @@ pub const Inst = struct {...@@ -86,81 +93,97 @@ pub const Inst = struct {
86 add_scale_src,93 add_scale_src,
87 add_scale_dst,94 add_scale_dst,
88 add_scale_imm,95 add_scale_imm,
96 add_mem_index_imm,
89 sub,97 sub,
90 sub_mem_imm,98 sub_mem_imm,
91 sub_scale_src,99 sub_scale_src,
92 sub_scale_dst,100 sub_scale_dst,
93 sub_scale_imm,101 sub_scale_imm,
102 sub_mem_index_imm,
94 xor,103 xor,
95 xor_mem_imm,104 xor_mem_imm,
96 xor_scale_src,105 xor_scale_src,
97 xor_scale_dst,106 xor_scale_dst,
98 xor_scale_imm,107 xor_scale_imm,
108 xor_mem_index_imm,
99 @"and",109 @"and",
100 and_mem_imm,110 and_mem_imm,
101 and_scale_src,111 and_scale_src,
102 and_scale_dst,112 and_scale_dst,
103 and_scale_imm,113 and_scale_imm,
114 and_mem_index_imm,
104 @"or",115 @"or",
105 or_mem_imm,116 or_mem_imm,
106 or_scale_src,117 or_scale_src,
107 or_scale_dst,118 or_scale_dst,
108 or_scale_imm,119 or_scale_imm,
120 or_mem_index_imm,
109 rol,121 rol,
110 rol_mem_imm,122 rol_mem_imm,
111 rol_scale_src,123 rol_scale_src,
112 rol_scale_dst,124 rol_scale_dst,
113 rol_scale_imm,125 rol_scale_imm,
126 rol_mem_index_imm,
114 ror,127 ror,
115 ror_mem_imm,128 ror_mem_imm,
116 ror_scale_src,129 ror_scale_src,
117 ror_scale_dst,130 ror_scale_dst,
118 ror_scale_imm,131 ror_scale_imm,
132 ror_mem_index_imm,
119 rcl,133 rcl,
120 rcl_mem_imm,134 rcl_mem_imm,
121 rcl_scale_src,135 rcl_scale_src,
122 rcl_scale_dst,136 rcl_scale_dst,
123 rcl_scale_imm,137 rcl_scale_imm,
138 rcl_mem_index_imm,
124 rcr,139 rcr,
125 rcr_mem_imm,140 rcr_mem_imm,
126 rcr_scale_src,141 rcr_scale_src,
127 rcr_scale_dst,142 rcr_scale_dst,
128 rcr_scale_imm,143 rcr_scale_imm,
144 rcr_mem_index_imm,
129 shl,145 shl,
130 shl_mem_imm,146 shl_mem_imm,
131 shl_scale_src,147 shl_scale_src,
132 shl_scale_dst,148 shl_scale_dst,
133 shl_scale_imm,149 shl_scale_imm,
150 shl_mem_index_imm,
134 sal,151 sal,
135 sal_mem_imm,152 sal_mem_imm,
136 sal_scale_src,153 sal_scale_src,
137 sal_scale_dst,154 sal_scale_dst,
138 sal_scale_imm,155 sal_scale_imm,
156 sal_mem_index_imm,
139 shr,157 shr,
140 shr_mem_imm,158 shr_mem_imm,
141 shr_scale_src,159 shr_scale_src,
142 shr_scale_dst,160 shr_scale_dst,
143 shr_scale_imm,161 shr_scale_imm,
162 shr_mem_index_imm,
144 sar,163 sar,
145 sar_mem_imm,164 sar_mem_imm,
146 sar_scale_src,165 sar_scale_src,
147 sar_scale_dst,166 sar_scale_dst,
148 sar_scale_imm,167 sar_scale_imm,
168 sar_mem_index_imm,
149 sbb,169 sbb,
150 sbb_mem_imm,170 sbb_mem_imm,
151 sbb_scale_src,171 sbb_scale_src,
152 sbb_scale_dst,172 sbb_scale_dst,
153 sbb_scale_imm,173 sbb_scale_imm,
174 sbb_mem_index_imm,
154 cmp,175 cmp,
155 cmp_mem_imm,176 cmp_mem_imm,
156 cmp_scale_src,177 cmp_scale_src,
157 cmp_scale_dst,178 cmp_scale_dst,
158 cmp_scale_imm,179 cmp_scale_imm,
180 cmp_mem_index_imm,
159 mov,181 mov,
160 mov_mem_imm,182 mov_mem_imm,
161 mov_scale_src,183 mov_scale_src,
162 mov_scale_dst,184 mov_scale_dst,
163 mov_scale_imm,185 mov_scale_imm,
186 mov_mem_index_imm,
164187
165 /// ops flags: form:188 /// ops flags: form:
166 /// 0b00 reg1, [reg2 + imm32]189 /// 0b00 reg1, [reg2 + imm32]
src/arch/x86_64/PrintMir.zig+32-7
...@@ -64,6 +64,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap...@@ -64,6 +64,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
64 .@"or" => try print.mirArith(.@"or", inst, w),64 .@"or" => try print.mirArith(.@"or", inst, w),
65 .sbb => try print.mirArith(.sbb, inst, w),65 .sbb => try print.mirArith(.sbb, inst, w),
66 .cmp => try print.mirArith(.cmp, inst, w),66 .cmp => try print.mirArith(.cmp, inst, w),
67 .mov => try print.mirArith(.mov, inst, w),
6768
68 .adc_mem_imm => try print.mirArithMemImm(.adc, inst, w),69 .adc_mem_imm => try print.mirArithMemImm(.adc, inst, w),
69 .add_mem_imm => try print.mirArithMemImm(.add, inst, w),70 .add_mem_imm => try print.mirArithMemImm(.add, inst, w),
...@@ -73,6 +74,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap...@@ -73,6 +74,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
73 .or_mem_imm => try print.mirArithMemImm(.@"or", inst, w),74 .or_mem_imm => try print.mirArithMemImm(.@"or", inst, w),
74 .sbb_mem_imm => try print.mirArithMemImm(.sbb, inst, w),75 .sbb_mem_imm => try print.mirArithMemImm(.sbb, inst, w),
75 .cmp_mem_imm => try print.mirArithMemImm(.cmp, inst, w),76 .cmp_mem_imm => try print.mirArithMemImm(.cmp, inst, w),
77 .mov_mem_imm => try print.mirArithMemImm(.mov, inst, w),
7678
77 .adc_scale_src => try print.mirArithScaleSrc(.adc, inst, w),79 .adc_scale_src => try print.mirArithScaleSrc(.adc, inst, w),
78 .add_scale_src => try print.mirArithScaleSrc(.add, inst, w),80 .add_scale_src => try print.mirArithScaleSrc(.add, inst, w),
...@@ -82,6 +84,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap...@@ -82,6 +84,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
82 .or_scale_src => try print.mirArithScaleSrc(.@"or", inst, w),84 .or_scale_src => try print.mirArithScaleSrc(.@"or", inst, w),
83 .sbb_scale_src => try print.mirArithScaleSrc(.sbb, inst, w),85 .sbb_scale_src => try print.mirArithScaleSrc(.sbb, inst, w),
84 .cmp_scale_src => try print.mirArithScaleSrc(.cmp, inst, w),86 .cmp_scale_src => try print.mirArithScaleSrc(.cmp, inst, w),
87 .mov_scale_src => try print.mirArithScaleSrc(.mov, inst, w),
8588
86 .adc_scale_dst => try print.mirArithScaleDst(.adc, inst, w),89 .adc_scale_dst => try print.mirArithScaleDst(.adc, inst, w),
87 .add_scale_dst => try print.mirArithScaleDst(.add, inst, w),90 .add_scale_dst => try print.mirArithScaleDst(.add, inst, w),
...@@ -91,6 +94,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap...@@ -91,6 +94,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
91 .or_scale_dst => try print.mirArithScaleDst(.@"or", inst, w),94 .or_scale_dst => try print.mirArithScaleDst(.@"or", inst, w),
92 .sbb_scale_dst => try print.mirArithScaleDst(.sbb, inst, w),95 .sbb_scale_dst => try print.mirArithScaleDst(.sbb, inst, w),
93 .cmp_scale_dst => try print.mirArithScaleDst(.cmp, inst, w),96 .cmp_scale_dst => try print.mirArithScaleDst(.cmp, inst, w),
97 .mov_scale_dst => try print.mirArithScaleDst(.mov, inst, w),
9498
95 .adc_scale_imm => try print.mirArithScaleImm(.adc, inst, w),99 .adc_scale_imm => try print.mirArithScaleImm(.adc, inst, w),
96 .add_scale_imm => try print.mirArithScaleImm(.add, inst, w),100 .add_scale_imm => try print.mirArithScaleImm(.add, inst, w),
...@@ -100,11 +104,18 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap...@@ -100,11 +104,18 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
100 .or_scale_imm => try print.mirArithScaleImm(.@"or", inst, w),104 .or_scale_imm => try print.mirArithScaleImm(.@"or", inst, w),
101 .sbb_scale_imm => try print.mirArithScaleImm(.sbb, inst, w),105 .sbb_scale_imm => try print.mirArithScaleImm(.sbb, inst, w),
102 .cmp_scale_imm => try print.mirArithScaleImm(.cmp, inst, w),106 .cmp_scale_imm => try print.mirArithScaleImm(.cmp, inst, w),
103
104 .mov => try print.mirArith(.mov, inst, w),
105 .mov_scale_src => try print.mirArithScaleSrc(.mov, inst, w),
106 .mov_scale_dst => try print.mirArithScaleDst(.mov, inst, w),
107 .mov_scale_imm => try print.mirArithScaleImm(.mov, inst, w),107 .mov_scale_imm => try print.mirArithScaleImm(.mov, inst, w),
108
109 .adc_mem_index_imm => try print.mirArithMemIndexImm(.adc, inst, w),
110 .add_mem_index_imm => try print.mirArithMemIndexImm(.add, inst, w),
111 .sub_mem_index_imm => try print.mirArithMemIndexImm(.sub, inst, w),
112 .xor_mem_index_imm => try print.mirArithMemIndexImm(.xor, inst, w),
113 .and_mem_index_imm => try print.mirArithMemIndexImm(.@"and", inst, w),
114 .or_mem_index_imm => try print.mirArithMemIndexImm(.@"or", inst, w),
115 .sbb_mem_index_imm => try print.mirArithMemIndexImm(.sbb, inst, w),
116 .cmp_mem_index_imm => try print.mirArithMemIndexImm(.cmp, inst, w),
117 .mov_mem_index_imm => try print.mirArithMemIndexImm(.mov, inst, w),
118
108 .movabs => try print.mirMovabs(inst, w),119 .movabs => try print.mirMovabs(inst, w),
109120
110 .lea => try print.mirLea(inst, w),121 .lea => try print.mirLea(inst, w),
...@@ -316,11 +327,11 @@ fn mirArithScaleDst(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index...@@ -316,11 +327,11 @@ fn mirArithScaleDst(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index
316327
317 if (ops.reg2 == .none) {328 if (ops.reg2 == .none) {
318 // OP [reg1 + scale*rax + 0], imm32329 // OP [reg1 + scale*rax + 0], imm32
319 try w.print("{s} [{s} + {d}*rcx + 0], {d}\n", .{ @tagName(tag), @tagName(ops.reg1), scale, imm });330 try w.print("{s} [{s} + {d}*rax + 0], {d}\n", .{ @tagName(tag), @tagName(ops.reg1), scale, imm });
320 }331 }
321332
322 // OP [reg1 + scale*rax + imm32], reg2333 // OP [reg1 + scale*rax + imm32], reg2
323 try w.print("{s} [{s} + {d}*rcx + {d}], {s}\n", .{ @tagName(tag), @tagName(ops.reg1), scale, imm, @tagName(ops.reg2) });334 try w.print("{s} [{s} + {d}*rax + {d}], {s}\n", .{ @tagName(tag), @tagName(ops.reg1), scale, imm, @tagName(ops.reg2) });
324}335}
325336
326fn mirArithScaleImm(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index, w: anytype) !void {337fn mirArithScaleImm(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index, w: anytype) !void {
...@@ -328,7 +339,21 @@ fn mirArithScaleImm(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index...@@ -328,7 +339,21 @@ fn mirArithScaleImm(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index
328 const scale = ops.flags;339 const scale = ops.flags;
329 const payload = print.mir.instructions.items(.data)[inst].payload;340 const payload = print.mir.instructions.items(.data)[inst].payload;
330 const imm_pair = print.mir.extraData(Mir.ImmPair, payload).data;341 const imm_pair = print.mir.extraData(Mir.ImmPair, payload).data;
331 try w.print("{s} [{s} + {d}*rcx + {d}], {d}\n", .{ @tagName(tag), @tagName(ops.reg1), scale, imm_pair.dest_off, imm_pair.operand });342 try w.print("{s} [{s} + {d}*rax + {d}], {d}\n", .{ @tagName(tag), @tagName(ops.reg1), scale, imm_pair.dest_off, imm_pair.operand });
343}
344
345fn mirArithMemIndexImm(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index, w: anytype) !void {
346 const ops = Mir.Ops.decode(print.mir.instructions.items(.ops)[inst]);
347 const payload = print.mir.instructions.items(.data)[inst].payload;
348 const imm_pair = print.mir.extraData(Mir.ImmPair, payload).data;
349 try w.print("{s} ", .{@tagName(tag)});
350 switch (ops.flags) {
351 0b00 => try w.print("byte ptr ", .{}),
352 0b01 => try w.print("word ptr ", .{}),
353 0b10 => try w.print("dword ptr ", .{}),
354 0b11 => try w.print("qword ptr ", .{}),
355 }
356 try w.print("[{s} + 1*rax + {d}], {d}\n", .{ @tagName(ops.reg1), imm_pair.dest_off, imm_pair.operand });
332}357}
333358
334fn mirMovabs(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void {359fn mirMovabs(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void {