| ... | @@ -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 integer | 42 | /// 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 | }; |
| 46 | | 51 | |
| 47 | pub const Result = union(enum) { | 52 | pub 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 { |
| 653 | | 658 | |
| 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 | }; |
| 2021 | | 2046 | |
| ... | @@ -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 | } |
| 2230 | | 2268 | |
| ... | @@ -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 undefined | 2316 | // 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; |