authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-09 23:58:46+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-09 23:58:46+02:00
logc3b7a5cc26d11a0349ff1d7812b00687cfa41c2e
tree78db1ef862fc73c093b39f3805f82b93b03b11a5
parent7b9f8bfbd80aa37afc160c39b341c59fdd3cbad8

x64: pass tag and maybe_inst explictly to genBinOp


1 files changed, 36 insertions(+), 32 deletions(-)

src/arch/x86_64/CodeGen.zig+36-32
...@@ -1122,7 +1122,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1122,7 +1122,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1122 },1122 },
1123 else => {},1123 else => {},
1124 }1124 }
1125 break :result try self.genBinOp(inst, ty_op.operand, .bool_true, true);1125 break :result try self.genBinOp(.not, inst, ty_op.operand, .bool_true);
1126 };1126 };
1127 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1127 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1128}1128}
...@@ -1208,10 +1208,13 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -1208,10 +1208,13 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
12081208
1209fn airBinOp(self: *Self, inst: Air.Inst.Index) !void {1209fn airBinOp(self: *Self, inst: Air.Inst.Index) !void {
1210 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1210 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1211 const result: MCValue = if (self.liveness.isUnused(inst))1211
1212 .dead1212 if (self.liveness.isUnused(inst)) {
1213 else1213 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
1214 try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, true);1214 }
1215
1216 const tag = self.air.instructions.items(.tag)[inst];
1217 const result = try self.genBinOp(tag, inst, bin_op.lhs, bin_op.rhs);
1215 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1218 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1216}1219}
12171220
...@@ -1260,7 +1263,7 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1260,7 +1263,7 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1260 try self.spillCompareFlagsIfOccupied();1263 try self.spillCompareFlagsIfOccupied();
1261 self.compare_flags_inst = inst;1264 self.compare_flags_inst = inst;
12621265
1263 const partial = try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, true);1266 const partial = try self.genBinOp(.add, inst, bin_op.lhs, bin_op.rhs);
1264 const result: MCValue = switch (int_info.signedness) {1267 const result: MCValue = switch (int_info.signedness) {
1265 .signed => .{ .register_overflow_signed = partial.register },1268 .signed => .{ .register_overflow_signed = partial.register },
1266 .unsigned => .{ .register_overflow_unsigned = partial.register },1269 .unsigned => .{ .register_overflow_unsigned = partial.register },
...@@ -1292,7 +1295,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1292,7 +1295,7 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1292 try self.spillCompareFlagsIfOccupied();1295 try self.spillCompareFlagsIfOccupied();
1293 self.compare_flags_inst = inst;1296 self.compare_flags_inst = inst;
12941297
1295 const partial = try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, true);1298 const partial = try self.genBinOp(.sub, inst, bin_op.lhs, bin_op.rhs);
1296 const result: MCValue = switch (int_info.signedness) {1299 const result: MCValue = switch (int_info.signedness) {
1297 .signed => .{ .register_overflow_signed = partial.register },1300 .signed => .{ .register_overflow_signed = partial.register },
1298 .unsigned => .{ .register_overflow_unsigned = partial.register },1301 .unsigned => .{ .register_overflow_unsigned = partial.register },
...@@ -1329,7 +1332,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1329,7 +1332,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
13291332
1330 if (math.isPowerOfTwo(int_info.bits)) {1333 if (math.isPowerOfTwo(int_info.bits)) {
1331 self.compare_flags_inst = inst;1334 self.compare_flags_inst = inst;
1332 const partial = try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, true);1335 const partial = try self.genBinOp(.mul, inst, bin_op.lhs, bin_op.rhs);
1333 break :result switch (int_info.signedness) {1336 break :result switch (int_info.signedness) {
1334 .signed => MCValue{ .register_overflow_signed = partial.register },1337 .signed => MCValue{ .register_overflow_signed = partial.register },
1335 .unsigned => MCValue{ .register_overflow_unsigned = partial.register },1338 .unsigned => MCValue{ .register_overflow_unsigned = partial.register },
...@@ -1372,7 +1375,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1372,7 +1375,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1372 break :dst_reg dst_reg;1375 break :dst_reg dst_reg;
1373 },1376 },
1374 .unsigned => {1377 .unsigned => {
1375 const dst_mcv = try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, false);1378 const dst_mcv = try self.genBinOp(.mul, null, bin_op.lhs, bin_op.rhs);
1376 break :dst_reg dst_mcv.register;1379 break :dst_reg dst_mcv.register;
1377 },1380 },
1378 }1381 }
...@@ -3211,16 +3214,14 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3211,16 +3214,14 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
3211/// Result is always a register.3214/// Result is always a register.
3212fn genBinOp(3215fn genBinOp(
3213 self: *Self,3216 self: *Self,
3214 inst: Air.Inst.Index,3217 tag: Air.Inst.Tag,
3218 maybe_inst: ?Air.Inst.Index,
3215 op_lhs: Air.Inst.Ref,3219 op_lhs: Air.Inst.Ref,
3216 op_rhs: Air.Inst.Ref,3220 op_rhs: Air.Inst.Ref,
3217 track: bool,
3218) !MCValue {3221) !MCValue {
3219 const tag = self.air.instructions.items(.tag)[inst];
3220 const is_commutative: bool = switch (tag) {3222 const is_commutative: bool = switch (tag) {
3221 .add,3223 .add,
3222 .addwrap,3224 .addwrap,
3223 .add_with_overflow,
3224 .bool_or,3225 .bool_or,
3225 .bit_or,3226 .bit_or,
3226 .bool_and,3227 .bool_and,
...@@ -3231,10 +3232,8 @@ fn genBinOp(...@@ -3231,10 +3232,8 @@ fn genBinOp(
32313232
3232 .sub,3233 .sub,
3233 .subwrap,3234 .subwrap,
3234 .sub_with_overflow,
3235 .mul,3235 .mul,
3236 .mulwrap,3236 .mulwrap,
3237 .mul_with_overflow,
3238 .shl,3237 .shl,
3239 .shr,3238 .shr,
3240 .ptr_add,3239 .ptr_add,
...@@ -3256,10 +3255,9 @@ fn genBinOp(...@@ -3256,10 +3255,9 @@ fn genBinOp(
3256 switch (tag) {3255 switch (tag) {
3257 .mul,3256 .mul,
3258 .mulwrap,3257 .mulwrap,
3259 .mul_with_overflow,
3260 => {3258 => {
3261 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.3259 // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
3262 try self.register_manager.getReg(.rax, if (track) inst else null);3260 try self.register_manager.getReg(.rax, maybe_inst);
3263 try self.register_manager.getReg(.rdx, null);3261 try self.register_manager.getReg(.rdx, null);
3264 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });3262 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
3265 defer for (reg_locks) |reg| {3263 defer for (reg_locks) |reg| {
...@@ -3299,18 +3297,17 @@ fn genBinOp(...@@ -3299,18 +3297,17 @@ fn genBinOp(
32993297
3300 var flipped: bool = false;3298 var flipped: bool = false;
3301 const dst_mcv: MCValue = blk: {3299 const dst_mcv: MCValue = blk: {
3302 if (self.reuseOperand(inst, op_lhs, 0, lhs) and lhs.isRegister()) {3300 if (maybe_inst) |inst| {
3303 break :blk lhs;3301 if (self.reuseOperand(inst, op_lhs, 0, lhs) and lhs.isRegister()) {
3304 }3302 break :blk lhs;
3305 if (is_commutative and self.reuseOperand(inst, op_rhs, 1, rhs) and rhs.isRegister()) {3303 }
3306 flipped = true;3304 if (is_commutative and self.reuseOperand(inst, op_rhs, 1, rhs) and rhs.isRegister()) {
3307 break :blk rhs;3305 flipped = true;
3308 }3306 break :blk rhs;
3309 if (track) {3307 }
3310 break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs);3308 break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs);
3311 } else {
3312 break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, lhs) };
3313 }3309 }
3310 break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, lhs) };
3314 };3311 };
3315 const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) {3312 const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) {
3316 .register => |reg| self.register_manager.lockReg(reg),3313 .register => |reg| self.register_manager.lockReg(reg),
...@@ -3332,12 +3329,10 @@ fn genBinOp(...@@ -3332,12 +3329,10 @@ fn genBinOp(
3332 switch (tag) {3329 switch (tag) {
3333 .add,3330 .add,
3334 .addwrap,3331 .addwrap,
3335 .add_with_overflow,
3336 => try self.genBinOpMir(.add, dst_ty, dst_mcv, src_mcv),3332 => try self.genBinOpMir(.add, dst_ty, dst_mcv, src_mcv),
33373333
3338 .sub,3334 .sub,
3339 .subwrap,3335 .subwrap,
3340 .sub_with_overflow,
3341 => try self.genBinOpMir(.sub, dst_ty, dst_mcv, src_mcv),3336 => try self.genBinOpMir(.sub, dst_ty, dst_mcv, src_mcv),
33423337
3343 .ptr_add,3338 .ptr_add,
...@@ -3353,9 +3348,18 @@ fn genBinOp(...@@ -3353,9 +3348,18 @@ fn genBinOp(
3353 try self.genBinOpMir(mir_tag, dst_ty, dst_mcv, src_mcv);3348 try self.genBinOpMir(mir_tag, dst_ty, dst_mcv, src_mcv);
3354 },3349 },
33553350
3356 .bool_or, .bit_or => try self.genBinOpMir(.@"or", dst_ty, dst_mcv, src_mcv),3351 .bool_or,
3357 .bool_and, .bit_and => try self.genBinOpMir(.@"and", dst_ty, dst_mcv, src_mcv),3352 .bit_or,
3358 .xor, .not => try self.genBinOpMir(.xor, dst_ty, dst_mcv, src_mcv),3353 => try self.genBinOpMir(.@"or", dst_ty, dst_mcv, src_mcv),
3354
3355 .bool_and,
3356 .bit_and,
3357 => try self.genBinOpMir(.@"and", dst_ty, dst_mcv, src_mcv),
3358
3359 .xor,
3360 .not,
3361 => try self.genBinOpMir(.xor, dst_ty, dst_mcv, src_mcv),
3362
3359 else => unreachable,3363 else => unreachable,
3360 }3364 }
3361 return dst_mcv;3365 return dst_mcv;