stage2: merge MOV back with arith instructions

* turns out MOV and other arithmetic instructions such as ADD can
  naturally share the same lowering codepath (for the same variants)
* there are variants that are specific to ADD, or MOV which will be
  implemented as standalone MIR tags
* tweak Isel tests to generate corresponding test cases for all
  arithmetic instructions in comptime
This commit is contained in:
Jakub Konka 2021-12-20 19:38:15 +01:00
parent 71c5eebd32
commit 5156ccd552
3 changed files with 549 additions and 658 deletions

View File

@ -1608,18 +1608,18 @@ fn genBinMathOpMir(
_ = try self.addInst(.{
.tag = mir_tag,
.ops = (Mir.Ops{
.reg1 = src_reg,
.reg2 = dst_reg,
.flags = 0b11,
.reg1 = registerAlias(dst_reg, @divExact(src_reg.size(), 8)),
.reg2 = src_reg,
}).encode(),
.data = undefined,
});
},
.immediate => |imm| {
// TODO I am not quite sure why we need to set the size of the register here...
_ = try self.addInst(.{
.tag = mir_tag,
.ops = (Mir.Ops{
.reg1 = dst_reg,
.reg1 = registerAlias(dst_reg, 4),
}).encode(),
.data = .{ .imm = @intCast(i32, imm) },
});
@ -1637,7 +1637,7 @@ fn genBinMathOpMir(
.tag = mir_tag,
.ops = (Mir.Ops{
.reg1 = registerAlias(dst_reg, @intCast(u32, abi_size)),
.reg2 = registerAlias(.rbp, @intCast(u32, abi_size)),
.reg2 = .rbp,
.flags = 0b01,
}).encode(),
.data = .{ .imm = -@intCast(i32, adj_off) },
@ -1667,8 +1667,8 @@ fn genBinMathOpMir(
_ = try self.addInst(.{
.tag = mir_tag,
.ops = (Mir.Ops{
.reg1 = registerAlias(src_reg, @intCast(u32, abi_size)),
.reg2 = registerAlias(.rbp, @intCast(u32, abi_size)),
.reg1 = .rbp,
.reg2 = registerAlias(src_reg, @intCast(u32, abi_size)),
.flags = 0b10,
}).encode(),
.data = .{ .imm = -@intCast(i32, adj_off) },
@ -2924,6 +2924,7 @@ 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{

File diff suppressed because it is too large Load Diff

View File

@ -136,19 +136,6 @@ pub const Inst = struct {
cmp_scale_src,
cmp_scale_dst,
cmp_scale_imm,
/// ops flags: form:
/// 0b00 reg1, reg2 (MR)
/// 0b00 reg1, imm32
/// 0b01 reg1, [reg2 + imm32]
/// 0b01 reg1, [ds:imm32]
/// 0b10 [reg1 + imm32], reg2
/// 0b10 [reg1 + 0], imm32
/// 0b11 [reg1 + imm32], imm32
/// 0b11 AVAILABLE
/// 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`.
mov,
mov_scale_src,
mov_scale_dst,