cg386ld.pas 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336
  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. loc:=p^.left^.location.loc;
  401. { lets try to optimize this (PM) }
  402. { define a dest_loc that is the location }
  403. { and a ptree to verify that it is the right }
  404. { place to insert it }
  405. {$ifdef test_dest_loc}
  406. if (aktexprlevel<4) then
  407. begin
  408. dest_loc_known:=true;
  409. dest_loc:=p^.left^.location;
  410. dest_loc_tree:=p^.right;
  411. end;
  412. {$endif test_dest_loc}
  413. { left can't be never a 64 bit LOC_REGISTER, so the 3. arg }
  414. { can be false }
  415. pushed:=maybe_push(p^.right^.registers32,p^.left,false);
  416. secondpass(p^.right);
  417. if pushed then restore(p^.left,false);
  418. if codegenerror then
  419. exit;
  420. {$ifdef test_dest_loc}
  421. dest_loc_known:=false;
  422. if in_dest_loc then
  423. begin
  424. truelabel:=otlabel;
  425. falselabel:=oflabel;
  426. in_dest_loc:=false;
  427. exit;
  428. end;
  429. {$endif test_dest_loc}
  430. if p^.left^.resulttype^.deftype=stringdef then
  431. begin
  432. if is_ansistring(p^.left^.resulttype) then
  433. begin
  434. { the source and destinations are released
  435. in loadansistring, because an ansi string can
  436. also be in a register
  437. }
  438. loadansistring(p);
  439. end
  440. else
  441. if is_shortstring(p^.left^.resulttype) and
  442. not (p^.concat_string) then
  443. begin
  444. if is_ansistring(p^.right^.resulttype) then
  445. begin
  446. if (p^.right^.treetype=stringconstn) and
  447. (p^.right^.length=0) then
  448. begin
  449. emit_const_ref(A_MOV,S_B,
  450. 0,newreference(p^.left^.location.reference));
  451. {$IfDef regallocfix}
  452. del_reference(p^.left^.location.reference);
  453. {$EndIf regallocfix}
  454. end
  455. else
  456. loadansi2short(p^.right,p^.left);
  457. end
  458. else
  459. begin
  460. { we do not need destination anymore }
  461. del_reference(p^.left^.location.reference);
  462. {del_reference(p^.right^.location.reference);
  463. done in loadshortstring }
  464. loadshortstring(p);
  465. ungetiftemp(p^.right^.location.reference);
  466. end;
  467. end
  468. else if is_longstring(p^.left^.resulttype) then
  469. begin
  470. end
  471. else
  472. begin
  473. { its the only thing we have to do }
  474. del_reference(p^.right^.location.reference);
  475. end
  476. end
  477. else case p^.right^.location.loc of
  478. LOC_REFERENCE,
  479. LOC_MEM : begin
  480. { extra handling for ordinal constants }
  481. if (p^.right^.treetype in [ordconstn,fixconstn]) or
  482. (loc=LOC_CREGISTER) then
  483. begin
  484. case p^.left^.resulttype^.size of
  485. 1 : opsize:=S_B;
  486. 2 : opsize:=S_W;
  487. 4 : opsize:=S_L;
  488. { S_L is correct, the copy is done }
  489. { with two moves }
  490. 8 : opsize:=S_L;
  491. end;
  492. if loc=LOC_CREGISTER then
  493. begin
  494. emit_ref_reg(A_MOV,opsize,
  495. newreference(p^.right^.location.reference),
  496. p^.left^.location.register);
  497. if is_64bitint(p^.right^.resulttype) then
  498. begin
  499. r:=newreference(p^.right^.location.reference);
  500. inc(r^.offset,4);
  501. emit_ref_reg(A_MOV,opsize,r,
  502. p^.left^.location.registerhigh);
  503. end;
  504. {$IfDef regallocfix}
  505. del_reference(p^.right^.location.reference);
  506. {$EndIf regallocfix}
  507. end
  508. else
  509. begin
  510. emit_const_ref(A_MOV,opsize,
  511. p^.right^.location.reference.offset,
  512. newreference(p^.left^.location.reference));
  513. if is_64bitint(p^.right^.resulttype) then
  514. begin
  515. r:=newreference(p^.left^.location.reference);
  516. inc(r^.offset,4);
  517. emit_const_ref(A_MOV,opsize,
  518. 0,r);
  519. end;
  520. {$IfDef regallocfix}
  521. del_reference(p^.left^.location.reference);
  522. {$EndIf regallocfix}
  523. {emit_const_loc(A_MOV,opsize,
  524. p^.right^.location.reference.offset,
  525. p^.left^.location);}
  526. end;
  527. end
  528. else if loc=LOC_CFPUREGISTER then
  529. begin
  530. floatloadops(pfloatdef(p^.right^.resulttype)^.typ,op,opsize);
  531. emit_ref(op,opsize,
  532. newreference(p^.right^.location.reference));
  533. emit_reg(A_FSTP,S_NO,
  534. correct_fpuregister(p^.left^.location.register,fpuvaroffset+1));
  535. end
  536. else
  537. begin
  538. if (p^.right^.resulttype^.needs_inittable) and
  539. ( (p^.right^.resulttype^.deftype<>objectdef) or
  540. not(pobjectdef(p^.right^.resulttype)^.is_class)) then
  541. begin
  542. { this would be a problem }
  543. if not(p^.left^.resulttype^.needs_inittable) then
  544. internalerror(3457);
  545. { increment source reference counter }
  546. new(r);
  547. reset_reference(r^);
  548. r^.symbol:=p^.right^.resulttype^.get_inittable_label;
  549. emitpushreferenceaddr(r^);
  550. emitpushreferenceaddr(p^.right^.location.reference);
  551. emitcall('FPC_ADDREF');
  552. { decrement destination reference counter }
  553. new(r);
  554. reset_reference(r^);
  555. r^.symbol:=p^.left^.resulttype^.get_inittable_label;
  556. emitpushreferenceaddr(r^);
  557. emitpushreferenceaddr(p^.left^.location.reference);
  558. emitcall('FPC_DECREF');
  559. end;
  560. {$ifdef regallocfix}
  561. concatcopy(p^.right^.location.reference,
  562. p^.left^.location.reference,p^.left^.resulttype^.size,true,false);
  563. ungetiftemp(p^.right^.location.reference);
  564. {$Else regallocfix}
  565. concatcopy(p^.right^.location.reference,
  566. p^.left^.location.reference,p^.left^.resulttype^.size,false,false);
  567. ungetiftemp(p^.right^.location.reference);
  568. {$endif regallocfix}
  569. end;
  570. end;
  571. {$ifdef SUPPORT_MMX}
  572. LOC_CMMXREGISTER,
  573. LOC_MMXREGISTER:
  574. begin
  575. if loc=LOC_CMMXREGISTER then
  576. emit_reg_reg(A_MOVQ,S_NO,
  577. p^.right^.location.register,p^.left^.location.register)
  578. else
  579. emit_reg_ref(A_MOVQ,S_NO,
  580. p^.right^.location.register,newreference(p^.left^.location.reference));
  581. end;
  582. {$endif SUPPORT_MMX}
  583. LOC_REGISTER,
  584. LOC_CREGISTER : begin
  585. case p^.right^.resulttype^.size of
  586. 1 : opsize:=S_B;
  587. 2 : opsize:=S_W;
  588. 4 : opsize:=S_L;
  589. 8 : opsize:=S_L;
  590. end;
  591. { simplified with op_reg_loc }
  592. if loc=LOC_CREGISTER then
  593. begin
  594. emit_reg_reg(A_MOV,opsize,
  595. p^.right^.location.register,
  596. p^.left^.location.register);
  597. {$IfDef regallocfix}
  598. ungetregister(p^.right^.location.register);
  599. {$EndIf regallocfix}
  600. end
  601. else
  602. Begin
  603. emit_reg_ref(A_MOV,opsize,
  604. p^.right^.location.register,
  605. newreference(p^.left^.location.reference));
  606. {$IfDef regallocfix}
  607. ungetregister(p^.right^.location.register);
  608. del_reference(p^.left^.location.reference);
  609. {$EndIf regallocfix}
  610. end;
  611. if is_64bitint(p^.right^.resulttype) then
  612. begin
  613. { simplified with op_reg_loc }
  614. if loc=LOC_CREGISTER then
  615. emit_reg_reg(A_MOV,opsize,
  616. p^.right^.location.registerhigh,
  617. p^.left^.location.registerhigh)
  618. else
  619. begin
  620. r:=newreference(p^.left^.location.reference);
  621. inc(r^.offset,4);
  622. emit_reg_ref(A_MOV,opsize,
  623. p^.right^.location.registerhigh,r);
  624. end;
  625. end;
  626. {emit_reg_loc(A_MOV,opsize,
  627. p^.right^.location.register,
  628. p^.left^.location); }
  629. end;
  630. LOC_FPU : begin
  631. if (p^.left^.resulttype^.deftype=floatdef) then
  632. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  633. else
  634. if (p^.right^.resulttype^.deftype=floatdef) then
  635. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  636. else
  637. if (p^.right^.treetype=typeconvn) and
  638. (p^.right^.left^.resulttype^.deftype=floatdef) then
  639. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  640. else
  641. fputyp:=s32real;
  642. case loc of
  643. LOC_CFPUREGISTER:
  644. begin
  645. emit_reg(A_FSTP,S_NO,
  646. correct_fpuregister(p^.left^.location.register,fpuvaroffset));
  647. dec(fpuvaroffset);
  648. end;
  649. LOC_REFERENCE:
  650. floatstore(fputyp,p^.left^.location.reference);
  651. else
  652. internalerror(48991);
  653. end;
  654. end;
  655. LOC_CFPUREGISTER: begin
  656. if (p^.left^.resulttype^.deftype=floatdef) then
  657. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  658. else
  659. if (p^.right^.resulttype^.deftype=floatdef) then
  660. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  661. else
  662. if (p^.right^.treetype=typeconvn) and
  663. (p^.right^.left^.resulttype^.deftype=floatdef) then
  664. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  665. else
  666. fputyp:=s32real;
  667. emit_reg(A_FLD,S_NO,
  668. correct_fpuregister(p^.right^.location.register,fpuvaroffset));
  669. inc(fpuvaroffset);
  670. case loc of
  671. LOC_CFPUREGISTER:
  672. begin
  673. emit_reg(A_FSTP,S_NO,
  674. correct_fpuregister(p^.right^.location.register,fpuvaroffset));
  675. dec(fpuvaroffset);
  676. end;
  677. LOC_REFERENCE:
  678. floatstore(fputyp,p^.left^.location.reference);
  679. else
  680. internalerror(48992);
  681. end;
  682. end;
  683. LOC_JUMP : begin
  684. getlabel(hlabel);
  685. emitlab(truelabel);
  686. if loc=LOC_CREGISTER then
  687. emit_const_reg(A_MOV,S_B,
  688. 1,p^.left^.location.register)
  689. else
  690. emit_const_ref(A_MOV,S_B,
  691. 1,newreference(p^.left^.location.reference));
  692. {emit_const_loc(A_MOV,S_B,
  693. 1,p^.left^.location);}
  694. emitjmp(C_None,hlabel);
  695. emitlab(falselabel);
  696. if loc=LOC_CREGISTER then
  697. emit_reg_reg(A_XOR,S_B,
  698. p^.left^.location.register,
  699. p^.left^.location.register)
  700. else
  701. begin
  702. emit_const_ref(A_MOV,S_B,
  703. 0,newreference(p^.left^.location.reference));
  704. {$IfDef regallocfix}
  705. del_reference(p^.left^.location.reference);
  706. {$EndIf regallocfix}
  707. end;
  708. emitlab(hlabel);
  709. end;
  710. LOC_FLAGS : begin
  711. if loc=LOC_CREGISTER then
  712. emit_flag2reg(p^.right^.location.resflags,p^.left^.location.register)
  713. else
  714. begin
  715. ai:=new(paicpu,op_ref(A_Setcc,S_B,newreference(p^.left^.location.reference)));
  716. ai^.SetCondition(flag_2_cond[p^.right^.location.resflags]);
  717. exprasmlist^.concat(ai);
  718. end;
  719. {$IfDef regallocfix}
  720. del_reference(p^.left^.location.reference);
  721. {$EndIf regallocfix}
  722. end;
  723. end;
  724. freelabel(truelabel);
  725. freelabel(falselabel);
  726. truelabel:=otlabel;
  727. falselabel:=oflabel;
  728. end;
  729. {*****************************************************************************
  730. SecondFuncRet
  731. *****************************************************************************}
  732. procedure secondfuncret(var p : ptree);
  733. var
  734. hr : tregister;
  735. hp : preference;
  736. pp : pprocinfo;
  737. hr_valid : boolean;
  738. begin
  739. reset_reference(p^.location.reference);
  740. hr_valid:=false;
  741. if procinfo<>pprocinfo(p^.funcretprocinfo) then
  742. begin
  743. hr:=getregister32;
  744. hr_valid:=true;
  745. hp:=new_reference(procinfo^.framepointer,
  746. procinfo^.framepointer_offset);
  747. emit_ref_reg(A_MOV,S_L,hp,hr);
  748. pp:=procinfo^.parent;
  749. { walk up the stack frame }
  750. while pp<>pprocinfo(p^.funcretprocinfo) do
  751. begin
  752. hp:=new_reference(hr,
  753. pp^.framepointer_offset);
  754. emit_ref_reg(A_MOV,S_L,hp,hr);
  755. pp:=pp^.parent;
  756. end;
  757. p^.location.reference.base:=hr;
  758. p^.location.reference.offset:=pp^.retoffset;
  759. end
  760. else
  761. begin
  762. p^.location.reference.base:=procinfo^.framepointer;
  763. p^.location.reference.offset:=procinfo^.retoffset;
  764. end;
  765. if ret_in_param(p^.retdef) then
  766. begin
  767. if not hr_valid then
  768. hr:=getregister32;
  769. emit_ref_reg(A_MOV,S_L,newreference(p^.location.reference),hr);
  770. p^.location.reference.base:=hr;
  771. p^.location.reference.offset:=0;
  772. end;
  773. end;
  774. {*****************************************************************************
  775. SecondArrayConstruct
  776. *****************************************************************************}
  777. const
  778. vtInteger = 0;
  779. vtBoolean = 1;
  780. vtChar = 2;
  781. vtExtended = 3;
  782. vtString = 4;
  783. vtPointer = 5;
  784. vtPChar = 6;
  785. vtObject = 7;
  786. vtClass = 8;
  787. vtWideChar = 9;
  788. vtPWideChar = 10;
  789. vtAnsiString = 11;
  790. vtCurrency = 12;
  791. vtVariant = 13;
  792. vtInterface = 14;
  793. vtWideString = 15;
  794. vtInt64 = 16;
  795. procedure secondarrayconstruct(var p : ptree);
  796. var
  797. hp : ptree;
  798. href : treference;
  799. lt : pdef;
  800. vaddr : boolean;
  801. vtype : longint;
  802. freetemp,
  803. dovariant : boolean;
  804. elesize : longint;
  805. begin
  806. dovariant:=p^.forcevaria or parraydef(p^.resulttype)^.isvariant;
  807. if dovariant then
  808. elesize:=8
  809. else
  810. begin
  811. elesize:=parraydef(p^.resulttype)^.elesize;
  812. if elesize>4 then
  813. internalerror(8765678);
  814. end;
  815. if not p^.cargs then
  816. begin
  817. reset_reference(p^.location.reference);
  818. { Allocate always a temp, also if no elements are required, to
  819. be sure that location is valid (PFV) }
  820. if parraydef(p^.resulttype)^.highrange=-1 then
  821. gettempofsizereference(elesize,p^.location.reference)
  822. else
  823. gettempofsizereference((parraydef(p^.resulttype)^.highrange+1)*elesize,p^.location.reference);
  824. href:=p^.location.reference;
  825. end;
  826. hp:=p;
  827. while assigned(hp) do
  828. begin
  829. if assigned(hp^.left) then
  830. begin
  831. freetemp:=true;
  832. secondpass(hp^.left);
  833. if codegenerror then
  834. exit;
  835. if dovariant then
  836. begin
  837. { find the correct vtype value }
  838. vtype:=$ff;
  839. vaddr:=false;
  840. lt:=hp^.left^.resulttype;
  841. case lt^.deftype of
  842. enumdef,
  843. orddef :
  844. begin
  845. if (lt^.deftype=enumdef) or
  846. is_integer(lt) then
  847. vtype:=vtInteger
  848. else
  849. if is_boolean(lt) then
  850. vtype:=vtBoolean
  851. else
  852. if (lt^.deftype=orddef) and (porddef(lt)^.typ=uchar) then
  853. vtype:=vtChar;
  854. end;
  855. floatdef :
  856. begin
  857. vtype:=vtExtended;
  858. vaddr:=true;
  859. end;
  860. procvardef,
  861. pointerdef :
  862. begin
  863. if is_pchar(lt) then
  864. vtype:=vtPChar
  865. else
  866. vtype:=vtPointer;
  867. end;
  868. classrefdef :
  869. vtype:=vtClass;
  870. objectdef :
  871. begin
  872. vtype:=vtObject;
  873. end;
  874. stringdef :
  875. begin
  876. if is_shortstring(lt) then
  877. begin
  878. vtype:=vtString;
  879. vaddr:=true;
  880. freetemp:=false;
  881. end
  882. else
  883. if is_ansistring(lt) then
  884. vtype:=vtAnsiString;
  885. end;
  886. end;
  887. if vtype=$ff then
  888. internalerror(14357);
  889. { write C style pushes or an pascal array }
  890. if p^.cargs then
  891. begin
  892. if vaddr then
  893. begin
  894. emit_to_mem(hp^.left);
  895. emit_push_lea_loc(hp^.left^.location,freetemp);
  896. del_reference(hp^.left^.location.reference);
  897. end
  898. else
  899. emit_push_loc(hp^.left^.location);
  900. end
  901. else
  902. begin
  903. { update href to the vtype field and write it }
  904. emit_const_ref(A_MOV,S_L,
  905. vtype,newreference(href));
  906. inc(href.offset,4);
  907. { write changing field update href to the next element }
  908. if vaddr then
  909. begin
  910. emit_to_mem(hp^.left);
  911. emit_lea_loc_ref(hp^.left^.location,href,freetemp);
  912. end
  913. else
  914. emit_mov_loc_ref(hp^.left^.location,href,S_L);
  915. inc(href.offset,4);
  916. end;
  917. end
  918. else
  919. { normal array constructor of the same type }
  920. begin
  921. case elesize of
  922. 1 :
  923. emit_mov_loc_ref(hp^.left^.location,href,S_B);
  924. 2 :
  925. emit_mov_loc_ref(hp^.left^.location,href,S_W);
  926. 4 :
  927. emit_mov_loc_ref(hp^.left^.location,href,S_L);
  928. else
  929. internalerror(87656781);
  930. end;
  931. inc(href.offset,elesize);
  932. end;
  933. end;
  934. { load next entry }
  935. hp:=hp^.right;
  936. end;
  937. end;
  938. end.
  939. {
  940. $Log$
  941. Revision 1.88 1999-09-27 23:44:47 peter
  942. * procinfo is now a pointer
  943. * support for result setting in sub procedure
  944. Revision 1.87 1999/09/26 13:26:06 florian
  945. * exception patch of Romio nevertheless the excpetion handling
  946. needs some corections regarding register saving
  947. * gettempansistring is again a procedure
  948. Revision 1.86 1999/09/16 07:56:46 pierre
  949. * double del_reference removed
  950. Revision 1.85 1999/09/12 08:48:03 florian
  951. * bugs 593 and 607 fixed
  952. * some other potential bugs with array constructors fixed
  953. * for classes compiled in $M+ and it's childs, the default access method
  954. is now published
  955. * fixed copyright message (it is now 1993-99)
  956. Revision 1.84 1999/09/11 09:08:31 florian
  957. * fixed bug 596
  958. * fixed some problems with procedure variables and procedures of object,
  959. especially in TP mode. Procedure of object doesn't apply only to classes,
  960. it is also allowed for objects !!
  961. Revision 1.83 1999/09/01 09:37:14 peter
  962. * removed warning
  963. Revision 1.82 1999/09/01 09:26:21 peter
  964. * fixed temp allocation for arrayconstructor
  965. Revision 1.81 1999/08/28 15:34:17 florian
  966. * bug 519 fixed
  967. Revision 1.80 1999/08/26 20:24:37 michael
  968. + Hopefuly last fixes for resourcestrings
  969. Revision 1.79 1999/08/25 16:41:05 peter
  970. * resources are working again
  971. Revision 1.78 1999/08/25 11:59:43 jonas
  972. * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
  973. Revision 1.77 1999/08/24 22:38:51 michael
  974. * more resourcestring changes
  975. Revision 1.76 1999/08/23 11:45:39 michael
  976. * Hopefully final attempt at resourcestrings
  977. Revision 1.75 1999/08/19 13:08:49 pierre
  978. * emit_??? used
  979. Revision 1.74 1999/08/17 13:26:06 peter
  980. * arrayconstructor -> arrayofconst fixed when arraycosntructor was not
  981. variant.
  982. Revision 1.73 1999/08/13 21:33:09 peter
  983. * support for array constructors extended and more error checking
  984. Revision 1.72 1999/08/09 22:19:50 peter
  985. * classes vmt changed to only positive addresses
  986. * sharedlib creation is working
  987. Revision 1.71 1999/08/07 14:20:55 florian
  988. * some small problems fixed
  989. Revision 1.70 1999/08/04 13:45:22 florian
  990. + floating point register variables !!
  991. * pairegalloc is now generated for register variables
  992. Revision 1.69 1999/08/04 00:22:50 florian
  993. * renamed i386asm and i386base to cpuasm and cpubase
  994. Revision 1.68 1999/08/03 22:02:43 peter
  995. * moved bitmask constants to sets
  996. * some other type/const renamings
  997. Revision 1.67 1999/07/27 23:36:36 peter
  998. * try to determine the fpu type needed in assignment
  999. Revision 1.66 1999/07/24 15:12:56 michael
  1000. changes for resourcestrings
  1001. Revision 1.65 1999/07/23 23:09:06 peter
  1002. * resourcestring fix
  1003. Revision 1.64 1999/07/22 09:37:37 florian
  1004. + resourcestring implemented
  1005. + start of longstring support
  1006. Revision 1.63 1999/07/05 20:13:12 peter
  1007. * removed temp defines
  1008. Revision 1.62 1999/06/30 15:43:18 florian
  1009. * two bugs regarding method variables fixed
  1010. - if you take in a method the address of another method
  1011. don't need self anymore
  1012. - if the class pointer was in a register, wrong code for a method
  1013. variable load was generated
  1014. Revision 1.61 1999/06/28 22:29:11 florian
  1015. * qword division fixed
  1016. + code for qword/int64 type casting added:
  1017. range checking isn't implemented yet
  1018. Revision 1.60 1999/05/31 12:42:43 peter
  1019. * fixed crash with empty array constructor
  1020. Revision 1.59 1999/05/27 19:44:14 peter
  1021. * removed oldasm
  1022. * plabel -> pasmlabel
  1023. * -a switches to source writing automaticly
  1024. * assembler readers OOPed
  1025. * asmsymbol automaticly external
  1026. * jumptables and other label fixes for asm readers
  1027. Revision 1.58 1999/05/23 18:42:02 florian
  1028. * better error recovering in typed constants
  1029. * some problems with arrays of const fixed, some problems
  1030. due my previous
  1031. - the location type of array constructor is now LOC_MEM
  1032. - the pushing of high fixed
  1033. - parameter copying fixed
  1034. - zero temp. allocation removed
  1035. * small problem in the assembler writers fixed:
  1036. ref to nil wasn't written correctly
  1037. Revision 1.57 1999/05/21 13:54:51 peter
  1038. * NEWLAB for label as symbol
  1039. Revision 1.56 1999/05/17 23:51:38 peter
  1040. * with temp vars now use a reference with a persistant temp instead
  1041. of setting datasize
  1042. Revision 1.55 1999/05/17 21:57:04 florian
  1043. * new temporary ansistring handling
  1044. Revision 1.54 1999/05/12 00:19:43 peter
  1045. * removed R_DEFAULT_SEG
  1046. * uniform float names
  1047. Revision 1.53 1999/05/06 09:05:16 peter
  1048. * generic write_float and str_float
  1049. * fixed constant float conversions
  1050. Revision 1.52 1999/05/01 13:24:10 peter
  1051. * merged nasm compiler
  1052. * old asm moved to oldasm/
  1053. Revision 1.51 1999/04/28 06:01:55 florian
  1054. * changes of Bruessel:
  1055. + message handler can now take an explicit self
  1056. * typinfo fixed: sometimes the type names weren't written
  1057. * the type checking for pointer comparisations and subtraction
  1058. and are now more strict (was also buggy)
  1059. * small bug fix to link.pas to support compiling on another
  1060. drive
  1061. * probable bug in popt386 fixed: call/jmp => push/jmp
  1062. transformation didn't count correctly the jmp references
  1063. + threadvar support
  1064. * warning if ln/sqrt gets an invalid constant argument
  1065. Revision 1.50 1999/04/16 13:42:26 jonas
  1066. * more regalloc fixes (still not complete)
  1067. Revision 1.49 1999/04/13 18:57:48 florian
  1068. * classes which contain ansistring get unnecessary calls
  1069. to addref/decref when they are assigned, fixed
  1070. Revision 1.48 1999/04/09 15:48:47 jonas
  1071. * added fix for missing register deallocation (-dregallocfix)
  1072. Revision 1.47 1999/03/31 13:55:07 peter
  1073. * assembler inlining working for ag386bin
  1074. Revision 1.46 1999/03/24 23:16:52 peter
  1075. * fixed bugs 212,222,225,227,229,231,233
  1076. Revision 1.45 1999/02/25 21:02:28 peter
  1077. * ag386bin updates
  1078. + coff writer
  1079. Revision 1.44 1999/02/22 02:15:12 peter
  1080. * updates for ag386bin
  1081. Revision 1.43 1999/01/27 00:13:54 florian
  1082. * "procedure of object"-stuff fixed
  1083. Revision 1.42 1999/01/21 22:10:40 peter
  1084. * fixed array of const
  1085. * generic platform independent high() support
  1086. Revision 1.41 1999/01/20 10:20:18 peter
  1087. * don't make localvar copies for assembler procedures
  1088. Revision 1.40 1998/12/30 13:41:07 peter
  1089. * released valuepara
  1090. Revision 1.39 1998/12/19 00:23:45 florian
  1091. * ansistring memory leaks fixed
  1092. Revision 1.38 1998/12/11 00:02:51 peter
  1093. + globtype,tokens,version unit splitted from globals
  1094. Revision 1.37 1998/12/10 09:47:17 florian
  1095. + basic operations with int64/qord (compiler with -dint64)
  1096. + rtti of enumerations extended: names are now written
  1097. Revision 1.36 1998/12/04 10:18:06 florian
  1098. * some stuff for procedures of object added
  1099. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  1100. Revision 1.35 1998/11/30 09:43:04 pierre
  1101. * some range check bugs fixed (still not working !)
  1102. + added DLL writing support for win32 (also accepts variables)
  1103. + TempAnsi for code that could be used for Temporary ansi strings
  1104. handling
  1105. Revision 1.34 1998/11/28 16:20:48 peter
  1106. + support for dll variables
  1107. Revision 1.33 1998/11/27 14:50:33 peter
  1108. + open strings, $P switch support
  1109. Revision 1.32 1998/11/26 09:53:36 florian
  1110. * for classes no init/final. code is necessary, fixed
  1111. Revision 1.31 1998/11/20 15:35:54 florian
  1112. * problems with rtti fixed, hope it works
  1113. Revision 1.30 1998/11/18 17:45:24 peter
  1114. * fixes for VALUEPARA
  1115. Revision 1.29 1998/11/18 15:44:11 peter
  1116. * VALUEPARA for tp7 compatible value parameters
  1117. Revision 1.28 1998/11/17 11:32:44 peter
  1118. * optimize str:='' in H+ mode
  1119. + -! to test ansistrings
  1120. Revision 1.27 1998/11/16 15:35:39 peter
  1121. * rename laod/copystring -> load/copyshortstring
  1122. * fixed int-bool cnv bug
  1123. + char-ansistring conversion
  1124. Revision 1.26 1998/11/10 10:09:10 peter
  1125. * va_list -> array of const
  1126. Revision 1.25 1998/11/05 12:02:35 peter
  1127. * released useansistring
  1128. * removed -Sv, its now available in fpc modes
  1129. Revision 1.24 1998/10/14 08:47:14 pierre
  1130. * bugs in secondfuncret for result in subprocedures removed
  1131. Revision 1.23 1998/10/06 17:16:44 pierre
  1132. * some memory leaks fixed (thanks to Peter for heaptrc !)
  1133. Revision 1.22 1998/10/01 09:22:53 peter
  1134. * fixed value openarray
  1135. * ungettemp of arrayconstruct
  1136. Revision 1.21 1998/09/28 11:07:39 peter
  1137. + floatdef support for array of const
  1138. Revision 1.20 1998/09/24 14:26:03 peter
  1139. * updated for new tvarrec
  1140. Revision 1.19 1998/09/23 17:49:59 peter
  1141. * high(arrayconstructor) is now correct
  1142. * procvardef support for variant record
  1143. Revision 1.18 1998/09/23 09:58:48 peter
  1144. * first working array of const things
  1145. Revision 1.17 1998/09/20 18:00:19 florian
  1146. * small compiling problems fixed
  1147. Revision 1.16 1998/09/20 17:46:48 florian
  1148. * some things regarding ansistrings fixed
  1149. Revision 1.15 1998/09/17 09:42:16 peter
  1150. + pass_2 for cg386
  1151. * Message() -> CGMessage() for pass_1/pass_2
  1152. Revision 1.14 1998/09/14 10:43:50 peter
  1153. * all internal RTL functions start with FPC_
  1154. Revision 1.13 1998/09/04 12:24:24 florian
  1155. * bug0159 fixed
  1156. Revision 1.12 1998/09/04 11:55:17 florian
  1157. * problem with -Or fixed
  1158. Revision 1.11 1998/09/03 16:03:14 florian
  1159. + rtti generation
  1160. * init table generation changed
  1161. Revision 1.10 1998/08/21 14:08:40 pierre
  1162. + TEST_FUNCRET now default (old code removed)
  1163. works also for m68k (at least compiles)
  1164. Revision 1.9 1998/08/20 09:26:37 pierre
  1165. + funcret setting in underproc testing
  1166. compile with _dTEST_FUNCRET
  1167. Revision 1.8 1998/08/10 14:49:48 peter
  1168. + localswitches, moduleswitches, globalswitches splitting
  1169. Revision 1.7 1998/07/30 13:30:33 florian
  1170. * final implemenation of exception support, maybe it needs
  1171. some fixes :)
  1172. Revision 1.6 1998/07/26 21:58:57 florian
  1173. + better support for switch $H
  1174. + index access to ansi strings added
  1175. + assigment of data (records/arrays) containing ansi strings
  1176. Revision 1.5 1998/07/24 22:16:54 florian
  1177. * internal error 10 together with array access fixed. I hope
  1178. that's the final fix.
  1179. Revision 1.4 1998/06/11 13:58:45 peter
  1180. * fixed too long line
  1181. Revision 1.3 1998/06/09 16:01:35 pierre
  1182. + added procedure directive parsing for procvars
  1183. (accepted are popstack cdecl and pascal)
  1184. + added C vars with the following syntax
  1185. var C calias 'true_c_name';(can be followed by external)
  1186. reason is that you must add the Cprefix
  1187. which is target dependent
  1188. Revision 1.2 1998/06/08 13:13:34 pierre
  1189. + temporary variables now in temp_gen.pas unit
  1190. because it is processor independent
  1191. * mppc68k.bat modified to undefine i386 and support_mmx
  1192. (which are defaults for i386)
  1193. Revision 1.1 1998/06/05 17:44:12 peter
  1194. * splitted cgi386
  1195. }