nmem.pas 35 KB

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