From 2ad263658872a7b8b7bf3275c35d0e4c4faebccd Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Tue, 24 Nov 2020 22:32:36 +0100 Subject: stage2 ARM: use strb + implement genBoolOp --- src/codegen.zig | 61 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/codegen.zig b/src/codegen.zig index 329bacdabf..ee3f0ee4a8 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -1246,6 +1246,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { writeInt(u32, try self.code.addManyAsArray(4), Instruction.rsb(.al, dst_reg, dst_reg, operand).toU32()); } }, + .booland => { + writeInt(u32, try self.code.addManyAsArray(4), Instruction.@"and"(.al, dst_reg, dst_reg, operand).toU32()); + }, + .boolor => { + writeInt(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, dst_reg, dst_reg, operand).toU32()); + }, .not => { writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32()); }, @@ -2209,7 +2215,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .booland => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 4, 0x20), // lhs OR rhs .boolor => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 1, 0x08), - else => unreachable, + else => unreachable, // Not a boolean operation + }, + .arm, .armeb => switch (inst.base.tag) { + .booland => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .booland), + .boolor => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .boolor), + else => unreachable, // Not a boolean operation }, else => return self.fail(inst.base.src, "TODO implement boolean operations for {}", .{self.target.cpu.arch}), } @@ -2464,14 +2475,23 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{}); }, .register => |reg| { - // TODO: strb, strh - if (stack_offset <= math.maxInt(u12)) { - writeInt(u32, try self.code.addManyAsArray(4), Instruction.str(.al, reg, .fp, .{ - .offset = Instruction.Offset.imm(@intCast(u12, stack_offset)), + // TODO: strh + const offset = if (stack_offset <= math.maxInt(u12)) blk: { + break :blk Instruction.Offset.imm(@intCast(u12, stack_offset)); + } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = stack_offset }), 0); + + const abi_size = ty.abiSize(self.target.*); + switch (abi_size) { + 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.strb(.al, reg, .fp, .{ + .offset = offset, .positive = false, - }).toU32()); - } else { - return self.fail(src, "TODO genSetStack with larger offsets", .{}); + }).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}), } }, .memory => |vaddr| { @@ -2642,15 +2662,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, reg, .{ .offset = Instruction.Offset.none }).toU32()); }, .stack_offset => |unadjusted_off| { - // TODO: ldrb, ldrh + // TODO: ldrh // TODO: maybe addressing from sp instead of fp - if (unadjusted_off <= math.maxInt(u12)) { - writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, .fp, .{ - .offset = Instruction.Offset.imm(@intCast(u12, unadjusted_off)), + const offset = if (unadjusted_off <= math.maxInt(u12)) blk: { + break :blk Instruction.Offset.imm(@intCast(u12, unadjusted_off)); + } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = unadjusted_off }), 0); + + // TODO: supply type information to genSetReg as we do to genSetStack + // const abi_size = ty.abiSize(self.target.*); + const abi_size = 4; + switch (abi_size) { + 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldrb(.al, reg, .fp, .{ + .offset = offset, .positive = false, - }).toU32()); - } else { - return self.fail(src, "TODO genSetReg with larger stack offset", .{}); + }).toU32()), + 2 => return self.fail(src, "TODO implement strh", .{}), + 4 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.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}), } }, else => return self.fail(src, "TODO implement getSetReg for arm {}", .{mcv}), -- cgit v1.2.3