diff options
| author | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2020-09-25 22:19:40 +0200 |
|---|---|---|
| committer | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2020-10-02 19:39:17 +0200 |
| commit | cfe486e3887ee5ea622234439fc7bd41fb2774bc (patch) | |
| tree | 7d1e7e0acd4c017bc3286027c1ce4e05f879b889 /src/codegen.zig | |
| parent | 35b228630cf1972868fe820baeb41a09801f2fbb (diff) | |
| download | zig-cfe486e3887ee5ea622234439fc7bd41fb2774bc.tar.gz zig-cfe486e3887ee5ea622234439fc7bd41fb2774bc.zip | |
stage2 ARM: Add push, pop alias instructions; non-leaf functions
Non-leaf functions now work. Combined with simple parameters and return
types, this allows more complicated programs than Hello World to be
correctly compiled.
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 541dced068..20da342db7 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -576,7 +576,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { // push {fp, lr} // mov fp, sp // sub sp, sp, #reloc - // mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .fp, Instruction.Operand.reg(.sp, Instruction.Operand.Shift.none)).toU32()); + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.push(.al, .{ .fp, .lr }).toU32()); + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .fp, Instruction.Operand.reg(.sp, Instruction.Operand.Shift.none)).toU32()); + // TODO: prepare stack for local variables // const backpatch_reloc = try self.code.addManyAsArray(4); try self.dbgSetPrologueEnd(); @@ -592,7 +594,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { // mov sp, fp // pop {fp, pc} - mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .sp, Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none)).toU32()); + // TODO: return by jumping to this code, use relocations + // mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .sp, Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none)).toU32()); + // mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.pop(.al, .{ .fp, .pc }).toU32()); } else { try self.dbgSetPrologueEnd(); try self.genBody(self.mod_fn.analysis.success); @@ -1661,7 +1665,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.jalr(.zero, 0, .ra).toU32()); }, .arm => { - mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.bx(.al, .lr).toU32()); + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .sp, Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none)).toU32()); + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.pop(.al, .{ .fp, .pc }).toU32()); + // TODO: jump to the end with relocation // // Just add space for an instruction, patch this later // try self.code.resize(self.code.items.len + 4); // try self.exitlude_jump_relocs.append(self.gpa, self.code.items.len - 4); @@ -2316,7 +2322,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { // The value is in memory at a hard-coded address. // If the type is a pointer, it means the pointer address is at this memory location. try self.genSetReg(src, reg, .{ .immediate = addr }); - mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, reg, Instruction.Offset.none).toU32()); + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, reg, .{ .offset = Instruction.Offset.none }).toU32()); }, else => return self.fail(src, "TODO implement getSetReg for arm {}", .{mcv}), }, |
