| ... | @@ -887,6 +887,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -887,6 +887,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 887 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 887 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 888 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 888 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 889 | const operand = try self.resolveInst(ty_op.operand); | 889 | const operand = try self.resolveInst(ty_op.operand); |
| | 890 | const operand_ty = self.air.typeOf(ty_op.operand); |
| 890 | switch (operand) { | 891 | switch (operand) { |
| 891 | .dead => unreachable, | 892 | .dead => unreachable, |
| 892 | .unreach => unreachable, | 893 | .unreach => unreachable, |
| ... | @@ -917,7 +918,68 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -917,7 +918,68 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 917 | break :result r; | 918 | break :result r; |
| 918 | }, | 919 | }, |
| 919 | else => { | 920 | 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 | } |
| 921 | }, | 983 | }, |
| 922 | } | 984 | } |
| 923 | }; | 985 | }; |
| ... | @@ -2073,9 +2135,6 @@ fn genBinOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Air | ... | @@ -2073,9 +2135,6 @@ fn genBinOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Air |
| 2073 | const ty = self.air.typeOf(op_lhs); | 2135 | const ty = self.air.typeOf(op_lhs); |
| 2074 | | 2136 | |
| 2075 | switch (ty.zigTypeTag()) { | 2137 | switch (ty.zigTypeTag()) { |
| 2076 | .Bool => { | | |
| 2077 | return self.genBinIntOp(inst, op_lhs, op_rhs, op, 1, .unsigned); | | |
| 2078 | }, | | |
| 2079 | .Int => { | 2138 | .Int => { |
| 2080 | const int_info = ty.intInfo(self.target.*); | 2139 | const int_info = ty.intInfo(self.target.*); |
| 2081 | return self.genBinIntOp(inst, op_lhs, op_rhs, op, int_info.bits, int_info.signedness); | 2140 | return self.genBinIntOp(inst, op_lhs, op_rhs, op, int_info.bits, int_info.signedness); |
| ... | @@ -2237,21 +2296,6 @@ fn genBinOpCode( | ... | @@ -2237,21 +2296,6 @@ fn genBinOpCode( |
| 2237 | }; | 2296 | }; |
| 2238 | | 2297 | |
| 2239 | switch (op) { | 2298 | 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 | }, | | |
| 2255 | .cmp_eq => { | 2299 | .cmp_eq => { |
| 2256 | _ = try self.addInst(.{ | 2300 | _ = try self.addInst(.{ |
| 2257 | .tag = .cmp, | 2301 | .tag = .cmp, |