| ... | @@ -1081,9 +1081,6 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r | ... | @@ -1081,9 +1081,6 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r |
| 1081 | const offset = try self.resolveInst(op_rhs); | 1081 | const offset = try self.resolveInst(op_rhs); |
| 1082 | const offset_ty = self.air.typeOf(op_rhs); | 1082 | const offset_ty = self.air.typeOf(op_rhs); |
| 1083 | | 1083 | |
| 1084 | ptr.freezeIfRegister(&self.register_manager); | | |
| 1085 | defer ptr.unfreezeIfRegister(&self.register_manager); | | |
| 1086 | | | |
| 1087 | offset.freezeIfRegister(&self.register_manager); | 1084 | offset.freezeIfRegister(&self.register_manager); |
| 1088 | defer offset.unfreezeIfRegister(&self.register_manager); | 1085 | defer offset.unfreezeIfRegister(&self.register_manager); |
| 1089 | | 1086 | |
| ... | @@ -1091,9 +1088,12 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r | ... | @@ -1091,9 +1088,12 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r |
| 1091 | if (self.reuseOperand(inst, op_lhs, 0, ptr)) { | 1088 | if (self.reuseOperand(inst, op_lhs, 0, ptr)) { |
| 1092 | if (ptr.isMemory() or ptr.isRegister()) break :blk ptr; | 1089 | if (ptr.isMemory() or ptr.isRegister()) break :blk ptr; |
| 1093 | } | 1090 | } |
| 1094 | break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, ptr); | 1091 | break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, ptr) }; |
| 1095 | }; | 1092 | }; |
| 1096 | | 1093 | |
| | 1094 | dst_mcv.freezeIfRegister(&self.register_manager); |
| | 1095 | defer dst_mcv.unfreezeIfRegister(&self.register_manager); |
| | 1096 | |
| 1097 | const offset_mcv = blk: { | 1097 | const offset_mcv = blk: { |
| 1098 | if (self.reuseOperand(inst, op_rhs, 1, offset)) { | 1098 | if (self.reuseOperand(inst, op_rhs, 1, offset)) { |
| 1099 | if (offset.isRegister()) break :blk offset; | 1099 | if (offset.isRegister()) break :blk offset; |
| ... | @@ -1101,6 +1101,9 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r | ... | @@ -1101,6 +1101,9 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r |
| 1101 | break :blk MCValue{ .register = try self.copyToTmpRegister(offset_ty, offset) }; | 1101 | break :blk MCValue{ .register = try self.copyToTmpRegister(offset_ty, offset) }; |
| 1102 | }; | 1102 | }; |
| 1103 | | 1103 | |
| | 1104 | offset_mcv.freezeIfRegister(&self.register_manager); |
| | 1105 | defer offset_mcv.unfreezeIfRegister(&self.register_manager); |
| | 1106 | |
| 1104 | try self.genIMulOpMir(offset_ty, offset_mcv, .{ .immediate = elem_size }); | 1107 | try self.genIMulOpMir(offset_ty, offset_mcv, .{ .immediate = elem_size }); |
| 1105 | | 1108 | |
| 1106 | const tag = self.air.instructions.items(.tag)[inst]; | 1109 | const tag = self.air.instructions.items(.tag)[inst]; |
| ... | @@ -1179,12 +1182,43 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1179,12 +1182,43 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 1179 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 1182 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1180 | } | 1183 | } |
| 1181 | | 1184 | |
| | 1185 | fn genSubOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Air.Inst.Ref) !MCValue { |
| | 1186 | const dst_ty = self.air.typeOfIndex(inst); |
| | 1187 | const lhs = try self.resolveInst(op_lhs); |
| | 1188 | const rhs = try self.resolveInst(op_rhs); |
| | 1189 | |
| | 1190 | rhs.freezeIfRegister(&self.register_manager); |
| | 1191 | defer rhs.unfreezeIfRegister(&self.register_manager); |
| | 1192 | |
| | 1193 | const dst_mcv = blk: { |
| | 1194 | if (self.reuseOperand(inst, op_lhs, 0, lhs)) { |
| | 1195 | if (lhs.isMemory() or lhs.isRegister()) break :blk lhs; |
| | 1196 | } |
| | 1197 | break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs); |
| | 1198 | }; |
| | 1199 | |
| | 1200 | dst_mcv.freezeIfRegister(&self.register_manager); |
| | 1201 | defer dst_mcv.unfreezeIfRegister(&self.register_manager); |
| | 1202 | |
| | 1203 | const rhs_mcv = blk: { |
| | 1204 | if (rhs.isRegister()) break :blk rhs; |
| | 1205 | break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, rhs) }; |
| | 1206 | }; |
| | 1207 | |
| | 1208 | rhs_mcv.freezeIfRegister(&self.register_manager); |
| | 1209 | defer rhs_mcv.unfreezeIfRegister(&self.register_manager); |
| | 1210 | |
| | 1211 | try self.genBinMathOpMir(.sub, dst_ty, dst_mcv, rhs_mcv); |
| | 1212 | |
| | 1213 | return dst_mcv; |
| | 1214 | } |
| | 1215 | |
| 1182 | fn airSub(self: *Self, inst: Air.Inst.Index) !void { | 1216 | fn airSub(self: *Self, inst: Air.Inst.Index) !void { |
| 1183 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 1217 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1184 | const result: MCValue = if (self.liveness.isUnused(inst)) | 1218 | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 1185 | .dead | 1219 | .dead |
| 1186 | else | 1220 | else |
| 1187 | try self.genBinMathOp(inst, bin_op.lhs, bin_op.rhs); | 1221 | try self.genSubOp(inst, bin_op.lhs, bin_op.rhs); |
| 1188 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 1222 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1189 | } | 1223 | } |
| 1190 | | 1224 | |
| ... | @@ -3628,7 +3662,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { | ... | @@ -3628,7 +3662,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 3628 | block_data.mcv = switch (operand_mcv) { | 3662 | block_data.mcv = switch (operand_mcv) { |
| 3629 | .none, .dead, .unreach => unreachable, | 3663 | .none, .dead, .unreach => unreachable, |
| 3630 | .register, .stack_offset, .memory => operand_mcv, | 3664 | .register, .stack_offset, .memory => operand_mcv, |
| 3631 | .immediate => blk: { | 3665 | .compare_flags_signed, .compare_flags_unsigned, .immediate => blk: { |
| 3632 | const new_mcv = try self.allocRegOrMem(block, true); | 3666 | const new_mcv = try self.allocRegOrMem(block, true); |
| 3633 | try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv); | 3667 | try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv); |
| 3634 | break :blk new_mcv; | 3668 | break :blk new_mcv; |
| ... | @@ -3957,9 +3991,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3957,9 +3991,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3957 | return self.genSetStack(ty, stack_offset, .{ .register = reg }); | 3991 | return self.genSetStack(ty, stack_offset, .{ .register = reg }); |
| 3958 | }, | 3992 | }, |
| 3959 | .immediate => |x_big| { | 3993 | .immediate => |x_big| { |
| 3960 | if (stack_offset > 128) { | | |
| 3961 | return self.fail("TODO implement set stack variable with large stack offset", .{}); | | |
| 3962 | } | | |
| 3963 | switch (abi_size) { | 3994 | switch (abi_size) { |
| 3964 | 1, 2, 4 => { | 3995 | 1, 2, 4 => { |
| 3965 | const payload = try self.addExtra(Mir.ImmPair{ | 3996 | const payload = try self.addExtra(Mir.ImmPair{ |