llvm_backend_proc.cpp 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551
  1. void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
  2. dst = lb_emit_conv(p, dst, t_rawptr);
  3. src = lb_emit_conv(p, src, t_rawptr);
  4. len = lb_emit_conv(p, len, t_int);
  5. char const *name = "llvm.memmove";
  6. if (LLVMIsConstant(len.value)) {
  7. i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
  8. if (const_len <= 4*build_context.word_size) {
  9. name = "llvm.memmove.inline";
  10. }
  11. }
  12. LLVMTypeRef types[3] = {
  13. lb_type(p->module, t_rawptr),
  14. lb_type(p->module, t_rawptr),
  15. lb_type(p->module, t_int)
  16. };
  17. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  18. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2]));
  19. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  20. LLVMValueRef args[4] = {};
  21. args[0] = dst.value;
  22. args[1] = src.value;
  23. args[2] = len.value;
  24. args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile);
  25. LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  26. }
  27. void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
  28. dst = lb_emit_conv(p, dst, t_rawptr);
  29. src = lb_emit_conv(p, src, t_rawptr);
  30. len = lb_emit_conv(p, len, t_int);
  31. char const *name = "llvm.memcpy";
  32. if (LLVMIsConstant(len.value)) {
  33. i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
  34. if (const_len <= 4*build_context.word_size) {
  35. name = "llvm.memcpy.inline";
  36. }
  37. }
  38. LLVMTypeRef types[3] = {
  39. lb_type(p->module, t_rawptr),
  40. lb_type(p->module, t_rawptr),
  41. lb_type(p->module, t_int)
  42. };
  43. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  44. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2]));
  45. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  46. LLVMValueRef args[4] = {};
  47. args[0] = dst.value;
  48. args[1] = src.value;
  49. args[2] = len.value;
  50. args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile);
  51. LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  52. }
  53. lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
  54. GB_ASSERT(entity != nullptr);
  55. GB_ASSERT(entity->kind == Entity_Procedure);
  56. if (!entity->Procedure.is_foreign) {
  57. GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s", LIT(entity->token.string), type_to_string(entity->type));
  58. }
  59. String link_name = {};
  60. if (ignore_body) {
  61. lbModule *other_module = lb_pkg_module(m->gen, entity->pkg);
  62. link_name = lb_get_entity_name(other_module, entity);
  63. } else {
  64. link_name = lb_get_entity_name(m, entity);
  65. }
  66. {
  67. StringHashKey key = string_hash_string(link_name);
  68. lbValue *found = string_map_get(&m->members, key);
  69. if (found) {
  70. lb_add_entity(m, entity, *found);
  71. return string_map_must_get(&m->procedures, key);
  72. }
  73. }
  74. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  75. p->module = m;
  76. entity->code_gen_module = m;
  77. entity->code_gen_procedure = p;
  78. p->entity = entity;
  79. p->name = link_name;
  80. DeclInfo *decl = entity->decl_info;
  81. ast_node(pl, ProcLit, decl->proc_lit);
  82. Type *pt = base_type(entity->type);
  83. GB_ASSERT(pt->kind == Type_Proc);
  84. p->type = entity->type;
  85. p->type_expr = decl->type_expr;
  86. p->body = pl->body;
  87. p->inlining = pl->inlining;
  88. p->is_foreign = entity->Procedure.is_foreign;
  89. p->is_export = entity->Procedure.is_export;
  90. p->is_entry_point = false;
  91. gbAllocator a = heap_allocator();
  92. p->children.allocator = a;
  93. p->defer_stmts.allocator = a;
  94. p->blocks.allocator = a;
  95. p->branch_blocks.allocator = a;
  96. p->context_stack.allocator = a;
  97. p->scope_stack.allocator = a;
  98. if (p->is_foreign) {
  99. lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library);
  100. }
  101. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  102. LLVMTypeRef func_ptr_type = lb_type(m, p->type);
  103. LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
  104. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  105. lb_ensure_abi_function_type(m, p);
  106. lb_add_function_type_attributes(p->value, p->abi_function_type, p->abi_function_type->calling_convention);
  107. if (pt->Proc.diverging) {
  108. lb_add_attribute_to_proc(m, p->value, "noreturn");
  109. }
  110. if (pt->Proc.calling_convention == ProcCC_Naked) {
  111. lb_add_attribute_to_proc(m, p->value, "naked");
  112. }
  113. switch (p->inlining) {
  114. case ProcInlining_inline:
  115. lb_add_attribute_to_proc(m, p->value, "alwaysinline");
  116. break;
  117. case ProcInlining_no_inline:
  118. lb_add_attribute_to_proc(m, p->value, "noinline");
  119. break;
  120. }
  121. if (entity->flags & EntityFlag_Cold) {
  122. lb_add_attribute_to_proc(m, p->value, "cold");
  123. }
  124. switch (entity->Procedure.optimization_mode) {
  125. case ProcedureOptimizationMode_None:
  126. lb_add_attribute_to_proc(m, p->value, "optnone");
  127. break;
  128. case ProcedureOptimizationMode_Minimal:
  129. lb_add_attribute_to_proc(m, p->value, "optnone");
  130. break;
  131. case ProcedureOptimizationMode_Size:
  132. lb_add_attribute_to_proc(m, p->value, "optsize");
  133. break;
  134. case ProcedureOptimizationMode_Speed:
  135. // TODO(bill): handle this correctly
  136. lb_add_attribute_to_proc(m, p->value, "optsize");
  137. break;
  138. }
  139. lbValue proc_value = {p->value, p->type};
  140. lb_add_entity(m, entity, proc_value);
  141. lb_add_member(m, p->name, proc_value);
  142. lb_add_procedure_value(m, p);
  143. if (p->is_export) {
  144. LLVMSetLinkage(p->value, LLVMDLLExportLinkage);
  145. LLVMSetDLLStorageClass(p->value, LLVMDLLExportStorageClass);
  146. LLVMSetVisibility(p->value, LLVMDefaultVisibility);
  147. lb_set_wasm_export_attributes(p->value, p->name);
  148. } else if (!p->is_foreign) {
  149. if (!USE_SEPARATE_MODULES) {
  150. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  151. // NOTE(bill): if a procedure is defined in package runtime and uses a custom link name,
  152. // then it is very likely it is required by LLVM and thus cannot have internal linkage
  153. if (entity->pkg != nullptr && entity->pkg->kind == Package_Runtime && p->body != nullptr) {
  154. GB_ASSERT(entity->kind == Entity_Procedure);
  155. String link_name = entity->Procedure.link_name;
  156. if (entity->flags & EntityFlag_CustomLinkName &&
  157. link_name != "") {
  158. if (string_starts_with(link_name, str_lit("__"))) {
  159. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  160. } else {
  161. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  162. }
  163. }
  164. }
  165. }
  166. }
  167. lb_set_linkage_from_entity_flags(p->module, p->value, entity->flags);
  168. if (p->is_foreign) {
  169. lb_set_wasm_import_attributes(p->value, entity, p->name);
  170. }
  171. // NOTE(bill): offset==0 is the return value
  172. isize offset = 1;
  173. if (pt->Proc.return_by_pointer) {
  174. offset = 2;
  175. }
  176. isize parameter_index = 0;
  177. if (pt->Proc.param_count) {
  178. TypeTuple *params = &pt->Proc.params->Tuple;
  179. for (isize i = 0; i < pt->Proc.param_count; i++) {
  180. Entity *e = params->variables[i];
  181. if (e->kind != Entity_Variable) {
  182. continue;
  183. }
  184. if (i+1 == params->variables.count && pt->Proc.c_vararg) {
  185. continue;
  186. }
  187. if (e->flags&EntityFlag_NoAlias) {
  188. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  189. }
  190. parameter_index += 1;
  191. }
  192. }
  193. if (ignore_body) {
  194. p->body = nullptr;
  195. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  196. }
  197. if (m->debug_builder) { // Debug Information
  198. Type *bt = base_type(p->type);
  199. unsigned line = cast(unsigned)entity->token.pos.line;
  200. LLVMMetadataRef scope = nullptr;
  201. LLVMMetadataRef file = nullptr;
  202. LLVMMetadataRef type = nullptr;
  203. scope = p->module->debug_compile_unit;
  204. type = lb_debug_type_internal_proc(m, bt);
  205. Ast *ident = entity->identifier.load();
  206. if (entity->file != nullptr) {
  207. file = lb_get_llvm_metadata(m, entity->file);
  208. scope = file;
  209. } else if (ident != nullptr && ident->file_id != 0) {
  210. file = lb_get_llvm_metadata(m, ident->file());
  211. scope = file;
  212. } else if (entity->scope != nullptr) {
  213. file = lb_get_llvm_metadata(m, entity->scope->file);
  214. scope = file;
  215. }
  216. GB_ASSERT_MSG(file != nullptr, "%.*s", LIT(entity->token.string));
  217. // LLVMBool is_local_to_unit = !entity->Procedure.is_export;
  218. LLVMBool is_local_to_unit = false;
  219. LLVMBool is_definition = p->body != nullptr;
  220. unsigned scope_line = line;
  221. u32 flags = LLVMDIFlagStaticMember;
  222. LLVMBool is_optimized = false;
  223. if (bt->Proc.diverging) {
  224. flags |= LLVMDIFlagNoReturn;
  225. }
  226. if (p->body == nullptr) {
  227. flags |= LLVMDIFlagPrototyped;
  228. is_optimized = false;
  229. }
  230. if (p->body != nullptr) {
  231. // String debug_name = entity->token.string.text;
  232. String debug_name = p->name;
  233. p->debug_info = LLVMDIBuilderCreateFunction(m->debug_builder, scope,
  234. cast(char const *)debug_name.text, debug_name.len,
  235. cast(char const *)p->name.text, p->name.len,
  236. file, line, type,
  237. is_local_to_unit, is_definition,
  238. scope_line, cast(LLVMDIFlags)flags, is_optimized
  239. );
  240. GB_ASSERT(p->debug_info != nullptr);
  241. LLVMSetSubprogram(p->value, p->debug_info);
  242. lb_set_llvm_metadata(m, p, p->debug_info);
  243. }
  244. }
  245. return p;
  246. }
  247. lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) {
  248. {
  249. lbValue *found = string_map_get(&m->members, link_name);
  250. GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name));
  251. }
  252. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  253. p->module = m;
  254. p->name = link_name;
  255. p->type = type;
  256. p->type_expr = nullptr;
  257. p->body = nullptr;
  258. p->tags = 0;
  259. p->inlining = ProcInlining_none;
  260. p->is_foreign = false;
  261. p->is_export = false;
  262. p->is_entry_point = false;
  263. gbAllocator a = permanent_allocator();
  264. p->children.allocator = a;
  265. p->defer_stmts.allocator = a;
  266. p->blocks.allocator = a;
  267. p->branch_blocks.allocator = a;
  268. p->context_stack.allocator = a;
  269. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  270. LLVMTypeRef func_ptr_type = lb_type(m, p->type);
  271. LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
  272. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  273. Type *pt = p->type;
  274. lbCallingConventionKind cc_kind = lbCallingConvention_C;
  275. // TODO(bill): Clean up this logic
  276. if (!is_arch_wasm()) {
  277. cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
  278. }
  279. LLVMSetFunctionCallConv(p->value, cc_kind);
  280. lbValue proc_value = {p->value, p->type};
  281. lb_add_member(m, p->name, proc_value);
  282. lb_add_procedure_value(m, p);
  283. // NOTE(bill): offset==0 is the return value
  284. isize offset = 1;
  285. if (pt->Proc.return_by_pointer) {
  286. lb_add_proc_attribute_at_index(p, 1, "sret");
  287. lb_add_proc_attribute_at_index(p, 1, "noalias");
  288. offset = 2;
  289. }
  290. isize parameter_index = 0;
  291. if (pt->Proc.calling_convention == ProcCC_Odin) {
  292. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  293. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nonnull");
  294. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nocapture");
  295. }
  296. return p;
  297. }
  298. lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
  299. lbParamPasskind kind = lbParamPass_Value;
  300. if (e != nullptr && !are_types_identical(abi_type, e->type)) {
  301. if (is_type_pointer(abi_type)) {
  302. GB_ASSERT(e->kind == Entity_Variable);
  303. Type *av = core_type(type_deref(abi_type));
  304. if (are_types_identical(av, core_type(e->type))) {
  305. kind = lbParamPass_Pointer;
  306. if (e->flags&EntityFlag_Value) {
  307. kind = lbParamPass_ConstRef;
  308. }
  309. } else {
  310. kind = lbParamPass_BitCast;
  311. }
  312. } else if (is_type_integer(abi_type)) {
  313. kind = lbParamPass_Integer;
  314. } else if (abi_type == t_llvm_bool) {
  315. kind = lbParamPass_Value;
  316. } else if (is_type_boolean(abi_type)) {
  317. kind = lbParamPass_Integer;
  318. } else if (is_type_simd_vector(abi_type)) {
  319. kind = lbParamPass_BitCast;
  320. } else if (is_type_float(abi_type)) {
  321. kind = lbParamPass_BitCast;
  322. } else if (is_type_tuple(abi_type)) {
  323. kind = lbParamPass_Tuple;
  324. } else if (is_type_proc(abi_type)) {
  325. kind = lbParamPass_Value;
  326. } else {
  327. GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
  328. }
  329. }
  330. if (kind_) *kind_ = kind;
  331. lbValue res = {};
  332. res.value = LLVMGetParam(p->value, cast(unsigned)index);
  333. res.type = abi_type;
  334. return res;
  335. }
  336. void lb_start_block(lbProcedure *p, lbBlock *b) {
  337. GB_ASSERT(b != nullptr);
  338. if (!b->appended) {
  339. b->appended = true;
  340. LLVMAppendExistingBasicBlock(p->value, b->block);
  341. }
  342. LLVMPositionBuilderAtEnd(p->builder, b->block);
  343. p->curr_block = b;
  344. }
  345. void lb_begin_procedure_body(lbProcedure *p) {
  346. DeclInfo *decl = decl_info_of_entity(p->entity);
  347. if (decl != nullptr) {
  348. for_array(i, decl->labels) {
  349. BlockLabel bl = decl->labels[i];
  350. lbBranchBlocks bb = {bl.label, nullptr, nullptr};
  351. array_add(&p->branch_blocks, bb);
  352. }
  353. }
  354. p->builder = LLVMCreateBuilderInContext(p->module->ctx);
  355. p->decl_block = lb_create_block(p, "decls", true);
  356. p->entry_block = lb_create_block(p, "entry", true);
  357. lb_start_block(p, p->entry_block);
  358. GB_ASSERT(p->type != nullptr);
  359. lb_ensure_abi_function_type(p->module, p);
  360. {
  361. lbFunctionType *ft = p->abi_function_type;
  362. unsigned param_offset = 0;
  363. lbValue return_ptr_value = {};
  364. if (ft->ret.kind == lbArg_Indirect) {
  365. // NOTE(bill): this must be parameter 0
  366. String name = str_lit("agg.result");
  367. Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results));
  368. Entity *e = alloc_entity_param(nullptr, make_token_ident(name), ptr_type, false, false);
  369. e->flags |= EntityFlag_Sret | EntityFlag_NoAlias;
  370. return_ptr_value.value = LLVMGetParam(p->value, 0);
  371. LLVMSetValueName2(return_ptr_value.value, cast(char const *)name.text, name.len);
  372. return_ptr_value.type = ptr_type;
  373. p->return_ptr = lb_addr(return_ptr_value);
  374. lb_add_entity(p->module, e, return_ptr_value);
  375. param_offset += 1;
  376. }
  377. if (p->type->Proc.params != nullptr) {
  378. TypeTuple *params = &p->type->Proc.params->Tuple;
  379. unsigned param_index = 0;
  380. for_array(i, params->variables) {
  381. Entity *e = params->variables[i];
  382. if (e->kind != Entity_Variable) {
  383. continue;
  384. }
  385. lbArgType *arg_type = &ft->args[param_index];
  386. defer (param_index += 1);
  387. if (arg_type->kind == lbArg_Ignore) {
  388. continue;
  389. } else if (arg_type->kind == lbArg_Direct) {
  390. if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
  391. LLVMTypeRef param_type = lb_type(p->module, e->type);
  392. LLVMValueRef original_value = LLVMGetParam(p->value, param_offset+param_index);
  393. LLVMValueRef value = OdinLLVMBuildTransmute(p, original_value, param_type);
  394. lbValue param = {};
  395. param.value = value;
  396. param.type = e->type;
  397. lbValue ptr = lb_address_from_load_or_generate_local(p, param);
  398. GB_ASSERT(LLVMIsAAllocaInst(ptr.value));
  399. lb_add_entity(p->module, e, ptr);
  400. lbBlock *block = p->decl_block;
  401. if (original_value != value) {
  402. block = p->curr_block;
  403. }
  404. LLVMValueRef debug_storage_value = value;
  405. if (original_value != value && LLVMIsALoadInst(value)) {
  406. debug_storage_value = LLVMGetOperand(value, 0);
  407. }
  408. lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block);
  409. }
  410. } else if (arg_type->kind == lbArg_Indirect) {
  411. if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
  412. lbValue ptr = {};
  413. ptr.value = LLVMGetParam(p->value, param_offset+param_index);
  414. ptr.type = alloc_type_pointer(e->type);
  415. lb_add_entity(p->module, e, ptr);
  416. lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block);
  417. }
  418. }
  419. }
  420. }
  421. if (p->type->Proc.has_named_results) {
  422. GB_ASSERT(p->type->Proc.result_count > 0);
  423. TypeTuple *results = &p->type->Proc.results->Tuple;
  424. for_array(i, results->variables) {
  425. Entity *e = results->variables[i];
  426. GB_ASSERT(e->kind == Entity_Variable);
  427. if (e->token.string != "") {
  428. GB_ASSERT(!is_blank_ident(e->token));
  429. lbAddr res = {};
  430. if (return_ptr_value.value) {
  431. lbValue ptr = return_ptr_value;
  432. if (results->variables.count != 1) {
  433. ptr = lb_emit_struct_ep(p, ptr, cast(i32)i);
  434. }
  435. res = lb_addr(ptr);
  436. lb_add_entity(p->module, e, ptr);
  437. } else {
  438. res = lb_add_local(p, e->type, e);
  439. }
  440. if (e->Variable.param_value.kind != ParameterValue_Invalid) {
  441. lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos);
  442. lb_addr_store(p, res, c);
  443. }
  444. }
  445. }
  446. }
  447. }
  448. if (p->type->Proc.calling_convention == ProcCC_Odin) {
  449. lb_push_context_onto_stack_from_implicit_parameter(p);
  450. }
  451. lb_start_block(p, p->entry_block);
  452. if (p->debug_info != nullptr) {
  453. TokenPos pos = {};
  454. if (p->body != nullptr) {
  455. pos = ast_token(p->body).pos;
  456. } else if (p->type_expr != nullptr) {
  457. pos = ast_token(p->type_expr).pos;
  458. } else if (p->entity != nullptr) {
  459. pos = p->entity->token.pos;
  460. }
  461. if (pos.file_id != 0) {
  462. LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_token_pos(p, pos));
  463. }
  464. if (p->context_stack.count != 0) {
  465. lb_add_debug_context_variable(p, lb_find_or_generate_context_ptr(p));
  466. }
  467. }
  468. }
  469. void lb_end_procedure_body(lbProcedure *p) {
  470. LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
  471. LLVMBuildBr(p->builder, p->entry_block->block);
  472. LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
  473. LLVMValueRef instr = nullptr;
  474. // Make sure there is a "ret void" at the end of a procedure with no return type
  475. if (p->type->Proc.result_count == 0) {
  476. instr = LLVMGetLastInstruction(p->curr_block->block);
  477. if (!lb_is_instr_terminating(instr)) {
  478. lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
  479. LLVMBuildRetVoid(p->builder);
  480. }
  481. }
  482. LLVMBasicBlockRef first_block = LLVMGetFirstBasicBlock(p->value);
  483. LLVMBasicBlockRef block = nullptr;
  484. // Make sure every block terminates, and if not, make it unreachable
  485. for (block = first_block; block != nullptr; block = LLVMGetNextBasicBlock(block)) {
  486. instr = LLVMGetLastInstruction(block);
  487. if (instr == nullptr || !lb_is_instr_terminating(instr)) {
  488. LLVMPositionBuilderAtEnd(p->builder, block);
  489. LLVMBuildUnreachable(p->builder);
  490. }
  491. }
  492. p->curr_block = nullptr;
  493. p->state_flags = 0;
  494. }
  495. void lb_end_procedure(lbProcedure *p) {
  496. LLVMDisposeBuilder(p->builder);
  497. }
  498. void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) {
  499. GB_ASSERT(pd->body != nullptr);
  500. lbModule *m = p->module;
  501. auto *min_dep_set = &m->info->minimum_dependency_set;
  502. if (ptr_set_exists(min_dep_set, e) == false) {
  503. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  504. return;
  505. }
  506. // NOTE(bill): Generate a new name
  507. // parent.name-guid
  508. String original_name = e->token.string;
  509. String pd_name = original_name;
  510. if (e->Procedure.link_name.len > 0) {
  511. pd_name = e->Procedure.link_name;
  512. }
  513. isize name_len = p->name.len + 1 + pd_name.len + 1 + 10 + 1;
  514. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  515. i32 guid = cast(i32)p->children.count;
  516. name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%d", LIT(p->name), LIT(pd_name), guid);
  517. String name = make_string(cast(u8 *)name_text, name_len-1);
  518. e->Procedure.link_name = name;
  519. lbProcedure *nested_proc = lb_create_procedure(p->module, e);
  520. e->code_gen_procedure = nested_proc;
  521. lbValue value = {};
  522. value.value = nested_proc->value;
  523. value.type = nested_proc->type;
  524. lb_add_entity(m, e, value);
  525. array_add(&p->children, nested_proc);
  526. array_add(&m->procedures_to_generate, nested_proc);
  527. }
  528. Array<lbValue> lb_value_to_array(lbProcedure *p, lbValue value) {
  529. Array<lbValue> array = {};
  530. Type *t = base_type(value.type);
  531. if (t == nullptr) {
  532. // Do nothing
  533. } else if (is_type_tuple(t)) {
  534. GB_ASSERT(t->kind == Type_Tuple);
  535. auto *rt = &t->Tuple;
  536. if (rt->variables.count > 0) {
  537. array = array_make<lbValue>(permanent_allocator(), rt->variables.count);
  538. for_array(i, rt->variables) {
  539. lbValue elem = lb_emit_struct_ev(p, value, cast(i32)i);
  540. array[i] = elem;
  541. }
  542. }
  543. } else {
  544. array = array_make<lbValue>(permanent_allocator(), 1);
  545. array[0] = value;
  546. }
  547. return array;
  548. }
  549. lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, Array<lbValue> const &processed_args, Type *abi_rt, lbAddr context_ptr, ProcInlining inlining) {
  550. GB_ASSERT(p->module->ctx == LLVMGetTypeContext(LLVMTypeOf(value.value)));
  551. unsigned arg_count = cast(unsigned)processed_args.count;
  552. if (return_ptr.value != nullptr) {
  553. arg_count += 1;
  554. }
  555. if (context_ptr.addr.value != nullptr) {
  556. arg_count += 1;
  557. }
  558. LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count);
  559. isize arg_index = 0;
  560. if (return_ptr.value != nullptr) {
  561. args[arg_index++] = return_ptr.value;
  562. }
  563. for_array(i, processed_args) {
  564. lbValue arg = processed_args[i];
  565. args[arg_index++] = arg.value;
  566. }
  567. if (context_ptr.addr.value != nullptr) {
  568. LLVMValueRef cp = context_ptr.addr.value;
  569. cp = LLVMBuildPointerCast(p->builder, cp, lb_type(p->module, t_rawptr), "");
  570. args[arg_index++] = cp;
  571. }
  572. LLVMBasicBlockRef curr_block = LLVMGetInsertBlock(p->builder);
  573. GB_ASSERT(curr_block != p->decl_block->block);
  574. {
  575. LLVMTypeRef ftp = lb_type(p->module, value.type);
  576. LLVMValueRef fn = value.value;
  577. if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
  578. fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
  579. }
  580. LLVMTypeRef fnp = LLVMGetElementType(LLVMTypeOf(fn));
  581. GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
  582. {
  583. unsigned param_count = LLVMCountParamTypes(fnp);
  584. GB_ASSERT(arg_count >= param_count);
  585. LLVMTypeRef *param_types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, param_count);
  586. LLVMGetParamTypes(fnp, param_types);
  587. for (unsigned i = 0; i < param_count; i++) {
  588. LLVMTypeRef param_type = param_types[i];
  589. LLVMTypeRef arg_type = LLVMTypeOf(args[i]);
  590. // LLVMTypeKind param_kind = LLVMGetTypeKind(param_type);
  591. // LLVMTypeKind arg_kind = LLVMGetTypeKind(arg_type);
  592. GB_ASSERT_MSG(
  593. arg_type == param_type,
  594. "Parameter types do not match: %s != %s, argument: %s",
  595. LLVMPrintTypeToString(arg_type),
  596. LLVMPrintTypeToString(param_type),
  597. LLVMPrintValueToString(args[i])
  598. );
  599. }
  600. }
  601. LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
  602. if (return_ptr.value != nullptr) {
  603. LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0])));
  604. }
  605. switch (inlining) {
  606. case ProcInlining_none:
  607. break;
  608. case ProcInlining_inline:
  609. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "alwaysinline"));
  610. break;
  611. case ProcInlining_no_inline:
  612. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "noinline"));
  613. break;
  614. }
  615. lbValue res = {};
  616. res.value = ret;
  617. res.type = abi_rt;
  618. return res;
  619. }
  620. }
  621. lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name) {
  622. AstPackage *pkg = m->info->runtime_package;
  623. Entity *e = scope_lookup_current(pkg->scope, name);
  624. return lb_find_procedure_value_from_entity(m, e);
  625. }
  626. lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
  627. String name = make_string_c(c_name);
  628. lbValue proc = lb_lookup_runtime_procedure(p->module, name);
  629. return lb_emit_call(p, proc, args);
  630. }
  631. lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
  632. lbValue res = {};
  633. Type *t = val.type;
  634. if (is_type_complex(t)) {
  635. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
  636. lbValue real = lb_emit_struct_ev(p, val, 0);
  637. lbValue imag = lb_emit_struct_ev(p, val, 1);
  638. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  639. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), real);
  640. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), imag);
  641. } else if (is_type_quaternion(t)) {
  642. // @QuaternionLayout
  643. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
  644. lbValue real = lb_emit_struct_ev(p, val, 3);
  645. lbValue imag = lb_emit_struct_ev(p, val, 0);
  646. lbValue jmag = lb_emit_struct_ev(p, val, 1);
  647. lbValue kmag = lb_emit_struct_ev(p, val, 2);
  648. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  649. jmag = lb_emit_unary_arith(p, Token_Sub, jmag, jmag.type);
  650. kmag = lb_emit_unary_arith(p, Token_Sub, kmag, kmag.type);
  651. lb_emit_store(p, lb_emit_struct_ep(p, res, 3), real);
  652. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), imag);
  653. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), jmag);
  654. lb_emit_store(p, lb_emit_struct_ep(p, res, 2), kmag);
  655. } else if (is_type_array_like(t)) {
  656. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true));
  657. Type *elem_type = base_array_type(t);
  658. i64 count = get_array_type_count(t);
  659. for (i64 i = 0; i < count; i++) {
  660. lbValue dst = lb_emit_array_epi(p, res, i);
  661. lbValue elem = lb_emit_struct_ev(p, val, cast(i32)i);
  662. elem = lb_emit_conjugate(p, elem, elem_type);
  663. lb_emit_store(p, dst, elem);
  664. }
  665. } else if (is_type_matrix(t)) {
  666. Type *mt = base_type(t);
  667. GB_ASSERT(mt->kind == Type_Matrix);
  668. Type *elem_type = mt->Matrix.elem;
  669. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true));
  670. for (i64 j = 0; j < mt->Matrix.column_count; j++) {
  671. for (i64 i = 0; i < mt->Matrix.row_count; i++) {
  672. lbValue dst = lb_emit_matrix_epi(p, res, i, j);
  673. lbValue elem = lb_emit_matrix_ev(p, val, i, j);
  674. elem = lb_emit_conjugate(p, elem, elem_type);
  675. lb_emit_store(p, dst, elem);
  676. }
  677. }
  678. }
  679. return lb_emit_load(p, res);
  680. }
  681. lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining, bool use_copy_elision_hint) {
  682. lbModule *m = p->module;
  683. Type *pt = base_type(value.type);
  684. GB_ASSERT(pt->kind == Type_Proc);
  685. Type *results = pt->Proc.results;
  686. if (p->entity != nullptr) {
  687. if (p->entity->flags & EntityFlag_Disabled) {
  688. return {};
  689. }
  690. }
  691. lbAddr context_ptr = {};
  692. if (pt->Proc.calling_convention == ProcCC_Odin) {
  693. context_ptr = lb_find_or_generate_context_ptr(p);
  694. }
  695. defer (if (pt->Proc.diverging) {
  696. LLVMBuildUnreachable(p->builder);
  697. });
  698. bool is_c_vararg = pt->Proc.c_vararg;
  699. isize param_count = pt->Proc.param_count;
  700. if (is_c_vararg) {
  701. GB_ASSERT(param_count-1 <= args.count);
  702. param_count -= 1;
  703. } else {
  704. GB_ASSERT_MSG(param_count == args.count, "%td == %td", param_count, args.count);
  705. }
  706. lbValue result = {};
  707. auto processed_args = array_make<lbValue>(permanent_allocator(), 0, args.count);
  708. {
  709. lbFunctionType *ft = lb_get_function_type(m, p, pt);
  710. bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
  711. unsigned param_index = 0;
  712. for (isize i = 0; i < param_count; i++) {
  713. Entity *e = pt->Proc.params->Tuple.variables[i];
  714. if (e->kind != Entity_Variable) {
  715. continue;
  716. }
  717. GB_ASSERT(e->flags & EntityFlag_Param);
  718. Type *original_type = e->type;
  719. lbArgType *arg = &ft->args[param_index];
  720. if (arg->kind == lbArg_Ignore) {
  721. continue;
  722. }
  723. lbValue x = lb_emit_conv(p, args[i], original_type);
  724. LLVMTypeRef xt = lb_type(p->module, x.type);
  725. if (arg->kind == lbArg_Direct) {
  726. LLVMTypeRef abi_type = arg->cast_type;
  727. if (!abi_type) {
  728. abi_type = arg->type;
  729. }
  730. if (xt == abi_type) {
  731. array_add(&processed_args, x);
  732. } else {
  733. x.value = OdinLLVMBuildTransmute(p, x.value, abi_type);
  734. array_add(&processed_args, x);
  735. }
  736. } else if (arg->kind == lbArg_Indirect) {
  737. lbValue ptr = {};
  738. if (arg->is_byval) {
  739. ptr = lb_copy_value_to_ptr(p, x, original_type, arg->byval_alignment);
  740. } else if (is_calling_convention_odin(pt->Proc.calling_convention)) {
  741. // NOTE(bill): Odin parameters are immutable so the original value can be passed if possible
  742. // i.e. `T const &` in C++
  743. ptr = lb_address_from_load_or_generate_local(p, x);
  744. } else {
  745. ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
  746. }
  747. array_add(&processed_args, ptr);
  748. }
  749. param_index += 1;
  750. }
  751. if (is_c_vararg) {
  752. for (isize i = processed_args.count; i < args.count; i++) {
  753. array_add(&processed_args, args[i]);
  754. }
  755. }
  756. if (inlining == ProcInlining_none) {
  757. inlining = p->inlining;
  758. }
  759. Type *rt = reduce_tuple_to_single_type(results);
  760. if (return_by_pointer) {
  761. lbValue return_ptr = {};
  762. if (use_copy_elision_hint && p->copy_elision_hint.ptr.value != nullptr) {
  763. if (are_types_identical(type_deref(p->copy_elision_hint.ptr.type), rt)) {
  764. return_ptr = lb_consume_copy_elision_hint(p);
  765. }
  766. }
  767. if (return_ptr.value == nullptr) {
  768. lbAddr r = lb_add_local_generated(p, rt, true);
  769. return_ptr = r.addr;
  770. }
  771. GB_ASSERT(is_type_pointer(return_ptr.type));
  772. lb_emit_call_internal(p, value, return_ptr, processed_args, nullptr, context_ptr, inlining);
  773. result = lb_emit_load(p, return_ptr);
  774. } else if (rt != nullptr) {
  775. result = lb_emit_call_internal(p, value, {}, processed_args, rt, context_ptr, inlining);
  776. if (ft->ret.cast_type) {
  777. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.cast_type);
  778. }
  779. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.type);
  780. result.type = rt;
  781. if (LLVMTypeOf(result.value) == LLVMInt1TypeInContext(p->module->ctx)) {
  782. result.type = t_llvm_bool;
  783. }
  784. if (!is_type_tuple(rt)) {
  785. result = lb_emit_conv(p, result, rt);
  786. }
  787. } else {
  788. lb_emit_call_internal(p, value, {}, processed_args, nullptr, context_ptr, inlining);
  789. }
  790. }
  791. Entity **found = map_get(&p->module->procedure_values, value.value);
  792. if (found != nullptr) {
  793. Entity *e = *found;
  794. if (e != nullptr && entity_has_deferred_procedure(e)) {
  795. DeferredProcedureKind kind = e->Procedure.deferred_procedure.kind;
  796. Entity *deferred_entity = e->Procedure.deferred_procedure.entity;
  797. lbValue deferred = lb_find_procedure_value_from_entity(p->module, deferred_entity);
  798. auto in_args = args;
  799. Array<lbValue> result_as_args = {};
  800. switch (kind) {
  801. case DeferredProcedure_none:
  802. break;
  803. case DeferredProcedure_in:
  804. result_as_args = in_args;
  805. break;
  806. case DeferredProcedure_out:
  807. result_as_args = lb_value_to_array(p, result);
  808. break;
  809. case DeferredProcedure_in_out:
  810. {
  811. auto out_args = lb_value_to_array(p, result);
  812. array_init(&result_as_args, permanent_allocator(), in_args.count + out_args.count);
  813. array_copy(&result_as_args, in_args, 0);
  814. array_copy(&result_as_args, out_args, in_args.count);
  815. }
  816. break;
  817. }
  818. lb_add_defer_proc(p, p->scope_index, deferred, result_as_args);
  819. }
  820. }
  821. return result;
  822. }
  823. lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId id) {
  824. ast_node(ce, CallExpr, expr);
  825. switch (id) {
  826. case BuiltinProc_DIRECTIVE: {
  827. ast_node(bd, BasicDirective, ce->proc);
  828. String name = bd->name.string;
  829. GB_ASSERT(name == "location");
  830. String procedure = p->entity->token.string;
  831. TokenPos pos = ast_token(ce->proc).pos;
  832. if (ce->args.count > 0) {
  833. Ast *ident = unselector_expr(ce->args[0]);
  834. GB_ASSERT(ident->kind == Ast_Ident);
  835. Entity *e = entity_of_node(ident);
  836. GB_ASSERT(e != nullptr);
  837. if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity != nullptr) {
  838. procedure = e->parent_proc_decl->entity->token.string;
  839. } else {
  840. procedure = str_lit("");
  841. }
  842. pos = e->token.pos;
  843. }
  844. return lb_emit_source_code_location(p, procedure, pos);
  845. }
  846. case BuiltinProc_type_info_of: {
  847. Ast *arg = ce->args[0];
  848. TypeAndValue tav = type_and_value_of_expr(arg);
  849. if (tav.mode == Addressing_Type) {
  850. Type *t = default_type(type_of_expr(arg));
  851. return lb_type_info(p->module, t);
  852. }
  853. GB_ASSERT(is_type_typeid(tav.type));
  854. auto args = array_make<lbValue>(permanent_allocator(), 1);
  855. args[0] = lb_build_expr(p, arg);
  856. return lb_emit_runtime_call(p, "__type_info_of", args);
  857. }
  858. case BuiltinProc_typeid_of: {
  859. Ast *arg = ce->args[0];
  860. TypeAndValue tav = type_and_value_of_expr(arg);
  861. GB_ASSERT(tav.mode == Addressing_Type);
  862. Type *t = default_type(type_of_expr(arg));
  863. return lb_typeid(p->module, t);
  864. }
  865. case BuiltinProc_len: {
  866. lbValue v = lb_build_expr(p, ce->args[0]);
  867. Type *t = base_type(v.type);
  868. if (is_type_pointer(t)) {
  869. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  870. v = lb_emit_load(p, v);
  871. t = type_deref(t);
  872. }
  873. if (is_type_cstring(t)) {
  874. return lb_cstring_len(p, v);
  875. } else if (is_type_string(t)) {
  876. return lb_string_len(p, v);
  877. } else if (is_type_array(t)) {
  878. GB_PANIC("Array lengths are constant");
  879. } else if (is_type_slice(t) || is_type_relative_slice(t)) {
  880. return lb_slice_len(p, v);
  881. } else if (is_type_dynamic_array(t)) {
  882. return lb_dynamic_array_len(p, v);
  883. } else if (is_type_map(t)) {
  884. return lb_map_len(p, v);
  885. } else if (is_type_soa_struct(t)) {
  886. return lb_soa_struct_len(p, v);
  887. }
  888. GB_PANIC("Unreachable");
  889. break;
  890. }
  891. case BuiltinProc_cap: {
  892. lbValue v = lb_build_expr(p, ce->args[0]);
  893. Type *t = base_type(v.type);
  894. if (is_type_pointer(t)) {
  895. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  896. v = lb_emit_load(p, v);
  897. t = type_deref(t);
  898. }
  899. if (is_type_string(t)) {
  900. GB_PANIC("Unreachable");
  901. } else if (is_type_array(t)) {
  902. GB_PANIC("Array lengths are constant");
  903. } else if (is_type_slice(t) || is_type_relative_slice(t)) {
  904. return lb_slice_len(p, v);
  905. } else if (is_type_dynamic_array(t)) {
  906. return lb_dynamic_array_cap(p, v);
  907. } else if (is_type_map(t)) {
  908. return lb_map_cap(p, v);
  909. } else if (is_type_soa_struct(t)) {
  910. return lb_soa_struct_cap(p, v);
  911. }
  912. GB_PANIC("Unreachable");
  913. break;
  914. }
  915. case BuiltinProc_swizzle: {
  916. isize index_count = ce->args.count-1;
  917. if (is_type_simd_vector(tv.type)) {
  918. lbValue vec = lb_build_expr(p, ce->args[0]);
  919. if (index_count == 0) {
  920. return vec;
  921. }
  922. unsigned mask_len = cast(unsigned)index_count;
  923. LLVMValueRef *mask_elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, index_count);
  924. for (isize i = 1; i < ce->args.count; i++) {
  925. TypeAndValue tv = type_and_value_of_expr(ce->args[i]);
  926. GB_ASSERT(is_type_integer(tv.type));
  927. GB_ASSERT(tv.value.kind == ExactValue_Integer);
  928. u32 index = cast(u32)big_int_to_i64(&tv.value.value_integer);
  929. mask_elems[i-1] = LLVMConstInt(lb_type(p->module, t_u32), index, false);
  930. }
  931. LLVMValueRef mask = LLVMConstVector(mask_elems, mask_len);
  932. LLVMValueRef v1 = vec.value;
  933. LLVMValueRef v2 = vec.value;
  934. lbValue res = {};
  935. res.type = tv.type;
  936. res.value = LLVMBuildShuffleVector(p->builder, v1, v2, mask, "");
  937. return res;
  938. }
  939. lbAddr addr = lb_build_array_swizzle_addr(p, ce, tv);
  940. return lb_addr_load(p, addr);
  941. }
  942. case BuiltinProc_complex: {
  943. lbValue real = lb_build_expr(p, ce->args[0]);
  944. lbValue imag = lb_build_expr(p, ce->args[1]);
  945. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  946. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  947. Type *ft = base_complex_elem_type(tv.type);
  948. real = lb_emit_conv(p, real, ft);
  949. imag = lb_emit_conv(p, imag, ft);
  950. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), real);
  951. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), imag);
  952. return lb_emit_load(p, dst);
  953. }
  954. case BuiltinProc_quaternion: {
  955. lbValue real = lb_build_expr(p, ce->args[0]);
  956. lbValue imag = lb_build_expr(p, ce->args[1]);
  957. lbValue jmag = lb_build_expr(p, ce->args[2]);
  958. lbValue kmag = lb_build_expr(p, ce->args[3]);
  959. // @QuaternionLayout
  960. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  961. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  962. Type *ft = base_complex_elem_type(tv.type);
  963. real = lb_emit_conv(p, real, ft);
  964. imag = lb_emit_conv(p, imag, ft);
  965. jmag = lb_emit_conv(p, jmag, ft);
  966. kmag = lb_emit_conv(p, kmag, ft);
  967. lb_emit_store(p, lb_emit_struct_ep(p, dst, 3), real);
  968. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), imag);
  969. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), jmag);
  970. lb_emit_store(p, lb_emit_struct_ep(p, dst, 2), kmag);
  971. return lb_emit_load(p, dst);
  972. }
  973. case BuiltinProc_real: {
  974. lbValue val = lb_build_expr(p, ce->args[0]);
  975. if (is_type_complex(val.type)) {
  976. lbValue real = lb_emit_struct_ev(p, val, 0);
  977. return lb_emit_conv(p, real, tv.type);
  978. } else if (is_type_quaternion(val.type)) {
  979. // @QuaternionLayout
  980. lbValue real = lb_emit_struct_ev(p, val, 3);
  981. return lb_emit_conv(p, real, tv.type);
  982. }
  983. GB_PANIC("invalid type for real");
  984. return {};
  985. }
  986. case BuiltinProc_imag: {
  987. lbValue val = lb_build_expr(p, ce->args[0]);
  988. if (is_type_complex(val.type)) {
  989. lbValue imag = lb_emit_struct_ev(p, val, 1);
  990. return lb_emit_conv(p, imag, tv.type);
  991. } else if (is_type_quaternion(val.type)) {
  992. // @QuaternionLayout
  993. lbValue imag = lb_emit_struct_ev(p, val, 0);
  994. return lb_emit_conv(p, imag, tv.type);
  995. }
  996. GB_PANIC("invalid type for imag");
  997. return {};
  998. }
  999. case BuiltinProc_jmag: {
  1000. lbValue val = lb_build_expr(p, ce->args[0]);
  1001. if (is_type_quaternion(val.type)) {
  1002. // @QuaternionLayout
  1003. lbValue imag = lb_emit_struct_ev(p, val, 1);
  1004. return lb_emit_conv(p, imag, tv.type);
  1005. }
  1006. GB_PANIC("invalid type for jmag");
  1007. return {};
  1008. }
  1009. case BuiltinProc_kmag: {
  1010. lbValue val = lb_build_expr(p, ce->args[0]);
  1011. if (is_type_quaternion(val.type)) {
  1012. // @QuaternionLayout
  1013. lbValue imag = lb_emit_struct_ev(p, val, 2);
  1014. return lb_emit_conv(p, imag, tv.type);
  1015. }
  1016. GB_PANIC("invalid type for kmag");
  1017. return {};
  1018. }
  1019. case BuiltinProc_conj: {
  1020. lbValue val = lb_build_expr(p, ce->args[0]);
  1021. return lb_emit_conjugate(p, val, tv.type);
  1022. }
  1023. case BuiltinProc_expand_to_tuple: {
  1024. lbValue val = lb_build_expr(p, ce->args[0]);
  1025. Type *t = base_type(val.type);
  1026. if (!is_type_tuple(tv.type)) {
  1027. if (t->kind == Type_Struct) {
  1028. GB_ASSERT(t->Struct.fields.count == 1);
  1029. return lb_emit_struct_ev(p, val, 0);
  1030. } else if (t->kind == Type_Array) {
  1031. GB_ASSERT(t->Array.count == 1);
  1032. return lb_emit_array_epi(p, val, 0);
  1033. } else {
  1034. GB_PANIC("Unknown type of expand_to_tuple");
  1035. }
  1036. }
  1037. GB_ASSERT(is_type_tuple(tv.type));
  1038. // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
  1039. lbValue tuple = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false));
  1040. if (t->kind == Type_Struct) {
  1041. for_array(src_index, t->Struct.fields) {
  1042. Entity *field = t->Struct.fields[src_index];
  1043. i32 field_index = field->Variable.field_index;
  1044. lbValue f = lb_emit_struct_ev(p, val, field_index);
  1045. lbValue ep = lb_emit_struct_ep(p, tuple, cast(i32)src_index);
  1046. lb_emit_store(p, ep, f);
  1047. }
  1048. } else if (is_type_array_like(t)) {
  1049. // TODO(bill): Clean-up this code
  1050. lbValue ap = lb_address_from_load_or_generate_local(p, val);
  1051. i32 n = cast(i32)get_array_type_count(t);
  1052. for (i32 i = 0; i < n; i++) {
  1053. lbValue f = lb_emit_load(p, lb_emit_array_epi(p, ap, i));
  1054. lbValue ep = lb_emit_struct_ep(p, tuple, i);
  1055. lb_emit_store(p, ep, f);
  1056. }
  1057. } else {
  1058. GB_PANIC("Unknown type of expand_to_tuple");
  1059. }
  1060. return lb_emit_load(p, tuple);
  1061. }
  1062. case BuiltinProc_min: {
  1063. Type *t = type_of_expr(expr);
  1064. if (ce->args.count == 2) {
  1065. return lb_emit_min(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  1066. } else {
  1067. lbValue x = lb_build_expr(p, ce->args[0]);
  1068. for (isize i = 1; i < ce->args.count; i++) {
  1069. x = lb_emit_min(p, t, x, lb_build_expr(p, ce->args[i]));
  1070. }
  1071. return x;
  1072. }
  1073. }
  1074. case BuiltinProc_max: {
  1075. Type *t = type_of_expr(expr);
  1076. if (ce->args.count == 2) {
  1077. return lb_emit_max(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  1078. } else {
  1079. lbValue x = lb_build_expr(p, ce->args[0]);
  1080. for (isize i = 1; i < ce->args.count; i++) {
  1081. x = lb_emit_max(p, t, x, lb_build_expr(p, ce->args[i]));
  1082. }
  1083. return x;
  1084. }
  1085. }
  1086. case BuiltinProc_abs: {
  1087. lbValue x = lb_build_expr(p, ce->args[0]);
  1088. Type *t = x.type;
  1089. if (is_type_unsigned(t)) {
  1090. return x;
  1091. }
  1092. if (is_type_quaternion(t)) {
  1093. i64 sz = 8*type_size_of(t);
  1094. auto args = array_make<lbValue>(permanent_allocator(), 1);
  1095. args[0] = x;
  1096. switch (sz) {
  1097. case 64: return lb_emit_runtime_call(p, "abs_quaternion64", args);
  1098. case 128: return lb_emit_runtime_call(p, "abs_quaternion128", args);
  1099. case 256: return lb_emit_runtime_call(p, "abs_quaternion256", args);
  1100. }
  1101. GB_PANIC("Unknown complex type");
  1102. } else if (is_type_complex(t)) {
  1103. i64 sz = 8*type_size_of(t);
  1104. auto args = array_make<lbValue>(permanent_allocator(), 1);
  1105. args[0] = x;
  1106. switch (sz) {
  1107. case 32: return lb_emit_runtime_call(p, "abs_complex32", args);
  1108. case 64: return lb_emit_runtime_call(p, "abs_complex64", args);
  1109. case 128: return lb_emit_runtime_call(p, "abs_complex128", args);
  1110. }
  1111. GB_PANIC("Unknown complex type");
  1112. }
  1113. lbValue zero = lb_const_nil(p->module, t);
  1114. lbValue cond = lb_emit_comp(p, Token_Lt, x, zero);
  1115. lbValue neg = lb_emit_unary_arith(p, Token_Sub, x, t);
  1116. return lb_emit_select(p, cond, neg, x);
  1117. }
  1118. case BuiltinProc_clamp:
  1119. return lb_emit_clamp(p, type_of_expr(expr),
  1120. lb_build_expr(p, ce->args[0]),
  1121. lb_build_expr(p, ce->args[1]),
  1122. lb_build_expr(p, ce->args[2]));
  1123. case BuiltinProc_soa_zip:
  1124. return lb_soa_zip(p, ce, tv);
  1125. case BuiltinProc_soa_unzip:
  1126. return lb_soa_unzip(p, ce, tv);
  1127. case BuiltinProc_transpose:
  1128. {
  1129. lbValue m = lb_build_expr(p, ce->args[0]);
  1130. return lb_emit_matrix_tranpose(p, m, tv.type);
  1131. }
  1132. case BuiltinProc_outer_product:
  1133. {
  1134. lbValue a = lb_build_expr(p, ce->args[0]);
  1135. lbValue b = lb_build_expr(p, ce->args[1]);
  1136. return lb_emit_outer_product(p, a, b, tv.type);
  1137. }
  1138. case BuiltinProc_hadamard_product:
  1139. {
  1140. lbValue a = lb_build_expr(p, ce->args[0]);
  1141. lbValue b = lb_build_expr(p, ce->args[1]);
  1142. if (is_type_array(tv.type)) {
  1143. return lb_emit_arith(p, Token_Mul, a, b, tv.type);
  1144. }
  1145. GB_ASSERT(is_type_matrix(tv.type));
  1146. return lb_emit_arith_matrix(p, Token_Mul, a, b, tv.type, true);
  1147. }
  1148. case BuiltinProc_matrix_flatten:
  1149. {
  1150. lbValue m = lb_build_expr(p, ce->args[0]);
  1151. return lb_emit_matrix_flatten(p, m, tv.type);
  1152. }
  1153. // "Intrinsics"
  1154. case BuiltinProc_alloca:
  1155. {
  1156. lbValue sz = lb_build_expr(p, ce->args[0]);
  1157. i64 al = exact_value_to_i64(type_and_value_of_expr(ce->args[1]).value);
  1158. lbValue res = {};
  1159. res.type = t_u8_ptr;
  1160. res.value = LLVMBuildArrayAlloca(p->builder, lb_type(p->module, t_u8), sz.value, "");
  1161. LLVMSetAlignment(res.value, cast(unsigned)al);
  1162. return res;
  1163. }
  1164. case BuiltinProc_cpu_relax:
  1165. if (build_context.metrics.arch == TargetArch_i386 ||
  1166. build_context.metrics.arch == TargetArch_amd64) {
  1167. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  1168. LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("pause"), {});
  1169. GB_ASSERT(the_asm != nullptr);
  1170. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1171. } else if (build_context.metrics.arch == TargetArch_arm64) {
  1172. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  1173. LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("yield"), {});
  1174. GB_ASSERT(the_asm != nullptr);
  1175. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1176. }
  1177. return {};
  1178. case BuiltinProc_debug_trap:
  1179. case BuiltinProc_trap:
  1180. {
  1181. char const *name = nullptr;
  1182. switch (id) {
  1183. case BuiltinProc_debug_trap: name = "llvm.debugtrap"; break;
  1184. case BuiltinProc_trap: name = "llvm.trap"; break;
  1185. }
  1186. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1187. GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
  1188. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
  1189. LLVMBuildCall(p->builder, ip, nullptr, 0, "");
  1190. if (id == BuiltinProc_trap) {
  1191. LLVMBuildUnreachable(p->builder);
  1192. }
  1193. return {};
  1194. }
  1195. case BuiltinProc_read_cycle_counter:
  1196. {
  1197. char const *name = "llvm.readcyclecounter";
  1198. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1199. GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
  1200. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
  1201. lbValue res = {};
  1202. res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, "");
  1203. res.type = tv.type;
  1204. return res;
  1205. }
  1206. case BuiltinProc_count_trailing_zeros:
  1207. return lb_emit_count_trailing_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1208. case BuiltinProc_count_leading_zeros:
  1209. return lb_emit_count_leading_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1210. case BuiltinProc_count_ones:
  1211. return lb_emit_count_ones(p, lb_build_expr(p, ce->args[0]), tv.type);
  1212. case BuiltinProc_count_zeros:
  1213. return lb_emit_count_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1214. case BuiltinProc_reverse_bits:
  1215. return lb_emit_reverse_bits(p, lb_build_expr(p, ce->args[0]), tv.type);
  1216. case BuiltinProc_byte_swap:
  1217. {
  1218. lbValue x = lb_build_expr(p, ce->args[0]);
  1219. x = lb_emit_conv(p, x, tv.type);
  1220. return lb_emit_byte_swap(p, x, tv.type);
  1221. }
  1222. case BuiltinProc_overflow_add:
  1223. case BuiltinProc_overflow_sub:
  1224. case BuiltinProc_overflow_mul:
  1225. {
  1226. Type *main_type = tv.type;
  1227. Type *type = main_type;
  1228. if (is_type_tuple(main_type)) {
  1229. type = main_type->Tuple.variables[0]->type;
  1230. }
  1231. lbValue x = lb_build_expr(p, ce->args[0]);
  1232. lbValue y = lb_build_expr(p, ce->args[1]);
  1233. x = lb_emit_conv(p, x, type);
  1234. y = lb_emit_conv(p, y, type);
  1235. char const *name = nullptr;
  1236. if (is_type_unsigned(type)) {
  1237. switch (id) {
  1238. case BuiltinProc_overflow_add: name = "llvm.uadd.with.overflow"; break;
  1239. case BuiltinProc_overflow_sub: name = "llvm.usub.with.overflow"; break;
  1240. case BuiltinProc_overflow_mul: name = "llvm.umul.with.overflow"; break;
  1241. }
  1242. } else {
  1243. switch (id) {
  1244. case BuiltinProc_overflow_add: name = "llvm.sadd.with.overflow"; break;
  1245. case BuiltinProc_overflow_sub: name = "llvm.ssub.with.overflow"; break;
  1246. case BuiltinProc_overflow_mul: name = "llvm.smul.with.overflow"; break;
  1247. }
  1248. }
  1249. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  1250. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1251. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1252. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1253. LLVMValueRef args[2] = {};
  1254. args[0] = x.value;
  1255. args[1] = y.value;
  1256. lbValue res = {};
  1257. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1258. if (is_type_tuple(main_type)) {
  1259. Type *res_type = nullptr;
  1260. gbAllocator a = permanent_allocator();
  1261. res_type = alloc_type_tuple();
  1262. slice_init(&res_type->Tuple.variables, a, 2);
  1263. res_type->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, type, false, 0);
  1264. res_type->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  1265. res.type = res_type;
  1266. } else {
  1267. res.value = LLVMBuildExtractValue(p->builder, res.value, 0, "");
  1268. res.type = type;
  1269. }
  1270. return res;
  1271. }
  1272. case BuiltinProc_sqrt:
  1273. {
  1274. Type *type = tv.type;
  1275. lbValue x = lb_build_expr(p, ce->args[0]);
  1276. x = lb_emit_conv(p, x, type);
  1277. char const *name = "llvm.sqrt";
  1278. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  1279. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1280. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1281. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1282. LLVMValueRef args[1] = {};
  1283. args[0] = x.value;
  1284. lbValue res = {};
  1285. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1286. res.type = type;
  1287. return res;
  1288. }
  1289. case BuiltinProc_mem_copy:
  1290. {
  1291. lbValue dst = lb_build_expr(p, ce->args[0]);
  1292. lbValue src = lb_build_expr(p, ce->args[1]);
  1293. lbValue len = lb_build_expr(p, ce->args[2]);
  1294. lb_mem_copy_overlapping(p, dst, src, len, false);
  1295. return {};
  1296. }
  1297. case BuiltinProc_mem_copy_non_overlapping:
  1298. {
  1299. lbValue dst = lb_build_expr(p, ce->args[0]);
  1300. lbValue src = lb_build_expr(p, ce->args[1]);
  1301. lbValue len = lb_build_expr(p, ce->args[2]);
  1302. lb_mem_copy_non_overlapping(p, dst, src, len, false);
  1303. return {};
  1304. }
  1305. case BuiltinProc_mem_zero:
  1306. {
  1307. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1308. lbValue len = lb_build_expr(p, ce->args[1]);
  1309. ptr = lb_emit_conv(p, ptr, t_rawptr);
  1310. len = lb_emit_conv(p, len, t_int);
  1311. unsigned alignment = 1;
  1312. lb_mem_zero_ptr_internal(p, ptr.value, len.value, alignment, false);
  1313. return {};
  1314. }
  1315. case BuiltinProc_mem_zero_volatile:
  1316. {
  1317. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1318. lbValue len = lb_build_expr(p, ce->args[1]);
  1319. ptr = lb_emit_conv(p, ptr, t_rawptr);
  1320. len = lb_emit_conv(p, len, t_int);
  1321. unsigned alignment = 1;
  1322. lb_mem_zero_ptr_internal(p, ptr.value, len.value, alignment, true);
  1323. return {};
  1324. }
  1325. case BuiltinProc_ptr_offset:
  1326. {
  1327. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1328. lbValue len = lb_build_expr(p, ce->args[1]);
  1329. len = lb_emit_conv(p, len, t_int);
  1330. LLVMValueRef indices[1] = {
  1331. len.value,
  1332. };
  1333. lbValue res = {};
  1334. res.type = tv.type;
  1335. res.value = LLVMBuildGEP(p->builder, ptr.value, indices, gb_count_of(indices), "");
  1336. return res;
  1337. }
  1338. case BuiltinProc_ptr_sub:
  1339. {
  1340. lbValue ptr0 = lb_build_expr(p, ce->args[0]);
  1341. lbValue ptr1 = lb_build_expr(p, ce->args[1]);
  1342. LLVMTypeRef type_int = lb_type(p->module, t_int);
  1343. LLVMValueRef diff = LLVMBuildPtrDiff(p->builder, ptr0.value, ptr1.value, "");
  1344. diff = LLVMBuildIntCast2(p->builder, diff, type_int, /*signed*/true, "");
  1345. lbValue res = {};
  1346. res.type = t_int;
  1347. res.value = diff;
  1348. return res;
  1349. }
  1350. case BuiltinProc_atomic_fence:
  1351. LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, "");
  1352. return {};
  1353. case BuiltinProc_atomic_fence_acq:
  1354. LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquire, false, "");
  1355. return {};
  1356. case BuiltinProc_atomic_fence_rel:
  1357. LLVMBuildFence(p->builder, LLVMAtomicOrderingRelease, false, "");
  1358. return {};
  1359. case BuiltinProc_atomic_fence_acqrel:
  1360. LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquireRelease, false, "");
  1361. return {};
  1362. case BuiltinProc_volatile_store:
  1363. case BuiltinProc_atomic_store:
  1364. case BuiltinProc_atomic_store_rel:
  1365. case BuiltinProc_atomic_store_relaxed:
  1366. case BuiltinProc_atomic_store_unordered: {
  1367. lbValue dst = lb_build_expr(p, ce->args[0]);
  1368. lbValue val = lb_build_expr(p, ce->args[1]);
  1369. val = lb_emit_conv(p, val, type_deref(dst.type));
  1370. LLVMValueRef instr = LLVMBuildStore(p->builder, val.value, dst.value);
  1371. switch (id) {
  1372. case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break;
  1373. case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  1374. case BuiltinProc_atomic_store_rel: LLVMSetOrdering(instr, LLVMAtomicOrderingRelease); break;
  1375. case BuiltinProc_atomic_store_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
  1376. case BuiltinProc_atomic_store_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
  1377. }
  1378. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  1379. return {};
  1380. }
  1381. case BuiltinProc_volatile_load:
  1382. case BuiltinProc_atomic_load:
  1383. case BuiltinProc_atomic_load_acq:
  1384. case BuiltinProc_atomic_load_relaxed:
  1385. case BuiltinProc_atomic_load_unordered: {
  1386. lbValue dst = lb_build_expr(p, ce->args[0]);
  1387. LLVMValueRef instr = LLVMBuildLoad(p->builder, dst.value, "");
  1388. switch (id) {
  1389. case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break;
  1390. case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  1391. case BuiltinProc_atomic_load_acq: LLVMSetOrdering(instr, LLVMAtomicOrderingAcquire); break;
  1392. case BuiltinProc_atomic_load_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
  1393. case BuiltinProc_atomic_load_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
  1394. }
  1395. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  1396. lbValue res = {};
  1397. res.value = instr;
  1398. res.type = type_deref(dst.type);
  1399. return res;
  1400. }
  1401. case BuiltinProc_unaligned_store:
  1402. {
  1403. lbValue dst = lb_build_expr(p, ce->args[0]);
  1404. lbValue src = lb_build_expr(p, ce->args[1]);
  1405. src = lb_address_from_load_or_generate_local(p, src);
  1406. Type *t = type_deref(dst.type);
  1407. lb_mem_copy_non_overlapping(p, dst, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
  1408. return {};
  1409. }
  1410. case BuiltinProc_unaligned_load:
  1411. {
  1412. lbValue src = lb_build_expr(p, ce->args[0]);
  1413. Type *t = type_deref(src.type);
  1414. lbAddr dst = lb_add_local_generated(p, t, false);
  1415. lb_mem_copy_non_overlapping(p, dst.addr, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
  1416. return lb_addr_load(p, dst);
  1417. }
  1418. case BuiltinProc_atomic_add:
  1419. case BuiltinProc_atomic_add_acq:
  1420. case BuiltinProc_atomic_add_rel:
  1421. case BuiltinProc_atomic_add_acqrel:
  1422. case BuiltinProc_atomic_add_relaxed:
  1423. case BuiltinProc_atomic_sub:
  1424. case BuiltinProc_atomic_sub_acq:
  1425. case BuiltinProc_atomic_sub_rel:
  1426. case BuiltinProc_atomic_sub_acqrel:
  1427. case BuiltinProc_atomic_sub_relaxed:
  1428. case BuiltinProc_atomic_and:
  1429. case BuiltinProc_atomic_and_acq:
  1430. case BuiltinProc_atomic_and_rel:
  1431. case BuiltinProc_atomic_and_acqrel:
  1432. case BuiltinProc_atomic_and_relaxed:
  1433. case BuiltinProc_atomic_nand:
  1434. case BuiltinProc_atomic_nand_acq:
  1435. case BuiltinProc_atomic_nand_rel:
  1436. case BuiltinProc_atomic_nand_acqrel:
  1437. case BuiltinProc_atomic_nand_relaxed:
  1438. case BuiltinProc_atomic_or:
  1439. case BuiltinProc_atomic_or_acq:
  1440. case BuiltinProc_atomic_or_rel:
  1441. case BuiltinProc_atomic_or_acqrel:
  1442. case BuiltinProc_atomic_or_relaxed:
  1443. case BuiltinProc_atomic_xor:
  1444. case BuiltinProc_atomic_xor_acq:
  1445. case BuiltinProc_atomic_xor_rel:
  1446. case BuiltinProc_atomic_xor_acqrel:
  1447. case BuiltinProc_atomic_xor_relaxed:
  1448. case BuiltinProc_atomic_xchg:
  1449. case BuiltinProc_atomic_xchg_acq:
  1450. case BuiltinProc_atomic_xchg_rel:
  1451. case BuiltinProc_atomic_xchg_acqrel:
  1452. case BuiltinProc_atomic_xchg_relaxed: {
  1453. lbValue dst = lb_build_expr(p, ce->args[0]);
  1454. lbValue val = lb_build_expr(p, ce->args[1]);
  1455. val = lb_emit_conv(p, val, type_deref(dst.type));
  1456. LLVMAtomicRMWBinOp op = {};
  1457. LLVMAtomicOrdering ordering = {};
  1458. switch (id) {
  1459. case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1460. case BuiltinProc_atomic_add_acq: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquire; break;
  1461. case BuiltinProc_atomic_add_rel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingRelease; break;
  1462. case BuiltinProc_atomic_add_acqrel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1463. case BuiltinProc_atomic_add_relaxed: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingMonotonic; break;
  1464. case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1465. case BuiltinProc_atomic_sub_acq: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquire; break;
  1466. case BuiltinProc_atomic_sub_rel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingRelease; break;
  1467. case BuiltinProc_atomic_sub_acqrel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1468. case BuiltinProc_atomic_sub_relaxed: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingMonotonic; break;
  1469. case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1470. case BuiltinProc_atomic_and_acq: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquire; break;
  1471. case BuiltinProc_atomic_and_rel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingRelease; break;
  1472. case BuiltinProc_atomic_and_acqrel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1473. case BuiltinProc_atomic_and_relaxed: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingMonotonic; break;
  1474. case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1475. case BuiltinProc_atomic_nand_acq: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquire; break;
  1476. case BuiltinProc_atomic_nand_rel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingRelease; break;
  1477. case BuiltinProc_atomic_nand_acqrel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1478. case BuiltinProc_atomic_nand_relaxed: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingMonotonic; break;
  1479. case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1480. case BuiltinProc_atomic_or_acq: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquire; break;
  1481. case BuiltinProc_atomic_or_rel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingRelease; break;
  1482. case BuiltinProc_atomic_or_acqrel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1483. case BuiltinProc_atomic_or_relaxed: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingMonotonic; break;
  1484. case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1485. case BuiltinProc_atomic_xor_acq: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquire; break;
  1486. case BuiltinProc_atomic_xor_rel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingRelease; break;
  1487. case BuiltinProc_atomic_xor_acqrel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1488. case BuiltinProc_atomic_xor_relaxed: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingMonotonic; break;
  1489. case BuiltinProc_atomic_xchg: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1490. case BuiltinProc_atomic_xchg_acq: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquire; break;
  1491. case BuiltinProc_atomic_xchg_rel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingRelease; break;
  1492. case BuiltinProc_atomic_xchg_acqrel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1493. case BuiltinProc_atomic_xchg_relaxed: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingMonotonic; break;
  1494. }
  1495. lbValue res = {};
  1496. res.value = LLVMBuildAtomicRMW(p->builder, op, dst.value, val.value, ordering, false);
  1497. res.type = tv.type;
  1498. return res;
  1499. }
  1500. case BuiltinProc_atomic_cxchg:
  1501. case BuiltinProc_atomic_cxchg_acq:
  1502. case BuiltinProc_atomic_cxchg_rel:
  1503. case BuiltinProc_atomic_cxchg_acqrel:
  1504. case BuiltinProc_atomic_cxchg_relaxed:
  1505. case BuiltinProc_atomic_cxchg_failrelaxed:
  1506. case BuiltinProc_atomic_cxchg_failacq:
  1507. case BuiltinProc_atomic_cxchg_acq_failrelaxed:
  1508. case BuiltinProc_atomic_cxchg_acqrel_failrelaxed:
  1509. case BuiltinProc_atomic_cxchgweak:
  1510. case BuiltinProc_atomic_cxchgweak_acq:
  1511. case BuiltinProc_atomic_cxchgweak_rel:
  1512. case BuiltinProc_atomic_cxchgweak_acqrel:
  1513. case BuiltinProc_atomic_cxchgweak_relaxed:
  1514. case BuiltinProc_atomic_cxchgweak_failrelaxed:
  1515. case BuiltinProc_atomic_cxchgweak_failacq:
  1516. case BuiltinProc_atomic_cxchgweak_acq_failrelaxed:
  1517. case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: {
  1518. lbValue address = lb_build_expr(p, ce->args[0]);
  1519. Type *elem = type_deref(address.type);
  1520. lbValue old_value = lb_build_expr(p, ce->args[1]);
  1521. lbValue new_value = lb_build_expr(p, ce->args[2]);
  1522. old_value = lb_emit_conv(p, old_value, elem);
  1523. new_value = lb_emit_conv(p, new_value, elem);
  1524. LLVMAtomicOrdering success_ordering = {};
  1525. LLVMAtomicOrdering failure_ordering = {};
  1526. LLVMBool weak = false;
  1527. switch (id) {
  1528. case BuiltinProc_atomic_cxchg: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1529. case BuiltinProc_atomic_cxchg_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1530. case BuiltinProc_atomic_cxchg_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1531. case BuiltinProc_atomic_cxchg_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1532. case BuiltinProc_atomic_cxchg_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1533. case BuiltinProc_atomic_cxchg_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1534. case BuiltinProc_atomic_cxchg_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = false; break;
  1535. case BuiltinProc_atomic_cxchg_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1536. case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1537. case BuiltinProc_atomic_cxchgweak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1538. case BuiltinProc_atomic_cxchgweak_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  1539. case BuiltinProc_atomic_cxchgweak_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  1540. case BuiltinProc_atomic_cxchgweak_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  1541. case BuiltinProc_atomic_cxchgweak_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1542. case BuiltinProc_atomic_cxchgweak_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1543. case BuiltinProc_atomic_cxchgweak_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = true; break;
  1544. case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1545. case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1546. }
  1547. // TODO(bill): Figure out how to make it weak
  1548. LLVMBool single_threaded = weak;
  1549. LLVMValueRef value = LLVMBuildAtomicCmpXchg(
  1550. p->builder, address.value,
  1551. old_value.value, new_value.value,
  1552. success_ordering,
  1553. failure_ordering,
  1554. single_threaded
  1555. );
  1556. if (tv.type->kind == Type_Tuple) {
  1557. Type *fix_typed = alloc_type_tuple();
  1558. slice_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
  1559. fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0];
  1560. fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  1561. lbValue res = {};
  1562. res.value = value;
  1563. res.type = fix_typed;
  1564. return res;
  1565. } else {
  1566. lbValue res = {};
  1567. res.value = LLVMBuildExtractValue(p->builder, value, 0, "");
  1568. res.type = tv.type;
  1569. return res;
  1570. }
  1571. }
  1572. case BuiltinProc_type_equal_proc:
  1573. return lb_get_equal_proc_for_type(p->module, ce->args[0]->tav.type);
  1574. case BuiltinProc_type_hasher_proc:
  1575. return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type);
  1576. case BuiltinProc_fixed_point_mul:
  1577. case BuiltinProc_fixed_point_div:
  1578. case BuiltinProc_fixed_point_mul_sat:
  1579. case BuiltinProc_fixed_point_div_sat:
  1580. {
  1581. Type *platform_type = integer_endian_type_to_platform_type(tv.type);
  1582. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), platform_type);
  1583. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), platform_type);
  1584. lbValue scale = lb_emit_conv(p, lb_build_expr(p, ce->args[2]), t_i32);
  1585. char const *name = nullptr;
  1586. if (is_type_unsigned(tv.type)) {
  1587. switch (id) {
  1588. case BuiltinProc_fixed_point_mul: name = "llvm.umul.fix"; break;
  1589. case BuiltinProc_fixed_point_div: name = "llvm.udiv.fix"; break;
  1590. case BuiltinProc_fixed_point_mul_sat: name = "llvm.umul.fix.sat"; break;
  1591. case BuiltinProc_fixed_point_div_sat: name = "llvm.udiv.fix.sat"; break;
  1592. }
  1593. } else {
  1594. switch (id) {
  1595. case BuiltinProc_fixed_point_mul: name = "llvm.smul.fix"; break;
  1596. case BuiltinProc_fixed_point_div: name = "llvm.sdiv.fix"; break;
  1597. case BuiltinProc_fixed_point_mul_sat: name = "llvm.smul.fix.sat"; break;
  1598. case BuiltinProc_fixed_point_div_sat: name = "llvm.sdiv.fix.sat"; break;
  1599. }
  1600. }
  1601. GB_ASSERT(name != nullptr);
  1602. LLVMTypeRef types[1] = {lb_type(p->module, platform_type)};
  1603. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1604. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1605. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1606. lbValue res = {};
  1607. LLVMValueRef args[3] = {};
  1608. args[0] = x.value;
  1609. args[1] = y.value;
  1610. args[2] = scale.value;
  1611. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1612. res.type = platform_type;
  1613. return lb_emit_conv(p, res, tv.type);
  1614. }
  1615. case BuiltinProc_expect:
  1616. {
  1617. Type *t = default_type(tv.type);
  1618. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t);
  1619. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t);
  1620. char const *name = "llvm.expect";
  1621. LLVMTypeRef types[1] = {lb_type(p->module, t)};
  1622. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1623. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1624. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1625. lbValue res = {};
  1626. LLVMValueRef args[2] = {};
  1627. args[0] = x.value;
  1628. args[1] = y.value;
  1629. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1630. res.type = t;
  1631. return lb_emit_conv(p, res, t);
  1632. }
  1633. case BuiltinProc_prefetch_read_instruction:
  1634. case BuiltinProc_prefetch_read_data:
  1635. case BuiltinProc_prefetch_write_instruction:
  1636. case BuiltinProc_prefetch_write_data:
  1637. {
  1638. lbValue ptr = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_rawptr);
  1639. unsigned long long locality = cast(unsigned long long)exact_value_to_i64(ce->args[1]->tav.value);
  1640. unsigned long long rw = 0;
  1641. unsigned long long cache = 0;
  1642. switch (id) {
  1643. case BuiltinProc_prefetch_read_instruction:
  1644. rw = 0;
  1645. cache = 0;
  1646. break;
  1647. case BuiltinProc_prefetch_read_data:
  1648. rw = 0;
  1649. cache = 1;
  1650. break;
  1651. case BuiltinProc_prefetch_write_instruction:
  1652. rw = 1;
  1653. cache = 0;
  1654. break;
  1655. case BuiltinProc_prefetch_write_data:
  1656. rw = 1;
  1657. cache = 1;
  1658. break;
  1659. }
  1660. char const *name = "llvm.prefetch";
  1661. LLVMTypeRef types[1] = {lb_type(p->module, t_rawptr)};
  1662. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1663. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1664. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1665. LLVMTypeRef llvm_i32 = lb_type(p->module, t_i32);
  1666. LLVMValueRef args[4] = {};
  1667. args[0] = ptr.value;
  1668. args[1] = LLVMConstInt(llvm_i32, rw, false);
  1669. args[2] = LLVMConstInt(llvm_i32, locality, false);
  1670. args[3] = LLVMConstInt(llvm_i32, cache, false);
  1671. lbValue res = {};
  1672. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1673. res.type = nullptr;
  1674. return res;
  1675. }
  1676. case BuiltinProc___entry_point:
  1677. if (p->module->info->entry_point) {
  1678. lbValue entry_point = lb_find_procedure_value_from_entity(p->module, p->module->info->entry_point);
  1679. GB_ASSERT(entry_point.value != nullptr);
  1680. lb_emit_call(p, entry_point, {});
  1681. }
  1682. return {};
  1683. case BuiltinProc_syscall:
  1684. {
  1685. unsigned arg_count = cast(unsigned)ce->args.count;
  1686. LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count);
  1687. for_array(i, ce->args) {
  1688. lbValue arg = lb_build_expr(p, ce->args[i]);
  1689. arg = lb_emit_conv(p, arg, t_uintptr);
  1690. args[i] = arg.value;
  1691. }
  1692. LLVMTypeRef llvm_uintptr = lb_type(p->module, t_uintptr);
  1693. LLVMTypeRef *llvm_arg_types = gb_alloc_array(permanent_allocator(), LLVMTypeRef, arg_count);
  1694. for (unsigned i = 0; i < arg_count; i++) {
  1695. llvm_arg_types[i] = llvm_uintptr;
  1696. }
  1697. LLVMTypeRef func_type = LLVMFunctionType(llvm_uintptr, llvm_arg_types, arg_count, false);
  1698. LLVMValueRef inline_asm = nullptr;
  1699. switch (build_context.metrics.arch) {
  1700. case TargetArch_amd64:
  1701. {
  1702. GB_ASSERT(arg_count <= 7);
  1703. char asm_string[] = "syscall";
  1704. gbString constraints = gb_string_make(heap_allocator(), "={rax}");
  1705. for (unsigned i = 0; i < arg_count; i++) {
  1706. constraints = gb_string_appendc(constraints, ",{");
  1707. static char const *regs[] = {
  1708. "rax",
  1709. "rdi",
  1710. "rsi",
  1711. "rdx",
  1712. "r10",
  1713. "r8",
  1714. "r9"
  1715. };
  1716. constraints = gb_string_appendc(constraints, regs[i]);
  1717. constraints = gb_string_appendc(constraints, "}");
  1718. }
  1719. // The SYSCALL instruction stores the address of the
  1720. // following instruction into RCX, and RFLAGS in R11.
  1721. //
  1722. // RSP is not saved, but at least on Linux it appears
  1723. // that the kernel system-call handler does the right
  1724. // thing.
  1725. //
  1726. // Some but not all system calls will additionally
  1727. // clobber memory.
  1728. //
  1729. // TODO: FreeBSD is different and will also clobber
  1730. // R8, R9, and R10. Additionally CF is used to
  1731. // indicate an error instead of -errno.
  1732. constraints = gb_string_appendc(constraints, ",~{rcx},~{r11},~{memory}");
  1733. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  1734. }
  1735. break;
  1736. case TargetArch_i386:
  1737. {
  1738. GB_ASSERT(arg_count <= 7);
  1739. char asm_string_default[] = "int $0x80";
  1740. char *asm_string = asm_string_default;
  1741. gbString constraints = gb_string_make(heap_allocator(), "={eax}");
  1742. for (unsigned i = 0; i < gb_min(arg_count, 6); i++) {
  1743. constraints = gb_string_appendc(constraints, ",{");
  1744. static char const *regs[] = {
  1745. "eax",
  1746. "ebx",
  1747. "ecx",
  1748. "edx",
  1749. "esi",
  1750. "edi",
  1751. };
  1752. constraints = gb_string_appendc(constraints, regs[i]);
  1753. constraints = gb_string_appendc(constraints, "}");
  1754. }
  1755. if (arg_count == 7) {
  1756. char asm_string7[] = "push %[arg6]\npush %%ebp\nmov 4(%%esp), %%ebp\nint $0x80\npop %%ebp\nadd $4, %%esp";
  1757. asm_string = asm_string7;
  1758. constraints = gb_string_appendc(constraints, ",rm");
  1759. }
  1760. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  1761. }
  1762. break;
  1763. case TargetArch_arm64:
  1764. {
  1765. GB_ASSERT(arg_count <= 7);
  1766. if(build_context.metrics.os == TargetOs_darwin) {
  1767. char asm_string[] = "svc #0x80";
  1768. gbString constraints = gb_string_make(heap_allocator(), "={x0}");
  1769. for (unsigned i = 0; i < arg_count; i++) {
  1770. constraints = gb_string_appendc(constraints, ",{");
  1771. static char const *regs[] = {
  1772. "x16",
  1773. "x0",
  1774. "x1",
  1775. "x2",
  1776. "x3",
  1777. "x4",
  1778. "x5",
  1779. };
  1780. constraints = gb_string_appendc(constraints, regs[i]);
  1781. constraints = gb_string_appendc(constraints, "}");
  1782. }
  1783. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  1784. } else {
  1785. char asm_string[] = "svc #0";
  1786. gbString constraints = gb_string_make(heap_allocator(), "={x0}");
  1787. for (unsigned i = 0; i < arg_count; i++) {
  1788. constraints = gb_string_appendc(constraints, ",{");
  1789. static char const *regs[] = {
  1790. "x8",
  1791. "x0",
  1792. "x1",
  1793. "x2",
  1794. "x3",
  1795. "x4",
  1796. "x5",
  1797. };
  1798. constraints = gb_string_appendc(constraints, regs[i]);
  1799. constraints = gb_string_appendc(constraints, "}");
  1800. }
  1801. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  1802. }
  1803. }
  1804. break;
  1805. default:
  1806. GB_PANIC("Unsupported platform");
  1807. }
  1808. lbValue res = {};
  1809. res.value = LLVMBuildCall2(p->builder, func_type, inline_asm, args, arg_count, "");
  1810. res.type = t_uintptr;
  1811. return res;
  1812. }
  1813. case BuiltinProc_objc_send:
  1814. return lb_handle_objc_send(p, expr);
  1815. case BuiltinProc_objc_find_selector: return lb_handle_objc_find_selector(p, expr);
  1816. case BuiltinProc_objc_find_class: return lb_handle_objc_find_class(p, expr);
  1817. case BuiltinProc_objc_register_selector: return lb_handle_objc_register_selector(p, expr);
  1818. case BuiltinProc_objc_register_class: return lb_handle_objc_register_class(p, expr);
  1819. case BuiltinProc_constant_utf16_cstring:
  1820. {
  1821. auto const encode_surrogate_pair = [](Rune r, u16 *r1, u16 *r2) {
  1822. if (r < 0x10000 || r > 0x10ffff) {
  1823. *r1 = 0xfffd;
  1824. *r2 = 0xfffd;
  1825. } else {
  1826. r -= 0x10000;
  1827. *r1 = 0xd800 + ((r>>10)&0x3ff);
  1828. *r2 = 0xdc00 + (r&0x3ff);
  1829. }
  1830. };
  1831. lbModule *m = p->module;
  1832. auto tav = type_and_value_of_expr(ce->args[0]);
  1833. GB_ASSERT(tav.value.kind == ExactValue_String);
  1834. String value = tav.value.value_string;
  1835. LLVMTypeRef llvm_u16 = lb_type(m, t_u16);
  1836. isize max_len = value.len*2 + 1;
  1837. LLVMValueRef *buffer = gb_alloc_array(temporary_allocator(), LLVMValueRef, max_len);
  1838. isize n = 0;
  1839. while (value.len > 0) {
  1840. Rune r = 0;
  1841. isize w = gb_utf8_decode(value.text, value.len, &r);
  1842. value.text += w;
  1843. value.len -= w;
  1844. if ((0 <= r && r < 0xd800) || (0xe000 <= r && r < 0x10000)) {
  1845. buffer[n++] = LLVMConstInt(llvm_u16, cast(u16)r, false);
  1846. } else if (0x10000 <= r && r <= 0x10ffff) {
  1847. u16 r1, r2;
  1848. encode_surrogate_pair(r, &r1, &r2);
  1849. buffer[n++] = LLVMConstInt(llvm_u16, r1, false);
  1850. buffer[n++] = LLVMConstInt(llvm_u16, r2, false);
  1851. } else {
  1852. buffer[n++] = LLVMConstInt(llvm_u16, 0xfffd, false);
  1853. }
  1854. }
  1855. buffer[n++] = LLVMConstInt(llvm_u16, 0, false);
  1856. LLVMValueRef array = LLVMConstArray(llvm_u16, buffer, cast(unsigned int)n);
  1857. char *name = nullptr;
  1858. {
  1859. isize max_len = 7+8+1;
  1860. name = gb_alloc_array(permanent_allocator(), char, max_len);
  1861. u32 id = m->gen->global_array_index.fetch_add(1);
  1862. isize len = gb_snprintf(name, max_len, "csbs$%x", id);
  1863. len -= 1;
  1864. }
  1865. LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(array), name);
  1866. LLVMSetInitializer(global_data, array);
  1867. LLVMSetLinkage(global_data, LLVMInternalLinkage);
  1868. LLVMValueRef indices[] = {
  1869. LLVMConstInt(lb_type(m, t_u32), 0, false),
  1870. LLVMConstInt(lb_type(m, t_u32), 0, false),
  1871. };
  1872. lbValue res = {};
  1873. res.type = tv.type;
  1874. res.value = LLVMBuildInBoundsGEP(p->builder, global_data, indices, gb_count_of(indices), "");
  1875. return res;
  1876. }
  1877. }
  1878. GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name));
  1879. return {};
  1880. }
  1881. lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
  1882. switch (param_value.kind) {
  1883. case ParameterValue_Constant:
  1884. if (is_type_constant_type(parameter_type)) {
  1885. auto res = lb_const_value(p->module, parameter_type, param_value.value);
  1886. return res;
  1887. } else {
  1888. ExactValue ev = param_value.value;
  1889. lbValue arg = {};
  1890. Type *type = type_of_expr(param_value.original_ast_expr);
  1891. if (type != nullptr) {
  1892. arg = lb_const_value(p->module, type, ev);
  1893. } else {
  1894. arg = lb_const_value(p->module, parameter_type, param_value.value);
  1895. }
  1896. return lb_emit_conv(p, arg, parameter_type);
  1897. }
  1898. case ParameterValue_Nil:
  1899. return lb_const_nil(p->module, parameter_type);
  1900. case ParameterValue_Location:
  1901. {
  1902. String proc_name = {};
  1903. if (p->entity != nullptr) {
  1904. proc_name = p->entity->token.string;
  1905. }
  1906. return lb_emit_source_code_location(p, proc_name, pos);
  1907. }
  1908. case ParameterValue_Value:
  1909. return lb_build_expr(p, param_value.ast_value);
  1910. }
  1911. return lb_const_nil(p->module, parameter_type);
  1912. }
  1913. lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr);
  1914. lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
  1915. expr = unparen_expr(expr);
  1916. ast_node(ce, CallExpr, expr);
  1917. if (ce->sce_temp_data) {
  1918. return *(lbValue *)ce->sce_temp_data;
  1919. }
  1920. lbValue res = lb_build_call_expr_internal(p, expr);
  1921. if (ce->optional_ok_one) { // TODO(bill): Minor hack for #optional_ok procedures
  1922. GB_ASSERT(is_type_tuple(res.type));
  1923. GB_ASSERT(res.type->Tuple.variables.count == 2);
  1924. return lb_emit_struct_ev(p, res, 0);
  1925. }
  1926. return res;
  1927. }
  1928. lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
  1929. lbModule *m = p->module;
  1930. TypeAndValue tv = type_and_value_of_expr(expr);
  1931. ast_node(ce, CallExpr, expr);
  1932. TypeAndValue proc_tv = type_and_value_of_expr(ce->proc);
  1933. AddressingMode proc_mode = proc_tv.mode;
  1934. if (proc_mode == Addressing_Type) {
  1935. GB_ASSERT(ce->args.count == 1);
  1936. lbValue x = lb_build_expr(p, ce->args[0]);
  1937. lbValue y = lb_emit_conv(p, x, tv.type);
  1938. return y;
  1939. }
  1940. Ast *pexpr = unparen_expr(ce->proc);
  1941. if (proc_mode == Addressing_Builtin) {
  1942. Entity *e = entity_of_node(pexpr);
  1943. BuiltinProcId id = BuiltinProc_Invalid;
  1944. if (e != nullptr) {
  1945. id = cast(BuiltinProcId)e->Builtin.id;
  1946. } else {
  1947. id = BuiltinProc_DIRECTIVE;
  1948. }
  1949. return lb_build_builtin_proc(p, expr, tv, id);
  1950. }
  1951. // NOTE(bill): Regular call
  1952. lbValue value = {};
  1953. Ast *proc_expr = unparen_expr(ce->proc);
  1954. if (proc_expr->tav.mode == Addressing_Constant) {
  1955. ExactValue v = proc_expr->tav.value;
  1956. switch (v.kind) {
  1957. case ExactValue_Integer:
  1958. {
  1959. u64 u = big_int_to_u64(&v.value_integer);
  1960. lbValue x = {};
  1961. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  1962. x.type = t_uintptr;
  1963. x = lb_emit_conv(p, x, t_rawptr);
  1964. value = lb_emit_conv(p, x, proc_expr->tav.type);
  1965. break;
  1966. }
  1967. case ExactValue_Pointer:
  1968. {
  1969. u64 u = cast(u64)v.value_pointer;
  1970. lbValue x = {};
  1971. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  1972. x.type = t_uintptr;
  1973. x = lb_emit_conv(p, x, t_rawptr);
  1974. value = lb_emit_conv(p, x, proc_expr->tav.type);
  1975. break;
  1976. }
  1977. }
  1978. }
  1979. Entity *proc_entity = entity_of_node(proc_expr);
  1980. if (proc_entity != nullptr) {
  1981. if (proc_entity->flags & EntityFlag_Disabled) {
  1982. return {};
  1983. }
  1984. }
  1985. if (value.value == nullptr) {
  1986. value = lb_build_expr(p, proc_expr);
  1987. }
  1988. GB_ASSERT(value.value != nullptr);
  1989. Type *proc_type_ = base_type(value.type);
  1990. GB_ASSERT(proc_type_->kind == Type_Proc);
  1991. TypeProc *pt = &proc_type_->Proc;
  1992. if (is_call_expr_field_value(ce)) {
  1993. auto args = array_make<lbValue>(permanent_allocator(), pt->param_count);
  1994. for_array(arg_index, ce->args) {
  1995. Ast *arg = ce->args[arg_index];
  1996. ast_node(fv, FieldValue, arg);
  1997. GB_ASSERT(fv->field->kind == Ast_Ident);
  1998. String name = fv->field->Ident.token.string;
  1999. isize index = lookup_procedure_parameter(pt, name);
  2000. GB_ASSERT(index >= 0);
  2001. TypeAndValue tav = type_and_value_of_expr(fv->value);
  2002. if (tav.mode == Addressing_Type) {
  2003. args[index] = lb_const_nil(m, tav.type);
  2004. } else {
  2005. args[index] = lb_build_expr(p, fv->value);
  2006. }
  2007. }
  2008. TypeTuple *params = &pt->params->Tuple;
  2009. for (isize i = 0; i < args.count; i++) {
  2010. Entity *e = params->variables[i];
  2011. if (e->kind == Entity_TypeName) {
  2012. args[i] = lb_const_nil(m, e->type);
  2013. } else if (e->kind == Entity_Constant) {
  2014. continue;
  2015. } else {
  2016. GB_ASSERT(e->kind == Entity_Variable);
  2017. if (args[i].value == nullptr) {
  2018. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2019. } else {
  2020. args[i] = lb_emit_conv(p, args[i], e->type);
  2021. }
  2022. }
  2023. }
  2024. for (isize i = 0; i < args.count; i++) {
  2025. Entity *e = params->variables[i];
  2026. if (args[i].type == nullptr) {
  2027. continue;
  2028. } else if (is_type_untyped_nil(args[i].type)) {
  2029. args[i] = lb_const_nil(m, e->type);
  2030. } else if (is_type_untyped_undef(args[i].type)) {
  2031. args[i] = lb_const_undef(m, e->type);
  2032. }
  2033. }
  2034. return lb_emit_call(p, value, args, ce->inlining, p->copy_elision_hint.ast == expr);
  2035. }
  2036. isize arg_index = 0;
  2037. isize arg_count = 0;
  2038. for_array(i, ce->args) {
  2039. Ast *arg = ce->args[i];
  2040. TypeAndValue tav = type_and_value_of_expr(arg);
  2041. GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s %s %d", expr_to_string(arg), expr_to_string(expr), tav.mode);
  2042. GB_ASSERT_MSG(tav.mode != Addressing_ProcGroup, "%s", expr_to_string(arg));
  2043. Type *at = tav.type;
  2044. if (at->kind == Type_Tuple) {
  2045. arg_count += at->Tuple.variables.count;
  2046. } else {
  2047. arg_count++;
  2048. }
  2049. }
  2050. isize param_count = 0;
  2051. if (pt->params) {
  2052. GB_ASSERT(pt->params->kind == Type_Tuple);
  2053. param_count = pt->params->Tuple.variables.count;
  2054. }
  2055. auto args = array_make<lbValue>(permanent_allocator(), cast(isize)gb_max(param_count, arg_count));
  2056. isize variadic_index = pt->variadic_index;
  2057. bool variadic = pt->variadic && variadic_index >= 0;
  2058. bool vari_expand = ce->ellipsis.pos.line != 0;
  2059. bool is_c_vararg = pt->c_vararg;
  2060. String proc_name = {};
  2061. if (p->entity != nullptr) {
  2062. proc_name = p->entity->token.string;
  2063. }
  2064. TokenPos pos = ast_token(ce->proc).pos;
  2065. TypeTuple *param_tuple = nullptr;
  2066. if (pt->params) {
  2067. GB_ASSERT(pt->params->kind == Type_Tuple);
  2068. param_tuple = &pt->params->Tuple;
  2069. }
  2070. for_array(i, ce->args) {
  2071. Ast *arg = ce->args[i];
  2072. TypeAndValue arg_tv = type_and_value_of_expr(arg);
  2073. if (arg_tv.mode == Addressing_Type) {
  2074. args[arg_index++] = lb_const_nil(m, arg_tv.type);
  2075. } else {
  2076. lbValue a = lb_build_expr(p, arg);
  2077. Type *at = a.type;
  2078. if (at->kind == Type_Tuple) {
  2079. for_array(i, at->Tuple.variables) {
  2080. lbValue v = lb_emit_struct_ev(p, a, cast(i32)i);
  2081. args[arg_index++] = v;
  2082. }
  2083. } else {
  2084. args[arg_index++] = a;
  2085. }
  2086. }
  2087. }
  2088. if (param_count > 0) {
  2089. GB_ASSERT_MSG(pt->params != nullptr, "%s %td", expr_to_string(expr), pt->param_count);
  2090. GB_ASSERT(param_count < 1000000);
  2091. if (arg_count < param_count) {
  2092. isize end = cast(isize)param_count;
  2093. if (variadic) {
  2094. end = variadic_index;
  2095. }
  2096. while (arg_index < end) {
  2097. Entity *e = param_tuple->variables[arg_index];
  2098. GB_ASSERT(e->kind == Entity_Variable);
  2099. args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2100. }
  2101. }
  2102. if (is_c_vararg) {
  2103. GB_ASSERT(variadic);
  2104. GB_ASSERT(!vari_expand);
  2105. isize i = 0;
  2106. for (; i < variadic_index; i++) {
  2107. Entity *e = param_tuple->variables[i];
  2108. if (e->kind == Entity_Variable) {
  2109. args[i] = lb_emit_conv(p, args[i], e->type);
  2110. }
  2111. }
  2112. Type *variadic_type = param_tuple->variables[i]->type;
  2113. GB_ASSERT(is_type_slice(variadic_type));
  2114. variadic_type = base_type(variadic_type)->Slice.elem;
  2115. if (!is_type_any(variadic_type)) {
  2116. for (; i < arg_count; i++) {
  2117. args[i] = lb_emit_conv(p, args[i], variadic_type);
  2118. }
  2119. } else {
  2120. for (; i < arg_count; i++) {
  2121. args[i] = lb_emit_conv(p, args[i], default_type(args[i].type));
  2122. }
  2123. }
  2124. } else if (variadic) {
  2125. isize i = 0;
  2126. for (; i < variadic_index; i++) {
  2127. Entity *e = param_tuple->variables[i];
  2128. if (e->kind == Entity_Variable) {
  2129. args[i] = lb_emit_conv(p, args[i], e->type);
  2130. }
  2131. }
  2132. if (!vari_expand) {
  2133. Type *variadic_type = param_tuple->variables[i]->type;
  2134. GB_ASSERT(is_type_slice(variadic_type));
  2135. variadic_type = base_type(variadic_type)->Slice.elem;
  2136. for (; i < arg_count; i++) {
  2137. args[i] = lb_emit_conv(p, args[i], variadic_type);
  2138. }
  2139. }
  2140. } else {
  2141. for (isize i = 0; i < param_count; i++) {
  2142. Entity *e = param_tuple->variables[i];
  2143. if (e->kind == Entity_Variable) {
  2144. if (args[i].value == nullptr) {
  2145. continue;
  2146. }
  2147. GB_ASSERT_MSG(args[i].value != nullptr, "%.*s", LIT(e->token.string));
  2148. args[i] = lb_emit_conv(p, args[i], e->type);
  2149. }
  2150. }
  2151. }
  2152. if (variadic && !vari_expand && !is_c_vararg) {
  2153. // variadic call argument generation
  2154. Type *slice_type = param_tuple->variables[variadic_index]->type;
  2155. Type *elem_type = base_type(slice_type)->Slice.elem;
  2156. lbAddr slice = lb_add_local_generated(p, slice_type, true);
  2157. isize slice_len = arg_count+1 - (variadic_index+1);
  2158. if (slice_len > 0) {
  2159. lbAddr base_array = lb_add_local_generated(p, alloc_type_array(elem_type, slice_len), true);
  2160. for (isize i = variadic_index, j = 0; i < arg_count; i++, j++) {
  2161. lbValue addr = lb_emit_array_epi(p, base_array.addr, cast(i32)j);
  2162. lb_emit_store(p, addr, args[i]);
  2163. }
  2164. lbValue base_elem = lb_emit_array_epi(p, base_array.addr, 0);
  2165. lbValue len = lb_const_int(m, t_int, slice_len);
  2166. lb_fill_slice(p, slice, base_elem, len);
  2167. }
  2168. arg_count = param_count;
  2169. args[variadic_index] = lb_addr_load(p, slice);
  2170. }
  2171. }
  2172. if (variadic && variadic_index+1 < param_count) {
  2173. for (isize i = variadic_index+1; i < param_count; i++) {
  2174. Entity *e = param_tuple->variables[i];
  2175. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2176. }
  2177. }
  2178. isize final_count = param_count;
  2179. if (is_c_vararg) {
  2180. final_count = arg_count;
  2181. }
  2182. if (param_tuple != nullptr) {
  2183. for (isize i = 0; i < gb_min(args.count, param_tuple->variables.count); i++) {
  2184. Entity *e = param_tuple->variables[i];
  2185. if (args[i].type == nullptr) {
  2186. continue;
  2187. } else if (is_type_untyped_nil(args[i].type)) {
  2188. args[i] = lb_const_nil(m, e->type);
  2189. } else if (is_type_untyped_undef(args[i].type)) {
  2190. args[i] = lb_const_undef(m, e->type);
  2191. }
  2192. }
  2193. }
  2194. auto call_args = array_slice(args, 0, final_count);
  2195. return lb_emit_call(p, value, call_args, ce->inlining, p->copy_elision_hint.ast == expr);
  2196. }