mirror of
https://github.com/ziglang/zig.git
synced 2025-12-30 01:53:16 +00:00
stage2: add separate tag for MI encoding
To request memory-immediate encoding at the MIR side, we should now use a new tag such as `mov_mem_imm` where the size of the memory pointer is encoded as the flags: ``` 0b00 => .byte_ptr, 0b01 => .word_ptr, 0b10 => .dword_ptr, 0b11 => .qword_ptr, ```
This commit is contained in:
parent
be5130ec53
commit
08ea1a2eab
@ -1646,7 +1646,7 @@ fn genBinMathOpMir(
|
||||
_ = try self.addInst(.{
|
||||
.tag = mir_tag,
|
||||
.ops = (Mir.Ops{
|
||||
.reg1 = registerAlias(dst_reg, 4),
|
||||
.reg1 = dst_reg.to32(),
|
||||
}).encode(),
|
||||
.data = .{ .imm = @intCast(i32, imm) },
|
||||
});
|
||||
@ -2807,10 +2807,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
|
||||
.operand = @bitCast(i32, @intCast(u32, x_big)),
|
||||
});
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov,
|
||||
.tag = .mov_mem_imm,
|
||||
.ops = (Mir.Ops{
|
||||
.reg1 = .rbp,
|
||||
.flags = 0b11,
|
||||
.flags = 0b10,
|
||||
}).encode(),
|
||||
.data = .{ .payload = payload },
|
||||
});
|
||||
@ -2828,10 +2828,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
|
||||
.operand = @bitCast(i32, @truncate(u32, x_big >> 32)),
|
||||
});
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov,
|
||||
.tag = .mov_mem_imm,
|
||||
.ops = (Mir.Ops{
|
||||
.reg1 = .rbp,
|
||||
.flags = 0b11,
|
||||
.flags = 0b10,
|
||||
}).encode(),
|
||||
.data = .{ .payload = payload },
|
||||
});
|
||||
@ -2842,10 +2842,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
|
||||
.operand = @bitCast(i32, @truncate(u32, x_big)),
|
||||
});
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov,
|
||||
.tag = .mov_mem_imm,
|
||||
.ops = (Mir.Ops{
|
||||
.reg1 = .rbp,
|
||||
.flags = 0b11,
|
||||
.flags = 0b10,
|
||||
}).encode(),
|
||||
.data = .{ .payload = payload },
|
||||
});
|
||||
@ -2955,11 +2955,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
}
|
||||
if (x <= math.maxInt(i32)) {
|
||||
// Next best case: if we set the lower four bytes, the upper four will be zeroed.
|
||||
// TODO I am not quite sure why we need to set the size of the register here...
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov,
|
||||
.ops = (Mir.Ops{
|
||||
.reg1 = registerAlias(reg, 4),
|
||||
.reg1 = reg.to32(),
|
||||
}).encode(),
|
||||
.data = .{ .imm = @intCast(i32, x) },
|
||||
});
|
||||
@ -2985,9 +2984,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
// We need the offset from RIP in a signed i32 twos complement.
|
||||
const payload = try self.addExtra(Mir.Imm64.encode(code_offset));
|
||||
_ = try self.addInst(.{
|
||||
.tag = .lea_rip,
|
||||
.tag = .lea,
|
||||
.ops = (Mir.Ops{
|
||||
.reg1 = reg,
|
||||
.flags = 0b01,
|
||||
}).encode(),
|
||||
.data = .{ .payload = payload },
|
||||
});
|
||||
@ -3011,10 +3011,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
if (self.bin_file.options.pie) {
|
||||
// TODO we should flag up `x` as GOT symbol entry explicitly rather than as a hack.
|
||||
_ = try self.addInst(.{
|
||||
.tag = .lea_rip,
|
||||
.tag = .lea,
|
||||
.ops = (Mir.Ops{
|
||||
.reg1 = reg,
|
||||
.flags = 0b01,
|
||||
.flags = 0b10,
|
||||
}).encode(),
|
||||
.data = .{ .got_entry = @intCast(u32, x) },
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -38,13 +38,18 @@ pub const Inst = struct {
|
||||
/// 0b01 reg1, [reg2 + imm32]
|
||||
/// 0b01 reg1, [ds:imm32]
|
||||
/// 0b10 [reg1 + imm32], reg2
|
||||
/// 0b10 [reg1 + 0], imm32
|
||||
/// 0b11 [reg1 + imm32], imm32
|
||||
/// Notes:
|
||||
/// * If reg2 is `none` then it means Data field `imm` is used as the immediate.
|
||||
/// * When two imm32 values are required, Data field `payload` points at `ImmPair`.
|
||||
adc,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 byte ptr [reg1 + imm32], imm8
|
||||
/// 0b01 word ptr [reg1 + imm32], imm16
|
||||
/// 0b10 dword ptr [reg1 + imm32], imm32
|
||||
/// 0b11 qword ptr [reg1 + imm32], imm32 (sign-extended to imm64)
|
||||
adc_mem_imm,
|
||||
|
||||
/// form: reg1, [reg2 + scale*rcx + imm32]
|
||||
/// ops flags scale
|
||||
/// 0b00 1
|
||||
@ -77,74 +82,95 @@ pub const Inst = struct {
|
||||
// The following instructions all have the same encoding as `adc`.
|
||||
|
||||
add,
|
||||
add_mem_imm,
|
||||
add_scale_src,
|
||||
add_scale_dst,
|
||||
add_scale_imm,
|
||||
sub,
|
||||
sub_mem_imm,
|
||||
sub_scale_src,
|
||||
sub_scale_dst,
|
||||
sub_scale_imm,
|
||||
xor,
|
||||
xor_mem_imm,
|
||||
xor_scale_src,
|
||||
xor_scale_dst,
|
||||
xor_scale_imm,
|
||||
@"and",
|
||||
and_mem_imm,
|
||||
and_scale_src,
|
||||
and_scale_dst,
|
||||
and_scale_imm,
|
||||
@"or",
|
||||
or_mem_imm,
|
||||
or_scale_src,
|
||||
or_scale_dst,
|
||||
or_scale_imm,
|
||||
rol,
|
||||
rol_mem_imm,
|
||||
rol_scale_src,
|
||||
rol_scale_dst,
|
||||
rol_scale_imm,
|
||||
ror,
|
||||
ror_mem_imm,
|
||||
ror_scale_src,
|
||||
ror_scale_dst,
|
||||
ror_scale_imm,
|
||||
rcl,
|
||||
rcl_mem_imm,
|
||||
rcl_scale_src,
|
||||
rcl_scale_dst,
|
||||
rcl_scale_imm,
|
||||
rcr,
|
||||
rcr_mem_imm,
|
||||
rcr_scale_src,
|
||||
rcr_scale_dst,
|
||||
rcr_scale_imm,
|
||||
shl,
|
||||
shl_mem_imm,
|
||||
shl_scale_src,
|
||||
shl_scale_dst,
|
||||
shl_scale_imm,
|
||||
sal,
|
||||
sal_mem_imm,
|
||||
sal_scale_src,
|
||||
sal_scale_dst,
|
||||
sal_scale_imm,
|
||||
shr,
|
||||
shr_mem_imm,
|
||||
shr_scale_src,
|
||||
shr_scale_dst,
|
||||
shr_scale_imm,
|
||||
sar,
|
||||
sar_mem_imm,
|
||||
sar_scale_src,
|
||||
sar_scale_dst,
|
||||
sar_scale_imm,
|
||||
sbb,
|
||||
sbb_mem_imm,
|
||||
sbb_scale_src,
|
||||
sbb_scale_dst,
|
||||
sbb_scale_imm,
|
||||
cmp,
|
||||
cmp_mem_imm,
|
||||
cmp_scale_src,
|
||||
cmp_scale_dst,
|
||||
cmp_scale_imm,
|
||||
mov,
|
||||
mov_mem_imm,
|
||||
mov_scale_src,
|
||||
mov_scale_dst,
|
||||
mov_scale_imm,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, [reg2 + imm32]
|
||||
/// 0b00 reg1, [ds:imm32]
|
||||
/// 0b01 reg1, [rip + imm32]
|
||||
/// 0b10 reg1, [rip + reloc]
|
||||
/// Notes:
|
||||
/// * if flags are 0b10, `Data` contains `got_entry` for the linker to generate
|
||||
/// a valid relocation for.
|
||||
lea,
|
||||
lea_scale_src,
|
||||
lea_scale_dst,
|
||||
lea_scale_imm,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0bX0 reg1
|
||||
@ -160,15 +186,6 @@ pub const Inst = struct {
|
||||
/// 0b11 reg1, [reg2 + imm32], imm32
|
||||
imul_complex,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0bX0 reg1, [rip + imm32]
|
||||
/// 0bX1 reg1, [rip + reloc]
|
||||
/// Notes:
|
||||
/// * if flags are 0bX1, `Data` contains `got_entry` for linker to generate
|
||||
/// valid relocation for.
|
||||
/// TODO handle more cases
|
||||
lea_rip,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0bX0 reg1, imm64
|
||||
/// 0bX1 rax, moffs64
|
||||
@ -233,16 +250,8 @@ pub const Inst = struct {
|
||||
syscall,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg2
|
||||
/// 0b00 reg1, imm32
|
||||
/// 0b01 reg1, [reg2 + imm32]
|
||||
/// 0b01 reg1, [ds:imm32]
|
||||
/// 0b10 [reg1 + imm32], reg2
|
||||
/// 0b10 [reg1 + 0], imm32
|
||||
/// 0b11 [reg1 + imm32], imm32
|
||||
/// Notes:
|
||||
/// * If reg2 is `none` then it means Data field `imm` is used as the immediate.
|
||||
/// * When two imm32 values are required, Data field `payload` points at `ImmPair`.
|
||||
/// TODO handle more cases
|
||||
@"test",
|
||||
|
||||
/// Breakpoint
|
||||
|
||||
@ -64,6 +64,15 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
|
||||
.sbb => try print.mirArith(.sbb, inst, w),
|
||||
.cmp => try print.mirArith(.cmp, inst, w),
|
||||
|
||||
.adc_mem_imm => try print.mirArithMemImm(.adc, inst, w),
|
||||
.add_mem_imm => try print.mirArithMemImm(.add, inst, w),
|
||||
.sub_mem_imm => try print.mirArithMemImm(.sub, inst, w),
|
||||
.xor_mem_imm => try print.mirArithMemImm(.xor, inst, w),
|
||||
.and_mem_imm => try print.mirArithMemImm(.@"and", inst, w),
|
||||
.or_mem_imm => try print.mirArithMemImm(.@"or", inst, w),
|
||||
.sbb_mem_imm => try print.mirArithMemImm(.sbb, inst, w),
|
||||
.cmp_mem_imm => try print.mirArithMemImm(.cmp, inst, w),
|
||||
|
||||
.adc_scale_src => try print.mirArithScaleSrc(.adc, inst, w),
|
||||
.add_scale_src => try print.mirArithScaleSrc(.add, inst, w),
|
||||
.sub_scale_src => try print.mirArithScaleSrc(.sub, inst, w),
|
||||
@ -98,7 +107,6 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
|
||||
.movabs => try print.mirMovabs(inst, w),
|
||||
|
||||
.lea => try print.mirLea(inst, w),
|
||||
.lea_rip => try print.mirLeaRip(inst, w),
|
||||
|
||||
.imul_complex => try print.mirIMulComplex(inst, w),
|
||||
|
||||
@ -490,6 +498,13 @@ fn mirArith(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index, w: any
|
||||
try w.writeByte('\n');
|
||||
}
|
||||
|
||||
fn mirArithMemImm(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index, w: anytype) !void {
|
||||
_ = print;
|
||||
_ = tag;
|
||||
_ = inst;
|
||||
return w.writeAll("TODO mirArithMemImm\n");
|
||||
}
|
||||
|
||||
fn mirArithScaleSrc(print: *const Print, tag: Mir.Inst.Tag, inst: Mir.Inst.Index, w: anytype) !void {
|
||||
const ops = Mir.Ops.decode(print.mir.instructions.items(.ops)[inst]);
|
||||
const scale = ops.flags;
|
||||
@ -560,19 +575,16 @@ fn mirIMulComplex(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void {
|
||||
}
|
||||
|
||||
fn mirLea(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void {
|
||||
const tag = print.mir.instructions.items(.tag)[inst];
|
||||
assert(tag == .lea);
|
||||
const ops = Mir.Ops.decode(print.mir.instructions.items(.ops)[inst]);
|
||||
assert(ops.flags == 0b01);
|
||||
const imm = print.mir.instructions.items(.data)[inst].imm;
|
||||
|
||||
try w.print("lea {s} [{s} + {d}]\n", .{ @tagName(ops.reg1), @tagName(ops.reg2), imm });
|
||||
}
|
||||
|
||||
fn mirLeaRip(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void {
|
||||
_ = print;
|
||||
_ = inst;
|
||||
return w.writeAll("TODO lea_rip\n");
|
||||
return w.writeAll("TODO lea\n");
|
||||
// const tag = print.mir.instructions.items(.tag)[inst];
|
||||
// assert(tag == .lea);
|
||||
// const ops = Mir.Ops.decode(print.mir.instructions.items(.ops)[inst]);
|
||||
// assert(ops.flags == 0b01);
|
||||
// const imm = print.mir.instructions.items(.data)[inst].imm;
|
||||
|
||||
// try w.print("lea {s} [{s} + {d}]\n", .{ @tagName(ops.reg1), @tagName(ops.reg2), imm });
|
||||
}
|
||||
|
||||
fn mirCallExtern(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user