authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-01 18:14:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-04 15:57:40-07:00
log2a0efbee56b03d9deafaa7918433ea10b46305c9
tree29f2dd885e12a2acafacd821cbfdd0b2bb9f384b
parent46f4a97d051e630dfae75e3856c81ffd1c7811e3

Revert "cbe: reduce amount of temporary locals"

This reverts commit 15cc83e27ae8a1740d9b7e2ec14044903979a832.

1 files changed, 128 insertions(+), 163 deletions(-)

src/codegen/c.zig+128-163
......@@ -50,8 +50,6 @@ pub const CValue = union(enum) {
5050 /// Render these bytes literally.
5151 /// TODO make this a [*:0]const u8 to save memory
5252 bytes: []const u8,
53 /// Index of an instruction that should later be rendered inline.
54 inline_index: Air.Inst.Index,
5553};
5654
5755const BlockData = struct {
......@@ -81,7 +79,6 @@ const ValueRenderLocation = enum {
8179 FunctionArgument,
8280 Initializer,
8381 Other,
84 condition,
8582};
8683
8784const BuiltinInfo = enum {
......@@ -281,19 +278,6 @@ pub const Function = struct {
281278 return result;
282279 }
283280
284 fn resolveInstNoInline(f: *Function, inst: Air.Inst.Ref) !CValue {
285 const operand = try f.resolveInst(inst);
286 if (operand != .inline_index) return operand;
287
288 const inst_ty = f.air.typeOf(inst);
289 const writer = f.object.writer();
290 const local = try f.allocLocal(inst_ty, .Const);
291 try writer.writeAll(" = ");
292 try f.writeCValueInline(operand.inline_index);
293 try writer.writeAll(";\n");
294 return local;
295 }
296
297281 fn wantSafety(f: *Function) bool {
298282 return switch (f.object.dg.module.optimizeMode()) {
299283 .Debug, .ReleaseSafe => true,
......@@ -329,74 +313,10 @@ pub const Function = struct {
329313 .constant => |inst| {
330314 const ty = f.air.typeOf(inst);
331315 const val = f.air.value(inst).?;
332 try f.object.dg.renderValue(w, ty, val, location);
333 },
334 .undef => |ty| try f.object.dg.renderValue(w, ty, Value.undef, location),
335 .inline_index => |node| {
336 if (location != .condition) try w.writeByte('(');
337 try f.writeCValueInline(node);
338 if (location != .condition) try w.writeByte(')');
339 },
340 else => try f.object.dg.writeCValue(w, c_value),
341 }
342 }
343
344 const E = error{ OutOfMemory, AnalysisFail };
345
346 fn writeCValueInline(f: *Function, inst: Air.Inst.Index) E!void {
347 switch (f.air.instructions.items(.tag)[inst]) {
348 // zig fmt: off
349 // TODO use a different strategy for add, sub, mul, div
350 // that communicates to the optimizer that wrapping is UB.
351 .add => try airBinOp(f, inst, "+", "add", .None),
352 .sub => try airBinOp(f, inst, "-", "sub", .None),
353 .mul => try airBinOp(f, inst, "*", "mul", .None),
354
355 .div_float => try airBinBuiltinCall(f, inst, "div", .None),
356
357 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None),
358 .rem => {
359 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
360 const lhs_ty = f.air.typeOf(bin_op.lhs);
361 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
362 // so we only check one.
363 if (lhs_ty.isInt())
364 try airBinOp(f, inst, "%", "rem", .None)
365 else
366 try airBinFloatOp(f, inst, "fmod");
316 return f.object.dg.renderValue(w, ty, val, location);
367317 },
368 .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .None),
369 .mod => try airBinBuiltinCall(f, inst, "mod", .None),
370
371 .addwrap => try airBinBuiltinCall(f, inst, "addw", .Bits),
372 .subwrap => try airBinBuiltinCall(f, inst, "subw", .Bits),
373 .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .Bits),
374
375 .add_sat => try airBinBuiltinCall(f, inst, "adds", .Bits),
376 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .Bits),
377 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .Bits),
378 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .Bits),
379
380 .min => try airMinMax(f, inst, '<', "fmin"),
381 .max => try airMinMax(f, inst, '>', "fmax"),
382
383 .cmp_gt => try airCmpOp(f, inst, ">", "gt"),
384 .cmp_gte => try airCmpOp(f, inst, ">=", "ge"),
385 .cmp_lt => try airCmpOp(f, inst, "<", "lt"),
386 .cmp_lte => try airCmpOp(f, inst, "<=", "le"),
387
388 .cmp_eq => try airEquality(f, inst, "((", "==", "eq"),
389 .cmp_neq => try airEquality(f, inst, "!((", "!=", "ne"),
390
391 .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .None),
392 .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None),
393 .xor => try airBinOp(f, inst, "^", "xor", .None),
394 .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None),
395 .shl, => try airBinBuiltinCall(f, inst, "shlw", .Bits),
396 .shl_exact => try airBinOp(f, inst, "<<", "shl", .None),
397 .not => try airNot (f, inst),
398 else => unreachable,
399 // zig fmt: on
318 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),
319 else => return f.object.dg.writeCValue(w, c_value),
400320 }
401321 }
402322
......@@ -2245,7 +2165,7 @@ pub const DeclGen = struct {
22452165
22462166 fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {
22472167 switch (c_value) {
2248 .none, .inline_index => unreachable,
2168 .none => unreachable,
22492169 .local => |i| return w.print("t{d}", .{i}),
22502170 .local_ref => |i| return w.print("&t{d}", .{i}),
22512171 .constant => unreachable,
......@@ -2264,7 +2184,7 @@ pub const DeclGen = struct {
22642184
22652185 fn writeCValueDeref(dg: *DeclGen, w: anytype, c_value: CValue) !void {
22662186 switch (c_value) {
2267 .none, .inline_index => unreachable,
2187 .none => unreachable,
22682188 .local => |i| return w.print("(*t{d})", .{i}),
22692189 .local_ref => |i| return w.print("t{d}", .{i}),
22702190 .constant => unreachable,
......@@ -2294,7 +2214,7 @@ pub const DeclGen = struct {
22942214
22952215 fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
22962216 switch (c_value) {
2297 .none, .constant, .field, .undef, .inline_index => unreachable,
2217 .none, .constant, .field, .undef => unreachable,
22982218 .local, .arg, .decl, .identifier, .bytes => {
22992219 try dg.writeCValue(writer, c_value);
23002220 try writer.writeAll("->");
......@@ -2633,26 +2553,37 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
26332553 .ptr_add => try airPtrAddSub(f, inst, '+'),
26342554 .ptr_sub => try airPtrAddSub(f, inst, '-'),
26352555
2636 .add => CValue{ .inline_index = inst },
2637 .sub => CValue{ .inline_index = inst },
2638 .mul => CValue{ .inline_index = inst },
2556 // TODO use a different strategy for add, sub, mul, div
2557 // that communicates to the optimizer that wrapping is UB.
2558 .add => try airBinOp(f, inst, "+", "add", .None),
2559 .sub => try airBinOp(f, inst, "-", "sub", .None),
2560 .mul => try airBinOp(f, inst, "*", "mul", .None),
26392561
26402562 .neg => try airFloatNeg(f, inst),
2641 .div_float => CValue{ .inline_index = inst },
2563 .div_float => try airBinBuiltinCall(f, inst, "div", .None),
26422564
2643 .div_trunc, .div_exact => CValue{ .inline_index = inst },
2644 .rem => CValue{ .inline_index = inst },
2645 .div_floor => CValue{ .inline_index = inst },
2646 .mod => CValue{ .inline_index = inst },
2565 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None),
2566 .rem => blk: {
2567 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2568 const lhs_ty = f.air.typeOf(bin_op.lhs);
2569 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2570 // so we only check one.
2571 break :blk if (lhs_ty.isInt())
2572 try airBinOp(f, inst, "%", "rem", .None)
2573 else
2574 try airBinFloatOp(f, inst, "fmod");
2575 },
2576 .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .None),
2577 .mod => try airBinBuiltinCall(f, inst, "mod", .None),
26472578
2648 .addwrap => CValue{ .inline_index = inst },
2649 .subwrap => CValue{ .inline_index = inst },
2650 .mulwrap => CValue{ .inline_index = inst },
2579 .addwrap => try airBinBuiltinCall(f, inst, "addw", .Bits),
2580 .subwrap => try airBinBuiltinCall(f, inst, "subw", .Bits),
2581 .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .Bits),
26512582
2652 .add_sat => CValue{ .inline_index = inst },
2653 .sub_sat => CValue{ .inline_index = inst },
2654 .mul_sat => CValue{ .inline_index = inst },
2655 .shl_sat => CValue{ .inline_index = inst },
2583 .add_sat => try airBinBuiltinCall(f, inst, "adds", .Bits),
2584 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .Bits),
2585 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .Bits),
2586 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .Bits),
26562587
26572588 .sqrt,
26582589 .sin,
......@@ -2677,30 +2608,30 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
26772608 .mul_with_overflow => try airOverflow(f, inst, "mul", .Bits),
26782609 .shl_with_overflow => try airOverflow(f, inst, "shl", .Bits),
26792610
2680 .min => CValue{ .inline_index = inst },
2681 .max => CValue{ .inline_index = inst },
2611 .min => try airMinMax(f, inst, '<', "fmin"),
2612 .max => try airMinMax(f, inst, '>', "fmax"),
26822613
26832614 .slice => try airSlice(f, inst),
26842615
2685 .cmp_gt => CValue{ .inline_index = inst },
2686 .cmp_gte => CValue{ .inline_index = inst },
2687 .cmp_lt => CValue{ .inline_index = inst },
2688 .cmp_lte => CValue{ .inline_index = inst },
2616 .cmp_gt => try airCmpOp(f, inst, ">", "gt"),
2617 .cmp_gte => try airCmpOp(f, inst, ">=", "ge"),
2618 .cmp_lt => try airCmpOp(f, inst, "<", "lt"),
2619 .cmp_lte => try airCmpOp(f, inst, "<=", "le"),
26892620
2690 .cmp_eq => CValue{ .inline_index = inst },
2691 .cmp_neq => CValue{ .inline_index = inst },
2621 .cmp_eq => try airEquality(f, inst, "((", "==", "eq"),
2622 .cmp_neq => try airEquality(f, inst, "!((", "!=", "ne"),
26922623
26932624 .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}),
26942625 .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst),
26952626
26962627 // bool_and and bool_or are non-short-circuit operations
2697 .bool_and, .bit_and => CValue{ .inline_index = inst },
2698 .bool_or, .bit_or => CValue{ .inline_index = inst },
2699 .xor => CValue{ .inline_index = inst },
2700 .shr, .shr_exact => CValue{ .inline_index = inst },
2701 .shl, => CValue{ .inline_index = inst },
2702 .shl_exact => CValue{ .inline_index = inst },
2703 .not => CValue{ .inline_index = inst },
2628 .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .None),
2629 .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None),
2630 .xor => try airBinOp(f, inst, "^", "xor", .None),
2631 .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None),
2632 .shl, => try airBinBuiltinCall(f, inst, "shlw", .Bits),
2633 .shl_exact => try airBinOp(f, inst, "<<", "shl", .None),
2634 .not => try airNot (f, inst),
27042635
27052636 .optional_payload => try airOptionalPayload(f, inst),
27062637 .optional_payload_ptr => try airOptionalPayloadPtr(f, inst),
......@@ -3449,21 +3380,22 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
34493380 return local;
34503381}
34513382
3452fn airNot(f: *Function, inst: Air.Inst.Index) !void {
3383fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
3384 if (f.liveness.isUnused(inst)) return CValue.none;
3385
34533386 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
34543387 const op = try f.resolveInst(ty_op.operand);
34553388
34563389 const writer = f.object.writer();
34573390 const inst_ty = f.air.typeOfIndex(inst);
3391 const local = try f.allocLocal(inst_ty, .Const);
34583392
3459 const target = f.object.dg.module.getTarget();
3460 if (inst_ty.bitSize(target) > 64) {}
3461
3462 try writer.writeByte('(');
3463 try f.renderTypecast(writer, inst_ty);
3464 try writer.writeByte(')');
3393 try writer.writeAll(" = ");
34653394 try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~');
34663395 try f.writeCValue(writer, op, .Other);
3396 try writer.writeAll(";\n");
3397
3398 return local;
34673399}
34683400
34693401fn airBinOp(
......@@ -3472,54 +3404,62 @@ fn airBinOp(
34723404 operator: []const u8,
34733405 operation: []const u8,
34743406 info: BuiltinInfo,
3475) !void {
3407) !CValue {
3408 if (f.liveness.isUnused(inst)) return CValue.none;
3409
34763410 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
34773411
34783412 const operand_ty = f.air.typeOf(bin_op.lhs);
34793413 const target = f.object.dg.module.getTarget();
34803414 if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat())
3481 return airBinBuiltinCall(f, inst, operation, info);
3415 return try airBinBuiltinCall(f, inst, operation, info);
34823416
34833417 const inst_ty = f.air.typeOfIndex(inst);
34843418 const lhs = try f.resolveInst(bin_op.lhs);
34853419 const rhs = try f.resolveInst(bin_op.rhs);
34863420
34873421 const writer = f.object.writer();
3488 try writer.writeByte('(');
3489 try f.renderTypecast(writer, inst_ty);
3490 try writer.writeAll(")(");
3422 const local = try f.allocLocal(inst_ty, .Const);
3423
3424 try writer.writeAll(" = ");
34913425 try f.writeCValue(writer, lhs, .Other);
34923426 try writer.writeByte(' ');
34933427 try writer.writeAll(operator);
34943428 try writer.writeByte(' ');
34953429 try f.writeCValue(writer, rhs, .Other);
3496 try writer.writeByte(')');
3430 try writer.writeAll(";\n");
3431
3432 return local;
34973433}
34983434
3499fn airCmpOp(
3500 f: *Function,
3501 inst: Air.Inst.Index,
3502 operator: []const u8,
3503 operation: []const u8,
3504) !void {
3435fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation: []const u8) !CValue {
3436 if (f.liveness.isUnused(inst)) return CValue.none;
3437
35053438 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
35063439
35073440 const operand_ty = f.air.typeOf(bin_op.lhs);
35083441 const target = f.object.dg.module.getTarget();
35093442 if (operand_ty.isInt() and operand_ty.bitSize(target) > 64)
3510 return airCmpBuiltinCall(f, inst, operator, "cmp");
3443 return try airCmpBuiltinCall(f, inst, operator, "cmp");
35113444 if (operand_ty.isRuntimeFloat())
3512 return airCmpBuiltinCall(f, inst, operator, operation);
3445 return try airCmpBuiltinCall(f, inst, operator, operation);
35133446
3447 const inst_ty = f.air.typeOfIndex(inst);
35143448 const lhs = try f.resolveInst(bin_op.lhs);
35153449 const rhs = try f.resolveInst(bin_op.rhs);
35163450
35173451 const writer = f.object.writer();
3452 const local = try f.allocLocal(inst_ty, .Const);
3453
3454 try writer.writeAll(" = ");
35183455 try f.writeCValue(writer, lhs, .Other);
35193456 try writer.writeByte(' ');
35203457 try writer.writeAll(operator);
35213458 try writer.writeByte(' ');
35223459 try f.writeCValue(writer, rhs, .Other);
3460 try writer.writeAll(";\n");
3461
3462 return local;
35233463}
35243464
35253465fn airEquality(
......@@ -3528,20 +3468,27 @@ fn airEquality(
35283468 negate_prefix: []const u8,
35293469 operator: []const u8,
35303470 operation: []const u8,
3531) !void {
3471) !CValue {
3472 if (f.liveness.isUnused(inst)) return CValue.none;
3473
35323474 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
35333475
35343476 const operand_ty = f.air.typeOf(bin_op.lhs);
35353477 const target = f.object.dg.module.getTarget();
35363478 if (operand_ty.isInt() and operand_ty.bitSize(target) > 64)
3537 return airCmpBuiltinCall(f, inst, operator, "cmp");
3479 return try airCmpBuiltinCall(f, inst, operator, "cmp");
35383480 if (operand_ty.isRuntimeFloat())
3539 return airCmpBuiltinCall(f, inst, operator, operation);
3481 return try airCmpBuiltinCall(f, inst, operator, operation);
35403482
35413483 const lhs = try f.resolveInst(bin_op.lhs);
35423484 const rhs = try f.resolveInst(bin_op.rhs);
35433485
35443486 const writer = f.object.writer();
3487 const inst_ty = f.air.typeOfIndex(inst);
3488 const local = try f.allocLocal(inst_ty, .Const);
3489
3490 try writer.writeAll(" = ");
3491
35453492 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.isPtrLikeOptional()) {
35463493 // (A && B) || (C && (A == B))
35473494 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
......@@ -3558,8 +3505,9 @@ fn airEquality(
35583505 try f.writeCValue(writer, lhs, .Other);
35593506 try writer.writeAll(".is_null == ");
35603507 try f.writeCValue(writer, rhs, .Other);
3561 try writer.writeAll(".is_null))");
3562 return;
3508 try writer.writeAll(".is_null));\n");
3509
3510 return local;
35633511 }
35643512
35653513 try f.writeCValue(writer, lhs, .Other);
......@@ -3567,6 +3515,9 @@ fn airEquality(
35673515 try writer.writeAll(operator);
35683516 try writer.writeByte(' ');
35693517 try f.writeCValue(writer, rhs, .Other);
3518 try writer.writeAll(";\n");
3519
3520 return local;
35703521}
35713522
35723523fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
......@@ -3620,23 +3571,26 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
36203571 return local;
36213572}
36223573
3623fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !void {
3574fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {
3575 if (f.liveness.isUnused(inst)) return CValue.none;
3576
36243577 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
36253578
36263579 const inst_ty = f.air.typeOfIndex(inst);
36273580 const target = f.object.dg.module.getTarget();
36283581 if (inst_ty.isInt() and inst_ty.bitSize(target) > 64)
3629 return airBinBuiltinCall(f, inst, operation[1..], .None);
3582 return try airBinBuiltinCall(f, inst, operation[1..], .None);
36303583 if (inst_ty.isRuntimeFloat())
3631 return airBinFloatOp(f, inst, operation);
3584 return try airBinFloatOp(f, inst, operation);
36323585
36333586 const lhs = try f.resolveInst(bin_op.lhs);
36343587 const rhs = try f.resolveInst(bin_op.rhs);
36353588
36363589 const writer = f.object.writer();
3590 const local = try f.allocLocal(inst_ty, .Const);
36373591
36383592 // (lhs <> rhs) ? lhs : rhs
3639 try writer.writeAll("(");
3593 try writer.writeAll(" = (");
36403594 try f.writeCValue(writer, lhs, .Other);
36413595 try writer.writeByte(' ');
36423596 try writer.writeByte(operator);
......@@ -3646,6 +3600,9 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
36463600 try f.writeCValue(writer, lhs, .Other);
36473601 try writer.writeAll(" : ");
36483602 try f.writeCValue(writer, rhs, .Other);
3603 try writer.writeAll(";\n");
3604
3605 return local;
36493606}
36503607
36513608fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
......@@ -3961,7 +3918,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
39613918 if (f.liveness.isUnused(inst) or !src_ty.hasRuntimeBits()) return CValue.none;
39623919
39633920 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3964 const operand = try f.resolveInstNoInline(ty_op.operand);
3921 const operand = try f.resolveInst(ty_op.operand);
39653922 const dest_ty = f.air.typeOf(ty_op.operand);
39663923 const target = f.object.dg.module.getTarget();
39673924
......@@ -4067,7 +4024,7 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
40674024 const body = f.air.extra[loop.end..][0..loop.data.body_len];
40684025 const writer = f.object.writer();
40694026 try writer.writeAll("while (");
4070 try f.object.dg.renderValue(writer, Type.bool, Value.true, .condition);
4027 try f.object.dg.renderValue(writer, Type.bool, Value.true, .Other);
40714028 try writer.writeAll(") ");
40724029 try genBody(f, body);
40734030 try writer.writeByte('\n');
......@@ -4083,7 +4040,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
40834040 const writer = f.object.writer();
40844041
40854042 try writer.writeAll("if (");
4086 try f.writeCValue(writer, cond, .condition);
4043 try f.writeCValue(writer, cond, .Other);
40874044 try writer.writeAll(") ");
40884045 try genBody(f, then_body);
40894046 try writer.writeAll(" else ");
......@@ -5174,12 +5131,16 @@ fn airBinBuiltinCall(
51745131 inst: Air.Inst.Index,
51755132 operation: []const u8,
51765133 info: BuiltinInfo,
5177) !void {
5134) !CValue {
5135 if (f.liveness.isUnused(inst)) return CValue.none;
5136
5137 const inst_ty = f.air.typeOfIndex(inst);
51785138 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
51795139 const operand_ty = f.air.typeOf(bin_op.lhs);
51805140
5141 const local = try f.allocLocal(inst_ty, .Const);
51815142 const writer = f.object.writer();
5182 try writer.writeAll("zig_");
5143 try writer.writeAll(" = zig_");
51835144 try writer.writeAll(operation);
51845145 try writer.writeByte('_');
51855146 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
......@@ -5188,7 +5149,8 @@ fn airBinBuiltinCall(
51885149 try writer.writeAll(", ");
51895150 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);
51905151 try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
5191 try writer.writeAll(")");
5152 try writer.writeAll(");\n");
5153 return local;
51925154}
51935155
51945156fn airCmpBuiltinCall(
......@@ -5196,12 +5158,16 @@ fn airCmpBuiltinCall(
51965158 inst: Air.Inst.Index,
51975159 operator: []const u8,
51985160 operation: []const u8,
5199) !void {
5161) !CValue {
5162 if (f.liveness.isUnused(inst)) return CValue.none;
5163
5164 const inst_ty = f.air.typeOfIndex(inst);
52005165 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
52015166 const operand_ty = f.air.typeOf(bin_op.lhs);
52025167
5168 const local = try f.allocLocal(inst_ty, .Const);
52035169 const writer = f.object.writer();
5204 try writer.writeAll("zig_");
5170 try writer.writeAll(" = zig_");
52055171 try writer.writeAll(operation);
52065172 try writer.writeByte('_');
52075173 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
......@@ -5209,7 +5175,8 @@ fn airCmpBuiltinCall(
52095175 try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument);
52105176 try writer.writeAll(", ");
52115177 try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument);
5212 try writer.print(") {s} {}", .{ operator, try f.fmtIntLiteral(Type.initTag(.i32), Value.zero) });
5178 try writer.print(") {s} {};\n", .{ operator, try f.fmtIntLiteral(Type.initTag(.i32), Value.zero) });
5179 return local;
52135180}
52145181
52155182fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
......@@ -5946,18 +5913,15 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
59465913 return local;
59475914}
59485915
5949fn airBinFloatOp(
5950 f: *Function,
5951 inst: Air.Inst.Index,
5952 operation: []const u8,
5953) !void {
5916fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
5917 if (f.liveness.isUnused(inst)) return CValue.none;
59545918 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
59555919 const writer = f.object.writer();
59565920 const inst_ty = f.air.typeOfIndex(inst);
59575921 const lhs = try f.resolveInst(bin_op.lhs);
59585922 const rhs = try f.resolveInst(bin_op.rhs);
5959
5960 try writer.writeAll("zig_libc_name_");
5923 const local = try f.allocLocal(inst_ty, .Const);
5924 try writer.writeAll(" = zig_libc_name_");
59615925 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
59625926 try writer.writeByte('(');
59635927 try writer.writeAll(operation);
......@@ -5965,7 +5929,8 @@ fn airBinFloatOp(
59655929 try f.writeCValue(writer, lhs, .FunctionArgument);
59665930 try writer.writeAll(", ");
59675931 try f.writeCValue(writer, rhs, .FunctionArgument);
5968 try writer.writeAll(")");
5932 try writer.writeAll(");\n");
5933 return local;
59695934}
59705935
59715936fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {