cg386ld.pas 54 KB

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