llvmdef.pas 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  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. aasmbase,
  23. parabase,
  24. symconst,symbase,symtype,symdef,
  25. llvmbase;
  26. type
  27. { there are three different circumstances in which procdefs are used:
  28. a) definition of a procdef that's implemented in the current module
  29. b) declaration of an external routine that's called in the current one
  30. c) alias declaration of a procdef implemented in the current module
  31. d) defining a procvar type
  32. The main differences between the contexts are:
  33. a) information about sign extension of result type, proc name, parameter names & sign-extension info & types
  34. b) information about sign extension of result type, proc name, no parameter names, with parameter sign-extension info & types
  35. c) no information about sign extension of result type, proc name, no parameter names, no information about sign extension of parameters, parameter types
  36. d) no information about sign extension of result type, no proc name, no parameter names, no information about sign extension of parameters, parameter types
  37. }
  38. tllvmprocdefdecltype = (lpd_def,lpd_decl,lpd_alias,lpd_procvar);
  39. { returns the identifier to use as typename for a def in llvm (llvm only
  40. allows naming struct types) -- only supported for defs with a typesym, and
  41. only for tabstractrecorddef descendantds and complex procvars }
  42. function llvmtypeidentifier(def: tdef): TSymStr;
  43. { encode a type into the internal format used by LLVM (for a type
  44. declaration) }
  45. function llvmencodetypedecl(def: tdef): TSymStr;
  46. { same as above, but use a type name if possible (for any use) }
  47. function llvmencodetypename(def: tdef): TSymStr;
  48. { encode a procdef/procvardef into the internal format used by LLVM }
  49. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  50. { incremental version of the above }
  51. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  52. { function result types may have to be represented differently, e.g. a
  53. record consisting of 4 longints must be returned as a record consisting of
  54. two int64's on x86-64. This function is used to create (and reuse)
  55. temporary recorddefs for such purposes.}
  56. function llvmgettemprecorddef(const fieldtypes: array of tdef; packrecords, recordalignmin: shortint): trecorddef;
  57. { get the llvm type corresponding to a parameter, e.g. a record containing
  58. two integer int64 for an arbitrary record split over two individual int64
  59. parameters, or an int32 for an int16 parameter on a platform that requires
  60. such parameters to be zero/sign extended. The second parameter can be used
  61. to get the type before zero/sign extension, as e.g. required to generate
  62. function declarations. }
  63. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean; callercallee: tcallercallee): tdef;
  64. { can be used to extract the value extension info from acgpara. Pass in
  65. the def of the cgpara as first parameter and a local variable holding
  66. a copy of the def of the location (value extension only makes sense for
  67. ordinal parameters that are smaller than a single location). The routine
  68. will return the def of the location without sign extension (if applicable)
  69. and the kind of sign extension that was originally performed in the
  70. signext parameter }
  71. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  72. { returns whether a paraloc should be translated into an llvm "byval"
  73. parameter. These are declared as pointers to a particular type, but
  74. usually turned into copies onto the stack. The exact behaviour for
  75. parameters that should be passed in registers is undefined and depends on
  76. the platform, and furthermore this modifier sometimes inhibits
  77. optimizations. As a result,we only use it for aggregate parameters of
  78. which we know that they should be passed on the stack }
  79. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  80. { returns whether a def is representated by an aggregate type in llvm
  81. (struct, array) }
  82. function llvmaggregatetype(def: tdef): boolean;
  83. function llvmconvop(var fromsize, tosize: tdef; inregs: boolean): tllvmop;
  84. { mangle a global identifier so that it's recognised by LLVM as a global
  85. (in the sense of module-global) label and so that it won't mangle the
  86. name further according to platform conventions (we already did that) }
  87. function llvmmangledname(const s: TSymStr): TSymStr;
  88. function llvmasmsymname(const sym: TAsmSymbol): TSymStr;
  89. implementation
  90. uses
  91. globals,cutils,constexp,
  92. verbose,systems,
  93. fmodule,
  94. symtable,symsym,
  95. llvmsym,hlcgobj,
  96. defutil,blockutl,cgbase,paramgr,
  97. cpubase;
  98. {******************************************************************
  99. Type encoding
  100. *******************************************************************}
  101. function llvmtypeidentifier(def: tdef): TSymStr;
  102. begin
  103. if not assigned(def.typesym) then
  104. internalerror(2015041901);
  105. result:='%"typ.'+def.fullownerhierarchyname(false)+def.typesym.realname+'"'
  106. end;
  107. function llvmaggregatetype(def: tdef): boolean;
  108. begin
  109. result:=
  110. (def.typ in [recorddef,filedef,variantdef]) or
  111. ((def.typ=arraydef) and
  112. not is_dynamic_array(def)) or
  113. ((def.typ=setdef) and
  114. not is_smallset(def)) or
  115. is_shortstring(def) or
  116. is_object(def) or
  117. ((def.typ=procvardef) and
  118. not tprocvardef(def).is_addressonly)
  119. end;
  120. function llvmconvop(var fromsize, tosize: tdef; inregs: boolean): tllvmop;
  121. var
  122. fromregtyp,
  123. toregtyp: tregistertype;
  124. frombytesize,
  125. tobytesize: asizeint;
  126. begin
  127. fromregtyp:=chlcgobj.def2regtyp(fromsize);
  128. toregtyp:=chlcgobj.def2regtyp(tosize);
  129. { int to pointer or vice versa }
  130. if fromregtyp=R_ADDRESSREGISTER then
  131. begin
  132. case toregtyp of
  133. R_INTREGISTER:
  134. result:=la_ptrtoint;
  135. R_ADDRESSREGISTER:
  136. result:=la_bitcast;
  137. else
  138. result:=la_ptrtoint_to_x;
  139. end;
  140. end
  141. else if toregtyp=R_ADDRESSREGISTER then
  142. begin
  143. case fromregtyp of
  144. R_INTREGISTER:
  145. result:=la_inttoptr;
  146. R_ADDRESSREGISTER:
  147. result:=la_bitcast;
  148. else
  149. result:=la_x_to_inttoptr;
  150. end;
  151. end
  152. else
  153. begin
  154. { treat comp and currency as extended in registers (see comment at start
  155. of thlgcobj.a_loadfpu_ref_reg) }
  156. if inregs and
  157. (fromsize.typ=floatdef) then
  158. begin
  159. if tfloatdef(fromsize).floattype in [s64comp,s64currency] then
  160. fromsize:=sc80floattype;
  161. { at the value level, s80real and sc80real are the same }
  162. if tfloatdef(fromsize).floattype<>s80real then
  163. frombytesize:=fromsize.size
  164. else
  165. frombytesize:=sc80floattype.size;
  166. end
  167. else
  168. frombytesize:=fromsize.size;
  169. if inregs and
  170. (tosize.typ=floatdef) then
  171. begin
  172. if tfloatdef(tosize).floattype in [s64comp,s64currency] then
  173. tosize:=sc80floattype;
  174. if tfloatdef(tosize).floattype<>s80real then
  175. tobytesize:=tosize.size
  176. else
  177. tobytesize:=sc80floattype.size;
  178. end
  179. else
  180. tobytesize:=tosize.size;
  181. { need zero/sign extension, float truncation or plain bitcast? }
  182. if tobytesize<>frombytesize then
  183. begin
  184. case fromregtyp of
  185. R_FPUREGISTER,
  186. R_MMREGISTER:
  187. begin
  188. { todo: update once we support vectors }
  189. if not(toregtyp in [R_FPUREGISTER,R_MMREGISTER]) then
  190. internalerror(2014062203);
  191. if tobytesize<frombytesize then
  192. result:=la_fptrunc
  193. else
  194. result:=la_fpext
  195. end;
  196. else
  197. begin
  198. if tobytesize<frombytesize then
  199. result:=la_trunc
  200. else if is_signed(fromsize) then
  201. { fromsize is signed -> sign extension }
  202. result:=la_sext
  203. else
  204. result:=la_zext;
  205. end;
  206. end;
  207. end
  208. else if (fromsize=llvmbool1type) and
  209. (tosize<>llvmbool1type) then
  210. begin
  211. if is_cbool(tosize) then
  212. result:=la_sext
  213. else
  214. result:=la_zext
  215. end
  216. else if (tosize=llvmbool1type) and
  217. (fromsize<>llvmbool1type) then
  218. begin
  219. { would have to compare with 0, can't just take the lowest bit }
  220. if is_cbool(fromsize) then
  221. internalerror(2016052001)
  222. else
  223. result:=la_trunc
  224. end
  225. else
  226. result:=la_bitcast;
  227. end;
  228. end;
  229. function llvmmangledname(const s: TSymStr): TSymStr;
  230. begin
  231. if copy(s,1,length('llvm.'))<>'llvm.' then
  232. if s[1]<>'"' then
  233. result:='@"\01'+s+'"'
  234. else
  235. begin
  236. { already quoted -> insert \01 and prepend @ }
  237. result:='@'+s;
  238. insert('\01',result,3);
  239. end
  240. else
  241. result:='@'+s
  242. end;
  243. function llvmasmsymname(const sym: TAsmSymbol): TSymStr;
  244. begin
  245. { AT_ADDR and AT_LABEL represent labels in the code, which have
  246. a different type in llvm compared to (global) data labels }
  247. if sym.bind=AB_TEMP then
  248. result:='%'+sym.name
  249. else if not(sym.typ in [AT_LABEL,AT_ADDR]) then
  250. result:=llvmmangledname(sym.name)
  251. else
  252. result:='label %'+sym.name;
  253. end;
  254. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  255. begin
  256. { "byval" is broken for register paras on several platforms in llvm
  257. (search for "byval" in llvm's bug tracker). Additionally, it should only
  258. be used to pass aggregate parameters on the stack, because it reportedly
  259. inhibits llvm's midlevel optimizers.
  260. Exception (for now?): parameters that have special shifting
  261. requirements, because modelling those in llvm is not easy (and clang
  262. nor llvm-gcc seem to do so either) }
  263. result:=
  264. ((paraloc^.loc=LOC_REFERENCE) and
  265. llvmaggregatetype(paraloc^.def)) or
  266. ((paraloc^.loc in [LOC_REGISTER,LOC_CREGISTER]) and
  267. (paraloc^.shiftval<>0))
  268. end;
  269. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr); forward;
  270. type
  271. tllvmencodeflag = (lef_inaggregate, lef_noimplicitderef, lef_typedecl);
  272. tllvmencodeflags = set of tllvmencodeflag;
  273. procedure llvmaddencodedtype_intern(def: tdef; const flags: tllvmencodeflags; var encodedstr: TSymStr);
  274. begin
  275. case def.typ of
  276. stringdef :
  277. begin
  278. case tstringdef(def).stringtype of
  279. st_widestring,
  280. st_unicodestring:
  281. { the variable does not point to the header, but to a
  282. null-terminated string/array with undefined bounds }
  283. encodedstr:=encodedstr+'i16*';
  284. st_ansistring:
  285. encodedstr:=encodedstr+'i8*';
  286. st_shortstring:
  287. { length byte followed by string bytes }
  288. if tstringdef(def).len>0 then
  289. encodedstr:=encodedstr+'['+tostr(tstringdef(def).len+1)+' x i8]'
  290. else
  291. encodedstr:=encodedstr+'[0 x i8]';
  292. else
  293. internalerror(2013100201);
  294. end;
  295. end;
  296. enumdef:
  297. begin
  298. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  299. end;
  300. orddef :
  301. begin
  302. if is_void(def) then
  303. encodedstr:=encodedstr+'void'
  304. { mainly required because comparison operations return i1, and
  305. we need a way to represent the i1 type in Pascal. We don't
  306. reuse pasbool1type, because putting an i1 in a record or
  307. passing it as a parameter may result in unexpected behaviour }
  308. else if def=llvmbool1type then
  309. encodedstr:=encodedstr+'i1'
  310. else if torddef(def).ordtype<>customint then
  311. encodedstr:=encodedstr+'i'+tostr(def.size*8)
  312. else
  313. encodedstr:=encodedstr+'i'+tostr(def.packedbitsize);
  314. end;
  315. pointerdef :
  316. begin
  317. if def=llvm_metadatatype then
  318. encodedstr:=encodedstr+'metadata'
  319. else if is_voidpointer(def) then
  320. encodedstr:=encodedstr+'i8*'
  321. else
  322. begin
  323. llvmaddencodedtype_intern(tpointerdef(def).pointeddef,[],encodedstr);
  324. encodedstr:=encodedstr+'*';
  325. end;
  326. end;
  327. floatdef :
  328. begin
  329. case tfloatdef(def).floattype of
  330. s32real:
  331. encodedstr:=encodedstr+'float';
  332. s64real:
  333. encodedstr:=encodedstr+'double';
  334. { necessary to be able to force our own size/alignment }
  335. s80real:
  336. { prevent llvm from allocating the standard ABI size for
  337. extended }
  338. if lef_inaggregate in flags then
  339. encodedstr:=encodedstr+'[10 x i8]'
  340. else
  341. encodedstr:=encodedstr+'x86_fp80';
  342. sc80real:
  343. encodedstr:=encodedstr+'x86_fp80';
  344. s64comp,
  345. s64currency:
  346. encodedstr:=encodedstr+'i64';
  347. s128real:
  348. {$if defined(powerpc) or defined(powerpc128)}
  349. encodedstr:=encodedstr+'ppc_fp128';
  350. {$else}
  351. encodedstr:=encodedstr+'fp128';
  352. {$endif}
  353. end;
  354. end;
  355. filedef :
  356. begin
  357. case tfiledef(def).filetyp of
  358. ft_text :
  359. llvmaddencodedtype_intern(search_system_type('TEXTREC').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  360. ft_typed :
  361. begin
  362. { in case of ISO-like I/O, the typed file def includes a
  363. get/put buffer of the size of the file's elements }
  364. if (m_isolike_io in current_settings.modeswitches) and
  365. not is_void(tfiledef(def).typedfiledef) then
  366. encodedstr:=encodedstr+'<{';
  367. llvmaddencodedtype_intern(search_system_type('FILEREC').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  368. if (m_isolike_io in current_settings.modeswitches) and
  369. not is_void(tfiledef(def).typedfiledef) then
  370. begin
  371. encodedstr:=encodedstr+',[';
  372. encodedstr:=encodedstr+tostr(tfiledef(def).typedfiledef.size);
  373. encodedstr:=encodedstr+' x i8]}>'
  374. end;
  375. end;
  376. ft_untyped :
  377. llvmaddencodedtype_intern(search_system_type('FILEREC').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  378. end;
  379. end;
  380. recorddef :
  381. begin
  382. { avoid endlessly recursive definitions }
  383. if assigned(def.typesym) and
  384. ((lef_inaggregate in flags) or
  385. not(lef_typedecl in flags)) then
  386. encodedstr:=encodedstr+llvmtypeidentifier(def)
  387. else
  388. llvmaddencodedabstractrecordtype(trecorddef(def),encodedstr);
  389. end;
  390. variantdef :
  391. begin
  392. llvmaddencodedtype_intern(search_system_type('TVARDATA').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  393. end;
  394. classrefdef :
  395. begin
  396. if is_class(tclassrefdef(def).pointeddef) then
  397. begin
  398. llvmaddencodedtype_intern(tobjectdef(tclassrefdef(def).pointeddef).vmt_def,flags,encodedstr);
  399. encodedstr:=encodedstr+'*';
  400. end
  401. else if is_objcclass(tclassrefdef(def).pointeddef) then
  402. llvmaddencodedtype_intern(objc_idtype,flags,encodedstr)
  403. else
  404. encodedstr:=encodedstr+'i8*'
  405. end;
  406. setdef :
  407. begin
  408. { just an array as far as llvm is concerned; don't use a "packed
  409. array of i1" or so, this requires special support in backends
  410. and guarantees nothing about the internal format }
  411. if is_smallset(def) then
  412. llvmaddencodedtype_intern(cgsize_orddef(def_cgsize(def)),[lef_inaggregate],encodedstr)
  413. else
  414. encodedstr:=encodedstr+'['+tostr(tsetdef(def).size)+' x i8]';
  415. end;
  416. formaldef :
  417. begin
  418. { var/const/out x (always treated as "pass by reference" -> don't
  419. add extra "*" here) }
  420. encodedstr:=encodedstr+'i8';
  421. end;
  422. arraydef :
  423. begin
  424. if tarraydef(def).is_hwvector then
  425. begin
  426. encodedstr:=encodedstr+'<'+tostr(tarraydef(def).elecount)+' x ';
  427. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  428. encodedstr:=encodedstr+'>';
  429. end
  430. else if is_array_of_const(def) then
  431. begin
  432. encodedstr:=encodedstr+'[0 x ';
  433. llvmaddencodedtype_intern(search_system_type('TVARREC').typedef,[lef_inaggregate],encodedstr);
  434. encodedstr:=encodedstr+']';
  435. end
  436. else if is_open_array(def) then
  437. begin
  438. encodedstr:=encodedstr+'[0 x ';
  439. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  440. encodedstr:=encodedstr+']';
  441. end
  442. else if is_dynamic_array(def) then
  443. begin
  444. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  445. encodedstr:=encodedstr+'*';
  446. end
  447. else if is_packed_array(def) and
  448. (tarraydef(def).elementdef.typ in [enumdef,orddef]) then
  449. begin
  450. { encode as an array of bytes rather than as an array of
  451. packedbitsloadsize(elesize), because even if the load size
  452. is e.g. 2 bytes, the array may only be 1 or 3 bytes long
  453. (and if this array is inside a record, it must not be
  454. encoded as a type that is too long) }
  455. encodedstr:=encodedstr+'['+tostr(tarraydef(def).size)+' x ';
  456. llvmaddencodedtype_intern(u8inttype,[lef_inaggregate],encodedstr);
  457. encodedstr:=encodedstr+']';
  458. end
  459. else
  460. begin
  461. encodedstr:=encodedstr+'['+tostr(tarraydef(def).elecount)+' x ';
  462. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  463. encodedstr:=encodedstr+']';
  464. end;
  465. end;
  466. procdef,
  467. procvardef :
  468. begin
  469. if (def.typ=procdef) or
  470. tprocvardef(def).is_addressonly then
  471. begin
  472. llvmaddencodedproctype(tabstractprocdef(def),'',lpd_procvar,encodedstr);
  473. if def.typ=procvardef then
  474. encodedstr:=encodedstr+'*';
  475. end
  476. else if ((lef_inaggregate in flags) or
  477. not(lef_typedecl in flags)) and
  478. assigned(tprocvardef(def).typesym) then
  479. begin
  480. { in case the procvardef recursively references itself, e.g.
  481. via a pointer }
  482. encodedstr:=encodedstr+llvmtypeidentifier(def);
  483. { blocks are implicit pointers }
  484. if is_block(def) then
  485. encodedstr:=encodedstr+'*'
  486. end
  487. else if is_block(def) then
  488. begin
  489. llvmaddencodedtype_intern(get_block_literal_type_for_proc(tabstractprocdef(def)),flags,encodedstr);
  490. end
  491. else
  492. begin
  493. encodedstr:=encodedstr+'<{';
  494. { code pointer }
  495. llvmaddencodedproctype(tabstractprocdef(def),'',lpd_procvar,encodedstr);
  496. { data pointer (maybe todo: generate actual layout if
  497. available) }
  498. encodedstr:=encodedstr+'*, i8*}>';
  499. end;
  500. end;
  501. objectdef :
  502. case tobjectdef(def).objecttype of
  503. odt_class,
  504. odt_objcclass,
  505. odt_object,
  506. odt_cppclass:
  507. begin
  508. if not(lef_typedecl in flags) and
  509. assigned(def.typesym) then
  510. encodedstr:=encodedstr+llvmtypeidentifier(def)
  511. else
  512. llvmaddencodedabstractrecordtype(tabstractrecorddef(def),encodedstr);
  513. if ([lef_typedecl,lef_noimplicitderef]*flags=[]) and
  514. is_implicit_pointer_object_type(def) then
  515. encodedstr:=encodedstr+'*'
  516. end;
  517. odt_interfacecom,
  518. odt_interfacecorba,
  519. odt_dispinterface:
  520. begin
  521. { type is a pointer to a pointer to the vmt }
  522. llvmaddencodedtype_intern(tobjectdef(def).vmt_def,flags,encodedstr);
  523. if ([lef_typedecl,lef_noimplicitderef]*flags=[]) then
  524. encodedstr:=encodedstr+'**';
  525. end;
  526. odt_interfacecom_function,
  527. odt_interfacecom_property,
  528. odt_objcprotocol:
  529. begin
  530. { opaque for now }
  531. encodedstr:=encodedstr+'i8*'
  532. end;
  533. odt_helper:
  534. llvmaddencodedtype_intern(tobjectdef(def).extendeddef,flags,encodedstr);
  535. else
  536. internalerror(2013100601);
  537. end;
  538. undefineddef,
  539. errordef :
  540. internalerror(2013100604);
  541. else
  542. internalerror(2013100603);
  543. end;
  544. end;
  545. function llvmencodetypename(def: tdef): TSymStr;
  546. begin
  547. result:='';
  548. llvmaddencodedtype_intern(def,[],result);
  549. end;
  550. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  551. var
  552. flags: tllvmencodeflags;
  553. begin
  554. if inaggregate then
  555. flags:=[lef_inaggregate]
  556. else
  557. flags:=[];
  558. llvmaddencodedtype_intern(def,flags,encodedstr);
  559. end;
  560. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr);
  561. var
  562. st: tllvmshadowsymtable;
  563. symdeflist: tfpobjectlist;
  564. i: longint;
  565. nopacked: boolean;
  566. begin
  567. st:=tabstractrecordsymtable(def.symtable).llvmst;
  568. symdeflist:=st.symdeflist;
  569. nopacked:=df_llvm_no_struct_packing in def.defoptions;
  570. if nopacked then
  571. encodedstr:=encodedstr+'{ '
  572. else
  573. encodedstr:=encodedstr+'<{ ';
  574. if symdeflist.count>0 then
  575. begin
  576. i:=0;
  577. if (def.typ=objectdef) and
  578. assigned(tobjectdef(def).childof) and
  579. is_class_or_interface_or_dispinterface(tllvmshadowsymtableentry(symdeflist[0]).def) then
  580. begin
  581. { insert the struct for the class rather than a pointer to the struct }
  582. if (tllvmshadowsymtableentry(symdeflist[0]).def.typ<>objectdef) then
  583. internalerror(2008070601);
  584. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[0]).def,[lef_inaggregate,lef_noimplicitderef],encodedstr);
  585. inc(i);
  586. end;
  587. while i<symdeflist.count do
  588. begin
  589. if i<>0 then
  590. encodedstr:=encodedstr+', ';
  591. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[i]).def,[lef_inaggregate],encodedstr);
  592. inc(i);
  593. end;
  594. end;
  595. if nopacked then
  596. encodedstr:=encodedstr+' }'
  597. else
  598. encodedstr:=encodedstr+' }>';
  599. end;
  600. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  601. begin
  602. { implicit zero/sign extension for ABI compliance? (yes, if the size
  603. of a paraloc is larger than the size of the entire parameter) }
  604. if is_ordinal(paradef) and
  605. is_ordinal(paralocdef) and
  606. (paradef.size<paralocdef.size) then
  607. begin
  608. paralocdef:=paradef;
  609. if is_signed(paradef) then
  610. signext:=lve_signext
  611. else
  612. signext:=lve_zeroext
  613. end
  614. else
  615. signext:=lve_none;
  616. end;
  617. procedure llvmaddencodedparaloctype(hp: tparavarsym; proccalloption: tproccalloption; withparaname, withattributes: boolean; var first: boolean; var encodedstr: TSymStr);
  618. var
  619. para: PCGPara;
  620. paraloc: PCGParaLocation;
  621. side: tcallercallee;
  622. signext: tllvmvalueextension;
  623. usedef: tdef;
  624. firstloc: boolean;
  625. begin
  626. if (proccalloption in cdecl_pocalls) and
  627. is_array_of_const(hp.vardef) then
  628. begin
  629. if not first then
  630. encodedstr:=encodedstr+', '
  631. else
  632. first:=false;
  633. encodedstr:=encodedstr+'...';
  634. exit
  635. end;
  636. if not withparaname then
  637. side:=callerside
  638. else
  639. side:=calleeside;
  640. { don't add parameters that don't take up registers or stack space;
  641. clang doesn't either and some LLVM backends don't support them }
  642. if hp.paraloc[side].isempty then
  643. exit;
  644. para:[email protected][side];
  645. paraloc:=para^.location;
  646. firstloc:=true;
  647. repeat
  648. usedef:=paraloc^.def;
  649. llvmextractvalueextinfo(hp.vardef,usedef,signext);
  650. { implicit zero/sign extension for ABI compliance? }
  651. if not first then
  652. encodedstr:=encodedstr+', ';
  653. llvmaddencodedtype_intern(usedef,[],encodedstr);
  654. { in case signextstr<>'', there should be only one paraloc -> no need
  655. to clear (reason: it means that the paraloc is larger than the
  656. original parameter) }
  657. if withattributes then
  658. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  659. { sret: hidden pointer for structured function result }
  660. if vo_is_funcret in hp.varoptions then
  661. begin
  662. { "sret" is only valid for the firstparameter, while in FPC this
  663. can sometimes be second one (self comes before). In general,
  664. this is not a problem: we can just leave out sret, which means
  665. the result will be a bit less well optimised), but it is for
  666. AArch64: there, the sret parameter must be passed in a different
  667. register (-> paranr_result is smaller than paranr_self for that
  668. platform in symconst) }
  669. {$ifdef aarch64}
  670. if not first then
  671. internalerror(2015101404);
  672. {$endif aarch64}
  673. if withattributes then
  674. if first then
  675. encodedstr:=encodedstr+' sret noalias nocapture'
  676. else
  677. encodedstr:=encodedstr+' noalias nocapture';
  678. end
  679. else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
  680. llvmbyvalparaloc(paraloc) then
  681. begin
  682. if withattributes then
  683. begin
  684. encodedstr:=encodedstr+'* byval';
  685. if firstloc and
  686. (para^.alignment<>std_param_align) then
  687. begin
  688. encodedstr:=encodedstr+' align '+tostr(para^.alignment);
  689. end;
  690. end
  691. else
  692. encodedstr:=encodedstr+'*';
  693. end
  694. else if withattributes and
  695. paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) then
  696. begin
  697. { it's not valid to take the address of a parameter and store it for
  698. use past the end of the function call (since the address can always
  699. be on the stack and become invalid later) }
  700. encodedstr:=encodedstr+' nocapture';
  701. { open array/array of const/variant array may be a valid pointer but empty }
  702. if not is_special_array(hp.vardef) and
  703. { e.g. empty records }
  704. (hp.vardef.size<>0) then
  705. begin
  706. case hp.varspez of
  707. vs_value,
  708. vs_const:
  709. begin
  710. encodedstr:=encodedstr+' readonly dereferenceable('
  711. end;
  712. vs_var,
  713. vs_out:
  714. begin
  715. { while normally these are not nil, it is technically possible
  716. to pass nil via ptrtype(nil)^ }
  717. encodedstr:=encodedstr+' dereferenceable_or_null(';
  718. end;
  719. vs_constref:
  720. begin
  721. encodedstr:=encodedstr+' readonly dereferenceable_or_null(';
  722. end;
  723. else
  724. internalerror(2018120801);
  725. end;
  726. if hp.vardef.typ<>formaldef then
  727. encodedstr:=encodedstr+tostr(hp.vardef.size)+')'
  728. else
  729. encodedstr:=encodedstr+'1)';
  730. end;
  731. end;
  732. if withparaname then
  733. begin
  734. if paraloc^.llvmloc.loc<>LOC_REFERENCE then
  735. internalerror(2014010803);
  736. encodedstr:=encodedstr+' '+llvmasmsymname(paraloc^.llvmloc.sym);
  737. end;
  738. paraloc:=paraloc^.next;
  739. firstloc:=false;
  740. first:=false;
  741. until not assigned(paraloc);
  742. end;
  743. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  744. begin
  745. result:='';
  746. llvmaddencodedproctype(def,customname,pddecltype,result);
  747. end;
  748. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  749. var
  750. callingconv: ansistring;
  751. usedef: tdef;
  752. paranr: longint;
  753. hp: tparavarsym;
  754. signext: tllvmvalueextension;
  755. useside: tcallercallee;
  756. first: boolean;
  757. begin
  758. if not(pddecltype in [lpd_alias,lpd_procvar]) then
  759. begin
  760. callingconv:=llvm_callingconvention_name(def.proccalloption);
  761. if callingconv<>'' then
  762. encodedstr:=encodedstr+' '+callingconv;
  763. end;
  764. { when writing a definition, we have to write the parameter names, and
  765. those are only available on the callee side. In all other cases,
  766. we are at the callerside }
  767. if pddecltype=lpd_def then
  768. useside:=calleeside
  769. else
  770. useside:=callerside;
  771. def.init_paraloc_info(useside);
  772. first:=true;
  773. { function result (return-by-ref is handled explicitly) }
  774. if not paramanager.ret_in_param(def.returndef,def) or
  775. def.generate_safecall_wrapper then
  776. begin
  777. if not def.generate_safecall_wrapper then
  778. usedef:=llvmgetcgparadef(def.funcretloc[useside],false,useside)
  779. else
  780. usedef:=ossinttype;
  781. llvmextractvalueextinfo(def.returndef,usedef,signext);
  782. { specifying result sign extention information for an alias causes
  783. an error for some reason }
  784. if pddecltype in [lpd_decl,lpd_def] then
  785. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  786. encodedstr:=encodedstr+' ';
  787. llvmaddencodedtype_intern(usedef,[],encodedstr);
  788. end
  789. else
  790. begin
  791. encodedstr:=encodedstr+' ';
  792. llvmaddencodedtype(voidtype,false,encodedstr);
  793. end;
  794. encodedstr:=encodedstr+' ';
  795. { add procname? }
  796. if (pddecltype in [lpd_decl,lpd_def]) and
  797. (def.typ=procdef) then
  798. if customname='' then
  799. encodedstr:=encodedstr+llvmmangledname(tprocdef(def).mangledname)
  800. else
  801. encodedstr:=encodedstr+llvmmangledname(customname);
  802. encodedstr:=encodedstr+'(';
  803. { parameters }
  804. first:=true;
  805. for paranr:=0 to def.paras.count-1 do
  806. begin
  807. hp:=tparavarsym(def.paras[paranr]);
  808. llvmaddencodedparaloctype(hp,def.proccalloption,pddecltype in [lpd_def],not(pddecltype in [lpd_procvar,lpd_alias]),first,encodedstr);
  809. end;
  810. if po_varargs in def.procoptions then
  811. begin
  812. if not first then
  813. encodedstr:=encodedstr+', ';
  814. encodedstr:=encodedstr+'...';
  815. end;
  816. encodedstr:=encodedstr+')'
  817. end;
  818. function llvmgettemprecorddef(const fieldtypes: array of tdef; packrecords, recordalignmin: shortint): trecorddef;
  819. var
  820. i: longint;
  821. res: PHashSetItem;
  822. oldsymtablestack: tsymtablestack;
  823. hrecst: trecordsymtable;
  824. hdef: tdef;
  825. hrecdef: trecorddef;
  826. sym: tfieldvarsym;
  827. typename: string;
  828. begin
  829. typename:=internaltypeprefixName[itp_llvmstruct];
  830. for i:=low(fieldtypes) to high(fieldtypes) do
  831. begin
  832. hdef:=fieldtypes[i];
  833. case hdef.typ of
  834. orddef:
  835. case torddef(hdef).ordtype of
  836. s8bit,
  837. u8bit,
  838. pasbool1,
  839. pasbool8:
  840. typename:=typename+'i8';
  841. s16bit,
  842. u16bit:
  843. typename:=typename+'i16';
  844. s32bit,
  845. u32bit:
  846. typename:=typename+'i32';
  847. s64bit,
  848. u64bit:
  849. typename:=typename+'i64';
  850. customint:
  851. typename:=typename+'i'+tostr(torddef(hdef).packedbitsize);
  852. else
  853. { other types should not appear currently, add as needed }
  854. internalerror(2014012001);
  855. end;
  856. floatdef:
  857. case tfloatdef(hdef).floattype of
  858. s32real:
  859. typename:=typename+'f32';
  860. s64real:
  861. typename:=typename+'f64';
  862. else
  863. { other types should not appear currently, add as needed }
  864. internalerror(2014012008);
  865. end;
  866. else
  867. typename:=typename+'d'+hdef.unique_id_str;
  868. end;
  869. end;
  870. if not assigned(current_module) then
  871. internalerror(2014012002);
  872. res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename));
  873. if not assigned(res^.Data) then
  874. begin
  875. res^.Data:=crecorddef.create_global_internal(typename,packrecords,
  876. recordalignmin);
  877. for i:=low(fieldtypes) to high(fieldtypes) do
  878. trecorddef(res^.Data).add_field_by_def('F'+tostr(i),fieldtypes[i]);
  879. end;
  880. trecordsymtable(trecorddef(res^.Data).symtable).addalignmentpadding;
  881. result:=trecorddef(res^.Data);
  882. end;
  883. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean; callercallee: tcallercallee): tdef;
  884. var
  885. retdeflist: array[0..9] of tdef;
  886. retloc: pcgparalocation;
  887. usedef: tdef;
  888. valueext: tllvmvalueextension;
  889. paraslots,
  890. i: longint;
  891. sizeleft: asizeint;
  892. begin
  893. { single location }
  894. if not assigned(cgpara.location^.next) then
  895. begin
  896. { def of the location, except in case of zero/sign-extension and
  897. zero-sized records }
  898. if not is_special_array(cgpara.def) and
  899. (cgpara.def.size=0) then
  900. usedef:=cgpara.def
  901. else
  902. usedef:=cgpara.location^.def;
  903. if beforevalueext then
  904. llvmextractvalueextinfo(cgpara.def,usedef,valueext);
  905. { comp and currency are handled by the x87 in this case. They cannot
  906. be represented directly in llvm, and llvmdef translates them into
  907. i64 (since that's their storage size and internally they also are
  908. int64). Solve this by changing the type to s80real in the
  909. returndef/parameter declaration. }
  910. if (usedef.typ=floatdef) and
  911. (tfloatdef(usedef).floattype in [s64comp,s64currency]) then
  912. usedef:=s80floattype;
  913. result:=usedef;
  914. exit
  915. end;
  916. { multiple locations -> create temp record }
  917. retloc:=cgpara.location;
  918. i:=0;
  919. sizeleft:=cgpara.Def.size;
  920. repeat
  921. if i>high(retdeflist) then
  922. internalerror(2016121801);
  923. if assigned(retloc^.next) then
  924. begin
  925. retdeflist[i]:=retloc^.def;
  926. dec(sizeleft,retloc^.def.size);
  927. end
  928. { on the callerside, "byval" parameter locations have the implicit
  929. pointer in their type -> remove if we wish to create a record
  930. containing all actual parameter data }
  931. else if (callercallee=callerside) and
  932. not retloc^.llvmvalueloc then
  933. begin
  934. if retloc^.def.typ<>pointerdef then
  935. internalerror(2019020201);
  936. retdeflist[i]:=tpointerdef(retloc^.def).pointeddef
  937. end
  938. else if retloc^.def.size<>sizeleft then
  939. begin
  940. case sizeleft of
  941. 1:
  942. retdeflist[i]:=u8inttype;
  943. 2:
  944. retdeflist[i]:=u16inttype;
  945. 3:
  946. retdeflist[i]:=u24inttype;
  947. 4:
  948. retdeflist[i]:=u32inttype;
  949. 5:
  950. retdeflist[i]:=u40inttype;
  951. 6:
  952. retdeflist[i]:=u48inttype;
  953. 7:
  954. retdeflist[i]:=u56inttype;
  955. else
  956. retdeflist[i]:=retloc^.def;
  957. end
  958. end
  959. else
  960. begin
  961. if retloc^.def.typ<>floatdef then
  962. begin
  963. paraslots:=sizeleft div cgpara.Alignment;
  964. if (paraslots>1) and
  965. ((paraslots*cgpara.Alignment)=sizeleft) then
  966. retdeflist[i]:=carraydef.getreusable(cgsize_orddef(int_cgsize(cgpara.Alignment)),paraslots)
  967. else
  968. retdeflist[i]:=retloc^.def;
  969. end
  970. else
  971. retdeflist[i]:=retloc^.def;
  972. end;
  973. inc(i);
  974. retloc:=retloc^.next;
  975. until not assigned(retloc);
  976. result:=llvmgettemprecorddef(slice(retdeflist,i),C_alignment,
  977. targetinfos[target_info.system]^.alignment.recordalignmin);
  978. include(result.defoptions,df_llvm_no_struct_packing);
  979. end;
  980. function llvmencodetypedecl(def: tdef): TSymStr;
  981. begin
  982. result:='';
  983. llvmaddencodedtype_intern(def,[lef_typedecl],result);
  984. end;
  985. end.