llvm_backend_proc.cpp 100 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157
  1. LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count)
  2. {
  3. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  4. GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
  5. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, type_count);
  6. LLVMTypeRef call_type = LLVMIntrinsicGetType(p->module->ctx, id, types, type_count);
  7. return LLVMBuildCall2(p->builder, call_type, ip, args, arg_count, "");
  8. }
  9. void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
  10. dst = lb_emit_conv(p, dst, t_rawptr);
  11. src = lb_emit_conv(p, src, t_rawptr);
  12. len = lb_emit_conv(p, len, t_int);
  13. char const *name = "llvm.memmove";
  14. if (LLVMIsConstant(len.value)) {
  15. i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
  16. if (const_len <= 4*build_context.word_size) {
  17. name = "llvm.memmove.inline";
  18. }
  19. }
  20. LLVMTypeRef types[3] = {
  21. lb_type(p->module, t_rawptr),
  22. lb_type(p->module, t_rawptr),
  23. lb_type(p->module, t_int)
  24. };
  25. LLVMValueRef args[4] = {
  26. dst.value,
  27. src.value,
  28. len.value,
  29. LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile)
  30. };
  31. lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  32. }
  33. void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
  34. dst = lb_emit_conv(p, dst, t_rawptr);
  35. src = lb_emit_conv(p, src, t_rawptr);
  36. len = lb_emit_conv(p, len, t_int);
  37. char const *name = "llvm.memcpy";
  38. if (LLVMIsConstant(len.value)) {
  39. i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
  40. if (const_len <= 4*build_context.word_size) {
  41. name = "llvm.memcpy.inline";
  42. }
  43. }
  44. LLVMTypeRef types[3] = {
  45. lb_type(p->module, t_rawptr),
  46. lb_type(p->module, t_rawptr),
  47. lb_type(p->module, t_int)
  48. };
  49. LLVMValueRef args[4] = {
  50. dst.value,
  51. src.value,
  52. len.value,
  53. LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile) };
  54. lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  55. }
  56. lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
  57. GB_ASSERT(entity != nullptr);
  58. GB_ASSERT(entity->kind == Entity_Procedure);
  59. if (!entity->Procedure.is_foreign) {
  60. GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s", LIT(entity->token.string), type_to_string(entity->type));
  61. }
  62. String link_name = {};
  63. if (ignore_body) {
  64. lbModule *other_module = lb_pkg_module(m->gen, entity->pkg);
  65. link_name = lb_get_entity_name(other_module, entity);
  66. } else {
  67. link_name = lb_get_entity_name(m, entity);
  68. }
  69. {
  70. StringHashKey key = string_hash_string(link_name);
  71. lbValue *found = string_map_get(&m->members, key);
  72. if (found) {
  73. lb_add_entity(m, entity, *found);
  74. return string_map_must_get(&m->procedures, key);
  75. }
  76. }
  77. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  78. p->module = m;
  79. entity->code_gen_module = m;
  80. entity->code_gen_procedure = p;
  81. p->entity = entity;
  82. p->name = link_name;
  83. DeclInfo *decl = entity->decl_info;
  84. ast_node(pl, ProcLit, decl->proc_lit);
  85. Type *pt = base_type(entity->type);
  86. GB_ASSERT(pt->kind == Type_Proc);
  87. p->type = entity->type;
  88. p->type_expr = decl->type_expr;
  89. p->body = pl->body;
  90. p->inlining = pl->inlining;
  91. p->is_foreign = entity->Procedure.is_foreign;
  92. p->is_export = entity->Procedure.is_export;
  93. p->is_entry_point = false;
  94. gbAllocator a = heap_allocator();
  95. p->children.allocator = a;
  96. p->defer_stmts.allocator = a;
  97. p->blocks.allocator = a;
  98. p->branch_blocks.allocator = a;
  99. p->context_stack.allocator = a;
  100. p->scope_stack.allocator = a;
  101. map_init(&p->selector_values, a, 0);
  102. map_init(&p->selector_addr, a, 0);
  103. if (p->is_foreign) {
  104. lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library);
  105. }
  106. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  107. LLVMTypeRef func_type = lb_get_procedure_raw_type(m, p->type);
  108. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  109. lb_ensure_abi_function_type(m, p);
  110. lb_add_function_type_attributes(p->value, p->abi_function_type, p->abi_function_type->calling_convention);
  111. if (pt->Proc.diverging) {
  112. lb_add_attribute_to_proc(m, p->value, "noreturn");
  113. }
  114. if (pt->Proc.calling_convention == ProcCC_Naked) {
  115. lb_add_attribute_to_proc(m, p->value, "naked");
  116. }
  117. if (!entity->Procedure.is_foreign && build_context.disable_red_zone) {
  118. lb_add_attribute_to_proc(m, p->value, "noredzone");
  119. }
  120. switch (p->inlining) {
  121. case ProcInlining_inline:
  122. lb_add_attribute_to_proc(m, p->value, "alwaysinline");
  123. break;
  124. case ProcInlining_no_inline:
  125. lb_add_attribute_to_proc(m, p->value, "noinline");
  126. break;
  127. }
  128. switch (entity->Procedure.optimization_mode) {
  129. case ProcedureOptimizationMode_None:
  130. lb_add_attribute_to_proc(m, p->value, "optnone");
  131. break;
  132. case ProcedureOptimizationMode_Minimal:
  133. lb_add_attribute_to_proc(m, p->value, "optnone");
  134. break;
  135. case ProcedureOptimizationMode_Size:
  136. lb_add_attribute_to_proc(m, p->value, "optsize");
  137. break;
  138. case ProcedureOptimizationMode_Speed:
  139. // TODO(bill): handle this correctly
  140. lb_add_attribute_to_proc(m, p->value, "optsize");
  141. break;
  142. }
  143. if (!entity->Procedure.target_feature_disabled &&
  144. entity->Procedure.target_feature.len != 0) {
  145. auto features = split_by_comma(entity->Procedure.target_feature);
  146. for_array(i, features) {
  147. String feature = features[i];
  148. LLVMAttributeRef ref = LLVMCreateStringAttribute(
  149. m->ctx,
  150. cast(char const *)feature.text, cast(unsigned)feature.len,
  151. "", 0);
  152. LLVMAddAttributeAtIndex(p->value, LLVMAttributeIndex_FunctionIndex, ref);
  153. }
  154. }
  155. if (entity->flags & EntityFlag_Cold) {
  156. lb_add_attribute_to_proc(m, p->value, "cold");
  157. }
  158. lbValue proc_value = {p->value, p->type};
  159. lb_add_entity(m, entity, proc_value);
  160. lb_add_member(m, p->name, proc_value);
  161. lb_add_procedure_value(m, p);
  162. if (p->is_export) {
  163. LLVMSetLinkage(p->value, LLVMDLLExportLinkage);
  164. LLVMSetDLLStorageClass(p->value, LLVMDLLExportStorageClass);
  165. LLVMSetVisibility(p->value, LLVMDefaultVisibility);
  166. lb_set_wasm_export_attributes(p->value, p->name);
  167. } else if (!p->is_foreign) {
  168. if (!USE_SEPARATE_MODULES) {
  169. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  170. // NOTE(bill): if a procedure is defined in package runtime and uses a custom link name,
  171. // then it is very likely it is required by LLVM and thus cannot have internal linkage
  172. if (entity->pkg != nullptr && entity->pkg->kind == Package_Runtime && p->body != nullptr) {
  173. GB_ASSERT(entity->kind == Entity_Procedure);
  174. String link_name = entity->Procedure.link_name;
  175. if (entity->flags & EntityFlag_CustomLinkName &&
  176. link_name != "") {
  177. if (string_starts_with(link_name, str_lit("__"))) {
  178. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  179. } else {
  180. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  181. }
  182. }
  183. }
  184. }
  185. }
  186. lb_set_linkage_from_entity_flags(p->module, p->value, entity->flags);
  187. if (p->is_foreign) {
  188. lb_set_wasm_import_attributes(p->value, entity, p->name);
  189. }
  190. // NOTE(bill): offset==0 is the return value
  191. isize offset = 1;
  192. if (pt->Proc.return_by_pointer) {
  193. offset = 2;
  194. }
  195. isize parameter_index = 0;
  196. if (pt->Proc.param_count) {
  197. TypeTuple *params = &pt->Proc.params->Tuple;
  198. for (isize i = 0; i < pt->Proc.param_count; i++) {
  199. Entity *e = params->variables[i];
  200. if (e->kind != Entity_Variable) {
  201. continue;
  202. }
  203. if (i+1 == params->variables.count && pt->Proc.c_vararg) {
  204. continue;
  205. }
  206. if (e->flags&EntityFlag_NoAlias) {
  207. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  208. }
  209. parameter_index += 1;
  210. }
  211. }
  212. if (ignore_body) {
  213. p->body = nullptr;
  214. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  215. }
  216. if (m->debug_builder) { // Debug Information
  217. Type *bt = base_type(p->type);
  218. unsigned line = cast(unsigned)entity->token.pos.line;
  219. LLVMMetadataRef scope = nullptr;
  220. LLVMMetadataRef file = nullptr;
  221. LLVMMetadataRef type = nullptr;
  222. scope = p->module->debug_compile_unit;
  223. type = lb_debug_type_internal_proc(m, bt);
  224. Ast *ident = entity->identifier.load();
  225. if (entity->file != nullptr) {
  226. file = lb_get_llvm_metadata(m, entity->file);
  227. scope = file;
  228. } else if (ident != nullptr && ident->file_id != 0) {
  229. file = lb_get_llvm_metadata(m, ident->file());
  230. scope = file;
  231. } else if (entity->scope != nullptr) {
  232. file = lb_get_llvm_metadata(m, entity->scope->file);
  233. scope = file;
  234. }
  235. GB_ASSERT_MSG(file != nullptr, "%.*s", LIT(entity->token.string));
  236. // LLVMBool is_local_to_unit = !entity->Procedure.is_export;
  237. LLVMBool is_local_to_unit = false;
  238. LLVMBool is_definition = p->body != nullptr;
  239. unsigned scope_line = line;
  240. u32 flags = LLVMDIFlagStaticMember;
  241. LLVMBool is_optimized = false;
  242. if (bt->Proc.diverging) {
  243. flags |= LLVMDIFlagNoReturn;
  244. }
  245. if (p->body == nullptr) {
  246. flags |= LLVMDIFlagPrototyped;
  247. is_optimized = false;
  248. }
  249. if (p->body != nullptr) {
  250. // String debug_name = entity->token.string.text;
  251. String debug_name = p->name;
  252. p->debug_info = LLVMDIBuilderCreateFunction(m->debug_builder, scope,
  253. cast(char const *)debug_name.text, debug_name.len,
  254. cast(char const *)p->name.text, p->name.len,
  255. file, line, type,
  256. is_local_to_unit, is_definition,
  257. scope_line, cast(LLVMDIFlags)flags, is_optimized
  258. );
  259. GB_ASSERT(p->debug_info != nullptr);
  260. LLVMSetSubprogram(p->value, p->debug_info);
  261. lb_set_llvm_metadata(m, p, p->debug_info);
  262. }
  263. }
  264. return p;
  265. }
  266. lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) {
  267. {
  268. lbValue *found = string_map_get(&m->members, link_name);
  269. GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name));
  270. }
  271. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  272. p->module = m;
  273. p->name = link_name;
  274. p->type = type;
  275. p->type_expr = nullptr;
  276. p->body = nullptr;
  277. p->tags = 0;
  278. p->inlining = ProcInlining_none;
  279. p->is_foreign = false;
  280. p->is_export = false;
  281. p->is_entry_point = false;
  282. gbAllocator a = permanent_allocator();
  283. p->children.allocator = a;
  284. p->defer_stmts.allocator = a;
  285. p->blocks.allocator = a;
  286. p->branch_blocks.allocator = a;
  287. p->context_stack.allocator = a;
  288. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  289. LLVMTypeRef func_type = lb_get_procedure_raw_type(m, p->type);
  290. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  291. Type *pt = p->type;
  292. lbCallingConventionKind cc_kind = lbCallingConvention_C;
  293. // TODO(bill): Clean up this logic
  294. if (!is_arch_wasm()) {
  295. cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
  296. }
  297. LLVMSetFunctionCallConv(p->value, cc_kind);
  298. lbValue proc_value = {p->value, p->type};
  299. lb_add_member(m, p->name, proc_value);
  300. lb_add_procedure_value(m, p);
  301. // NOTE(bill): offset==0 is the return value
  302. isize offset = 1;
  303. if (pt->Proc.return_by_pointer) {
  304. lb_add_proc_attribute_at_index(p, 1, "sret");
  305. lb_add_proc_attribute_at_index(p, 1, "noalias");
  306. offset = 2;
  307. }
  308. isize parameter_index = 0;
  309. if (pt->Proc.calling_convention == ProcCC_Odin) {
  310. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  311. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nonnull");
  312. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nocapture");
  313. }
  314. return p;
  315. }
  316. lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
  317. lbParamPasskind kind = lbParamPass_Value;
  318. if (e != nullptr && !are_types_identical(abi_type, e->type)) {
  319. if (is_type_pointer(abi_type)) {
  320. GB_ASSERT(e->kind == Entity_Variable);
  321. Type *av = core_type(type_deref(abi_type));
  322. if (are_types_identical(av, core_type(e->type))) {
  323. kind = lbParamPass_Pointer;
  324. if (e->flags&EntityFlag_Value) {
  325. kind = lbParamPass_ConstRef;
  326. }
  327. } else {
  328. kind = lbParamPass_BitCast;
  329. }
  330. } else if (is_type_integer(abi_type)) {
  331. kind = lbParamPass_Integer;
  332. } else if (abi_type == t_llvm_bool) {
  333. kind = lbParamPass_Value;
  334. } else if (is_type_boolean(abi_type)) {
  335. kind = lbParamPass_Integer;
  336. } else if (is_type_simd_vector(abi_type)) {
  337. kind = lbParamPass_BitCast;
  338. } else if (is_type_float(abi_type)) {
  339. kind = lbParamPass_BitCast;
  340. } else if (is_type_tuple(abi_type)) {
  341. kind = lbParamPass_Tuple;
  342. } else if (is_type_proc(abi_type)) {
  343. kind = lbParamPass_Value;
  344. } else {
  345. GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
  346. }
  347. }
  348. if (kind_) *kind_ = kind;
  349. lbValue res = {};
  350. res.value = LLVMGetParam(p->value, cast(unsigned)index);
  351. res.type = abi_type;
  352. return res;
  353. }
  354. void lb_start_block(lbProcedure *p, lbBlock *b) {
  355. GB_ASSERT(b != nullptr);
  356. if (!b->appended) {
  357. b->appended = true;
  358. LLVMAppendExistingBasicBlock(p->value, b->block);
  359. }
  360. LLVMPositionBuilderAtEnd(p->builder, b->block);
  361. p->curr_block = b;
  362. }
  363. void lb_set_debug_position_to_procedure_begin(lbProcedure *p) {
  364. if (p->debug_info == nullptr) {
  365. return;
  366. }
  367. TokenPos pos = {};
  368. if (p->body != nullptr) {
  369. pos = ast_token(p->body).pos;
  370. } else if (p->type_expr != nullptr) {
  371. pos = ast_token(p->type_expr).pos;
  372. } else if (p->entity != nullptr) {
  373. pos = p->entity->token.pos;
  374. }
  375. if (pos.file_id != 0) {
  376. LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_token_pos(p, pos));
  377. }
  378. }
  379. void lb_set_debug_position_to_procedure_end(lbProcedure *p) {
  380. if (p->debug_info == nullptr) {
  381. return;
  382. }
  383. TokenPos pos = {};
  384. if (p->body != nullptr) {
  385. pos = ast_end_token(p->body).pos;
  386. } else if (p->type_expr != nullptr) {
  387. pos = ast_end_token(p->type_expr).pos;
  388. } else if (p->entity != nullptr) {
  389. pos = p->entity->token.pos;
  390. }
  391. if (pos.file_id != 0) {
  392. LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_token_pos(p, pos));
  393. }
  394. }
  395. void lb_begin_procedure_body(lbProcedure *p) {
  396. DeclInfo *decl = decl_info_of_entity(p->entity);
  397. if (decl != nullptr) {
  398. for_array(i, decl->labels) {
  399. BlockLabel bl = decl->labels[i];
  400. lbBranchBlocks bb = {bl.label, nullptr, nullptr};
  401. array_add(&p->branch_blocks, bb);
  402. }
  403. }
  404. p->builder = LLVMCreateBuilderInContext(p->module->ctx);
  405. p->decl_block = lb_create_block(p, "decls", true);
  406. p->entry_block = lb_create_block(p, "entry", true);
  407. lb_start_block(p, p->entry_block);
  408. GB_ASSERT(p->type != nullptr);
  409. lb_ensure_abi_function_type(p->module, p);
  410. {
  411. lbFunctionType *ft = p->abi_function_type;
  412. unsigned param_offset = 0;
  413. lbValue return_ptr_value = {};
  414. if (ft->ret.kind == lbArg_Indirect) {
  415. // NOTE(bill): this must be parameter 0
  416. String name = str_lit("agg.result");
  417. Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results));
  418. Entity *e = alloc_entity_param(nullptr, make_token_ident(name), ptr_type, false, false);
  419. e->flags |= EntityFlag_NoAlias;
  420. return_ptr_value.value = LLVMGetParam(p->value, 0);
  421. LLVMSetValueName2(return_ptr_value.value, cast(char const *)name.text, name.len);
  422. return_ptr_value.type = ptr_type;
  423. p->return_ptr = lb_addr(return_ptr_value);
  424. lb_add_entity(p->module, e, return_ptr_value);
  425. param_offset += 1;
  426. }
  427. if (p->type->Proc.params != nullptr) {
  428. TypeTuple *params = &p->type->Proc.params->Tuple;
  429. unsigned param_index = 0;
  430. for_array(i, params->variables) {
  431. Entity *e = params->variables[i];
  432. if (e->kind != Entity_Variable) {
  433. continue;
  434. }
  435. lbArgType *arg_type = &ft->args[param_index];
  436. defer (param_index += 1);
  437. if (arg_type->kind == lbArg_Ignore) {
  438. continue;
  439. } else if (arg_type->kind == lbArg_Direct) {
  440. if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
  441. LLVMTypeRef param_type = lb_type(p->module, e->type);
  442. LLVMValueRef original_value = LLVMGetParam(p->value, param_offset+param_index);
  443. LLVMValueRef value = OdinLLVMBuildTransmute(p, original_value, param_type);
  444. lbValue param = {};
  445. param.value = value;
  446. param.type = e->type;
  447. lbValue ptr = lb_address_from_load_or_generate_local(p, param);
  448. GB_ASSERT(LLVMIsAAllocaInst(ptr.value));
  449. lb_add_entity(p->module, e, ptr);
  450. lbBlock *block = p->decl_block;
  451. if (original_value != value) {
  452. block = p->curr_block;
  453. }
  454. LLVMValueRef debug_storage_value = value;
  455. if (original_value != value && LLVMIsALoadInst(value)) {
  456. debug_storage_value = LLVMGetOperand(value, 0);
  457. }
  458. lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block);
  459. }
  460. } else if (arg_type->kind == lbArg_Indirect) {
  461. if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
  462. lbValue ptr = {};
  463. ptr.value = LLVMGetParam(p->value, param_offset+param_index);
  464. ptr.type = alloc_type_pointer(e->type);
  465. lb_add_entity(p->module, e, ptr);
  466. lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block);
  467. }
  468. }
  469. }
  470. }
  471. if (p->type->Proc.has_named_results) {
  472. GB_ASSERT(p->type->Proc.result_count > 0);
  473. TypeTuple *results = &p->type->Proc.results->Tuple;
  474. for_array(i, results->variables) {
  475. Entity *e = results->variables[i];
  476. GB_ASSERT(e->kind == Entity_Variable);
  477. if (e->token.string != "") {
  478. GB_ASSERT(!is_blank_ident(e->token));
  479. lbAddr res = {};
  480. if (return_ptr_value.value) {
  481. lbValue ptr = return_ptr_value;
  482. if (results->variables.count != 1) {
  483. ptr = lb_emit_struct_ep(p, ptr, cast(i32)i);
  484. }
  485. res = lb_addr(ptr);
  486. lb_add_entity(p->module, e, ptr);
  487. } else {
  488. res = lb_add_local(p, e->type, e);
  489. }
  490. if (e->Variable.param_value.kind != ParameterValue_Invalid) {
  491. lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos);
  492. lb_addr_store(p, res, c);
  493. }
  494. }
  495. }
  496. }
  497. }
  498. if (p->type->Proc.calling_convention == ProcCC_Odin) {
  499. lb_push_context_onto_stack_from_implicit_parameter(p);
  500. }
  501. lb_set_debug_position_to_procedure_begin(p);
  502. if (p->debug_info != nullptr) {
  503. if (p->context_stack.count != 0) {
  504. p->curr_block = p->decl_block;
  505. lb_add_debug_context_variable(p, lb_find_or_generate_context_ptr(p));
  506. }
  507. }
  508. lb_start_block(p, p->entry_block);
  509. }
  510. void lb_end_procedure_body(lbProcedure *p) {
  511. lb_set_debug_position_to_procedure_begin(p);
  512. LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
  513. LLVMBuildBr(p->builder, p->entry_block->block);
  514. LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
  515. LLVMValueRef instr = nullptr;
  516. // Make sure there is a "ret void" at the end of a procedure with no return type
  517. if (p->type->Proc.result_count == 0) {
  518. instr = LLVMGetLastInstruction(p->curr_block->block);
  519. if (!lb_is_instr_terminating(instr)) {
  520. lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
  521. lb_set_debug_position_to_procedure_end(p);
  522. LLVMBuildRetVoid(p->builder);
  523. }
  524. }
  525. LLVMBasicBlockRef first_block = LLVMGetFirstBasicBlock(p->value);
  526. LLVMBasicBlockRef block = nullptr;
  527. // Make sure every block terminates, and if not, make it unreachable
  528. for (block = first_block; block != nullptr; block = LLVMGetNextBasicBlock(block)) {
  529. instr = LLVMGetLastInstruction(block);
  530. if (instr == nullptr || !lb_is_instr_terminating(instr)) {
  531. LLVMPositionBuilderAtEnd(p->builder, block);
  532. LLVMBuildUnreachable(p->builder);
  533. }
  534. }
  535. p->curr_block = nullptr;
  536. p->state_flags = 0;
  537. }
  538. void lb_end_procedure(lbProcedure *p) {
  539. LLVMDisposeBuilder(p->builder);
  540. }
  541. void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) {
  542. GB_ASSERT(pd->body != nullptr);
  543. lbModule *m = p->module;
  544. auto *min_dep_set = &m->info->minimum_dependency_set;
  545. if (ptr_set_exists(min_dep_set, e) == false) {
  546. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  547. return;
  548. }
  549. // NOTE(bill): Generate a new name
  550. // parent.name-guid
  551. String original_name = e->token.string;
  552. String pd_name = original_name;
  553. if (e->Procedure.link_name.len > 0) {
  554. pd_name = e->Procedure.link_name;
  555. }
  556. isize name_len = p->name.len + 1 + pd_name.len + 1 + 10 + 1;
  557. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  558. i32 guid = cast(i32)p->children.count;
  559. name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%d", LIT(p->name), LIT(pd_name), guid);
  560. String name = make_string(cast(u8 *)name_text, name_len-1);
  561. e->Procedure.link_name = name;
  562. lbProcedure *nested_proc = lb_create_procedure(p->module, e);
  563. e->code_gen_procedure = nested_proc;
  564. lbValue value = {};
  565. value.value = nested_proc->value;
  566. value.type = nested_proc->type;
  567. lb_add_entity(m, e, value);
  568. array_add(&p->children, nested_proc);
  569. array_add(&m->procedures_to_generate, nested_proc);
  570. }
  571. Array<lbValue> lb_value_to_array(lbProcedure *p, lbValue value) {
  572. Array<lbValue> array = {};
  573. Type *t = base_type(value.type);
  574. if (t == nullptr) {
  575. // Do nothing
  576. } else if (is_type_tuple(t)) {
  577. GB_ASSERT(t->kind == Type_Tuple);
  578. auto *rt = &t->Tuple;
  579. if (rt->variables.count > 0) {
  580. array = array_make<lbValue>(permanent_allocator(), rt->variables.count);
  581. for_array(i, rt->variables) {
  582. lbValue elem = lb_emit_struct_ev(p, value, cast(i32)i);
  583. array[i] = elem;
  584. }
  585. }
  586. } else {
  587. array = array_make<lbValue>(permanent_allocator(), 1);
  588. array[0] = value;
  589. }
  590. return array;
  591. }
  592. 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) {
  593. GB_ASSERT(p->module->ctx == LLVMGetTypeContext(LLVMTypeOf(value.value)));
  594. unsigned arg_count = cast(unsigned)processed_args.count;
  595. if (return_ptr.value != nullptr) {
  596. arg_count += 1;
  597. }
  598. if (context_ptr.addr.value != nullptr) {
  599. arg_count += 1;
  600. }
  601. LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count);
  602. isize arg_index = 0;
  603. if (return_ptr.value != nullptr) {
  604. args[arg_index++] = return_ptr.value;
  605. }
  606. for_array(i, processed_args) {
  607. lbValue arg = processed_args[i];
  608. args[arg_index++] = arg.value;
  609. }
  610. if (context_ptr.addr.value != nullptr) {
  611. LLVMValueRef cp = context_ptr.addr.value;
  612. cp = LLVMBuildPointerCast(p->builder, cp, lb_type(p->module, t_rawptr), "");
  613. args[arg_index++] = cp;
  614. }
  615. LLVMBasicBlockRef curr_block = LLVMGetInsertBlock(p->builder);
  616. GB_ASSERT(curr_block != p->decl_block->block);
  617. {
  618. LLVMTypeRef fnp = lb_type_internal_for_procedures_raw(p->module, value.type);
  619. LLVMTypeRef ftp = LLVMPointerType(fnp, 0);
  620. LLVMValueRef fn = value.value;
  621. if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
  622. fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
  623. }
  624. GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
  625. {
  626. unsigned param_count = LLVMCountParamTypes(fnp);
  627. GB_ASSERT(arg_count >= param_count);
  628. LLVMTypeRef *param_types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, param_count);
  629. LLVMGetParamTypes(fnp, param_types);
  630. for (unsigned i = 0; i < param_count; i++) {
  631. LLVMTypeRef param_type = param_types[i];
  632. LLVMTypeRef arg_type = LLVMTypeOf(args[i]);
  633. // LLVMTypeKind param_kind = LLVMGetTypeKind(param_type);
  634. // LLVMTypeKind arg_kind = LLVMGetTypeKind(arg_type);
  635. GB_ASSERT_MSG(
  636. arg_type == param_type,
  637. "Parameter types do not match: %s != %s, argument: %s",
  638. LLVMPrintTypeToString(arg_type),
  639. LLVMPrintTypeToString(param_type),
  640. LLVMPrintValueToString(args[i])
  641. );
  642. }
  643. }
  644. LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
  645. if (return_ptr.value != nullptr) {
  646. LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0])));
  647. }
  648. switch (inlining) {
  649. case ProcInlining_none:
  650. break;
  651. case ProcInlining_inline:
  652. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "alwaysinline"));
  653. break;
  654. case ProcInlining_no_inline:
  655. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "noinline"));
  656. break;
  657. }
  658. lbValue res = {};
  659. res.value = ret;
  660. res.type = abi_rt;
  661. return res;
  662. }
  663. }
  664. lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name) {
  665. AstPackage *pkg = m->info->runtime_package;
  666. Entity *e = scope_lookup_current(pkg->scope, name);
  667. return lb_find_procedure_value_from_entity(m, e);
  668. }
  669. lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
  670. String name = make_string_c(c_name);
  671. lbValue proc = lb_lookup_runtime_procedure(p->module, name);
  672. return lb_emit_call(p, proc, args);
  673. }
  674. lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
  675. lbValue res = {};
  676. Type *t = val.type;
  677. if (is_type_complex(t)) {
  678. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
  679. lbValue real = lb_emit_struct_ev(p, val, 0);
  680. lbValue imag = lb_emit_struct_ev(p, val, 1);
  681. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  682. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), real);
  683. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), imag);
  684. } else if (is_type_quaternion(t)) {
  685. // @QuaternionLayout
  686. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
  687. lbValue real = lb_emit_struct_ev(p, val, 3);
  688. lbValue imag = lb_emit_struct_ev(p, val, 0);
  689. lbValue jmag = lb_emit_struct_ev(p, val, 1);
  690. lbValue kmag = lb_emit_struct_ev(p, val, 2);
  691. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  692. jmag = lb_emit_unary_arith(p, Token_Sub, jmag, jmag.type);
  693. kmag = lb_emit_unary_arith(p, Token_Sub, kmag, kmag.type);
  694. lb_emit_store(p, lb_emit_struct_ep(p, res, 3), real);
  695. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), imag);
  696. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), jmag);
  697. lb_emit_store(p, lb_emit_struct_ep(p, res, 2), kmag);
  698. } else if (is_type_array_like(t)) {
  699. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true));
  700. Type *elem_type = base_array_type(t);
  701. i64 count = get_array_type_count(t);
  702. for (i64 i = 0; i < count; i++) {
  703. lbValue dst = lb_emit_array_epi(p, res, i);
  704. lbValue elem = lb_emit_struct_ev(p, val, cast(i32)i);
  705. elem = lb_emit_conjugate(p, elem, elem_type);
  706. lb_emit_store(p, dst, elem);
  707. }
  708. } else if (is_type_matrix(t)) {
  709. Type *mt = base_type(t);
  710. GB_ASSERT(mt->kind == Type_Matrix);
  711. Type *elem_type = mt->Matrix.elem;
  712. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true));
  713. for (i64 j = 0; j < mt->Matrix.column_count; j++) {
  714. for (i64 i = 0; i < mt->Matrix.row_count; i++) {
  715. lbValue dst = lb_emit_matrix_epi(p, res, i, j);
  716. lbValue elem = lb_emit_matrix_ev(p, val, i, j);
  717. elem = lb_emit_conjugate(p, elem, elem_type);
  718. lb_emit_store(p, dst, elem);
  719. }
  720. }
  721. }
  722. return lb_emit_load(p, res);
  723. }
  724. lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining, bool use_copy_elision_hint) {
  725. lbModule *m = p->module;
  726. Type *pt = base_type(value.type);
  727. GB_ASSERT(pt->kind == Type_Proc);
  728. Type *results = pt->Proc.results;
  729. lbAddr context_ptr = {};
  730. if (pt->Proc.calling_convention == ProcCC_Odin) {
  731. context_ptr = lb_find_or_generate_context_ptr(p);
  732. }
  733. defer (if (pt->Proc.diverging) {
  734. LLVMBuildUnreachable(p->builder);
  735. });
  736. bool is_c_vararg = pt->Proc.c_vararg;
  737. isize param_count = pt->Proc.param_count;
  738. if (is_c_vararg) {
  739. GB_ASSERT(param_count-1 <= args.count);
  740. param_count -= 1;
  741. } else {
  742. GB_ASSERT_MSG(param_count == args.count, "%td == %td", param_count, args.count);
  743. }
  744. lbValue result = {};
  745. auto processed_args = array_make<lbValue>(permanent_allocator(), 0, args.count);
  746. {
  747. lbFunctionType *ft = lb_get_function_type(m, p, pt);
  748. bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
  749. unsigned param_index = 0;
  750. for (isize i = 0; i < param_count; i++) {
  751. Entity *e = pt->Proc.params->Tuple.variables[i];
  752. if (e->kind != Entity_Variable) {
  753. continue;
  754. }
  755. GB_ASSERT(e->flags & EntityFlag_Param);
  756. Type *original_type = e->type;
  757. lbArgType *arg = &ft->args[param_index];
  758. if (arg->kind == lbArg_Ignore) {
  759. continue;
  760. }
  761. lbValue x = lb_emit_conv(p, args[i], original_type);
  762. LLVMTypeRef xt = lb_type(p->module, x.type);
  763. if (arg->kind == lbArg_Direct) {
  764. LLVMTypeRef abi_type = arg->cast_type;
  765. if (!abi_type) {
  766. abi_type = arg->type;
  767. }
  768. if (xt == abi_type) {
  769. array_add(&processed_args, x);
  770. } else {
  771. x.value = OdinLLVMBuildTransmute(p, x.value, abi_type);
  772. array_add(&processed_args, x);
  773. }
  774. } else if (arg->kind == lbArg_Indirect) {
  775. lbValue ptr = {};
  776. if (arg->is_byval) {
  777. ptr = lb_copy_value_to_ptr(p, x, original_type, arg->byval_alignment);
  778. } else if (is_calling_convention_odin(pt->Proc.calling_convention)) {
  779. // NOTE(bill): Odin parameters are immutable so the original value can be passed if possible
  780. // i.e. `T const &` in C++
  781. ptr = lb_address_from_load_or_generate_local(p, x);
  782. } else {
  783. ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
  784. }
  785. array_add(&processed_args, ptr);
  786. }
  787. param_index += 1;
  788. }
  789. if (is_c_vararg) {
  790. for (isize i = processed_args.count; i < args.count; i++) {
  791. array_add(&processed_args, args[i]);
  792. }
  793. }
  794. if (inlining == ProcInlining_none) {
  795. inlining = p->inlining;
  796. }
  797. Type *rt = reduce_tuple_to_single_type(results);
  798. if (return_by_pointer) {
  799. lbValue return_ptr = {};
  800. if (use_copy_elision_hint && p->copy_elision_hint.ptr.value != nullptr) {
  801. if (are_types_identical(type_deref(p->copy_elision_hint.ptr.type), rt)) {
  802. return_ptr = lb_consume_copy_elision_hint(p);
  803. }
  804. }
  805. if (return_ptr.value == nullptr) {
  806. lbAddr r = lb_add_local_generated(p, rt, true);
  807. return_ptr = r.addr;
  808. }
  809. GB_ASSERT(is_type_pointer(return_ptr.type));
  810. lb_emit_call_internal(p, value, return_ptr, processed_args, nullptr, context_ptr, inlining);
  811. result = lb_emit_load(p, return_ptr);
  812. } else if (rt != nullptr) {
  813. result = lb_emit_call_internal(p, value, {}, processed_args, rt, context_ptr, inlining);
  814. if (ft->ret.cast_type) {
  815. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.cast_type);
  816. }
  817. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.type);
  818. result.type = rt;
  819. if (LLVMTypeOf(result.value) == LLVMInt1TypeInContext(p->module->ctx)) {
  820. result.type = t_llvm_bool;
  821. }
  822. if (!is_type_tuple(rt)) {
  823. result = lb_emit_conv(p, result, rt);
  824. }
  825. } else {
  826. lb_emit_call_internal(p, value, {}, processed_args, nullptr, context_ptr, inlining);
  827. }
  828. }
  829. Entity **found = map_get(&p->module->procedure_values, value.value);
  830. if (found != nullptr) {
  831. Entity *e = *found;
  832. if (e != nullptr && entity_has_deferred_procedure(e)) {
  833. DeferredProcedureKind kind = e->Procedure.deferred_procedure.kind;
  834. Entity *deferred_entity = e->Procedure.deferred_procedure.entity;
  835. lbValue deferred = lb_find_procedure_value_from_entity(p->module, deferred_entity);
  836. auto in_args = args;
  837. Array<lbValue> result_as_args = {};
  838. switch (kind) {
  839. case DeferredProcedure_none:
  840. break;
  841. case DeferredProcedure_in:
  842. result_as_args = in_args;
  843. break;
  844. case DeferredProcedure_out:
  845. result_as_args = lb_value_to_array(p, result);
  846. break;
  847. case DeferredProcedure_in_out:
  848. {
  849. auto out_args = lb_value_to_array(p, result);
  850. array_init(&result_as_args, permanent_allocator(), in_args.count + out_args.count);
  851. array_copy(&result_as_args, in_args, 0);
  852. array_copy(&result_as_args, out_args, in_args.count);
  853. }
  854. break;
  855. }
  856. lb_add_defer_proc(p, p->scope_index, deferred, result_as_args);
  857. }
  858. }
  859. return result;
  860. }
  861. LLVMValueRef llvm_splat_float(i64 count, LLVMTypeRef type, f64 value) {
  862. LLVMValueRef v = LLVMConstReal(type, value);
  863. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
  864. for (i64 i = 0; i < count; i++) {
  865. values[i] = v;
  866. }
  867. return LLVMConstVector(values, cast(unsigned)count);
  868. }
  869. LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) {
  870. LLVMValueRef v = LLVMConstInt(type, value, is_signed);
  871. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
  872. for (i64 i = 0; i < count; i++) {
  873. values[i] = v;
  874. }
  875. return LLVMConstVector(values, cast(unsigned)count);
  876. }
  877. lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId builtin_id) {
  878. ast_node(ce, CallExpr, expr);
  879. lbModule *m = p->module;
  880. lbValue res = {};
  881. res.type = tv.type;
  882. lbValue arg0 = {}; if (ce->args.count > 0) arg0 = lb_build_expr(p, ce->args[0]);
  883. lbValue arg1 = {}; if (ce->args.count > 1) arg1 = lb_build_expr(p, ce->args[1]);
  884. lbValue arg2 = {}; if (ce->args.count > 2) arg2 = lb_build_expr(p, ce->args[2]);
  885. Type *elem = base_array_type(arg0.type);
  886. bool is_float = is_type_float(elem);
  887. bool is_signed = !is_type_unsigned(elem);
  888. LLVMOpcode op_code = cast(LLVMOpcode)0;
  889. switch (builtin_id) {
  890. case BuiltinProc_simd_add:
  891. case BuiltinProc_simd_sub:
  892. case BuiltinProc_simd_mul:
  893. case BuiltinProc_simd_div:
  894. case BuiltinProc_simd_rem:
  895. if (is_float) {
  896. switch (builtin_id) {
  897. case BuiltinProc_simd_add: op_code = LLVMFAdd; break;
  898. case BuiltinProc_simd_sub: op_code = LLVMFSub; break;
  899. case BuiltinProc_simd_mul: op_code = LLVMFMul; break;
  900. case BuiltinProc_simd_div: op_code = LLVMFDiv; break;
  901. }
  902. } else {
  903. switch (builtin_id) {
  904. case BuiltinProc_simd_add: op_code = LLVMAdd; break;
  905. case BuiltinProc_simd_sub: op_code = LLVMSub; break;
  906. case BuiltinProc_simd_mul: op_code = LLVMMul; break;
  907. case BuiltinProc_simd_div:
  908. if (is_signed) {
  909. op_code = LLVMSDiv;
  910. } else {
  911. op_code = LLVMUDiv;
  912. }
  913. break;
  914. case BuiltinProc_simd_rem:
  915. if (is_signed) {
  916. op_code = LLVMSRem;
  917. } else {
  918. op_code = LLVMURem;
  919. }
  920. break;
  921. }
  922. }
  923. if (op_code) {
  924. res.value = LLVMBuildBinOp(p->builder, op_code, arg0.value, arg1.value, "");
  925. return res;
  926. }
  927. break;
  928. case BuiltinProc_simd_shl: // Odin logic
  929. case BuiltinProc_simd_shr: // Odin logic
  930. case BuiltinProc_simd_shl_masked: // C logic
  931. case BuiltinProc_simd_shr_masked: // C logic
  932. {
  933. i64 sz = type_size_of(elem);
  934. GB_ASSERT(arg0.type->kind == Type_SimdVector);
  935. i64 count = arg0.type->SimdVector.count;
  936. Type *elem1 = base_array_type(arg1.type);
  937. bool is_masked = false;
  938. switch (builtin_id) {
  939. case BuiltinProc_simd_shl: op_code = LLVMShl; is_masked = false; break;
  940. case BuiltinProc_simd_shr: op_code = is_signed ? LLVMAShr : LLVMLShr; is_masked = false; break;
  941. case BuiltinProc_simd_shl_masked: op_code = LLVMShl; is_masked = true; break;
  942. case BuiltinProc_simd_shr_masked: op_code = is_signed ? LLVMAShr : LLVMLShr; is_masked = true; break;
  943. }
  944. if (op_code) {
  945. LLVMValueRef bits = llvm_splat_int(count, lb_type(m, elem1), sz*8 - 1);
  946. if (is_masked) {
  947. // C logic
  948. LLVMValueRef shift = LLVMBuildAnd(p->builder, arg1.value, bits, "");
  949. res.value = LLVMBuildBinOp(p->builder, op_code, arg0.value, shift, "");
  950. } else {
  951. // Odin logic
  952. LLVMValueRef zero = lb_const_nil(m, arg1.type).value;
  953. LLVMValueRef mask = LLVMBuildICmp(p->builder, LLVMIntULE, arg1.value, bits, "");
  954. LLVMValueRef shift = LLVMBuildBinOp(p->builder, op_code, arg0.value, arg1.value, "");
  955. res.value = LLVMBuildSelect(p->builder, mask, shift, zero, "");
  956. }
  957. return res;
  958. }
  959. }
  960. break;
  961. case BuiltinProc_simd_and:
  962. case BuiltinProc_simd_or:
  963. case BuiltinProc_simd_xor:
  964. case BuiltinProc_simd_and_not:
  965. switch (builtin_id) {
  966. case BuiltinProc_simd_and: op_code = LLVMAnd; break;
  967. case BuiltinProc_simd_or: op_code = LLVMOr; break;
  968. case BuiltinProc_simd_xor: op_code = LLVMXor; break;
  969. case BuiltinProc_simd_and_not:
  970. op_code = LLVMAnd;
  971. arg1.value = LLVMBuildNot(p->builder, arg1.value, "");
  972. break;
  973. }
  974. if (op_code) {
  975. res.value = LLVMBuildBinOp(p->builder, op_code, arg0.value, arg1.value, "");
  976. return res;
  977. }
  978. break;
  979. case BuiltinProc_simd_neg:
  980. if (is_float) {
  981. res.value = LLVMBuildFNeg(p->builder, arg0.value, "");
  982. } else {
  983. res.value = LLVMBuildNeg(p->builder, arg0.value, "");
  984. }
  985. return res;
  986. case BuiltinProc_simd_abs:
  987. if (is_float) {
  988. LLVMValueRef pos = arg0.value;
  989. LLVMValueRef neg = LLVMBuildFNeg(p->builder, pos, "");
  990. LLVMValueRef cond = LLVMBuildFCmp(p->builder, LLVMRealOGT, pos, neg, "");
  991. res.value = LLVMBuildSelect(p->builder, cond, pos, neg, "");
  992. } else {
  993. LLVMValueRef pos = arg0.value;
  994. LLVMValueRef neg = LLVMBuildNeg(p->builder, pos, "");
  995. LLVMValueRef cond = LLVMBuildICmp(p->builder, is_signed ? LLVMIntSGT : LLVMIntUGT, pos, neg, "");
  996. res.value = LLVMBuildSelect(p->builder, cond, pos, neg, "");
  997. }
  998. return res;
  999. case BuiltinProc_simd_min:
  1000. if (is_float) {
  1001. LLVMValueRef cond = LLVMBuildFCmp(p->builder, LLVMRealOLT, arg0.value, arg1.value, "");
  1002. res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");
  1003. } else {
  1004. LLVMValueRef cond = LLVMBuildICmp(p->builder, is_signed ? LLVMIntSLT : LLVMIntULT, arg0.value, arg1.value, "");
  1005. res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");
  1006. }
  1007. return res;
  1008. case BuiltinProc_simd_max:
  1009. if (is_float) {
  1010. LLVMValueRef cond = LLVMBuildFCmp(p->builder, LLVMRealOGT, arg0.value, arg1.value, "");
  1011. res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");
  1012. } else {
  1013. LLVMValueRef cond = LLVMBuildICmp(p->builder, is_signed ? LLVMIntSGT : LLVMIntUGT, arg0.value, arg1.value, "");
  1014. res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");
  1015. }
  1016. return res;
  1017. case BuiltinProc_simd_lanes_eq:
  1018. case BuiltinProc_simd_lanes_ne:
  1019. case BuiltinProc_simd_lanes_lt:
  1020. case BuiltinProc_simd_lanes_le:
  1021. case BuiltinProc_simd_lanes_gt:
  1022. case BuiltinProc_simd_lanes_ge:
  1023. if (is_float) {
  1024. LLVMRealPredicate pred = cast(LLVMRealPredicate)0;
  1025. switch (builtin_id) {
  1026. case BuiltinProc_simd_lanes_eq: pred = LLVMRealOEQ; break;
  1027. case BuiltinProc_simd_lanes_ne: pred = LLVMRealONE; break;
  1028. case BuiltinProc_simd_lanes_lt: pred = LLVMRealOLT; break;
  1029. case BuiltinProc_simd_lanes_le: pred = LLVMRealOLE; break;
  1030. case BuiltinProc_simd_lanes_gt: pred = LLVMRealOGT; break;
  1031. case BuiltinProc_simd_lanes_ge: pred = LLVMRealOGE; break;
  1032. }
  1033. if (pred) {
  1034. res.value = LLVMBuildFCmp(p->builder, pred, arg0.value, arg1.value, "");
  1035. res.value = LLVMBuildSExtOrBitCast(p->builder, res.value, lb_type(m, tv.type), "");
  1036. return res;
  1037. }
  1038. } else {
  1039. LLVMIntPredicate pred = cast(LLVMIntPredicate)0;
  1040. switch (builtin_id) {
  1041. case BuiltinProc_simd_lanes_eq: pred = LLVMIntEQ; break;
  1042. case BuiltinProc_simd_lanes_ne: pred = LLVMIntNE; break;
  1043. case BuiltinProc_simd_lanes_lt: pred = is_signed ? LLVMIntSLT :LLVMIntULT; break;
  1044. case BuiltinProc_simd_lanes_le: pred = is_signed ? LLVMIntSLE :LLVMIntULE; break;
  1045. case BuiltinProc_simd_lanes_gt: pred = is_signed ? LLVMIntSGT :LLVMIntUGT; break;
  1046. case BuiltinProc_simd_lanes_ge: pred = is_signed ? LLVMIntSGE :LLVMIntUGE; break;
  1047. }
  1048. if (pred) {
  1049. res.value = LLVMBuildICmp(p->builder, pred, arg0.value, arg1.value, "");
  1050. res.value = LLVMBuildSExtOrBitCast(p->builder, res.value, lb_type(m, tv.type), "");
  1051. return res;
  1052. }
  1053. }
  1054. break;
  1055. case BuiltinProc_simd_extract:
  1056. res.value = LLVMBuildExtractElement(p->builder, arg0.value, arg1.value, "");
  1057. return res;
  1058. case BuiltinProc_simd_replace:
  1059. res.value = LLVMBuildInsertElement(p->builder, arg0.value, arg2.value, arg1.value, "");
  1060. return res;
  1061. case BuiltinProc_simd_reduce_add_ordered:
  1062. case BuiltinProc_simd_reduce_mul_ordered:
  1063. {
  1064. LLVMTypeRef llvm_elem = lb_type(m, elem);
  1065. LLVMValueRef args[2] = {};
  1066. isize args_count = 0;
  1067. char const *name = nullptr;
  1068. switch (builtin_id) {
  1069. case BuiltinProc_simd_reduce_add_ordered:
  1070. if (is_float) {
  1071. name = "llvm.vector.reduce.fadd";
  1072. args[args_count++] = LLVMConstReal(llvm_elem, 0.0);
  1073. } else {
  1074. name = "llvm.vector.reduce.add";
  1075. }
  1076. break;
  1077. case BuiltinProc_simd_reduce_mul_ordered:
  1078. if (is_float) {
  1079. name = "llvm.vector.reduce.fmul";
  1080. args[args_count++] = LLVMConstReal(llvm_elem, 1.0);
  1081. } else {
  1082. name = "llvm.vector.reduce.mul";
  1083. }
  1084. break;
  1085. }
  1086. args[args_count++] = arg0.value;
  1087. LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
  1088. res.value = lb_call_intrinsic(p, name, args, cast(unsigned)args_count, types, gb_count_of(types));
  1089. return res;
  1090. }
  1091. case BuiltinProc_simd_reduce_min:
  1092. case BuiltinProc_simd_reduce_max:
  1093. case BuiltinProc_simd_reduce_and:
  1094. case BuiltinProc_simd_reduce_or:
  1095. case BuiltinProc_simd_reduce_xor:
  1096. {
  1097. char const *name = nullptr;
  1098. switch (builtin_id) {
  1099. case BuiltinProc_simd_reduce_min:
  1100. if (is_float) {
  1101. name = "llvm.vector.reduce.fmin";
  1102. } else if (is_signed) {
  1103. name = "llvm.vector.reduce.smin";
  1104. } else {
  1105. name = "llvm.vector.reduce.umin";
  1106. }
  1107. break;
  1108. case BuiltinProc_simd_reduce_max:
  1109. if (is_float) {
  1110. name = "llvm.vector.reduce.fmax";
  1111. } else if (is_signed) {
  1112. name = "llvm.vector.reduce.smax";
  1113. } else {
  1114. name = "llvm.vector.reduce.umax";
  1115. }
  1116. break;
  1117. case BuiltinProc_simd_reduce_and: name = "llvm.vector.reduce.and"; break;
  1118. case BuiltinProc_simd_reduce_or: name = "llvm.vector.reduce.or"; break;
  1119. case BuiltinProc_simd_reduce_xor: name = "llvm.vector.reduce.xor"; break;
  1120. }
  1121. LLVMTypeRef types[1] = { lb_type(p->module, arg0.type) };
  1122. LLVMValueRef args[1] = { arg0.value };
  1123. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1124. return res;
  1125. }
  1126. case BuiltinProc_simd_shuffle:
  1127. {
  1128. Type *vt = arg0.type;
  1129. GB_ASSERT(vt->kind == Type_SimdVector);
  1130. i64 indices_count = ce->args.count-2;
  1131. i64 max_count = vt->SimdVector.count*2;
  1132. GB_ASSERT(indices_count <= max_count);
  1133. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, indices_count);
  1134. for (isize i = 0; i < indices_count; i++) {
  1135. lbValue idx = lb_build_expr(p, ce->args[i+2]);
  1136. GB_ASSERT(LLVMIsConstant(idx.value));
  1137. values[i] = idx.value;
  1138. }
  1139. LLVMValueRef indices = LLVMConstVector(values, cast(unsigned)indices_count);
  1140. res.value = LLVMBuildShuffleVector(p->builder, arg0.value, arg1.value, indices, "");
  1141. return res;
  1142. }
  1143. case BuiltinProc_simd_select:
  1144. {
  1145. LLVMValueRef cond = arg0.value;
  1146. LLVMValueRef x = lb_build_expr(p, ce->args[1]).value;
  1147. LLVMValueRef y = lb_build_expr(p, ce->args[2]).value;
  1148. cond = LLVMBuildICmp(p->builder, LLVMIntNE, cond, LLVMConstNull(LLVMTypeOf(cond)), "");
  1149. res.value = LLVMBuildSelect(p->builder, cond, x, y, "");
  1150. return res;
  1151. }
  1152. case BuiltinProc_simd_ceil:
  1153. case BuiltinProc_simd_floor:
  1154. case BuiltinProc_simd_trunc:
  1155. case BuiltinProc_simd_nearest:
  1156. {
  1157. char const *name = nullptr;
  1158. switch (builtin_id) {
  1159. case BuiltinProc_simd_ceil: name = "llvm.ceil"; break;
  1160. case BuiltinProc_simd_floor: name = "llvm.floor"; break;
  1161. case BuiltinProc_simd_trunc: name = "llvm.trunc"; break;
  1162. case BuiltinProc_simd_nearest: name = "llvm.nearbyint"; break;
  1163. }
  1164. LLVMTypeRef types[1] = { lb_type(p->module, arg0.type) };
  1165. LLVMValueRef args[1] = { arg0.value };
  1166. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1167. return res;
  1168. }
  1169. case BuiltinProc_simd_lanes_reverse:
  1170. {
  1171. i64 count = get_array_type_count(arg0.type);
  1172. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
  1173. LLVMTypeRef llvm_u32 = lb_type(m, t_u32);
  1174. for (i64 i = 0; i < count; i++) {
  1175. values[i] = LLVMConstInt(llvm_u32, count-1-i, false);
  1176. }
  1177. LLVMValueRef mask = LLVMConstVector(values, cast(unsigned)count);
  1178. LLVMValueRef v = arg0.value;
  1179. res.value = LLVMBuildShuffleVector(p->builder, v, v, mask, "");
  1180. return res;
  1181. }
  1182. case BuiltinProc_simd_lanes_rotate_left:
  1183. case BuiltinProc_simd_lanes_rotate_right:
  1184. {
  1185. i64 count = get_array_type_count(arg0.type);
  1186. GB_ASSERT(is_power_of_two(count));
  1187. BigInt bi_count = {};
  1188. big_int_from_i64(&bi_count, count);
  1189. TypeAndValue const &tv = ce->args[1]->tav;
  1190. ExactValue val = exact_value_to_integer(tv.value);
  1191. GB_ASSERT(val.kind == ExactValue_Integer);
  1192. BigInt *bi = &val.value_integer;
  1193. if (builtin_id == BuiltinProc_simd_lanes_rotate_right) {
  1194. big_int_neg(bi, bi);
  1195. }
  1196. big_int_rem(bi, bi, &bi_count);
  1197. big_int_dealloc(&bi_count);
  1198. i64 left = big_int_to_i64(bi);
  1199. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count);
  1200. LLVMTypeRef llvm_u32 = lb_type(m, t_u32);
  1201. for (i64 i = 0; i < count; i++) {
  1202. u64 idx = cast(u64)(i+left) & cast(u64)(count-1);
  1203. values[i] = LLVMConstInt(llvm_u32, idx, false);
  1204. }
  1205. LLVMValueRef mask = LLVMConstVector(values, cast(unsigned)count);
  1206. LLVMValueRef v = arg0.value;
  1207. res.value = LLVMBuildShuffleVector(p->builder, v, v, mask, "");
  1208. return res;
  1209. }
  1210. case BuiltinProc_simd_add_sat:
  1211. case BuiltinProc_simd_sub_sat:
  1212. {
  1213. char const *name = nullptr;
  1214. switch (builtin_id) {
  1215. case BuiltinProc_simd_add_sat: name = is_signed ? "llvm.sadd.sat" : "llvm.uadd.sat"; break;
  1216. case BuiltinProc_simd_sub_sat: name = is_signed ? "llvm.ssub.sat" : "llvm.usub.sat"; break;
  1217. }
  1218. LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
  1219. LLVMValueRef args[2] = { arg0.value, arg1.value };
  1220. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1221. return res;
  1222. }
  1223. case BuiltinProc_simd_clamp:
  1224. {
  1225. LLVMValueRef v = arg0.value;
  1226. LLVMValueRef min = arg1.value;
  1227. LLVMValueRef max = arg2.value;
  1228. if (is_float) {
  1229. v = LLVMBuildSelect(p->builder, LLVMBuildFCmp(p->builder, LLVMRealOLT, v, min, ""), min, v, "");
  1230. res.value = LLVMBuildSelect(p->builder, LLVMBuildFCmp(p->builder, LLVMRealOGT, v, max, ""), max, v, "");
  1231. } else if (is_signed) {
  1232. v = LLVMBuildSelect(p->builder, LLVMBuildICmp(p->builder, LLVMIntSLT, v, min, ""), min, v, "");
  1233. res.value = LLVMBuildSelect(p->builder, LLVMBuildICmp(p->builder, LLVMIntSGT, v, max, ""), max, v, "");
  1234. } else {
  1235. v = LLVMBuildSelect(p->builder, LLVMBuildICmp(p->builder, LLVMIntULT, v, min, ""), min, v, "");
  1236. res.value = LLVMBuildSelect(p->builder, LLVMBuildICmp(p->builder, LLVMIntUGT, v, max, ""), max, v, "");
  1237. }
  1238. return res;
  1239. }
  1240. case BuiltinProc_simd_to_bits:
  1241. {
  1242. res.value = LLVMBuildBitCast(p->builder, arg0.value, lb_type(m, tv.type), "");
  1243. return res;
  1244. }
  1245. }
  1246. GB_PANIC("Unhandled simd intrinsic: '%.*s'", LIT(builtin_procs[builtin_id].name));
  1247. return {};
  1248. }
  1249. lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId id) {
  1250. ast_node(ce, CallExpr, expr);
  1251. if (BuiltinProc__simd_begin < id && id < BuiltinProc__simd_end) {
  1252. return lb_build_builtin_simd_proc(p, expr, tv, id);
  1253. }
  1254. switch (id) {
  1255. case BuiltinProc_DIRECTIVE: {
  1256. ast_node(bd, BasicDirective, ce->proc);
  1257. String name = bd->name.string;
  1258. GB_ASSERT(name == "location");
  1259. String procedure = p->entity->token.string;
  1260. TokenPos pos = ast_token(ce->proc).pos;
  1261. if (ce->args.count > 0) {
  1262. Ast *ident = unselector_expr(ce->args[0]);
  1263. GB_ASSERT(ident->kind == Ast_Ident);
  1264. Entity *e = entity_of_node(ident);
  1265. GB_ASSERT(e != nullptr);
  1266. if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity != nullptr) {
  1267. procedure = e->parent_proc_decl->entity->token.string;
  1268. } else {
  1269. procedure = str_lit("");
  1270. }
  1271. pos = e->token.pos;
  1272. }
  1273. return lb_emit_source_code_location(p, procedure, pos);
  1274. }
  1275. case BuiltinProc_type_info_of: {
  1276. Ast *arg = ce->args[0];
  1277. TypeAndValue tav = type_and_value_of_expr(arg);
  1278. if (tav.mode == Addressing_Type) {
  1279. Type *t = default_type(type_of_expr(arg));
  1280. return lb_type_info(p->module, t);
  1281. }
  1282. GB_ASSERT(is_type_typeid(tav.type));
  1283. auto args = array_make<lbValue>(permanent_allocator(), 1);
  1284. args[0] = lb_build_expr(p, arg);
  1285. return lb_emit_runtime_call(p, "__type_info_of", args);
  1286. }
  1287. case BuiltinProc_typeid_of: {
  1288. Ast *arg = ce->args[0];
  1289. TypeAndValue tav = type_and_value_of_expr(arg);
  1290. GB_ASSERT(tav.mode == Addressing_Type);
  1291. Type *t = default_type(type_of_expr(arg));
  1292. return lb_typeid(p->module, t);
  1293. }
  1294. case BuiltinProc_len: {
  1295. lbValue v = lb_build_expr(p, ce->args[0]);
  1296. Type *t = base_type(v.type);
  1297. if (is_type_pointer(t)) {
  1298. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  1299. v = lb_emit_load(p, v);
  1300. t = type_deref(t);
  1301. }
  1302. if (is_type_cstring(t)) {
  1303. return lb_cstring_len(p, v);
  1304. } else if (is_type_string(t)) {
  1305. return lb_string_len(p, v);
  1306. } else if (is_type_array(t)) {
  1307. GB_PANIC("Array lengths are constant");
  1308. } else if (is_type_slice(t) || is_type_relative_slice(t)) {
  1309. return lb_slice_len(p, v);
  1310. } else if (is_type_dynamic_array(t)) {
  1311. return lb_dynamic_array_len(p, v);
  1312. } else if (is_type_map(t)) {
  1313. return lb_map_len(p, v);
  1314. } else if (is_type_soa_struct(t)) {
  1315. return lb_soa_struct_len(p, v);
  1316. }
  1317. GB_PANIC("Unreachable");
  1318. break;
  1319. }
  1320. case BuiltinProc_cap: {
  1321. lbValue v = lb_build_expr(p, ce->args[0]);
  1322. Type *t = base_type(v.type);
  1323. if (is_type_pointer(t)) {
  1324. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  1325. v = lb_emit_load(p, v);
  1326. t = type_deref(t);
  1327. }
  1328. if (is_type_string(t)) {
  1329. GB_PANIC("Unreachable");
  1330. } else if (is_type_array(t)) {
  1331. GB_PANIC("Array lengths are constant");
  1332. } else if (is_type_slice(t) || is_type_relative_slice(t)) {
  1333. return lb_slice_len(p, v);
  1334. } else if (is_type_dynamic_array(t)) {
  1335. return lb_dynamic_array_cap(p, v);
  1336. } else if (is_type_map(t)) {
  1337. return lb_map_cap(p, v);
  1338. } else if (is_type_soa_struct(t)) {
  1339. return lb_soa_struct_cap(p, v);
  1340. }
  1341. GB_PANIC("Unreachable");
  1342. break;
  1343. }
  1344. case BuiltinProc_swizzle: {
  1345. isize index_count = ce->args.count-1;
  1346. if (is_type_simd_vector(tv.type)) {
  1347. lbValue vec = lb_build_expr(p, ce->args[0]);
  1348. if (index_count == 0) {
  1349. return vec;
  1350. }
  1351. unsigned mask_len = cast(unsigned)index_count;
  1352. LLVMValueRef *mask_elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, index_count);
  1353. for (isize i = 1; i < ce->args.count; i++) {
  1354. TypeAndValue tv = type_and_value_of_expr(ce->args[i]);
  1355. GB_ASSERT(is_type_integer(tv.type));
  1356. GB_ASSERT(tv.value.kind == ExactValue_Integer);
  1357. u32 index = cast(u32)big_int_to_i64(&tv.value.value_integer);
  1358. mask_elems[i-1] = LLVMConstInt(lb_type(p->module, t_u32), index, false);
  1359. }
  1360. LLVMValueRef mask = LLVMConstVector(mask_elems, mask_len);
  1361. LLVMValueRef v1 = vec.value;
  1362. LLVMValueRef v2 = vec.value;
  1363. lbValue res = {};
  1364. res.type = tv.type;
  1365. res.value = LLVMBuildShuffleVector(p->builder, v1, v2, mask, "");
  1366. return res;
  1367. }
  1368. lbAddr addr = lb_build_array_swizzle_addr(p, ce, tv);
  1369. return lb_addr_load(p, addr);
  1370. }
  1371. case BuiltinProc_complex: {
  1372. lbValue real = lb_build_expr(p, ce->args[0]);
  1373. lbValue imag = lb_build_expr(p, ce->args[1]);
  1374. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  1375. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  1376. Type *ft = base_complex_elem_type(tv.type);
  1377. real = lb_emit_conv(p, real, ft);
  1378. imag = lb_emit_conv(p, imag, ft);
  1379. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), real);
  1380. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), imag);
  1381. return lb_emit_load(p, dst);
  1382. }
  1383. case BuiltinProc_quaternion: {
  1384. lbValue real = lb_build_expr(p, ce->args[0]);
  1385. lbValue imag = lb_build_expr(p, ce->args[1]);
  1386. lbValue jmag = lb_build_expr(p, ce->args[2]);
  1387. lbValue kmag = lb_build_expr(p, ce->args[3]);
  1388. // @QuaternionLayout
  1389. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  1390. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  1391. Type *ft = base_complex_elem_type(tv.type);
  1392. real = lb_emit_conv(p, real, ft);
  1393. imag = lb_emit_conv(p, imag, ft);
  1394. jmag = lb_emit_conv(p, jmag, ft);
  1395. kmag = lb_emit_conv(p, kmag, ft);
  1396. lb_emit_store(p, lb_emit_struct_ep(p, dst, 3), real);
  1397. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), imag);
  1398. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), jmag);
  1399. lb_emit_store(p, lb_emit_struct_ep(p, dst, 2), kmag);
  1400. return lb_emit_load(p, dst);
  1401. }
  1402. case BuiltinProc_real: {
  1403. lbValue val = lb_build_expr(p, ce->args[0]);
  1404. if (is_type_complex(val.type)) {
  1405. lbValue real = lb_emit_struct_ev(p, val, 0);
  1406. return lb_emit_conv(p, real, tv.type);
  1407. } else if (is_type_quaternion(val.type)) {
  1408. // @QuaternionLayout
  1409. lbValue real = lb_emit_struct_ev(p, val, 3);
  1410. return lb_emit_conv(p, real, tv.type);
  1411. }
  1412. GB_PANIC("invalid type for real");
  1413. return {};
  1414. }
  1415. case BuiltinProc_imag: {
  1416. lbValue val = lb_build_expr(p, ce->args[0]);
  1417. if (is_type_complex(val.type)) {
  1418. lbValue imag = lb_emit_struct_ev(p, val, 1);
  1419. return lb_emit_conv(p, imag, tv.type);
  1420. } else if (is_type_quaternion(val.type)) {
  1421. // @QuaternionLayout
  1422. lbValue imag = lb_emit_struct_ev(p, val, 0);
  1423. return lb_emit_conv(p, imag, tv.type);
  1424. }
  1425. GB_PANIC("invalid type for imag");
  1426. return {};
  1427. }
  1428. case BuiltinProc_jmag: {
  1429. lbValue val = lb_build_expr(p, ce->args[0]);
  1430. if (is_type_quaternion(val.type)) {
  1431. // @QuaternionLayout
  1432. lbValue imag = lb_emit_struct_ev(p, val, 1);
  1433. return lb_emit_conv(p, imag, tv.type);
  1434. }
  1435. GB_PANIC("invalid type for jmag");
  1436. return {};
  1437. }
  1438. case BuiltinProc_kmag: {
  1439. lbValue val = lb_build_expr(p, ce->args[0]);
  1440. if (is_type_quaternion(val.type)) {
  1441. // @QuaternionLayout
  1442. lbValue imag = lb_emit_struct_ev(p, val, 2);
  1443. return lb_emit_conv(p, imag, tv.type);
  1444. }
  1445. GB_PANIC("invalid type for kmag");
  1446. return {};
  1447. }
  1448. case BuiltinProc_conj: {
  1449. lbValue val = lb_build_expr(p, ce->args[0]);
  1450. return lb_emit_conjugate(p, val, tv.type);
  1451. }
  1452. case BuiltinProc_expand_to_tuple: {
  1453. lbValue val = lb_build_expr(p, ce->args[0]);
  1454. Type *t = base_type(val.type);
  1455. if (!is_type_tuple(tv.type)) {
  1456. if (t->kind == Type_Struct) {
  1457. GB_ASSERT(t->Struct.fields.count == 1);
  1458. return lb_emit_struct_ev(p, val, 0);
  1459. } else if (t->kind == Type_Array) {
  1460. GB_ASSERT(t->Array.count == 1);
  1461. return lb_emit_array_epi(p, val, 0);
  1462. } else {
  1463. GB_PANIC("Unknown type of expand_to_tuple");
  1464. }
  1465. }
  1466. GB_ASSERT(is_type_tuple(tv.type));
  1467. // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
  1468. lbValue tuple = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false));
  1469. if (t->kind == Type_Struct) {
  1470. for_array(src_index, t->Struct.fields) {
  1471. Entity *field = t->Struct.fields[src_index];
  1472. i32 field_index = field->Variable.field_index;
  1473. lbValue f = lb_emit_struct_ev(p, val, field_index);
  1474. lbValue ep = lb_emit_struct_ep(p, tuple, cast(i32)src_index);
  1475. lb_emit_store(p, ep, f);
  1476. }
  1477. } else if (is_type_array_like(t)) {
  1478. // TODO(bill): Clean-up this code
  1479. lbValue ap = lb_address_from_load_or_generate_local(p, val);
  1480. i32 n = cast(i32)get_array_type_count(t);
  1481. for (i32 i = 0; i < n; i++) {
  1482. lbValue f = lb_emit_load(p, lb_emit_array_epi(p, ap, i));
  1483. lbValue ep = lb_emit_struct_ep(p, tuple, i);
  1484. lb_emit_store(p, ep, f);
  1485. }
  1486. } else {
  1487. GB_PANIC("Unknown type of expand_to_tuple");
  1488. }
  1489. return lb_emit_load(p, tuple);
  1490. }
  1491. case BuiltinProc_min: {
  1492. Type *t = type_of_expr(expr);
  1493. if (ce->args.count == 2) {
  1494. return lb_emit_min(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  1495. } else {
  1496. lbValue x = lb_build_expr(p, ce->args[0]);
  1497. for (isize i = 1; i < ce->args.count; i++) {
  1498. x = lb_emit_min(p, t, x, lb_build_expr(p, ce->args[i]));
  1499. }
  1500. return x;
  1501. }
  1502. }
  1503. case BuiltinProc_max: {
  1504. Type *t = type_of_expr(expr);
  1505. if (ce->args.count == 2) {
  1506. return lb_emit_max(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  1507. } else {
  1508. lbValue x = lb_build_expr(p, ce->args[0]);
  1509. for (isize i = 1; i < ce->args.count; i++) {
  1510. x = lb_emit_max(p, t, x, lb_build_expr(p, ce->args[i]));
  1511. }
  1512. return x;
  1513. }
  1514. }
  1515. case BuiltinProc_abs: {
  1516. lbValue x = lb_build_expr(p, ce->args[0]);
  1517. Type *t = x.type;
  1518. if (is_type_unsigned(t)) {
  1519. return x;
  1520. }
  1521. if (is_type_quaternion(t)) {
  1522. i64 sz = 8*type_size_of(t);
  1523. auto args = array_make<lbValue>(permanent_allocator(), 1);
  1524. args[0] = x;
  1525. switch (sz) {
  1526. case 64: return lb_emit_runtime_call(p, "abs_quaternion64", args);
  1527. case 128: return lb_emit_runtime_call(p, "abs_quaternion128", args);
  1528. case 256: return lb_emit_runtime_call(p, "abs_quaternion256", args);
  1529. }
  1530. GB_PANIC("Unknown complex type");
  1531. } else if (is_type_complex(t)) {
  1532. i64 sz = 8*type_size_of(t);
  1533. auto args = array_make<lbValue>(permanent_allocator(), 1);
  1534. args[0] = x;
  1535. switch (sz) {
  1536. case 32: return lb_emit_runtime_call(p, "abs_complex32", args);
  1537. case 64: return lb_emit_runtime_call(p, "abs_complex64", args);
  1538. case 128: return lb_emit_runtime_call(p, "abs_complex128", args);
  1539. }
  1540. GB_PANIC("Unknown complex type");
  1541. }
  1542. lbValue zero = lb_const_nil(p->module, t);
  1543. lbValue cond = lb_emit_comp(p, Token_Lt, x, zero);
  1544. lbValue neg = lb_emit_unary_arith(p, Token_Sub, x, t);
  1545. return lb_emit_select(p, cond, neg, x);
  1546. }
  1547. case BuiltinProc_clamp:
  1548. return lb_emit_clamp(p, type_of_expr(expr),
  1549. lb_build_expr(p, ce->args[0]),
  1550. lb_build_expr(p, ce->args[1]),
  1551. lb_build_expr(p, ce->args[2]));
  1552. case BuiltinProc_soa_zip:
  1553. return lb_soa_zip(p, ce, tv);
  1554. case BuiltinProc_soa_unzip:
  1555. return lb_soa_unzip(p, ce, tv);
  1556. case BuiltinProc_transpose:
  1557. {
  1558. lbValue m = lb_build_expr(p, ce->args[0]);
  1559. return lb_emit_matrix_tranpose(p, m, tv.type);
  1560. }
  1561. case BuiltinProc_outer_product:
  1562. {
  1563. lbValue a = lb_build_expr(p, ce->args[0]);
  1564. lbValue b = lb_build_expr(p, ce->args[1]);
  1565. return lb_emit_outer_product(p, a, b, tv.type);
  1566. }
  1567. case BuiltinProc_hadamard_product:
  1568. {
  1569. lbValue a = lb_build_expr(p, ce->args[0]);
  1570. lbValue b = lb_build_expr(p, ce->args[1]);
  1571. if (is_type_array(tv.type)) {
  1572. return lb_emit_arith(p, Token_Mul, a, b, tv.type);
  1573. }
  1574. GB_ASSERT(is_type_matrix(tv.type));
  1575. return lb_emit_arith_matrix(p, Token_Mul, a, b, tv.type, true);
  1576. }
  1577. case BuiltinProc_matrix_flatten:
  1578. {
  1579. lbValue m = lb_build_expr(p, ce->args[0]);
  1580. return lb_emit_matrix_flatten(p, m, tv.type);
  1581. }
  1582. case BuiltinProc_unreachable:
  1583. lb_emit_unreachable(p);
  1584. return {};
  1585. // "Intrinsics"
  1586. case BuiltinProc_alloca:
  1587. {
  1588. lbValue sz = lb_build_expr(p, ce->args[0]);
  1589. i64 al = exact_value_to_i64(type_and_value_of_expr(ce->args[1]).value);
  1590. lbValue res = {};
  1591. res.type = t_u8_ptr;
  1592. res.value = LLVMBuildArrayAlloca(p->builder, lb_type(p->module, t_u8), sz.value, "");
  1593. LLVMSetAlignment(res.value, cast(unsigned)al);
  1594. return res;
  1595. }
  1596. case BuiltinProc_cpu_relax:
  1597. if (build_context.metrics.arch == TargetArch_i386 ||
  1598. build_context.metrics.arch == TargetArch_amd64) {
  1599. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  1600. LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("pause"), {}, true);
  1601. GB_ASSERT(the_asm != nullptr);
  1602. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1603. } else if (build_context.metrics.arch == TargetArch_arm64) {
  1604. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  1605. // NOTE(bill, 2022-03-30): `isb` appears to a better option that `yield`
  1606. // See: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8258604
  1607. LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("isb"), {}, true);
  1608. GB_ASSERT(the_asm != nullptr);
  1609. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1610. } else {
  1611. // NOTE: default to something to prevent optimization
  1612. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  1613. LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit(""), {}, true);
  1614. GB_ASSERT(the_asm != nullptr);
  1615. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1616. }
  1617. return {};
  1618. case BuiltinProc_debug_trap:
  1619. case BuiltinProc_trap:
  1620. {
  1621. char const *name = nullptr;
  1622. switch (id) {
  1623. case BuiltinProc_debug_trap: name = "llvm.debugtrap"; break;
  1624. case BuiltinProc_trap: name = "llvm.trap"; break;
  1625. }
  1626. lb_call_intrinsic(p, name, nullptr, 0, nullptr, 0);
  1627. if (id == BuiltinProc_trap) {
  1628. LLVMBuildUnreachable(p->builder);
  1629. }
  1630. return {};
  1631. }
  1632. case BuiltinProc_read_cycle_counter:
  1633. {
  1634. lbValue res = {};
  1635. res.type = tv.type;
  1636. if (build_context.metrics.arch == TargetArch_arm64) {
  1637. LLVMTypeRef func_type = LLVMFunctionType(LLVMInt64TypeInContext(p->module->ctx), nullptr, 0, false);
  1638. bool has_side_effects = false;
  1639. LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("mrs x9, cntvct_el0"), str_lit("=r"), has_side_effects);
  1640. GB_ASSERT(the_asm != nullptr);
  1641. res.value = LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1642. } else {
  1643. char const *name = "llvm.readcyclecounter";
  1644. res.value = lb_call_intrinsic(p, name, nullptr, 0, nullptr, 0);
  1645. }
  1646. return res;
  1647. }
  1648. case BuiltinProc_count_trailing_zeros:
  1649. return lb_emit_count_trailing_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1650. case BuiltinProc_count_leading_zeros:
  1651. return lb_emit_count_leading_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1652. case BuiltinProc_count_ones:
  1653. return lb_emit_count_ones(p, lb_build_expr(p, ce->args[0]), tv.type);
  1654. case BuiltinProc_count_zeros:
  1655. return lb_emit_count_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1656. case BuiltinProc_reverse_bits:
  1657. return lb_emit_reverse_bits(p, lb_build_expr(p, ce->args[0]), tv.type);
  1658. case BuiltinProc_byte_swap:
  1659. {
  1660. lbValue x = lb_build_expr(p, ce->args[0]);
  1661. x = lb_emit_conv(p, x, tv.type);
  1662. return lb_emit_byte_swap(p, x, tv.type);
  1663. }
  1664. case BuiltinProc_overflow_add:
  1665. case BuiltinProc_overflow_sub:
  1666. case BuiltinProc_overflow_mul:
  1667. {
  1668. Type *main_type = tv.type;
  1669. Type *type = main_type;
  1670. if (is_type_tuple(main_type)) {
  1671. type = main_type->Tuple.variables[0]->type;
  1672. }
  1673. lbValue x = lb_build_expr(p, ce->args[0]);
  1674. lbValue y = lb_build_expr(p, ce->args[1]);
  1675. x = lb_emit_conv(p, x, type);
  1676. y = lb_emit_conv(p, y, type);
  1677. char const *name = nullptr;
  1678. if (is_type_unsigned(type)) {
  1679. switch (id) {
  1680. case BuiltinProc_overflow_add: name = "llvm.uadd.with.overflow"; break;
  1681. case BuiltinProc_overflow_sub: name = "llvm.usub.with.overflow"; break;
  1682. case BuiltinProc_overflow_mul: name = "llvm.umul.with.overflow"; break;
  1683. }
  1684. } else {
  1685. switch (id) {
  1686. case BuiltinProc_overflow_add: name = "llvm.sadd.with.overflow"; break;
  1687. case BuiltinProc_overflow_sub: name = "llvm.ssub.with.overflow"; break;
  1688. case BuiltinProc_overflow_mul: name = "llvm.smul.with.overflow"; break;
  1689. }
  1690. }
  1691. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  1692. LLVMValueRef args[2] = { x.value, y.value };
  1693. lbValue res = {};
  1694. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1695. if (is_type_tuple(main_type)) {
  1696. Type *res_type = nullptr;
  1697. gbAllocator a = permanent_allocator();
  1698. res_type = alloc_type_tuple();
  1699. slice_init(&res_type->Tuple.variables, a, 2);
  1700. res_type->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, type, false, 0);
  1701. res_type->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  1702. res.type = res_type;
  1703. } else {
  1704. res.value = LLVMBuildExtractValue(p->builder, res.value, 0, "");
  1705. res.type = type;
  1706. }
  1707. return res;
  1708. }
  1709. case BuiltinProc_sqrt:
  1710. {
  1711. Type *type = tv.type;
  1712. lbValue x = lb_build_expr(p, ce->args[0]);
  1713. x = lb_emit_conv(p, x, type);
  1714. char const *name = "llvm.sqrt";
  1715. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  1716. LLVMValueRef args[1] = { x.value };
  1717. lbValue res = {};
  1718. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1719. res.type = type;
  1720. return res;
  1721. }
  1722. case BuiltinProc_fused_mul_add:
  1723. {
  1724. Type *type = tv.type;
  1725. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), type);
  1726. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), type);
  1727. lbValue z = lb_emit_conv(p, lb_build_expr(p, ce->args[2]), type);
  1728. char const *name = "llvm.fma";
  1729. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  1730. LLVMValueRef args[3] = { x.value, y.value, z.value };
  1731. lbValue res = {};
  1732. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1733. res.type = type;
  1734. return res;
  1735. }
  1736. case BuiltinProc_mem_copy:
  1737. {
  1738. lbValue dst = lb_build_expr(p, ce->args[0]);
  1739. lbValue src = lb_build_expr(p, ce->args[1]);
  1740. lbValue len = lb_build_expr(p, ce->args[2]);
  1741. lb_mem_copy_overlapping(p, dst, src, len, false);
  1742. return {};
  1743. }
  1744. case BuiltinProc_mem_copy_non_overlapping:
  1745. {
  1746. lbValue dst = lb_build_expr(p, ce->args[0]);
  1747. lbValue src = lb_build_expr(p, ce->args[1]);
  1748. lbValue len = lb_build_expr(p, ce->args[2]);
  1749. lb_mem_copy_non_overlapping(p, dst, src, len, false);
  1750. return {};
  1751. }
  1752. case BuiltinProc_mem_zero:
  1753. {
  1754. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1755. lbValue len = lb_build_expr(p, ce->args[1]);
  1756. ptr = lb_emit_conv(p, ptr, t_rawptr);
  1757. len = lb_emit_conv(p, len, t_int);
  1758. unsigned alignment = 1;
  1759. lb_mem_zero_ptr_internal(p, ptr.value, len.value, alignment, false);
  1760. return {};
  1761. }
  1762. case BuiltinProc_mem_zero_volatile:
  1763. {
  1764. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1765. lbValue len = lb_build_expr(p, ce->args[1]);
  1766. ptr = lb_emit_conv(p, ptr, t_rawptr);
  1767. len = lb_emit_conv(p, len, t_int);
  1768. unsigned alignment = 1;
  1769. lb_mem_zero_ptr_internal(p, ptr.value, len.value, alignment, true);
  1770. return {};
  1771. }
  1772. case BuiltinProc_ptr_offset:
  1773. {
  1774. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1775. lbValue len = lb_build_expr(p, ce->args[1]);
  1776. len = lb_emit_conv(p, len, t_int);
  1777. return lb_emit_ptr_offset(p, ptr, len);
  1778. }
  1779. case BuiltinProc_ptr_sub:
  1780. {
  1781. lbValue ptr0 = lb_build_expr(p, ce->args[0]);
  1782. lbValue ptr1 = lb_build_expr(p, ce->args[1]);
  1783. LLVMTypeRef type_int = lb_type(p->module, t_int);
  1784. LLVMValueRef diff = LLVMBuildPtrDiff2(p->builder, lb_type(p->module, ptr0.type), ptr0.value, ptr1.value, "");
  1785. diff = LLVMBuildIntCast2(p->builder, diff, type_int, /*signed*/true, "");
  1786. lbValue res = {};
  1787. res.type = t_int;
  1788. res.value = diff;
  1789. return res;
  1790. }
  1791. // TODO(bill): Which is correct?
  1792. case BuiltinProc_atomic_thread_fence:
  1793. LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), false, "");
  1794. return {};
  1795. case BuiltinProc_atomic_signal_fence:
  1796. LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), true, "");
  1797. return {};
  1798. case BuiltinProc_volatile_store:
  1799. case BuiltinProc_non_temporal_store:
  1800. case BuiltinProc_atomic_store:
  1801. case BuiltinProc_atomic_store_explicit: {
  1802. lbValue dst = lb_build_expr(p, ce->args[0]);
  1803. lbValue val = lb_build_expr(p, ce->args[1]);
  1804. val = lb_emit_conv(p, val, type_deref(dst.type));
  1805. LLVMValueRef instr = LLVMBuildStore(p->builder, val.value, dst.value);
  1806. switch (id) {
  1807. case BuiltinProc_non_temporal_store:
  1808. {
  1809. unsigned kind_id = LLVMGetMDKindIDInContext(p->module->ctx, "nontemporal", 11);
  1810. LLVMMetadataRef node = LLVMValueAsMetadata(LLVMConstInt(lb_type(p->module, t_u32), 1, false));
  1811. LLVMSetMetadata(instr, kind_id, LLVMMetadataAsValue(p->module->ctx, node));
  1812. }
  1813. break;
  1814. case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break;
  1815. case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  1816. case BuiltinProc_atomic_store_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[2])); break;
  1817. }
  1818. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  1819. return {};
  1820. }
  1821. case BuiltinProc_volatile_load:
  1822. case BuiltinProc_non_temporal_load:
  1823. case BuiltinProc_atomic_load:
  1824. case BuiltinProc_atomic_load_explicit: {
  1825. lbValue dst = lb_build_expr(p, ce->args[0]);
  1826. LLVMValueRef instr = LLVMBuildLoad2(p->builder, lb_type(p->module, type_deref(dst.type)), dst.value, "");
  1827. switch (id) {
  1828. case BuiltinProc_non_temporal_load:
  1829. {
  1830. unsigned kind_id = LLVMGetMDKindIDInContext(p->module->ctx, "nontemporal", 11);
  1831. LLVMMetadataRef node = LLVMValueAsMetadata(LLVMConstInt(lb_type(p->module, t_u32), 1, false));
  1832. LLVMSetMetadata(instr, kind_id, LLVMMetadataAsValue(p->module->ctx, node));
  1833. }
  1834. break;
  1835. break;
  1836. case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break;
  1837. case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  1838. case BuiltinProc_atomic_load_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[1])); break;
  1839. }
  1840. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  1841. lbValue res = {};
  1842. res.value = instr;
  1843. res.type = type_deref(dst.type);
  1844. return res;
  1845. }
  1846. case BuiltinProc_unaligned_store:
  1847. {
  1848. lbValue dst = lb_build_expr(p, ce->args[0]);
  1849. lbValue src = lb_build_expr(p, ce->args[1]);
  1850. src = lb_address_from_load_or_generate_local(p, src);
  1851. Type *t = type_deref(dst.type);
  1852. lb_mem_copy_non_overlapping(p, dst, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
  1853. return {};
  1854. }
  1855. case BuiltinProc_unaligned_load:
  1856. {
  1857. lbValue src = lb_build_expr(p, ce->args[0]);
  1858. Type *t = type_deref(src.type);
  1859. lbAddr dst = lb_add_local_generated(p, t, false);
  1860. lb_mem_copy_non_overlapping(p, dst.addr, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
  1861. return lb_addr_load(p, dst);
  1862. }
  1863. case BuiltinProc_atomic_add:
  1864. case BuiltinProc_atomic_sub:
  1865. case BuiltinProc_atomic_and:
  1866. case BuiltinProc_atomic_nand:
  1867. case BuiltinProc_atomic_or:
  1868. case BuiltinProc_atomic_xor:
  1869. case BuiltinProc_atomic_exchange:
  1870. case BuiltinProc_atomic_add_explicit:
  1871. case BuiltinProc_atomic_sub_explicit:
  1872. case BuiltinProc_atomic_and_explicit:
  1873. case BuiltinProc_atomic_nand_explicit:
  1874. case BuiltinProc_atomic_or_explicit:
  1875. case BuiltinProc_atomic_xor_explicit:
  1876. case BuiltinProc_atomic_exchange_explicit: {
  1877. lbValue dst = lb_build_expr(p, ce->args[0]);
  1878. lbValue val = lb_build_expr(p, ce->args[1]);
  1879. val = lb_emit_conv(p, val, type_deref(dst.type));
  1880. LLVMAtomicRMWBinOp op = {};
  1881. LLVMAtomicOrdering ordering = {};
  1882. switch (id) {
  1883. case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1884. case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1885. case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1886. case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1887. case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1888. case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1889. case BuiltinProc_atomic_exchange: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1890. case BuiltinProc_atomic_add_explicit: op = LLVMAtomicRMWBinOpAdd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
  1891. case BuiltinProc_atomic_sub_explicit: op = LLVMAtomicRMWBinOpSub; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
  1892. case BuiltinProc_atomic_and_explicit: op = LLVMAtomicRMWBinOpAnd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
  1893. case BuiltinProc_atomic_nand_explicit: op = LLVMAtomicRMWBinOpNand; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
  1894. case BuiltinProc_atomic_or_explicit: op = LLVMAtomicRMWBinOpOr; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
  1895. case BuiltinProc_atomic_xor_explicit: op = LLVMAtomicRMWBinOpXor; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
  1896. case BuiltinProc_atomic_exchange_explicit: op = LLVMAtomicRMWBinOpXchg; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break;
  1897. }
  1898. lbValue res = {};
  1899. res.value = LLVMBuildAtomicRMW(p->builder, op, dst.value, val.value, ordering, false);
  1900. res.type = tv.type;
  1901. return res;
  1902. }
  1903. case BuiltinProc_atomic_compare_exchange_strong:
  1904. case BuiltinProc_atomic_compare_exchange_weak:
  1905. case BuiltinProc_atomic_compare_exchange_strong_explicit:
  1906. case BuiltinProc_atomic_compare_exchange_weak_explicit: {
  1907. lbValue address = lb_build_expr(p, ce->args[0]);
  1908. Type *elem = type_deref(address.type);
  1909. lbValue old_value = lb_build_expr(p, ce->args[1]);
  1910. lbValue new_value = lb_build_expr(p, ce->args[2]);
  1911. old_value = lb_emit_conv(p, old_value, elem);
  1912. new_value = lb_emit_conv(p, new_value, elem);
  1913. LLVMAtomicOrdering success_ordering = {};
  1914. LLVMAtomicOrdering failure_ordering = {};
  1915. LLVMBool weak = false;
  1916. switch (id) {
  1917. case BuiltinProc_atomic_compare_exchange_strong: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1918. case BuiltinProc_atomic_compare_exchange_weak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  1919. case BuiltinProc_atomic_compare_exchange_strong_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = false; break;
  1920. case BuiltinProc_atomic_compare_exchange_weak_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = true; break;
  1921. }
  1922. // TODO(bill): Figure out how to make it weak
  1923. LLVMBool single_threaded = false;
  1924. LLVMValueRef value = LLVMBuildAtomicCmpXchg(
  1925. p->builder, address.value,
  1926. old_value.value, new_value.value,
  1927. success_ordering,
  1928. failure_ordering,
  1929. single_threaded
  1930. );
  1931. LLVMSetWeak(value, weak);
  1932. if (tv.type->kind == Type_Tuple) {
  1933. Type *fix_typed = alloc_type_tuple();
  1934. slice_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
  1935. fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0];
  1936. fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  1937. lbValue res = {};
  1938. res.value = value;
  1939. res.type = fix_typed;
  1940. return res;
  1941. } else {
  1942. lbValue res = {};
  1943. res.value = LLVMBuildExtractValue(p->builder, value, 0, "");
  1944. res.type = tv.type;
  1945. return res;
  1946. }
  1947. }
  1948. case BuiltinProc_type_equal_proc:
  1949. return lb_get_equal_proc_for_type(p->module, ce->args[0]->tav.type);
  1950. case BuiltinProc_type_hasher_proc:
  1951. return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type);
  1952. case BuiltinProc_fixed_point_mul:
  1953. case BuiltinProc_fixed_point_div:
  1954. case BuiltinProc_fixed_point_mul_sat:
  1955. case BuiltinProc_fixed_point_div_sat:
  1956. {
  1957. Type *platform_type = integer_endian_type_to_platform_type(tv.type);
  1958. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), platform_type);
  1959. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), platform_type);
  1960. lbValue scale = lb_emit_conv(p, lb_build_expr(p, ce->args[2]), t_i32);
  1961. char const *name = nullptr;
  1962. if (is_type_unsigned(tv.type)) {
  1963. switch (id) {
  1964. case BuiltinProc_fixed_point_mul: name = "llvm.umul.fix"; break;
  1965. case BuiltinProc_fixed_point_div: name = "llvm.udiv.fix"; break;
  1966. case BuiltinProc_fixed_point_mul_sat: name = "llvm.umul.fix.sat"; break;
  1967. case BuiltinProc_fixed_point_div_sat: name = "llvm.udiv.fix.sat"; break;
  1968. }
  1969. } else {
  1970. switch (id) {
  1971. case BuiltinProc_fixed_point_mul: name = "llvm.smul.fix"; break;
  1972. case BuiltinProc_fixed_point_div: name = "llvm.sdiv.fix"; break;
  1973. case BuiltinProc_fixed_point_mul_sat: name = "llvm.smul.fix.sat"; break;
  1974. case BuiltinProc_fixed_point_div_sat: name = "llvm.sdiv.fix.sat"; break;
  1975. }
  1976. }
  1977. GB_ASSERT(name != nullptr);
  1978. LLVMTypeRef types[1] = {lb_type(p->module, platform_type)};
  1979. lbValue res = {};
  1980. LLVMValueRef args[3] = {
  1981. x.value,
  1982. y.value,
  1983. scale.value };
  1984. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1985. res.type = platform_type;
  1986. return lb_emit_conv(p, res, tv.type);
  1987. }
  1988. case BuiltinProc_expect:
  1989. {
  1990. Type *t = default_type(tv.type);
  1991. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t);
  1992. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t);
  1993. char const *name = "llvm.expect";
  1994. LLVMTypeRef types[1] = {lb_type(p->module, t)};
  1995. lbValue res = {};
  1996. LLVMValueRef args[2] = { x.value, y.value };
  1997. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  1998. res.type = t;
  1999. return lb_emit_conv(p, res, t);
  2000. }
  2001. case BuiltinProc_prefetch_read_instruction:
  2002. case BuiltinProc_prefetch_read_data:
  2003. case BuiltinProc_prefetch_write_instruction:
  2004. case BuiltinProc_prefetch_write_data:
  2005. {
  2006. lbValue ptr = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_rawptr);
  2007. unsigned long long locality = cast(unsigned long long)exact_value_to_i64(ce->args[1]->tav.value);
  2008. unsigned long long rw = 0;
  2009. unsigned long long cache = 0;
  2010. switch (id) {
  2011. case BuiltinProc_prefetch_read_instruction:
  2012. rw = 0;
  2013. cache = 0;
  2014. break;
  2015. case BuiltinProc_prefetch_read_data:
  2016. rw = 0;
  2017. cache = 1;
  2018. break;
  2019. case BuiltinProc_prefetch_write_instruction:
  2020. rw = 1;
  2021. cache = 0;
  2022. break;
  2023. case BuiltinProc_prefetch_write_data:
  2024. rw = 1;
  2025. cache = 1;
  2026. break;
  2027. }
  2028. char const *name = "llvm.prefetch";
  2029. LLVMTypeRef types[1] = {lb_type(p->module, t_rawptr)};
  2030. LLVMTypeRef llvm_i32 = lb_type(p->module, t_i32);
  2031. LLVMValueRef args[4] = {};
  2032. args[0] = ptr.value;
  2033. args[1] = LLVMConstInt(llvm_i32, rw, false);
  2034. args[2] = LLVMConstInt(llvm_i32, locality, false);
  2035. args[3] = LLVMConstInt(llvm_i32, cache, false);
  2036. lbValue res = {};
  2037. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  2038. res.type = nullptr;
  2039. return res;
  2040. }
  2041. case BuiltinProc___entry_point:
  2042. if (p->module->info->entry_point) {
  2043. lbValue entry_point = lb_find_procedure_value_from_entity(p->module, p->module->info->entry_point);
  2044. GB_ASSERT(entry_point.value != nullptr);
  2045. lb_emit_call(p, entry_point, {});
  2046. }
  2047. return {};
  2048. case BuiltinProc_syscall:
  2049. {
  2050. unsigned arg_count = cast(unsigned)ce->args.count;
  2051. LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count);
  2052. for_array(i, ce->args) {
  2053. lbValue arg = lb_build_expr(p, ce->args[i]);
  2054. arg = lb_emit_conv(p, arg, t_uintptr);
  2055. args[i] = arg.value;
  2056. }
  2057. LLVMTypeRef llvm_uintptr = lb_type(p->module, t_uintptr);
  2058. LLVMTypeRef *llvm_arg_types = gb_alloc_array(permanent_allocator(), LLVMTypeRef, arg_count);
  2059. for (unsigned i = 0; i < arg_count; i++) {
  2060. llvm_arg_types[i] = llvm_uintptr;
  2061. }
  2062. LLVMTypeRef func_type = LLVMFunctionType(llvm_uintptr, llvm_arg_types, arg_count, false);
  2063. LLVMValueRef inline_asm = nullptr;
  2064. switch (build_context.metrics.arch) {
  2065. case TargetArch_amd64:
  2066. {
  2067. GB_ASSERT(arg_count <= 7);
  2068. char asm_string[] = "syscall";
  2069. gbString constraints = gb_string_make(heap_allocator(), "={rax}");
  2070. for (unsigned i = 0; i < arg_count; i++) {
  2071. constraints = gb_string_appendc(constraints, ",{");
  2072. static char const *regs[] = {
  2073. "rax",
  2074. "rdi",
  2075. "rsi",
  2076. "rdx",
  2077. "r10",
  2078. "r8",
  2079. "r9"
  2080. };
  2081. constraints = gb_string_appendc(constraints, regs[i]);
  2082. constraints = gb_string_appendc(constraints, "}");
  2083. }
  2084. // The SYSCALL instruction stores the address of the
  2085. // following instruction into RCX, and RFLAGS in R11.
  2086. //
  2087. // RSP is not saved, but at least on Linux it appears
  2088. // that the kernel system-call handler does the right
  2089. // thing.
  2090. //
  2091. // Some but not all system calls will additionally
  2092. // clobber memory.
  2093. //
  2094. // TODO: FreeBSD is different and will also clobber
  2095. // R8, R9, and R10. Additionally CF is used to
  2096. // indicate an error instead of -errno.
  2097. constraints = gb_string_appendc(constraints, ",~{rcx},~{r11},~{memory}");
  2098. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  2099. }
  2100. break;
  2101. case TargetArch_i386:
  2102. {
  2103. GB_ASSERT(arg_count <= 7);
  2104. char asm_string_default[] = "int $0x80";
  2105. char *asm_string = asm_string_default;
  2106. gbString constraints = gb_string_make(heap_allocator(), "={eax}");
  2107. for (unsigned i = 0; i < gb_min(arg_count, 6); i++) {
  2108. constraints = gb_string_appendc(constraints, ",{");
  2109. static char const *regs[] = {
  2110. "eax",
  2111. "ebx",
  2112. "ecx",
  2113. "edx",
  2114. "esi",
  2115. "edi",
  2116. };
  2117. constraints = gb_string_appendc(constraints, regs[i]);
  2118. constraints = gb_string_appendc(constraints, "}");
  2119. }
  2120. if (arg_count == 7) {
  2121. char asm_string7[] = "push %[arg6]\npush %%ebp\nmov 4(%%esp), %%ebp\nint $0x80\npop %%ebp\nadd $4, %%esp";
  2122. asm_string = asm_string7;
  2123. constraints = gb_string_appendc(constraints, ",rm");
  2124. }
  2125. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  2126. }
  2127. break;
  2128. case TargetArch_arm64:
  2129. {
  2130. GB_ASSERT(arg_count <= 7);
  2131. if(build_context.metrics.os == TargetOs_darwin) {
  2132. char asm_string[] = "svc #0x80";
  2133. gbString constraints = gb_string_make(heap_allocator(), "={x0}");
  2134. for (unsigned i = 0; i < arg_count; i++) {
  2135. constraints = gb_string_appendc(constraints, ",{");
  2136. static char const *regs[] = {
  2137. "x16",
  2138. "x0",
  2139. "x1",
  2140. "x2",
  2141. "x3",
  2142. "x4",
  2143. "x5",
  2144. };
  2145. constraints = gb_string_appendc(constraints, regs[i]);
  2146. constraints = gb_string_appendc(constraints, "}");
  2147. }
  2148. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  2149. } else {
  2150. char asm_string[] = "svc #0";
  2151. gbString constraints = gb_string_make(heap_allocator(), "={x0}");
  2152. for (unsigned i = 0; i < arg_count; i++) {
  2153. constraints = gb_string_appendc(constraints, ",{");
  2154. static char const *regs[] = {
  2155. "x8",
  2156. "x0",
  2157. "x1",
  2158. "x2",
  2159. "x3",
  2160. "x4",
  2161. "x5",
  2162. };
  2163. constraints = gb_string_appendc(constraints, regs[i]);
  2164. constraints = gb_string_appendc(constraints, "}");
  2165. }
  2166. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  2167. }
  2168. }
  2169. break;
  2170. case TargetArch_arm32:
  2171. {
  2172. // TODO(bill): Check this is correct
  2173. GB_ASSERT(arg_count <= 7);
  2174. char asm_string[] = "svc #0";
  2175. gbString constraints = gb_string_make(heap_allocator(), "={r0}");
  2176. for (unsigned i = 0; i < arg_count; i++) {
  2177. constraints = gb_string_appendc(constraints, ",{");
  2178. static char const *regs[] = {
  2179. "r8",
  2180. "r0",
  2181. "r1",
  2182. "r2",
  2183. "r3",
  2184. "r4",
  2185. "r5",
  2186. };
  2187. constraints = gb_string_appendc(constraints, regs[i]);
  2188. constraints = gb_string_appendc(constraints, "}");
  2189. }
  2190. inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
  2191. }
  2192. break;
  2193. default:
  2194. GB_PANIC("Unsupported platform");
  2195. }
  2196. lbValue res = {};
  2197. res.value = LLVMBuildCall2(p->builder, func_type, inline_asm, args, arg_count, "");
  2198. res.type = t_uintptr;
  2199. return res;
  2200. }
  2201. case BuiltinProc_objc_send:
  2202. return lb_handle_objc_send(p, expr);
  2203. case BuiltinProc_objc_find_selector: return lb_handle_objc_find_selector(p, expr);
  2204. case BuiltinProc_objc_find_class: return lb_handle_objc_find_class(p, expr);
  2205. case BuiltinProc_objc_register_selector: return lb_handle_objc_register_selector(p, expr);
  2206. case BuiltinProc_objc_register_class: return lb_handle_objc_register_class(p, expr);
  2207. case BuiltinProc_constant_utf16_cstring:
  2208. {
  2209. auto const encode_surrogate_pair = [](Rune r, u16 *r1, u16 *r2) {
  2210. if (r < 0x10000 || r > 0x10ffff) {
  2211. *r1 = 0xfffd;
  2212. *r2 = 0xfffd;
  2213. } else {
  2214. r -= 0x10000;
  2215. *r1 = 0xd800 + ((r>>10)&0x3ff);
  2216. *r2 = 0xdc00 + (r&0x3ff);
  2217. }
  2218. };
  2219. lbModule *m = p->module;
  2220. auto tav = type_and_value_of_expr(ce->args[0]);
  2221. GB_ASSERT(tav.value.kind == ExactValue_String);
  2222. String value = tav.value.value_string;
  2223. LLVMTypeRef llvm_u16 = lb_type(m, t_u16);
  2224. isize max_len = value.len*2 + 1;
  2225. LLVMValueRef *buffer = gb_alloc_array(temporary_allocator(), LLVMValueRef, max_len);
  2226. isize n = 0;
  2227. while (value.len > 0) {
  2228. Rune r = 0;
  2229. isize w = gb_utf8_decode(value.text, value.len, &r);
  2230. value.text += w;
  2231. value.len -= w;
  2232. if ((0 <= r && r < 0xd800) || (0xe000 <= r && r < 0x10000)) {
  2233. buffer[n++] = LLVMConstInt(llvm_u16, cast(u16)r, false);
  2234. } else if (0x10000 <= r && r <= 0x10ffff) {
  2235. u16 r1, r2;
  2236. encode_surrogate_pair(r, &r1, &r2);
  2237. buffer[n++] = LLVMConstInt(llvm_u16, r1, false);
  2238. buffer[n++] = LLVMConstInt(llvm_u16, r2, false);
  2239. } else {
  2240. buffer[n++] = LLVMConstInt(llvm_u16, 0xfffd, false);
  2241. }
  2242. }
  2243. buffer[n++] = LLVMConstInt(llvm_u16, 0, false);
  2244. LLVMValueRef array = LLVMConstArray(llvm_u16, buffer, cast(unsigned int)n);
  2245. char *name = nullptr;
  2246. {
  2247. isize max_len = 7+8+1;
  2248. name = gb_alloc_array(permanent_allocator(), char, max_len);
  2249. u32 id = m->gen->global_array_index.fetch_add(1);
  2250. isize len = gb_snprintf(name, max_len, "csbs$%x", id);
  2251. len -= 1;
  2252. }
  2253. LLVMTypeRef type = LLVMTypeOf(array);
  2254. LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name);
  2255. LLVMSetInitializer(global_data, array);
  2256. LLVMSetLinkage(global_data, LLVMInternalLinkage);
  2257. LLVMValueRef indices[] = {
  2258. LLVMConstInt(lb_type(m, t_u32), 0, false),
  2259. LLVMConstInt(lb_type(m, t_u32), 0, false),
  2260. };
  2261. lbValue res = {};
  2262. res.type = tv.type;
  2263. res.value = LLVMBuildInBoundsGEP2(p->builder, type, global_data, indices, gb_count_of(indices), "");
  2264. return res;
  2265. }
  2266. case BuiltinProc_wasm_memory_grow:
  2267. {
  2268. char const *name = "llvm.wasm.memory.grow";
  2269. LLVMTypeRef types[1] = {
  2270. lb_type(p->module, t_uintptr),
  2271. };
  2272. LLVMValueRef args[2] = {};
  2273. args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value;
  2274. args[1] = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_uintptr).value;
  2275. lbValue res = {};
  2276. res.type = tv.type;
  2277. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  2278. return res;
  2279. }
  2280. case BuiltinProc_wasm_memory_size:
  2281. {
  2282. char const *name = "llvm.wasm.memory.size";
  2283. LLVMTypeRef types[1] = {
  2284. lb_type(p->module, t_uintptr),
  2285. };
  2286. LLVMValueRef args[1] = {};
  2287. args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value;
  2288. lbValue res = {};
  2289. res.type = tv.type;
  2290. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  2291. return res;
  2292. }
  2293. case BuiltinProc_wasm_memory_atomic_wait32:
  2294. {
  2295. char const *name = "llvm.wasm.memory.atomic.wait32";
  2296. LLVMTypeRef types[1] = {
  2297. lb_type(p->module, t_u32),
  2298. };
  2299. Type *t_u32_ptr = alloc_type_pointer(t_u32);
  2300. LLVMValueRef args[3] = {};
  2301. args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_u32_ptr).value;
  2302. args[1] = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_u32).value;
  2303. args[2] = lb_emit_conv(p, lb_build_expr(p, ce->args[2]), t_i64).value;
  2304. lbValue res = {};
  2305. res.type = tv.type;
  2306. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  2307. return res;
  2308. }
  2309. case BuiltinProc_wasm_memory_atomic_notify32:
  2310. {
  2311. char const *name = "llvm.wasm.memory.atomic.notify";
  2312. LLVMTypeRef types[1] = {
  2313. lb_type(p->module, t_u32),
  2314. };
  2315. Type *t_u32_ptr = alloc_type_pointer(t_u32);
  2316. LLVMValueRef args[2] = {
  2317. lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_u32_ptr).value,
  2318. lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_u32).value };
  2319. lbValue res = {};
  2320. res.type = tv.type;
  2321. res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
  2322. return res;
  2323. }
  2324. case BuiltinProc_x86_cpuid:
  2325. {
  2326. Type *param_types[2] = {t_u32, t_u32};
  2327. Type *type = alloc_type_proc_from_types(param_types, gb_count_of(param_types), tv.type, false, ProcCC_None);
  2328. LLVMTypeRef func_type = lb_get_procedure_raw_type(p->module, type);
  2329. LLVMValueRef the_asm = llvm_get_inline_asm(
  2330. func_type,
  2331. str_lit("cpuid"),
  2332. str_lit("={ax},={bx},={cx},={dx},{ax},{cx}"),
  2333. true
  2334. );
  2335. GB_ASSERT(the_asm != nullptr);
  2336. LLVMValueRef args[2] = {};
  2337. args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_u32).value;
  2338. args[1] = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_u32).value;
  2339. lbValue res = {};
  2340. res.type = tv.type;
  2341. res.value = LLVMBuildCall2(p->builder, func_type, the_asm, args, gb_count_of(args), "");
  2342. return res;
  2343. }
  2344. case BuiltinProc_x86_xgetbv:
  2345. {
  2346. Type *type = alloc_type_proc_from_types(&t_u32, 1, tv.type, false, ProcCC_None);
  2347. LLVMTypeRef func_type = lb_get_procedure_raw_type(p->module, type);
  2348. LLVMValueRef the_asm = llvm_get_inline_asm(
  2349. func_type,
  2350. str_lit("xgetbv"),
  2351. str_lit("={ax},={dx},{cx}"),
  2352. true
  2353. );
  2354. GB_ASSERT(the_asm != nullptr);
  2355. LLVMValueRef args[1] = {};
  2356. args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_u32).value;
  2357. lbValue res = {};
  2358. res.type = tv.type;
  2359. res.value = LLVMBuildCall2(p->builder, func_type, the_asm, args, gb_count_of(args), "");
  2360. return res;
  2361. }
  2362. case BuiltinProc_valgrind_client_request:
  2363. {
  2364. lbValue args[7] = {};
  2365. for (isize i = 0; i < 7; i++) {
  2366. args[i] = lb_emit_conv(p, lb_build_expr(p, ce->args[i]), t_uintptr);
  2367. }
  2368. if (!build_context.ODIN_VALGRIND_SUPPORT) {
  2369. return args[0];
  2370. }
  2371. lbValue array = lb_generate_local_array(p, t_uintptr, 6, false);
  2372. for (isize i = 0; i < 6; i++) {
  2373. lbValue gep = lb_emit_array_epi(p, array, i);
  2374. lb_emit_store(p, gep, args[i+1]);
  2375. }
  2376. switch (build_context.metrics.arch) {
  2377. case TargetArch_amd64:
  2378. {
  2379. Type *param_types[2] = {};
  2380. param_types[0] = t_uintptr;
  2381. param_types[1] = array.type;
  2382. Type *type = alloc_type_proc_from_types(param_types, gb_count_of(param_types), t_uintptr, false, ProcCC_None);
  2383. LLVMTypeRef func_type = lb_get_procedure_raw_type(p->module, type);
  2384. LLVMValueRef the_asm = llvm_get_inline_asm(
  2385. func_type,
  2386. str_lit("rolq $3, %rdi; rolq $13, %rdi\n rolq $61, %rdi; rolq $51, %rdi\n xchgq %rbx, %rbx"),
  2387. str_lit("={rdx},{rdx},{rax},cc,memory"),
  2388. true
  2389. );
  2390. LLVMValueRef asm_args[2] = {};
  2391. asm_args[0] = args[0].value;
  2392. asm_args[1] = array.value;
  2393. lbValue res = {};
  2394. res.type = t_uintptr;
  2395. res.value = LLVMBuildCall2(p->builder, func_type, the_asm, asm_args, gb_count_of(asm_args), "");
  2396. return res;
  2397. }
  2398. break;
  2399. default:
  2400. GB_PANIC("Unsupported architecture: %.*s", LIT(target_arch_names[build_context.metrics.arch]));
  2401. break;
  2402. }
  2403. }
  2404. }
  2405. GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name));
  2406. return {};
  2407. }
  2408. lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
  2409. switch (param_value.kind) {
  2410. case ParameterValue_Constant:
  2411. if (is_type_constant_type(parameter_type)) {
  2412. auto res = lb_const_value(p->module, parameter_type, param_value.value);
  2413. return res;
  2414. } else {
  2415. ExactValue ev = param_value.value;
  2416. lbValue arg = {};
  2417. Type *type = type_of_expr(param_value.original_ast_expr);
  2418. if (type != nullptr) {
  2419. arg = lb_const_value(p->module, type, ev);
  2420. } else {
  2421. arg = lb_const_value(p->module, parameter_type, param_value.value);
  2422. }
  2423. return lb_emit_conv(p, arg, parameter_type);
  2424. }
  2425. case ParameterValue_Nil:
  2426. return lb_const_nil(p->module, parameter_type);
  2427. case ParameterValue_Location:
  2428. {
  2429. String proc_name = {};
  2430. if (p->entity != nullptr) {
  2431. proc_name = p->entity->token.string;
  2432. }
  2433. return lb_emit_source_code_location(p, proc_name, pos);
  2434. }
  2435. case ParameterValue_Value:
  2436. return lb_build_expr(p, param_value.ast_value);
  2437. }
  2438. return lb_const_nil(p->module, parameter_type);
  2439. }
  2440. lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr);
  2441. lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
  2442. expr = unparen_expr(expr);
  2443. ast_node(ce, CallExpr, expr);
  2444. lbValue res = lb_build_call_expr_internal(p, expr);
  2445. if (ce->optional_ok_one) { // TODO(bill): Minor hack for #optional_ok procedures
  2446. GB_ASSERT(is_type_tuple(res.type));
  2447. GB_ASSERT(res.type->Tuple.variables.count == 2);
  2448. return lb_emit_struct_ev(p, res, 0);
  2449. }
  2450. return res;
  2451. }
  2452. lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
  2453. lbModule *m = p->module;
  2454. TypeAndValue tv = type_and_value_of_expr(expr);
  2455. ast_node(ce, CallExpr, expr);
  2456. TypeAndValue proc_tv = type_and_value_of_expr(ce->proc);
  2457. AddressingMode proc_mode = proc_tv.mode;
  2458. if (proc_mode == Addressing_Type) {
  2459. GB_ASSERT(ce->args.count == 1);
  2460. lbValue x = lb_build_expr(p, ce->args[0]);
  2461. lbValue y = lb_emit_conv(p, x, tv.type);
  2462. return y;
  2463. }
  2464. Ast *pexpr = unparen_expr(ce->proc);
  2465. if (proc_mode == Addressing_Builtin) {
  2466. Entity *e = entity_of_node(pexpr);
  2467. BuiltinProcId id = BuiltinProc_Invalid;
  2468. if (e != nullptr) {
  2469. id = cast(BuiltinProcId)e->Builtin.id;
  2470. } else {
  2471. id = BuiltinProc_DIRECTIVE;
  2472. }
  2473. return lb_build_builtin_proc(p, expr, tv, id);
  2474. }
  2475. // NOTE(bill): Regular call
  2476. lbValue value = {};
  2477. Ast *proc_expr = unparen_expr(ce->proc);
  2478. Entity *proc_entity = entity_of_node(proc_expr);
  2479. if (proc_entity != nullptr) {
  2480. if (proc_entity->flags & EntityFlag_Disabled) {
  2481. GB_ASSERT(tv.type == nullptr);
  2482. return {};
  2483. }
  2484. }
  2485. if (proc_expr->tav.mode == Addressing_Constant) {
  2486. ExactValue v = proc_expr->tav.value;
  2487. switch (v.kind) {
  2488. case ExactValue_Integer:
  2489. {
  2490. u64 u = big_int_to_u64(&v.value_integer);
  2491. lbValue x = {};
  2492. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  2493. x.type = t_uintptr;
  2494. x = lb_emit_conv(p, x, t_rawptr);
  2495. value = lb_emit_conv(p, x, proc_expr->tav.type);
  2496. break;
  2497. }
  2498. case ExactValue_Pointer:
  2499. {
  2500. u64 u = cast(u64)v.value_pointer;
  2501. lbValue x = {};
  2502. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  2503. x.type = t_uintptr;
  2504. x = lb_emit_conv(p, x, t_rawptr);
  2505. value = lb_emit_conv(p, x, proc_expr->tav.type);
  2506. break;
  2507. }
  2508. }
  2509. }
  2510. if (value.value == nullptr) {
  2511. value = lb_build_expr(p, proc_expr);
  2512. }
  2513. GB_ASSERT(value.value != nullptr);
  2514. Type *proc_type_ = base_type(value.type);
  2515. GB_ASSERT(proc_type_->kind == Type_Proc);
  2516. TypeProc *pt = &proc_type_->Proc;
  2517. if (is_call_expr_field_value(ce)) {
  2518. auto args = array_make<lbValue>(permanent_allocator(), pt->param_count);
  2519. for_array(arg_index, ce->args) {
  2520. Ast *arg = ce->args[arg_index];
  2521. ast_node(fv, FieldValue, arg);
  2522. GB_ASSERT(fv->field->kind == Ast_Ident);
  2523. String name = fv->field->Ident.token.string;
  2524. isize index = lookup_procedure_parameter(pt, name);
  2525. GB_ASSERT(index >= 0);
  2526. TypeAndValue tav = type_and_value_of_expr(fv->value);
  2527. if (tav.mode == Addressing_Type) {
  2528. args[index] = lb_const_nil(m, tav.type);
  2529. } else {
  2530. args[index] = lb_build_expr(p, fv->value);
  2531. }
  2532. }
  2533. TypeTuple *params = &pt->params->Tuple;
  2534. for (isize i = 0; i < args.count; i++) {
  2535. Entity *e = params->variables[i];
  2536. if (e->kind == Entity_TypeName) {
  2537. args[i] = lb_const_nil(m, e->type);
  2538. } else if (e->kind == Entity_Constant) {
  2539. continue;
  2540. } else {
  2541. GB_ASSERT(e->kind == Entity_Variable);
  2542. if (args[i].value == nullptr) {
  2543. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2544. } else {
  2545. args[i] = lb_emit_conv(p, args[i], e->type);
  2546. }
  2547. }
  2548. }
  2549. for (isize i = 0; i < args.count; i++) {
  2550. Entity *e = params->variables[i];
  2551. if (args[i].type == nullptr) {
  2552. continue;
  2553. } else if (is_type_untyped_nil(args[i].type)) {
  2554. args[i] = lb_const_nil(m, e->type);
  2555. } else if (is_type_untyped_undef(args[i].type)) {
  2556. args[i] = lb_const_undef(m, e->type);
  2557. }
  2558. }
  2559. return lb_emit_call(p, value, args, ce->inlining, p->copy_elision_hint.ast == expr);
  2560. }
  2561. isize arg_index = 0;
  2562. isize arg_count = 0;
  2563. for_array(i, ce->args) {
  2564. Ast *arg = ce->args[i];
  2565. TypeAndValue tav = type_and_value_of_expr(arg);
  2566. GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s %s %d", expr_to_string(arg), expr_to_string(expr), tav.mode);
  2567. GB_ASSERT_MSG(tav.mode != Addressing_ProcGroup, "%s", expr_to_string(arg));
  2568. Type *at = tav.type;
  2569. if (at->kind == Type_Tuple) {
  2570. arg_count += at->Tuple.variables.count;
  2571. } else {
  2572. arg_count++;
  2573. }
  2574. }
  2575. isize param_count = 0;
  2576. if (pt->params) {
  2577. GB_ASSERT(pt->params->kind == Type_Tuple);
  2578. param_count = pt->params->Tuple.variables.count;
  2579. }
  2580. auto args = array_make<lbValue>(permanent_allocator(), cast(isize)gb_max(param_count, arg_count));
  2581. isize variadic_index = pt->variadic_index;
  2582. bool variadic = pt->variadic && variadic_index >= 0;
  2583. bool vari_expand = ce->ellipsis.pos.line != 0;
  2584. bool is_c_vararg = pt->c_vararg;
  2585. String proc_name = {};
  2586. if (p->entity != nullptr) {
  2587. proc_name = p->entity->token.string;
  2588. }
  2589. TokenPos pos = ast_token(ce->proc).pos;
  2590. TypeTuple *param_tuple = nullptr;
  2591. if (pt->params) {
  2592. GB_ASSERT(pt->params->kind == Type_Tuple);
  2593. param_tuple = &pt->params->Tuple;
  2594. }
  2595. for_array(i, ce->args) {
  2596. Ast *arg = ce->args[i];
  2597. TypeAndValue arg_tv = type_and_value_of_expr(arg);
  2598. if (arg_tv.mode == Addressing_Type) {
  2599. args[arg_index++] = lb_const_nil(m, arg_tv.type);
  2600. } else {
  2601. lbValue a = lb_build_expr(p, arg);
  2602. Type *at = a.type;
  2603. if (at->kind == Type_Tuple) {
  2604. for_array(i, at->Tuple.variables) {
  2605. lbValue v = lb_emit_struct_ev(p, a, cast(i32)i);
  2606. args[arg_index++] = v;
  2607. }
  2608. } else {
  2609. args[arg_index++] = a;
  2610. }
  2611. }
  2612. }
  2613. if (param_count > 0) {
  2614. GB_ASSERT_MSG(pt->params != nullptr, "%s %td", expr_to_string(expr), pt->param_count);
  2615. GB_ASSERT(param_count < 1000000);
  2616. if (arg_count < param_count) {
  2617. isize end = cast(isize)param_count;
  2618. if (variadic) {
  2619. end = variadic_index;
  2620. }
  2621. while (arg_index < end) {
  2622. Entity *e = param_tuple->variables[arg_index];
  2623. GB_ASSERT(e->kind == Entity_Variable);
  2624. args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2625. }
  2626. }
  2627. if (is_c_vararg) {
  2628. GB_ASSERT(variadic);
  2629. GB_ASSERT(!vari_expand);
  2630. isize i = 0;
  2631. for (; i < variadic_index; i++) {
  2632. Entity *e = param_tuple->variables[i];
  2633. if (e->kind == Entity_Variable) {
  2634. args[i] = lb_emit_conv(p, args[i], e->type);
  2635. }
  2636. }
  2637. Type *variadic_type = param_tuple->variables[i]->type;
  2638. GB_ASSERT(is_type_slice(variadic_type));
  2639. variadic_type = base_type(variadic_type)->Slice.elem;
  2640. if (!is_type_any(variadic_type)) {
  2641. for (; i < arg_count; i++) {
  2642. args[i] = lb_emit_conv(p, args[i], variadic_type);
  2643. }
  2644. } else {
  2645. for (; i < arg_count; i++) {
  2646. args[i] = lb_emit_conv(p, args[i], default_type(args[i].type));
  2647. }
  2648. }
  2649. } else if (variadic) {
  2650. isize i = 0;
  2651. for (; i < variadic_index; i++) {
  2652. Entity *e = param_tuple->variables[i];
  2653. if (e->kind == Entity_Variable) {
  2654. args[i] = lb_emit_conv(p, args[i], e->type);
  2655. }
  2656. }
  2657. if (!vari_expand) {
  2658. Type *variadic_type = param_tuple->variables[i]->type;
  2659. GB_ASSERT(is_type_slice(variadic_type));
  2660. variadic_type = base_type(variadic_type)->Slice.elem;
  2661. for (; i < arg_count; i++) {
  2662. args[i] = lb_emit_conv(p, args[i], variadic_type);
  2663. }
  2664. }
  2665. } else {
  2666. for (isize i = 0; i < param_count; i++) {
  2667. Entity *e = param_tuple->variables[i];
  2668. if (e->kind == Entity_Variable) {
  2669. if (args[i].value == nullptr) {
  2670. continue;
  2671. }
  2672. GB_ASSERT_MSG(args[i].value != nullptr, "%.*s", LIT(e->token.string));
  2673. args[i] = lb_emit_conv(p, args[i], e->type);
  2674. }
  2675. }
  2676. }
  2677. if (variadic && !vari_expand && !is_c_vararg) {
  2678. // variadic call argument generation
  2679. Type *slice_type = param_tuple->variables[variadic_index]->type;
  2680. Type *elem_type = base_type(slice_type)->Slice.elem;
  2681. lbAddr slice = lb_add_local_generated(p, slice_type, true);
  2682. isize slice_len = arg_count+1 - (variadic_index+1);
  2683. if (slice_len > 0) {
  2684. lbAddr base_array = lb_add_local_generated(p, alloc_type_array(elem_type, slice_len), true);
  2685. for (isize i = variadic_index, j = 0; i < arg_count; i++, j++) {
  2686. lbValue addr = lb_emit_array_epi(p, base_array.addr, cast(i32)j);
  2687. lb_emit_store(p, addr, args[i]);
  2688. }
  2689. lbValue base_elem = lb_emit_array_epi(p, base_array.addr, 0);
  2690. lbValue len = lb_const_int(m, t_int, slice_len);
  2691. lb_fill_slice(p, slice, base_elem, len);
  2692. }
  2693. arg_count = param_count;
  2694. args[variadic_index] = lb_addr_load(p, slice);
  2695. }
  2696. }
  2697. if (variadic && variadic_index+1 < param_count) {
  2698. for (isize i = variadic_index+1; i < param_count; i++) {
  2699. Entity *e = param_tuple->variables[i];
  2700. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2701. }
  2702. }
  2703. isize final_count = param_count;
  2704. if (is_c_vararg) {
  2705. final_count = arg_count;
  2706. }
  2707. if (param_tuple != nullptr) {
  2708. for (isize i = 0; i < gb_min(args.count, param_tuple->variables.count); i++) {
  2709. Entity *e = param_tuple->variables[i];
  2710. if (args[i].type == nullptr) {
  2711. continue;
  2712. } else if (is_type_untyped_nil(args[i].type)) {
  2713. args[i] = lb_const_nil(m, e->type);
  2714. } else if (is_type_untyped_undef(args[i].type)) {
  2715. args[i] = lb_const_undef(m, e->type);
  2716. }
  2717. }
  2718. }
  2719. auto call_args = array_slice(args, 0, final_count);
  2720. return lb_emit_call(p, value, call_args, ce->inlining, p->copy_elision_hint.ast == expr);
  2721. }