| ... | ... | @@ -395,27 +395,6 @@ pub const Function = struct { |
| 395 | 395 | .shl, => try airBinBuiltinCall(f, inst, "shlw", .Bits), |
| 396 | 396 | .shl_exact => try airBinOp(f, inst, "<<", "shl", .None), |
| 397 | 397 | .not => try airNot (f, inst), |
| 398 | | |
| 399 | | .is_err => try airIsErr(f, inst, false, "!="), |
| 400 | | .is_non_err => try airIsErr(f, inst, false, "=="), |
| 401 | | .is_err_ptr => try airIsErr(f, inst, true, "!="), |
| 402 | | .is_non_err_ptr => try airIsErr(f, inst, true, "=="), |
| 403 | | |
| 404 | | .is_null => try airIsNull(f, inst, "==", false), |
| 405 | | .is_non_null => try airIsNull(f, inst, "!=", false), |
| 406 | | .is_null_ptr => try airIsNull(f, inst, "==", true), |
| 407 | | .is_non_null_ptr => try airIsNull(f, inst, "!=", true), |
| 408 | | |
| 409 | | .get_union_tag => try airGetUnionTag(f, inst), |
| 410 | | .clz => try airUnBuiltinCall(f, inst, "clz", .Bits), |
| 411 | | .ctz => try airUnBuiltinCall(f, inst, "ctz", .Bits), |
| 412 | | .popcount => try airUnBuiltinCall(f, inst, "popcount", .Bits), |
| 413 | | .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .Bits), |
| 414 | | .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .Bits), |
| 415 | | .tag_name => try airTagName(f, inst), |
| 416 | | .error_name => try airErrorName(f, inst), |
| 417 | | |
| 418 | | .ptrtoint => try airPtrToInt(f, inst), |
| 419 | 398 | else => unreachable, |
| 420 | 399 | // zig fmt: on |
| 421 | 400 | } |
| ... | ... | @@ -443,7 +422,6 @@ pub const Function = struct { |
| 443 | 422 | try w.writeByte('.'); |
| 444 | 423 | return f.writeCValue(w, member, .Other); |
| 445 | 424 | }, |
| 446 | | .inline_index => unreachable, // Use resolveInstNoInline |
| 447 | 425 | else => return f.object.dg.writeCValueMember(w, c_value, member), |
| 448 | 426 | } |
| 449 | 427 | } |
| ... | ... | @@ -2729,15 +2707,15 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2729 | 2707 | .optional_payload_ptr_set => try airOptionalPayloadPtrSet(f, inst), |
| 2730 | 2708 | .wrap_optional => try airWrapOptional(f, inst), |
| 2731 | 2709 | |
| 2732 | | .is_err => CValue{ .inline_index = inst }, |
| 2733 | | .is_non_err => CValue{ .inline_index = inst }, |
| 2734 | | .is_err_ptr => CValue{ .inline_index = inst }, |
| 2735 | | .is_non_err_ptr => CValue{ .inline_index = inst }, |
| 2710 | .is_err => try airIsErr(f, inst, false, "!="), |
| 2711 | .is_non_err => try airIsErr(f, inst, false, "=="), |
| 2712 | .is_err_ptr => try airIsErr(f, inst, true, "!="), |
| 2713 | .is_non_err_ptr => try airIsErr(f, inst, true, "=="), |
| 2736 | 2714 | |
| 2737 | | .is_null => CValue{ .inline_index = inst }, |
| 2738 | | .is_non_null => CValue{ .inline_index = inst }, |
| 2739 | | .is_null_ptr => CValue{ .inline_index = inst }, |
| 2740 | | .is_non_null_ptr => CValue{ .inline_index = inst }, |
| 2715 | .is_null => try airIsNull(f, inst, "==", false), |
| 2716 | .is_non_null => try airIsNull(f, inst, "!=", false), |
| 2717 | .is_null_ptr => try airIsNull(f, inst, "==", true), |
| 2718 | .is_non_null_ptr => try airIsNull(f, inst, "!=", true), |
| 2741 | 2719 | |
| 2742 | 2720 | .alloc => try airAlloc(f, inst), |
| 2743 | 2721 | .ret_ptr => try airRetPtr(f, inst), |
| ... | ... | @@ -2765,14 +2743,14 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2765 | 2743 | .memset => try airMemset(f, inst), |
| 2766 | 2744 | .memcpy => try airMemcpy(f, inst), |
| 2767 | 2745 | .set_union_tag => try airSetUnionTag(f, inst), |
| 2768 | | .get_union_tag => CValue{ .inline_index = inst }, |
| 2769 | | .clz => CValue{ .inline_index = inst }, |
| 2770 | | .ctz => CValue{ .inline_index = inst }, |
| 2771 | | .popcount => CValue{ .inline_index = inst }, |
| 2772 | | .byte_swap => CValue{ .inline_index = inst }, |
| 2773 | | .bit_reverse => CValue{ .inline_index = inst }, |
| 2774 | | .tag_name => CValue{ .inline_index = inst }, |
| 2775 | | .error_name => CValue{ .inline_index = inst }, |
| 2746 | .get_union_tag => try airGetUnionTag(f, inst), |
| 2747 | .clz => try airUnBuiltinCall(f, inst, "clz", .Bits), |
| 2748 | .ctz => try airUnBuiltinCall(f, inst, "ctz", .Bits), |
| 2749 | .popcount => try airUnBuiltinCall(f, inst, "popcount", .Bits), |
| 2750 | .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .Bits), |
| 2751 | .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .Bits), |
| 2752 | .tag_name => try airTagName(f, inst), |
| 2753 | .error_name => try airErrorName(f, inst), |
| 2776 | 2754 | .splat => try airSplat(f, inst), |
| 2777 | 2755 | .select => try airSelect(f, inst), |
| 2778 | 2756 | .shuffle => try airShuffle(f, inst), |
| ... | ... | @@ -2808,7 +2786,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2808 | 2786 | .fpext, |
| 2809 | 2787 | => try airFloatCast(f, inst), |
| 2810 | 2788 | |
| 2811 | | .ptrtoint => CValue{ .inline_index = inst }, |
| 2789 | .ptrtoint => try airPtrToInt(f, inst), |
| 2812 | 2790 | |
| 2813 | 2791 | .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)), |
| 2814 | 2792 | .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)), |
| ... | ... | @@ -2889,7 +2867,7 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ |
| 2889 | 2867 | |
| 2890 | 2868 | const inst_ty = f.air.typeOfIndex(inst); |
| 2891 | 2869 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 2892 | | const operand = try f.resolveInstNoInline(ty_op.operand); |
| 2870 | const operand = try f.resolveInst(ty_op.operand); |
| 2893 | 2871 | const writer = f.object.writer(); |
| 2894 | 2872 | const local = try f.allocLocal(inst_ty, .Const); |
| 2895 | 2873 | try writer.writeAll(" = "); |
| ... | ... | @@ -4425,11 +4403,16 @@ fn airIsNull( |
| 4425 | 4403 | inst: Air.Inst.Index, |
| 4426 | 4404 | operator: []const u8, |
| 4427 | 4405 | is_ptr: bool, |
| 4428 | | ) !void { |
| 4406 | ) !CValue { |
| 4407 | if (f.liveness.isUnused(inst)) |
| 4408 | return CValue.none; |
| 4409 | |
| 4429 | 4410 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 4430 | 4411 | const writer = f.object.writer(); |
| 4431 | 4412 | const operand = try f.resolveInst(un_op); |
| 4432 | 4413 | |
| 4414 | const local = try f.allocLocal(Type.initTag(.bool), .Const); |
| 4415 | try writer.writeAll(" = "); |
| 4433 | 4416 | try if (is_ptr) f.writeCValueDeref(writer, operand) else f.writeCValue(writer, operand, .Other); |
| 4434 | 4417 | |
| 4435 | 4418 | const operand_ty = f.air.typeOf(un_op); |
| ... | ... | @@ -4457,6 +4440,8 @@ fn airIsNull( |
| 4457 | 4440 | try writer.writeAll(operator); |
| 4458 | 4441 | try writer.writeByte(' '); |
| 4459 | 4442 | try f.object.dg.renderValue(writer, rhs.ty, rhs.val, .Other); |
| 4443 | try writer.writeAll(";\n"); |
| 4444 | return local; |
| 4460 | 4445 | } |
| 4461 | 4446 | |
| 4462 | 4447 | fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | ... | @@ -5038,15 +5023,21 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5038 | 5023 | return local; |
| 5039 | 5024 | } |
| 5040 | 5025 | |
| 5041 | | fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !void { |
| 5026 | fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue { |
| 5027 | if (f.liveness.isUnused(inst)) |
| 5028 | return CValue.none; |
| 5029 | |
| 5042 | 5030 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 5043 | 5031 | const writer = f.object.writer(); |
| 5044 | 5032 | const operand = try f.resolveInst(un_op); |
| 5045 | 5033 | const operand_ty = f.air.typeOf(un_op); |
| 5034 | const local = try f.allocLocal(Type.initTag(.bool), .Const); |
| 5046 | 5035 | const err_union_ty = if (is_ptr) operand_ty.childType() else operand_ty; |
| 5047 | 5036 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 5048 | 5037 | const error_ty = err_union_ty.errorUnionSet(); |
| 5049 | 5038 | |
| 5039 | try writer.writeAll(" = "); |
| 5040 | |
| 5050 | 5041 | if (!error_ty.errorSetIsEmpty()) |
| 5051 | 5042 | if (payload_ty.hasRuntimeBits()) |
| 5052 | 5043 | if (is_ptr) |
| ... | ... | @@ -5061,6 +5052,8 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const |
| 5061 | 5052 | try writer.writeAll(operator); |
| 5062 | 5053 | try writer.writeByte(' '); |
| 5063 | 5054 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); |
| 5055 | try writer.writeAll(";\n"); |
| 5056 | return local; |
| 5064 | 5057 | } |
| 5065 | 5058 | |
| 5066 | 5059 | fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | ... | @@ -5134,16 +5127,21 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5134 | 5127 | return local; |
| 5135 | 5128 | } |
| 5136 | 5129 | |
| 5137 | | fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !void { |
| 5130 | fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5131 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 5132 | |
| 5138 | 5133 | const inst_ty = f.air.typeOfIndex(inst); |
| 5134 | const local = try f.allocLocal(inst_ty, .Const); |
| 5139 | 5135 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 5140 | 5136 | const writer = f.object.writer(); |
| 5141 | 5137 | const operand = try f.resolveInst(un_op); |
| 5142 | 5138 | |
| 5143 | | try writer.writeAll("("); |
| 5139 | try writer.writeAll(" = ("); |
| 5144 | 5140 | try f.renderTypecast(writer, inst_ty); |
| 5145 | 5141 | try writer.writeByte(')'); |
| 5146 | 5142 | try f.writeCValue(writer, operand, .Other); |
| 5143 | try writer.writeAll(";\n"); |
| 5144 | return local; |
| 5147 | 5145 | } |
| 5148 | 5146 | |
| 5149 | 5147 | fn airUnBuiltinCall( |
| ... | ... | @@ -5151,19 +5149,24 @@ fn airUnBuiltinCall( |
| 5151 | 5149 | inst: Air.Inst.Index, |
| 5152 | 5150 | operation: []const u8, |
| 5153 | 5151 | info: BuiltinInfo, |
| 5154 | | ) !void { |
| 5152 | ) !CValue { |
| 5153 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 5154 | |
| 5155 | const inst_ty = f.air.typeOfIndex(inst); |
| 5155 | 5156 | const operand = f.air.instructions.items(.data)[inst].ty_op.operand; |
| 5156 | 5157 | const operand_ty = f.air.typeOf(operand); |
| 5157 | 5158 | |
| 5159 | const local = try f.allocLocal(inst_ty, .Const); |
| 5158 | 5160 | const writer = f.object.writer(); |
| 5159 | | try writer.writeAll("zig_"); |
| 5161 | try writer.writeAll(" = zig_"); |
| 5160 | 5162 | try writer.writeAll(operation); |
| 5161 | 5163 | try writer.writeByte('_'); |
| 5162 | 5164 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); |
| 5163 | 5165 | try writer.writeByte('('); |
| 5164 | 5166 | try f.writeCValue(writer, try f.resolveInst(operand), .FunctionArgument); |
| 5165 | 5167 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); |
| 5166 | | try writer.writeAll(")"); |
| 5168 | try writer.writeAll(");\n"); |
| 5169 | return local; |
| 5167 | 5170 | } |
| 5168 | 5171 | |
| 5169 | 5172 | fn airBinBuiltinCall( |
| ... | ... | @@ -5436,7 +5439,12 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5436 | 5439 | return CValue.none; |
| 5437 | 5440 | } |
| 5438 | 5441 | |
| 5439 | | fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !void { |
| 5442 | fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5443 | if (f.liveness.isUnused(inst)) |
| 5444 | return CValue.none; |
| 5445 | |
| 5446 | const inst_ty = f.air.typeOfIndex(inst); |
| 5447 | const local = try f.allocLocal(inst_ty, .Const); |
| 5440 | 5448 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 5441 | 5449 | const un_ty = f.air.typeOf(ty_op.operand); |
| 5442 | 5450 | const writer = f.object.writer(); |
| ... | ... | @@ -5444,31 +5452,44 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !void { |
| 5444 | 5452 | |
| 5445 | 5453 | const target = f.object.dg.module.getTarget(); |
| 5446 | 5454 | const layout = un_ty.unionGetLayout(target); |
| 5447 | | assert(layout.tag_size != 0); |
| 5455 | if (layout.tag_size == 0) return CValue.none; |
| 5448 | 5456 | |
| 5457 | try writer.writeAll(" = "); |
| 5449 | 5458 | try f.writeCValue(writer, operand, .Other); |
| 5450 | | try writer.writeAll(".tag"); |
| 5459 | try writer.writeAll(".tag;\n"); |
| 5460 | return local; |
| 5451 | 5461 | } |
| 5452 | 5462 | |
| 5453 | | fn airTagName(f: *Function, inst: Air.Inst.Index) !void { |
| 5463 | fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5464 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 5465 | |
| 5454 | 5466 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 5467 | const inst_ty = f.air.typeOfIndex(inst); |
| 5455 | 5468 | const enum_ty = f.air.typeOf(un_op); |
| 5456 | 5469 | const operand = try f.resolveInst(un_op); |
| 5457 | 5470 | |
| 5458 | 5471 | const writer = f.object.writer(); |
| 5459 | | try writer.print("{s}(", .{try f.object.dg.getTagNameFn(enum_ty)}); |
| 5472 | const local = try f.allocLocal(inst_ty, .Const); |
| 5473 | try writer.print(" = {s}(", .{try f.object.dg.getTagNameFn(enum_ty)}); |
| 5460 | 5474 | try f.writeCValue(writer, operand, .Other); |
| 5461 | | try writer.writeAll(")"); |
| 5475 | try writer.writeAll(");\n"); |
| 5476 | |
| 5477 | return local; |
| 5462 | 5478 | } |
| 5463 | 5479 | |
| 5464 | | fn airErrorName(f: *Function, inst: Air.Inst.Index) !void { |
| 5480 | fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5481 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 5482 | |
| 5465 | 5483 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 5466 | 5484 | const writer = f.object.writer(); |
| 5485 | const inst_ty = f.air.typeOfIndex(inst); |
| 5467 | 5486 | const operand = try f.resolveInst(un_op); |
| 5487 | const local = try f.allocLocal(inst_ty, .Const); |
| 5468 | 5488 | |
| 5469 | | try writer.writeAll("zig_errorName["); |
| 5489 | try writer.writeAll(" = zig_errorName["); |
| 5470 | 5490 | try f.writeCValue(writer, operand, .Other); |
| 5471 | | try writer.writeAll("]"); |
| 5491 | try writer.writeAll("];\n"); |
| 5492 | return local; |
| 5472 | 5493 | } |
| 5473 | 5494 | |
| 5474 | 5495 | fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { |