cg386ld.pas 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Generate i386 assembler for load/assignment nodes
  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 cg386ld;
  19. interface
  20. uses
  21. tree;
  22. procedure secondload(var p : ptree);
  23. procedure secondassignment(var p : ptree);
  24. procedure secondfuncret(var p : ptree);
  25. procedure secondarrayconstruct(var p : ptree);
  26. implementation
  27. uses
  28. globtype,systems,
  29. cobjects,verbose,globals,files,
  30. symconst,symtable,aasm,types,
  31. hcodegen,temp_gen,pass_2,
  32. cpubase,cpuasm,
  33. cgai386,tgeni386,cg386cnv,cresstr;
  34. {*****************************************************************************
  35. SecondLoad
  36. *****************************************************************************}
  37. procedure secondload(var p : ptree);
  38. var
  39. hregister : tregister;
  40. symtabletype : tsymtabletype;
  41. i : longint;
  42. hp : preference;
  43. s : pasmsymbol;
  44. popeax : boolean;
  45. pushed : tpushed;
  46. hr : treference;
  47. begin
  48. simple_loadn:=true;
  49. reset_reference(p^.location.reference);
  50. case p^.symtableentry^.typ of
  51. { this is only for toasm and toaddr }
  52. absolutesym :
  53. begin
  54. p^.location.reference.symbol:=nil;
  55. if (pabsolutesym(p^.symtableentry)^.abstyp=toaddr) then
  56. begin
  57. if pabsolutesym(p^.symtableentry)^.absseg then
  58. p^.location.reference.segment:=R_FS;
  59. p^.location.reference.offset:=pabsolutesym(p^.symtableentry)^.address;
  60. end
  61. else
  62. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  63. end;
  64. constsym:
  65. begin
  66. if pconstsym(p^.symtableentry)^.consttype=constresourcestring then
  67. begin
  68. pushusedregisters(pushed,$ff);
  69. emit_const(A_PUSH,S_L,
  70. pconstsym(p^.symtableentry)^.resstrindex);
  71. emit_sym(A_PUSH,S_L,newasmsymbol(pconstsym(p^.symtableentry)^.owner^.name^+'_RESOURCESTRINGLIST'));
  72. emitcall('FPC_GETRESOURCESTRING');
  73. hregister:=getexplicitregister32(R_EAX);
  74. emit_reg_reg(A_MOV,S_L,R_EAX,hregister);
  75. gettempansistringreference(hr);
  76. decrstringref(p^.resulttype,hr);
  77. emit_reg_ref(A_MOV,S_L,hregister,
  78. newreference(hr));
  79. ungetregister32(hregister);
  80. popusedregisters(pushed);
  81. p^.location.loc:=LOC_MEM;
  82. p^.location.reference:=hr;
  83. end
  84. else
  85. internalerror(22798);
  86. end;
  87. varsym :
  88. begin
  89. hregister:=R_NO;
  90. { C variable }
  91. if (vo_is_C_var in pvarsym(p^.symtableentry)^.varoptions) then
  92. begin
  93. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  94. end
  95. { DLL variable }
  96. else if (vo_is_dll_var in pvarsym(p^.symtableentry)^.varoptions) then
  97. begin
  98. hregister:=getregister32;
  99. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  100. emit_ref_reg(A_MOV,S_L,newreference(p^.location.reference),hregister);
  101. p^.location.reference.symbol:=nil;
  102. p^.location.reference.base:=hregister;
  103. end
  104. { external variable }
  105. else if (vo_is_external in pvarsym(p^.symtableentry)^.varoptions) then
  106. begin
  107. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  108. end
  109. { thread variable }
  110. else if (vo_is_thread_var in pvarsym(p^.symtableentry)^.varoptions) then
  111. begin
  112. popeax:=not(R_EAX in unused);
  113. if popeax then
  114. emit_reg(A_PUSH,S_L,R_EAX);
  115. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  116. emit_ref(A_PUSH,S_L,newreference(p^.location.reference));
  117. { the called procedure isn't allowed to change }
  118. { any register except EAX }
  119. emitcall('FPC_RELOCATE_THREADVAR');
  120. reset_reference(p^.location.reference);
  121. p^.location.reference.base:=getregister32;
  122. emit_reg_reg(A_MOV,S_L,R_EAX,p^.location.reference.base);
  123. if popeax then
  124. emit_reg(A_POP,S_L,R_EAX);
  125. end
  126. { normal variable }
  127. else
  128. begin
  129. symtabletype:=p^.symtable^.symtabletype;
  130. { in case it is a register variable: }
  131. if pvarsym(p^.symtableentry)^.reg<>R_NO then
  132. begin
  133. if pvarsym(p^.symtableentry)^.reg in [R_ST0..R_ST7] then
  134. begin
  135. p^.location.loc:=LOC_CFPUREGISTER;
  136. p^.location.register:=pvarsym(p^.symtableentry)^.reg;
  137. end
  138. else
  139. begin
  140. p^.location.loc:=LOC_CREGISTER;
  141. p^.location.register:=pvarsym(p^.symtableentry)^.reg;
  142. unused:=unused-[pvarsym(p^.symtableentry)^.reg];
  143. end;
  144. end
  145. else
  146. begin
  147. { first handle local and temporary variables }
  148. if (symtabletype in [parasymtable,inlinelocalsymtable,
  149. inlineparasymtable,localsymtable]) then
  150. begin
  151. p^.location.reference.base:=procinfo^.framepointer;
  152. p^.location.reference.offset:=pvarsym(p^.symtableentry)^.address+p^.symtable^.address_fixup;
  153. if (symtabletype in [localsymtable,inlinelocalsymtable]) then
  154. begin
  155. if use_esp_stackframe then
  156. dec(p^.location.reference.offset,
  157. pvarsym(p^.symtableentry)^.getsize)
  158. else
  159. p^.location.reference.offset:=-p^.location.reference.offset;
  160. end;
  161. if (lexlevel>(p^.symtable^.symtablelevel)) then
  162. begin
  163. hregister:=getregister32;
  164. { make a reference }
  165. hp:=new_reference(procinfo^.framepointer,
  166. procinfo^.framepointer_offset);
  167. emit_ref_reg(A_MOV,S_L,hp,hregister);
  168. simple_loadn:=false;
  169. i:=lexlevel-1;
  170. while i>(p^.symtable^.symtablelevel) do
  171. begin
  172. { make a reference }
  173. hp:=new_reference(hregister,8);
  174. emit_ref_reg(A_MOV,S_L,hp,hregister);
  175. dec(i);
  176. end;
  177. p^.location.reference.base:=hregister;
  178. end;
  179. end
  180. else
  181. case symtabletype of
  182. unitsymtable,globalsymtable,
  183. staticsymtable :
  184. begin
  185. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  186. end;
  187. stt_exceptsymtable:
  188. begin
  189. p^.location.reference.base:=procinfo^.framepointer;
  190. p^.location.reference.offset:=pvarsym(p^.symtableentry)^.address;
  191. end;
  192. objectsymtable:
  193. begin
  194. if (sp_static in pvarsym(p^.symtableentry)^.symoptions) then
  195. begin
  196. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  197. end
  198. else
  199. begin
  200. p^.location.reference.base:=R_ESI;
  201. p^.location.reference.offset:=pvarsym(p^.symtableentry)^.address;
  202. end;
  203. end;
  204. withsymtable:
  205. begin
  206. { make a reference }
  207. { symtable datasize field
  208. contains the offset of the temp
  209. stored }
  210. { hp:=new_reference(procinfo^.framepointer,
  211. p^.symtable^.datasize);
  212. emit_ref_reg(A_MOV,S_L,hp,hregister);}
  213. if ptree(pwithsymtable(p^.symtable)^.withnode)^.islocal then
  214. begin
  215. p^.location.reference:=ptree(pwithsymtable(p^.symtable)^.withnode)^.withreference^;
  216. end
  217. else
  218. begin
  219. hregister:=getregister32;
  220. p^.location.reference.base:=hregister;
  221. emit_ref_reg(A_MOV,S_L,
  222. newreference(ptree(pwithsymtable(p^.symtable)^.withnode)^.withreference^),
  223. hregister);
  224. end;
  225. inc(p^.location.reference.offset,pvarsym(p^.symtableentry)^.address);
  226. end;
  227. end;
  228. end;
  229. { in case call by reference, then calculate. Open array
  230. is always an reference! }
  231. if (pvarsym(p^.symtableentry)^.varspez=vs_var) or
  232. is_open_array(pvarsym(p^.symtableentry)^.definition) or
  233. is_array_of_const(pvarsym(p^.symtableentry)^.definition) or
  234. ((pvarsym(p^.symtableentry)^.varspez=vs_const) and
  235. push_addr_param(pvarsym(p^.symtableentry)^.definition)) then
  236. begin
  237. simple_loadn:=false;
  238. if hregister=R_NO then
  239. hregister:=getregister32;
  240. if p^.location.loc=LOC_CREGISTER then
  241. begin
  242. emit_reg_reg(A_MOV,S_L,
  243. p^.location.register,hregister);
  244. p^.location.loc:=LOC_REFERENCE;
  245. end
  246. else
  247. begin
  248. emit_ref_reg(A_MOV,S_L,
  249. newreference(p^.location.reference),
  250. hregister);
  251. end;
  252. reset_reference(p^.location.reference);
  253. p^.location.reference.base:=hregister;
  254. end;
  255. end;
  256. end;
  257. procsym:
  258. begin
  259. if assigned(p^.left) then
  260. begin
  261. secondpass(p^.left);
  262. p^.location.loc:=LOC_MEM;
  263. gettempofsizereference(8,p^.location.reference);
  264. { load class instance address }
  265. case p^.left^.location.loc of
  266. LOC_CREGISTER,
  267. LOC_REGISTER:
  268. begin
  269. hregister:=p^.left^.location.register;
  270. ungetregister32(p^.left^.location.register);
  271. if not(pobjectdef(p^.left^.resulttype)^.is_class) then
  272. CGMessage(cg_e_illegal_expression);
  273. end;
  274. LOC_MEM,
  275. LOC_REFERENCE:
  276. begin
  277. hregister:=R_EDI;
  278. if pobjectdef(p^.left^.resulttype)^.is_class then
  279. emit_ref_reg(A_MOV,S_L,
  280. newreference(p^.left^.location.reference),R_EDI)
  281. else
  282. emit_ref_reg(A_LEA,S_L,
  283. newreference(p^.left^.location.reference),R_EDI);
  284. del_reference(p^.left^.location.reference);
  285. ungetiftemp(p^.left^.location.reference);
  286. end;
  287. else internalerror(26019);
  288. end;
  289. { store the class instance address }
  290. new(hp);
  291. hp^:=p^.location.reference;
  292. inc(hp^.offset,4);
  293. emit_reg_ref(A_MOV,S_L,
  294. hregister,hp);
  295. { virtual method ? }
  296. if (po_virtualmethod in pprocsym(p^.symtableentry)^.definition^.procoptions) then
  297. begin
  298. new(hp);
  299. reset_reference(hp^);
  300. hp^.base:=hregister;
  301. { load vmt pointer }
  302. emit_ref_reg(A_MOV,S_L,
  303. hp,R_EDI);
  304. {$IfDef regallocfix}
  305. del_reference(hp^);
  306. {$EndIf regallocfix}
  307. { load method address }
  308. new(hp);
  309. reset_reference(hp^);
  310. hp^.base:=R_EDI;
  311. hp^.offset:=pprocsym(p^.symtableentry)^.definition^._class^.vmtmethodoffset(
  312. pprocsym(p^.symtableentry)^.definition^.extnumber);
  313. emit_ref_reg(A_MOV,S_L,
  314. hp,R_EDI);
  315. { ... and store it }
  316. emit_reg_ref(A_MOV,S_L,
  317. R_EDI,newreference(p^.location.reference));
  318. end
  319. else
  320. begin
  321. s:=newasmsymbol(pprocsym(p^.symtableentry)^.definition^.mangledname);
  322. emit_sym_ofs_ref(A_MOV,S_L,s,0,
  323. newreference(p^.location.reference));
  324. end;
  325. end
  326. else
  327. begin
  328. {!!!!! Be aware, work on virtual methods too }
  329. p^.location.reference.symbol:=newasmsymbol(pprocsym(p^.symtableentry)^.definition^.mangledname);
  330. end;
  331. end;
  332. typedconstsym :
  333. begin
  334. p^.location.reference.symbol:=newasmsymbol(p^.symtableentry^.mangledname);
  335. end;
  336. else internalerror(4);
  337. end;
  338. end;
  339. {*****************************************************************************
  340. SecondAssignment
  341. *****************************************************************************}
  342. procedure secondassignment(var p : ptree);
  343. var
  344. opsize : topsize;
  345. otlabel,hlabel,oflabel : pasmlabel;
  346. fputyp : tfloattype;
  347. loc : tloc;
  348. r : preference;
  349. ai : paicpu;
  350. op : tasmop;
  351. pushed : boolean;
  352. begin
  353. otlabel:=truelabel;
  354. oflabel:=falselabel;
  355. getlabel(truelabel);
  356. getlabel(falselabel);
  357. { calculate left sides }
  358. if not(p^.concat_string) then
  359. secondpass(p^.left);
  360. if codegenerror then
  361. exit;
  362. {$ifdef dummy}
  363. { we use now the standard mechanism via maybe_push/restore
  364. to do that (FK)
  365. }
  366. case p^.left^.location.loc of
  367. LOC_REFERENCE : begin
  368. { in case left operator uses to register }
  369. { but to few are free then LEA }
  370. if (p^.left^.location.reference.base<>R_NO) and
  371. (p^.left^.location.reference.index<>R_NO) and
  372. (usablereg32<p^.right^.registers32) then
  373. begin
  374. del_reference(p^.left^.location.reference);
  375. hregister:=getregister32;
  376. emit_ref_reg(A_LEA,S_L,newreference(
  377. p^.left^.location.reference),
  378. hregister);
  379. reset_reference(p^.left^.location.reference);
  380. p^.left^.location.reference.base:=hregister;
  381. p^.left^.location.reference.index:=R_NO;
  382. end;
  383. loc:=LOC_REFERENCE;
  384. end;
  385. LOC_CFPUREGISTER:
  386. loc:=LOC_CFPUREGISTER;
  387. LOC_CREGISTER:
  388. loc:=LOC_CREGISTER;
  389. LOC_MMXREGISTER:
  390. loc:=LOC_MMXREGISTER;
  391. LOC_CMMXREGISTER:
  392. loc:=LOC_CMMXREGISTER;
  393. else
  394. begin
  395. CGMessage(cg_e_illegal_expression);
  396. exit;
  397. end;
  398. end;
  399. {$endif dummy}
  400. if not(p^.left^.location.loc in [LOC_REFERENCE,LOC_CFPUREGISTER,
  401. LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER]) then
  402. begin
  403. CGMessage(cg_e_illegal_expression);
  404. exit;
  405. end;
  406. loc:=p^.left^.location.loc;
  407. { lets try to optimize this (PM) }
  408. { define a dest_loc that is the location }
  409. { and a ptree to verify that it is the right }
  410. { place to insert it }
  411. {$ifdef test_dest_loc}
  412. if (aktexprlevel<4) then
  413. begin
  414. dest_loc_known:=true;
  415. dest_loc:=p^.left^.location;
  416. dest_loc_tree:=p^.right;
  417. end;
  418. {$endif test_dest_loc}
  419. { left can't be never a 64 bit LOC_REGISTER, so the 3. arg }
  420. { can be false }
  421. pushed:=maybe_push(p^.right^.registers32,p^.left,false);
  422. secondpass(p^.right);
  423. if pushed then restore(p^.left,false);
  424. if codegenerror then
  425. exit;
  426. {$ifdef test_dest_loc}
  427. dest_loc_known:=false;
  428. if in_dest_loc then
  429. begin
  430. truelabel:=otlabel;
  431. falselabel:=oflabel;
  432. in_dest_loc:=false;
  433. exit;
  434. end;
  435. {$endif test_dest_loc}
  436. if p^.left^.resulttype^.deftype=stringdef then
  437. begin
  438. if is_ansistring(p^.left^.resulttype) then
  439. begin
  440. { the source and destinations are released
  441. in loadansistring, because an ansi string can
  442. also be in a register
  443. }
  444. loadansistring(p);
  445. end
  446. else
  447. if is_shortstring(p^.left^.resulttype) and
  448. not (p^.concat_string) then
  449. begin
  450. if is_ansistring(p^.right^.resulttype) then
  451. begin
  452. if (p^.right^.treetype=stringconstn) and
  453. (p^.right^.length=0) then
  454. begin
  455. emit_const_ref(A_MOV,S_B,
  456. 0,newreference(p^.left^.location.reference));
  457. {$IfDef regallocfix}
  458. del_reference(p^.left^.location.reference);
  459. {$EndIf regallocfix}
  460. end
  461. else
  462. loadansi2short(p^.right,p^.left);
  463. end
  464. else
  465. begin
  466. { we do not need destination anymore }
  467. del_reference(p^.left^.location.reference);
  468. {del_reference(p^.right^.location.reference);
  469. done in loadshortstring }
  470. loadshortstring(p);
  471. ungetiftemp(p^.right^.location.reference);
  472. end;
  473. end
  474. else if is_longstring(p^.left^.resulttype) then
  475. begin
  476. end
  477. else
  478. begin
  479. { its the only thing we have to do }
  480. del_reference(p^.right^.location.reference);
  481. end
  482. end
  483. else case p^.right^.location.loc of
  484. LOC_REFERENCE,
  485. LOC_MEM : begin
  486. { extra handling for ordinal constants }
  487. if (p^.right^.treetype in [ordconstn,fixconstn]) or
  488. (loc=LOC_CREGISTER) then
  489. begin
  490. case p^.left^.resulttype^.size of
  491. 1 : opsize:=S_B;
  492. 2 : opsize:=S_W;
  493. 4 : opsize:=S_L;
  494. { S_L is correct, the copy is done }
  495. { with two moves }
  496. 8 : opsize:=S_L;
  497. end;
  498. if loc=LOC_CREGISTER then
  499. begin
  500. emit_ref_reg(A_MOV,opsize,
  501. newreference(p^.right^.location.reference),
  502. p^.left^.location.register);
  503. if is_64bitint(p^.right^.resulttype) then
  504. begin
  505. r:=newreference(p^.right^.location.reference);
  506. inc(r^.offset,4);
  507. emit_ref_reg(A_MOV,opsize,r,
  508. p^.left^.location.registerhigh);
  509. end;
  510. {$IfDef regallocfix}
  511. del_reference(p^.right^.location.reference);
  512. {$EndIf regallocfix}
  513. end
  514. else
  515. begin
  516. emit_const_ref(A_MOV,opsize,
  517. p^.right^.location.reference.offset,
  518. newreference(p^.left^.location.reference));
  519. if is_64bitint(p^.right^.resulttype) then
  520. begin
  521. r:=newreference(p^.left^.location.reference);
  522. inc(r^.offset,4);
  523. emit_const_ref(A_MOV,opsize,
  524. 0,r);
  525. end;
  526. {$IfDef regallocfix}
  527. del_reference(p^.left^.location.reference);
  528. {$EndIf regallocfix}
  529. {emit_const_loc(A_MOV,opsize,
  530. p^.right^.location.reference.offset,
  531. p^.left^.location);}
  532. end;
  533. end
  534. else if loc=LOC_CFPUREGISTER then
  535. begin
  536. floatloadops(pfloatdef(p^.right^.resulttype)^.typ,op,opsize);
  537. emit_ref(op,opsize,
  538. newreference(p^.right^.location.reference));
  539. emit_reg(A_FSTP,S_NO,
  540. correct_fpuregister(p^.left^.location.register,fpuvaroffset+1));
  541. end
  542. else
  543. begin
  544. if (p^.right^.resulttype^.needs_inittable) and
  545. ( (p^.right^.resulttype^.deftype<>objectdef) or
  546. not(pobjectdef(p^.right^.resulttype)^.is_class)) then
  547. begin
  548. { this would be a problem }
  549. if not(p^.left^.resulttype^.needs_inittable) then
  550. internalerror(3457);
  551. { increment source reference counter }
  552. new(r);
  553. reset_reference(r^);
  554. r^.symbol:=p^.right^.resulttype^.get_inittable_label;
  555. emitpushreferenceaddr(r^);
  556. emitpushreferenceaddr(p^.right^.location.reference);
  557. emitcall('FPC_ADDREF');
  558. { decrement destination reference counter }
  559. new(r);
  560. reset_reference(r^);
  561. r^.symbol:=p^.left^.resulttype^.get_inittable_label;
  562. emitpushreferenceaddr(r^);
  563. emitpushreferenceaddr(p^.left^.location.reference);
  564. emitcall('FPC_DECREF');
  565. end;
  566. {$ifdef regallocfix}
  567. concatcopy(p^.right^.location.reference,
  568. p^.left^.location.reference,p^.left^.resulttype^.size,true,false);
  569. ungetiftemp(p^.right^.location.reference);
  570. {$Else regallocfix}
  571. concatcopy(p^.right^.location.reference,
  572. p^.left^.location.reference,p^.left^.resulttype^.size,false,false);
  573. ungetiftemp(p^.right^.location.reference);
  574. {$endif regallocfix}
  575. end;
  576. end;
  577. {$ifdef SUPPORT_MMX}
  578. LOC_CMMXREGISTER,
  579. LOC_MMXREGISTER:
  580. begin
  581. if loc=LOC_CMMXREGISTER then
  582. emit_reg_reg(A_MOVQ,S_NO,
  583. p^.right^.location.register,p^.left^.location.register)
  584. else
  585. emit_reg_ref(A_MOVQ,S_NO,
  586. p^.right^.location.register,newreference(p^.left^.location.reference));
  587. end;
  588. {$endif SUPPORT_MMX}
  589. LOC_REGISTER,
  590. LOC_CREGISTER : begin
  591. case p^.right^.resulttype^.size of
  592. 1 : opsize:=S_B;
  593. 2 : opsize:=S_W;
  594. 4 : opsize:=S_L;
  595. 8 : opsize:=S_L;
  596. end;
  597. { simplified with op_reg_loc }
  598. if loc=LOC_CREGISTER then
  599. begin
  600. emit_reg_reg(A_MOV,opsize,
  601. p^.right^.location.register,
  602. p^.left^.location.register);
  603. {$IfDef regallocfix}
  604. ungetregister(p^.right^.location.register);
  605. {$EndIf regallocfix}
  606. end
  607. else
  608. Begin
  609. emit_reg_ref(A_MOV,opsize,
  610. p^.right^.location.register,
  611. newreference(p^.left^.location.reference));
  612. {$IfDef regallocfix}
  613. ungetregister(p^.right^.location.register);
  614. del_reference(p^.left^.location.reference);
  615. {$EndIf regallocfix}
  616. end;
  617. if is_64bitint(p^.right^.resulttype) then
  618. begin
  619. { simplified with op_reg_loc }
  620. if loc=LOC_CREGISTER then
  621. emit_reg_reg(A_MOV,opsize,
  622. p^.right^.location.registerhigh,
  623. p^.left^.location.registerhigh)
  624. else
  625. begin
  626. r:=newreference(p^.left^.location.reference);
  627. inc(r^.offset,4);
  628. emit_reg_ref(A_MOV,opsize,
  629. p^.right^.location.registerhigh,r);
  630. end;
  631. end;
  632. {emit_reg_loc(A_MOV,opsize,
  633. p^.right^.location.register,
  634. p^.left^.location); }
  635. end;
  636. LOC_FPU : begin
  637. if (p^.left^.resulttype^.deftype=floatdef) then
  638. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  639. else
  640. if (p^.right^.resulttype^.deftype=floatdef) then
  641. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  642. else
  643. if (p^.right^.treetype=typeconvn) and
  644. (p^.right^.left^.resulttype^.deftype=floatdef) then
  645. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  646. else
  647. fputyp:=s32real;
  648. case loc of
  649. LOC_CFPUREGISTER:
  650. begin
  651. emit_reg(A_FSTP,S_NO,
  652. correct_fpuregister(p^.left^.location.register,fpuvaroffset));
  653. dec(fpuvaroffset);
  654. end;
  655. LOC_REFERENCE:
  656. floatstore(fputyp,p^.left^.location.reference);
  657. else
  658. internalerror(48991);
  659. end;
  660. end;
  661. LOC_CFPUREGISTER: begin
  662. if (p^.left^.resulttype^.deftype=floatdef) then
  663. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  664. else
  665. if (p^.right^.resulttype^.deftype=floatdef) then
  666. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  667. else
  668. if (p^.right^.treetype=typeconvn) and
  669. (p^.right^.left^.resulttype^.deftype=floatdef) then
  670. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  671. else
  672. fputyp:=s32real;
  673. emit_reg(A_FLD,S_NO,
  674. correct_fpuregister(p^.right^.location.register,fpuvaroffset));
  675. inc(fpuvaroffset);
  676. case loc of
  677. LOC_CFPUREGISTER:
  678. begin
  679. emit_reg(A_FSTP,S_NO,
  680. correct_fpuregister(p^.right^.location.register,fpuvaroffset));
  681. dec(fpuvaroffset);
  682. end;
  683. LOC_REFERENCE:
  684. floatstore(fputyp,p^.left^.location.reference);
  685. else
  686. internalerror(48992);
  687. end;
  688. end;
  689. LOC_JUMP : begin
  690. getlabel(hlabel);
  691. emitlab(truelabel);
  692. if loc=LOC_CREGISTER then
  693. emit_const_reg(A_MOV,S_B,
  694. 1,p^.left^.location.register)
  695. else
  696. emit_const_ref(A_MOV,S_B,
  697. 1,newreference(p^.left^.location.reference));
  698. {emit_const_loc(A_MOV,S_B,
  699. 1,p^.left^.location);}
  700. emitjmp(C_None,hlabel);
  701. emitlab(falselabel);
  702. if loc=LOC_CREGISTER then
  703. emit_reg_reg(A_XOR,S_B,
  704. p^.left^.location.register,
  705. p^.left^.location.register)
  706. else
  707. begin
  708. emit_const_ref(A_MOV,S_B,
  709. 0,newreference(p^.left^.location.reference));
  710. {$IfDef regallocfix}
  711. del_reference(p^.left^.location.reference);
  712. {$EndIf regallocfix}
  713. end;
  714. emitlab(hlabel);
  715. end;
  716. LOC_FLAGS : begin
  717. if loc=LOC_CREGISTER then
  718. emit_flag2reg(p^.right^.location.resflags,p^.left^.location.register)
  719. else
  720. begin
  721. ai:=new(paicpu,op_ref(A_Setcc,S_B,newreference(p^.left^.location.reference)));
  722. ai^.SetCondition(flag_2_cond[p^.right^.location.resflags]);
  723. exprasmlist^.concat(ai);
  724. end;
  725. {$IfDef regallocfix}
  726. del_reference(p^.left^.location.reference);
  727. {$EndIf regallocfix}
  728. end;
  729. end;
  730. freelabel(truelabel);
  731. freelabel(falselabel);
  732. truelabel:=otlabel;
  733. falselabel:=oflabel;
  734. end;
  735. {*****************************************************************************
  736. SecondFuncRet
  737. *****************************************************************************}
  738. procedure secondfuncret(var p : ptree);
  739. var
  740. hr : tregister;
  741. hp : preference;
  742. pp : pprocinfo;
  743. hr_valid : boolean;
  744. begin
  745. reset_reference(p^.location.reference);
  746. hr_valid:=false;
  747. if procinfo<>pprocinfo(p^.funcretprocinfo) then
  748. begin
  749. hr:=getregister32;
  750. hr_valid:=true;
  751. hp:=new_reference(procinfo^.framepointer,
  752. procinfo^.framepointer_offset);
  753. emit_ref_reg(A_MOV,S_L,hp,hr);
  754. pp:=procinfo^.parent;
  755. { walk up the stack frame }
  756. while pp<>pprocinfo(p^.funcretprocinfo) do
  757. begin
  758. hp:=new_reference(hr,
  759. pp^.framepointer_offset);
  760. emit_ref_reg(A_MOV,S_L,hp,hr);
  761. pp:=pp^.parent;
  762. end;
  763. p^.location.reference.base:=hr;
  764. p^.location.reference.offset:=pp^.retoffset;
  765. end
  766. else
  767. begin
  768. p^.location.reference.base:=procinfo^.framepointer;
  769. p^.location.reference.offset:=procinfo^.retoffset;
  770. end;
  771. if ret_in_param(p^.retdef) then
  772. begin
  773. if not hr_valid then
  774. hr:=getregister32;
  775. emit_ref_reg(A_MOV,S_L,newreference(p^.location.reference),hr);
  776. p^.location.reference.base:=hr;
  777. p^.location.reference.offset:=0;
  778. end;
  779. end;
  780. {*****************************************************************************
  781. SecondArrayConstruct
  782. *****************************************************************************}
  783. const
  784. vtInteger = 0;
  785. vtBoolean = 1;
  786. vtChar = 2;
  787. vtExtended = 3;
  788. vtString = 4;
  789. vtPointer = 5;
  790. vtPChar = 6;
  791. vtObject = 7;
  792. vtClass = 8;
  793. vtWideChar = 9;
  794. vtPWideChar = 10;
  795. vtAnsiString = 11;
  796. vtCurrency = 12;
  797. vtVariant = 13;
  798. vtInterface = 14;
  799. vtWideString = 15;
  800. vtInt64 = 16;
  801. procedure secondarrayconstruct(var p : ptree);
  802. var
  803. hp : ptree;
  804. href : treference;
  805. lt : pdef;
  806. vaddr : boolean;
  807. vtype : longint;
  808. freetemp,
  809. dovariant : boolean;
  810. elesize : longint;
  811. begin
  812. dovariant:=p^.forcevaria or parraydef(p^.resulttype)^.isvariant;
  813. if dovariant then
  814. elesize:=8
  815. else
  816. begin
  817. elesize:=parraydef(p^.resulttype)^.elesize;
  818. if elesize>4 then
  819. internalerror(8765678);
  820. end;
  821. if not p^.cargs then
  822. begin
  823. reset_reference(p^.location.reference);
  824. { Allocate always a temp, also if no elements are required, to
  825. be sure that location is valid (PFV) }
  826. if parraydef(p^.resulttype)^.highrange=-1 then
  827. gettempofsizereference(elesize,p^.location.reference)
  828. else
  829. gettempofsizereference((parraydef(p^.resulttype)^.highrange+1)*elesize,p^.location.reference);
  830. href:=p^.location.reference;
  831. end;
  832. hp:=p;
  833. while assigned(hp) do
  834. begin
  835. if assigned(hp^.left) then
  836. begin
  837. freetemp:=true;
  838. secondpass(hp^.left);
  839. if codegenerror then
  840. exit;
  841. if dovariant then
  842. begin
  843. { find the correct vtype value }
  844. vtype:=$ff;
  845. vaddr:=false;
  846. lt:=hp^.left^.resulttype;
  847. case lt^.deftype of
  848. enumdef,
  849. orddef :
  850. begin
  851. if (lt^.deftype=enumdef) or
  852. is_integer(lt) then
  853. vtype:=vtInteger
  854. else
  855. if is_boolean(lt) then
  856. vtype:=vtBoolean
  857. else
  858. if (lt^.deftype=orddef) and (porddef(lt)^.typ=uchar) then
  859. vtype:=vtChar;
  860. end;
  861. floatdef :
  862. begin
  863. vtype:=vtExtended;
  864. vaddr:=true;
  865. end;
  866. procvardef,
  867. pointerdef :
  868. begin
  869. if is_pchar(lt) then
  870. vtype:=vtPChar
  871. else
  872. vtype:=vtPointer;
  873. end;
  874. classrefdef :
  875. vtype:=vtClass;
  876. objectdef :
  877. begin
  878. vtype:=vtObject;
  879. end;
  880. stringdef :
  881. begin
  882. if is_shortstring(lt) then
  883. begin
  884. vtype:=vtString;
  885. vaddr:=true;
  886. freetemp:=false;
  887. end
  888. else
  889. if is_ansistring(lt) then
  890. vtype:=vtAnsiString;
  891. end;
  892. end;
  893. if vtype=$ff then
  894. internalerror(14357);
  895. { write C style pushes or an pascal array }
  896. if p^.cargs then
  897. begin
  898. if vaddr then
  899. begin
  900. emit_to_mem(hp^.left);
  901. emit_push_lea_loc(hp^.left^.location,freetemp);
  902. del_reference(hp^.left^.location.reference);
  903. end
  904. else
  905. emit_push_loc(hp^.left^.location);
  906. end
  907. else
  908. begin
  909. { update href to the vtype field and write it }
  910. emit_const_ref(A_MOV,S_L,
  911. vtype,newreference(href));
  912. inc(href.offset,4);
  913. { write changing field update href to the next element }
  914. if vaddr then
  915. begin
  916. emit_to_mem(hp^.left);
  917. emit_lea_loc_ref(hp^.left^.location,href,freetemp);
  918. end
  919. else
  920. emit_mov_loc_ref(hp^.left^.location,href,S_L);
  921. inc(href.offset,4);
  922. end;
  923. end
  924. else
  925. { normal array constructor of the same type }
  926. begin
  927. case elesize of
  928. 1 :
  929. emit_mov_loc_ref(hp^.left^.location,href,S_B);
  930. 2 :
  931. emit_mov_loc_ref(hp^.left^.location,href,S_W);
  932. 4 :
  933. emit_mov_loc_ref(hp^.left^.location,href,S_L);
  934. else
  935. internalerror(87656781);
  936. end;
  937. inc(href.offset,elesize);
  938. end;
  939. end;
  940. { load next entry }
  941. hp:=hp^.right;
  942. end;
  943. end;
  944. end.
  945. {
  946. $Log$
  947. Revision 1.89 1999-10-12 22:35:48 florian
  948. * compiler didn't complain about l1+l2:=l1+l2; it gave only an assembler
  949. error, fixed
  950. Revision 1.88 1999/09/27 23:44:47 peter
  951. * procinfo is now a pointer
  952. * support for result setting in sub procedure
  953. Revision 1.87 1999/09/26 13:26:06 florian
  954. * exception patch of Romio nevertheless the excpetion handling
  955. needs some corections regarding register saving
  956. * gettempansistring is again a procedure
  957. Revision 1.86 1999/09/16 07:56:46 pierre
  958. * double del_reference removed
  959. Revision 1.85 1999/09/12 08:48:03 florian
  960. * bugs 593 and 607 fixed
  961. * some other potential bugs with array constructors fixed
  962. * for classes compiled in $M+ and it's childs, the default access method
  963. is now published
  964. * fixed copyright message (it is now 1993-99)
  965. Revision 1.84 1999/09/11 09:08:31 florian
  966. * fixed bug 596
  967. * fixed some problems with procedure variables and procedures of object,
  968. especially in TP mode. Procedure of object doesn't apply only to classes,
  969. it is also allowed for objects !!
  970. Revision 1.83 1999/09/01 09:37:14 peter
  971. * removed warning
  972. Revision 1.82 1999/09/01 09:26:21 peter
  973. * fixed temp allocation for arrayconstructor
  974. Revision 1.81 1999/08/28 15:34:17 florian
  975. * bug 519 fixed
  976. Revision 1.80 1999/08/26 20:24:37 michael
  977. + Hopefuly last fixes for resourcestrings
  978. Revision 1.79 1999/08/25 16:41:05 peter
  979. * resources are working again
  980. Revision 1.78 1999/08/25 11:59:43 jonas
  981. * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
  982. Revision 1.77 1999/08/24 22:38:51 michael
  983. * more resourcestring changes
  984. Revision 1.76 1999/08/23 11:45:39 michael
  985. * Hopefully final attempt at resourcestrings
  986. Revision 1.75 1999/08/19 13:08:49 pierre
  987. * emit_??? used
  988. Revision 1.74 1999/08/17 13:26:06 peter
  989. * arrayconstructor -> arrayofconst fixed when arraycosntructor was not
  990. variant.
  991. Revision 1.73 1999/08/13 21:33:09 peter
  992. * support for array constructors extended and more error checking
  993. Revision 1.72 1999/08/09 22:19:50 peter
  994. * classes vmt changed to only positive addresses
  995. * sharedlib creation is working
  996. Revision 1.71 1999/08/07 14:20:55 florian
  997. * some small problems fixed
  998. Revision 1.70 1999/08/04 13:45:22 florian
  999. + floating point register variables !!
  1000. * pairegalloc is now generated for register variables
  1001. Revision 1.69 1999/08/04 00:22:50 florian
  1002. * renamed i386asm and i386base to cpuasm and cpubase
  1003. Revision 1.68 1999/08/03 22:02:43 peter
  1004. * moved bitmask constants to sets
  1005. * some other type/const renamings
  1006. Revision 1.67 1999/07/27 23:36:36 peter
  1007. * try to determine the fpu type needed in assignment
  1008. Revision 1.66 1999/07/24 15:12:56 michael
  1009. changes for resourcestrings
  1010. Revision 1.65 1999/07/23 23:09:06 peter
  1011. * resourcestring fix
  1012. Revision 1.64 1999/07/22 09:37:37 florian
  1013. + resourcestring implemented
  1014. + start of longstring support
  1015. Revision 1.63 1999/07/05 20:13:12 peter
  1016. * removed temp defines
  1017. Revision 1.62 1999/06/30 15:43:18 florian
  1018. * two bugs regarding method variables fixed
  1019. - if you take in a method the address of another method
  1020. don't need self anymore
  1021. - if the class pointer was in a register, wrong code for a method
  1022. variable load was generated
  1023. Revision 1.61 1999/06/28 22:29:11 florian
  1024. * qword division fixed
  1025. + code for qword/int64 type casting added:
  1026. range checking isn't implemented yet
  1027. Revision 1.60 1999/05/31 12:42:43 peter
  1028. * fixed crash with empty array constructor
  1029. Revision 1.59 1999/05/27 19:44:14 peter
  1030. * removed oldasm
  1031. * plabel -> pasmlabel
  1032. * -a switches to source writing automaticly
  1033. * assembler readers OOPed
  1034. * asmsymbol automaticly external
  1035. * jumptables and other label fixes for asm readers
  1036. Revision 1.58 1999/05/23 18:42:02 florian
  1037. * better error recovering in typed constants
  1038. * some problems with arrays of const fixed, some problems
  1039. due my previous
  1040. - the location type of array constructor is now LOC_MEM
  1041. - the pushing of high fixed
  1042. - parameter copying fixed
  1043. - zero temp. allocation removed
  1044. * small problem in the assembler writers fixed:
  1045. ref to nil wasn't written correctly
  1046. Revision 1.57 1999/05/21 13:54:51 peter
  1047. * NEWLAB for label as symbol
  1048. Revision 1.56 1999/05/17 23:51:38 peter
  1049. * with temp vars now use a reference with a persistant temp instead
  1050. of setting datasize
  1051. Revision 1.55 1999/05/17 21:57:04 florian
  1052. * new temporary ansistring handling
  1053. Revision 1.54 1999/05/12 00:19:43 peter
  1054. * removed R_DEFAULT_SEG
  1055. * uniform float names
  1056. Revision 1.53 1999/05/06 09:05:16 peter
  1057. * generic write_float and str_float
  1058. * fixed constant float conversions
  1059. Revision 1.52 1999/05/01 13:24:10 peter
  1060. * merged nasm compiler
  1061. * old asm moved to oldasm/
  1062. Revision 1.51 1999/04/28 06:01:55 florian
  1063. * changes of Bruessel:
  1064. + message handler can now take an explicit self
  1065. * typinfo fixed: sometimes the type names weren't written
  1066. * the type checking for pointer comparisations and subtraction
  1067. and are now more strict (was also buggy)
  1068. * small bug fix to link.pas to support compiling on another
  1069. drive
  1070. * probable bug in popt386 fixed: call/jmp => push/jmp
  1071. transformation didn't count correctly the jmp references
  1072. + threadvar support
  1073. * warning if ln/sqrt gets an invalid constant argument
  1074. Revision 1.50 1999/04/16 13:42:26 jonas
  1075. * more regalloc fixes (still not complete)
  1076. Revision 1.49 1999/04/13 18:57:48 florian
  1077. * classes which contain ansistring get unnecessary calls
  1078. to addref/decref when they are assigned, fixed
  1079. Revision 1.48 1999/04/09 15:48:47 jonas
  1080. * added fix for missing register deallocation (-dregallocfix)
  1081. Revision 1.47 1999/03/31 13:55:07 peter
  1082. * assembler inlining working for ag386bin
  1083. Revision 1.46 1999/03/24 23:16:52 peter
  1084. * fixed bugs 212,222,225,227,229,231,233
  1085. Revision 1.45 1999/02/25 21:02:28 peter
  1086. * ag386bin updates
  1087. + coff writer
  1088. Revision 1.44 1999/02/22 02:15:12 peter
  1089. * updates for ag386bin
  1090. Revision 1.43 1999/01/27 00:13:54 florian
  1091. * "procedure of object"-stuff fixed
  1092. Revision 1.42 1999/01/21 22:10:40 peter
  1093. * fixed array of const
  1094. * generic platform independent high() support
  1095. Revision 1.41 1999/01/20 10:20:18 peter
  1096. * don't make localvar copies for assembler procedures
  1097. Revision 1.40 1998/12/30 13:41:07 peter
  1098. * released valuepara
  1099. Revision 1.39 1998/12/19 00:23:45 florian
  1100. * ansistring memory leaks fixed
  1101. Revision 1.38 1998/12/11 00:02:51 peter
  1102. + globtype,tokens,version unit splitted from globals
  1103. Revision 1.37 1998/12/10 09:47:17 florian
  1104. + basic operations with int64/qord (compiler with -dint64)
  1105. + rtti of enumerations extended: names are now written
  1106. Revision 1.36 1998/12/04 10:18:06 florian
  1107. * some stuff for procedures of object added
  1108. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  1109. Revision 1.35 1998/11/30 09:43:04 pierre
  1110. * some range check bugs fixed (still not working !)
  1111. + added DLL writing support for win32 (also accepts variables)
  1112. + TempAnsi for code that could be used for Temporary ansi strings
  1113. handling
  1114. Revision 1.34 1998/11/28 16:20:48 peter
  1115. + support for dll variables
  1116. Revision 1.33 1998/11/27 14:50:33 peter
  1117. + open strings, $P switch support
  1118. Revision 1.32 1998/11/26 09:53:36 florian
  1119. * for classes no init/final. code is necessary, fixed
  1120. Revision 1.31 1998/11/20 15:35:54 florian
  1121. * problems with rtti fixed, hope it works
  1122. Revision 1.30 1998/11/18 17:45:24 peter
  1123. * fixes for VALUEPARA
  1124. Revision 1.29 1998/11/18 15:44:11 peter
  1125. * VALUEPARA for tp7 compatible value parameters
  1126. Revision 1.28 1998/11/17 11:32:44 peter
  1127. * optimize str:='' in H+ mode
  1128. + -! to test ansistrings
  1129. Revision 1.27 1998/11/16 15:35:39 peter
  1130. * rename laod/copystring -> load/copyshortstring
  1131. * fixed int-bool cnv bug
  1132. + char-ansistring conversion
  1133. Revision 1.26 1998/11/10 10:09:10 peter
  1134. * va_list -> array of const
  1135. Revision 1.25 1998/11/05 12:02:35 peter
  1136. * released useansistring
  1137. * removed -Sv, its now available in fpc modes
  1138. Revision 1.24 1998/10/14 08:47:14 pierre
  1139. * bugs in secondfuncret for result in subprocedures removed
  1140. Revision 1.23 1998/10/06 17:16:44 pierre
  1141. * some memory leaks fixed (thanks to Peter for heaptrc !)
  1142. Revision 1.22 1998/10/01 09:22:53 peter
  1143. * fixed value openarray
  1144. * ungettemp of arrayconstruct
  1145. Revision 1.21 1998/09/28 11:07:39 peter
  1146. + floatdef support for array of const
  1147. Revision 1.20 1998/09/24 14:26:03 peter
  1148. * updated for new tvarrec
  1149. Revision 1.19 1998/09/23 17:49:59 peter
  1150. * high(arrayconstructor) is now correct
  1151. * procvardef support for variant record
  1152. Revision 1.18 1998/09/23 09:58:48 peter
  1153. * first working array of const things
  1154. Revision 1.17 1998/09/20 18:00:19 florian
  1155. * small compiling problems fixed
  1156. Revision 1.16 1998/09/20 17:46:48 florian
  1157. * some things regarding ansistrings fixed
  1158. Revision 1.15 1998/09/17 09:42:16 peter
  1159. + pass_2 for cg386
  1160. * Message() -> CGMessage() for pass_1/pass_2
  1161. Revision 1.14 1998/09/14 10:43:50 peter
  1162. * all internal RTL functions start with FPC_
  1163. Revision 1.13 1998/09/04 12:24:24 florian
  1164. * bug0159 fixed
  1165. Revision 1.12 1998/09/04 11:55:17 florian
  1166. * problem with -Or fixed
  1167. Revision 1.11 1998/09/03 16:03:14 florian
  1168. + rtti generation
  1169. * init table generation changed
  1170. Revision 1.10 1998/08/21 14:08:40 pierre
  1171. + TEST_FUNCRET now default (old code removed)
  1172. works also for m68k (at least compiles)
  1173. Revision 1.9 1998/08/20 09:26:37 pierre
  1174. + funcret setting in underproc testing
  1175. compile with _dTEST_FUNCRET
  1176. Revision 1.8 1998/08/10 14:49:48 peter
  1177. + localswitches, moduleswitches, globalswitches splitting
  1178. Revision 1.7 1998/07/30 13:30:33 florian
  1179. * final implemenation of exception support, maybe it needs
  1180. some fixes :)
  1181. Revision 1.6 1998/07/26 21:58:57 florian
  1182. + better support for switch $H
  1183. + index access to ansi strings added
  1184. + assigment of data (records/arrays) containing ansi strings
  1185. Revision 1.5 1998/07/24 22:16:54 florian
  1186. * internal error 10 together with array access fixed. I hope
  1187. that's the final fix.
  1188. Revision 1.4 1998/06/11 13:58:45 peter
  1189. * fixed too long line
  1190. Revision 1.3 1998/06/09 16:01:35 pierre
  1191. + added procedure directive parsing for procvars
  1192. (accepted are popstack cdecl and pascal)
  1193. + added C vars with the following syntax
  1194. var C calias 'true_c_name';(can be followed by external)
  1195. reason is that you must add the Cprefix
  1196. which is target dependent
  1197. Revision 1.2 1998/06/08 13:13:34 pierre
  1198. + temporary variables now in temp_gen.pas unit
  1199. because it is processor independent
  1200. * mppc68k.bat modified to undefine i386 and support_mmx
  1201. (which are defaults for i386)
  1202. Revision 1.1 1998/06/05 17:44:12 peter
  1203. * splitted cgi386
  1204. }