diff options
| author | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2021-01-10 20:50:38 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-01-16 12:06:31 -0800 |
| commit | d2a297c2b3eb293b393f41640892ff7a5a71027f (patch) | |
| tree | 08f48ee321f3114ba6eebc71c592f40ca8247d1c /src/codegen.zig | |
| parent | fbd5fbe729b7d3f085d2d479ed9957decc019332 (diff) | |
| download | zig-d2a297c2b3eb293b393f41640892ff7a5a71027f.tar.gz zig-d2a297c2b3eb293b393f41640892ff7a5a71027f.zip | |
stage2 ARM: add extra load/store instructions
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 76 |
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}), } }, |
