| ... | @@ -385,6 +385,24 @@ pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 { | ... | @@ -385,6 +385,24 @@ pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 { |
| 385 | return self.addExtraAssumeCapacity(extra); | 385 | return self.addExtraAssumeCapacity(extra); |
| 386 | } | 386 | } |
| 387 | | 387 | |
| | 388 | fn extraData(self: *Self, comptime T: type, index: u32) struct { data: T, end: u32 } { |
| | 389 | const fields = std.meta.fields(T); |
| | 390 | var i: u32 = index; |
| | 391 | var result: T = undefined; |
| | 392 | inline for (fields) |field| { |
| | 393 | @field(result, field.name) = switch (field.type) { |
| | 394 | u32 => self.mir_extra.items[i], |
| | 395 | i32 => @bitCast(i32, self.mir_extra.items[i]), |
| | 396 | else => @compileError("bad field type"), |
| | 397 | }; |
| | 398 | i += 1; |
| | 399 | } |
| | 400 | return .{ |
| | 401 | .data = result, |
| | 402 | .end = i, |
| | 403 | }; |
| | 404 | } |
| | 405 | |
| 388 | pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | 406 | pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 389 | const fields = std.meta.fields(@TypeOf(extra)); | 407 | const fields = std.meta.fields(@TypeOf(extra)); |
| 390 | const result = @intCast(u32, self.mir_extra.items.len); | 408 | const result = @intCast(u32, self.mir_extra.items.len); |
| ... | @@ -2759,9 +2777,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2759,9 +2777,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2759 | 1, 2, 4 => { | 2777 | 1, 2, 4 => { |
| 2760 | // TODO this is wasteful! | 2778 | // TODO this is wasteful! |
| 2761 | // introduce new MIR tag specifically for mov [reg + 0], imm | 2779 | // 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 | }; |
| 2762 | const payload = try self.addExtra(Mir.ImmPair{ | 2786 | const payload = try self.addExtra(Mir.ImmPair{ |
| 2763 | .dest_off = 0, | 2787 | .dest_off = 0, |
| 2764 | .operand = @truncate(u32, imm), | 2788 | .operand = operand, |
| 2765 | }); | 2789 | }); |
| 2766 | _ = try self.addInst(.{ | 2790 | _ = try self.addInst(.{ |
| 2767 | .tag = .mov_mem_imm, | 2791 | .tag = .mov_mem_imm, |
| ... | @@ -2872,10 +2896,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2872,10 +2896,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2872 | 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}); |
| 2873 | } | 2897 | } |
| 2874 | | 2898 | |
| | 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 | }; |
| 2875 | const payload = try self.addExtra(Mir.ImmPair{ | 2906 | const payload = try self.addExtra(Mir.ImmPair{ |
| 2876 | .dest_off = 0, | 2907 | .dest_off = 0, |
| 2877 | // TODO check if this logic is correct | 2908 | // TODO check if this logic is correct |
| 2878 | .operand = @truncate(u32, imm), | 2909 | .operand = operand, |
| 2879 | }); | 2910 | }); |
| 2880 | const flags: u2 = switch (abi_size) { | 2911 | const flags: u2 = switch (abi_size) { |
| 2881 | 1 => 0b00, | 2912 | 1 => 0b00, |
| ... | @@ -3600,7 +3631,13 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3600,7 +3631,13 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3600 | _ = try self.addInst(.{ | 3631 | _ = try self.addInst(.{ |
| 3601 | .tag = mir_tag, | 3632 | .tag = mir_tag, |
| 3602 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(dst_reg, abi_size) }), | 3633 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(dst_reg, abi_size) }), |
| 3603 | .data = .{ .imm = @truncate(u32, imm) }, | 3634 | .data = .{ .imm = switch (abi_size) { |
| | 3635 | 1 => @truncate(u8, imm), |
| | 3636 | 2 => @truncate(u16, imm), |
| | 3637 | 4 => @truncate(u32, imm), |
| | 3638 | 8 => @truncate(u32, imm), |
| | 3639 | else => unreachable, |
| | 3640 | } }, |
| 3604 | }); | 3641 | }); |
| 3605 | }, | 3642 | }, |
| 3606 | .memory, | 3643 | .memory, |
| ... | @@ -3671,9 +3708,16 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3671,9 +3708,16 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3671 | 8 => 0b11, | 3708 | 8 => 0b11, |
| 3672 | else => unreachable, | 3709 | else => unreachable, |
| 3673 | }; | 3710 | }; |
| | 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 | }; |
| 3674 | const payload = try self.addExtra(Mir.ImmPair{ | 3718 | const payload = try self.addExtra(Mir.ImmPair{ |
| 3675 | .dest_off = -off, | 3719 | .dest_off = -off, |
| 3676 | .operand = @truncate(u32, imm), | 3720 | .operand = operand, |
| 3677 | }); | 3721 | }); |
| 3678 | _ = try self.addInst(.{ | 3722 | _ = try self.addInst(.{ |
| 3679 | .tag = tag, | 3723 | .tag = tag, |
| ... | @@ -4855,7 +4899,13 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u | ... | @@ -4855,7 +4899,13 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4855 | _ = try self.addInst(.{ | 4899 | _ = try self.addInst(.{ |
| 4856 | .tag = .xor, | 4900 | .tag = .xor, |
| 4857 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(cond_reg, abi_size) }), | 4901 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(cond_reg, abi_size) }), |
| 4858 | .data = .{ .imm = @intCast(u32, imm) }, | 4902 | .data = .{ .imm = switch (abi_size) { |
| | 4903 | 1 => @truncate(u8, imm), |
| | 4904 | 2 => @truncate(u16, imm), |
| | 4905 | 4 => @truncate(u32, imm), |
| | 4906 | 8 => @truncate(u32, imm), |
| | 4907 | else => unreachable, |
| | 4908 | } }, |
| 4859 | }); | 4909 | }); |
| 4860 | }, | 4910 | }, |
| 4861 | .register => |reg| { | 4911 | .register => |reg| { |
| ... | @@ -5366,20 +5416,27 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -5366,20 +5416,27 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 5366 | // We have a positive stack offset value but we want a twos complement negative | 5416 | // We have a positive stack offset value but we want a twos complement negative |
| 5367 | // offset from rbp, which is at the top of the stack frame. | 5417 | // offset from rbp, which is at the top of the stack frame. |
| 5368 | // mov [rbp+offset], immediate | 5418 | // 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) { |
| | 5426 | 1 => 0b00, |
| | 5427 | 2 => 0b01, |
| | 5428 | 4 => 0b10, |
| | 5429 | else => unreachable, |
| | 5430 | }; |
| 5369 | const payload = try self.addExtra(Mir.ImmPair{ | 5431 | const payload = try self.addExtra(Mir.ImmPair{ |
| 5370 | .dest_off = -stack_offset, | 5432 | .dest_off = -stack_offset, |
| 5371 | .operand = @truncate(u32, imm), | 5433 | .operand = operand, |
| 5372 | }); | 5434 | }); |
| 5373 | _ = try self.addInst(.{ | 5435 | _ = try self.addInst(.{ |
| 5374 | .tag = .mov_mem_imm, | 5436 | .tag = .mov_mem_imm, |
| 5375 | .ops = Mir.Inst.Ops.encode(.{ | 5437 | .ops = Mir.Inst.Ops.encode(.{ |
| 5376 | .reg1 = .rsp, | 5438 | .reg1 = .rsp, |
| 5377 | .flags = switch (abi_size) { | 5439 | .flags = flags, |
| 5378 | 1 => 0b00, | | |
| 5379 | 2 => 0b01, | | |
| 5380 | 4 => 0b10, | | |
| 5381 | else => unreachable, | | |
| 5382 | }, | | |
| 5383 | }), | 5440 | }), |
| 5384 | .data = .{ .payload = payload }, | 5441 | .data = .{ .payload = payload }, |
| 5385 | }); | 5442 | }); |
| ... | @@ -5518,7 +5575,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5518,7 +5575,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5518 | assert(ty.isError()); | 5575 | assert(ty.isError()); |
| 5519 | const payload = try self.addExtra(Mir.ImmPair{ | 5576 | const payload = try self.addExtra(Mir.ImmPair{ |
| 5520 | .dest_off = -stack_offset, | 5577 | .dest_off = -stack_offset, |
| 5521 | .operand = @truncate(u32, x_big), | 5578 | .operand = @truncate(u8, x_big), |
| 5522 | }); | 5579 | }); |
| 5523 | _ = try self.addInst(.{ | 5580 | _ = try self.addInst(.{ |
| 5524 | .tag = .mov_mem_imm, | 5581 | .tag = .mov_mem_imm, |
| ... | @@ -5530,9 +5587,15 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5530,9 +5587,15 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5530 | }); | 5587 | }); |
| 5531 | }, | 5588 | }, |
| 5532 | 1, 2, 4 => { | 5589 | 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 | }; |
| 5533 | const payload = try self.addExtra(Mir.ImmPair{ | 5596 | const payload = try self.addExtra(Mir.ImmPair{ |
| 5534 | .dest_off = -stack_offset, | 5597 | .dest_off = -stack_offset, |
| 5535 | .operand = @truncate(u32, x_big), | 5598 | .operand = operand, |
| 5536 | }); | 5599 | }); |
| 5537 | _ = try self.addInst(.{ | 5600 | _ = try self.addInst(.{ |
| 5538 | .tag = .mov_mem_imm, | 5601 | .tag = .mov_mem_imm, |
| ... | @@ -5932,7 +5995,7 @@ fn genInlineMemset( | ... | @@ -5932,7 +5995,7 @@ fn genInlineMemset( |
| 5932 | const loop_start = try self.addInst(.{ | 5995 | const loop_start = try self.addInst(.{ |
| 5933 | .tag = .cmp, | 5996 | .tag = .cmp, |
| 5934 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = index_reg }), | 5997 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = index_reg }), |
| 5935 | .data = .{ .imm = @bitCast(u32, @as(i32, -1)) }, | 5998 | .data = .{ .imm = @bitCast(u8, @as(i8, -1)) }, |
| 5936 | }); | 5999 | }); |
| 5937 | | 6000 | |
| 5938 | // je end | 6001 | // je end |
| ... | @@ -6037,7 +6100,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6037,7 +6100,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6037 | _ = try self.addInst(.{ | 6100 | _ = try self.addInst(.{ |
| 6038 | .tag = .mov, | 6101 | .tag = .mov, |
| 6039 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(reg, abi_size) }), | 6102 | .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(reg, abi_size) }), |
| 6040 | .data = .{ .imm = @truncate(u32, x) }, | 6103 | .data = .{ .imm = switch (abi_size) { |
| | 6104 | 1 => @truncate(u8, x), |
| | 6105 | 2 => @truncate(u16, x), |
| | 6106 | 4 => @truncate(u32, x), |
| | 6107 | 8 => @truncate(u32, x), |
| | 6108 | else => unreachable, |
| | 6109 | } }, |
| 6041 | }); | 6110 | }); |
| 6042 | return; | 6111 | return; |
| 6043 | } | 6112 | } |
| ... | @@ -6204,7 +6273,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6204,7 +6273,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6204 | .reg1 = registerAlias(reg, abi_size), | 6273 | .reg1 = registerAlias(reg, abi_size), |
| 6205 | .flags = 0b01, | 6274 | .flags = 0b01, |
| 6206 | }), | 6275 | }), |
| 6207 | .data = .{ .imm = @truncate(u32, x) }, | 6276 | .data = .{ .imm = switch (abi_size) { |
| | 6277 | 1 => @truncate(u8, x), |
| | 6278 | 2 => @truncate(u16, x), |
| | 6279 | 4 => @truncate(u32, x), |
| | 6280 | 8 => @truncate(u32, x), |
| | 6281 | else => unreachable, |
| | 6282 | } }, |
| 6208 | }); | 6283 | }); |
| 6209 | } else { | 6284 | } else { |
| 6210 | // If this is RAX, we can use a direct load. | 6285 | // If this is RAX, we can use a direct load. |