ncgld.pas 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Generate assembler for nodes that handle loads and assignments which
  4. are the same for all (most) processors
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit ncgld;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,
  23. symtype,symsym,
  24. aasmdata,
  25. node,nld,cgutils;
  26. type
  27. tcgloadnode = class(tloadnode)
  28. protected
  29. procedure generate_nested_access(vs: tsym);virtual;
  30. procedure generate_absaddr_access(vs: tabsolutevarsym); virtual;
  31. procedure generate_threadvar_access(gvs: tstaticvarsym); virtual;
  32. function use_indirect_symbol(gvs: tstaticvarsym): boolean;
  33. public
  34. procedure pass_generate_code;override;
  35. procedure changereflocation(const ref: treference);
  36. end;
  37. tcgassignmentnode = class(tassignmentnode)
  38. protected
  39. function maybechangetemp(list: TAsmList; var n: tnode; const newref: treference): boolean;virtual;
  40. public
  41. procedure pass_generate_code;override;
  42. end;
  43. tcgarrayconstructornode = class(tarrayconstructornode)
  44. protected
  45. procedure makearrayref(var ref: treference; eledef: tdef);virtual;
  46. procedure advancearrayoffset(var ref: treference; elesize: asizeint);virtual;
  47. public
  48. procedure pass_generate_code;override;
  49. end;
  50. tcgrttinode = class(trttinode)
  51. procedure pass_generate_code;override;
  52. end;
  53. implementation
  54. uses
  55. cutils,
  56. systems,
  57. verbose,globals,constexp,fmodule,
  58. nutils,
  59. symtable,symconst,symdef,defutil,paramgr,ncon,nbas,ncgrtti,
  60. aasmbase,
  61. cgbase,pass_2,
  62. procinfo,
  63. cpubase,parabase,
  64. tgobj,
  65. cgobj,hlcgobj,
  66. ncgbas,ncgflw,
  67. wpobase;
  68. {*****************************************************************************
  69. SSA (for memory temps) support
  70. *****************************************************************************}
  71. type
  72. preplacerefrec = ^treplacerefrec;
  73. treplacerefrec = record
  74. old, new: preference;
  75. ressym: tsym;
  76. end;
  77. function doreplaceref(var n: tnode; para: pointer): foreachnoderesult;
  78. var
  79. rr: preplacerefrec absolute para;
  80. begin
  81. result := fen_false;
  82. case n.nodetype of
  83. loadn:
  84. begin
  85. { regular variable }
  86. if (tabstractvarsym(tloadnode(n).symtableentry).varoptions * [vo_is_dll_var, vo_is_thread_var] = []) and
  87. not assigned(tloadnode(n).left) and
  88. { not function result, or no exit in function }
  89. (((tloadnode(n).symtableentry <> rr^.ressym) and
  90. not(vo_is_funcret in tabstractvarsym(tloadnode(n).symtableentry).varoptions)) or
  91. not(fc_exit in flowcontrol)) and
  92. { stored in memory... }
  93. (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.loc in [LOC_REFERENCE]) and
  94. { ... at the place we are looking for }
  95. references_equal(tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.reference,rr^.old^) and
  96. { its address cannot have escaped the current routine }
  97. not(tabstractvarsym(tloadnode(n).symtableentry).addr_taken) and
  98. { it is not accessed in nested procedures }
  99. not(tabstractvarsym(tloadnode(n).symtableentry).different_scope) then
  100. begin
  101. { relocate variable }
  102. tcgloadnode(n).changereflocation(rr^.new^);
  103. result := fen_norecurse_true;
  104. end;
  105. end;
  106. temprefn:
  107. begin
  108. if (ti_valid in ttemprefnode(n).tempflags) and
  109. { memory temp... }
  110. (ttemprefnode(n).tempinfo^.location.loc in [LOC_REFERENCE]) and
  111. { ... at the place we are looking for }
  112. references_equal(ttemprefnode(n).tempinfo^.location.reference,rr^.old^) and
  113. { its address cannot have escaped the current routine }
  114. not(ti_addr_taken in ttemprefnode(n).tempflags) then
  115. begin
  116. { relocate the temp }
  117. tcgtemprefnode(n).changelocation(rr^.new^);
  118. result := fen_norecurse_true;
  119. end;
  120. end;
  121. { Subscriptn must be rejected, otherwise we may replace an
  122. an entire record with a temp for its first field, mantis #13948)
  123. Exception: the field's size is the same as the entire record
  124. The same goes for array indexing
  125. }
  126. subscriptn,
  127. vecn:
  128. if not(tunarynode(n).left.resultdef.typ in [recorddef,objectdef,arraydef,stringdef]) or
  129. { make sure we don't try to call resultdef.size for types that
  130. don't have a compile-time size such as open arrays }
  131. is_special_array(tunarynode(n).left.resultdef) or
  132. (tunarynode(n).left.resultdef.size<>tunarynode(n).resultdef.size) then
  133. result := fen_norecurse_false;
  134. { optimize the searching a bit }
  135. derefn,addrn,
  136. calln,inlinen,casen,
  137. addn,subn,muln,
  138. andn,orn,xorn,
  139. ltn,lten,gtn,gten,equaln,unequaln,
  140. slashn,divn,shrn,shln,notn,
  141. inn,
  142. asn,isn:
  143. result := fen_norecurse_false;
  144. end;
  145. end;
  146. function tcgassignmentnode.maybechangetemp(list: TAsmList; var n: tnode; const newref: treference): boolean;
  147. var
  148. rr: treplacerefrec;
  149. begin
  150. result := false;
  151. { only do for -O2 or higher (breaks debugging since }
  152. { variables move to different memory locations) }
  153. if not(cs_opt_level2 in current_settings.optimizerswitches) or
  154. { must be a copy to a memory location ... }
  155. (n.location.loc <> LOC_REFERENCE) or
  156. { not inside a control flow statement and no goto's in sight }
  157. ([fc_inflowcontrol,fc_gotolabel] * flowcontrol <> []) or
  158. { not for refcounted types, because those locations are }
  159. { still used later on in initialisation/finalisation code }
  160. is_managed_type(n.resultdef) or
  161. { source and destination are temps (= not global variables) }
  162. { and both point to the start of a temp, and the source is a }
  163. { non-persistent temp (otherwise we need some kind of copy- }
  164. { on-write support in case later on both are still used) }
  165. not tg.isstartoftemp(newref) or
  166. not tg.isstartoftemp(n.location.reference) or
  167. (tg.gettypeoftemp(newref) <> tt_normal) or
  168. not (tg.gettypeoftemp(n.location.reference) in [tt_normal,tt_persistent]) or
  169. { and both have the same size }
  170. (tg.sizeoftemp(current_asmdata.CurrAsmList,newref) <> tg.sizeoftemp(current_asmdata.CurrAsmList,n.location.reference)) then
  171. exit;
  172. { find the source of the old reference (loadnode or tempnode) }
  173. { and replace it with the new reference }
  174. rr.old := @n.location.reference;
  175. rr.new := @newref;
  176. rr.ressym := nil;
  177. if assigned(current_procinfo.procdef.funcretsym) and
  178. (tabstractvarsym(current_procinfo.procdef.funcretsym).refs <> 0) then
  179. if (current_procinfo.procdef.proctypeoption=potype_constructor) then
  180. rr.ressym:=tsym(current_procinfo.procdef.parast.Find('self'))
  181. else
  182. rr.ressym:=current_procinfo.procdef.funcretsym;
  183. { if source not found, don't do anything }
  184. if not foreachnodestatic(n,@doreplaceref,@rr) then
  185. exit;
  186. n.location.reference := newref;
  187. result:=true;
  188. end;
  189. {*****************************************************************************
  190. SecondLoad
  191. *****************************************************************************}
  192. procedure tcgloadnode.changereflocation(const ref: treference);
  193. var
  194. oldtemptype: ttemptype;
  195. begin
  196. if (location.loc<>LOC_REFERENCE) then
  197. internalerror(2007020812);
  198. if not tg.istemp(location.reference) then
  199. internalerror(2007020813);
  200. oldtemptype:=tg.gettypeoftemp(location.reference);
  201. if (oldtemptype = tt_persistent) then
  202. tg.ChangeTempType(current_asmdata.CurrAsmList,location.reference,tt_normal);
  203. tg.ungettemp(current_asmdata.CurrAsmList,location.reference);
  204. location.reference:=ref;
  205. tg.ChangeTempType(current_asmdata.CurrAsmList,location.reference,oldtemptype);
  206. tabstractnormalvarsym(symtableentry).localloc:=location;
  207. end;
  208. procedure tcgloadnode.generate_nested_access(vs: tsym);
  209. var
  210. { paramter declared as tsym to reduce interface unit dependencies }
  211. lvs: tabstractnormalvarsym absolute vs;
  212. begin
  213. secondpass(left);
  214. if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  215. internalerror(200309286);
  216. if lvs.localloc.loc<>LOC_REFERENCE then
  217. internalerror(200409241);
  218. hlcg.reference_reset_base(location.reference,left.resultdef,left.location.register,lvs.localloc.reference.offset,ctempposinvalid,lvs.localloc.reference.alignment,lvs.localloc.reference.volatility);
  219. end;
  220. procedure tcgloadnode.generate_absaddr_access(vs: tabsolutevarsym);
  221. begin
  222. location.reference.offset:=asizeint(vs.addroffset);
  223. location.reference.volatility:=[vol_read,vol_write];
  224. end;
  225. procedure tcgloadnode.generate_threadvar_access(gvs: tstaticvarsym);
  226. var
  227. respara,
  228. paraloc1 : tcgpara;
  229. fieldptrdef,
  230. pvd : tdef;
  231. endrelocatelab,
  232. norelocatelab : tasmlabel;
  233. tvref,
  234. href : treference;
  235. hregister, hreg_tv_rec : tregister;
  236. tv_rec : trecorddef;
  237. tv_index_field,
  238. tv_non_mt_data_field: tsym;
  239. tmpresloc: tlocation;
  240. issystemunit,
  241. indirect : boolean;
  242. size_opt : boolean;
  243. begin
  244. if (tf_section_threadvars in target_info.flags) then
  245. begin
  246. if gvs.localloc.loc=LOC_INVALID then
  247. if not(vo_is_weak_external in gvs.varoptions) then
  248. reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,location.reference.alignment,[])
  249. else
  250. reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment,[])
  251. else
  252. location:=gvs.localloc;
  253. end
  254. else
  255. begin
  256. {
  257. Thread var loading is optimized to first check if
  258. a relocate function is available. When the function
  259. is available it is called to retrieve the address.
  260. Otherwise the address is loaded with the symbol
  261. }
  262. tv_rec:=get_threadvar_record(resultdef,tv_index_field,tv_non_mt_data_field);
  263. fieldptrdef:=cpointerdef.getreusable(resultdef);
  264. current_asmdata.getjumplabel(norelocatelab);
  265. current_asmdata.getjumplabel(endrelocatelab);
  266. { make sure hregister can't allocate the register necessary for the parameter }
  267. pvd:=search_system_type('TRELOCATETHREADVARHANDLER').typedef;
  268. if pvd.typ<>procvardef then
  269. internalerror(2012120901);
  270. { FPC_THREADVAR_RELOCATE is nil? }
  271. issystemunit:=not current_module.is_unit or
  272. (
  273. assigned(current_module.globalsymtable) and
  274. (current_module.globalsymtable=systemunit)
  275. ) or
  276. (
  277. not assigned(current_module.globalsymtable) and
  278. (current_module.localsymtable=systemunit)
  279. );
  280. indirect:=(tf_supports_packages in target_info.flags) and
  281. (target_info.system in systems_indirect_var_imports) and
  282. (cs_imported_data in current_settings.localswitches) and
  283. not issystemunit;
  284. if not(vo_is_weak_external in gvs.varoptions) then
  285. reference_reset_symbol(tvref,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,sizeof(pint),[])
  286. else
  287. reference_reset_symbol(tvref,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,sizeof(pint),[]);
  288. { Enable size optimization with -Os or PIC code is generated and PIC uses GOT }
  289. size_opt:=(cs_opt_size in current_settings.optimizerswitches)
  290. or ((cs_create_pic in current_settings.moduleswitches) and (tf_pic_uses_got in target_info.flags));
  291. hreg_tv_rec:=NR_INVALID;
  292. if size_opt then
  293. begin
  294. { Load a pointer to the thread var record into a register. }
  295. { This register will be used in both multithreaded and non-multithreaded cases. }
  296. hreg_tv_rec:=hlcg.getaddressregister(current_asmdata.CurrAsmList,cpointerdef.getreusable(tv_rec));
  297. hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,tv_rec,cpointerdef.getreusable(tv_rec),tvref,hreg_tv_rec);
  298. reference_reset_base(tvref,hreg_tv_rec,0,ctempposinvalid,tvref.alignment,tvref.volatility)
  299. end;
  300. paraloc1.init;
  301. paramanager.getintparaloc(current_asmdata.CurrAsmList,tprocvardef(pvd),1,paraloc1);
  302. hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,pvd);
  303. reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE',AT_DATA,indirect),0,pvd.alignment,[]);
  304. if not issystemunit then
  305. current_module.add_extern_asmsym('FPC_THREADVAR_RELOCATE',AB_EXTERNAL,AT_DATA);
  306. hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,pvd,pvd,href,hregister);
  307. hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
  308. { no, call it with the index of the threadvar as parameter }
  309. href:=tvref;
  310. hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,
  311. tv_rec,
  312. tfieldvarsym(tv_index_field),href);
  313. hlcg.a_load_ref_cgpara(current_asmdata.CurrAsmList,tfieldvarsym(tv_index_field).vardef,href,paraloc1);
  314. { Dealloc the threadvar record register before calling the helper function to allow }
  315. { the register allocator to assign non-mandatory real registers for hreg_tv_rec. }
  316. if size_opt then
  317. cg.a_reg_dealloc(current_asmdata.CurrAsmList,hreg_tv_rec);
  318. paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
  319. cg.allocallcpuregisters(current_asmdata.CurrAsmList);
  320. { result is the address of the threadvar }
  321. respara:=hlcg.a_call_reg(current_asmdata.CurrAsmList,tprocvardef(pvd),hregister,[@paraloc1]);
  322. paraloc1.done;
  323. cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
  324. { load the address of the result in hregister }
  325. hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,fieldptrdef);
  326. location_reset(tmpresloc,LOC_REGISTER,def_cgsize(fieldptrdef));
  327. tmpresloc.register:=hregister;
  328. hlcg.gen_load_cgpara_loc(current_asmdata.CurrAsmList,fieldptrdef,respara,tmpresloc,true);
  329. respara.resetiftemp;
  330. hlcg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
  331. { no relocation needed, load the address of the variable only, the
  332. layout of a threadvar is:
  333. 0 - Threadvar index
  334. sizeof(pint) - Threadvar value in single threading }
  335. hlcg.a_label(current_asmdata.CurrAsmList,norelocatelab);
  336. href:=tvref;
  337. hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,
  338. tv_rec,
  339. tfieldvarsym(tv_non_mt_data_field),href);
  340. hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,fieldptrdef,href,hregister);
  341. hlcg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
  342. hlcg.reference_reset_base(location.reference,fieldptrdef,hregister,0,ctempposinvalid,resultdef.alignment,[]);
  343. end;
  344. end;
  345. function tcgloadnode.use_indirect_symbol(gvs:tstaticvarsym):boolean;
  346. begin
  347. { we are using a direct reference if any of the following is true:
  348. - the target does not support packages
  349. - the target does not use indirect references
  350. - the variable is declared as (weak) external
  351. - G- is set
  352. - the variable is located inside the same unit }
  353. result:=(tf_supports_packages in target_info.flags) and
  354. (target_info.system in systems_indirect_var_imports) and
  355. (gvs.varoptions*[vo_is_external,vo_is_weak_external]=[]) and
  356. (gvs.owner.symtabletype in [globalsymtable,staticsymtable]) and
  357. (cs_imported_data in current_settings.localswitches) and
  358. not sym_is_owned_by(gvs,current_module.globalsymtable) and
  359. (
  360. (current_module.globalsymtable=current_module.localsymtable) or
  361. not sym_is_owned_by(gvs,current_module.localsymtable)
  362. );
  363. end;
  364. procedure tcgloadnode.pass_generate_code;
  365. var
  366. hregister : tregister;
  367. vs : tabstractnormalvarsym;
  368. gvs : tstaticvarsym;
  369. vmtdef : tpointerdef;
  370. vmtentry: tfieldvarsym;
  371. pd : tprocdef;
  372. href : treference;
  373. newsize : tcgsize;
  374. vd : tdef;
  375. alignment: longint;
  376. indirect : boolean;
  377. name : TSymStr;
  378. begin
  379. { we don't know the size of all arrays }
  380. newsize:=def_cgsize(resultdef);
  381. { alignment is overridden per case below }
  382. location_reset_ref(location,LOC_REFERENCE,newsize,resultdef.alignment,[]);
  383. case symtableentry.typ of
  384. absolutevarsym :
  385. begin
  386. { this is only for toasm and toaddr }
  387. case tabsolutevarsym(symtableentry).abstyp of
  388. toaddr :
  389. generate_absaddr_access(tabsolutevarsym(symtableentry));
  390. toasm :
  391. location.reference.symbol:=current_asmdata.RefAsmSymbol(tabsolutevarsym(symtableentry).mangledname,AT_DATA);
  392. else
  393. internalerror(200310283);
  394. end;
  395. end;
  396. constsym:
  397. begin
  398. if tconstsym(symtableentry).consttyp=constresourcestring then
  399. begin
  400. location_reset_ref(location,LOC_CREFERENCE,def_cgsize(cansistringtype),cansistringtype.size,[]);
  401. indirect:=(tf_supports_packages in target_info.flags) and
  402. (target_info.system in systems_indirect_var_imports) and
  403. (cs_imported_data in current_settings.localswitches) and
  404. (symtableentry.owner.moduleid<>current_module.moduleid);
  405. name:=make_mangledname('RESSTR',symtableentry.owner,symtableentry.name);
  406. location.reference.symbol:=current_asmdata.RefAsmSymbol(name,AT_DATA,indirect);
  407. if symtableentry.owner.moduleid<>current_module.moduleid then
  408. current_module.addimportedsym(symtableentry);
  409. vd:=search_system_type('TRESOURCESTRINGRECORD').typedef;
  410. hlcg.g_set_addr_nonbitpacked_field_ref(
  411. current_asmdata.CurrAsmList,
  412. trecorddef(vd),
  413. tfieldvarsym(search_struct_member(trecorddef(vd),'CURRENTVALUE')),
  414. location.reference);
  415. end
  416. else
  417. internalerror(22798);
  418. end;
  419. staticvarsym :
  420. begin
  421. gvs:=tstaticvarsym(symtableentry);
  422. if (vo_is_dll_var in gvs.varoptions) then
  423. { DLL variable }
  424. begin
  425. hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
  426. if not(vo_is_weak_external in gvs.varoptions) then
  427. location.reference.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(symtableentry).mangledname,AT_DATA)
  428. else
  429. location.reference.symbol:=current_asmdata.WeakRefAsmSymbol(tstaticvarsym(symtableentry).mangledname,AT_DATA);
  430. cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,location.reference,hregister);
  431. reference_reset_base(location.reference,hregister,0,ctempposinvalid,location.reference.alignment,[]);
  432. end
  433. { Thread variable }
  434. else if (vo_is_thread_var in gvs.varoptions) then
  435. generate_threadvar_access(gvs)
  436. { Normal (or external) variable }
  437. else
  438. begin
  439. if gvs.localloc.loc=LOC_INVALID then
  440. begin
  441. { static data is currently always volatile }
  442. if not(vo_is_weak_external in gvs.varoptions) then
  443. reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,location.reference.alignment,[])
  444. else
  445. reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment,[])
  446. end
  447. else
  448. location:=gvs.localloc;
  449. end;
  450. { make const a LOC_CREFERENCE }
  451. if (gvs.varspez=vs_const) and
  452. (location.loc=LOC_REFERENCE) then
  453. location.loc:=LOC_CREFERENCE;
  454. end;
  455. paravarsym,
  456. localvarsym :
  457. begin
  458. vs:=tabstractnormalvarsym(symtableentry);
  459. { Nested variable }
  460. if assigned(left) then
  461. generate_nested_access(vs)
  462. else
  463. location:=vs.localloc;
  464. { handle call by reference variables when they are not
  465. already copied to local copies. Also ignore the reference
  466. when we need to load the self pointer for objects }
  467. if is_addr_param_load then
  468. begin
  469. if (location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
  470. hregister:=location.register
  471. else
  472. begin
  473. vd:=cpointerdef.getreusable(resultdef);
  474. hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,vd);
  475. { we need to load only an address }
  476. location.size:=int_cgsize(vd.size);
  477. hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,vd,vd,location,hregister);
  478. end;
  479. { assume packed records may always be unaligned }
  480. if not(resultdef.typ in [recorddef,objectdef]) or
  481. (tabstractrecordsymtable(tabstractrecorddef(resultdef).symtable).usefieldalignment<>1) then
  482. begin
  483. alignment:=min(min(min(resultdef.alignment,current_settings.alignment.localalignmax),current_settings.alignment.constalignmax),current_settings.alignment.varalignmax);
  484. location_reset_ref(location,LOC_REFERENCE,newsize,alignment,[]);
  485. end
  486. else
  487. location_reset_ref(location,LOC_REFERENCE,newsize,1,[]);
  488. hlcg.reference_reset_base(location.reference,voidpointertype,hregister,0,ctempposinvalid,location.reference.alignment,[]);
  489. end;
  490. { make const a LOC_CREFERENCE }
  491. if (vs.varspez=vs_const) and
  492. (location.loc=LOC_REFERENCE) then
  493. location.loc:=LOC_CREFERENCE;
  494. end;
  495. procsym:
  496. begin
  497. if not assigned(procdef) then
  498. internalerror(200312011);
  499. if assigned(left) and
  500. (resultdef.typ in [symconst.procdef,procvardef]) and
  501. not tabstractprocdef(resultdef).is_addressonly then
  502. begin
  503. location_reset(location,LOC_CREGISTER,int_cgsize(voidpointertype.size*2));
  504. secondpass(left);
  505. { load class instance/classrefdef address }
  506. if left.location.loc=LOC_CONSTANT then
  507. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  508. { vd will contain the type of the self pointer (self in
  509. case of a class/classref, address of self in case of
  510. an object }
  511. vd:=nil;
  512. case left.location.loc of
  513. LOC_CREGISTER,
  514. LOC_REGISTER:
  515. begin
  516. { this is not possible for objects }
  517. if is_object(left.resultdef) then
  518. internalerror(200304234);
  519. location.registerhi:=left.location.register;
  520. vd:=left.resultdef;
  521. end;
  522. LOC_CREFERENCE,
  523. LOC_REFERENCE:
  524. begin
  525. if is_implicit_pointer_object_type(left.resultdef) or
  526. (left.resultdef.typ=classrefdef) then
  527. begin
  528. vd:=left.resultdef;
  529. location.registerhi:=hlcg.getaddressregister(current_asmdata.CurrAsmList,left.resultdef);
  530. hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,left.resultdef,left.resultdef,left.location.reference,location.registerhi)
  531. end
  532. else
  533. begin
  534. vd:=cpointerdef.getreusable(left.resultdef);
  535. location.registerhi:=hlcg.getaddressregister(current_asmdata.CurrAsmList,vd);
  536. hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,vd,left.location.reference,location.registerhi);
  537. end;
  538. location_freetemp(current_asmdata.CurrAsmList,left.location);
  539. end;
  540. else
  541. internalerror(200610311);
  542. end;
  543. { virtual method ? }
  544. if (po_virtualmethod in procdef.procoptions) and
  545. not(loadnf_inherited in loadnodeflags) and
  546. not is_objectpascal_helper(procdef.struct) then
  547. begin
  548. if (not assigned(current_procinfo) or
  549. wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
  550. tobjectdef(procdef.struct).register_vmt_call(procdef.extnumber);
  551. {$ifdef vtentry}
  552. if not is_interface(procdef.struct) then
  553. begin
  554. inc(current_asmdata.NextVTEntryNr);
  555. current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+procdef._class.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0,voidpointerdef));
  556. end;
  557. {$endif vtentry}
  558. if (left.resultdef.typ=objectdef) and
  559. assigned(tobjectdef(left.resultdef).vmt_field) then
  560. begin
  561. { vmt pointer is a pointer to the vmt record }
  562. hlcg.reference_reset_base(href,vd,location.registerhi,0,ctempposinvalid,vd.alignment,[]);
  563. vmtdef:=cpointerdef.getreusable(tobjectdef(left.resultdef).vmt_def);
  564. hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,tobjectdef(left.resultdef),tfieldvarsym(tobjectdef(left.resultdef).vmt_field),href);
  565. hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,vmtdef);
  566. hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,tfieldvarsym(tobjectdef(left.resultdef).vmt_field).vardef,vmtdef,href,hregister);
  567. end
  568. else if left.resultdef.typ=classrefdef then
  569. begin
  570. { classrefdef is a pointer to the vmt already }
  571. hregister:=location.registerhi;
  572. vmtdef:=cpointerdef.getreusable(tobjectdef(tclassrefdef(left.resultdef).pointeddef).vmt_def);
  573. hlcg.g_ptrtypecast_reg(current_asmdata.CurrAsmList,left.resultdef,vmtdef,hregister);
  574. end
  575. else if is_any_interface_kind(left.resultdef) then
  576. begin
  577. { an interface is a pointer to a pointer to a vmt }
  578. hlcg.reference_reset_base(href,vd,location.registerhi,0,ctempposinvalid,vd.alignment,[]);
  579. vmtdef:=cpointerdef.getreusable(tobjectdef(left.resultdef).vmt_def);
  580. hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,vmtdef);
  581. hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,vmtdef,vmtdef,href,hregister);
  582. end
  583. else
  584. internalerror(2015112501);
  585. { load method address }
  586. vmtentry:=tabstractrecordsymtable(trecorddef(vmtdef.pointeddef).symtable).findfieldbyoffset(
  587. tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber));
  588. hlcg.reference_reset_base(href,vmtdef,hregister,0,ctempposinvalid,vmtdef.alignment,[]);
  589. location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,vmtentry.vardef);
  590. hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,tabstractrecorddef(vmtdef.pointeddef),vmtentry,href);
  591. hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,vmtentry.vardef,vmtentry.vardef,href,location.register);
  592. end
  593. else
  594. begin
  595. { load address of the function }
  596. reference_reset_symbol(href,current_asmdata.RefAsmSymbol(procdef.mangledname,AT_FUNCTION),0,procdef.address_type.alignment,[]);
  597. location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,cprocvardef.getreusableprocaddr(procdef));
  598. hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,procdef,cprocvardef.getreusableprocaddr(procdef),href,location.register);
  599. end;
  600. { to get methodpointers stored correctly, code and self register must be swapped on
  601. big endian targets }
  602. if target_info.endian=endian_big then
  603. begin
  604. hregister:=location.register;
  605. location.register:=location.registerhi;
  606. location.registerhi:=hregister;
  607. end;
  608. end
  609. else
  610. begin
  611. pd:=tprocdef(tprocsym(symtableentry).ProcdefList[0]);
  612. { def_cgsize does not work for tprocdef, so we use pd.address_type }
  613. location.size:=def_cgsize(pd.address_type);
  614. if not(po_weakexternal in pd.procoptions) then
  615. location.reference.symbol:=current_asmdata.RefAsmSymbol(procdef.mangledname,AT_FUNCTION)
  616. else
  617. location.reference.symbol:=current_asmdata.WeakRefAsmSymbol(procdef.mangledname,AT_FUNCTION);
  618. end;
  619. end;
  620. labelsym :
  621. if assigned(tlabelsym(symtableentry).asmblocklabel) then
  622. location.reference.symbol:=tlabelsym(symtableentry).asmblocklabel
  623. else
  624. location.reference.symbol:=tcglabelnode((tlabelsym(symtableentry).code)).getasmlabel;
  625. else internalerror(200510032);
  626. end;
  627. end;
  628. {*****************************************************************************
  629. SecondAssignment
  630. *****************************************************************************}
  631. procedure tcgassignmentnode.pass_generate_code;
  632. var
  633. shuffle : pmmshuffle;
  634. hlabel : tasmlabel;
  635. href : treference;
  636. releaseright : boolean;
  637. alignmentrequirement,
  638. len : aint;
  639. r : tregister;
  640. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  641. r64 : tregister64;
  642. {$endif}
  643. oldflowcontrol : tflowcontrol;
  644. begin
  645. { previously, managed types were handled in firstpass
  646. newer FPCs however can identify situations when
  647. assignments of managed types require no special code and the
  648. value could be just copied so this could should be able also to handle
  649. managed types without any special "managing code"}
  650. location_reset(location,LOC_VOID,OS_NO);
  651. {
  652. in most cases we can process first the right node which contains
  653. the most complex code. Exceptions for this are:
  654. - result is in flags, loading left will then destroy the flags
  655. - result is a jump, loading left must be already done before the jump is made
  656. - result need reference count, when left points to a value used in
  657. right then decreasing the refcnt on left can possibly release
  658. the memory before right increased the refcnt, result is that an
  659. empty value is assigned
  660. But not when the result is in the flags, then
  661. loading the left node afterwards can destroy the flags.
  662. }
  663. if not(right.expectloc in [LOC_FLAGS,LOC_JUMP]) and
  664. (node_complexity(right)>node_complexity(left)) then
  665. begin
  666. secondpass(right);
  667. if codegenerror then
  668. exit;
  669. secondpass(left);
  670. if codegenerror then
  671. exit;
  672. end
  673. else
  674. begin
  675. { calculate left sides }
  676. secondpass(left);
  677. if codegenerror then
  678. exit;
  679. { tell the SSA/SSL code that the left side was handled first so
  680. ni SSL is done
  681. }
  682. oldflowcontrol:=flowcontrol;
  683. include(flowcontrol,fc_lefthandled);
  684. secondpass(right);
  685. flowcontrol:=oldflowcontrol;
  686. if codegenerror then
  687. exit;
  688. end;
  689. releaseright:=
  690. (left.nodetype<>temprefn) or
  691. not(ti_const in ttemprefnode(left).tempflags);
  692. { shortstring assignments are handled separately }
  693. if is_shortstring(left.resultdef) then
  694. begin
  695. {
  696. we can get here only in the following situations
  697. for the right node:
  698. - empty constant string
  699. - char
  700. }
  701. { The addn is replaced by a blockn or calln that already returns
  702. a shortstring }
  703. if is_shortstring(right.resultdef) and
  704. (right.nodetype in [blockn,calln]) then
  705. begin
  706. { verify that we indeed have nothing to do }
  707. if not(nf_assign_done_in_right in flags) then
  708. internalerror(2015042201);
  709. end
  710. { empty constant string }
  711. else if (right.nodetype=stringconstn) and
  712. (tstringconstnode(right).len=0) then
  713. begin
  714. hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(left.resultdef),tpointerdef(charpointertype),left.location.reference);
  715. hlcg.a_load_const_ref(current_asmdata.CurrAsmList,cansichartype,0,left.location.reference);
  716. end
  717. { char loading }
  718. else if is_char(right.resultdef) then
  719. begin
  720. if right.nodetype=ordconstn then
  721. begin
  722. hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(left.resultdef),cpointerdef.getreusable(u16inttype),left.location.reference);
  723. if (target_info.endian = endian_little) then
  724. hlcg.a_load_const_ref(current_asmdata.CurrAsmList,u16inttype,(tordconstnode(right).value.svalue shl 8) or 1,
  725. setalignment(left.location.reference,1))
  726. else
  727. hlcg.a_load_const_ref(current_asmdata.CurrAsmList,u16inttype,tordconstnode(right).value.svalue or (1 shl 8),
  728. setalignment(left.location.reference,1));
  729. end
  730. else
  731. begin
  732. href:=left.location.reference;
  733. hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(left.resultdef),tpointerdef(charpointertype),href);
  734. hlcg.a_load_const_ref(current_asmdata.CurrAsmList,cansichartype,1,href);
  735. inc(href.offset,1);
  736. href.alignment:=1;
  737. case right.location.loc of
  738. LOC_REGISTER,
  739. LOC_CREGISTER :
  740. begin
  741. {$ifndef cpuhighleveltarget}
  742. r:=cg.makeregsize(current_asmdata.CurrAsmList,right.location.register,OS_8);
  743. {$else not cpuhighleveltarget}
  744. r:=hlcg.getintregister(current_asmdata.CurrAsmList,u8inttype);
  745. hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,cansichartype,u8inttype,right.location.register,r);
  746. {$endif cpuhighleveltarget}
  747. hlcg.a_load_reg_ref(current_asmdata.CurrAsmList,u8inttype,u8inttype,r,href);
  748. end;
  749. LOC_REFERENCE,
  750. LOC_CREFERENCE :
  751. hlcg.a_load_ref_ref(current_asmdata.CurrAsmList,cansichartype,cansichartype,right.location.reference,href);
  752. else
  753. internalerror(200205111);
  754. end;
  755. end;
  756. end
  757. else
  758. internalerror(2002042410);
  759. end
  760. { try to reuse memory locations instead of copying }
  761. { copy to a memory location ... }
  762. else if (right.location.loc = LOC_REFERENCE) and
  763. maybechangetemp(current_asmdata.CurrAsmList,left,right.location.reference) then
  764. begin
  765. { if it worked, we're done }
  766. end
  767. else
  768. begin
  769. { SSA support }
  770. hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,left,false);
  771. hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,right,true);
  772. case right.location.loc of
  773. LOC_CONSTANT :
  774. begin
  775. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  776. if (left.location.size in [OS_64,OS_S64]) or (right.location.size in [OS_64,OS_S64]) then
  777. cg64.a_load64_const_loc(current_asmdata.CurrAsmList,right.location.value64,left.location)
  778. else
  779. {$endif not cpu64bitalu and not cpuhighleveltarget}
  780. hlcg.a_load_const_loc(current_asmdata.CurrAsmList,left.resultdef,right.location.value,left.location);
  781. end;
  782. LOC_REFERENCE,
  783. LOC_CREFERENCE :
  784. begin
  785. case left.location.loc of
  786. LOC_REGISTER,
  787. LOC_CREGISTER :
  788. begin
  789. {$ifndef cpuhighleveltarget}
  790. {$ifdef cpu64bitalu}
  791. if left.location.size in [OS_128,OS_S128] then
  792. cg128.a_load128_ref_reg(current_asmdata.CurrAsmList,right.location.reference,left.location.register128)
  793. else
  794. {$else cpu64bitalu}
  795. if left.location.size in [OS_64,OS_S64] then
  796. cg64.a_load64_ref_reg(current_asmdata.CurrAsmList,right.location.reference,left.location.register64)
  797. else
  798. {$endif cpu64bitalu}
  799. {$endif not cpuhighleveltarget}
  800. hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.reference,left.location.register);
  801. end;
  802. LOC_FPUREGISTER,
  803. LOC_CFPUREGISTER :
  804. begin
  805. hlcg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,
  806. right.resultdef,left.resultdef,
  807. right.location.reference,
  808. left.location.register);
  809. end;
  810. LOC_REFERENCE,
  811. LOC_CREFERENCE :
  812. begin
  813. if (left.resultdef.typ=floatdef) and
  814. (right.resultdef.typ=floatdef) and
  815. (left.location.size<>right.location.size) then
  816. begin
  817. { assume that all float types can be handed by the
  818. fpu if one can be handled by the fpu }
  819. if not use_vectorfpu(left.resultdef) or
  820. not use_vectorfpu(right.resultdef) then
  821. hlcg.a_loadfpu_ref_ref(current_asmdata.CurrAsmList,
  822. right.resultdef,left.resultdef,
  823. right.location.reference,left.location.reference)
  824. else
  825. hlcg.a_loadmm_ref_ref(current_asmdata.CurrAsmList,
  826. right.resultdef,left.resultdef,
  827. right.location.reference,left.location.reference,mms_movescalar)
  828. end
  829. else
  830. begin
  831. { TODO: HACK: unaligned test, maybe remove all unaligned locations (array of char) from the compiler}
  832. { Use unaligned copy when the offset is not aligned }
  833. len:=left.resultdef.size;
  834. { can be 0 in case of formaldef on JVM target }
  835. if len=0 then
  836. len:=sizeof(pint);
  837. { data smaller than an aint has less alignment requirements }
  838. { max(1,...) avoids div by zero in case of an empty record }
  839. alignmentrequirement:=min(max(1,len),sizeof(aint));
  840. if (right.location.reference.offset mod alignmentrequirement<>0) or
  841. (left.location.reference.offset mod alignmentrequirement<>0) or
  842. (right.resultdef.alignment<alignmentrequirement) or
  843. ((right.location.reference.alignment<>0) and
  844. (right.location.reference.alignment<alignmentrequirement)) or
  845. ((left.location.reference.alignment<>0) and
  846. (left.location.reference.alignment<alignmentrequirement)) then
  847. hlcg.g_concatcopy_unaligned(current_asmdata.CurrAsmList,left.resultdef,right.location.reference,left.location.reference)
  848. else
  849. hlcg.g_concatcopy(current_asmdata.CurrAsmList,left.resultdef,right.location.reference,left.location.reference);
  850. end;
  851. end;
  852. LOC_MMREGISTER,
  853. LOC_CMMREGISTER:
  854. begin
  855. {$if defined(x86) and not defined(llvm)}
  856. if (right.resultdef.typ=floatdef) and
  857. not use_vectorfpu(right.resultdef) then
  858. begin
  859. { perform size conversion if needed (the mm-code cannot }
  860. { convert an extended into a double/single, since sse }
  861. { doesn't support extended) }
  862. r:=cg.getfpuregister(current_asmdata.CurrAsmList,right.location.size);
  863. tg.gethltemp(current_asmdata.CurrAsmList,left.resultdef,left.resultdef.size,tt_normal,href);
  864. cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,right.location.size,right.location.size,right.location.reference,r);
  865. cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,right.location.size,left.location.size,r,href);
  866. if releaseright then
  867. location_freetemp(current_asmdata.CurrAsmList,right.location);
  868. releaseright:=true;
  869. location_reset_ref(right.location,LOC_REFERENCE,left.location.size,0,[]);
  870. right.location.reference:=href;
  871. right.resultdef:=left.resultdef;
  872. end;
  873. {$endif}
  874. hlcg.a_loadmm_ref_reg(current_asmdata.CurrAsmList,
  875. right.resultdef,
  876. left.resultdef,
  877. right.location.reference,
  878. left.location.register,mms_movescalar);
  879. end;
  880. LOC_SUBSETREG,
  881. LOC_CSUBSETREG:
  882. hlcg.a_load_ref_subsetreg(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.reference,left.location.sreg);
  883. LOC_SUBSETREF,
  884. LOC_CSUBSETREF:
  885. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  886. if right.location.size in [OS_64,OS_S64] then
  887. cg64.a_load64_ref_subsetref(current_asmdata.CurrAsmList,right.location.reference,left.location.sref)
  888. else
  889. {$endif not cpu64bitalu and not cpuhighleveltarget}
  890. hlcg.a_load_ref_subsetref(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.reference,left.location.sref);
  891. else
  892. internalerror(200203284);
  893. end;
  894. end;
  895. {$ifdef SUPPORT_MMX}
  896. LOC_CMMXREGISTER,
  897. LOC_MMXREGISTER:
  898. begin
  899. if left.location.loc=LOC_CMMXREGISTER then
  900. cg.a_loadmm_reg_reg(current_asmdata.CurrAsmList,OS_M64,OS_M64,right.location.register,left.location.register,nil)
  901. else
  902. cg.a_loadmm_reg_ref(current_asmdata.CurrAsmList,OS_M64,OS_M64,right.location.register,left.location.reference,nil);
  903. end;
  904. {$endif SUPPORT_MMX}
  905. LOC_MMREGISTER,
  906. LOC_CMMREGISTER:
  907. begin
  908. if (is_vector(left.resultdef)) then
  909. shuffle := nil
  910. else
  911. shuffle := mms_movescalar;
  912. case left.location.loc of
  913. LOC_CMMREGISTER,
  914. LOC_MMREGISTER:
  915. hlcg.a_loadmm_reg_reg(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.register,left.location.register, shuffle);
  916. LOC_REFERENCE,
  917. LOC_CREFERENCE:
  918. hlcg.a_loadmm_reg_ref(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.register,left.location.reference, shuffle);
  919. else
  920. internalerror(2009112601);
  921. end;
  922. end;
  923. LOC_REGISTER,
  924. LOC_CREGISTER :
  925. begin
  926. {$ifndef cpuhighleveltarget}
  927. {$ifdef cpu64bitalu}
  928. if left.location.size in [OS_128,OS_S128] then
  929. cg128.a_load128_reg_loc(current_asmdata.CurrAsmList,
  930. right.location.register128,left.location)
  931. else
  932. {$else cpu64bitalu}
  933. { also OS_F64 in case of mmreg -> intreg }
  934. if left.location.size in [OS_64,OS_S64,OS_F64] then
  935. cg64.a_load64_reg_loc(current_asmdata.CurrAsmList,
  936. right.location.register64,left.location)
  937. else
  938. {$endif cpu64bitalu}
  939. {$endif not cpuhighleveltarget}
  940. {$ifdef i8086}
  941. { prefer a_load_loc_ref, because it supports i8086-specific types
  942. that use registerhi (like 6-byte method pointers)
  943. (todo: maybe we should add a_load_loc_loc?) }
  944. if left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
  945. hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location,left.location.reference)
  946. else
  947. {$endif i8086}
  948. hlcg.a_load_reg_loc(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.register,left.location);
  949. end;
  950. LOC_FPUREGISTER,
  951. LOC_CFPUREGISTER :
  952. begin
  953. { we can't do direct moves between fpu and mm registers }
  954. if left.location.loc in [LOC_MMREGISTER,LOC_CMMREGISTER] then
  955. begin
  956. {$if defined(x86) and not defined(llvm)}
  957. if not use_vectorfpu(right.resultdef) then
  958. begin
  959. { perform size conversion if needed (the mm-code cannot convert an }
  960. { extended into a double/single, since sse doesn't support extended) }
  961. tg.gethltemp(current_asmdata.CurrAsmList,left.resultdef,left.resultdef.size,tt_normal,href);
  962. cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,right.location.size,left.location.size,right.location.register,href);
  963. location_reset_ref(right.location,LOC_REFERENCE,left.location.size,0,[]);
  964. right.location.reference:=href;
  965. right.resultdef:=left.resultdef;
  966. end;
  967. {$endif}
  968. hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,false);
  969. hlcg.a_loadmm_reg_reg(current_asmdata.CurrAsmList,
  970. right.resultdef,left.resultdef,
  971. right.location.register,left.location.register,mms_movescalar);
  972. end
  973. else
  974. hlcg.a_loadfpu_reg_loc(current_asmdata.CurrAsmList,
  975. right.resultdef,left.resultdef,
  976. right.location.register,left.location);
  977. end;
  978. LOC_SUBSETREG,
  979. LOC_CSUBSETREG:
  980. begin
  981. hlcg.a_load_subsetreg_loc(current_asmdata.CurrAsmList,
  982. right.resultdef,left.resultdef,right.location.sreg,left.location);
  983. end;
  984. LOC_SUBSETREF,
  985. LOC_CSUBSETREF:
  986. begin
  987. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  988. if right.location.size in [OS_64,OS_S64] then
  989. cg64.a_load64_subsetref_loc(current_asmdata.CurrAsmList,right.location.sref,left.location)
  990. else
  991. {$endif not cpu64bitalu and not cpuhighleveltarget}
  992. hlcg.a_load_subsetref_loc(current_asmdata.CurrAsmList,
  993. right.resultdef,left.resultdef,right.location.sref,left.location);
  994. end;
  995. LOC_JUMP :
  996. begin
  997. current_asmdata.getjumplabel(hlabel);
  998. hlcg.a_label(current_asmdata.CurrAsmList,right.location.truelabel);
  999. if is_pasbool(left.resultdef) then
  1000. begin
  1001. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  1002. if left.location.size in [OS_64,OS_S64] then
  1003. cg64.a_load64_const_loc(current_asmdata.CurrAsmList,1,left.location)
  1004. else
  1005. {$endif not cpu64bitalu and not cpuhighleveltarget}
  1006. hlcg.a_load_const_loc(current_asmdata.CurrAsmList,left.resultdef,1,left.location)
  1007. end
  1008. else
  1009. begin
  1010. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  1011. if left.location.size in [OS_64,OS_S64] then
  1012. cg64.a_load64_const_loc(current_asmdata.CurrAsmList,-1,left.location)
  1013. else
  1014. {$endif not cpu64bitalu and not cpuhighleveltarget}
  1015. hlcg.a_load_const_loc(current_asmdata.CurrAsmList,left.resultdef,-1,left.location);
  1016. end;
  1017. hlcg.a_jmp_always(current_asmdata.CurrAsmList,hlabel);
  1018. hlcg.a_label(current_asmdata.CurrAsmList,right.location.falselabel);
  1019. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  1020. if left.location.size in [OS_64,OS_S64] then
  1021. cg64.a_load64_const_loc(current_asmdata.CurrAsmList,0,left.location)
  1022. else
  1023. {$endif not cpu64bitalu and not cpuhighleveltarget}
  1024. hlcg.a_load_const_loc(current_asmdata.CurrAsmList,left.resultdef,0,left.location);
  1025. hlcg.a_label(current_asmdata.CurrAsmList,hlabel);
  1026. end;
  1027. {$ifdef cpuflags}
  1028. LOC_FLAGS :
  1029. begin
  1030. if is_pasbool(left.resultdef) then
  1031. begin
  1032. case left.location.loc of
  1033. LOC_REGISTER,LOC_CREGISTER:
  1034. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  1035. if left.location.size in [OS_S64,OS_64] then
  1036. begin
  1037. cg.g_flags2reg(current_asmdata.CurrAsmList,OS_32,right.location.resflags,left.location.register64.reglo);
  1038. cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
  1039. cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,left.location.register64.reghi);
  1040. end
  1041. else
  1042. {$endif not cpu64bitalu and not cpuhighleveltarget}
  1043. begin
  1044. cg.g_flags2reg(current_asmdata.CurrAsmList,left.location.size,right.location.resflags,left.location.register);
  1045. cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
  1046. end;
  1047. LOC_REFERENCE:
  1048. { i8086 and i386 have hacks in their code generators so that they can
  1049. deal with 64 bit locations in this parcticular case }
  1050. {$if not defined(cpu64bitalu) and not defined(x86) and not defined(cpuhighleveltarget)}
  1051. if left.location.size in [OS_S64,OS_64] then
  1052. begin
  1053. r64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
  1054. r64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
  1055. cg.g_flags2reg(current_asmdata.CurrAsmList,OS_32,right.location.resflags,r64.reglo);
  1056. cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
  1057. cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,r64.reghi);
  1058. cg64.a_load64_reg_ref(current_asmdata.CurrAsmList,r64,left.location.reference);
  1059. end
  1060. else
  1061. {$endif not cpu64bitalu and not x86 and not cpuhighleveltarget}
  1062. begin
  1063. cg.g_flags2ref(current_asmdata.CurrAsmList,left.location.size,right.location.resflags,left.location.reference);
  1064. cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
  1065. end;
  1066. LOC_SUBSETREG,LOC_SUBSETREF:
  1067. begin
  1068. r:=cg.getintregister(current_asmdata.CurrAsmList,left.location.size);
  1069. cg.g_flags2reg(current_asmdata.CurrAsmList,left.location.size,right.location.resflags,r);
  1070. cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
  1071. hlcg.a_load_reg_loc(current_asmdata.CurrAsmList,left.resultdef,left.resultdef,r,left.location);
  1072. end;
  1073. else
  1074. internalerror(200203273);
  1075. end;
  1076. end
  1077. else
  1078. begin
  1079. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  1080. if left.location.size in [OS_S64,OS_64] then
  1081. begin
  1082. r64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
  1083. r64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
  1084. cg.g_flags2reg(current_asmdata.CurrAsmList,OS_32,right.location.resflags,r64.reglo);
  1085. cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
  1086. cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,r64.reghi);
  1087. cg64.a_op64_reg_reg(current_asmdata.CurrAsmList,OP_NEG,OS_S64,
  1088. r64,r64);
  1089. cg64.a_load64_reg_loc(current_asmdata.CurrAsmList,r64,left.location);
  1090. end
  1091. else
  1092. {$endif not cpu64bitalu and not cpuhighleveltarget}
  1093. begin
  1094. r:=cg.getintregister(current_asmdata.CurrAsmList,left.location.size);
  1095. cg.g_flags2reg(current_asmdata.CurrAsmList,left.location.size,right.location.resflags,r);
  1096. cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
  1097. cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,left.location.size,r,r);
  1098. hlcg.a_load_reg_loc(current_asmdata.CurrAsmList,left.resultdef,left.resultdef,r,left.location);
  1099. end
  1100. end;
  1101. end;
  1102. {$endif cpuflags}
  1103. end;
  1104. end;
  1105. if releaseright then
  1106. location_freetemp(current_asmdata.CurrAsmList,right.location);
  1107. end;
  1108. {*****************************************************************************
  1109. SecondArrayConstruct
  1110. *****************************************************************************}
  1111. const
  1112. vtInteger = 0;
  1113. vtBoolean = 1;
  1114. vtChar = 2;
  1115. vtExtended = 3;
  1116. vtString = 4;
  1117. vtPointer = 5;
  1118. vtPChar = 6;
  1119. vtObject = 7;
  1120. vtClass = 8;
  1121. vtWideChar = 9;
  1122. vtPWideChar = 10;
  1123. vtAnsiString32 = 11;
  1124. vtCurrency = 12;
  1125. vtVariant = 13;
  1126. vtInterface = 14;
  1127. vtWideString = 15;
  1128. vtInt64 = 16;
  1129. vtQWord = 17;
  1130. vtUnicodeString = 18;
  1131. vtAnsiString16 = 19;
  1132. vtAnsiString64 = 20;
  1133. procedure tcgarrayconstructornode.makearrayref(var ref: treference; eledef: tdef);
  1134. begin
  1135. { do nothing by default }
  1136. end;
  1137. procedure tcgarrayconstructornode.advancearrayoffset(var ref: treference; elesize: asizeint);
  1138. begin
  1139. ref.alignment:=newalignment(ref.alignment,elesize);
  1140. inc(ref.offset,elesize);
  1141. end;
  1142. procedure tcgarrayconstructornode.pass_generate_code;
  1143. var
  1144. hp : tarrayconstructornode;
  1145. href,
  1146. fref : treference;
  1147. lt : tdef;
  1148. paraloc : tcgparalocation;
  1149. varvtypefield,
  1150. varfield : tfieldvarsym;
  1151. vtype : longint;
  1152. eledef: tdef;
  1153. elesize : longint;
  1154. tmpreg : tregister;
  1155. vaddr : boolean;
  1156. freetemp,
  1157. dovariant: boolean;
  1158. begin
  1159. if is_packed_array(resultdef) then
  1160. internalerror(200608042);
  1161. dovariant:=
  1162. ((nf_forcevaria in flags) or is_variant_array(resultdef)) and
  1163. not(target_info.system in systems_managed_vm);
  1164. eledef:=tarraydef(resultdef).elementdef;
  1165. elesize:=eledef.size;
  1166. if dovariant then
  1167. varvtypefield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VTYPE'))
  1168. else
  1169. varvtypefield:=nil;
  1170. { alignment is filled in by tg.gethltemp below }
  1171. location_reset_ref(location,LOC_CREFERENCE,OS_NO,0,[]);
  1172. fillchar(paraloc,sizeof(paraloc),0);
  1173. { Allocate always a temp, also if no elements are required, to
  1174. be sure that location is valid (PFV) }
  1175. { on the JVM platform, an array can have 0 elements; since the length
  1176. of the array is part of the array itself, make sure we allocate one
  1177. of the proper length to avoid getting unexpected results later --
  1178. allocating a temp of size 0 also forces it to be size 4 on regular
  1179. targets }
  1180. tg.gethltemp(current_asmdata.CurrAsmList,resultdef,(tarraydef(resultdef).highrange+1)*elesize,tt_normal,location.reference);
  1181. href:=location.reference;
  1182. makearrayref(href,eledef);
  1183. { Process nodes in array constructor }
  1184. hp:=self;
  1185. while assigned(hp) do
  1186. begin
  1187. if assigned(hp.left) then
  1188. begin
  1189. freetemp:=true;
  1190. secondpass(hp.left);
  1191. if (hp.left.location.loc=LOC_JUMP)<>
  1192. (hp.left.expectloc=LOC_JUMP) then
  1193. internalerror(2007103101);
  1194. { Move flags and jump in register }
  1195. if hp.left.location.loc in [LOC_FLAGS,LOC_JUMP] then
  1196. hlcg.location_force_reg(current_asmdata.CurrAsmList,hp.left.location,hp.left.resultdef,hp.left.resultdef,false);
  1197. if dovariant then
  1198. begin
  1199. { find the correct vtype value }
  1200. vtype:=$ff;
  1201. varfield:=nil;
  1202. vaddr:=false;
  1203. lt:=hp.left.resultdef;
  1204. case lt.typ of
  1205. enumdef,
  1206. orddef :
  1207. begin
  1208. if is_64bit(lt) then
  1209. begin
  1210. case torddef(lt).ordtype of
  1211. scurrency:
  1212. begin
  1213. vtype:=vtCurrency;
  1214. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VCURRENCY'));
  1215. end;
  1216. s64bit:
  1217. begin
  1218. vtype:=vtInt64;
  1219. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VINT64'));
  1220. end;
  1221. u64bit:
  1222. begin
  1223. vtype:=vtQWord;
  1224. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VQWORD'));
  1225. end;
  1226. end;
  1227. freetemp:=false;
  1228. vaddr:=true;
  1229. end
  1230. else if (lt.typ=enumdef) or
  1231. is_integer(lt) then
  1232. begin
  1233. vtype:=vtInteger;
  1234. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VINTEGER'));
  1235. end
  1236. else
  1237. if is_boolean(lt) then
  1238. begin
  1239. vtype:=vtBoolean;
  1240. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VINTEGER'));
  1241. end
  1242. else
  1243. if (lt.typ=orddef) then
  1244. begin
  1245. case torddef(lt).ordtype of
  1246. uchar:
  1247. begin
  1248. vtype:=vtChar;
  1249. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VINTEGER'));
  1250. end;
  1251. uwidechar:
  1252. begin
  1253. vtype:=vtWideChar;
  1254. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VINTEGER'));
  1255. end;
  1256. end;
  1257. end;
  1258. end;
  1259. floatdef :
  1260. begin
  1261. if is_currency(lt) then
  1262. begin
  1263. vtype:=vtCurrency;
  1264. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VCURRENCY'));
  1265. end
  1266. else
  1267. begin
  1268. vtype:=vtExtended;
  1269. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VEXTENDED'));
  1270. end;
  1271. freetemp:=false;
  1272. vaddr:=true;
  1273. end;
  1274. procvardef,
  1275. pointerdef :
  1276. begin
  1277. if is_pchar(lt) then
  1278. begin
  1279. vtype:=vtPChar;
  1280. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VPCHAR'));
  1281. end
  1282. else if is_pwidechar(lt) then
  1283. begin
  1284. vtype:=vtPWideChar;
  1285. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VPWIDECHAR'));
  1286. end
  1287. else
  1288. begin
  1289. vtype:=vtPointer;
  1290. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VPOINTER'));
  1291. end;
  1292. end;
  1293. variantdef :
  1294. begin
  1295. vtype:=vtVariant;
  1296. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VVARIANT'));
  1297. vaddr:=true;
  1298. freetemp:=false;
  1299. end;
  1300. classrefdef :
  1301. begin
  1302. vtype:=vtClass;
  1303. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VCLASS'));
  1304. end;
  1305. objectdef :
  1306. if is_interface(lt) then
  1307. begin
  1308. vtype:=vtInterface;
  1309. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VINTERFACE'));
  1310. end
  1311. { vtObject really means a class based on TObject }
  1312. else if is_class(lt) then
  1313. begin
  1314. vtype:=vtObject;
  1315. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VOBJECT'));
  1316. end
  1317. else
  1318. internalerror(200505171);
  1319. stringdef :
  1320. begin
  1321. if is_shortstring(lt) then
  1322. begin
  1323. vtype:=vtString;
  1324. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VSTRING'));
  1325. vaddr:=true;
  1326. freetemp:=false;
  1327. end
  1328. else
  1329. if is_ansistring(lt) then
  1330. begin
  1331. vtype:=vtAnsiString;
  1332. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VANSISTRING'));
  1333. freetemp:=false;
  1334. end
  1335. else
  1336. if is_widestring(lt) then
  1337. begin
  1338. vtype:=vtWideString;
  1339. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VWIDESTRING'));
  1340. freetemp:=false;
  1341. end
  1342. else
  1343. if is_unicodestring(lt) then
  1344. begin
  1345. vtype:=vtUnicodeString;
  1346. varfield:=tfieldvarsym(search_struct_member_no_helper(trecorddef(eledef),'VUNICODESTRING'));
  1347. freetemp:=false;
  1348. end;
  1349. end;
  1350. end;
  1351. if vtype=$ff then
  1352. internalerror(14357);
  1353. if not assigned(varfield) then
  1354. internalerror(2015102901);
  1355. { write changing field update href to the next element }
  1356. fref:=href;
  1357. hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,trecorddef(eledef),varfield,fref);
  1358. if vaddr then
  1359. begin
  1360. hlcg.location_force_mem(current_asmdata.CurrAsmList,hp.left.location,lt);
  1361. tmpreg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,cpointerdef.getreusable(lt));
  1362. hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,hp.left.resultdef,cpointerdef.getreusable(lt),hp.left.location.reference,tmpreg);
  1363. hlcg.a_load_reg_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(lt),varfield.vardef,tmpreg,fref);
  1364. end
  1365. else
  1366. hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,hp.left.resultdef,varfield.vardef,hp.left.location,fref);
  1367. { update href to the vtype field and write it }
  1368. fref:=href;
  1369. hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,trecorddef(eledef),varvtypefield,fref);
  1370. hlcg.a_load_const_ref(current_asmdata.CurrAsmList,varvtypefield.vardef,vtype,fref);
  1371. { goto next array element }
  1372. advancearrayoffset(href,elesize);
  1373. end
  1374. else
  1375. { normal array constructor of the same type }
  1376. begin
  1377. if is_managed_type(resultdef) then
  1378. freetemp:=false;
  1379. case hp.left.location.loc of
  1380. LOC_MMREGISTER,
  1381. LOC_CMMREGISTER:
  1382. hlcg.a_loadmm_reg_ref(current_asmdata.CurrAsmList,hp.left.resultdef,hp.left.resultdef,
  1383. hp.left.location.register,href,mms_movescalar);
  1384. LOC_FPUREGISTER,
  1385. LOC_CFPUREGISTER :
  1386. hlcg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,hp.left.resultdef,hp.left.resultdef,hp.left.location.register,href);
  1387. LOC_REFERENCE,
  1388. LOC_CREFERENCE :
  1389. begin
  1390. if is_shortstring(hp.left.resultdef) then
  1391. hlcg.g_copyshortstring(current_asmdata.CurrAsmList,hp.left.location.reference,href,
  1392. Tstringdef(hp.left.resultdef))
  1393. else
  1394. hlcg.g_concatcopy(current_asmdata.CurrAsmList,eledef,hp.left.location.reference,href);
  1395. end;
  1396. else
  1397. begin
  1398. {$ifndef cpuhighleveltarget}
  1399. {$ifdef cpu64bitalu}
  1400. if hp.left.location.size in [OS_128,OS_S128] then
  1401. cg128.a_load128_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
  1402. else
  1403. {$else cpu64bitalu}
  1404. if hp.left.location.size in [OS_64,OS_S64] then
  1405. cg64.a_load64_loc_ref(current_asmdata.CurrAsmList,hp.left.location,href)
  1406. else
  1407. {$endif cpu64bitalu}
  1408. {$endif not cpuhighleveltarget}
  1409. hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,eledef,eledef,hp.left.location,href);
  1410. end;
  1411. end;
  1412. advancearrayoffset(href,elesize);
  1413. end;
  1414. if freetemp then
  1415. location_freetemp(current_asmdata.CurrAsmList,hp.left.location);
  1416. end;
  1417. { load next entry }
  1418. hp:=tarrayconstructornode(hp.right);
  1419. end;
  1420. end;
  1421. {*****************************************************************************
  1422. SecondRTTI
  1423. *****************************************************************************}
  1424. procedure tcgrttinode.pass_generate_code;
  1425. var
  1426. indirect : boolean;
  1427. begin
  1428. indirect := (tf_supports_packages in target_info.flags) and
  1429. (target_info.system in systems_indirect_var_imports) and
  1430. (cs_imported_data in current_settings.localswitches) and
  1431. (rttidef.owner.moduleid<>current_module.moduleid);
  1432. location_reset_ref(location,LOC_CREFERENCE,OS_NO,sizeof(pint),[]);
  1433. case rttidatatype of
  1434. rdt_normal:
  1435. location.reference.symbol:=RTTIWriter.get_rtti_label(rttidef,rttitype,indirect);
  1436. rdt_ord2str:
  1437. location.reference.symbol:=RTTIWriter.get_rtti_label_ord2str(rttidef,rttitype,indirect);
  1438. rdt_str2ord:
  1439. location.reference.symbol:=RTTIWriter.get_rtti_label_str2ord(rttidef,rttitype,indirect);
  1440. end;
  1441. end;
  1442. begin
  1443. cloadnode:=tcgloadnode;
  1444. cassignmentnode:=tcgassignmentnode;
  1445. carrayconstructornode:=tcgarrayconstructornode;
  1446. crttinode:=tcgrttinode;
  1447. end.