/* * Copyright (c) 2016 Andrew Kelley * * This file is part of zig, which is MIT licensed. * See http://opensource.org/licenses/MIT */ #include "all_types.hpp" #include "analyze.hpp" #include "ir.hpp" #include "astgen.hpp" #include "ir_print.hpp" #include "os.hpp" static uint32_t hash_inst_src_ptr(Stage1ZirInst* instruction) { return (uint32_t)(uintptr_t)instruction; } static uint32_t hash_inst_gen_ptr(Stage1AirInst* instruction) { return (uint32_t)(uintptr_t)instruction; } static bool inst_src_ptr_eql(Stage1ZirInst* a, Stage1ZirInst* b) { return a == b; } static bool inst_gen_ptr_eql(Stage1AirInst* a, Stage1AirInst* b) { return a == b; } using InstSetSrc = HashMap; using InstSetGen = HashMap; using InstListSrc = ZigList; using InstListGen = ZigList; struct IrPrintSrc { CodeGen *codegen; FILE *f; int indent; int indent_size; }; struct IrPrintGen { CodeGen *codegen; FILE *f; int indent; int indent_size; // When printing pass 2 instructions referenced var instructions are not // present in the instruction list. Thus we track which instructions // are printed (per executable) and after each pass 2 instruction those // var instructions are rendered in a trailing fashion. InstSetGen printed; InstListGen pending; }; static void ir_print_other_inst_src(IrPrintSrc *irp, Stage1ZirInst *inst); static void ir_print_other_inst_gen(IrPrintGen *irp, Stage1AirInst *inst); static void ir_print_call_modifier(FILE *f, CallModifier modifier) { switch (modifier) { case CallModifierNone: break; case CallModifierNoSuspend: fprintf(f, "nosuspend "); break; case CallModifierAsync: fprintf(f, "async "); break; case CallModifierNeverTail: fprintf(f, "notail "); break; case CallModifierNeverInline: fprintf(f, "noinline "); break; case CallModifierAlwaysTail: fprintf(f, "tail "); break; case CallModifierAlwaysInline: fprintf(f, "inline "); break; case CallModifierCompileTime: fprintf(f, "comptime "); break; case CallModifierBuiltin: zig_unreachable(); } } const char* ir_inst_src_type_str(Stage1ZirInstId id) { switch (id) { case Stage1ZirInstIdInvalid: return "SrcInvalid"; case Stage1ZirInstIdShuffleVector: return "SrcShuffle"; case Stage1ZirInstIdSelect: return "SrcSelect"; case Stage1ZirInstIdSplat: return "SrcSplat"; case Stage1ZirInstIdDeclVar: return "SrcDeclVar"; case Stage1ZirInstIdBr: return "SrcBr"; case Stage1ZirInstIdCondBr: return "SrcCondBr"; case Stage1ZirInstIdSwitchBr: return "SrcSwitchBr"; case Stage1ZirInstIdSwitchVar: return "SrcSwitchVar"; case Stage1ZirInstIdSwitchElseVar: return "SrcSwitchElseVar"; case Stage1ZirInstIdSwitchTarget: return "SrcSwitchTarget"; case Stage1ZirInstIdPhi: return "SrcPhi"; case Stage1ZirInstIdUnOp: return "SrcUnOp"; case Stage1ZirInstIdBinOp: return "SrcBinOp"; case Stage1ZirInstIdMergeErrSets: return "SrcMergeErrSets"; case Stage1ZirInstIdLoadPtr: return "SrcLoadPtr"; case Stage1ZirInstIdStorePtr: return "SrcStorePtr"; case Stage1ZirInstIdFieldPtr: return "SrcFieldPtr"; case Stage1ZirInstIdElemPtr: return "SrcElemPtr"; case Stage1ZirInstIdVarPtr: return "SrcVarPtr"; case Stage1ZirInstIdCallExtra: return "SrcCallExtra"; case Stage1ZirInstIdAsyncCallExtra: return "SrcAsyncCallExtra"; case Stage1ZirInstIdCall: return "SrcCall"; case Stage1ZirInstIdCallArgs: return "SrcCallArgs"; case Stage1ZirInstIdConst: return "SrcConst"; case Stage1ZirInstIdReturn: return "SrcReturn"; case Stage1ZirInstIdContainerInitList: return "SrcContainerInitList"; case Stage1ZirInstIdContainerInitFields: return "SrcContainerInitFields"; case Stage1ZirInstIdUnreachable: return "SrcUnreachable"; case Stage1ZirInstIdTypeOf: return "SrcTypeOf"; case Stage1ZirInstIdSetCold: return "SrcSetCold"; case Stage1ZirInstIdSetRuntimeSafety: return "SrcSetRuntimeSafety"; case Stage1ZirInstIdSetFloatMode: return "SrcSetFloatMode"; case Stage1ZirInstIdArrayType: return "SrcArrayType"; case Stage1ZirInstIdAnyFrameType: return "SrcAnyFrameType"; case Stage1ZirInstIdSliceType: return "SrcSliceType"; case Stage1ZirInstIdAsm: return "SrcAsm"; case Stage1ZirInstIdSizeOf: return "SrcSizeOf"; case Stage1ZirInstIdTestNonNull: return "SrcTestNonNull"; case Stage1ZirInstIdOptionalUnwrapPtr: return "SrcOptionalUnwrapPtr"; case Stage1ZirInstIdClz: return "SrcClz"; case Stage1ZirInstIdCtz: return "SrcCtz"; case Stage1ZirInstIdPopCount: return "SrcPopCount"; case Stage1ZirInstIdBswap: return "SrcBswap"; case Stage1ZirInstIdBitReverse: return "SrcBitReverse"; case Stage1ZirInstIdImport: return "SrcImport"; case Stage1ZirInstIdCImport: return "SrcCImport"; case Stage1ZirInstIdCInclude: return "SrcCInclude"; case Stage1ZirInstIdCDefine: return "SrcCDefine"; case Stage1ZirInstIdCUndef: return "SrcCUndef"; case Stage1ZirInstIdRef: return "SrcRef"; case Stage1ZirInstIdCompileErr: return "SrcCompileErr"; case Stage1ZirInstIdCompileLog: return "SrcCompileLog"; case Stage1ZirInstIdErrName: return "SrcErrName"; case Stage1ZirInstIdEmbedFile: return "SrcEmbedFile"; case Stage1ZirInstIdCmpxchg: return "SrcCmpxchg"; case Stage1ZirInstIdFence: return "SrcFence"; case Stage1ZirInstIdReduce: return "SrcReduce"; case Stage1ZirInstIdTruncate: return "SrcTruncate"; case Stage1ZirInstIdIntCast: return "SrcIntCast"; case Stage1ZirInstIdFloatCast: return "SrcFloatCast"; case Stage1ZirInstIdIntToFloat: return "SrcIntToFloat"; case Stage1ZirInstIdFloatToInt: return "SrcFloatToInt"; case Stage1ZirInstIdBoolToInt: return "SrcBoolToInt"; case Stage1ZirInstIdVectorType: return "SrcVectorType"; case Stage1ZirInstIdBoolNot: return "SrcBoolNot"; case Stage1ZirInstIdMemset: return "SrcMemset"; case Stage1ZirInstIdMemcpy: return "SrcMemcpy"; case Stage1ZirInstIdSlice: return "SrcSlice"; case Stage1ZirInstIdBreakpoint: return "SrcBreakpoint"; case Stage1ZirInstIdReturnAddress: return "SrcReturnAddress"; case Stage1ZirInstIdFrameAddress: return "SrcFrameAddress"; case Stage1ZirInstIdFrameHandle: return "SrcFrameHandle"; case Stage1ZirInstIdFrameType: return "SrcFrameType"; case Stage1ZirInstIdFrameSize: return "SrcFrameSize"; case Stage1ZirInstIdAlignOf: return "SrcAlignOf"; case Stage1ZirInstIdOverflowOp: return "SrcOverflowOp"; case Stage1ZirInstIdTestErr: return "SrcTestErr"; case Stage1ZirInstIdMulAdd: return "SrcMulAdd"; case Stage1ZirInstIdFloatOp: return "SrcFloatOp"; case Stage1ZirInstIdUnwrapErrCode: return "SrcUnwrapErrCode"; case Stage1ZirInstIdUnwrapErrPayload: return "SrcUnwrapErrPayload"; case Stage1ZirInstIdFnProto: return "SrcFnProto"; case Stage1ZirInstIdTestComptime: return "SrcTestComptime"; case Stage1ZirInstIdPtrCast: return "SrcPtrCast"; case Stage1ZirInstIdBitCast: return "SrcBitCast"; case Stage1ZirInstIdIntToPtr: return "SrcIntToPtr"; case Stage1ZirInstIdPtrToInt: return "SrcPtrToInt"; case Stage1ZirInstIdIntToEnum: return "SrcIntToEnum"; case Stage1ZirInstIdEnumToInt: return "SrcEnumToInt"; case Stage1ZirInstIdIntToErr: return "SrcIntToErr"; case Stage1ZirInstIdErrToInt: return "SrcErrToInt"; case Stage1ZirInstIdCheckSwitchProngsUnderNo: return "SrcCheckSwitchProngsUnderNo"; case Stage1ZirInstIdCheckSwitchProngsUnderYes: return "SrcCheckSwitchProngsUnderYes"; case Stage1ZirInstIdCheckStatementIsVoid: return "SrcCheckStatementIsVoid"; case Stage1ZirInstIdTypeName: return "SrcTypeName"; case Stage1ZirInstIdDeclRef: return "SrcDeclRef"; case Stage1ZirInstIdPanic: return "SrcPanic"; case Stage1ZirInstIdTagName: return "SrcTagName"; case Stage1ZirInstIdFieldParentPtr: return "SrcFieldParentPtr"; case Stage1ZirInstIdOffsetOf: return "SrcOffsetOf"; case Stage1ZirInstIdBitOffsetOf: return "SrcBitOffsetOf"; case Stage1ZirInstIdTypeInfo: return "SrcTypeInfo"; case Stage1ZirInstIdType: return "SrcType"; case Stage1ZirInstIdHasField: return "SrcHasField"; case Stage1ZirInstIdSetEvalBranchQuota: return "SrcSetEvalBranchQuota"; case Stage1ZirInstIdPtrType: return "SrcPtrType"; case Stage1ZirInstIdPtrTypeSimple: return "SrcPtrTypeSimple"; case Stage1ZirInstIdPtrTypeSimpleConst: return "SrcPtrTypeSimpleConst"; case Stage1ZirInstIdAlignCast: return "SrcAlignCast"; case Stage1ZirInstIdImplicitCast: return "SrcImplicitCast"; case Stage1ZirInstIdResolveResult: return "SrcResolveResult"; case Stage1ZirInstIdResetResult: return "SrcResetResult"; case Stage1ZirInstIdSetAlignStack: return "SrcSetAlignStack"; case Stage1ZirInstIdArgTypeAllowVarFalse: return "SrcArgTypeAllowVarFalse"; case Stage1ZirInstIdArgTypeAllowVarTrue: return "SrcArgTypeAllowVarTrue"; case Stage1ZirInstIdExport: return "SrcExport"; case Stage1ZirInstIdExtern: return "SrcExtern"; case Stage1ZirInstIdErrorReturnTrace: return "SrcErrorReturnTrace"; case Stage1ZirInstIdErrorUnion: return "SrcErrorUnion"; case Stage1ZirInstIdAtomicRmw: return "SrcAtomicRmw"; case Stage1ZirInstIdAtomicLoad: return "SrcAtomicLoad"; case Stage1ZirInstIdAtomicStore: return "SrcAtomicStore"; case Stage1ZirInstIdSaveErrRetAddr: return "SrcSaveErrRetAddr"; case Stage1ZirInstIdAddImplicitReturnType: return "SrcAddImplicitReturnType"; case Stage1ZirInstIdErrSetCast: return "SrcErrSetCast"; case Stage1ZirInstIdCheckRuntimeScope: return "SrcCheckRuntimeScope"; case Stage1ZirInstIdHasDecl: return "SrcHasDecl"; case Stage1ZirInstIdUndeclaredIdent: return "SrcUndeclaredIdent"; case Stage1ZirInstIdAlloca: return "SrcAlloca"; case Stage1ZirInstIdEndExpr: return "SrcEndExpr"; case Stage1ZirInstIdUnionInitNamedField: return "SrcUnionInitNamedField"; case Stage1ZirInstIdSuspendBegin: return "SrcSuspendBegin"; case Stage1ZirInstIdSuspendFinish: return "SrcSuspendFinish"; case Stage1ZirInstIdAwait: return "SrcAwaitSr"; case Stage1ZirInstIdResume: return "SrcResume"; case Stage1ZirInstIdSpillBegin: return "SrcSpillBegin"; case Stage1ZirInstIdSpillEnd: return "SrcSpillEnd"; case Stage1ZirInstIdWasmMemorySize: return "SrcWasmMemorySize"; case Stage1ZirInstIdWasmMemoryGrow: return "SrcWasmMemoryGrow"; case Stage1ZirInstIdSrc: return "SrcSrc"; case Stage1ZirInstIdPrefetch: return "SrcPrefetch"; } zig_unreachable(); } const char* ir_inst_gen_type_str(Stage1AirInstId id) { switch (id) { case Stage1AirInstIdInvalid: return "GenInvalid"; case Stage1AirInstIdShuffleVector: return "GenShuffle"; case Stage1AirInstIdSelect: return "GenSelect"; case Stage1AirInstIdSplat: return "GenSplat"; case Stage1AirInstIdDeclVar: return "GenDeclVar"; case Stage1AirInstIdBr: return "GenBr"; case Stage1AirInstIdCondBr: return "GenCondBr"; case Stage1AirInstIdSwitchBr: return "GenSwitchBr"; case Stage1AirInstIdPhi: return "GenPhi"; case Stage1AirInstIdBinOp: return "GenBinOp"; case Stage1AirInstIdLoadPtr: return "GenLoadPtr"; case Stage1AirInstIdStorePtr: return "GenStorePtr"; case Stage1AirInstIdVectorStoreElem: return "GenVectorStoreElem"; case Stage1AirInstIdStructFieldPtr: return "GenStructFieldPtr"; case Stage1AirInstIdUnionFieldPtr: return "GenUnionFieldPtr"; case Stage1AirInstIdElemPtr: return "GenElemPtr"; case Stage1AirInstIdVarPtr: return "GenVarPtr"; case Stage1AirInstIdReturnPtr: return "GenReturnPtr"; case Stage1AirInstIdCall: return "GenCall"; case Stage1AirInstIdConst: return "GenConst"; case Stage1AirInstIdReturn: return "GenReturn"; case Stage1AirInstIdCast: return "GenCast"; case Stage1AirInstIdUnreachable: return "GenUnreachable"; case Stage1AirInstIdAsm: return "GenAsm"; case Stage1AirInstIdTestNonNull: return "GenTestNonNull"; case Stage1AirInstIdOptionalUnwrapPtr: return "GenOptionalUnwrapPtr"; case Stage1AirInstIdOptionalWrap: return "GenOptionalWrap"; case Stage1AirInstIdUnionTag: return "GenUnionTag"; case Stage1AirInstIdClz: return "GenClz"; case Stage1AirInstIdCtz: return "GenCtz"; case Stage1AirInstIdPopCount: return "GenPopCount"; case Stage1AirInstIdBswap: return "GenBswap"; case Stage1AirInstIdBitReverse: return "GenBitReverse"; case Stage1AirInstIdRef: return "GenRef"; case Stage1AirInstIdErrName: return "GenErrName"; case Stage1AirInstIdCmpxchg: return "GenCmpxchg"; case Stage1AirInstIdFence: return "GenFence"; case Stage1AirInstIdReduce: return "GenReduce"; case Stage1AirInstIdTruncate: return "GenTruncate"; case Stage1AirInstIdBoolNot: return "GenBoolNot"; case Stage1AirInstIdMemset: return "GenMemset"; case Stage1AirInstIdMemcpy: return "GenMemcpy"; case Stage1AirInstIdSlice: return "GenSlice"; case Stage1AirInstIdBreakpoint: return "GenBreakpoint"; case Stage1AirInstIdReturnAddress: return "GenReturnAddress"; case Stage1AirInstIdFrameAddress: return "GenFrameAddress"; case Stage1AirInstIdFrameHandle: return "GenFrameHandle"; case Stage1AirInstIdFrameSize: return "GenFrameSize"; case Stage1AirInstIdOverflowOp: return "GenOverflowOp"; case Stage1AirInstIdTestErr: return "GenTestErr"; case Stage1AirInstIdMulAdd: return "GenMulAdd"; case Stage1AirInstIdFloatOp: return "GenFloatOp"; case Stage1AirInstIdUnwrapErrCode: return "GenUnwrapErrCode"; case Stage1AirInstIdUnwrapErrPayload: return "GenUnwrapErrPayload"; case Stage1AirInstIdErrWrapCode: return "GenErrWrapCode"; case Stage1AirInstIdErrWrapPayload: return "GenErrWrapPayload"; case Stage1AirInstIdPtrCast: return "GenPtrCast"; case Stage1AirInstIdBitCast: return "GenBitCast"; case Stage1AirInstIdWidenOrShorten: return "GenWidenOrShorten"; case Stage1AirInstIdIntToPtr: return "GenIntToPtr"; case Stage1AirInstIdPtrToInt: return "GenPtrToInt"; case Stage1AirInstIdIntToEnum: return "GenIntToEnum"; case Stage1AirInstIdIntToErr: return "GenIntToErr"; case Stage1AirInstIdErrToInt: return "GenErrToInt"; case Stage1AirInstIdPanic: return "GenPanic"; case Stage1AirInstIdTagName: return "GenTagName"; case Stage1AirInstIdFieldParentPtr: return "GenFieldParentPtr"; case Stage1AirInstIdAlignCast: return "GenAlignCast"; case Stage1AirInstIdErrorReturnTrace: return "GenErrorReturnTrace"; case Stage1AirInstIdAtomicRmw: return "GenAtomicRmw"; case Stage1AirInstIdAtomicLoad: return "GenAtomicLoad"; case Stage1AirInstIdAtomicStore: return "GenAtomicStore"; case Stage1AirInstIdSaveErrRetAddr: return "GenSaveErrRetAddr"; case Stage1AirInstIdVectorToArray: return "GenVectorToArray"; case Stage1AirInstIdArrayToVector: return "GenArrayToVector"; case Stage1AirInstIdAssertZero: return "GenAssertZero"; case Stage1AirInstIdAssertNonNull: return "GenAssertNonNull"; case Stage1AirInstIdAlloca: return "GenAlloca"; case Stage1AirInstIdPtrOfArrayToSlice: return "GenPtrOfArrayToSlice"; case Stage1AirInstIdSuspendBegin: return "GenSuspendBegin"; case Stage1AirInstIdSuspendFinish: return "GenSuspendFinish"; case Stage1AirInstIdAwait: return "GenAwait"; case Stage1AirInstIdResume: return "GenResume"; case Stage1AirInstIdSpillBegin: return "GenSpillBegin"; case Stage1AirInstIdSpillEnd: return "GenSpillEnd"; case Stage1AirInstIdVectorExtractElem: return "GenVectorExtractElem"; case Stage1AirInstIdBinaryNot: return "GenBinaryNot"; case Stage1AirInstIdNegation: return "GenNegation"; case Stage1AirInstIdWasmMemorySize: return "GenWasmMemorySize"; case Stage1AirInstIdWasmMemoryGrow: return "GenWasmMemoryGrow"; case Stage1AirInstIdExtern: return "GenExtern"; case Stage1AirInstIdPrefetch: return "GenPrefetch"; } zig_unreachable(); } static void ir_print_indent_src(IrPrintSrc *irp) { for (int i = 0; i < irp->indent; i += 1) { fprintf(irp->f, " "); } } static void ir_print_indent_gen(IrPrintGen *irp) { for (int i = 0; i < irp->indent; i += 1) { fprintf(irp->f, " "); } } static void ir_print_prefix_src(IrPrintSrc *irp, Stage1ZirInst *instruction, bool trailing) { ir_print_indent_src(irp); const char mark = trailing ? ':' : '#'; const char *type_name; if (instruction->id == Stage1ZirInstIdConst) { type_name = buf_ptr(&reinterpret_cast(instruction)->value->type->name); } else { type_name = "(unknown)"; } const char *ref_count = ir_inst_src_has_side_effects(instruction) ? "-" : buf_ptr(buf_sprintf("%" PRIu32 "", instruction->ref_count)); fprintf(irp->f, "%c%-3" PRIu32 "| %-22s| %-12s| %-2s| ", mark, instruction->debug_id, ir_inst_src_type_str(instruction->id), type_name, ref_count); } static void ir_print_prefix_gen(IrPrintGen *irp, Stage1AirInst *instruction, bool trailing) { ir_print_indent_gen(irp); const char mark = trailing ? ':' : '#'; const char *type_name = instruction->value->type ? buf_ptr(&instruction->value->type->name) : "(unknown)"; const char *ref_count = ir_inst_gen_has_side_effects(instruction) ? "-" : buf_ptr(buf_sprintf("%" PRIu32 "", instruction->ref_count)); fprintf(irp->f, "%c%-3" PRIu32 "| %-22s| %-12s| %-2s| ", mark, instruction->debug_id, ir_inst_gen_type_str(instruction->id), type_name, ref_count); } static void ir_print_var_src(IrPrintSrc *irp, Stage1ZirInst *inst) { fprintf(irp->f, "#%" PRIu32 "", inst->debug_id); } static void ir_print_var_gen(IrPrintGen *irp, Stage1AirInst *inst) { fprintf(irp->f, "#%" PRIu32 "", inst->debug_id); if (irp->printed.maybe_get(inst) == nullptr) { irp->printed.put(inst, 0); irp->pending.append(inst); } } static void ir_print_other_inst_src(IrPrintSrc *irp, Stage1ZirInst *inst) { if (inst == nullptr) { fprintf(irp->f, "(null)"); return; } ir_print_var_src(irp, inst); } static void ir_print_const_value(CodeGen *g, FILE *f, ZigValue *const_val) { Buf buf = BUF_INIT; buf_resize(&buf, 0); render_const_value(g, &buf, const_val); fprintf(f, "%s", buf_ptr(&buf)); } static void ir_print_other_inst_gen(IrPrintGen *irp, Stage1AirInst *inst) { if (inst == nullptr) { fprintf(irp->f, "(null)"); } else { ir_print_var_gen(irp, inst); } } static void ir_print_other_block(IrPrintSrc *irp, Stage1ZirBasicBlock *bb) { if (bb == nullptr) { fprintf(irp->f, "(null block)"); } else { fprintf(irp->f, "$%s_%" PRIu32 "", bb->name_hint, bb->debug_id); } } static void ir_print_other_block_gen(IrPrintGen *irp, Stage1AirBasicBlock *bb) { if (bb == nullptr) { fprintf(irp->f, "(null block)"); } else { fprintf(irp->f, "$%s_%" PRIu32 "", bb->name_hint, bb->debug_id); } } static void ir_print_return_src(IrPrintSrc *irp, Stage1ZirInstReturn *inst) { fprintf(irp->f, "return "); ir_print_other_inst_src(irp, inst->operand); } static void ir_print_return_gen(IrPrintGen *irp, Stage1AirInstReturn *inst) { fprintf(irp->f, "return "); ir_print_other_inst_gen(irp, inst->operand); } static void ir_print_const(IrPrintSrc *irp, Stage1ZirInstConst *const_instruction) { ir_print_const_value(irp->codegen, irp->f, const_instruction->value); } static void ir_print_const(IrPrintGen *irp, Stage1AirInstConst *const_instruction) { ir_print_const_value(irp->codegen, irp->f, const_instruction->base.value); } static const char *ir_bin_op_id_str(IrBinOp op_id) { switch (op_id) { case IrBinOpInvalid: zig_unreachable(); case IrBinOpBoolOr: return "BoolOr"; case IrBinOpBoolAnd: return "BoolAnd"; case IrBinOpCmpEq: return "=="; case IrBinOpCmpNotEq: return "!="; case IrBinOpCmpLessThan: return "<"; case IrBinOpCmpGreaterThan: return ">"; case IrBinOpCmpLessOrEq: return "<="; case IrBinOpCmpGreaterOrEq: return ">="; case IrBinOpBinOr: return "|"; case IrBinOpBinXor: return "^"; case IrBinOpBinAnd: return "&"; case IrBinOpBitShiftLeftLossy: return "<<"; case IrBinOpBitShiftLeftExact: return "@shlExact"; case IrBinOpBitShiftRightLossy: return ">>"; case IrBinOpBitShiftRightExact: return "@shrExact"; case IrBinOpAdd: return "+"; case IrBinOpAddWrap: return "+%"; case IrBinOpSub: return "-"; case IrBinOpSubWrap: return "-%"; case IrBinOpMult: return "*"; case IrBinOpMultWrap: return "*%"; case IrBinOpDivUnspecified: return "/"; case IrBinOpDivTrunc: return "@divTrunc"; case IrBinOpDivFloor: return "@divFloor"; case IrBinOpDivExact: return "@divExact"; case IrBinOpRemUnspecified: return "%"; case IrBinOpRemRem: return "@rem"; case IrBinOpRemMod: return "@mod"; case IrBinOpArrayCat: return "++"; case IrBinOpArrayMult: return "**"; case IrBinOpMaximum: return "@maximum"; case IrBinOpMinimum: return "@minimum"; case IrBinOpAddSat: return "@addWithSaturation"; case IrBinOpSubSat: return "@subWithSaturation"; case IrBinOpMultSat: return "@mulWithSaturation"; case IrBinOpShlSat: return "@shlWithSaturation"; } zig_unreachable(); } static const char *ir_un_op_id_str(IrUnOp op_id) { switch (op_id) { case IrUnOpInvalid: zig_unreachable(); case IrUnOpBinNot: return "~"; case IrUnOpNegation: return "-"; case IrUnOpNegationWrap: return "-%"; case IrUnOpDereference: return "*"; case IrUnOpOptional: return "?"; } zig_unreachable(); } static void ir_print_un_op(IrPrintSrc *irp, Stage1ZirInstUnOp *inst) { fprintf(irp->f, "%s ", ir_un_op_id_str(inst->op_id)); ir_print_other_inst_src(irp, inst->value); } static void ir_print_bin_op(IrPrintSrc *irp, Stage1ZirInstBinOp *bin_op_instruction) { ir_print_other_inst_src(irp, bin_op_instruction->op1); fprintf(irp->f, " %s ", ir_bin_op_id_str(bin_op_instruction->op_id)); ir_print_other_inst_src(irp, bin_op_instruction->op2); if (!bin_op_instruction->safety_check_on) { fprintf(irp->f, " // no safety"); } } static void ir_print_bin_op(IrPrintGen *irp, Stage1AirInstBinOp *bin_op_instruction) { ir_print_other_inst_gen(irp, bin_op_instruction->op1); fprintf(irp->f, " %s ", ir_bin_op_id_str(bin_op_instruction->op_id)); ir_print_other_inst_gen(irp, bin_op_instruction->op2); if (!bin_op_instruction->safety_check_on) { fprintf(irp->f, " // no safety"); } } static void ir_print_merge_err_sets(IrPrintSrc *irp, Stage1ZirInstMergeErrSets *instruction) { ir_print_other_inst_src(irp, instruction->op1); fprintf(irp->f, " || "); ir_print_other_inst_src(irp, instruction->op2); if (instruction->type_name != nullptr) { fprintf(irp->f, " // name=%s", buf_ptr(instruction->type_name)); } } static void ir_print_decl_var_src(IrPrintSrc *irp, Stage1ZirInstDeclVar *decl_var_instruction) { const char *var_or_const = decl_var_instruction->var->gen_is_const ? "const" : "var"; const char *name = decl_var_instruction->var->name; if (decl_var_instruction->var_type) { fprintf(irp->f, "%s %s: ", var_or_const, name); ir_print_other_inst_src(irp, decl_var_instruction->var_type); fprintf(irp->f, " "); } else { fprintf(irp->f, "%s %s ", var_or_const, name); } if (decl_var_instruction->align_value) { fprintf(irp->f, "align "); ir_print_other_inst_src(irp, decl_var_instruction->align_value); fprintf(irp->f, " "); } fprintf(irp->f, "= "); ir_print_other_inst_src(irp, decl_var_instruction->ptr); if (decl_var_instruction->var->is_comptime != nullptr) { fprintf(irp->f, " // comptime = "); ir_print_other_inst_src(irp, decl_var_instruction->var->is_comptime); } } static const char *cast_op_str(CastOp op) { switch (op) { case CastOpNoCast: return "NoCast"; case CastOpNoop: return "NoOp"; case CastOpIntToFloat: return "IntToFloat"; case CastOpFloatToInt: return "FloatToInt"; case CastOpBoolToInt: return "BoolToInt"; case CastOpNumLitToConcrete: return "NumLitToConcrete"; case CastOpErrSet: return "ErrSet"; case CastOpBitCast: return "BitCast"; } zig_unreachable(); } static void ir_print_cast(IrPrintGen *irp, Stage1AirInstCast *cast_instruction) { fprintf(irp->f, "%s cast ", cast_op_str(cast_instruction->cast_op)); ir_print_other_inst_gen(irp, cast_instruction->value); } static void ir_print_result_loc_var(IrPrintSrc *irp, ResultLocVar *result_loc_var) { fprintf(irp->f, "var("); ir_print_other_inst_src(irp, result_loc_var->base.source_instruction); fprintf(irp->f, ")"); } static void ir_print_result_loc_instruction(IrPrintSrc *irp, ResultLocInstruction *result_loc_inst) { fprintf(irp->f, "inst("); ir_print_other_inst_src(irp, result_loc_inst->base.source_instruction); fprintf(irp->f, ")"); } static void ir_print_result_loc_peer(IrPrintSrc *irp, ResultLocPeer *result_loc_peer) { fprintf(irp->f, "peer(next="); ir_print_other_block(irp, result_loc_peer->next_bb); fprintf(irp->f, ")"); } static void ir_print_result_loc_bit_cast(IrPrintSrc *irp, ResultLocBitCast *result_loc_bit_cast) { fprintf(irp->f, "bitcast(ty="); ir_print_other_inst_src(irp, result_loc_bit_cast->base.source_instruction); fprintf(irp->f, ")"); } static void ir_print_result_loc_cast(IrPrintSrc *irp, ResultLocCast *result_loc_cast) { fprintf(irp->f, "cast(ty="); ir_print_other_inst_src(irp, result_loc_cast->base.source_instruction); fprintf(irp->f, ")"); } static void ir_print_result_loc(IrPrintSrc *irp, ResultLoc *result_loc) { switch (result_loc->id) { case ResultLocIdInvalid: zig_unreachable(); case ResultLocIdNone: fprintf(irp->f, "none"); return; case ResultLocIdReturn: fprintf(irp->f, "return"); return; case ResultLocIdVar: return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc); case ResultLocIdInstruction: return ir_print_result_loc_instruction(irp, (ResultLocInstruction *)result_loc); case ResultLocIdPeer: return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc); case ResultLocIdBitCast: return ir_print_result_loc_bit_cast(irp, (ResultLocBitCast *)result_loc); case ResultLocIdCast: return ir_print_result_loc_cast(irp, (ResultLocCast *)result_loc); case ResultLocIdPeerParent: fprintf(irp->f, "peer_parent"); return; } zig_unreachable(); } static void ir_print_call_extra(IrPrintSrc *irp, Stage1ZirInstCallExtra *instruction) { fprintf(irp->f, "opts="); ir_print_other_inst_src(irp, instruction->options); fprintf(irp->f, ", fn="); ir_print_other_inst_src(irp, instruction->fn_ref); fprintf(irp->f, ", args="); ir_print_other_inst_src(irp, instruction->args); fprintf(irp->f, ", result="); ir_print_result_loc(irp, instruction->result_loc); } static void ir_print_async_call_extra(IrPrintSrc *irp, Stage1ZirInstAsyncCallExtra *instruction) { fprintf(irp->f, "modifier="); ir_print_call_modifier(irp->f, instruction->modifier); fprintf(irp->f, ", fn="); ir_print_other_inst_src(irp, instruction->fn_ref); if (instruction->ret_ptr != nullptr) { fprintf(irp->f, ", ret_ptr="); ir_print_other_inst_src(irp, instruction->ret_ptr); } fprintf(irp->f, ", new_stack="); ir_print_other_inst_src(irp, instruction->new_stack); fprintf(irp->f, ", args="); ir_print_other_inst_src(irp, instruction->args); fprintf(irp->f, ", result="); ir_print_result_loc(irp, instruction->result_loc); } static void ir_print_call_args(IrPrintSrc *irp, Stage1ZirInstCallArgs *instruction) { fprintf(irp->f, "opts="); ir_print_other_inst_src(irp, instruction->options); fprintf(irp->f, ", fn="); ir_print_other_inst_src(irp, instruction->fn_ref); fprintf(irp->f, ", args=("); for (size_t i = 0; i < instruction->args_len; i += 1) { Stage1ZirInst *arg = instruction->args_ptr[i]; if (i != 0) fprintf(irp->f, ", "); ir_print_other_inst_src(irp, arg); } fprintf(irp->f, "), result="); ir_print_result_loc(irp, instruction->result_loc); } static void ir_print_call_src(IrPrintSrc *irp, Stage1ZirInstCall *call_instruction) { ir_print_call_modifier(irp->f, call_instruction->modifier); if (call_instruction->fn_entry) { fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name)); } else { assert(call_instruction->fn_ref); ir_print_other_inst_src(irp, call_instruction->fn_ref); } fprintf(irp->f, "("); for (size_t i = 0; i < call_instruction->arg_count; i += 1) { Stage1ZirInst *arg = call_instruction->args[i]; if (i != 0) fprintf(irp->f, ", "); ir_print_other_inst_src(irp, arg); } fprintf(irp->f, ")result="); ir_print_result_loc(irp, call_instruction->result_loc); } static void ir_print_call_gen(IrPrintGen *irp, Stage1AirInstCall *call_instruction) { ir_print_call_modifier(irp->f, call_instruction->modifier); if (call_instruction->fn_entry) { fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name)); } else { assert(call_instruction->fn_ref); ir_print_other_inst_gen(irp, call_instruction->fn_ref); } fprintf(irp->f, "("); for (size_t i = 0; i < call_instruction->arg_count; i += 1) { Stage1AirInst *arg = call_instruction->args[i]; if (i != 0) fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, arg); } fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, call_instruction->result_loc); } static void ir_print_cond_br(IrPrintSrc *irp, Stage1ZirInstCondBr *inst) { fprintf(irp->f, "if ("); ir_print_other_inst_src(irp, inst->condition); fprintf(irp->f, ") "); ir_print_other_block(irp, inst->then_block); fprintf(irp->f, " else "); ir_print_other_block(irp, inst->else_block); if (inst->is_comptime != nullptr) { fprintf(irp->f, " // comptime = "); ir_print_other_inst_src(irp, inst->is_comptime); } } static void ir_print_cond_br(IrPrintGen *irp, Stage1AirInstCondBr *inst) { fprintf(irp->f, "if ("); ir_print_other_inst_gen(irp, inst->condition); fprintf(irp->f, ") "); ir_print_other_block_gen(irp, inst->then_block); fprintf(irp->f, " else "); ir_print_other_block_gen(irp, inst->else_block); } static void ir_print_br(IrPrintSrc *irp, Stage1ZirInstBr *br_instruction) { fprintf(irp->f, "goto "); ir_print_other_block(irp, br_instruction->dest_block); if (br_instruction->is_comptime != nullptr) { fprintf(irp->f, " // comptime = "); ir_print_other_inst_src(irp, br_instruction->is_comptime); } } static void ir_print_br(IrPrintGen *irp, Stage1AirInstBr *inst) { fprintf(irp->f, "goto "); ir_print_other_block_gen(irp, inst->dest_block); } static void ir_print_phi(IrPrintSrc *irp, Stage1ZirInstPhi *phi_instruction) { assert(phi_instruction->incoming_count != 0); assert(phi_instruction->incoming_count != SIZE_MAX); for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { Stage1ZirBasicBlock *incoming_block = phi_instruction->incoming_blocks[i]; Stage1ZirInst *incoming_value = phi_instruction->incoming_values[i]; if (i != 0) fprintf(irp->f, " "); ir_print_other_block(irp, incoming_block); fprintf(irp->f, ":"); ir_print_other_inst_src(irp, incoming_value); } } static void ir_print_phi(IrPrintGen *irp, Stage1AirInstPhi *phi_instruction) { assert(phi_instruction->incoming_count != 0); assert(phi_instruction->incoming_count != SIZE_MAX); for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { Stage1AirBasicBlock *incoming_block = phi_instruction->incoming_blocks[i]; Stage1AirInst *incoming_value = phi_instruction->incoming_values[i]; if (i != 0) fprintf(irp->f, " "); ir_print_other_block_gen(irp, incoming_block); fprintf(irp->f, ":"); ir_print_other_inst_gen(irp, incoming_value); } } static void ir_print_container_init_list(IrPrintSrc *irp, Stage1ZirInstContainerInitList *instruction) { fprintf(irp->f, "{"); if (instruction->item_count > 50) { fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count); } else { for (size_t i = 0; i < instruction->item_count; i += 1) { Stage1ZirInst *result_loc = instruction->elem_result_loc_list[i]; if (i != 0) fprintf(irp->f, ", "); ir_print_other_inst_src(irp, result_loc); } } fprintf(irp->f, "}result="); ir_print_other_inst_src(irp, instruction->result_loc); } static void ir_print_container_init_fields(IrPrintSrc *irp, Stage1ZirInstContainerInitFields *instruction) { fprintf(irp->f, "{"); for (size_t i = 0; i < instruction->field_count; i += 1) { Stage1ZirInstContainerInitFieldsField *field = &instruction->fields[i]; const char *comma = (i == 0) ? "" : ", "; fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name)); ir_print_other_inst_src(irp, field->result_loc); } fprintf(irp->f, "}result="); ir_print_other_inst_src(irp, instruction->result_loc); } static void ir_print_unreachable(IrPrintSrc *irp, Stage1ZirInstUnreachable *instruction) { fprintf(irp->f, "unreachable"); } static void ir_print_unreachable(IrPrintGen *irp, Stage1AirInstUnreachable *instruction) { fprintf(irp->f, "unreachable"); } static void ir_print_elem_ptr(IrPrintSrc *irp, Stage1ZirInstElemPtr *instruction) { fprintf(irp->f, "&"); ir_print_other_inst_src(irp, instruction->array_ptr); fprintf(irp->f, "["); ir_print_other_inst_src(irp, instruction->elem_index); fprintf(irp->f, "]"); if (!instruction->safety_check_on) { fprintf(irp->f, " // no safety"); } } static void ir_print_elem_ptr(IrPrintGen *irp, Stage1AirInstElemPtr *instruction) { fprintf(irp->f, "&"); ir_print_other_inst_gen(irp, instruction->array_ptr); fprintf(irp->f, "["); ir_print_other_inst_gen(irp, instruction->elem_index); fprintf(irp->f, "]"); if (!instruction->safety_check_on) { fprintf(irp->f, " // no safety"); } } static void ir_print_var_ptr(IrPrintSrc *irp, Stage1ZirInstVarPtr *instruction) { fprintf(irp->f, "&%s", instruction->var->name); } static void ir_print_var_ptr(IrPrintGen *irp, Stage1AirInstVarPtr *instruction) { fprintf(irp->f, "&%s", instruction->var->name); } static void ir_print_return_ptr(IrPrintGen *irp, Stage1AirInstReturnPtr *instruction) { fprintf(irp->f, "@ReturnPtr"); } static void ir_print_load_ptr(IrPrintSrc *irp, Stage1ZirInstLoadPtr *instruction) { ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, ".*"); } static void ir_print_load_ptr_gen(IrPrintGen *irp, Stage1AirInstLoadPtr *instruction) { fprintf(irp->f, "loadptr("); ir_print_other_inst_gen(irp, instruction->ptr); fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_store_ptr(IrPrintSrc *irp, Stage1ZirInstStorePtr *instruction) { fprintf(irp->f, "*"); ir_print_var_src(irp, instruction->ptr); fprintf(irp->f, " = "); ir_print_other_inst_src(irp, instruction->value); } static void ir_print_store_ptr(IrPrintGen *irp, Stage1AirInstStorePtr *instruction) { fprintf(irp->f, "*"); ir_print_var_gen(irp, instruction->ptr); fprintf(irp->f, " = "); ir_print_other_inst_gen(irp, instruction->value); } static void ir_print_vector_store_elem(IrPrintGen *irp, Stage1AirInstVectorStoreElem *instruction) { fprintf(irp->f, "vector_ptr="); ir_print_var_gen(irp, instruction->vector_ptr); fprintf(irp->f, ",index="); ir_print_var_gen(irp, instruction->index); fprintf(irp->f, ",value="); ir_print_other_inst_gen(irp, instruction->value); } static void ir_print_typeof(IrPrintSrc *irp, Stage1ZirInstTypeOf *instruction) { fprintf(irp->f, "@TypeOf("); if (instruction->value_count == 1) { ir_print_other_inst_src(irp, instruction->value.scalar); } else { for (size_t i = 0; i < instruction->value_count; i += 1) { ir_print_other_inst_src(irp, instruction->value.list[i]); } } fprintf(irp->f, ")"); } static void ir_print_binary_not(IrPrintGen *irp, Stage1AirInstBinaryNot *instruction) { fprintf(irp->f, "~"); ir_print_other_inst_gen(irp, instruction->operand); } static void ir_print_negation(IrPrintGen *irp, Stage1AirInstNegation *instruction) { fprintf(irp->f, instruction->wrapping ? "-%%" : "-"); ir_print_other_inst_gen(irp, instruction->operand); } static void ir_print_field_ptr(IrPrintSrc *irp, Stage1ZirInstFieldPtr *instruction) { if (instruction->field_name_buffer) { fprintf(irp->f, "fieldptr "); ir_print_other_inst_src(irp, instruction->container_ptr); fprintf(irp->f, ".%s", buf_ptr(instruction->field_name_buffer)); } else { assert(instruction->field_name_expr); fprintf(irp->f, "@field("); ir_print_other_inst_src(irp, instruction->container_ptr); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->field_name_expr); fprintf(irp->f, ")"); } } static void ir_print_struct_field_ptr(IrPrintGen *irp, Stage1AirInstStructFieldPtr *instruction) { fprintf(irp->f, "@StructFieldPtr(&"); ir_print_other_inst_gen(irp, instruction->struct_ptr); fprintf(irp->f, ".%s", buf_ptr(instruction->field->name)); fprintf(irp->f, ")"); } static void ir_print_union_field_ptr(IrPrintGen *irp, Stage1AirInstUnionFieldPtr *instruction) { fprintf(irp->f, "@UnionFieldPtr(&"); ir_print_other_inst_gen(irp, instruction->union_ptr); fprintf(irp->f, ".%s", buf_ptr(instruction->field->enum_field->name)); fprintf(irp->f, ")"); } static void ir_print_set_cold(IrPrintSrc *irp, Stage1ZirInstSetCold *instruction) { fprintf(irp->f, "@setCold("); ir_print_other_inst_src(irp, instruction->is_cold); fprintf(irp->f, ")"); } static void ir_print_set_runtime_safety(IrPrintSrc *irp, Stage1ZirInstSetRuntimeSafety *instruction) { fprintf(irp->f, "@setRuntimeSafety("); ir_print_other_inst_src(irp, instruction->safety_on); fprintf(irp->f, ")"); } static void ir_print_set_float_mode(IrPrintSrc *irp, Stage1ZirInstSetFloatMode *instruction) { fprintf(irp->f, "@setFloatMode("); ir_print_other_inst_src(irp, instruction->scope_value); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->mode_value); fprintf(irp->f, ")"); } static void ir_print_array_type(IrPrintSrc *irp, Stage1ZirInstArrayType *instruction) { fprintf(irp->f, "["); ir_print_other_inst_src(irp, instruction->size); if (instruction->sentinel != nullptr) { fprintf(irp->f, ":"); ir_print_other_inst_src(irp, instruction->sentinel); } fprintf(irp->f, "]"); ir_print_other_inst_src(irp, instruction->child_type); } static void ir_print_slice_type(IrPrintSrc *irp, Stage1ZirInstSliceType *instruction) { const char *const_kw = instruction->is_const ? "const " : ""; fprintf(irp->f, "[]%s", const_kw); ir_print_other_inst_src(irp, instruction->child_type); } static void ir_print_any_frame_type(IrPrintSrc *irp, Stage1ZirInstAnyFrameType *instruction) { if (instruction->payload_type == nullptr) { fprintf(irp->f, "anyframe"); } else { fprintf(irp->f, "anyframe->"); ir_print_other_inst_src(irp, instruction->payload_type); } } static void ir_print_asm_src(IrPrintSrc *irp, Stage1ZirInstAsm *instruction) { assert(instruction->base.source_node->type == NodeTypeAsmExpr); AstNodeAsmExpr *asm_expr = &instruction->base.source_node->data.asm_expr; const char *volatile_kw = instruction->has_side_effects ? " volatile" : ""; fprintf(irp->f, "asm%s (", volatile_kw); ir_print_other_inst_src(irp, instruction->asm_template); for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { AsmOutput *asm_output = asm_expr->output_list.at(i); if (i != 0) fprintf(irp->f, ", "); fprintf(irp->f, "[%s] \"%s\" (", buf_ptr(asm_output->asm_symbolic_name), buf_ptr(asm_output->constraint)); if (asm_output->return_type) { fprintf(irp->f, "-> "); ir_print_other_inst_src(irp, instruction->output_types[i]); } else { fprintf(irp->f, "%s", buf_ptr(asm_output->variable_name)); } fprintf(irp->f, ")"); } fprintf(irp->f, " : "); for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { AsmInput *asm_input = asm_expr->input_list.at(i); if (i != 0) fprintf(irp->f, ", "); fprintf(irp->f, "[%s] \"%s\" (", buf_ptr(asm_input->asm_symbolic_name), buf_ptr(asm_input->constraint)); ir_print_other_inst_src(irp, instruction->input_list[i]); fprintf(irp->f, ")"); } fprintf(irp->f, " : "); for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1) { Buf *reg_name = asm_expr->clobber_list.at(i); if (i != 0) fprintf(irp->f, ", "); fprintf(irp->f, "\"%s\"", buf_ptr(reg_name)); } fprintf(irp->f, ")"); } static void ir_print_asm_gen(IrPrintGen *irp, Stage1AirInstAsm *instruction) { assert(instruction->base.source_node->type == NodeTypeAsmExpr); AstNodeAsmExpr *asm_expr = &instruction->base.source_node->data.asm_expr; const char *volatile_kw = instruction->has_side_effects ? " volatile" : ""; fprintf(irp->f, "asm%s (\"%s\") : ", volatile_kw, buf_ptr(instruction->asm_template)); for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { AsmOutput *asm_output = asm_expr->output_list.at(i); if (i != 0) fprintf(irp->f, ", "); fprintf(irp->f, "[%s] \"%s\" (", buf_ptr(asm_output->asm_symbolic_name), buf_ptr(asm_output->constraint)); if (asm_output->return_type) { fprintf(irp->f, "-> "); ir_print_other_inst_gen(irp, instruction->output_types[i]); } else { fprintf(irp->f, "%s", buf_ptr(asm_output->variable_name)); } fprintf(irp->f, ")"); } fprintf(irp->f, " : "); for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { AsmInput *asm_input = asm_expr->input_list.at(i); if (i != 0) fprintf(irp->f, ", "); fprintf(irp->f, "[%s] \"%s\" (", buf_ptr(asm_input->asm_symbolic_name), buf_ptr(asm_input->constraint)); ir_print_other_inst_gen(irp, instruction->input_list[i]); fprintf(irp->f, ")"); } fprintf(irp->f, " : "); for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1) { Buf *reg_name = asm_expr->clobber_list.at(i); if (i != 0) fprintf(irp->f, ", "); fprintf(irp->f, "\"%s\"", buf_ptr(reg_name)); } fprintf(irp->f, ")"); } static void ir_print_size_of(IrPrintSrc *irp, Stage1ZirInstSizeOf *instruction) { if (instruction->bit_size) fprintf(irp->f, "@bitSizeOf("); else fprintf(irp->f, "@sizeOf("); ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ")"); } static void ir_print_test_non_null(IrPrintSrc *irp, Stage1ZirInstTestNonNull *instruction) { ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, " != null"); } static void ir_print_test_non_null(IrPrintGen *irp, Stage1AirInstTestNonNull *instruction) { ir_print_other_inst_gen(irp, instruction->value); fprintf(irp->f, " != null"); } static void ir_print_optional_unwrap_ptr(IrPrintSrc *irp, Stage1ZirInstOptionalUnwrapPtr *instruction) { fprintf(irp->f, "&"); ir_print_other_inst_src(irp, instruction->base_ptr); fprintf(irp->f, ".*.?"); if (!instruction->safety_check_on) { fprintf(irp->f, " // no safety"); } } static void ir_print_optional_unwrap_ptr(IrPrintGen *irp, Stage1AirInstOptionalUnwrapPtr *instruction) { fprintf(irp->f, "&"); ir_print_other_inst_gen(irp, instruction->base_ptr); fprintf(irp->f, ".*.?"); if (!instruction->safety_check_on) { fprintf(irp->f, " // no safety"); } } static void ir_print_clz(IrPrintSrc *irp, Stage1ZirInstClz *instruction) { fprintf(irp->f, "@clz("); ir_print_other_inst_src(irp, instruction->type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_clz(IrPrintGen *irp, Stage1AirInstClz *instruction) { fprintf(irp->f, "@clz("); ir_print_other_inst_gen(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_ctz(IrPrintSrc *irp, Stage1ZirInstCtz *instruction) { fprintf(irp->f, "@ctz("); ir_print_other_inst_src(irp, instruction->type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_ctz(IrPrintGen *irp, Stage1AirInstCtz *instruction) { fprintf(irp->f, "@ctz("); ir_print_other_inst_gen(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_pop_count(IrPrintSrc *irp, Stage1ZirInstPopCount *instruction) { fprintf(irp->f, "@popCount("); ir_print_other_inst_src(irp, instruction->type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_pop_count(IrPrintGen *irp, Stage1AirInstPopCount *instruction) { fprintf(irp->f, "@popCount("); ir_print_other_inst_gen(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_bswap(IrPrintSrc *irp, Stage1ZirInstBswap *instruction) { fprintf(irp->f, "@byteSwap("); ir_print_other_inst_src(irp, instruction->type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_bswap(IrPrintGen *irp, Stage1AirInstBswap *instruction) { fprintf(irp->f, "@byteSwap("); ir_print_other_inst_gen(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_bit_reverse(IrPrintSrc *irp, Stage1ZirInstBitReverse *instruction) { fprintf(irp->f, "@bitReverse("); ir_print_other_inst_src(irp, instruction->type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_bit_reverse(IrPrintGen *irp, Stage1AirInstBitReverse *instruction) { fprintf(irp->f, "@bitReverse("); ir_print_other_inst_gen(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_switch_br(IrPrintSrc *irp, Stage1ZirInstSwitchBr *instruction) { fprintf(irp->f, "switch ("); ir_print_other_inst_src(irp, instruction->target_value); fprintf(irp->f, ") "); for (size_t i = 0; i < instruction->case_count; i += 1) { Stage1ZirInstSwitchBrCase *this_case = &instruction->cases[i]; ir_print_other_inst_src(irp, this_case->value); fprintf(irp->f, " => "); ir_print_other_block(irp, this_case->block); fprintf(irp->f, ", "); } fprintf(irp->f, "else => "); ir_print_other_block(irp, instruction->else_block); if (instruction->is_comptime != nullptr) { fprintf(irp->f, " // comptime = "); ir_print_other_inst_src(irp, instruction->is_comptime); } } static void ir_print_switch_br(IrPrintGen *irp, Stage1AirInstSwitchBr *instruction) { fprintf(irp->f, "switch ("); ir_print_other_inst_gen(irp, instruction->target_value); fprintf(irp->f, ") "); for (size_t i = 0; i < instruction->case_count; i += 1) { Stage1AirInstSwitchBrCase *this_case = &instruction->cases[i]; ir_print_other_inst_gen(irp, this_case->value); fprintf(irp->f, " => "); ir_print_other_block_gen(irp, this_case->block); fprintf(irp->f, ", "); } fprintf(irp->f, "else => "); ir_print_other_block_gen(irp, instruction->else_block); } static void ir_print_switch_var(IrPrintSrc *irp, Stage1ZirInstSwitchVar *instruction) { fprintf(irp->f, "switchvar "); ir_print_other_inst_src(irp, instruction->target_value_ptr); for (size_t i = 0; i < instruction->prongs_len; i += 1) { fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->prongs_ptr[i]); } } static void ir_print_switch_else_var(IrPrintSrc *irp, Stage1ZirInstSwitchElseVar *instruction) { fprintf(irp->f, "switchelsevar "); ir_print_other_inst_src(irp, &instruction->switch_br->base); } static void ir_print_switch_target(IrPrintSrc *irp, Stage1ZirInstSwitchTarget *instruction) { fprintf(irp->f, "switchtarget "); ir_print_other_inst_src(irp, instruction->target_value_ptr); } static void ir_print_union_tag(IrPrintGen *irp, Stage1AirInstUnionTag *instruction) { fprintf(irp->f, "uniontag "); ir_print_other_inst_gen(irp, instruction->value); } static void ir_print_import(IrPrintSrc *irp, Stage1ZirInstImport *instruction) { fprintf(irp->f, "@import("); ir_print_other_inst_src(irp, instruction->name); fprintf(irp->f, ")"); } static void ir_print_ref(IrPrintSrc *irp, Stage1ZirInstRef *instruction) { fprintf(irp->f, "ref "); ir_print_other_inst_src(irp, instruction->value); } static void ir_print_ref_gen(IrPrintGen *irp, Stage1AirInstRef *instruction) { fprintf(irp->f, "@ref("); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_compile_err(IrPrintSrc *irp, Stage1ZirInstCompileErr *instruction) { fprintf(irp->f, "@compileError("); ir_print_other_inst_src(irp, instruction->msg); fprintf(irp->f, ")"); } static void ir_print_compile_log(IrPrintSrc *irp, Stage1ZirInstCompileLog *instruction) { fprintf(irp->f, "@compileLog("); for (size_t i = 0; i < instruction->msg_count; i += 1) { if (i != 0) fprintf(irp->f, ","); Stage1ZirInst *msg = instruction->msg_list[i]; ir_print_other_inst_src(irp, msg); } fprintf(irp->f, ")"); } static void ir_print_err_name(IrPrintSrc *irp, Stage1ZirInstErrName *instruction) { fprintf(irp->f, "@errorName("); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_err_name(IrPrintGen *irp, Stage1AirInstErrName *instruction) { fprintf(irp->f, "@errorName("); ir_print_other_inst_gen(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_c_import(IrPrintSrc *irp, Stage1ZirInstCImport *instruction) { fprintf(irp->f, "@cImport(...)"); } static void ir_print_c_include(IrPrintSrc *irp, Stage1ZirInstCInclude *instruction) { fprintf(irp->f, "@cInclude("); ir_print_other_inst_src(irp, instruction->name); fprintf(irp->f, ")"); } static void ir_print_c_define(IrPrintSrc *irp, Stage1ZirInstCDefine *instruction) { fprintf(irp->f, "@cDefine("); ir_print_other_inst_src(irp, instruction->name); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_c_undef(IrPrintSrc *irp, Stage1ZirInstCUndef *instruction) { fprintf(irp->f, "@cUndef("); ir_print_other_inst_src(irp, instruction->name); fprintf(irp->f, ")"); } static void ir_print_embed_file(IrPrintSrc *irp, Stage1ZirInstEmbedFile *instruction) { fprintf(irp->f, "@embedFile("); ir_print_other_inst_src(irp, instruction->name); fprintf(irp->f, ")"); } static void ir_print_cmpxchg_src(IrPrintSrc *irp, Stage1ZirInstCmpxchg *instruction) { fprintf(irp->f, "@cmpxchg("); ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->cmp_value); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->new_value); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->success_order_value); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->failure_order_value); fprintf(irp->f, ")result="); ir_print_result_loc(irp, instruction->result_loc); } static void ir_print_cmpxchg_gen(IrPrintGen *irp, Stage1AirInstCmpxchg *instruction) { fprintf(irp->f, "@cmpxchg("); ir_print_other_inst_gen(irp, instruction->ptr); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->cmp_value); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->new_value); fprintf(irp->f, ", TODO print atomic orders)result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_fence(IrPrintSrc *irp, Stage1ZirInstFence *instruction) { fprintf(irp->f, "@fence("); ir_print_other_inst_src(irp, instruction->order); fprintf(irp->f, ")"); } static void ir_print_reduce(IrPrintSrc *irp, Stage1ZirInstReduce *instruction) { fprintf(irp->f, "@reduce("); ir_print_other_inst_src(irp, instruction->op); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ")"); } static const char *atomic_order_str(AtomicOrder order) { switch (order) { case AtomicOrderUnordered: return "Unordered"; case AtomicOrderMonotonic: return "Monotonic"; case AtomicOrderAcquire: return "Acquire"; case AtomicOrderRelease: return "Release"; case AtomicOrderAcqRel: return "AcqRel"; case AtomicOrderSeqCst: return "SeqCst"; } zig_unreachable(); } static void ir_print_fence(IrPrintGen *irp, Stage1AirInstFence *instruction) { fprintf(irp->f, "fence %s", atomic_order_str(instruction->order)); } static const char *reduce_op_str(ReduceOp op) { switch (op) { case ReduceOp_and: return "And"; case ReduceOp_or: return "Or"; case ReduceOp_xor: return "Xor"; case ReduceOp_min: return "Min"; case ReduceOp_max: return "Max"; case ReduceOp_add: return "Add"; case ReduceOp_mul: return "Mul"; } zig_unreachable(); } static void ir_print_reduce(IrPrintGen *irp, Stage1AirInstReduce *instruction) { fprintf(irp->f, "@reduce(.%s, ", reduce_op_str(instruction->op)); ir_print_other_inst_gen(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_truncate(IrPrintSrc *irp, Stage1ZirInstTruncate *instruction) { fprintf(irp->f, "@truncate("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_truncate(IrPrintGen *irp, Stage1AirInstTruncate *instruction) { fprintf(irp->f, "@truncate("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_int_cast(IrPrintSrc *irp, Stage1ZirInstIntCast *instruction) { fprintf(irp->f, "@intCast("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_float_cast(IrPrintSrc *irp, Stage1ZirInstFloatCast *instruction) { fprintf(irp->f, "@floatCast("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_err_set_cast(IrPrintSrc *irp, Stage1ZirInstErrSetCast *instruction) { fprintf(irp->f, "@errSetCast("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_int_to_float(IrPrintSrc *irp, Stage1ZirInstIntToFloat *instruction) { fprintf(irp->f, "@intToFloat("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_float_to_int(IrPrintSrc *irp, Stage1ZirInstFloatToInt *instruction) { fprintf(irp->f, "@floatToInt("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_bool_to_int(IrPrintSrc *irp, Stage1ZirInstBoolToInt *instruction) { fprintf(irp->f, "@boolToInt("); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_vector_type(IrPrintSrc *irp, Stage1ZirInstVectorType *instruction) { fprintf(irp->f, "@Vector("); ir_print_other_inst_src(irp, instruction->len); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->elem_type); fprintf(irp->f, ")"); } static void ir_print_shuffle_vector(IrPrintSrc *irp, Stage1ZirInstShuffleVector *instruction) { fprintf(irp->f, "@shuffle("); ir_print_other_inst_src(irp, instruction->scalar_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->a); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->b); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->mask); fprintf(irp->f, ")"); } static void ir_print_shuffle_vector(IrPrintGen *irp, Stage1AirInstShuffleVector *instruction) { fprintf(irp->f, "@shuffle("); ir_print_other_inst_gen(irp, instruction->a); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->b); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->mask); fprintf(irp->f, ")"); } static void ir_print_select(IrPrintSrc *irp, Stage1ZirInstSelect *instruction) { fprintf(irp->f, "@select("); ir_print_other_inst_src(irp, instruction->scalar_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->pred); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->a); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->b); fprintf(irp->f, ")"); } static void ir_print_select(IrPrintGen *irp, Stage1AirInstSelect *instruction) { fprintf(irp->f, "@select("); ir_print_other_inst_gen(irp, instruction->pred); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->a); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->b); fprintf(irp->f, ")"); } static void ir_print_splat_src(IrPrintSrc *irp, Stage1ZirInstSplat *instruction) { fprintf(irp->f, "@splat("); ir_print_other_inst_src(irp, instruction->len); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->scalar); fprintf(irp->f, ")"); } static void ir_print_splat_gen(IrPrintGen *irp, Stage1AirInstSplat *instruction) { fprintf(irp->f, "@splat("); ir_print_other_inst_gen(irp, instruction->scalar); fprintf(irp->f, ")"); } static void ir_print_bool_not(IrPrintSrc *irp, Stage1ZirInstBoolNot *instruction) { fprintf(irp->f, "! "); ir_print_other_inst_src(irp, instruction->value); } static void ir_print_bool_not(IrPrintGen *irp, Stage1AirInstBoolNot *instruction) { fprintf(irp->f, "! "); ir_print_other_inst_gen(irp, instruction->value); } static void ir_print_wasm_memory_size(IrPrintSrc *irp, Stage1ZirInstWasmMemorySize *instruction) { fprintf(irp->f, "@wasmMemorySize("); ir_print_other_inst_src(irp, instruction->index); fprintf(irp->f, ")"); } static void ir_print_wasm_memory_size(IrPrintGen *irp, Stage1AirInstWasmMemorySize *instruction) { fprintf(irp->f, "@wasmMemorySize("); ir_print_other_inst_gen(irp, instruction->index); fprintf(irp->f, ")"); } static void ir_print_wasm_memory_grow(IrPrintSrc *irp, Stage1ZirInstWasmMemoryGrow *instruction) { fprintf(irp->f, "@wasmMemoryGrow("); ir_print_other_inst_src(irp, instruction->index); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->delta); fprintf(irp->f, ")"); } static void ir_print_wasm_memory_grow(IrPrintGen *irp, Stage1AirInstWasmMemoryGrow *instruction) { fprintf(irp->f, "@wasmMemoryGrow("); ir_print_other_inst_gen(irp, instruction->index); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->delta); fprintf(irp->f, ")"); } static void ir_print_builtin_src(IrPrintSrc *irp, Stage1ZirInstSrc *instruction) { fprintf(irp->f, "@src()"); } static void ir_print_memset(IrPrintSrc *irp, Stage1ZirInstMemset *instruction) { fprintf(irp->f, "@memset("); ir_print_other_inst_src(irp, instruction->dest_ptr); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->byte); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->count); fprintf(irp->f, ")"); } static void ir_print_memset(IrPrintGen *irp, Stage1AirInstMemset *instruction) { fprintf(irp->f, "@memset("); ir_print_other_inst_gen(irp, instruction->dest_ptr); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->byte); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->count); fprintf(irp->f, ")"); } static void ir_print_memcpy(IrPrintSrc *irp, Stage1ZirInstMemcpy *instruction) { fprintf(irp->f, "@memcpy("); ir_print_other_inst_src(irp, instruction->dest_ptr); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->src_ptr); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->count); fprintf(irp->f, ")"); } static void ir_print_memcpy(IrPrintGen *irp, Stage1AirInstMemcpy *instruction) { fprintf(irp->f, "@memcpy("); ir_print_other_inst_gen(irp, instruction->dest_ptr); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->src_ptr); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->count); fprintf(irp->f, ")"); } static void ir_print_slice_src(IrPrintSrc *irp, Stage1ZirInstSlice *instruction) { ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, "["); ir_print_other_inst_src(irp, instruction->start); fprintf(irp->f, ".."); if (instruction->end) ir_print_other_inst_src(irp, instruction->end); fprintf(irp->f, "]result="); ir_print_result_loc(irp, instruction->result_loc); } static void ir_print_slice_gen(IrPrintGen *irp, Stage1AirInstSlice *instruction) { ir_print_other_inst_gen(irp, instruction->ptr); fprintf(irp->f, "["); ir_print_other_inst_gen(irp, instruction->start); fprintf(irp->f, ".."); if (instruction->end) ir_print_other_inst_gen(irp, instruction->end); fprintf(irp->f, "]result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_breakpoint(IrPrintSrc *irp, Stage1ZirInstBreakpoint *instruction) { fprintf(irp->f, "@breakpoint()"); } static void ir_print_breakpoint(IrPrintGen *irp, Stage1AirInstBreakpoint *instruction) { fprintf(irp->f, "@breakpoint()"); } static void ir_print_frame_address(IrPrintSrc *irp, Stage1ZirInstFrameAddress *instruction) { fprintf(irp->f, "@frameAddress()"); } static void ir_print_frame_address(IrPrintGen *irp, Stage1AirInstFrameAddress *instruction) { fprintf(irp->f, "@frameAddress()"); } static void ir_print_handle(IrPrintSrc *irp, Stage1ZirInstFrameHandle *instruction) { fprintf(irp->f, "@frame()"); } static void ir_print_handle(IrPrintGen *irp, Stage1AirInstFrameHandle *instruction) { fprintf(irp->f, "@frame()"); } static void ir_print_frame_type(IrPrintSrc *irp, Stage1ZirInstFrameType *instruction) { fprintf(irp->f, "@Frame("); ir_print_other_inst_src(irp, instruction->fn); fprintf(irp->f, ")"); } static void ir_print_frame_size_src(IrPrintSrc *irp, Stage1ZirInstFrameSize *instruction) { fprintf(irp->f, "@frameSize("); ir_print_other_inst_src(irp, instruction->fn); fprintf(irp->f, ")"); } static void ir_print_frame_size_gen(IrPrintGen *irp, Stage1AirInstFrameSize *instruction) { fprintf(irp->f, "@frameSize("); ir_print_other_inst_gen(irp, instruction->fn); fprintf(irp->f, ")"); } static void ir_print_return_address(IrPrintSrc *irp, Stage1ZirInstReturnAddress *instruction) { fprintf(irp->f, "@returnAddress()"); } static void ir_print_return_address(IrPrintGen *irp, Stage1AirInstReturnAddress *instruction) { fprintf(irp->f, "@returnAddress()"); } static void ir_print_align_of(IrPrintSrc *irp, Stage1ZirInstAlignOf *instruction) { fprintf(irp->f, "@alignOf("); ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ")"); } static void ir_print_overflow_op(IrPrintSrc *irp, Stage1ZirInstOverflowOp *instruction) { switch (instruction->op) { case IrOverflowOpAdd: fprintf(irp->f, "@addWithOverflow("); break; case IrOverflowOpSub: fprintf(irp->f, "@subWithOverflow("); break; case IrOverflowOpMul: fprintf(irp->f, "@mulWithOverflow("); break; case IrOverflowOpShl: fprintf(irp->f, "@shlWithOverflow("); break; } ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->op1); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->op2); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->result_ptr); fprintf(irp->f, ")"); } static void ir_print_overflow_op(IrPrintGen *irp, Stage1AirInstOverflowOp *instruction) { switch (instruction->op) { case IrOverflowOpAdd: fprintf(irp->f, "@addWithOverflow("); break; case IrOverflowOpSub: fprintf(irp->f, "@subWithOverflow("); break; case IrOverflowOpMul: fprintf(irp->f, "@mulWithOverflow("); break; case IrOverflowOpShl: fprintf(irp->f, "@shlWithOverflow("); break; } ir_print_other_inst_gen(irp, instruction->op1); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->op2); fprintf(irp->f, ", "); ir_print_other_inst_gen(irp, instruction->result_ptr); fprintf(irp->f, ")"); } static void ir_print_test_err_src(IrPrintSrc *irp, Stage1ZirInstTestErr *instruction) { fprintf(irp->f, "@testError("); ir_print_other_inst_src(irp, instruction->base_ptr); fprintf(irp->f, ")"); } static void ir_print_test_err_gen(IrPrintGen *irp, Stage1AirInstTestErr *instruction) { fprintf(irp->f, "@testError("); ir_print_other_inst_gen(irp, instruction->err_union); fprintf(irp->f, ")"); } static void ir_print_unwrap_err_code(IrPrintSrc *irp, Stage1ZirInstUnwrapErrCode *instruction) { fprintf(irp->f, "UnwrapErrorCode("); ir_print_other_inst_src(irp, instruction->err_union_ptr); fprintf(irp->f, ")"); } static void ir_print_unwrap_err_code(IrPrintGen *irp, Stage1AirInstUnwrapErrCode *instruction) { fprintf(irp->f, "UnwrapErrorCode("); ir_print_other_inst_gen(irp, instruction->err_union_ptr); fprintf(irp->f, ")"); } static void ir_print_unwrap_err_payload(IrPrintSrc *irp, Stage1ZirInstUnwrapErrPayload *instruction) { fprintf(irp->f, "ErrorUnionFieldPayload("); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ")safety=%d,init=%d",instruction->safety_check_on, instruction->initializing); } static void ir_print_unwrap_err_payload(IrPrintGen *irp, Stage1AirInstUnwrapErrPayload *instruction) { fprintf(irp->f, "ErrorUnionFieldPayload("); ir_print_other_inst_gen(irp, instruction->value); fprintf(irp->f, ")safety=%d,init=%d",instruction->safety_check_on, instruction->initializing); } static void ir_print_optional_wrap(IrPrintGen *irp, Stage1AirInstOptionalWrap *instruction) { fprintf(irp->f, "@optionalWrap("); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_err_wrap_code(IrPrintGen *irp, Stage1AirInstErrWrapCode *instruction) { fprintf(irp->f, "@errWrapCode("); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_err_wrap_payload(IrPrintGen *irp, Stage1AirInstErrWrapPayload *instruction) { fprintf(irp->f, "@errWrapPayload("); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_fn_proto(IrPrintSrc *irp, Stage1ZirInstFnProto *instruction) { fprintf(irp->f, "fn("); for (size_t i = 0; i < instruction->base.source_node->data.fn_proto.params.length; i += 1) { if (i != 0) fprintf(irp->f, ","); if (instruction->is_var_args && i == instruction->base.source_node->data.fn_proto.params.length - 1) { fprintf(irp->f, "..."); } else { ir_print_other_inst_src(irp, instruction->param_types[i]); } } fprintf(irp->f, ")"); if (instruction->align_value != nullptr) { fprintf(irp->f, " align "); ir_print_other_inst_src(irp, instruction->align_value); fprintf(irp->f, " "); } fprintf(irp->f, "->"); ir_print_other_inst_src(irp, instruction->return_type); } static void ir_print_test_comptime(IrPrintSrc *irp, Stage1ZirInstTestComptime *instruction) { fprintf(irp->f, "@testComptime("); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_ptr_cast_src(IrPrintSrc *irp, Stage1ZirInstPtrCast *instruction) { fprintf(irp->f, "@ptrCast("); if (instruction->dest_type) { ir_print_other_inst_src(irp, instruction->dest_type); } fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, ")"); } static void ir_print_ptr_cast_gen(IrPrintGen *irp, Stage1AirInstPtrCast *instruction) { fprintf(irp->f, "@ptrCast("); ir_print_other_inst_gen(irp, instruction->ptr); fprintf(irp->f, ")"); } static void ir_print_implicit_cast(IrPrintSrc *irp, Stage1ZirInstImplicitCast *instruction) { fprintf(irp->f, "@implicitCast("); ir_print_other_inst_src(irp, instruction->operand); fprintf(irp->f, ")result="); ir_print_result_loc(irp, &instruction->result_loc_cast->base); } static void ir_print_bit_cast_src(IrPrintSrc *irp, Stage1ZirInstBitCast *instruction) { fprintf(irp->f, "@bitCast("); ir_print_other_inst_src(irp, instruction->operand); fprintf(irp->f, ")result="); ir_print_result_loc(irp, &instruction->result_loc_bit_cast->base); } static void ir_print_bit_cast_gen(IrPrintGen *irp, Stage1AirInstBitCast *instruction) { fprintf(irp->f, "@bitCast("); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")"); } static void ir_print_widen_or_shorten(IrPrintGen *irp, Stage1AirInstWidenOrShorten *instruction) { fprintf(irp->f, "WidenOrShorten("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_ptr_to_int(IrPrintSrc *irp, Stage1ZirInstPtrToInt *instruction) { fprintf(irp->f, "@ptrToInt("); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_ptr_to_int(IrPrintGen *irp, Stage1AirInstPtrToInt *instruction) { fprintf(irp->f, "@ptrToInt("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_int_to_ptr(IrPrintSrc *irp, Stage1ZirInstIntToPtr *instruction) { fprintf(irp->f, "@intToPtr("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_int_to_ptr(IrPrintGen *irp, Stage1AirInstIntToPtr *instruction) { fprintf(irp->f, "@intToPtr("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_int_to_enum(IrPrintSrc *irp, Stage1ZirInstIntToEnum *instruction) { fprintf(irp->f, "@intToEnum("); ir_print_other_inst_src(irp, instruction->dest_type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_int_to_enum(IrPrintGen *irp, Stage1AirInstIntToEnum *instruction) { fprintf(irp->f, "@intToEnum("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_enum_to_int(IrPrintSrc *irp, Stage1ZirInstEnumToInt *instruction) { fprintf(irp->f, "@enumToInt("); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_check_runtime_scope(IrPrintSrc *irp, Stage1ZirInstCheckRuntimeScope *instruction) { fprintf(irp->f, "@checkRuntimeScope("); ir_print_other_inst_src(irp, instruction->scope_is_comptime); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->is_comptime); fprintf(irp->f, ")"); } static void ir_print_array_to_vector(IrPrintGen *irp, Stage1AirInstArrayToVector *instruction) { fprintf(irp->f, "ArrayToVector("); ir_print_other_inst_gen(irp, instruction->array); fprintf(irp->f, ")"); } static void ir_print_vector_to_array(IrPrintGen *irp, Stage1AirInstVectorToArray *instruction) { fprintf(irp->f, "VectorToArray("); ir_print_other_inst_gen(irp, instruction->vector); fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_ptr_of_array_to_slice(IrPrintGen *irp, Stage1AirInstPtrOfArrayToSlice *instruction) { fprintf(irp->f, "PtrOfArrayToSlice("); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")result="); ir_print_other_inst_gen(irp, instruction->result_loc); } static void ir_print_assert_zero(IrPrintGen *irp, Stage1AirInstAssertZero *instruction) { fprintf(irp->f, "AssertZero("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_assert_non_null(IrPrintGen *irp, Stage1AirInstAssertNonNull *instruction) { fprintf(irp->f, "AssertNonNull("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_alloca_src(IrPrintSrc *irp, Stage1ZirInstAlloca *instruction) { fprintf(irp->f, "Alloca(align="); ir_print_other_inst_src(irp, instruction->align); fprintf(irp->f, ",name=%s)", instruction->name_hint); } static void ir_print_alloca_gen(IrPrintGen *irp, Stage1AirInstAlloca *instruction) { fprintf(irp->f, "Alloca(align=%" PRIu32 ",name=%s)", instruction->align, instruction->name_hint); } static void ir_print_end_expr(IrPrintSrc *irp, Stage1ZirInstEndExpr *instruction) { fprintf(irp->f, "EndExpr(result="); ir_print_result_loc(irp, instruction->result_loc); fprintf(irp->f, ",value="); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_int_to_err(IrPrintSrc *irp, Stage1ZirInstIntToErr *instruction) { fprintf(irp->f, "inttoerr "); ir_print_other_inst_src(irp, instruction->target); } static void ir_print_int_to_err(IrPrintGen *irp, Stage1AirInstIntToErr *instruction) { fprintf(irp->f, "inttoerr "); ir_print_other_inst_gen(irp, instruction->target); } static void ir_print_err_to_int(IrPrintSrc *irp, Stage1ZirInstErrToInt *instruction) { fprintf(irp->f, "errtoint "); ir_print_other_inst_src(irp, instruction->target); } static void ir_print_err_to_int(IrPrintGen *irp, Stage1AirInstErrToInt *instruction) { fprintf(irp->f, "errtoint "); ir_print_other_inst_gen(irp, instruction->target); } static void ir_print_check_switch_prongs(IrPrintSrc *irp, Stage1ZirInstCheckSwitchProngs *instruction, bool have_underscore_prong) { fprintf(irp->f, "@checkSwitchProngs("); ir_print_other_inst_src(irp, instruction->target_value); fprintf(irp->f, ","); for (size_t i = 0; i < instruction->range_count; i += 1) { if (i != 0) fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ranges[i].start); fprintf(irp->f, "..."); ir_print_other_inst_src(irp, instruction->ranges[i].end); } const char *have_else_str = instruction->else_prong != nullptr ? "yes" : "no"; fprintf(irp->f, ")else:%s", have_else_str); const char *have_under_str = have_underscore_prong ? "yes" : "no"; fprintf(irp->f, " _:%s", have_under_str); } static void ir_print_check_statement_is_void(IrPrintSrc *irp, Stage1ZirInstCheckStatementIsVoid *instruction) { fprintf(irp->f, "@checkStatementIsVoid("); ir_print_other_inst_src(irp, instruction->statement_value); fprintf(irp->f, ")"); } static void ir_print_type_name(IrPrintSrc *irp, Stage1ZirInstTypeName *instruction) { fprintf(irp->f, "typename "); ir_print_other_inst_src(irp, instruction->type_value); } static void ir_print_tag_name(IrPrintSrc *irp, Stage1ZirInstTagName *instruction) { fprintf(irp->f, "tagname "); ir_print_other_inst_src(irp, instruction->target); } static void ir_print_tag_name(IrPrintGen *irp, Stage1AirInstTagName *instruction) { fprintf(irp->f, "tagname "); ir_print_other_inst_gen(irp, instruction->target); } static void ir_print_ptr_type(IrPrintSrc *irp, Stage1ZirInstPtrType *instruction) { fprintf(irp->f, "&"); if (instruction->align_value != nullptr) { fprintf(irp->f, "align("); ir_print_other_inst_src(irp, instruction->align_value); fprintf(irp->f, ")"); } const char *const_str = instruction->is_const ? "const " : ""; const char *volatile_str = instruction->is_volatile ? "volatile " : ""; fprintf(irp->f, ":%" PRIu32 ":%" PRIu32 " %s%s", instruction->bit_offset_start, instruction->host_int_bytes, const_str, volatile_str); ir_print_other_inst_src(irp, instruction->child_type); } static void ir_print_ptr_type_simple(IrPrintSrc *irp, Stage1ZirInstPtrTypeSimple *instruction, bool is_const) { fprintf(irp->f, "&"); const char *const_str = is_const ? "const " : ""; fprintf(irp->f, "*%s", const_str); ir_print_other_inst_src(irp, instruction->child_type); } static void ir_print_decl_ref(IrPrintSrc *irp, Stage1ZirInstDeclRef *instruction) { const char *ptr_str = (instruction->lval != LValNone) ? "ptr " : ""; fprintf(irp->f, "declref %s%s", ptr_str, buf_ptr(instruction->tld->name)); } static void ir_print_panic(IrPrintSrc *irp, Stage1ZirInstPanic *instruction) { fprintf(irp->f, "@panic("); ir_print_other_inst_src(irp, instruction->msg); fprintf(irp->f, ")"); } static void ir_print_panic(IrPrintGen *irp, Stage1AirInstPanic *instruction) { fprintf(irp->f, "@panic("); ir_print_other_inst_gen(irp, instruction->msg); fprintf(irp->f, ")"); } static void ir_print_field_parent_ptr(IrPrintSrc *irp, Stage1ZirInstFieldParentPtr *instruction) { fprintf(irp->f, "@fieldParentPtr("); ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->field_name); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->field_ptr); fprintf(irp->f, ")"); } static void ir_print_field_parent_ptr(IrPrintGen *irp, Stage1AirInstFieldParentPtr *instruction) { fprintf(irp->f, "@fieldParentPtr(%s,", buf_ptr(instruction->field->name)); ir_print_other_inst_gen(irp, instruction->field_ptr); fprintf(irp->f, ")"); } static void ir_print_offset_of(IrPrintSrc *irp, Stage1ZirInstOffsetOf *instruction) { fprintf(irp->f, "@offset_of("); ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->field_name); fprintf(irp->f, ")"); } static void ir_print_bit_offset_of(IrPrintSrc *irp, Stage1ZirInstBitOffsetOf *instruction) { fprintf(irp->f, "@bit_offset_of("); ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->field_name); fprintf(irp->f, ")"); } static void ir_print_type_info(IrPrintSrc *irp, Stage1ZirInstTypeInfo *instruction) { fprintf(irp->f, "@typeInfo("); ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ")"); } static void ir_print_type(IrPrintSrc *irp, Stage1ZirInstType *instruction) { fprintf(irp->f, "@Type("); ir_print_other_inst_src(irp, instruction->type_info); fprintf(irp->f, ")"); } static void ir_print_has_field(IrPrintSrc *irp, Stage1ZirInstHasField *instruction) { fprintf(irp->f, "@hasField("); ir_print_other_inst_src(irp, instruction->container_type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->field_name); fprintf(irp->f, ")"); } static void ir_print_set_eval_branch_quota(IrPrintSrc *irp, Stage1ZirInstSetEvalBranchQuota *instruction) { fprintf(irp->f, "@setEvalBranchQuota("); ir_print_other_inst_src(irp, instruction->new_quota); fprintf(irp->f, ")"); } static void ir_print_align_cast(IrPrintSrc *irp, Stage1ZirInstAlignCast *instruction) { fprintf(irp->f, "@alignCast("); ir_print_other_inst_src(irp, instruction->align_bytes); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_align_cast(IrPrintGen *irp, Stage1AirInstAlignCast *instruction) { fprintf(irp->f, "@alignCast("); ir_print_other_inst_gen(irp, instruction->target); fprintf(irp->f, ")"); } static void ir_print_resolve_result(IrPrintSrc *irp, Stage1ZirInstResolveResult *instruction) { fprintf(irp->f, "ResolveResult("); ir_print_result_loc(irp, instruction->result_loc); fprintf(irp->f, ")"); } static void ir_print_reset_result(IrPrintSrc *irp, Stage1ZirInstResetResult *instruction) { fprintf(irp->f, "ResetResult("); ir_print_result_loc(irp, instruction->result_loc); fprintf(irp->f, ")"); } static void ir_print_set_align_stack(IrPrintSrc *irp, Stage1ZirInstSetAlignStack *instruction) { fprintf(irp->f, "@setAlignStack("); ir_print_other_inst_src(irp, instruction->align_bytes); fprintf(irp->f, ")"); } static void ir_print_arg_type(IrPrintSrc *irp, Stage1ZirInstArgType *instruction, bool allow_var) { fprintf(irp->f, "@ArgType("); ir_print_other_inst_src(irp, instruction->fn_type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->arg_index); fprintf(irp->f, ","); if (allow_var) { fprintf(irp->f, "allow_var=true"); } else { fprintf(irp->f, "allow_var=false"); } fprintf(irp->f, ")"); } static void ir_print_export(IrPrintSrc *irp, Stage1ZirInstExport *instruction) { fprintf(irp->f, "@export("); ir_print_other_inst_src(irp, instruction->target); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->options); fprintf(irp->f, ")"); } static void ir_print_extern(IrPrintGen *irp, Stage1AirInstExtern *instruction) { fprintf(irp->f, "@extern(...)"); } static void ir_print_extern(IrPrintSrc *irp, Stage1ZirInstExtern *instruction) { fprintf(irp->f, "@extern("); ir_print_other_inst_src(irp, instruction->type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->options); fprintf(irp->f, ")"); } static void ir_print_prefetch(IrPrintSrc *irp, Stage1ZirInstPrefetch *instruction) { fprintf(irp->f, "@prefetch("); ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->options); fprintf(irp->f, ")"); } static void ir_print_prefetch(IrPrintGen *irp, Stage1AirInstPrefetch *instruction) { fprintf(irp->f, "@prefetch(...)"); } static void ir_print_error_return_trace(IrPrintSrc *irp, Stage1ZirInstErrorReturnTrace *instruction) { fprintf(irp->f, "@errorReturnTrace("); switch (instruction->optional) { case IrInstErrorReturnTraceNull: fprintf(irp->f, "Null"); break; case IrInstErrorReturnTraceNonNull: fprintf(irp->f, "NonNull"); break; } fprintf(irp->f, ")"); } static void ir_print_error_return_trace(IrPrintGen *irp, Stage1AirInstErrorReturnTrace *instruction) { fprintf(irp->f, "@errorReturnTrace("); switch (instruction->optional) { case IrInstErrorReturnTraceNull: fprintf(irp->f, "Null"); break; case IrInstErrorReturnTraceNonNull: fprintf(irp->f, "NonNull"); break; } fprintf(irp->f, ")"); } static void ir_print_error_union(IrPrintSrc *irp, Stage1ZirInstErrorUnion *instruction) { ir_print_other_inst_src(irp, instruction->err_set); fprintf(irp->f, "!"); ir_print_other_inst_src(irp, instruction->payload); } static void ir_print_atomic_rmw(IrPrintSrc *irp, Stage1ZirInstAtomicRmw *instruction) { fprintf(irp->f, "@atomicRmw("); ir_print_other_inst_src(irp, instruction->operand_type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->operand); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ordering); fprintf(irp->f, ")"); } static void ir_print_atomic_rmw(IrPrintGen *irp, Stage1AirInstAtomicRmw *instruction) { fprintf(irp->f, "@atomicRmw("); ir_print_other_inst_gen(irp, instruction->ptr); fprintf(irp->f, ",[TODO print op],"); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ",%s)", atomic_order_str(instruction->ordering)); } static void ir_print_atomic_load(IrPrintSrc *irp, Stage1ZirInstAtomicLoad *instruction) { fprintf(irp->f, "@atomicLoad("); ir_print_other_inst_src(irp, instruction->operand_type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ordering); fprintf(irp->f, ")"); } static void ir_print_atomic_load(IrPrintGen *irp, Stage1AirInstAtomicLoad *instruction) { fprintf(irp->f, "@atomicLoad("); ir_print_other_inst_gen(irp, instruction->ptr); fprintf(irp->f, ",%s)", atomic_order_str(instruction->ordering)); } static void ir_print_atomic_store(IrPrintSrc *irp, Stage1ZirInstAtomicStore *instruction) { fprintf(irp->f, "@atomicStore("); ir_print_other_inst_src(irp, instruction->operand_type); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ptr); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->ordering); fprintf(irp->f, ")"); } static void ir_print_atomic_store(IrPrintGen *irp, Stage1AirInstAtomicStore *instruction) { fprintf(irp->f, "@atomicStore("); ir_print_other_inst_gen(irp, instruction->ptr); fprintf(irp->f, ","); ir_print_other_inst_gen(irp, instruction->value); fprintf(irp->f, ",%s)", atomic_order_str(instruction->ordering)); } static void ir_print_save_err_ret_addr(IrPrintSrc *irp, Stage1ZirInstSaveErrRetAddr *instruction) { fprintf(irp->f, "@saveErrRetAddr()"); } static void ir_print_save_err_ret_addr(IrPrintGen *irp, Stage1AirInstSaveErrRetAddr *instruction) { fprintf(irp->f, "@saveErrRetAddr()"); } static void ir_print_add_implicit_return_type(IrPrintSrc *irp, Stage1ZirInstAddImplicitReturnType *instruction) { fprintf(irp->f, "@addImplicitReturnType("); ir_print_other_inst_src(irp, instruction->value); fprintf(irp->f, ")"); } static void ir_print_float_op(IrPrintSrc *irp, Stage1ZirInstFloatOp *instruction) { fprintf(irp->f, "@%s(", float_un_op_to_name(instruction->fn_id)); ir_print_other_inst_src(irp, instruction->operand); fprintf(irp->f, ")"); } static void ir_print_float_op(IrPrintGen *irp, Stage1AirInstFloatOp *instruction) { fprintf(irp->f, "@%s(", float_un_op_to_name(instruction->fn_id)); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")"); } static void ir_print_mul_add(IrPrintSrc *irp, Stage1ZirInstMulAdd *instruction) { fprintf(irp->f, "@mulAdd("); ir_print_other_inst_src(irp, instruction->type_value); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op1); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op2); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->op3); fprintf(irp->f, ")"); } static void ir_print_mul_add(IrPrintGen *irp, Stage1AirInstMulAdd *instruction) { fprintf(irp->f, "@mulAdd("); ir_print_other_inst_gen(irp, instruction->op1); fprintf(irp->f, ","); ir_print_other_inst_gen(irp, instruction->op2); fprintf(irp->f, ","); ir_print_other_inst_gen(irp, instruction->op3); fprintf(irp->f, ")"); } static void ir_print_decl_var_gen(IrPrintGen *irp, Stage1AirInstDeclVar *decl_var_instruction) { ZigVar *var = decl_var_instruction->var; const char *var_or_const = decl_var_instruction->var->gen_is_const ? "const" : "var"; const char *name = decl_var_instruction->var->name; fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name), var->align_bytes); ir_print_other_inst_gen(irp, decl_var_instruction->var_ptr); } static void ir_print_has_decl(IrPrintSrc *irp, Stage1ZirInstHasDecl *instruction) { fprintf(irp->f, "@hasDecl("); ir_print_other_inst_src(irp, instruction->container); fprintf(irp->f, ","); ir_print_other_inst_src(irp, instruction->name); fprintf(irp->f, ")"); } static void ir_print_undeclared_ident(IrPrintSrc *irp, Stage1ZirInstUndeclaredIdent *instruction) { fprintf(irp->f, "@undeclaredIdent(%s)", buf_ptr(instruction->name)); } static void ir_print_union_init_named_field(IrPrintSrc *irp, Stage1ZirInstUnionInitNamedField *instruction) { fprintf(irp->f, "@unionInit("); ir_print_other_inst_src(irp, instruction->union_type); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->field_name); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->field_result_loc); fprintf(irp->f, ", "); ir_print_other_inst_src(irp, instruction->result_loc); fprintf(irp->f, ")"); } static void ir_print_suspend_begin(IrPrintSrc *irp, Stage1ZirInstSuspendBegin *instruction) { fprintf(irp->f, "@suspendBegin()"); } static void ir_print_suspend_begin(IrPrintGen *irp, Stage1AirInstSuspendBegin *instruction) { fprintf(irp->f, "@suspendBegin()"); } static void ir_print_suspend_finish(IrPrintSrc *irp, Stage1ZirInstSuspendFinish *instruction) { fprintf(irp->f, "@suspendFinish()"); } static void ir_print_suspend_finish(IrPrintGen *irp, Stage1AirInstSuspendFinish *instruction) { fprintf(irp->f, "@suspendFinish()"); } static void ir_print_resume(IrPrintSrc *irp, Stage1ZirInstResume *instruction) { fprintf(irp->f, "resume "); ir_print_other_inst_src(irp, instruction->frame); } static void ir_print_resume(IrPrintGen *irp, Stage1AirInstResume *instruction) { fprintf(irp->f, "resume "); ir_print_other_inst_gen(irp, instruction->frame); } static void ir_print_await_src(IrPrintSrc *irp, Stage1ZirInstAwait *instruction) { fprintf(irp->f, "@await("); ir_print_other_inst_src(irp, instruction->frame); fprintf(irp->f, ","); ir_print_result_loc(irp, instruction->result_loc); fprintf(irp->f, ")"); } static void ir_print_await_gen(IrPrintGen *irp, Stage1AirInstAwait *instruction) { fprintf(irp->f, "@await("); ir_print_other_inst_gen(irp, instruction->frame); fprintf(irp->f, ","); ir_print_other_inst_gen(irp, instruction->result_loc); fprintf(irp->f, ")"); } static void ir_print_spill_begin(IrPrintSrc *irp, Stage1ZirInstSpillBegin *instruction) { fprintf(irp->f, "@spillBegin("); ir_print_other_inst_src(irp, instruction->operand); fprintf(irp->f, ")"); } static void ir_print_spill_begin(IrPrintGen *irp, Stage1AirInstSpillBegin *instruction) { fprintf(irp->f, "@spillBegin("); ir_print_other_inst_gen(irp, instruction->operand); fprintf(irp->f, ")"); } static void ir_print_spill_end(IrPrintSrc *irp, Stage1ZirInstSpillEnd *instruction) { fprintf(irp->f, "@spillEnd("); ir_print_other_inst_src(irp, &instruction->begin->base); fprintf(irp->f, ")"); } static void ir_print_spill_end(IrPrintGen *irp, Stage1AirInstSpillEnd *instruction) { fprintf(irp->f, "@spillEnd("); ir_print_other_inst_gen(irp, &instruction->begin->base); fprintf(irp->f, ")"); } static void ir_print_vector_extract_elem(IrPrintGen *irp, Stage1AirInstVectorExtractElem *instruction) { fprintf(irp->f, "@vectorExtractElem("); ir_print_other_inst_gen(irp, instruction->vector); fprintf(irp->f, ","); ir_print_other_inst_gen(irp, instruction->index); fprintf(irp->f, ")"); } static void ir_print_inst_src(IrPrintSrc *irp, Stage1ZirInst *instruction, bool trailing) { ir_print_prefix_src(irp, instruction, trailing); switch (instruction->id) { case Stage1ZirInstIdInvalid: zig_unreachable(); case Stage1ZirInstIdReturn: ir_print_return_src(irp, (Stage1ZirInstReturn *)instruction); break; case Stage1ZirInstIdConst: ir_print_const(irp, (Stage1ZirInstConst *)instruction); break; case Stage1ZirInstIdBinOp: ir_print_bin_op(irp, (Stage1ZirInstBinOp *)instruction); break; case Stage1ZirInstIdMergeErrSets: ir_print_merge_err_sets(irp, (Stage1ZirInstMergeErrSets *)instruction); break; case Stage1ZirInstIdDeclVar: ir_print_decl_var_src(irp, (Stage1ZirInstDeclVar *)instruction); break; case Stage1ZirInstIdCallExtra: ir_print_call_extra(irp, (Stage1ZirInstCallExtra *)instruction); break; case Stage1ZirInstIdAsyncCallExtra: ir_print_async_call_extra(irp, (Stage1ZirInstAsyncCallExtra *)instruction); break; case Stage1ZirInstIdCall: ir_print_call_src(irp, (Stage1ZirInstCall *)instruction); break; case Stage1ZirInstIdCallArgs: ir_print_call_args(irp, (Stage1ZirInstCallArgs *)instruction); break; case Stage1ZirInstIdUnOp: ir_print_un_op(irp, (Stage1ZirInstUnOp *)instruction); break; case Stage1ZirInstIdCondBr: ir_print_cond_br(irp, (Stage1ZirInstCondBr *)instruction); break; case Stage1ZirInstIdBr: ir_print_br(irp, (Stage1ZirInstBr *)instruction); break; case Stage1ZirInstIdPhi: ir_print_phi(irp, (Stage1ZirInstPhi *)instruction); break; case Stage1ZirInstIdContainerInitList: ir_print_container_init_list(irp, (Stage1ZirInstContainerInitList *)instruction); break; case Stage1ZirInstIdContainerInitFields: ir_print_container_init_fields(irp, (Stage1ZirInstContainerInitFields *)instruction); break; case Stage1ZirInstIdUnreachable: ir_print_unreachable(irp, (Stage1ZirInstUnreachable *)instruction); break; case Stage1ZirInstIdElemPtr: ir_print_elem_ptr(irp, (Stage1ZirInstElemPtr *)instruction); break; case Stage1ZirInstIdVarPtr: ir_print_var_ptr(irp, (Stage1ZirInstVarPtr *)instruction); break; case Stage1ZirInstIdLoadPtr: ir_print_load_ptr(irp, (Stage1ZirInstLoadPtr *)instruction); break; case Stage1ZirInstIdStorePtr: ir_print_store_ptr(irp, (Stage1ZirInstStorePtr *)instruction); break; case Stage1ZirInstIdTypeOf: ir_print_typeof(irp, (Stage1ZirInstTypeOf *)instruction); break; case Stage1ZirInstIdFieldPtr: ir_print_field_ptr(irp, (Stage1ZirInstFieldPtr *)instruction); break; case Stage1ZirInstIdSetCold: ir_print_set_cold(irp, (Stage1ZirInstSetCold *)instruction); break; case Stage1ZirInstIdSetRuntimeSafety: ir_print_set_runtime_safety(irp, (Stage1ZirInstSetRuntimeSafety *)instruction); break; case Stage1ZirInstIdSetFloatMode: ir_print_set_float_mode(irp, (Stage1ZirInstSetFloatMode *)instruction); break; case Stage1ZirInstIdArrayType: ir_print_array_type(irp, (Stage1ZirInstArrayType *)instruction); break; case Stage1ZirInstIdSliceType: ir_print_slice_type(irp, (Stage1ZirInstSliceType *)instruction); break; case Stage1ZirInstIdAnyFrameType: ir_print_any_frame_type(irp, (Stage1ZirInstAnyFrameType *)instruction); break; case Stage1ZirInstIdAsm: ir_print_asm_src(irp, (Stage1ZirInstAsm *)instruction); break; case Stage1ZirInstIdSizeOf: ir_print_size_of(irp, (Stage1ZirInstSizeOf *)instruction); break; case Stage1ZirInstIdTestNonNull: ir_print_test_non_null(irp, (Stage1ZirInstTestNonNull *)instruction); break; case Stage1ZirInstIdOptionalUnwrapPtr: ir_print_optional_unwrap_ptr(irp, (Stage1ZirInstOptionalUnwrapPtr *)instruction); break; case Stage1ZirInstIdPopCount: ir_print_pop_count(irp, (Stage1ZirInstPopCount *)instruction); break; case Stage1ZirInstIdCtz: ir_print_ctz(irp, (Stage1ZirInstCtz *)instruction); break; case Stage1ZirInstIdBswap: ir_print_bswap(irp, (Stage1ZirInstBswap *)instruction); break; case Stage1ZirInstIdBitReverse: ir_print_bit_reverse(irp, (Stage1ZirInstBitReverse *)instruction); break; case Stage1ZirInstIdSwitchBr: ir_print_switch_br(irp, (Stage1ZirInstSwitchBr *)instruction); break; case Stage1ZirInstIdSwitchVar: ir_print_switch_var(irp, (Stage1ZirInstSwitchVar *)instruction); break; case Stage1ZirInstIdSwitchElseVar: ir_print_switch_else_var(irp, (Stage1ZirInstSwitchElseVar *)instruction); break; case Stage1ZirInstIdSwitchTarget: ir_print_switch_target(irp, (Stage1ZirInstSwitchTarget *)instruction); break; case Stage1ZirInstIdImport: ir_print_import(irp, (Stage1ZirInstImport *)instruction); break; case Stage1ZirInstIdRef: ir_print_ref(irp, (Stage1ZirInstRef *)instruction); break; case Stage1ZirInstIdCompileErr: ir_print_compile_err(irp, (Stage1ZirInstCompileErr *)instruction); break; case Stage1ZirInstIdCompileLog: ir_print_compile_log(irp, (Stage1ZirInstCompileLog *)instruction); break; case Stage1ZirInstIdErrName: ir_print_err_name(irp, (Stage1ZirInstErrName *)instruction); break; case Stage1ZirInstIdCImport: ir_print_c_import(irp, (Stage1ZirInstCImport *)instruction); break; case Stage1ZirInstIdCInclude: ir_print_c_include(irp, (Stage1ZirInstCInclude *)instruction); break; case Stage1ZirInstIdCDefine: ir_print_c_define(irp, (Stage1ZirInstCDefine *)instruction); break; case Stage1ZirInstIdCUndef: ir_print_c_undef(irp, (Stage1ZirInstCUndef *)instruction); break; case Stage1ZirInstIdEmbedFile: ir_print_embed_file(irp, (Stage1ZirInstEmbedFile *)instruction); break; case Stage1ZirInstIdCmpxchg: ir_print_cmpxchg_src(irp, (Stage1ZirInstCmpxchg *)instruction); break; case Stage1ZirInstIdFence: ir_print_fence(irp, (Stage1ZirInstFence *)instruction); break; case Stage1ZirInstIdReduce: ir_print_reduce(irp, (Stage1ZirInstReduce *)instruction); break; case Stage1ZirInstIdTruncate: ir_print_truncate(irp, (Stage1ZirInstTruncate *)instruction); break; case Stage1ZirInstIdIntCast: ir_print_int_cast(irp, (Stage1ZirInstIntCast *)instruction); break; case Stage1ZirInstIdFloatCast: ir_print_float_cast(irp, (Stage1ZirInstFloatCast *)instruction); break; case Stage1ZirInstIdErrSetCast: ir_print_err_set_cast(irp, (Stage1ZirInstErrSetCast *)instruction); break; case Stage1ZirInstIdIntToFloat: ir_print_int_to_float(irp, (Stage1ZirInstIntToFloat *)instruction); break; case Stage1ZirInstIdFloatToInt: ir_print_float_to_int(irp, (Stage1ZirInstFloatToInt *)instruction); break; case Stage1ZirInstIdBoolToInt: ir_print_bool_to_int(irp, (Stage1ZirInstBoolToInt *)instruction); break; case Stage1ZirInstIdVectorType: ir_print_vector_type(irp, (Stage1ZirInstVectorType *)instruction); break; case Stage1ZirInstIdShuffleVector: ir_print_shuffle_vector(irp, (Stage1ZirInstShuffleVector *)instruction); break; case Stage1ZirInstIdSelect: ir_print_select(irp, (Stage1ZirInstSelect *)instruction); break; case Stage1ZirInstIdSplat: ir_print_splat_src(irp, (Stage1ZirInstSplat *)instruction); break; case Stage1ZirInstIdBoolNot: ir_print_bool_not(irp, (Stage1ZirInstBoolNot *)instruction); break; case Stage1ZirInstIdMemset: ir_print_memset(irp, (Stage1ZirInstMemset *)instruction); break; case Stage1ZirInstIdMemcpy: ir_print_memcpy(irp, (Stage1ZirInstMemcpy *)instruction); break; case Stage1ZirInstIdSlice: ir_print_slice_src(irp, (Stage1ZirInstSlice *)instruction); break; case Stage1ZirInstIdBreakpoint: ir_print_breakpoint(irp, (Stage1ZirInstBreakpoint *)instruction); break; case Stage1ZirInstIdReturnAddress: ir_print_return_address(irp, (Stage1ZirInstReturnAddress *)instruction); break; case Stage1ZirInstIdFrameAddress: ir_print_frame_address(irp, (Stage1ZirInstFrameAddress *)instruction); break; case Stage1ZirInstIdFrameHandle: ir_print_handle(irp, (Stage1ZirInstFrameHandle *)instruction); break; case Stage1ZirInstIdFrameType: ir_print_frame_type(irp, (Stage1ZirInstFrameType *)instruction); break; case Stage1ZirInstIdFrameSize: ir_print_frame_size_src(irp, (Stage1ZirInstFrameSize *)instruction); break; case Stage1ZirInstIdAlignOf: ir_print_align_of(irp, (Stage1ZirInstAlignOf *)instruction); break; case Stage1ZirInstIdOverflowOp: ir_print_overflow_op(irp, (Stage1ZirInstOverflowOp *)instruction); break; case Stage1ZirInstIdTestErr: ir_print_test_err_src(irp, (Stage1ZirInstTestErr *)instruction); break; case Stage1ZirInstIdUnwrapErrCode: ir_print_unwrap_err_code(irp, (Stage1ZirInstUnwrapErrCode *)instruction); break; case Stage1ZirInstIdUnwrapErrPayload: ir_print_unwrap_err_payload(irp, (Stage1ZirInstUnwrapErrPayload *)instruction); break; case Stage1ZirInstIdFnProto: ir_print_fn_proto(irp, (Stage1ZirInstFnProto *)instruction); break; case Stage1ZirInstIdTestComptime: ir_print_test_comptime(irp, (Stage1ZirInstTestComptime *)instruction); break; case Stage1ZirInstIdPtrCast: ir_print_ptr_cast_src(irp, (Stage1ZirInstPtrCast *)instruction); break; case Stage1ZirInstIdBitCast: ir_print_bit_cast_src(irp, (Stage1ZirInstBitCast *)instruction); break; case Stage1ZirInstIdPtrToInt: ir_print_ptr_to_int(irp, (Stage1ZirInstPtrToInt *)instruction); break; case Stage1ZirInstIdIntToPtr: ir_print_int_to_ptr(irp, (Stage1ZirInstIntToPtr *)instruction); break; case Stage1ZirInstIdIntToEnum: ir_print_int_to_enum(irp, (Stage1ZirInstIntToEnum *)instruction); break; case Stage1ZirInstIdIntToErr: ir_print_int_to_err(irp, (Stage1ZirInstIntToErr *)instruction); break; case Stage1ZirInstIdErrToInt: ir_print_err_to_int(irp, (Stage1ZirInstErrToInt *)instruction); break; case Stage1ZirInstIdCheckSwitchProngsUnderNo: ir_print_check_switch_prongs(irp, (Stage1ZirInstCheckSwitchProngs *)instruction, false); break; case Stage1ZirInstIdCheckSwitchProngsUnderYes: ir_print_check_switch_prongs(irp, (Stage1ZirInstCheckSwitchProngs *)instruction, true); break; case Stage1ZirInstIdCheckStatementIsVoid: ir_print_check_statement_is_void(irp, (Stage1ZirInstCheckStatementIsVoid *)instruction); break; case Stage1ZirInstIdTypeName: ir_print_type_name(irp, (Stage1ZirInstTypeName *)instruction); break; case Stage1ZirInstIdTagName: ir_print_tag_name(irp, (Stage1ZirInstTagName *)instruction); break; case Stage1ZirInstIdPtrType: ir_print_ptr_type(irp, (Stage1ZirInstPtrType *)instruction); break; case Stage1ZirInstIdPtrTypeSimple: ir_print_ptr_type_simple(irp, (Stage1ZirInstPtrTypeSimple *)instruction, false); break; case Stage1ZirInstIdPtrTypeSimpleConst: ir_print_ptr_type_simple(irp, (Stage1ZirInstPtrTypeSimple *)instruction, true); break; case Stage1ZirInstIdDeclRef: ir_print_decl_ref(irp, (Stage1ZirInstDeclRef *)instruction); break; case Stage1ZirInstIdPanic: ir_print_panic(irp, (Stage1ZirInstPanic *)instruction); break; case Stage1ZirInstIdFieldParentPtr: ir_print_field_parent_ptr(irp, (Stage1ZirInstFieldParentPtr *)instruction); break; case Stage1ZirInstIdOffsetOf: ir_print_offset_of(irp, (Stage1ZirInstOffsetOf *)instruction); break; case Stage1ZirInstIdBitOffsetOf: ir_print_bit_offset_of(irp, (Stage1ZirInstBitOffsetOf *)instruction); break; case Stage1ZirInstIdTypeInfo: ir_print_type_info(irp, (Stage1ZirInstTypeInfo *)instruction); break; case Stage1ZirInstIdType: ir_print_type(irp, (Stage1ZirInstType *)instruction); break; case Stage1ZirInstIdHasField: ir_print_has_field(irp, (Stage1ZirInstHasField *)instruction); break; case Stage1ZirInstIdSetEvalBranchQuota: ir_print_set_eval_branch_quota(irp, (Stage1ZirInstSetEvalBranchQuota *)instruction); break; case Stage1ZirInstIdAlignCast: ir_print_align_cast(irp, (Stage1ZirInstAlignCast *)instruction); break; case Stage1ZirInstIdImplicitCast: ir_print_implicit_cast(irp, (Stage1ZirInstImplicitCast *)instruction); break; case Stage1ZirInstIdResolveResult: ir_print_resolve_result(irp, (Stage1ZirInstResolveResult *)instruction); break; case Stage1ZirInstIdResetResult: ir_print_reset_result(irp, (Stage1ZirInstResetResult *)instruction); break; case Stage1ZirInstIdSetAlignStack: ir_print_set_align_stack(irp, (Stage1ZirInstSetAlignStack *)instruction); break; case Stage1ZirInstIdArgTypeAllowVarFalse: ir_print_arg_type(irp, (Stage1ZirInstArgType *)instruction, false); break; case Stage1ZirInstIdArgTypeAllowVarTrue: ir_print_arg_type(irp, (Stage1ZirInstArgType *)instruction, true); break; case Stage1ZirInstIdExport: ir_print_export(irp, (Stage1ZirInstExport *)instruction); break; case Stage1ZirInstIdExtern: ir_print_extern(irp, (Stage1ZirInstExtern*)instruction); break; case Stage1ZirInstIdErrorReturnTrace: ir_print_error_return_trace(irp, (Stage1ZirInstErrorReturnTrace *)instruction); break; case Stage1ZirInstIdErrorUnion: ir_print_error_union(irp, (Stage1ZirInstErrorUnion *)instruction); break; case Stage1ZirInstIdAtomicRmw: ir_print_atomic_rmw(irp, (Stage1ZirInstAtomicRmw *)instruction); break; case Stage1ZirInstIdSaveErrRetAddr: ir_print_save_err_ret_addr(irp, (Stage1ZirInstSaveErrRetAddr *)instruction); break; case Stage1ZirInstIdAddImplicitReturnType: ir_print_add_implicit_return_type(irp, (Stage1ZirInstAddImplicitReturnType *)instruction); break; case Stage1ZirInstIdFloatOp: ir_print_float_op(irp, (Stage1ZirInstFloatOp *)instruction); break; case Stage1ZirInstIdMulAdd: ir_print_mul_add(irp, (Stage1ZirInstMulAdd *)instruction); break; case Stage1ZirInstIdAtomicLoad: ir_print_atomic_load(irp, (Stage1ZirInstAtomicLoad *)instruction); break; case Stage1ZirInstIdAtomicStore: ir_print_atomic_store(irp, (Stage1ZirInstAtomicStore *)instruction); break; case Stage1ZirInstIdEnumToInt: ir_print_enum_to_int(irp, (Stage1ZirInstEnumToInt *)instruction); break; case Stage1ZirInstIdCheckRuntimeScope: ir_print_check_runtime_scope(irp, (Stage1ZirInstCheckRuntimeScope *)instruction); break; case Stage1ZirInstIdHasDecl: ir_print_has_decl(irp, (Stage1ZirInstHasDecl *)instruction); break; case Stage1ZirInstIdUndeclaredIdent: ir_print_undeclared_ident(irp, (Stage1ZirInstUndeclaredIdent *)instruction); break; case Stage1ZirInstIdAlloca: ir_print_alloca_src(irp, (Stage1ZirInstAlloca *)instruction); break; case Stage1ZirInstIdEndExpr: ir_print_end_expr(irp, (Stage1ZirInstEndExpr *)instruction); break; case Stage1ZirInstIdUnionInitNamedField: ir_print_union_init_named_field(irp, (Stage1ZirInstUnionInitNamedField *)instruction); break; case Stage1ZirInstIdSuspendBegin: ir_print_suspend_begin(irp, (Stage1ZirInstSuspendBegin *)instruction); break; case Stage1ZirInstIdSuspendFinish: ir_print_suspend_finish(irp, (Stage1ZirInstSuspendFinish *)instruction); break; case Stage1ZirInstIdResume: ir_print_resume(irp, (Stage1ZirInstResume *)instruction); break; case Stage1ZirInstIdAwait: ir_print_await_src(irp, (Stage1ZirInstAwait *)instruction); break; case Stage1ZirInstIdSpillBegin: ir_print_spill_begin(irp, (Stage1ZirInstSpillBegin *)instruction); break; case Stage1ZirInstIdSpillEnd: ir_print_spill_end(irp, (Stage1ZirInstSpillEnd *)instruction); break; case Stage1ZirInstIdClz: ir_print_clz(irp, (Stage1ZirInstClz *)instruction); break; case Stage1ZirInstIdWasmMemorySize: ir_print_wasm_memory_size(irp, (Stage1ZirInstWasmMemorySize *)instruction); break; case Stage1ZirInstIdWasmMemoryGrow: ir_print_wasm_memory_grow(irp, (Stage1ZirInstWasmMemoryGrow *)instruction); break; case Stage1ZirInstIdSrc: ir_print_builtin_src(irp, (Stage1ZirInstSrc *)instruction); break; case Stage1ZirInstIdPrefetch: ir_print_prefetch(irp, (Stage1ZirInstPrefetch *)instruction); break; } fprintf(irp->f, "\n"); } static void ir_print_inst_gen(IrPrintGen *irp, Stage1AirInst *instruction, bool trailing) { ir_print_prefix_gen(irp, instruction, trailing); switch (instruction->id) { case Stage1AirInstIdInvalid: zig_unreachable(); case Stage1AirInstIdReturn: ir_print_return_gen(irp, (Stage1AirInstReturn *)instruction); break; case Stage1AirInstIdConst: ir_print_const(irp, (Stage1AirInstConst *)instruction); break; case Stage1AirInstIdBinOp: ir_print_bin_op(irp, (Stage1AirInstBinOp *)instruction); break; case Stage1AirInstIdDeclVar: ir_print_decl_var_gen(irp, (Stage1AirInstDeclVar *)instruction); break; case Stage1AirInstIdCast: ir_print_cast(irp, (Stage1AirInstCast *)instruction); break; case Stage1AirInstIdCall: ir_print_call_gen(irp, (Stage1AirInstCall *)instruction); break; case Stage1AirInstIdCondBr: ir_print_cond_br(irp, (Stage1AirInstCondBr *)instruction); break; case Stage1AirInstIdBr: ir_print_br(irp, (Stage1AirInstBr *)instruction); break; case Stage1AirInstIdPhi: ir_print_phi(irp, (Stage1AirInstPhi *)instruction); break; case Stage1AirInstIdUnreachable: ir_print_unreachable(irp, (Stage1AirInstUnreachable *)instruction); break; case Stage1AirInstIdElemPtr: ir_print_elem_ptr(irp, (Stage1AirInstElemPtr *)instruction); break; case Stage1AirInstIdVarPtr: ir_print_var_ptr(irp, (Stage1AirInstVarPtr *)instruction); break; case Stage1AirInstIdReturnPtr: ir_print_return_ptr(irp, (Stage1AirInstReturnPtr *)instruction); break; case Stage1AirInstIdLoadPtr: ir_print_load_ptr_gen(irp, (Stage1AirInstLoadPtr *)instruction); break; case Stage1AirInstIdStorePtr: ir_print_store_ptr(irp, (Stage1AirInstStorePtr *)instruction); break; case Stage1AirInstIdStructFieldPtr: ir_print_struct_field_ptr(irp, (Stage1AirInstStructFieldPtr *)instruction); break; case Stage1AirInstIdUnionFieldPtr: ir_print_union_field_ptr(irp, (Stage1AirInstUnionFieldPtr *)instruction); break; case Stage1AirInstIdAsm: ir_print_asm_gen(irp, (Stage1AirInstAsm *)instruction); break; case Stage1AirInstIdTestNonNull: ir_print_test_non_null(irp, (Stage1AirInstTestNonNull *)instruction); break; case Stage1AirInstIdOptionalUnwrapPtr: ir_print_optional_unwrap_ptr(irp, (Stage1AirInstOptionalUnwrapPtr *)instruction); break; case Stage1AirInstIdPopCount: ir_print_pop_count(irp, (Stage1AirInstPopCount *)instruction); break; case Stage1AirInstIdClz: ir_print_clz(irp, (Stage1AirInstClz *)instruction); break; case Stage1AirInstIdCtz: ir_print_ctz(irp, (Stage1AirInstCtz *)instruction); break; case Stage1AirInstIdBswap: ir_print_bswap(irp, (Stage1AirInstBswap *)instruction); break; case Stage1AirInstIdBitReverse: ir_print_bit_reverse(irp, (Stage1AirInstBitReverse *)instruction); break; case Stage1AirInstIdSwitchBr: ir_print_switch_br(irp, (Stage1AirInstSwitchBr *)instruction); break; case Stage1AirInstIdUnionTag: ir_print_union_tag(irp, (Stage1AirInstUnionTag *)instruction); break; case Stage1AirInstIdRef: ir_print_ref_gen(irp, (Stage1AirInstRef *)instruction); break; case Stage1AirInstIdErrName: ir_print_err_name(irp, (Stage1AirInstErrName *)instruction); break; case Stage1AirInstIdCmpxchg: ir_print_cmpxchg_gen(irp, (Stage1AirInstCmpxchg *)instruction); break; case Stage1AirInstIdFence: ir_print_fence(irp, (Stage1AirInstFence *)instruction); break; case Stage1AirInstIdReduce: ir_print_reduce(irp, (Stage1AirInstReduce *)instruction); break; case Stage1AirInstIdTruncate: ir_print_truncate(irp, (Stage1AirInstTruncate *)instruction); break; case Stage1AirInstIdShuffleVector: ir_print_shuffle_vector(irp, (Stage1AirInstShuffleVector *)instruction); break; case Stage1AirInstIdSelect: ir_print_select(irp, (Stage1AirInstSelect *)instruction); break; case Stage1AirInstIdSplat: ir_print_splat_gen(irp, (Stage1AirInstSplat *)instruction); break; case Stage1AirInstIdBoolNot: ir_print_bool_not(irp, (Stage1AirInstBoolNot *)instruction); break; case Stage1AirInstIdMemset: ir_print_memset(irp, (Stage1AirInstMemset *)instruction); break; case Stage1AirInstIdMemcpy: ir_print_memcpy(irp, (Stage1AirInstMemcpy *)instruction); break; case Stage1AirInstIdSlice: ir_print_slice_gen(irp, (Stage1AirInstSlice *)instruction); break; case Stage1AirInstIdBreakpoint: ir_print_breakpoint(irp, (Stage1AirInstBreakpoint *)instruction); break; case Stage1AirInstIdReturnAddress: ir_print_return_address(irp, (Stage1AirInstReturnAddress *)instruction); break; case Stage1AirInstIdFrameAddress: ir_print_frame_address(irp, (Stage1AirInstFrameAddress *)instruction); break; case Stage1AirInstIdFrameHandle: ir_print_handle(irp, (Stage1AirInstFrameHandle *)instruction); break; case Stage1AirInstIdFrameSize: ir_print_frame_size_gen(irp, (Stage1AirInstFrameSize *)instruction); break; case Stage1AirInstIdOverflowOp: ir_print_overflow_op(irp, (Stage1AirInstOverflowOp *)instruction); break; case Stage1AirInstIdTestErr: ir_print_test_err_gen(irp, (Stage1AirInstTestErr *)instruction); break; case Stage1AirInstIdUnwrapErrCode: ir_print_unwrap_err_code(irp, (Stage1AirInstUnwrapErrCode *)instruction); break; case Stage1AirInstIdUnwrapErrPayload: ir_print_unwrap_err_payload(irp, (Stage1AirInstUnwrapErrPayload *)instruction); break; case Stage1AirInstIdOptionalWrap: ir_print_optional_wrap(irp, (Stage1AirInstOptionalWrap *)instruction); break; case Stage1AirInstIdErrWrapCode: ir_print_err_wrap_code(irp, (Stage1AirInstErrWrapCode *)instruction); break; case Stage1AirInstIdErrWrapPayload: ir_print_err_wrap_payload(irp, (Stage1AirInstErrWrapPayload *)instruction); break; case Stage1AirInstIdPtrCast: ir_print_ptr_cast_gen(irp, (Stage1AirInstPtrCast *)instruction); break; case Stage1AirInstIdBitCast: ir_print_bit_cast_gen(irp, (Stage1AirInstBitCast *)instruction); break; case Stage1AirInstIdWidenOrShorten: ir_print_widen_or_shorten(irp, (Stage1AirInstWidenOrShorten *)instruction); break; case Stage1AirInstIdPtrToInt: ir_print_ptr_to_int(irp, (Stage1AirInstPtrToInt *)instruction); break; case Stage1AirInstIdIntToPtr: ir_print_int_to_ptr(irp, (Stage1AirInstIntToPtr *)instruction); break; case Stage1AirInstIdIntToEnum: ir_print_int_to_enum(irp, (Stage1AirInstIntToEnum *)instruction); break; case Stage1AirInstIdIntToErr: ir_print_int_to_err(irp, (Stage1AirInstIntToErr *)instruction); break; case Stage1AirInstIdErrToInt: ir_print_err_to_int(irp, (Stage1AirInstErrToInt *)instruction); break; case Stage1AirInstIdTagName: ir_print_tag_name(irp, (Stage1AirInstTagName *)instruction); break; case Stage1AirInstIdPanic: ir_print_panic(irp, (Stage1AirInstPanic *)instruction); break; case Stage1AirInstIdFieldParentPtr: ir_print_field_parent_ptr(irp, (Stage1AirInstFieldParentPtr *)instruction); break; case Stage1AirInstIdAlignCast: ir_print_align_cast(irp, (Stage1AirInstAlignCast *)instruction); break; case Stage1AirInstIdErrorReturnTrace: ir_print_error_return_trace(irp, (Stage1AirInstErrorReturnTrace *)instruction); break; case Stage1AirInstIdAtomicRmw: ir_print_atomic_rmw(irp, (Stage1AirInstAtomicRmw *)instruction); break; case Stage1AirInstIdSaveErrRetAddr: ir_print_save_err_ret_addr(irp, (Stage1AirInstSaveErrRetAddr *)instruction); break; case Stage1AirInstIdFloatOp: ir_print_float_op(irp, (Stage1AirInstFloatOp *)instruction); break; case Stage1AirInstIdMulAdd: ir_print_mul_add(irp, (Stage1AirInstMulAdd *)instruction); break; case Stage1AirInstIdAtomicLoad: ir_print_atomic_load(irp, (Stage1AirInstAtomicLoad *)instruction); break; case Stage1AirInstIdAtomicStore: ir_print_atomic_store(irp, (Stage1AirInstAtomicStore *)instruction); break; case Stage1AirInstIdArrayToVector: ir_print_array_to_vector(irp, (Stage1AirInstArrayToVector *)instruction); break; case Stage1AirInstIdVectorToArray: ir_print_vector_to_array(irp, (Stage1AirInstVectorToArray *)instruction); break; case Stage1AirInstIdPtrOfArrayToSlice: ir_print_ptr_of_array_to_slice(irp, (Stage1AirInstPtrOfArrayToSlice *)instruction); break; case Stage1AirInstIdAssertZero: ir_print_assert_zero(irp, (Stage1AirInstAssertZero *)instruction); break; case Stage1AirInstIdAssertNonNull: ir_print_assert_non_null(irp, (Stage1AirInstAssertNonNull *)instruction); break; case Stage1AirInstIdAlloca: ir_print_alloca_gen(irp, (Stage1AirInstAlloca *)instruction); break; case Stage1AirInstIdSuspendBegin: ir_print_suspend_begin(irp, (Stage1AirInstSuspendBegin *)instruction); break; case Stage1AirInstIdSuspendFinish: ir_print_suspend_finish(irp, (Stage1AirInstSuspendFinish *)instruction); break; case Stage1AirInstIdResume: ir_print_resume(irp, (Stage1AirInstResume *)instruction); break; case Stage1AirInstIdAwait: ir_print_await_gen(irp, (Stage1AirInstAwait *)instruction); break; case Stage1AirInstIdSpillBegin: ir_print_spill_begin(irp, (Stage1AirInstSpillBegin *)instruction); break; case Stage1AirInstIdSpillEnd: ir_print_spill_end(irp, (Stage1AirInstSpillEnd *)instruction); break; case Stage1AirInstIdVectorExtractElem: ir_print_vector_extract_elem(irp, (Stage1AirInstVectorExtractElem *)instruction); break; case Stage1AirInstIdVectorStoreElem: ir_print_vector_store_elem(irp, (Stage1AirInstVectorStoreElem *)instruction); break; case Stage1AirInstIdBinaryNot: ir_print_binary_not(irp, (Stage1AirInstBinaryNot *)instruction); break; case Stage1AirInstIdNegation: ir_print_negation(irp, (Stage1AirInstNegation *)instruction); break; case Stage1AirInstIdWasmMemorySize: ir_print_wasm_memory_size(irp, (Stage1AirInstWasmMemorySize *)instruction); break; case Stage1AirInstIdWasmMemoryGrow: ir_print_wasm_memory_grow(irp, (Stage1AirInstWasmMemoryGrow *)instruction); break; case Stage1AirInstIdExtern: ir_print_extern(irp, (Stage1AirInstExtern *)instruction); break; case Stage1AirInstIdPrefetch: ir_print_prefetch(irp, (Stage1AirInstPrefetch *)instruction); break; } fprintf(irp->f, "\n"); } static void irp_print_basic_block_src(IrPrintSrc *irp, Stage1ZirBasicBlock *current_block) { fprintf(irp->f, "%s_%" PRIu32 ":\n", current_block->name_hint, current_block->debug_id); for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) { Stage1ZirInst *instruction = current_block->instruction_list.at(instr_i); ir_print_inst_src(irp, instruction, false); } } static void irp_print_basic_block_gen(IrPrintGen *irp, Stage1AirBasicBlock *current_block) { fprintf(irp->f, "%s_%" PRIu32 ":\n", current_block->name_hint, current_block->debug_id); for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) { Stage1AirInst *instruction = current_block->instruction_list.at(instr_i); irp->printed.put(instruction, 0); irp->pending.clear(); ir_print_inst_gen(irp, instruction, false); for (size_t j = 0; j < irp->pending.length; ++j) ir_print_inst_gen(irp, irp->pending.at(j), true); } } void ir_print_basic_block_src(CodeGen *codegen, FILE *f, Stage1ZirBasicBlock *bb, int indent_size) { IrPrintSrc ir_print = {}; ir_print.codegen = codegen; ir_print.f = f; ir_print.indent = indent_size; ir_print.indent_size = indent_size; irp_print_basic_block_src(&ir_print, bb); } void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, Stage1AirBasicBlock *bb, int indent_size) { IrPrintGen ir_print = {}; ir_print.codegen = codegen; ir_print.f = f; ir_print.indent = indent_size; ir_print.indent_size = indent_size; ir_print.printed = {}; ir_print.printed.init(64); ir_print.pending = {}; irp_print_basic_block_gen(&ir_print, bb); ir_print.pending.deinit(); ir_print.printed.deinit(); } void ir_print_src(CodeGen *codegen, FILE *f, Stage1Zir *executable, int indent_size) { IrPrintSrc ir_print = {}; IrPrintSrc *irp = &ir_print; irp->codegen = codegen; irp->f = f; irp->indent = indent_size; irp->indent_size = indent_size; for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) { irp_print_basic_block_src(irp, executable->basic_block_list.at(bb_i)); } } void ir_print_gen(CodeGen *codegen, FILE *f, Stage1Air *executable, int indent_size) { IrPrintGen ir_print = {}; IrPrintGen *irp = &ir_print; irp->codegen = codegen; irp->f = f; irp->indent = indent_size; irp->indent_size = indent_size; irp->printed = {}; irp->printed.init(64); irp->pending = {}; for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) { irp_print_basic_block_gen(irp, executable->basic_block_list.at(bb_i)); } irp->pending.deinit(); irp->printed.deinit(); } void ir_print_inst_src(CodeGen *codegen, FILE *f, Stage1ZirInst *instruction, int indent_size) { IrPrintSrc ir_print = {}; IrPrintSrc *irp = &ir_print; irp->codegen = codegen; irp->f = f; irp->indent = indent_size; irp->indent_size = indent_size; ir_print_inst_src(irp, instruction, false); } void ir_print_inst_gen(CodeGen *codegen, FILE *f, Stage1AirInst *instruction, int indent_size) { IrPrintGen ir_print = {}; IrPrintGen *irp = &ir_print; irp->codegen = codegen; irp->f = f; irp->indent = indent_size; irp->indent_size = indent_size; irp->printed = {}; irp->printed.init(4); irp->pending = {}; ir_print_inst_gen(irp, instruction, false); } void Stage1ZirInst::dump() { Stage1ZirInst *inst = this; inst->src(); if (inst->scope == nullptr) { fprintf(stderr, "(null scope)\n"); } else { ir_print_inst_src(inst->scope->codegen, stderr, inst, 0); fprintf(stderr, "-> "); ir_print_inst_gen(inst->scope->codegen, stderr, inst->child, 0); } }