authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2020-11-24 22:32:36+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2020-11-28 18:19:22+01:00
log2ad263658872a7b8b7bf3275c35d0e4c4faebccd
treea75c027baa9b503ac529e89076ab5d434ed71aed
parentf06f0ebcda57c65f481e5da41fb3949b9863744c
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: use strb + implement genBoolOp


1 files changed, 46 insertions(+), 15 deletions(-)

src/codegen.zig+46-15
......@@ -1246,6 +1246,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
12461246 writeInt(u32, try self.code.addManyAsArray(4), Instruction.rsb(.al, dst_reg, dst_reg, operand).toU32());
12471247 }
12481248 },
1249 .booland => {
1250 writeInt(u32, try self.code.addManyAsArray(4), Instruction.@"and"(.al, dst_reg, dst_reg, operand).toU32());
1251 },
1252 .boolor => {
1253 writeInt(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, dst_reg, dst_reg, operand).toU32());
1254 },
12491255 .not => {
12501256 writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32());
12511257 },
......@@ -2209,7 +2215,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
22092215 .booland => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 4, 0x20),
22102216 // lhs OR rhs
22112217 .boolor => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 1, 0x08),
2212 else => unreachable,
2218 else => unreachable, // Not a boolean operation
2219 },
2220 .arm, .armeb => switch (inst.base.tag) {
2221 .booland => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .booland),
2222 .boolor => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .boolor),
2223 else => unreachable, // Not a boolean operation
22132224 },
22142225 else => return self.fail(inst.base.src, "TODO implement boolean operations for {}", .{self.target.cpu.arch}),
22152226 }
......@@ -2464,14 +2475,23 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24642475 return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{});
24652476 },
24662477 .register => |reg| {
2467 // TODO: strb, strh
2468 if (stack_offset <= math.maxInt(u12)) {
2469 writeInt(u32, try self.code.addManyAsArray(4), Instruction.str(.al, reg, .fp, .{
2470 .offset = Instruction.Offset.imm(@intCast(u12, stack_offset)),
2478 // TODO: strh
2479 const offset = if (stack_offset <= math.maxInt(u12)) blk: {
2480 break :blk Instruction.Offset.imm(@intCast(u12, stack_offset));
2481 } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = stack_offset }), 0);
2482
2483 const abi_size = ty.abiSize(self.target.*);
2484 switch (abi_size) {
2485 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.strb(.al, reg, .fp, .{
2486 .offset = offset,
24712487 .positive = false,
2472 }).toU32());
2473 } else {
2474 return self.fail(src, "TODO genSetStack with larger offsets", .{});
2488 }).toU32()),
2489 2 => return self.fail(src, "TODO implement strh", .{}),
2490 4 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.str(.al, reg, .fp, .{
2491 .offset = offset,
2492 .positive = false,
2493 }).toU32()),
2494 else => return self.fail(src, "TODO a type of size {} is not allowed in a register", .{abi_size}),
24752495 }
24762496 },
24772497 .memory => |vaddr| {
......@@ -2642,15 +2662,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
26422662 writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, reg, .{ .offset = Instruction.Offset.none }).toU32());
26432663 },
26442664 .stack_offset => |unadjusted_off| {
2645 // TODO: ldrb, ldrh
2665 // TODO: ldrh
26462666 // TODO: maybe addressing from sp instead of fp
2647 if (unadjusted_off <= math.maxInt(u12)) {
2648 writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, .fp, .{
2649 .offset = Instruction.Offset.imm(@intCast(u12, unadjusted_off)),
2667 const offset = if (unadjusted_off <= math.maxInt(u12)) blk: {
2668 break :blk Instruction.Offset.imm(@intCast(u12, unadjusted_off));
2669 } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = unadjusted_off }), 0);
2670
2671 // TODO: supply type information to genSetReg as we do to genSetStack
2672 // const abi_size = ty.abiSize(self.target.*);
2673 const abi_size = 4;
2674 switch (abi_size) {
2675 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldrb(.al, reg, .fp, .{
2676 .offset = offset,
26502677 .positive = false,
2651 }).toU32());
2652 } else {
2653 return self.fail(src, "TODO genSetReg with larger stack offset", .{});
2678 }).toU32()),
2679 2 => return self.fail(src, "TODO implement strh", .{}),
2680 4 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, .fp, .{
2681 .offset = offset,
2682 .positive = false,
2683 }).toU32()),
2684 else => return self.fail(src, "TODO a type of size {} is not allowed in a register", .{abi_size}),
26542685 }
26552686 },
26562687 else => return self.fail(src, "TODO implement getSetReg for arm {}", .{mcv}),