aboutsummaryrefslogtreecommitdiff
path: root/src/arch/aarch64/CodeGen.zig
diff options
context:
space:
mode:
authorjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-02-08 19:57:01 +0100
committerjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-02-14 22:09:43 +0100
commitf47245865eea35fa0b08cb2a87e3620fa904dd88 (patch)
tree61995c5a806a91a2cc90cba8cd5eab40655d226b /src/arch/aarch64/CodeGen.zig
parentf598d2ae056e72bda1efb3bc7d77e8183e95e191 (diff)
downloadzig-f47245865eea35fa0b08cb2a87e3620fa904dd88.tar.gz
zig-f47245865eea35fa0b08cb2a87e3620fa904dd88.zip
stage2 AArch64: minor refactors in Mir + Emit
Diffstat (limited to 'src/arch/aarch64/CodeGen.zig')
-rw-r--r--src/arch/aarch64/CodeGen.zig79
1 files changed, 30 insertions, 49 deletions
diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig
index bd6b875550..4e14760286 100644
--- a/src/arch/aarch64/CodeGen.zig
+++ b/src/arch/aarch64/CodeGen.zig
@@ -2121,8 +2121,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
.immediate => |imm| {
_ = try self.addInst(.{
.tag = .cmp_immediate,
- .data = .{ .rr_imm12_sh = .{
- .rd = .xzr,
+ .data = .{ .r_imm12_sh = .{
.rn = lhs_mcv.register,
.imm12 = @intCast(u12, imm),
} },
@@ -2334,8 +2333,7 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
_ = try self.addInst(.{
.tag = .cmp_immediate,
- .data = .{ .rr_imm12_sh = .{
- .rd = .xzr,
+ .data = .{ .r_imm12_sh = .{
.rn = reg_mcv.register,
.imm12 = 0,
} },
@@ -2559,7 +2557,16 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
const operand_mcv = try self.resolveInst(operand);
const block_mcv = block_data.mcv;
if (block_mcv == .none) {
- block_data.mcv = operand_mcv;
+ block_data.mcv = switch (operand_mcv) {
+ .none, .dead, .unreach => unreachable,
+ .register, .stack_offset, .memory => operand_mcv,
+ .immediate => blk: {
+ const new_mcv = try self.allocRegOrMem(block, true);
+ try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);
+ break :blk new_mcv;
+ },
+ else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
+ };
} else {
try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);
}
@@ -2845,10 +2852,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
_ = try self.addInst(.{
.tag = .cset,
- .data = .{ .rrr_cond = .{
+ .data = .{ .r_cond = .{
.rd = reg,
- .rn = .xzr,
- .rm = .xzr,
.cond = condition,
} },
});
@@ -2933,7 +2938,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
} },
});
},
- 3 => return self.fail("TODO implement genSetReg types size 3", .{}),
+ 3, 5, 6, 7 => return self.fail("TODO implement genSetReg types size {}", .{abi_size}),
else => unreachable,
}
},
@@ -3114,27 +3119,6 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
}
}
-/// If the MCValue is an immediate, and it does not fit within this type,
-/// we put it in a register.
-/// A potential opportunity for future optimization here would be keeping track
-/// of the fact that the instruction is available both as an immediate
-/// and as a register.
-fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCValue {
- const mcv = try self.resolveInst(operand);
- const ti = @typeInfo(T).Int;
- switch (mcv) {
- .immediate => |imm| {
- // This immediate is unsigned.
- const U = std.meta.Int(.unsigned, ti.bits - @boolToInt(ti.signedness == .signed));
- if (imm >= math.maxInt(U)) {
- return MCValue{ .register = try self.copyToTmpRegister(Type.initTag(.usize), mcv) };
- }
- },
- else => {},
- }
- return mcv;
-}
-
fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
@@ -3248,19 +3232,11 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
}
},
.ErrorSet => {
- switch (typed_value.val.tag()) {
- .@"error" => {
- const err_name = typed_value.val.castTag(.@"error").?.data.name;
- const module = self.bin_file.options.module.?;
- const global_error_set = module.global_error_set;
- const error_index = global_error_set.get(err_name).?;
- return MCValue{ .immediate = error_index };
- },
- else => {
- // In this case we are rendering an error union which has a 0 bits payload.
- return MCValue{ .immediate = 0 };
- },
- }
+ const err_name = typed_value.val.castTag(.@"error").?.data.name;
+ const module = self.bin_file.options.module.?;
+ const global_error_set = module.global_error_set;
+ const error_index = global_error_set.get(err_name).?;
+ return MCValue{ .immediate = error_index };
},
.ErrorUnion => {
const error_type = typed_value.ty.errorUnionSet();
@@ -3425,13 +3401,18 @@ fn parseRegName(name: []const u8) ?Register {
}
fn registerAlias(reg: Register, size_bytes: u32) Register {
- _ = size_bytes;
-
- return reg;
+ if (size_bytes == 0) {
+ unreachable; // should be comptime known
+ } else if (size_bytes <= 4) {
+ return reg.to32();
+ } else if (size_bytes <= 8) {
+ return reg.to64();
+ } else {
+ unreachable; // TODO handle floating-point registers
+ }
}
-/// For most architectures this does nothing. For x86_64 it resolves any aliased registers
-/// to the 64-bit wide ones.
+/// Resolves any aliased registers to the 64-bit wide ones.
fn toCanonicalReg(reg: Register) Register {
- return reg;
+ return reg.to64();
}