aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorjoachimschmidt557 <joachim.schmidt557@outlook.com>2020-09-25 22:19:40 +0200
committerjoachimschmidt557 <joachim.schmidt557@outlook.com>2020-10-02 19:39:17 +0200
commitcfe486e3887ee5ea622234439fc7bd41fb2774bc (patch)
tree7d1e7e0acd4c017bc3286027c1ce4e05f879b889 /src/codegen.zig
parent35b228630cf1972868fe820baeb41a09801f2fbb (diff)
downloadzig-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.zig14
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}),
},