nmem.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  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. constructor init(l,r : pnode);
  39. destructor done;virtual;
  40. procedure det_temp;virtual;
  41. procedure det_resulttype;virtual;
  42. procedure secondpass;virtual;
  43. end;
  44. var
  45. { this is necessary for the const section }
  46. simple_loadn : boolean;
  47. p2_assignment : procedure(p : passignmentnode);
  48. p2_assignment_flags : procedure(p : passignmentnode);
  49. p2_assignment_string : procedure(p : passignmentnode);
  50. p2_assignment_int64_reg : procedure(p : passignmentnode);
  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. procedure loadansistring;
  277. begin
  278. { !!! }
  279. end;
  280. procedure loadansi2short(right,left: pnode);
  281. begin
  282. { !!! }
  283. end;
  284. procedure loadshortstring;
  285. begin
  286. { !!! }
  287. end;
  288. constructor tassignmentnode.init(l,r : pnode);
  289. begin
  290. inherited init(l,r);
  291. { concat_string:=false; }
  292. assigntyp:=at_normal;
  293. end;
  294. destructor tassignmentnode.done;
  295. begin
  296. inherited done;
  297. end;
  298. procedure tassignmentnode.det_temp;
  299. begin
  300. end;
  301. procedure tassignmentnode.det_resulttype;
  302. begin
  303. inherited det_resulttype;
  304. resulttype:=voiddef;
  305. { assignements to open arrays aren't allowed }
  306. if is_open_array(left^.resulttype) then
  307. CGMessage(type_e_mismatch);
  308. end;
  309. { updated from old cg on 29.2.00 by FK }
  310. procedure generic_p2_assignment(p : passignmentnode);
  311. var
  312. opsize : tcgsize;
  313. otlabel,hlabel,oflabel : pasmlabel;
  314. fputyp : tfloattype;
  315. loc : tloc;
  316. r : preference;
  317. ai : paicpu;
  318. op : tasmop;
  319. begin
  320. loc:= p^.left^.location.loc;
  321. case p^.right^.location.loc of
  322. LOC_REFERENCE,
  323. LOC_MEM : begin
  324. { extra handling for ordinal constants }
  325. if (p^.right^.treetype in [ordconstn,fixconstn]) or
  326. (loc=LOC_CREGISTER) then
  327. begin
  328. case p^.left^.resulttype^.size of
  329. 1 : opsize:=OS_8;
  330. 2 : opsize:=OS_16;
  331. 4 : opsize:=OS_32;
  332. 8 : opsize:=OS_64;
  333. end;
  334. if loc=LOC_CREGISTER then
  335. begin
  336. cg^.a_load_ref_reg(p^.list,opsize,
  337. p^.right^.location.reference,
  338. p^.left^.location.register);
  339. {$ifdef dummy}
  340. !!!!!!!!!!!! only 32 bit cpus
  341. if is_64bitint(p^.right^.resulttype) then
  342. begin
  343. r:=newreference(p^.right^.location.reference);
  344. inc(r^.offset,4);
  345. emit_ref_reg(A_MOV,opsize,r,
  346. p^.left^.location.registerhigh);
  347. end;
  348. {$endif dummy}
  349. tg.del_reference(p^.right^.location.reference);
  350. end
  351. else
  352. begin
  353. cg^.a_load_const_ref(p^.list,opsize,
  354. p^.right^.location.reference.offset,
  355. p^.left^.location.reference);
  356. {$ifdef dummy}
  357. !!!!!!!!!!!! only 32 bit cpus
  358. if is_64bitint(p^.right^.resulttype) then
  359. begin
  360. r:=newreference(p^.left^.location.reference);
  361. inc(r^.offset,4);
  362. emit_const_ref(A_MOV,opsize,
  363. 0,r);
  364. end;
  365. {$endif dummy}
  366. tg.del_reference(p^.left^.location.reference);
  367. end;
  368. end
  369. {$ifdef i386}
  370. !!!!!!!!!!!! only 386
  371. else if loc=LOC_CFPUREGISTER then
  372. begin
  373. floatloadops(pfloatdef(p^.right^.resulttype)^.typ,op,opsize);
  374. emit_ref(op,opsize,
  375. newreference(p^.right^.location.reference));
  376. emit_reg(A_FSTP,S_NO,
  377. correct_fpuregister(p^.left^.location.register,fpuvaroffset+1));
  378. end
  379. {$endif i386}
  380. else
  381. begin
  382. {$ifdef dummy}
  383. if (p^.right^.resulttype^.needs_inittable) and
  384. ((p^.right^.resulttype^.deftype<>objectdef) or
  385. not(pobjectdef(p^.right^.resulttype)^.is_class)) then
  386. begin
  387. { this would be a problem }
  388. if not(left^.resulttype^.needs_inittable) then
  389. internalerror(292001);
  390. { increment source reference counter }
  391. new(r);
  392. reset_reference(r^);
  393. r^.symbol:=p^.right^.resulttype^.get_inittable_label;
  394. emitpushreferenceaddr(r^);
  395. emitpushreferenceaddr(p^.right^.location.reference);
  396. emitcall('FPC_ADDREF');
  397. { decrement destination reference counter }
  398. new(r);
  399. reset_reference(r^);
  400. r^.symbol:=p^.left^.resulttype^.get_inittable_label;
  401. emitpushreferenceaddr(r^);
  402. emitpushreferenceaddr(p^.left^.location.reference);
  403. emitcall('FPC_DECREF');
  404. end;
  405. {$endif dummy}
  406. {$ifdef regallocfix}
  407. cg^.concatcopy(p^.list,p^.right^.location.reference,
  408. p^.left^.location.reference,p^.left^.resulttype^.size,true,false);
  409. ungetiftemp(p^.right^.location.reference);
  410. {$Else regallocfix}
  411. cg^.g_concatcopy(p^.list,p^.right^.location.reference,
  412. p^.left^.location.reference,p^.left^.resulttype^.size,false);
  413. tg.ungetiftemp(p^.right^.location.reference);
  414. {$endif regallocfix}
  415. end;
  416. end;
  417. {$ifdef SUPPORT_MMX}
  418. LOC_CMMXREGISTER,
  419. LOC_MMXREGISTER:
  420. begin
  421. if loc=LOC_CMMXREGISTER then
  422. emit_reg_reg(A_MOVQ,S_NO,
  423. p^.right^.location.register,p^.left^.location.register)
  424. else
  425. emit_reg_ref(A_MOVQ,S_NO,
  426. p^.right^.location.register,newreference(p^.left^.location.reference));
  427. end;
  428. {$endif SUPPORT_MMX}
  429. LOC_REGISTER,
  430. LOC_CREGISTER : begin
  431. case p^.right^.resulttype^.size of
  432. 1 : opsize:=OS_8;
  433. 2 : opsize:=OS_16;
  434. 4 : opsize:=OS_32;
  435. 8 : opsize:=OS_64;
  436. end;
  437. { simplified with op_reg_loc }
  438. if loc=LOC_CREGISTER then
  439. begin
  440. cg^.a_load_reg_reg(p^.list,opsize,
  441. p^.right^.location.register,
  442. p^.left^.location.register);
  443. tg.ungetregister(p^.right^.location.register);
  444. end
  445. else
  446. Begin
  447. cg^.a_load_reg_ref(p^.list,opsize,
  448. p^.right^.location.register,
  449. p^.left^.location.reference);
  450. tg.ungetregister(p^.right^.location.register);
  451. tg.del_reference(p^.left^.location.reference);
  452. end;
  453. {$ifdef dummy}
  454. !!!! only for 32bit processors
  455. if is_64bitint(p^.right^.resulttype) then
  456. begin
  457. { simplified with op_reg_loc }
  458. if loc=LOC_CREGISTER then
  459. emit_reg_reg(A_MOV,opsize,
  460. p^.right^.location.registerhigh,
  461. p^.left^.location.registerhigh)
  462. else
  463. begin
  464. r:=newreference(p^.left^.location.reference);
  465. inc(r^.offset,4);
  466. emit_reg_ref(A_MOV,opsize,
  467. p^.right^.location.registerhigh,r);
  468. end;
  469. end;
  470. {$endif dummy}
  471. end;
  472. {$ifdef dummy}
  473. LOC_FPU : begin
  474. if (p^.left^.resulttype^.deftype=floatdef) then
  475. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  476. else
  477. if (p^.right^.resulttype^.deftype=floatdef) then
  478. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  479. else
  480. if (p^.right^.treetype=typeconvn) and
  481. (p^.right^.left^.resulttype^.deftype=floatdef) then
  482. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  483. else
  484. fputyp:=s32real;
  485. case loc of
  486. LOC_CFPUREGISTER:
  487. begin
  488. emit_reg(A_FSTP,S_NO,
  489. correct_fpuregister(p^.left^.location.register,fpuvaroffset));
  490. dec(fpuvaroffset);
  491. end;
  492. LOC_REFERENCE:
  493. floatstore(fputyp,p^.left^.location.reference);
  494. else
  495. internalerror(48991);
  496. end;
  497. end;
  498. {$ifdef i386}
  499. !!!!!!!!!!!! only 386
  500. LOC_CFPUREGISTER: begin
  501. if (p^.left^.resulttype^.deftype=floatdef) then
  502. fputyp:=pfloatdef(p^.left^.resulttype)^.typ
  503. else
  504. if (p^.right^.resulttype^.deftype=floatdef) then
  505. fputyp:=pfloatdef(p^.right^.resulttype)^.typ
  506. else
  507. if (p^.right^.treetype=typeconvn) and
  508. (p^.right^.left^.resulttype^.deftype=floatdef) then
  509. fputyp:=pfloatdef(p^.right^.left^.resulttype)^.typ
  510. else
  511. fputyp:=s32real;
  512. emit_reg(A_FLD,S_NO,
  513. correct_fpuregister(p^.right^.location.register,fpuvaroffset));
  514. inc(fpuvaroffset);
  515. case loc of
  516. LOC_CFPUREGISTER:
  517. begin
  518. emit_reg(A_FSTP,S_NO,
  519. correct_fpuregister(p^.right^.location.register,fpuvaroffset));
  520. dec(fpuvaroffset);
  521. end;
  522. LOC_REFERENCE:
  523. floatstore(fputyp,p^.left^.location.reference);
  524. else
  525. internalerror(48992);
  526. end;
  527. end;
  528. {$endif i386}
  529. {$endif dummy}
  530. LOC_JUMP : begin
  531. { support every type of boolean here }
  532. case p^.right^.resulttype^.size of
  533. 1 : opsize:=OS_8;
  534. 2 : opsize:=OS_16;
  535. 4 : opsize:=OS_32;
  536. { this leads to an efficiency of 1.5 }
  537. { per cent regarding memory usage .... }
  538. 8 : opsize:=OS_64;
  539. end;
  540. getlabel(hlabel);
  541. cg^.a_label(p^.list,p^.truelabel);
  542. if loc=LOC_CREGISTER then
  543. cg^.a_load_const_reg(p^.list,opsize,1,
  544. p^.left^.location.register)
  545. else
  546. cg^.a_load_const_ref(p^.list,opsize,1,
  547. p^.left^.location.reference);
  548. cg^.a_jmp_cond(p^.list,OC_None,hlabel);
  549. cg^.a_label(p^.list,p^.falselabel);
  550. if loc=LOC_CREGISTER then
  551. cg^.a_load_const_reg(p^.list,opsize,0,
  552. p^.left^.location.register)
  553. else
  554. begin
  555. cg^.a_load_const_ref(p^.list,opsize,0,
  556. p^.left^.location.reference);
  557. tg.del_reference(p^.left^.location.reference);
  558. end;
  559. cg^.a_label(p^.list,hlabel);
  560. end;
  561. LOC_FLAGS:
  562. p2_assignment_flags(p);
  563. end;
  564. end;
  565. { updated from old cg on 29.2.00 by FK }
  566. procedure generic_p2_assignment_string(p : passignmentnode);
  567. begin
  568. with p^ do
  569. if is_ansistring(left^.resulttype) then
  570. begin
  571. { the source and destinations are released
  572. in loadansistring, because an ansi string can
  573. also be in a register
  574. }
  575. loadansistring;
  576. end
  577. else
  578. if is_shortstring(left^.resulttype) then
  579. begin
  580. if is_ansistring(right^.resulttype) then
  581. begin
  582. if (right^.treetype=stringconstn) and
  583. (pstringconstnode(right)^.length=0) then
  584. begin
  585. cg^.a_load_const_ref(list,OS_8,0,left^.location.reference);
  586. tg.del_reference(left^.location.reference);
  587. end
  588. else
  589. loadansi2short(right,left);
  590. end
  591. else
  592. begin
  593. { we do not need destination anymore }
  594. tg.del_reference(left^.location.reference);
  595. { tg.del_reference(right^.location.reference);
  596. done in loadshortstring }
  597. loadshortstring;
  598. tg.ungetiftemp(right^.location.reference);
  599. end;
  600. end
  601. else if is_longstring(left^.resulttype) then
  602. begin
  603. abstract;
  604. end
  605. else
  606. begin
  607. { its the only thing we have to do }
  608. tg.del_reference(right^.location.reference);
  609. end
  610. end;
  611. procedure generic_p2_assignment_int64_reg(p : passignmentnode);
  612. begin
  613. { we don't know it better here }
  614. generic_p2_assignment(p);
  615. end;
  616. { updated from old cg on 29.2.00 by FK }
  617. procedure generic_p2_assignment_flags(p : passignmentnode);
  618. begin
  619. { for example the alpha doesn't have flags }
  620. abstract;
  621. end;
  622. procedure tassignmentnode.secondpass;
  623. var
  624. r : treference;
  625. opsize : tcgsize;
  626. begin
  627. if not(left^.location.loc in lvaluelocations) then
  628. begin
  629. CGMessage(cg_e_illegal_expression);
  630. exit;
  631. end;
  632. if left^.resulttype^.deftype=stringdef then
  633. p2_assignment_string(@self)
  634. { if is an int64 which has to do with registers, we
  635. need to call probably a procedure for 32 bit processors
  636. }
  637. else if is_64bitint(left^.resulttype) and
  638. ((left^.location.loc in [LOC_REGISTER,LOC_CREGISTER]) or
  639. (left^.location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
  640. p2_assignment_int64_reg(@self)
  641. else
  642. p2_assignment(@self);
  643. end;
  644. begin
  645. p2_assignment:=@generic_p2_assignment;
  646. p2_assignment_flags:=@generic_p2_assignment_flags;
  647. p2_assignment_string:=@generic_p2_assignment_string;
  648. p2_assignment_int64_reg:=@generic_p2_assignment_int64_reg;
  649. end.
  650. {
  651. $Log$
  652. Revision 1.1 2000-07-13 06:30:08 michael
  653. + Initial import
  654. Revision 1.18 2000/04/29 09:01:06 jonas
  655. * nmem compiles again (at least for powerpc)
  656. Revision 1.17 2000/03/01 15:36:13 florian
  657. * some new stuff for the new cg
  658. Revision 1.16 2000/01/07 01:14:53 peter
  659. * updated copyright to 2000
  660. Revision 1.15 1999/12/06 18:17:10 peter
  661. * newcg compiler compiles again
  662. Revision 1.14 1999/10/12 21:20:46 florian
  663. * new codegenerator compiles again
  664. Revision 1.13 1999/09/15 20:35:46 florian
  665. * small fix to operator overloading when in MMX mode
  666. + the compiler uses now fldz and fld1 if possible
  667. + some fixes to floating point registers
  668. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  669. * .... ???
  670. Revision 1.12 1999/09/14 11:16:09 florian
  671. * only small updates to work with the current compiler
  672. Revision 1.11 1999/08/25 12:00:12 jonas
  673. * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
  674. Revision 1.10 1999/08/18 17:05:56 florian
  675. + implemented initilizing of data for the new code generator
  676. so it should compile now simple programs
  677. Revision 1.9 1999/08/06 18:05:54 florian
  678. * implemented some stuff for assignments
  679. Revision 1.8 1999/08/06 15:53:51 florian
  680. * made the alpha version compilable
  681. Revision 1.7 1999/08/05 17:10:57 florian
  682. * some more additions, especially procedure
  683. exit code generation
  684. Revision 1.6 1999/08/05 14:58:13 florian
  685. * some fixes for the floating point registers
  686. * more things for the new code generator
  687. Revision 1.5 1999/08/04 00:23:56 florian
  688. * renamed i386asm and i386base to cpuasm and cpubase
  689. Revision 1.4 1999/08/03 17:09:45 florian
  690. * the alpha compiler can be compiled now
  691. Revision 1.3 1999/08/02 17:14:08 florian
  692. + changed the temp. generator to an object
  693. Revision 1.2 1999/08/01 18:22:35 florian
  694. * made it again compilable
  695. Revision 1.1 1999/01/24 22:32:36 florian
  696. * well, more changes, especially parts of secondload ported
  697. }