Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include "IRGenerator.h" | ||
4 | |||
5 | #include <ast/ASTNodes.h> | ||
6 | #include <llvm/IR/InlineAsm.h> | ||
7 | |||
8 | #include <llvm/IR/Module.h> | ||
9 | |||
10 | namespace spice::compiler { | ||
11 | |||
12 | 1355 | std::any IRGenerator::visitBuiltinCall(const BuiltinCallNode *node) { | |
13 |
2/2✓ Branch 0 (2→3) taken 619 times.
✓ Branch 1 (2→4) taken 736 times.
|
1355 | if (node->printfCall) |
14 | 619 | return visit(node->printfCall); | |
15 |
2/2✓ Branch 0 (4→5) taken 126 times.
✓ Branch 1 (4→6) taken 610 times.
|
736 | if (node->sizeofCall) |
16 | 126 | return visit(node->sizeofCall); | |
17 |
2/2✓ Branch 0 (6→7) taken 11 times.
✓ Branch 1 (6→8) taken 599 times.
|
610 | if (node->alignofCall) |
18 | 11 | return visit(node->alignofCall); | |
19 |
2/2✓ Branch 0 (8→9) taken 35 times.
✓ Branch 1 (8→10) taken 564 times.
|
599 | if (node->lenCall) |
20 | 35 | return visit(node->lenCall); | |
21 |
2/2✓ Branch 0 (10→11) taken 563 times.
✓ Branch 1 (10→12) taken 1 times.
|
564 | if (node->panicCall) |
22 | 563 | return visit(node->panicCall); | |
23 |
1/2✓ Branch 0 (12→13) taken 1 times.
✗ Branch 1 (12→14) not taken.
|
1 | if (node->sysCall) |
24 | 1 | return visit(node->sysCall); | |
25 | ✗ | assert_fail("Unknown builtin call"); | |
26 | return nullptr; | ||
27 | } | ||
28 | |||
29 | 619 | std::any IRGenerator::visitPrintfCall(const PrintfCallNode *node) { | |
30 | // Retrieve printf function | ||
31 |
1/2✓ Branch 0 (2→3) taken 619 times.
✗ Branch 1 (2→114) not taken.
|
619 | llvm::Function *printfFct = stdFunctionManager.getPrintfFct(); |
32 | |||
33 | // Push the template string as first argument | ||
34 | 619 | std::vector<llvm::Value *> printfArgs; | |
35 |
2/4✓ Branch 0 (5→6) taken 619 times.
✗ Branch 1 (5→75) not taken.
✓ Branch 2 (6→7) taken 619 times.
✗ Branch 3 (6→73) not taken.
|
1238 | llvm::Constant *templateString = createGlobalStringConst("printf.str.", node->templatedString, node->codeLoc); |
36 |
1/2✓ Branch 0 (9→10) taken 619 times.
✗ Branch 1 (9→79) not taken.
|
619 | printfArgs.push_back(templateString); |
37 | |||
38 | // Collect replacement arguments | ||
39 |
2/2✓ Branch 0 (62→12) taken 513 times.
✓ Branch 1 (62→63) taken 619 times.
|
1132 | for (const AssignExprNode *arg : node->args) { |
40 | // Retrieve type of argument | ||
41 |
1/2✓ Branch 0 (13→14) taken 513 times.
✗ Branch 1 (13→106) not taken.
|
513 | const QualType argSymbolType = arg->getEvaluatedSymbolType(manIdx); |
42 | |||
43 | // Re-map some values | ||
44 | llvm::Value *argVal; | ||
45 |
2/4✓ Branch 0 (14→15) taken 513 times.
✗ Branch 1 (14→106) not taken.
✗ Branch 2 (15→16) not taken.
✓ Branch 3 (15→28) taken 513 times.
|
513 | if (argSymbolType.isArray()) { |
46 | ✗ | llvm::Value *argValPtr = resolveAddress(arg); | |
47 | ✗ | llvm::Value *indices[2] = {builder.getInt64(0), builder.getInt32(0)}; | |
48 | ✗ | llvm::Type *argType = argSymbolType.toLLVMType(sourceFile); | |
49 | ✗ | argVal = insertInBoundsGEP(argType, argValPtr, indices); | |
50 |
4/6✓ Branch 0 (28→29) taken 513 times.
✗ Branch 1 (28→88) not taken.
✓ Branch 2 (29→30) taken 513 times.
✗ Branch 3 (29→88) not taken.
✓ Branch 4 (30→31) taken 41 times.
✓ Branch 5 (30→48) taken 472 times.
|
513 | } else if (argSymbolType.getBase().isStringObj()) { |
51 |
1/2✓ Branch 0 (31→32) taken 41 times.
✗ Branch 1 (31→106) not taken.
|
41 | llvm::Value *argValPtr = resolveAddress(arg); |
52 |
2/4✓ Branch 0 (32→33) taken 41 times.
✗ Branch 1 (32→89) not taken.
✓ Branch 2 (33→34) taken 41 times.
✗ Branch 3 (33→89) not taken.
|
41 | llvm::Type *argBaseType = argSymbolType.getBase().toLLVMType(sourceFile); |
53 |
1/2✓ Branch 0 (37→38) taken 41 times.
✗ Branch 1 (37→90) not taken.
|
41 | argValPtr = insertStructGEP(argBaseType, argValPtr, 0); |
54 |
3/6✓ Branch 0 (42→43) taken 41 times.
✗ Branch 1 (42→98) not taken.
✓ Branch 2 (43→44) taken 41 times.
✗ Branch 3 (43→96) not taken.
✓ Branch 4 (44→45) taken 41 times.
✗ Branch 5 (44→96) not taken.
|
82 | argVal = insertLoad(builder.getPtrTy(), argValPtr); |
55 | } else { | ||
56 |
1/2✓ Branch 0 (48→49) taken 472 times.
✗ Branch 1 (48→106) not taken.
|
472 | argVal = resolveValue(arg); |
57 | } | ||
58 | |||
59 | // Extend all integer types lower than 32 bit to 32 bit | ||
60 |
4/6✓ Branch 0 (50→51) taken 513 times.
✗ Branch 1 (50→103) not taken.
✓ Branch 2 (51→52) taken 513 times.
✗ Branch 3 (51→102) not taken.
✓ Branch 4 (52→53) taken 77 times.
✓ Branch 5 (52→59) taken 436 times.
|
513 | if (argSymbolType.removeReferenceWrapper().isOneOf({TY_SHORT, TY_BYTE, TY_CHAR, TY_BOOL})) |
61 |
5/10✓ Branch 0 (53→54) taken 77 times.
✗ Branch 1 (53→105) not taken.
✓ Branch 2 (54→55) taken 77 times.
✗ Branch 3 (54→104) not taken.
✓ Branch 4 (55→56) taken 77 times.
✗ Branch 5 (55→104) not taken.
✓ Branch 6 (56→57) taken 77 times.
✗ Branch 7 (56→104) not taken.
✓ Branch 8 (57→58) taken 77 times.
✗ Branch 9 (57→104) not taken.
|
77 | argVal = builder.CreateIntCast(argVal, builder.getInt32Ty(), argSymbolType.removeReferenceWrapper().isSigned()); |
62 | |||
63 |
1/2✓ Branch 0 (59→60) taken 513 times.
✗ Branch 1 (59→106) not taken.
|
513 | printfArgs.push_back(argVal); |
64 | } | ||
65 | |||
66 | // Call printf function | ||
67 |
3/6✓ Branch 0 (63→64) taken 619 times.
✗ Branch 1 (63→110) not taken.
✓ Branch 2 (65→66) taken 619 times.
✗ Branch 3 (65→108) not taken.
✓ Branch 4 (66→67) taken 619 times.
✗ Branch 5 (66→108) not taken.
|
619 | llvm::CallInst *returnValue = builder.CreateCall(printfFct, printfArgs); |
68 | |||
69 | // Add noundef attribute to template string | ||
70 |
1/2✓ Branch 0 (67→68) taken 619 times.
✗ Branch 1 (67→112) not taken.
|
619 | returnValue->addParamAttr(0, llvm::Attribute::NoUndef); |
71 | |||
72 |
1/2✓ Branch 0 (68→69) taken 619 times.
✗ Branch 1 (68→111) not taken.
|
1238 | return LLVMExprResult{.value = returnValue}; |
73 | 619 | } | |
74 | |||
75 | 126 | std::any IRGenerator::visitSizeofCall(const SizeofCallNode *node) { | |
76 | llvm::Type *type; | ||
77 |
2/2✓ Branch 0 (2→3) taken 109 times.
✓ Branch 1 (2→7) taken 17 times.
|
126 | if (node->isType) { // Size of type |
78 |
2/4✓ Branch 0 (3→4) taken 109 times.
✗ Branch 1 (3→20) not taken.
✓ Branch 2 (4→5) taken 109 times.
✗ Branch 3 (4→18) not taken.
|
109 | type = any_cast<llvm::Type *>(visit(node->dataType)); |
79 | } else { // Size of value | ||
80 |
2/4✓ Branch 0 (7→8) taken 17 times.
✗ Branch 1 (7→22) not taken.
✓ Branch 2 (8→9) taken 17 times.
✗ Branch 3 (8→22) not taken.
|
17 | type = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile); |
81 | } | ||
82 | // Calculate size at compile-time | ||
83 |
1/2✓ Branch 0 (11→12) taken 126 times.
✗ Branch 1 (11→22) not taken.
|
126 | const llvm::TypeSize sizeInBits = module->getDataLayout().getTypeSizeInBits(type); |
84 | |||
85 | // Return size value | ||
86 |
2/4✓ Branch 0 (12→13) taken 126 times.
✗ Branch 1 (12→22) not taken.
✓ Branch 2 (13→14) taken 126 times.
✗ Branch 3 (13→22) not taken.
|
126 | llvm::Value *sizeValue = builder.getInt64(sizeInBits); |
87 |
1/2✓ Branch 0 (14→15) taken 126 times.
✗ Branch 1 (14→21) not taken.
|
252 | return LLVMExprResult{.value = sizeValue}; |
88 | } | ||
89 | |||
90 | 11 | std::any IRGenerator::visitAlignofCall(const AlignofCallNode *node) { | |
91 | llvm::Type *type; | ||
92 |
2/2✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→7) taken 10 times.
|
11 | if (node->isType) { // Align of type |
93 |
2/4✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→20) not taken.
✓ Branch 2 (4→5) taken 1 times.
✗ Branch 3 (4→18) not taken.
|
1 | type = any_cast<llvm::Type *>(visit(node->dataType)); |
94 | } else { // Align of value | ||
95 |
2/4✓ Branch 0 (7→8) taken 10 times.
✗ Branch 1 (7→22) not taken.
✓ Branch 2 (8→9) taken 10 times.
✗ Branch 3 (8→22) not taken.
|
10 | type = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile); |
96 | } | ||
97 | // Calculate size at compile-time | ||
98 |
1/2✓ Branch 0 (11→12) taken 11 times.
✗ Branch 1 (11→22) not taken.
|
11 | const llvm::Align align = module->getDataLayout().getABITypeAlign(type); |
99 | |||
100 | // Return align value | ||
101 |
1/2✓ Branch 0 (13→14) taken 11 times.
✗ Branch 1 (13→22) not taken.
|
11 | llvm::Value *sizeValue = builder.getInt64(align.value()); |
102 |
1/2✓ Branch 0 (14→15) taken 11 times.
✗ Branch 1 (14→21) not taken.
|
22 | return LLVMExprResult{.value = sizeValue}; |
103 | } | ||
104 | |||
105 | 35 | std::any IRGenerator::visitLenCall(const LenCallNode *node) { | |
106 | // Check if the length is fixed and known via the symbol type | ||
107 |
1/2✓ Branch 0 (2→3) taken 35 times.
✗ Branch 1 (2→32) not taken.
|
35 | QualType symbolType = node->assignExpr->getEvaluatedSymbolType(manIdx); |
108 |
1/2✓ Branch 0 (3→4) taken 35 times.
✗ Branch 1 (3→26) not taken.
|
35 | symbolType = symbolType.removeReferenceWrapper(); |
109 | |||
110 | llvm::Value *lengthValue; | ||
111 |
3/4✓ Branch 0 (4→5) taken 35 times.
✗ Branch 1 (4→32) not taken.
✓ Branch 2 (5→6) taken 23 times.
✓ Branch 3 (5→13) taken 12 times.
|
35 | if (symbolType.is(TY_STRING)) { |
112 |
1/2✓ Branch 0 (6→7) taken 23 times.
✗ Branch 1 (6→32) not taken.
|
23 | llvm::Function *getRawLengthFct = stdFunctionManager.getStringGetRawLengthStringFct(); |
113 |
4/8✓ Branch 0 (7→8) taken 23 times.
✗ Branch 1 (7→30) not taken.
✓ Branch 2 (8→9) taken 23 times.
✗ Branch 3 (8→28) not taken.
✓ Branch 4 (10→11) taken 23 times.
✗ Branch 5 (10→27) not taken.
✓ Branch 6 (11→12) taken 23 times.
✗ Branch 7 (11→27) not taken.
|
23 | lengthValue = builder.CreateCall(getRawLengthFct, resolveValue(node->assignExpr)); |
114 | } else { | ||
115 |
4/8✓ Branch 0 (13→14) taken 12 times.
✗ Branch 1 (13→32) not taken.
✓ Branch 2 (14→15) taken 12 times.
✗ Branch 3 (14→18) not taken.
✓ Branch 4 (15→16) taken 12 times.
✗ Branch 5 (15→32) not taken.
✓ Branch 6 (16→17) taken 12 times.
✗ Branch 7 (16→18) not taken.
|
12 | assert(symbolType.isArray() && symbolType.getArraySize() != ARRAY_SIZE_UNKNOWN); |
116 | // Return length value | ||
117 |
2/4✓ Branch 0 (19→20) taken 12 times.
✗ Branch 1 (19→32) not taken.
✓ Branch 2 (20→21) taken 12 times.
✗ Branch 3 (20→32) not taken.
|
12 | lengthValue = builder.getInt64(symbolType.getArraySize()); |
118 | } | ||
119 |
1/2✓ Branch 0 (22→23) taken 35 times.
✗ Branch 1 (22→31) not taken.
|
70 | return LLVMExprResult{.value = lengthValue}; |
120 | } | ||
121 | |||
122 | 563 | std::any IRGenerator::visitPanicCall(const PanicCallNode *node) { | |
123 | // Get value for stderr | ||
124 |
1/2✓ Branch 0 (2→3) taken 563 times.
✗ Branch 1 (2→128) not taken.
|
563 | llvm::PointerType *ptrTy = builder.getPtrTy(); |
125 | 563 | constexpr auto globalName = "stderr"; | |
126 |
2/4✓ Branch 0 (3→4) taken 563 times.
✗ Branch 1 (3→71) not taken.
✓ Branch 2 (4→5) taken 563 times.
✗ Branch 3 (4→71) not taken.
|
563 | module->getOrInsertGlobal(globalName, ptrTy); |
127 |
2/4✓ Branch 0 (5→6) taken 563 times.
✗ Branch 1 (5→72) not taken.
✓ Branch 2 (6→7) taken 563 times.
✗ Branch 3 (6→72) not taken.
|
563 | llvm::GlobalVariable *stdErrPtr = module->getNamedGlobal(globalName); |
128 |
1/2✓ Branch 0 (7→8) taken 563 times.
✗ Branch 1 (7→128) not taken.
|
563 | stdErrPtr->setLinkage(llvm::GlobalVariable::ExternalLinkage); |
129 | 563 | stdErrPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local); | |
130 |
2/4✓ Branch 0 (9→10) taken 563 times.
✗ Branch 1 (9→73) not taken.
✓ Branch 2 (10→11) taken 563 times.
✗ Branch 3 (10→73) not taken.
|
563 | stdErrPtr->setAlignment(llvm::MaybeAlign(8)); |
131 |
2/4✓ Branch 0 (13→14) taken 563 times.
✗ Branch 1 (13→76) not taken.
✓ Branch 2 (14→15) taken 563 times.
✗ Branch 3 (14→74) not taken.
|
563 | llvm::Value *stdErr = insertLoad(ptrTy, stdErrPtr); |
132 | |||
133 | // Create constant for error message | ||
134 |
1/2✓ Branch 0 (17→18) taken 563 times.
✗ Branch 1 (17→128) not taken.
|
563 | const std::string codeLoc = node->codeLoc.toPrettyString(); |
135 |
5/10✓ Branch 0 (18→19) taken 563 times.
✗ Branch 1 (18→90) not taken.
✓ Branch 2 (19→20) taken 563 times.
✗ Branch 3 (19→86) not taken.
✓ Branch 4 (20→21) taken 563 times.
✗ Branch 5 (20→84) not taken.
✓ Branch 6 (21→22) taken 563 times.
✗ Branch 7 (21→82) not taken.
✓ Branch 8 (22→23) taken 563 times.
✗ Branch 9 (22→80) not taken.
|
563 | const std::string templateStr = "Program panicked at " + codeLoc + ": %s\n" + node->getErrorMessage() + "\n"; |
136 |
4/8✓ Branch 0 (29→30) taken 563 times.
✗ Branch 1 (29→97) not taken.
✓ Branch 2 (30→31) taken 563 times.
✗ Branch 3 (30→95) not taken.
✓ Branch 4 (31→32) taken 563 times.
✗ Branch 5 (31→93) not taken.
✓ Branch 6 (33→34) taken 563 times.
✗ Branch 7 (33→92) not taken.
|
1126 | llvm::Constant *globalString = builder.CreateGlobalString(templateStr, getUnusedGlobalName(ANON_GLOBAL_STRING_NAME)); |
137 | |||
138 | // Get actual error message | ||
139 |
1/2✓ Branch 0 (37→38) taken 563 times.
✗ Branch 1 (37→124) not taken.
|
563 | llvm::Value *errorObjPtr = resolveAddress(node->assignExpr); |
140 |
2/4✓ Branch 0 (38→39) taken 563 times.
✗ Branch 1 (38→124) not taken.
✓ Branch 2 (39→40) taken 563 times.
✗ Branch 3 (39→124) not taken.
|
563 | llvm::Type *errorObjTy = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile); |
141 |
1/2✓ Branch 0 (43→44) taken 563 times.
✗ Branch 1 (43→103) not taken.
|
563 | llvm::Value *errorMessagePtr = insertStructGEP(errorObjTy, errorObjPtr, 1); |
142 |
2/4✓ Branch 0 (48→49) taken 563 times.
✗ Branch 1 (48→111) not taken.
✓ Branch 2 (49→50) taken 563 times.
✗ Branch 3 (49→109) not taken.
|
563 | llvm::Value *errorMessage = insertLoad(ptrTy, errorMessagePtr); |
143 | |||
144 | // Print the error message to stderr | ||
145 |
1/2✓ Branch 0 (52→53) taken 563 times.
✗ Branch 1 (52→124) not taken.
|
563 | llvm::Function *fprintfFct = stdFunctionManager.getFPrintfFct(); |
146 |
3/6✓ Branch 0 (53→54) taken 563 times.
✗ Branch 1 (53→118) not taken.
✓ Branch 2 (55→56) taken 563 times.
✗ Branch 3 (55→115) not taken.
✓ Branch 4 (56→57) taken 563 times.
✗ Branch 5 (56→115) not taken.
|
563 | builder.CreateCall(fprintfFct, {stdErr, globalString, errorMessage}); |
147 | |||
148 | // Generate call to exit() | ||
149 |
1/2✓ Branch 0 (57→58) taken 563 times.
✗ Branch 1 (57→124) not taken.
|
563 | llvm::Function *exitFct = stdFunctionManager.getExitFct(); |
150 |
4/8✓ Branch 0 (58→59) taken 563 times.
✗ Branch 1 (58→122) not taken.
✓ Branch 2 (59→60) taken 563 times.
✗ Branch 3 (59→120) not taken.
✓ Branch 4 (61→62) taken 563 times.
✗ Branch 5 (61→119) not taken.
✓ Branch 6 (62→63) taken 563 times.
✗ Branch 7 (62→119) not taken.
|
563 | builder.CreateCall(exitFct, builder.getInt32(EXIT_FAILURE)); |
151 | // Create unreachable instruction | ||
152 |
1/2✓ Branch 0 (63→64) taken 563 times.
✗ Branch 1 (63→124) not taken.
|
563 | builder.CreateUnreachable(); |
153 | // Unreachable counts as terminator | ||
154 |
2/4✓ Branch 0 (64→65) taken 563 times.
✗ Branch 1 (64→124) not taken.
✓ Branch 2 (65→66) taken 563 times.
✗ Branch 3 (65→124) not taken.
|
563 | terminateBlock(node->getNextOuterStmtLst()); |
155 | |||
156 |
1/2✓ Branch 0 (66→67) taken 563 times.
✗ Branch 1 (66→123) not taken.
|
1126 | return nullptr; |
157 | 563 | } | |
158 | |||
159 | 1 | std::any IRGenerator::visitSysCall(const SysCallNode *node) { | |
160 | // Create assembly string | ||
161 | static constexpr uint8_t NUM_REGS = 7; | ||
162 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→54) not taken.
|
1 | const char *asmString = getSysCallAsmString(); |
163 |
1/2✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→54) not taken.
|
1 | const char *constraints = getSysCallConstraintString(); |
164 | |||
165 | // Create inline assembly | ||
166 |
1/2✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→54) not taken.
|
1 | llvm::Type *int64Ty = builder.getInt64Ty(); |
167 | 1 | llvm::Type *argTypes[NUM_REGS] = {int64Ty, int64Ty, int64Ty, int64Ty, int64Ty, int64Ty, int64Ty}; | |
168 |
2/4✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→43) not taken.
✓ Branch 2 (7→8) taken 1 times.
✗ Branch 3 (7→43) not taken.
|
1 | llvm::FunctionType *fctType = llvm::FunctionType::get(builder.getVoidTy(), argTypes, false); |
169 |
3/6✓ Branch 0 (8→9) taken 1 times.
✗ Branch 1 (8→45) not taken.
✓ Branch 2 (9→10) taken 1 times.
✗ Branch 3 (9→44) not taken.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→44) not taken.
|
1 | llvm::InlineAsm *inlineAsm = llvm::InlineAsm::get(fctType, asmString, constraints, true); |
170 | |||
171 | // Fill arguments array (first argument is syscall number) | ||
172 | llvm::Value *argValues[NUM_REGS]; | ||
173 |
2/2✓ Branch 0 (34→12) taken 7 times.
✓ Branch 1 (34→35) taken 1 times.
|
8 | for (unsigned short i = 0; i < NUM_REGS; i++) { |
174 |
2/2✓ Branch 0 (13→14) taken 4 times.
✓ Branch 1 (13→31) taken 3 times.
|
7 | if (i < node->args.size()) { |
175 |
1/2✓ Branch 0 (14→15) taken 4 times.
✗ Branch 1 (14→54) not taken.
|
4 | const AssignExprNode *argNode = node->args.at(i); |
176 |
1/2✓ Branch 0 (15→16) taken 4 times.
✗ Branch 1 (15→54) not taken.
|
4 | const QualType &argType = argNode->getEvaluatedSymbolType(manIdx); |
177 |
2/4✓ Branch 0 (16→17) taken 4 times.
✗ Branch 1 (16→46) not taken.
✗ Branch 2 (17→18) not taken.
✓ Branch 3 (17→19) taken 4 times.
|
4 | assert(argType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BOOL, TY_BYTE, TY_PTR, TY_STRING})); |
178 |
3/4✓ Branch 0 (19→20) taken 4 times.
✗ Branch 1 (19→47) not taken.
✓ Branch 2 (20→21) taken 1 times.
✓ Branch 3 (20→26) taken 3 times.
|
4 | if (argType.isOneOf({TY_PTR, TY_STRING})) |
179 |
4/8✓ Branch 0 (21→22) taken 1 times.
✗ Branch 1 (21→48) not taken.
✓ Branch 2 (22→23) taken 1 times.
✗ Branch 3 (22→48) not taken.
✓ Branch 4 (23→24) taken 1 times.
✗ Branch 5 (23→48) not taken.
✓ Branch 6 (24→25) taken 1 times.
✗ Branch 7 (24→48) not taken.
|
1 | argValues[i] = builder.CreatePtrToInt(resolveValue(argNode), builder.getInt64Ty()); |
180 | else | ||
181 |
4/8✓ Branch 0 (26→27) taken 3 times.
✗ Branch 1 (26→49) not taken.
✓ Branch 2 (27→28) taken 3 times.
✗ Branch 3 (27→49) not taken.
✓ Branch 4 (28→29) taken 3 times.
✗ Branch 5 (28→49) not taken.
✓ Branch 6 (29→30) taken 3 times.
✗ Branch 7 (29→49) not taken.
|
3 | argValues[i] = builder.CreateZExt(resolveValue(argNode), builder.getInt64Ty()); |
182 | } else { | ||
183 |
1/2✓ Branch 0 (31→32) taken 3 times.
✗ Branch 1 (31→54) not taken.
|
3 | argValues[i] = builder.getInt64(0); |
184 | } | ||
185 | } | ||
186 | |||
187 | // Generate call | ||
188 |
3/6✓ Branch 0 (35→36) taken 1 times.
✗ Branch 1 (35→52) not taken.
✓ Branch 2 (37→38) taken 1 times.
✗ Branch 3 (37→50) not taken.
✓ Branch 4 (38→39) taken 1 times.
✗ Branch 5 (38→50) not taken.
|
1 | llvm::Value *result = builder.CreateCall(inlineAsm, argValues); |
189 | |||
190 |
1/2✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→53) not taken.
|
2 | return LLVMExprResult{.value = result}; |
191 | } | ||
192 | |||
193 | } // namespace spice::compiler | ||
194 |