llvmdef.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. {
  2. Copyright (c) 2013 by Jonas Maebe
  3. This unit implements some LLVM type helper routines.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. {$i fpcdefs.inc}
  18. unit llvmdef;
  19. interface
  20. uses
  21. cclasses,globtype,
  22. parabase,
  23. symbase,symtype,symdef,
  24. llvmbase;
  25. type
  26. { there are three different circumstances in which procdefs are used:
  27. a) definition of a procdef that's implemented in the current module or
  28. declaration of an external routine that's called in the current one
  29. b) alias declaration of a procdef implemented in the current module
  30. c) defining a procvar type
  31. The main differences between the contexts are:
  32. a) information about sign extension of result type, proc name, parameter names & types
  33. b) no information about sign extension of result type, proc name, no parameter names, parameter types
  34. c) information about sign extension of result type, no proc name, no parameter names, parameter types
  35. }
  36. tllvmprocdefdecltype = (lpd_decl,lpd_alias,lpd_procvar);
  37. { Encode a type into the internal format used by LLVM. }
  38. function llvmencodetype(def: tdef): TSymStr;
  39. { incremental version of llvmencodetype(). "inaggregate" indicates whether
  40. this was a recursive call to get the type of an entity part of an
  41. aggregate type (array, record, ...) }
  42. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  43. { encode a procdef/procvardef into the internal format used by LLVM }
  44. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  45. { incremental version of the above }
  46. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  47. { function result types may have to be represented differently, e.g. a
  48. record consisting of 4 longints must be returned as a record consisting of
  49. two int64's on x86-64. This function is used to create (and reuse)
  50. temporary recorddefs for such purposes.}
  51. function llvmgettemprecorddef(fieldtypes: tfplist; packrecords: shortint): trecorddef;
  52. { get the llvm type corresponding to a parameter, e.g. a record containing
  53. two integer int64 for an arbitrary record split over two individual int64
  54. parameters, or an int32 for an int16 parameter on a platform that requires
  55. such parameters to be zero/sign extended. The second parameter can be used
  56. to get the type before zero/sign extension, as e.g. required to generate
  57. function declarations. }
  58. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean): tdef;
  59. { can be used to extract the value extension info from acgpara. Pass in
  60. the def of the cgpara as first parameter and a local variable holding
  61. a copy of the def of the location (value extension only makes sense for
  62. ordinal parameters that are smaller than a single location). The routine
  63. will return the def of the location without sign extension (if applicable)
  64. and the kind of sign extension that was originally performed in the
  65. signext parameter }
  66. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  67. { returns whether a paraloc should be translated into an llvm "byval"
  68. parameter. These are declared as pointers to a particular type, but
  69. usually turned into copies onto the stack. The exact behaviour for
  70. parameters that should be passed in registers is undefined and depends on
  71. the platform, and furthermore this modifier sometimes inhibits
  72. optimizations. As a result,we only use it for aggregate parameters of
  73. which we know that they should be passed on the stack }
  74. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  75. { returns whether a def is representated by an aggregate type in llvm
  76. (struct, array) }
  77. function llvmaggregatetype(def: tdef): boolean;
  78. function llvmconvop(fromsize, tosize: tdef): tllvmop;
  79. implementation
  80. uses
  81. cutils,constexp,
  82. verbose,systems,
  83. fmodule,
  84. symtable,symconst,symsym,
  85. llvmsym,hlcgobj,
  86. defutil,cgbase,paramgr;
  87. {******************************************************************
  88. Type encoding
  89. *******************************************************************}
  90. function llvmaggregatetype(def: tdef): boolean;
  91. begin
  92. result:=
  93. (def.typ in [recorddef,filedef,variantdef]) or
  94. ((def.typ=arraydef) and
  95. not is_dynamic_array(def)) or
  96. ((def.typ=setdef) and
  97. not is_smallset(def)) or
  98. is_shortstring(def) or
  99. is_object(def) or
  100. ((def.typ=procvardef) and
  101. not tprocvardef(def).is_addressonly)
  102. end;
  103. function llvmconvop(fromsize, tosize: tdef): tllvmop;
  104. var
  105. fromregtyp,
  106. toregtyp: tregistertype;
  107. frombytesize,
  108. tobytesize: asizeint;
  109. begin
  110. fromregtyp:=hlcg.def2regtyp(fromsize);
  111. toregtyp:=hlcg.def2regtyp(tosize);
  112. { int to pointer or vice versa }
  113. if fromregtyp=R_ADDRESSREGISTER then
  114. begin
  115. case toregtyp of
  116. R_INTREGISTER:
  117. result:=la_ptrtoint;
  118. R_ADDRESSREGISTER:
  119. result:=la_bitcast;
  120. else
  121. result:=la_ptrtoint_to_x;
  122. end;
  123. end
  124. else if toregtyp=R_ADDRESSREGISTER then
  125. begin
  126. case fromregtyp of
  127. R_INTREGISTER:
  128. result:=la_inttoptr;
  129. R_ADDRESSREGISTER:
  130. result:=la_bitcast;
  131. else
  132. result:=la_x_to_inttoptr;
  133. end;
  134. end
  135. else
  136. begin
  137. frombytesize:=fromsize.size;
  138. tobytesize:=tosize.size;
  139. { need zero/sign extension, float truncation or plain bitcast? }
  140. if tobytesize<>frombytesize then
  141. begin
  142. case fromregtyp of
  143. R_FPUREGISTER,
  144. R_MMREGISTER:
  145. begin
  146. { todo: update once we support vectors }
  147. if not(toregtyp in [R_FPUREGISTER,R_MMREGISTER]) then
  148. internalerror(2014062203);
  149. if tobytesize<frombytesize then
  150. result:=la_fptrunc
  151. else
  152. result:=la_fpext
  153. end;
  154. else
  155. begin
  156. if tobytesize<frombytesize then
  157. result:=la_trunc
  158. else if is_signed(fromsize) then
  159. { fromsize is signed -> sign extension }
  160. result:=la_sext
  161. else
  162. result:=la_zext;
  163. end;
  164. end;
  165. end
  166. else
  167. result:=la_bitcast;
  168. end;
  169. end;
  170. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  171. begin
  172. { "byval" is broken for register paras on several platforms in llvm
  173. (search for "byval" in llvm's bug tracker). Additionally, it should only
  174. be used to pass aggregate parameters on the stack, because it reportedly
  175. inhibits llvm's midlevel optimizers.
  176. Exception (for now?): parameters that have special shifting
  177. requirements, because modelling those in llvm is not easy (and clang
  178. nor llvm-gcc seem to do so either) }
  179. result:=
  180. ((paraloc^.loc=LOC_REFERENCE) and
  181. llvmaggregatetype(paraloc^.def)) or
  182. (paraloc^.shiftval<>0)
  183. end;
  184. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr); forward;
  185. procedure llvmaddencodedtype_intern(def: tdef; inaggregate, noimplicitderef: boolean; var encodedstr: TSymStr);
  186. begin
  187. case def.typ of
  188. stringdef :
  189. begin
  190. case tstringdef(def).stringtype of
  191. st_widestring,
  192. st_unicodestring:
  193. { the variable does not point to the header, but to a
  194. null-terminated string/array with undefined bounds }
  195. encodedstr:=encodedstr+'i16*';
  196. st_ansistring:
  197. encodedstr:=encodedstr+'i8*';
  198. st_shortstring:
  199. { length byte followed by string bytes }
  200. if tstringdef(def).len>0 then
  201. encodedstr:=encodedstr+'['+tostr(tstringdef(def).len+1)+' x i8]'
  202. else
  203. encodedstr:=encodedstr+'[0 x i8]';
  204. else
  205. internalerror(2013100201);
  206. end;
  207. end;
  208. enumdef:
  209. begin
  210. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  211. end;
  212. orddef :
  213. begin
  214. if is_void(def) then
  215. encodedstr:=encodedstr+'void'
  216. { mainly required because comparison operations return i1, and
  217. otherwise we always have to immediatel extend them to i8 for
  218. no good reason; besides, Pascal booleans can only contain 0
  219. or 1 in valid code anyway (famous last words...) }
  220. else if torddef(def).ordtype=pasbool8 then
  221. encodedstr:=encodedstr+'i1'
  222. else
  223. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  224. end;
  225. pointerdef :
  226. begin
  227. if is_voidpointer(def) then
  228. encodedstr:=encodedstr+'i8*'
  229. else
  230. begin
  231. llvmaddencodedtype_intern(tpointerdef(def).pointeddef,inaggregate,false,encodedstr);
  232. encodedstr:=encodedstr+'*';
  233. end;
  234. end;
  235. floatdef :
  236. begin
  237. case tfloatdef(def).floattype of
  238. s32real:
  239. encodedstr:=encodedstr+'float';
  240. s64real:
  241. encodedstr:=encodedstr+'double';
  242. { necessary to be able to force our own size/alignment }
  243. s80real:
  244. { prevent llvm from allocating the standard ABI size for
  245. extended }
  246. if inaggregate then
  247. encodedstr:=encodedstr+'[10 x i8]'
  248. else
  249. encodedstr:=encodedstr+'x86_fp80';
  250. sc80real:
  251. encodedstr:=encodedstr+'x86_fp80';
  252. s64comp,
  253. s64currency:
  254. encodedstr:=encodedstr+'i64';
  255. s128real:
  256. {$if defined(powerpc) or defined(powerpc128)}
  257. encodedstr:=encodedstr+'ppc_fp128';
  258. {$else}
  259. encodedstr:=encodedstr+'fp128';
  260. {$endif}
  261. else
  262. internalerror(2013100202);
  263. end;
  264. end;
  265. filedef :
  266. begin
  267. case tfiledef(def).filetyp of
  268. ft_text :
  269. llvmaddencodedtype_intern(search_system_type('TEXTREC').typedef,inaggregate,false,encodedstr);
  270. ft_typed,
  271. ft_untyped :
  272. llvmaddencodedtype_intern(search_system_type('FILEREC').typedef,inaggregate,false,encodedstr);
  273. else
  274. internalerror(2013100203);
  275. end;
  276. end;
  277. recorddef :
  278. begin
  279. llvmaddencodedabstractrecordtype(trecorddef(def),encodedstr);
  280. end;
  281. variantdef :
  282. begin
  283. llvmaddencodedtype_intern(search_system_type('TVARDATA').typedef,inaggregate,false,encodedstr);
  284. end;
  285. classrefdef :
  286. begin
  287. { todo: define proper type for VMT and use that }
  288. encodedstr:=encodedstr+'i8*';
  289. end;
  290. setdef :
  291. begin
  292. { just an array as far as llvm is concerned; don't use a "packed
  293. array of i1" or so, this requires special support in backends
  294. and guarantees nothing about the internal format }
  295. if is_smallset(def) then
  296. llvmaddencodedtype_intern(cgsize_orddef(def_cgsize(def)),inaggregate,false,encodedstr)
  297. else
  298. encodedstr:=encodedstr+'['+tostr(tsetdef(def).size)+' x i8]';
  299. end;
  300. formaldef :
  301. begin
  302. { var/const/out x }
  303. encodedstr:=encodedstr+'i8*';
  304. end;
  305. arraydef :
  306. begin
  307. if is_array_of_const(def) then
  308. begin
  309. encodedstr:=encodedstr+'[0 x ';
  310. llvmaddencodedtype_intern(search_system_type('TVARREC').typedef,true,false,encodedstr);
  311. encodedstr:=encodedstr+']';
  312. end
  313. else if is_open_array(def) then
  314. begin
  315. encodedstr:=encodedstr+'[0 x ';
  316. llvmaddencodedtype_intern(tarraydef(def).elementdef,true,false,encodedstr);
  317. encodedstr:=encodedstr+']';
  318. end
  319. else if is_dynamic_array(def) then
  320. begin
  321. llvmaddencodedtype_intern(tarraydef(def).elementdef,inaggregate,false,encodedstr);
  322. encodedstr:=encodedstr+'*';
  323. end
  324. else if is_packed_array(def) then
  325. begin
  326. encodedstr:=encodedstr+'['+tostr(tarraydef(def).size div tarraydef(def).elementdef.packedbitsize)+' x ';
  327. { encode as an array of integers with the size on which we
  328. perform the packedbits operations }
  329. llvmaddencodedtype_intern(cgsize_orddef(int_cgsize(packedbitsloadsize(tarraydef(def).elementdef.packedbitsize))),true,false,encodedstr);
  330. encodedstr:=encodedstr+']';
  331. end
  332. else
  333. begin
  334. encodedstr:=encodedstr+'['+tostr(tarraydef(def).elecount)+' x ';
  335. llvmaddencodedtype_intern(tarraydef(def).elementdef,true,false,encodedstr);
  336. encodedstr:=encodedstr+']';
  337. end;
  338. end;
  339. procdef,
  340. procvardef :
  341. begin
  342. if (def.typ=procdef) or
  343. tprocvardef(def).is_addressonly then
  344. begin
  345. llvmaddencodedproctype(tabstractprocdef(def),'',lpd_procvar,encodedstr);
  346. encodedstr:=encodedstr+'*';
  347. end
  348. else
  349. begin
  350. encodedstr:=encodedstr+'{';
  351. { code pointer }
  352. llvmaddencodedproctype(tabstractprocdef(def),'',lpd_procvar,encodedstr);
  353. { data pointer (maybe todo: generate actual layout if
  354. available) }
  355. encodedstr:=encodedstr+'*, i8*}';
  356. end;
  357. end;
  358. objectdef :
  359. case tobjectdef(def).objecttype of
  360. odt_class,
  361. odt_objcclass,
  362. odt_object,
  363. odt_cppclass:
  364. begin
  365. { for now don't handle fields yet }
  366. encodedstr:=encodedstr+'{[i8 x '+tostr(def.size)+']}';
  367. if not noimplicitderef and
  368. is_implicit_pointer_object_type(def) then
  369. encodedstr:=encodedstr+'*'
  370. end;
  371. odt_interfacecom,
  372. odt_interfacecom_function,
  373. odt_interfacecom_property,
  374. odt_interfacecorba,
  375. odt_dispinterface,
  376. odt_objcprotocol:
  377. begin
  378. { opaque for now }
  379. encodedstr:=encodedstr+'i8*'
  380. end;
  381. else
  382. internalerror(2013100601);
  383. end;
  384. undefineddef,
  385. errordef :
  386. internalerror(2013100604);
  387. else
  388. internalerror(2013100603);
  389. end;
  390. end;
  391. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  392. begin
  393. llvmaddencodedtype_intern(def,inaggregate,false,encodedstr);
  394. end;
  395. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr);
  396. var
  397. st: tllvmshadowsymtable;
  398. symdeflist: tfpobjectlist;
  399. i: longint;
  400. begin
  401. st:=tabstractrecordsymtable(def.symtable).llvmst;
  402. symdeflist:=st.symdeflist;
  403. if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
  404. encodedstr:=encodedstr+'<';
  405. encodedstr:=encodedstr+'{ ';
  406. if symdeflist.count>0 then
  407. begin
  408. i:=0;
  409. if (def.typ=objectdef) and
  410. assigned(tobjectdef(def).childof) and
  411. is_class_or_interface_or_dispinterface(tllvmshadowsymtableentry(symdeflist[0]).def) then
  412. begin
  413. { insert the struct for the class rather than a pointer to the struct }
  414. if (tllvmshadowsymtableentry(symdeflist[0]).def.typ<>objectdef) then
  415. internalerror(2008070601);
  416. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[0]).def,true,true,encodedstr);
  417. inc(i);
  418. end;
  419. while i<symdeflist.count do
  420. begin
  421. if i<>0 then
  422. encodedstr:=encodedstr+', ';
  423. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[i]).def,true,false,encodedstr);
  424. inc(i);
  425. end;
  426. end;
  427. encodedstr:=encodedstr+' }';
  428. if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
  429. encodedstr:=encodedstr+'>';
  430. end;
  431. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  432. begin
  433. { implicit zero/sign extension for ABI compliance? (yes, if the size
  434. of a paraloc is larger than the size of the entire parameter) }
  435. if is_ordinal(paradef) and
  436. is_ordinal(paralocdef) and
  437. (paradef.size<paralocdef.size) then
  438. begin
  439. paralocdef:=paradef;
  440. if is_signed(paradef) then
  441. signext:=lve_signext
  442. else
  443. signext:=lve_zeroext
  444. end
  445. else
  446. signext:=lve_none;
  447. end;
  448. procedure llvmaddencodedparaloctype(hp: tparavarsym; proccalloption: tproccalloption; withparaname: boolean; var first: boolean; var encodedstr: TSymStr);
  449. var
  450. paraloc: PCGParaLocation;
  451. signext: tllvmvalueextension;
  452. usedef: tdef;
  453. begin
  454. paraloc:=hp.paraloc[calleeside].location;
  455. repeat
  456. usedef:=paraloc^.def;
  457. llvmextractvalueextinfo(hp.vardef,usedef,signext);
  458. { implicit zero/sign extension for ABI compliance? }
  459. if not first then
  460. encodedstr:=encodedstr+', '
  461. else
  462. first:=false;
  463. llvmaddencodedtype(usedef,false,encodedstr);
  464. { in case signextstr<>'', there should be only one paraloc -> no need
  465. to clear (reason: it means that the paraloc is larger than the
  466. original parameter) }
  467. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  468. { sret: hidden pointer for structured function result }
  469. if vo_is_funcret in hp.varoptions then
  470. encodedstr:=encodedstr+' sret'
  471. else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
  472. llvmbyvalparaloc(paraloc) then
  473. encodedstr:=encodedstr+'* byval';
  474. if withparaname then
  475. begin
  476. if paraloc^.llvmloc.loc<>LOC_REFERENCE then
  477. internalerror(2014010803);
  478. encodedstr:=encodedstr+' '+paraloc^.llvmloc.sym.name;
  479. end;
  480. paraloc:=paraloc^.next;
  481. until not assigned(paraloc);
  482. end;
  483. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  484. begin
  485. result:='';
  486. llvmaddencodedproctype(def,customname,pddecltype,result);
  487. end;
  488. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  489. var
  490. usedef: tdef;
  491. paranr: longint;
  492. hp: tparavarsym;
  493. signext: tllvmvalueextension;
  494. first: boolean;
  495. begin
  496. def.init_paraloc_info(calleeside);
  497. first:=true;
  498. { function result (return-by-ref is handled explicitly) }
  499. if not paramanager.ret_in_param(def.returndef,def) then
  500. begin
  501. usedef:=llvmgetcgparadef(def.funcretloc[calleeside],false);
  502. llvmextractvalueextinfo(def.returndef,usedef,signext);
  503. { specifying result sign extention information for an alias causes
  504. an error for some reason }
  505. if pddecltype in [lpd_decl,lpd_procvar] then
  506. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  507. encodedstr:=encodedstr+' ';
  508. llvmaddencodedtype_intern(usedef,false,false,encodedstr);
  509. end
  510. else
  511. begin
  512. encodedstr:=encodedstr+' ';
  513. llvmaddencodedtype(voidtype,false,encodedstr);
  514. end;
  515. encodedstr:=encodedstr+' ';
  516. { add procname? }
  517. if (pddecltype in [lpd_decl]) and
  518. (def.typ=procdef) then
  519. if customname='' then
  520. encodedstr:=encodedstr+tprocdef(def).mangledname
  521. else
  522. encodedstr:=encodedstr+customname;
  523. encodedstr:=encodedstr+'(';
  524. { parameters }
  525. first:=true;
  526. for paranr:=0 to def.paras.count-1 do
  527. begin
  528. hp:=tparavarsym(def.paras[paranr]);
  529. llvmaddencodedparaloctype(hp,def.proccalloption,pddecltype in [lpd_decl],first,encodedstr);
  530. end;
  531. encodedstr:=encodedstr+')'
  532. end;
  533. function llvmgettemprecorddef(fieldtypes: tfplist; packrecords: shortint): trecorddef;
  534. var
  535. i: longint;
  536. res: PHashSetItem;
  537. oldsymtablestack: tsymtablestack;
  538. hrecst: trecordsymtable;
  539. hdef: tdef;
  540. hrecdef: trecorddef;
  541. sym: tfieldvarsym;
  542. typename: string;
  543. begin
  544. typename:='$llvmstruct_';
  545. for i:=0 to fieldtypes.count-1 do
  546. begin
  547. hdef:=tdef(fieldtypes[i]);
  548. case hdef.typ of
  549. orddef:
  550. case torddef(hdef).ordtype of
  551. s8bit,
  552. u8bit:
  553. typename:=typename+'i8';
  554. s16bit,
  555. u16bit:
  556. typename:=typename+'i16';
  557. s32bit,
  558. u32bit:
  559. typename:=typename+'i32';
  560. s64bit,
  561. u64bit:
  562. typename:=typename+'i64';
  563. else
  564. { other types should not appear currently, add as needed }
  565. internalerror(2014012001);
  566. end;
  567. floatdef:
  568. case tfloatdef(hdef).floattype of
  569. s32real:
  570. typename:=typename+'f32';
  571. s64real:
  572. typename:=typename+'f64';
  573. else
  574. { other types should not appear currently, add as needed }
  575. internalerror(2014012008);
  576. end;
  577. else
  578. { other types should not appear currently, add as needed }
  579. internalerror(2014012009);
  580. end;
  581. end;
  582. if not assigned(current_module) then
  583. internalerror(2014012002);
  584. res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename));
  585. if not assigned(res^.Data) then
  586. begin
  587. oldsymtablestack:=symtablestack;
  588. { do not simply push/pop current_module.localsymtable, because
  589. that can have side-effects (e.g., it removes helpers) }
  590. symtablestack:=nil;
  591. hrecst:=trecordsymtable.create(typename,packrecords);
  592. hrecdef:=trecorddef.create(typename,hrecst);
  593. for i:=0 to fieldtypes.count-1 do
  594. begin
  595. sym:=tfieldvarsym.create('$f'+tostr(i),vs_value,tdef(fieldtypes[i]),[]);
  596. hrecst.insert(sym);
  597. hrecst.addfield(sym,vis_hidden);
  598. end;
  599. res^.Data:=hrecdef;
  600. if assigned(current_module.localsymtable) then
  601. current_module.localsymtable.insertdef(tdef(res^.Data))
  602. else
  603. current_module.globalsymtable.insertdef(tdef(res^.Data));
  604. symtablestack:=oldsymtablestack;
  605. end;
  606. result:=trecorddef(res^.Data);
  607. end;
  608. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean): tdef;
  609. var
  610. retdeflist: tfplist;
  611. retloc: pcgparalocation;
  612. usedef: tdef;
  613. valueext: tllvmvalueextension;
  614. begin
  615. { single location }
  616. if not assigned(cgpara.location^.next) then
  617. begin
  618. { def of the location, except in case of zero/sign-extension }
  619. usedef:=cgpara.location^.def;
  620. if beforevalueext then
  621. llvmextractvalueextinfo(cgpara.def,usedef,valueext);
  622. result:=usedef;
  623. exit
  624. end;
  625. { multiple locations -> create temp record }
  626. retdeflist:=tfplist.create;
  627. retloc:=cgpara.location;
  628. repeat
  629. retdeflist.add(retloc^.def);
  630. retloc:=retloc^.next;
  631. until not assigned(retloc);
  632. result:=llvmgettemprecorddef(retdeflist,C_alignment);
  633. end;
  634. function llvmencodetype(def: tdef): TSymStr;
  635. begin
  636. result:='';
  637. llvmaddencodedtype(def,false,result);
  638. end;
  639. end.