nmem.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. {
  2. $Id$
  3. Copyright (C) 1998-2000 by Florian Klaempfl
  4. This unit implements load nodes etc.
  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 nmem;
  19. interface
  20. uses
  21. tree,symtable;
  22. type
  23. ploadnode = ^tloadnode;
  24. tloadnode = object(tnode)
  25. symtableentry : psym;
  26. symtable : psymtable;
  27. is_absolute,is_first,is_methodpointer : boolean;
  28. constructor init(v : psym;st : psymtable);
  29. destructor done;virtual;
  30. procedure det_temp;virtual;
  31. procedure det_resulttype;virtual;
  32. procedure secondpass;virtual;
  33. end;
  34. tassigntyp = (at_normal,at_plus,at_minus,at_star,at_slash);
  35. passignmentnode = ^tassignmentnode;
  36. tassignmentnode = object(tbinarynode)
  37. assigntyp : tassigntyp;
  38. concat_string : boolean;
  39. constructor init(l,r : pnode);
  40. destructor done;virtual;
  41. procedure det_temp;virtual;
  42. procedure det_resulttype;virtual;
  43. procedure secondpass;virtual;
  44. procedure loadansistring;
  45. procedure loadshortstring;
  46. procedure loadansi2short(l,r : pnode);
  47. end;
  48. var
  49. { this is necessary for the const section }
  50. simple_loadn : boolean;
  51. implementation
  52. uses
  53. cobjects,globals,aasm,cgbase,cgobj,types,verbose,tgobj,tgcpu,symconst,
  54. cpubase,cpuasm,ncon;
  55. {****************************************************************************
  56. TLOADNODE
  57. ****************************************************************************}
  58. constructor tloadnode.init(v : psym;st : psymtable);
  59. var
  60. p : ptree;
  61. begin
  62. inherited init;
  63. treetype:=loadn;
  64. if v^.typ=varsym then
  65. resulttype:=pvarsym(v)^.vartype.def;
  66. symtableentry:=v;
  67. symtable:=st;
  68. is_first := False;
  69. is_methodpointer:=false;
  70. { method pointer load nodes can use the left subtree }
  71. { !!!!! left:=nil; }
  72. end;
  73. destructor tloadnode.done;
  74. begin
  75. inherited done;
  76. { method pointer load nodes can use the left subtree }
  77. { !!!!! dispose(left,done); }
  78. end;
  79. procedure tloadnode.det_temp;
  80. begin
  81. end;
  82. procedure tloadnode.det_resulttype;
  83. begin
  84. end;
  85. procedure tloadnode.secondpass;
  86. var
  87. hregister : tregister;
  88. symtabletype : tsymtabletype;
  89. i : longint;
  90. hp : preference;
  91. begin
  92. simple_loadn:=true;
  93. reset_reference(location.reference);
  94. case symtableentry^.typ of
  95. { this is only for toasm and toaddr }
  96. absolutesym :
  97. begin
  98. if (pabsolutesym(symtableentry)^.abstyp=toaddr) then
  99. begin
  100. {$ifdef i386}
  101. { absseg is go32v2 target specific }
  102. if pabsolutesym(symtableentry)^.absseg then
  103. location.reference.segment:=R_FS;
  104. {$endif i386}
  105. location.reference.offset:=pabsolutesym(symtableentry)^.address;
  106. end
  107. else
  108. location.reference.symbol:=newasmsymbol(symtableentry^.mangledname);
  109. end;
  110. varsym :
  111. begin
  112. hregister:=R_NO;
  113. { C variable }
  114. if (vo_is_C_var in pvarsym(symtableentry)^.varoptions) then
  115. begin
  116. location.reference.symbol:=newasmsymbol(symtableentry^.mangledname);
  117. end
  118. {$ifdef dummy}
  119. { DLL variable, DLL variables are only available on the win32 target }
  120. { maybe we've to add this later for the alpha WinNT }
  121. else if vo_is_dll_var in pvarsym(symtableentry)^.varoptions then
  122. begin
  123. hregister:=tg.getregisterint;
  124. location.reference.symbol:=newasmsymbol(symtableentry^.mangledname);
  125. exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,S_L,newreference(location.reference),hregister)));
  126. location.reference.symbol:=nil;
  127. location.reference.base:=hregister;
  128. end
  129. {$endif dummy}
  130. else
  131. begin
  132. {$ifdef dummy}
  133. symtabletype:=symtable^.symtabletype;
  134. { in case it is a register variable: }
  135. if pvarsym(symtableentry)^.reg<>R_NO then
  136. begin
  137. if pvarsym(symtableentry)^.reg in fpuregs then
  138. begin
  139. location.loc:=LOC_CFPUREGISTER;
  140. tg.unusedregsfpu:=tg.unusedregsfpu-[pvarsym(symtableentry)^.reg];
  141. end
  142. else
  143. begin
  144. location.loc:=LOC_CREGISTER;
  145. tg.unusedregsint:=tg.unusedregsint-[pvarsym(symtableentry)^.reg];
  146. end;
  147. location.register:=pvarsym(symtableentry)^.reg;
  148. end
  149. else
  150. begin
  151. { first handle local and temporary variables }
  152. if (symtabletype in [parasymtable,inlinelocalsymtable,
  153. inlineparasymtable,localsymtable]) then
  154. begin
  155. location.reference.base:=procinfo.framepointer;
  156. location.reference.offset:=pvarsym(symtableentry)^.address;
  157. if (symtabletype in [localsymtable,inlinelocalsymtable]) and
  158. not(use_esp_stackframe) then
  159. location.reference.offset:=-location.reference.offset;
  160. if (lexlevel>(symtable^.symtablelevel)) then
  161. begin
  162. hregister:=tg.getregisterint;
  163. { make a reference }
  164. hp:=new_reference(procinfo^.framepointer,
  165. procinfo^.framepointer_offset);
  166. exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,S_L,hp,hregister)));
  167. simple_loadn:=false;
  168. i:=lexlevel-1;
  169. while i>(symtable^.symtablelevel) do
  170. begin
  171. { make a reference }
  172. hp:=new_reference(hregister,8);
  173. exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,S_L,hp,hregister)));
  174. dec(i);
  175. end;
  176. location.reference.base:=hregister;
  177. end;
  178. end
  179. else
  180. case symtabletype of
  181. unitsymtable,globalsymtable,
  182. staticsymtable : begin
  183. location.reference.symbol:=newasmsymbol(symtableentry^.mangledname);
  184. end;
  185. stt_exceptsymtable:
  186. begin
  187. location.reference.base:=procinfo^.framepointer;
  188. location.reference.offset:=pvarsym(symtableentry)^.address;
  189. end;
  190. objectsymtable:
  191. begin
  192. if sp_static in pvarsym(symtableentry)^.symoptions then
  193. begin
  194. location.reference.symbol:=newasmsymbol(symtableentry^.mangledname);
  195. end
  196. else
  197. begin
  198. location.reference.base:=self_pointer;
  199. location.reference.offset:=pvarsym(symtableentry)^.address;
  200. end;
  201. end;
  202. withsymtable:
  203. begin
  204. hregister:=tg.getregisterint;
  205. location.reference.base:=hregister;
  206. { make a reference }
  207. { symtable datasize field
  208. contains the offset of the temp
  209. stored }
  210. hp:=new_reference(procinfo^.framepointer,
  211. symtable^.datasize);
  212. exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,S_L,hp,hregister)));
  213. location.reference.offset:=
  214. pvarsym(symtableentry)^.address;
  215. end;
  216. end;
  217. end;
  218. { in case call by reference, then calculate: }
  219. if (pvarsym(symtableentry)^.varspez=vs_var) or
  220. is_open_array(pvarsym(symtableentry)^.definition) or
  221. is_array_of_const(pvarsym(symtableentry)^.definition) or
  222. ((pvarsym(symtableentry)^.varspez=vs_const) and
  223. push_addr_param(pvarsym(symtableentry)^.definition)) then
  224. begin
  225. simple_loadn:=false;
  226. if hregister=R_NO then
  227. hregister:=tg.getregisterint;
  228. if is_open_array(pvarsym(symtableentry)^.definition) or
  229. is_open_string(pvarsym(symtableentry)^.definition) then
  230. begin
  231. if (location.reference.base=procinfo^.framepointer) then
  232. begin
  233. highframepointer:=location.reference.base;
  234. highoffset:=location.reference.offset;
  235. end
  236. else
  237. begin
  238. highframepointer:=R_EDI;
  239. highoffset:=location.reference.offset;
  240. exprasmlist^.concat(new(paicpu,op_reg_reg(A_MOV,S_L,
  241. location.reference.base,R_EDI)));
  242. end;
  243. end;
  244. if location.loc=LOC_CREGISTER then
  245. begin
  246. exprasmlist^.concat(new(paicpu,op_reg_reg(A_MOV,S_L,
  247. location.register,hregister)));
  248. location.loc:=LOC_REFERENCE;
  249. end
  250. else
  251. begin
  252. exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,S_L,
  253. newreference(location.reference),
  254. hregister)));
  255. end;
  256. reset_reference(location.reference);
  257. location.reference.base:=hregister;
  258. end;
  259. {$endif dummy}
  260. end;
  261. end;
  262. procsym:
  263. begin
  264. {!!!!!!!!!!}
  265. end;
  266. typedconstsym :
  267. begin
  268. location.reference.symbol:=newasmsymbol(symtableentry^.mangledname);
  269. end;
  270. else internalerror(4);
  271. end;
  272. end;
  273. {****************************************************************************
  274. TASSIGNMENTNODE
  275. ****************************************************************************}
  276. constructor tassignmentnode.init(l,r : pnode);
  277. begin
  278. inherited init(l,r);
  279. concat_string:=false;
  280. assigntyp:=at_normal;
  281. end;
  282. destructor tassignmentnode.done;
  283. begin
  284. inherited done;
  285. end;
  286. procedure tassignmentnode.loadansistring;
  287. begin
  288. abstract;
  289. end;
  290. procedure tassignmentnode.loadshortstring;
  291. begin
  292. abstract;
  293. end;
  294. procedure tassignmentnode.loadansi2short(l,r : pnode);
  295. begin
  296. abstract;
  297. end;
  298. procedure tassignmentnode.det_temp;
  299. begin
  300. {$ifdef dummy}
  301. store_valid:=must_be_valid;
  302. must_be_valid:=false;
  303. { must be made unique }
  304. set_unique(p^.left);
  305. firstpass(p^.left);
  306. if codegenerror then
  307. exit;
  308. { test if we can avoid copying string to temp
  309. as in s:=s+...; (PM) }
  310. must_be_valid:=true;
  311. firstpass(p^.right);
  312. must_be_valid:=store_valid;
  313. if codegenerror then
  314. exit;
  315. { some string functions don't need conversion, so treat them separatly }
  316. if is_shortstring(p^.left^.resulttype) and (assigned(p^.right^.resulttype)) then
  317. begin
  318. if not (is_shortstring(p^.right^.resulttype) or
  319. is_ansistring(p^.right^.resulttype) or
  320. is_char(p^.right^.resulttype)) then
  321. begin
  322. p^.right:=gentypeconvnode(p^.right,p^.left^.resulttype);
  323. firstpass(p^.right);
  324. if codegenerror then
  325. exit;
  326. end;
  327. { we call STRCOPY }
  328. procinfo.flags:=procinfo.flags or pi_do_call;
  329. hp:=p^.right;
  330. end
  331. else
  332. begin
  333. p^.right:=gentypeconvnode(p^.right,p^.left^.resulttype);
  334. firstpass(p^.right);
  335. if codegenerror then
  336. exit;
  337. end;
  338. { set assigned flag for varsyms }
  339. if (p^.left^.treetype=loadn) and
  340. (p^.left^.symtableentry^.typ=varsym) and
  341. (pvarsym(p^.left^.symtableentry)^.varstate=vs_declared) then
  342. pvarsym(p^.left^.symtableentry)^.varstate:=vs_assigned;
  343. p^.registersint:=p^.left^.registersint+p^.right^.registersint;
  344. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  345. p^.registersmm:=max(p^.left^.registersmm,p^.right^.registersmm);
  346. {$endif dummy}
  347. end;
  348. procedure tassignmentnode.det_resulttype;
  349. begin
  350. inherited det_resulttype;
  351. resulttype:=voiddef;
  352. { assignements to open arrays aren't allowed }
  353. if is_open_array(left^.resulttype) then
  354. CGMessage(type_e_mismatch);
  355. end;
  356. procedure tassignmentnode.secondpass;
  357. var
  358. r : treference;
  359. opsize : tcgsize;
  360. begin
  361. if left^.resulttype^.deftype=stringdef then
  362. begin
  363. if is_ansistring(left^.resulttype) then
  364. begin
  365. { the source and destinations are released
  366. in loadansistring, because an ansi string can
  367. also be in a register
  368. }
  369. loadansistring;
  370. end
  371. else
  372. if is_shortstring(left^.resulttype) then
  373. begin
  374. if is_ansistring(right^.resulttype) then
  375. begin
  376. if (right^.treetype=stringconstn) and
  377. (pstringconstnode(right)^.length=0) then
  378. begin
  379. cg^.a_load_const_ref(list,OS_8,0,left^.location.reference);
  380. tg.del_reference(left^.location.reference);
  381. end
  382. else
  383. loadansi2short(right,left);
  384. end
  385. else
  386. begin
  387. { we do not need destination anymore }
  388. tg.del_reference(left^.location.reference);
  389. tg.del_reference(right^.location.reference);
  390. loadshortstring;
  391. tg.ungetiftemp(right^.location.reference);
  392. end;
  393. end
  394. else if is_longstring(left^.resulttype) then
  395. begin
  396. abstract;
  397. end
  398. else
  399. begin
  400. { its the only thing we have to do }
  401. tg.del_reference(right^.location.reference);
  402. end
  403. end
  404. else case right^.location.loc of
  405. LOC_REFERENCE,
  406. LOC_MEM : begin
  407. {$ifdef dummy}
  408. { extra handling for ordinal constants }
  409. if (right^.treetype in [ordconstn,fixconstn]) or
  410. (loc=LOC_CREGISTER) then
  411. begin
  412. case p^.left^.resulttype^.size of
  413. 1 : opsize:=OS_B;
  414. 2 : opsize:=OS_W;
  415. 4 : opsize:=OS_L;
  416. { S_L is correct, the copy is done }
  417. { with two moves }
  418. 8 : opsize:=OS_L;
  419. end;
  420. if loc=LOC_CREGISTER then
  421. begin
  422. exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,opsize,
  423. newreference(p^.right^.location.reference),
  424. p^.left^.location.register)));
  425. if is_64bitint(p^.right^.resulttype) then
  426. begin
  427. r:=newreference(p^.right^.location.reference);
  428. inc(r^.offset,4);
  429. exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,opsize,r,
  430. p^.left^.location.registerhigh)));
  431. end;
  432. {$IfDef regallocfix}
  433. del_reference(p^.right^.location.reference);
  434. {$EndIf regallocfix}
  435. end
  436. else
  437. begin
  438. exprasmlist^.concat(new(paicpu,op_const_ref(A_MOV,opsize,
  439. p^.right^.location.reference.offset,
  440. newreference(p^.left^.location.reference))));
  441. if is_64bitint(p^.right^.resulttype) then
  442. begin
  443. r:=newreference(p^.left^.location.reference);
  444. inc(r^.offset,4);
  445. exprasmlist^.concat(new(paicpu,op_const_ref(A_MOV,opsize,
  446. 0,r)));
  447. end;
  448. {$IfDef regallocfix}
  449. del_reference(p^.left^.location.reference);
  450. {$EndIf regallocfix}
  451. {exprasmlist^.concat(new(paicpu,op_const_loc(A_MOV,opsize,
  452. p^.right^.location.reference.offset,
  453. p^.left^.location)));}
  454. end;
  455. end
  456. else if loc=LOC_CFPUREGISTER then
  457. begin
  458. floatloadops(pfloatdef(p^.right^.resulttype)^.typ,op,opsize);
  459. exprasmlist^.concat(new(paicpu,op_ref(op,opsize,
  460. newreference(p^.right^.location.reference))));
  461. exprasmlist^.concat(new(paicpu,op_reg(A_FSTP,S_NO,
  462. correct_fpuregister(p^.left^.location.register,fpuvaroffset+1))));
  463. end
  464. else
  465. {$endif dummy}
  466. begin
  467. if (right^.resulttype^.needs_inittable) and
  468. ( (right^.resulttype^.deftype<>objectdef) or
  469. not(pobjectdef(right^.resulttype)^.is_class)) then
  470. begin
  471. { this would be a problem }
  472. if not(left^.resulttype^.needs_inittable) then
  473. internalerror(3457);
  474. { increment source reference counter }
  475. r.symbol:=right^.resulttype^.get_inittable_label;
  476. cg^.a_param_ref_addr(list,r,2);
  477. cg^.a_param_ref_addr(list,right^.location.reference,1);
  478. cg^.a_call_name(list,'FPC_ADDREF',0);
  479. { decrement destination reference counter }
  480. r.symbol:=left^.resulttype^.get_inittable_label;
  481. cg^.a_param_ref_addr(list,r,2);
  482. cg^.a_param_ref_addr(list,left^.location.reference,1);
  483. cg^.a_call_name(list,'FPC_DECREF',0)
  484. end;
  485. cg^.g_concatcopy(list,right^.location.reference,
  486. left^.location.reference,left^.resulttype^.size,false);
  487. tg.ungetiftemp(right^.location.reference);
  488. end;
  489. end;
  490. end; { needs to be removed together with the dummy }
  491. {$ifdef dummy}
  492. {$ifdef SUPPORT_MMX}
  493. LOC_CMMXREGISTER,
  494. LOC_MMXREGISTER:
  495. begin
  496. if loc=LOC_CMMXREGISTER then
  497. exprasmlist^.concat(new(paicpu,op_reg_reg(A_MOVQ,S_NO,
  498. p^.right^.location.register,p^.left^.location.register)))
  499. else
  500. exprasmlist^.concat(new(paicpu,op_reg_ref(A_MOVQ,S_NO,
  501. p^.right^.location.register,newreference(p^.left^.location.reference))));
  502. end;
  503. {$endif SUPPORT_MMX}
  504. LOC_REGISTER,
  505. LOC_CREGISTER : begin
  506. case p^.right^.resulttype^.size of
  507. 1 : opsize:=S_B;
  508. 2 : opsize:=S_W;
  509. 4 : opsize:=S_L;
  510. 8 : opsize:=S_L;
  511. end;
  512. { simplified with op_reg_loc }
  513. if loc=LOC_CREGISTER then
  514. begin
  515. exprasmlist^.concat(new(paicpu,op_reg_reg(A_MOV,opsize,
  516. p^.right^.location.register,
  517. p^.left^.location.register)));
  518. {$IfDef regallocfix}
  519. ungetregister(p^.right^.location.register);
  520. {$EndIf regallocfix}
  521. end
  522. else
  523. Begin
  524. exprasmlist^.concat(new(paicpu,op_reg_ref(A_MOV,opsize,
  525. p^.right^.location.register,
  526. newreference(p^.left^.location.reference))));
  527. {$IfDef regallocfix}
  528. ungetregister(p^.right^.location.register);
  529. del_reference(p^.left^.location.reference);
  530. {$EndIf regallocfix}
  531. end;
  532. if is_64bitint(p^.right^.resulttype) then
  533. begin
  534. { simplified with op_reg_loc }
  535. if loc=LOC_CREGISTER then
  536. exprasmlist^.concat(new(paicpu,op_reg_reg(A_MOV,opsize,
  537. p^.right^.location.registerhigh,
  538. p^.left^.location.registerhigh)))
  539. else
  540. begin
  541. r:=newreference(p^.left^.location.reference);
  542. inc(r^.offset,4);
  543. exprasmlist^.concat(new(paicpu,op_reg_ref(A_MOV,opsize,
  544. p^.right^.location.registerhigh,r)));
  545. end;
  546. end;
  547. {exprasmlist^.concat(new(paicpu,op_reg_loc(A_MOV,opsize,
  548. p^.right^.location.register,
  549. p^.left^.location))); }
  550. end;
  551. LOC_FPU : begin
  552. if (p^.left^.resulttype^.deftype=floatdef) then
  553. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  554. else
  555. if (p^.right^.resulttype^.deftype=floatdef) then
  556. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  557. else
  558. if (p^.right^.treetype=typeconvn) and
  559. (p^.right^.left^.resulttype^.deftype=floatdef) then
  560. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  561. else
  562. fputyp:=s32real;
  563. case loc of
  564. LOC_CFPUREGISTER:
  565. begin
  566. exprasmlist^.concat(new(paicpu,op_reg(A_FSTP,S_NO,
  567. correct_fpuregister(p^.left^.location.register,fpuvaroffset))));
  568. dec(fpuvaroffset);
  569. end;
  570. LOC_REFERENCE:
  571. floatstore(fputyp,p^.left^.location.reference);
  572. else
  573. internalerror(48991);
  574. end;
  575. end;
  576. LOC_CFPUREGISTER: begin
  577. if (p^.left^.resulttype^.deftype=floatdef) then
  578. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  579. else
  580. if (p^.right^.resulttype^.deftype=floatdef) then
  581. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  582. else
  583. if (p^.right^.treetype=typeconvn) and
  584. (p^.right^.left^.resulttype^.deftype=floatdef) then
  585. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  586. else
  587. fputyp:=s32real;
  588. exprasmlist^.concat(new(paicpu,op_reg(A_FLD,S_NO,
  589. correct_fpuregister(p^.right^.location.register,fpuvaroffset))));
  590. inc(fpuvaroffset);
  591. case loc of
  592. LOC_CFPUREGISTER:
  593. begin
  594. exprasmlist^.concat(new(paicpu,op_reg(A_FSTP,S_NO,
  595. correct_fpuregister(p^.right^.location.register,fpuvaroffset))));
  596. dec(fpuvaroffset);
  597. end;
  598. LOC_REFERENCE:
  599. floatstore(fputyp,p^.left^.location.reference);
  600. else
  601. internalerror(48992);
  602. end;
  603. end;
  604. LOC_JUMP : begin
  605. getlabel(hlabel);
  606. emitlab(truelabel);
  607. if loc=LOC_CREGISTER then
  608. exprasmlist^.concat(new(paicpu,op_const_reg(A_MOV,S_B,
  609. 1,p^.left^.location.register)))
  610. else
  611. exprasmlist^.concat(new(paicpu,op_const_ref(A_MOV,S_B,
  612. 1,newreference(p^.left^.location.reference))));
  613. {exprasmlist^.concat(new(paicpu,op_const_loc(A_MOV,S_B,
  614. 1,p^.left^.location)));}
  615. emitjmp(C_None,hlabel);
  616. emitlab(falselabel);
  617. if loc=LOC_CREGISTER then
  618. exprasmlist^.concat(new(paicpu,op_reg_reg(A_XOR,S_B,
  619. p^.left^.location.register,
  620. p^.left^.location.register)))
  621. else
  622. begin
  623. exprasmlist^.concat(new(paicpu,op_const_ref(A_MOV,S_B,
  624. 0,newreference(p^.left^.location.reference))));
  625. {$IfDef regallocfix}
  626. del_reference(p^.left^.location.reference);
  627. {$EndIf regallocfix}
  628. end;
  629. emitlab(hlabel);
  630. end;
  631. LOC_FLAGS : begin
  632. if loc=LOC_CREGISTER then
  633. emit_flag2reg(p^.right^.location.resflags,p^.left^.location.register)
  634. else
  635. begin
  636. ai:=new(paicpu,op_ref(A_Setcc,S_B,newreference(p^.left^.location.reference)));
  637. ai^.SetCondition(flag_2_cond[p^.right^.location.resflags]);
  638. exprasmlist^.concat(ai);
  639. end;
  640. {$IfDef regallocfix}
  641. del_reference(p^.left^.location.reference);
  642. {$EndIf regallocfix}
  643. end;
  644. else internalerror(68997);
  645. end;
  646. {$endif dummy}
  647. end;
  648. end.
  649. {
  650. $Log$
  651. Revision 1.16 2000-01-07 01:14:53 peter
  652. * updated copyright to 2000
  653. Revision 1.15 1999/12/06 18:17:10 peter
  654. * newcg compiler compiles again
  655. Revision 1.14 1999/10/12 21:20:46 florian
  656. * new codegenerator compiles again
  657. Revision 1.13 1999/09/15 20:35:46 florian
  658. * small fix to operator overloading when in MMX mode
  659. + the compiler uses now fldz and fld1 if possible
  660. + some fixes to floating point registers
  661. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  662. * .... ???
  663. Revision 1.12 1999/09/14 11:16:09 florian
  664. * only small updates to work with the current compiler
  665. Revision 1.11 1999/08/25 12:00:12 jonas
  666. * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
  667. Revision 1.10 1999/08/18 17:05:56 florian
  668. + implemented initilizing of data for the new code generator
  669. so it should compile now simple programs
  670. Revision 1.9 1999/08/06 18:05:54 florian
  671. * implemented some stuff for assignments
  672. Revision 1.8 1999/08/06 15:53:51 florian
  673. * made the alpha version compilable
  674. Revision 1.7 1999/08/05 17:10:57 florian
  675. * some more additions, especially procedure
  676. exit code generation
  677. Revision 1.6 1999/08/05 14:58:13 florian
  678. * some fixes for the floating point registers
  679. * more things for the new code generator
  680. Revision 1.5 1999/08/04 00:23:56 florian
  681. * renamed i386asm and i386base to cpuasm and cpubase
  682. Revision 1.4 1999/08/03 17:09:45 florian
  683. * the alpha compiler can be compiled now
  684. Revision 1.3 1999/08/02 17:14:08 florian
  685. + changed the temp. generator to an object
  686. Revision 1.2 1999/08/01 18:22:35 florian
  687. * made it again compilable
  688. Revision 1.1 1999/01/24 22:32:36 florian
  689. * well, more changes, especially parts of secondload ported
  690. }