nmem.pas 33 KB

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