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) {...@@ -42,6 +42,11 @@ pub const Reloc = union(enum) {
42 /// To perform the reloc, write 32-bit signed little-endian integer42 /// To perform the reloc, write 32-bit signed little-endian integer
43 /// which is a relative jump, based on the address following the reloc.43 /// which is a relative jump, based on the address following the reloc.
44 rel32: usize,44 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 },
45};50};
4651
47pub const Result = union(enum) {52pub const Result = union(enum) {
...@@ -653,7 +658,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -653,7 +658,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
653658
654 const mcv = try self.genFuncInst(inst);659 const mcv = try self.genFuncInst(inst);
655 if (!inst.isUnused()) {660 if (!inst.isUnused()) {
656 log.debug("{*} => {}", .{ inst, mcv });
657 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];661 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
658 try branch.inst_table.putNoClobber(self.gpa, inst, mcv);662 try branch.inst_table.putNoClobber(self.gpa, inst, mcv);
659 }663 }
...@@ -2016,6 +2020,27 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2016,6 +2020,27 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2016 self.code.items.len += 4;2020 self.code.items.len += 4;
2017 break :reloc reloc;2021 break :reloc reloc;
2018 },2022 },
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 },
2019 else => return self.fail(inst.base.src, "TODO implement condbr {}", .{self.target.cpu.arch}),2044 else => return self.fail(inst.base.src, "TODO implement condbr {}", .{self.target.cpu.arch}),
2020 };2045 };
20212046
...@@ -2225,6 +2250,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2225,6 +2250,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2225 return self.fail(src, "unable to perform relocation: jump too far", .{});2250 return self.fail(src, "unable to perform relocation: jump too far", .{});
2226 mem.writeIntLittle(i32, self.code.items[pos..][0..4], s32_amt);2251 mem.writeIntLittle(i32, self.code.items[pos..][0..4], s32_amt);
2227 },2252 },
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 },
2228 }2266 }
2229 }2267 }
22302268
...@@ -2278,6 +2316,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2278,6 +2316,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2278 // Leave the jump offset undefined2316 // Leave the jump offset undefined
2279 block.codegen.relocs.appendAssumeCapacity(.{ .rel32 = self.code.items.len - 4 });2317 block.codegen.relocs.appendAssumeCapacity(.{ .rel32 = self.code.items.len - 4 });
2280 },2318 },
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 },
2281 else => return self.fail(src, "TODO implement brvoid for {}", .{self.target.cpu.arch}),2328 else => return self.fail(src, "TODO implement brvoid for {}", .{self.target.cpu.arch}),
2282 }2329 }
2283 return .none;2330 return .none;