aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorjoachimschmidt557 <joachim.schmidt557@outlook.com>2021-01-10 20:50:38 +0100
committerAndrew Kelley <andrew@ziglang.org>2021-01-16 12:06:31 -0800
commitd2a297c2b3eb293b393f41640892ff7a5a71027f (patch)
tree08f48ee321f3114ba6eebc71c592f40ca8247d1c /src/codegen.zig
parentfbd5fbe729b7d3f085d2d479ed9957decc019332 (diff)
downloadzig-d2a297c2b3eb293b393f41640892ff7a5a71027f.tar.gz
zig-d2a297c2b3eb293b393f41640892ff7a5a71027f.zip
stage2 ARM: add extra load/store instructions
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig76
1 files changed, 51 insertions, 25 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 7c67a9191b..709c91a635 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -2630,21 +2630,34 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
.register => |reg| {
const abi_size = ty.abiSize(self.target.*);
const adj_off = stack_offset + abi_size;
- const offset = if (adj_off <= math.maxInt(u12)) blk: {
- break :blk Instruction.Offset.imm(@intCast(u12, adj_off));
- } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0);
switch (abi_size) {
- 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.strb(.al, reg, .fp, .{
- .offset = offset,
- .positive = false,
- }).toU32()),
- 2 => return self.fail(src, "TODO implement strh", .{}),
- 4 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.str(.al, reg, .fp, .{
- .offset = offset,
- .positive = false,
- }).toU32()),
- else => return self.fail(src, "TODO a type of size {} is not allowed in a register", .{abi_size}),
+ 1, 4 => {
+ const offset = if (adj_off <= math.maxInt(u12)) blk: {
+ break :blk Instruction.Offset.imm(@intCast(u12, adj_off));
+ } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0);
+ const str = switch (abi_size) {
+ 1 => Instruction.strb,
+ 4 => Instruction.str,
+ else => unreachable,
+ };
+
+ writeInt(u32, try self.code.addManyAsArray(4), str(.al, reg, .fp, .{
+ .offset = offset,
+ .positive = false,
+ }).toU32());
+ },
+ 2 => {
+ const offset = if (adj_off <= math.maxInt(u8)) blk: {
+ break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, adj_off));
+ } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }));
+
+ writeInt(u32, try self.code.addManyAsArray(4), Instruction.strh(.al, reg, .fp, .{
+ .offset = offset,
+ .positive = false,
+ }).toU32());
+ },
+ else => return self.fail(src, "TODO implement storing other types abi_size={}", .{abi_size}),
}
},
.memory => |vaddr| {
@@ -2836,20 +2849,33 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
// const abi_size = ty.abiSize(self.target.*);
const abi_size = 4;
const adj_off = unadjusted_off + abi_size;
- const offset = if (adj_off <= math.maxInt(u12)) blk: {
- break :blk Instruction.Offset.imm(@intCast(u12, adj_off));
- } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0);
switch (abi_size) {
- 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldrb(.al, reg, .fp, .{
- .offset = offset,
- .positive = false,
- }).toU32()),
- 2 => return self.fail(src, "TODO implement ldrh", .{}),
- 4 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, .fp, .{
- .offset = offset,
- .positive = false,
- }).toU32()),
+ 1, 4 => {
+ const offset = if (adj_off <= math.maxInt(u12)) blk: {
+ break :blk Instruction.Offset.imm(@intCast(u12, adj_off));
+ } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0);
+ const ldr = switch (abi_size) {
+ 1 => Instruction.ldrb,
+ 4 => Instruction.ldr,
+ else => unreachable,
+ };
+
+ writeInt(u32, try self.code.addManyAsArray(4), ldr(.al, reg, .fp, .{
+ .offset = offset,
+ .positive = false,
+ }).toU32());
+ },
+ 2 => {
+ const offset = if (adj_off <= math.maxInt(u8)) blk: {
+ break :blk Instruction.ExtraLoadStoreOffset.imm(@intCast(u8, adj_off));
+ } else Instruction.ExtraLoadStoreOffset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }));
+
+ writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldrh(.al, reg, .fp, .{
+ .offset = offset,
+ .positive = false,
+ }).toU32());
+ },
else => return self.fail(src, "TODO a type of size {} is not allowed in a register", .{abi_size}),
}
},