authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2020-12-27 18:56:33+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-01-01 12:22:14+01:00
log4d2919a1eed3a916f87cc5f838c9cd2b23ddef70
tree9fbbf622d1e58c8bdce697ea0c990d474ea08399
parent93bb1d93cd18e739410009e7c77048d151a93b10
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: implement genCondBr


1 files changed, 48 insertions(+), 1 deletions(-)

src/codegen.zig+48-1
......@@ -42,6 +42,11 @@ pub const Reloc = union(enum) {
4242 /// To perform the reloc, write 32-bit signed little-endian integer
4343 /// which is a relative jump, based on the address following the reloc.
4444 rel32: usize,
45 /// A branch in the ARM instruction set
46 arm_branch: struct {
47 pos: usize,
48 cond: @import("codegen/arm.zig").Condition,
49 },
4550};
4651
4752pub const Result = union(enum) {
......@@ -653,7 +658,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
653658
654659 const mcv = try self.genFuncInst(inst);
655660 if (!inst.isUnused()) {
656 log.debug("{*} => {}", .{ inst, mcv });
657661 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
658662 try branch.inst_table.putNoClobber(self.gpa, inst, mcv);
659663 }
......@@ -2016,6 +2020,27 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
20162020 self.code.items.len += 4;
20172021 break :reloc reloc;
20182022 },
2023 .arm, .armeb => reloc: {
2024 const condition: Condition = switch (cond) {
2025 .register => |reg| blk: {
2026 // cmp reg, 1
2027 // bne ...
2028 const op = Instruction.Operand.imm(1, 0);
2029 writeInt(u32, try self.code.addManyAsArray(4), Instruction.cmp(.al, reg, op).toU32());
2030 break :blk .ne;
2031 },
2032 else => return self.fail(inst.base.src, "TODO implement condbr {} when condition is {}", .{ self.target.cpu.arch, @tagName(cond) }),
2033 };
2034
2035 const reloc = Reloc{
2036 .arm_branch = .{
2037 .pos = self.code.items.len,
2038 .cond = condition,
2039 },
2040 };
2041 try self.code.resize(self.code.items.len + 4);
2042 break :reloc reloc;
2043 },
20192044 else => return self.fail(inst.base.src, "TODO implement condbr {}", .{self.target.cpu.arch}),
20202045 };
20212046
......@@ -2225,6 +2250,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
22252250 return self.fail(src, "unable to perform relocation: jump too far", .{});
22262251 mem.writeIntLittle(i32, self.code.items[pos..][0..4], s32_amt);
22272252 },
2253 .arm_branch => |info| {
2254 switch (arch) {
2255 .arm, .armeb => {
2256 const amt = self.code.items.len - (info.pos + 4);
2257 if (math.cast(i26, amt)) |delta| {
2258 writeInt(u32, self.code.items[info.pos..][0..4], Instruction.b(info.cond, delta).toU32());
2259 } else |_| {
2260 return self.fail(src, "TODO: enable larger branch offset", .{});
2261 }
2262 },
2263 else => unreachable, // attempting to perfrom an ARM relocation on a non-ARM target arch
2264 }
2265 },
22282266 }
22292267 }
22302268
......@@ -2278,6 +2316,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
22782316 // Leave the jump offset undefined
22792317 block.codegen.relocs.appendAssumeCapacity(.{ .rel32 = self.code.items.len - 4 });
22802318 },
2319 .arm, .armeb => {
2320 try self.code.resize(self.code.items.len + 4);
2321 block.codegen.relocs.appendAssumeCapacity(.{
2322 .arm_branch = .{
2323 .pos = self.code.items.len - 4,
2324 .cond = .al,
2325 },
2326 });
2327 },
22812328 else => return self.fail(src, "TODO implement brvoid for {}", .{self.target.cpu.arch}),
22822329 }
22832330 return .none;