authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-17 21:50:22+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-19 12:06:34+01:00
log3b1762bb4769fdbe9d345218f0412595fa1d6e43
tree03829620213c106f6a26ae8a2471face99b41a3a
parent7b833b2fba35a1022ea76e89b6760e462ba09651
signature Commit is signed but in an unrecognized format.

stage2 ARM: fix boolean and bitwise not


1 files changed, 63 insertions(+), 19 deletions(-)

src/arch/arm/CodeGen.zig+63-19
......@@ -887,6 +887,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
887887 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
888888 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
889889 const operand = try self.resolveInst(ty_op.operand);
890 const operand_ty = self.air.typeOf(ty_op.operand);
890891 switch (operand) {
891892 .dead => unreachable,
892893 .unreach => unreachable,
......@@ -917,7 +918,68 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
917918 break :result r;
918919 },
919920 else => {
920 break :result try self.genBinOp(inst, ty_op.operand, .bool_true, .not);
921 switch (operand_ty.zigTypeTag()) {
922 .Bool => {
923 const op_reg = switch (operand) {
924 .register => |r| r,
925 else => try self.copyToTmpRegister(operand_ty, operand),
926 };
927 self.register_manager.freezeRegs(&.{op_reg});
928 defer self.register_manager.unfreezeRegs(&.{op_reg});
929
930 const dest_reg = blk: {
931 if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
932 break :blk op_reg;
933 }
934
935 break :blk try self.register_manager.allocReg(null);
936 };
937
938 _ = try self.addInst(.{
939 .tag = .eor,
940 .data = .{ .rr_op = .{
941 .rd = dest_reg,
942 .rn = op_reg,
943 .op = Instruction.Operand.fromU32(1).?,
944 } },
945 });
946
947 break :result MCValue{ .register = dest_reg };
948 },
949 .Int => {
950 const int_info = operand_ty.intInfo(self.target.*);
951 if (int_info.bits <= 32) {
952 const op_reg = switch (operand) {
953 .register => |r| r,
954 else => try self.copyToTmpRegister(operand_ty, operand),
955 };
956 self.register_manager.freezeRegs(&.{op_reg});
957 defer self.register_manager.unfreezeRegs(&.{op_reg});
958
959 const dest_reg = blk: {
960 if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
961 break :blk op_reg;
962 }
963
964 break :blk try self.register_manager.allocReg(null);
965 };
966
967 _ = try self.addInst(.{
968 .tag = .mvn,
969 .data = .{ .rr_op = .{
970 .rd = dest_reg,
971 .rn = undefined,
972 .op = Instruction.Operand.reg(op_reg, Instruction.Operand.Shift.none),
973 } },
974 });
975
976 break :result MCValue{ .register = dest_reg };
977 } else {
978 return self.fail("TODO ARM not on integers > u32/i32", .{});
979 }
980 },
981 else => unreachable,
982 }
921983 },
922984 }
923985 };
......@@ -2073,9 +2135,6 @@ fn genBinOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Air
20732135 const ty = self.air.typeOf(op_lhs);
20742136
20752137 switch (ty.zigTypeTag()) {
2076 .Bool => {
2077 return self.genBinIntOp(inst, op_lhs, op_rhs, op, 1, .unsigned);
2078 },
20792138 .Int => {
20802139 const int_info = ty.intInfo(self.target.*);
20812140 return self.genBinIntOp(inst, op_lhs, op_rhs, op, int_info.bits, int_info.signedness);
......@@ -2237,21 +2296,6 @@ fn genBinOpCode(
22372296 };
22382297
22392298 switch (op) {
2240 .not => {
2241 const tag: Mir.Inst.Tag = switch (op) {
2242 .not => .eor,
2243 else => unreachable,
2244 };
2245
2246 _ = try self.addInst(.{
2247 .tag = tag,
2248 .data = .{ .rr_op = .{
2249 .rd = dst_reg,
2250 .rn = op1,
2251 .op = operand,
2252 } },
2253 });
2254 },
22552299 .cmp_eq => {
22562300 _ = try self.addInst(.{
22572301 .tag = .cmp,