Commit a9154a7eaf
Changed files (2)
src
arch
aarch64
test
behavior
src/arch/aarch64/CodeGen.zig
@@ -449,7 +449,7 @@ fn gen(self: *Self) !void {
// the code. Therefore, we can just delete
// the space initially reserved for the
// jump
- self.mir_instructions.len -= 1;
+ self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.items[0]);
} else for (self.exitlude_jump_relocs.items) |jmp_reloc| {
self.mir_instructions.set(jmp_reloc, .{
.tag = .b,
@@ -1756,23 +1756,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
self.register_manager.freezeRegs(&.{addr_reg});
defer self.register_manager.unfreezeRegs(&.{addr_reg});
+ const abi_size = elem_ty.abiSize(self.target.*);
switch (dst_mcv) {
.dead => unreachable,
.undef => unreachable,
.compare_flags_signed, .compare_flags_unsigned => unreachable,
.embedded_in_code => unreachable,
.register => |dst_reg| {
- _ = try self.addInst(.{
- .tag = .ldr_immediate,
- .data = .{ .load_store_register_immediate = .{
- .rt = dst_reg,
- .rn = addr_reg,
- .offset = Instruction.LoadStoreOffset.none.immediate,
- } },
- });
+ try self.genLdrRegister(dst_reg, addr_reg, abi_size);
},
.stack_offset => |off| {
- if (elem_ty.abiSize(self.target.*) <= 8) {
+ if (abi_size <= 8) {
const tmp_reg = try self.register_manager.allocReg(null);
self.register_manager.freezeRegs(&.{tmp_reg});
defer self.register_manager.unfreezeRegs(&.{tmp_reg});
@@ -1933,6 +1927,100 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
+fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, abi_size: u64) !void {
+ switch (abi_size) {
+ 1 => {
+ _ = try self.addInst(.{
+ .tag = .ldrb_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to32(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 2 => {
+ _ = try self.addInst(.{
+ .tag = .ldrh_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to32(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 4 => {
+ _ = try self.addInst(.{
+ .tag = .ldr_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to32(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 8 => {
+ _ = try self.addInst(.{
+ .tag = .ldr_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to64(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 3, 5, 6, 7 => return self.fail("TODO: genLdrRegister for more abi_sizes", .{}),
+ else => unreachable,
+ }
+}
+
+fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, abi_size: u64) !void {
+ switch (abi_size) {
+ 1 => {
+ _ = try self.addInst(.{
+ .tag = .strb_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to32(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 2 => {
+ _ = try self.addInst(.{
+ .tag = .strh_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to32(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 4 => {
+ _ = try self.addInst(.{
+ .tag = .str_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to32(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 8 => {
+ _ = try self.addInst(.{
+ .tag = .str_immediate,
+ .data = .{ .load_store_register_immediate = .{
+ .rt = value_reg.to64(),
+ .rn = addr_reg,
+ .offset = Instruction.LoadStoreOffset.none.immediate,
+ } },
+ });
+ },
+ 3, 5, 6, 7 => return self.fail("TODO: genStrRegister for more abi_sizes", .{}),
+ else => unreachable,
+ }
+}
+
fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
switch (ptr) {
.none => unreachable,
@@ -1953,8 +2041,28 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
.embedded_in_code => {
return self.fail("TODO implement storing to MCValue.embedded_in_code", .{});
},
- .register => {
- return self.fail("TODO implement storing to MCValue.register", .{});
+ .register => |addr_reg| {
+ self.register_manager.freezeRegs(&.{addr_reg});
+ defer self.register_manager.unfreezeRegs(&.{addr_reg});
+
+ const abi_size = value_ty.abiSize(self.target.*);
+ switch (value) {
+ .register => |value_reg| {
+ try self.genStrRegister(value_reg, addr_reg, abi_size);
+ },
+ else => {
+ if (abi_size <= 8) {
+ const tmp_reg = try self.register_manager.allocReg(null);
+ self.register_manager.freezeRegs(&.{tmp_reg});
+ defer self.register_manager.unfreezeRegs(&.{tmp_reg});
+
+ try self.genSetReg(value_ty, tmp_reg, value);
+ try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty);
+ } else {
+ return self.fail("TODO implement memcpy", .{});
+ }
+ },
+ }
},
.memory,
.stack_offset,
test/behavior/basic.zig
@@ -48,7 +48,7 @@ const g1: i32 = 1233 + 1;
var g2: i32 = 0;
test "global variables" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
try expect(g2 == 0);
g2 = g1;
try expect(g2 == 1234);