stage2 AArch64: remove MIR load_memory instruction

This instruction now just represents loading from a hard-coded adrress
after extracting the other use cases for load_memory into load_got and
load_direct.
This commit is contained in:
joachimschmidt557 2022-02-23 12:39:58 +01:00
parent acec06cfaf
commit 4683f94463
No known key found for this signature in database
GPG Key ID: E0B575BE2884ACC5
4 changed files with 20 additions and 78 deletions

View File

@ -3318,15 +3318,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
});
},
.memory => |addr| {
_ = try self.addInst(.{
.tag = .load_memory,
.data = .{
.load_memory = .{
.register = @enumToInt(reg),
.addr = @intCast(u32, addr),
},
},
});
// The value is in memory at a hard-coded address.
// If the type is a pointer, it means the pointer address is at this memory location.
try self.genSetReg(ty, reg, .{ .immediate = addr });
try self.genLdrRegister(reg, reg, ty.abiSize(self.target.*));
},
.stack_offset => |unadjusted_off| {
const abi_size = ty.abiSize(self.target.*);

View File

@ -108,7 +108,6 @@ pub fn emitMir(
.eor_shifted_register => try emit.mirLogicalShiftedRegister(inst),
.load_memory => try emit.mirLoadMemory(inst),
.load_memory_got => try emit.mirLoadMemoryPie(inst),
.load_memory_direct => try emit.mirLoadMemoryPie(inst),
@ -210,16 +209,6 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {
.load_memory_got,
.load_memory_direct,
=> return 2 * 4,
.load_memory => {
const load_memory = emit.mir.instructions.items(.data)[inst].load_memory;
const addr = load_memory.addr;
// movz, [movk, ...], ldr
if (addr <= math.maxInt(u16)) return 2 * 4;
if (addr <= math.maxInt(u32)) return 3 * 4;
if (addr <= math.maxInt(u48)) return 4 * 4;
return 5 * 4;
},
.pop_regs, .push_regs => {
const reg_list = emit.mir.instructions.items(.data)[inst].reg_list;
const number_of_regs = @popCount(u32, reg_list);
@ -655,21 +644,6 @@ fn mirLogicalShiftedRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
}
}
fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
assert(emit.mir.instructions.items(.tag)[inst] == .load_memory);
const load_memory = emit.mir.instructions.items(.data)[inst].load_memory;
const reg = @intToEnum(Register, load_memory.register);
const addr = load_memory.addr;
// The value is in memory at a hard-coded address.
// If the type is a pointer, it means the pointer address is at this memory location.
try emit.moveImmediate(reg, addr);
try emit.writeInstruction(Instruction.ldr(
reg,
reg,
Instruction.LoadStoreOffset.none,
));
}
fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
const tag = emit.mir.instructions.items(.tag)[inst];
const payload = emit.mir.instructions.items(.data)[inst].payload;
@ -741,6 +715,7 @@ fn mirLoadStoreRegisterPair(emit: *Emit, inst: Mir.Inst.Index) !void {
fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
const tag = emit.mir.instructions.items(.tag)[inst];
const load_store_stack = emit.mir.instructions.items(.data)[inst].load_store_stack;
const rt = load_store_stack.rt;
const raw_offset = emit.stack_size - load_store_stack.offset;
const offset = switch (tag) {
@ -760,7 +735,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
}
},
.ldr_stack, .str_stack => blk: {
const alignment: u32 = switch (load_store_stack.rt.size()) {
const alignment: u32 = switch (rt.size()) {
32 => 4,
64 => 8,
else => unreachable,
@ -777,36 +752,12 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
};
switch (tag) {
.ldr_stack => try emit.writeInstruction(Instruction.ldr(
load_store_stack.rt,
Register.sp,
offset,
)),
.ldrb_stack => try emit.writeInstruction(Instruction.ldrb(
load_store_stack.rt,
Register.sp,
offset,
)),
.ldrh_stack => try emit.writeInstruction(Instruction.ldrh(
load_store_stack.rt,
Register.sp,
offset,
)),
.str_stack => try emit.writeInstruction(Instruction.str(
load_store_stack.rt,
Register.sp,
offset,
)),
.strb_stack => try emit.writeInstruction(Instruction.strb(
load_store_stack.rt,
Register.sp,
offset,
)),
.strh_stack => try emit.writeInstruction(Instruction.strh(
load_store_stack.rt,
Register.sp,
offset,
)),
.ldr_stack => try emit.writeInstruction(Instruction.ldr(rt, .sp, offset)),
.ldrb_stack => try emit.writeInstruction(Instruction.ldrb(rt, .sp, offset)),
.ldrh_stack => try emit.writeInstruction(Instruction.ldrh(rt, .sp, offset)),
.str_stack => try emit.writeInstruction(Instruction.str(rt, .sp, offset)),
.strb_stack => try emit.writeInstruction(Instruction.strb(rt, .sp, offset)),
.strh_stack => try emit.writeInstruction(Instruction.strh(rt, .sp, offset)),
else => unreachable,
}
}
@ -914,7 +865,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
if (count == number_of_regs - 1) {
try emit.writeInstruction(Instruction.ldr(
reg,
Register.sp,
.sp,
Instruction.LoadStoreOffset.imm_post_index(16),
));
} else {
@ -924,7 +875,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
try emit.writeInstruction(Instruction.ldp(
reg,
other_reg,
Register.sp,
.sp,
Instruction.LoadStorePairOffset.post_index(16),
));
}
@ -944,7 +895,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
if (count == number_of_regs - 1) {
try emit.writeInstruction(Instruction.str(
reg,
Register.sp,
.sp,
Instruction.LoadStoreOffset.imm_pre_index(-16),
));
} else {
@ -954,7 +905,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
try emit.writeInstruction(Instruction.stp(
other_reg,
reg,
Register.sp,
.sp,
Instruction.LoadStorePairOffset.pre_index(-16),
));
}

View File

@ -56,10 +56,6 @@ pub const Inst = struct {
dbg_line,
/// Bitwise Exclusive OR (shifted register)
eor_shifted_register,
/// Pseudo-instruction: Load memory
///
/// Payload is `load_memory`
load_memory,
/// Payload is `LoadMemoryPie`
load_memory_got,
/// Payload is `LoadMemoryPie`

View File

@ -1486,19 +1486,19 @@ test "serialize instructions" {
.expected = 0b1_00_10000_1111111111111111110_00010,
},
.{ // stp x1, x2, [sp, #8]
.inst = Instruction.stp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.signed(8)),
.inst = Instruction.stp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.signed(8)),
.expected = 0b10_101_0_010_0_0000001_00010_11111_00001,
},
.{ // ldp x1, x2, [sp, #8]
.inst = Instruction.ldp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.signed(8)),
.inst = Instruction.ldp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.signed(8)),
.expected = 0b10_101_0_010_1_0000001_00010_11111_00001,
},
.{ // stp x1, x2, [sp, #-16]!
.inst = Instruction.stp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.pre_index(-16)),
.inst = Instruction.stp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.pre_index(-16)),
.expected = 0b10_101_0_011_0_1111110_00010_11111_00001,
},
.{ // ldp x1, x2, [sp], #16
.inst = Instruction.ldp(.x1, .x2, Register.sp, Instruction.LoadStorePairOffset.post_index(16)),
.inst = Instruction.ldp(.x1, .x2, .sp, Instruction.LoadStorePairOffset.post_index(16)),
.expected = 0b10_101_0_001_1_0000010_00010_11111_00001,
},
.{ // and x0, x4, x2