llvm_backend_proc.cpp 101 KB

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