cg68kld.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Generate m68k assembler for load/assignment nodes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit cg68kld;
  19. interface
  20. uses
  21. tree,m68k;
  22. var
  23. { this is for open arrays and strings }
  24. { but be careful, this data is in the }
  25. { generated code destroyed quick, and also }
  26. { the next call of secondload destroys this }
  27. { data }
  28. { So be careful using the informations }
  29. { provided by this variables }
  30. highframepointer : tregister;
  31. highoffset : longint;
  32. procedure secondload(var p : ptree);
  33. procedure secondassignment(var p : ptree);
  34. procedure secondfuncret(var p : ptree);
  35. procedure secondarrayconstruct(var p : ptree);
  36. implementation
  37. uses
  38. cobjects,verbose,globals,
  39. symtable,aasm,types,
  40. hcodegen,temp_gen,pass_2,
  41. cga68k,tgen68k;
  42. {*****************************************************************************
  43. SecondLoad
  44. *****************************************************************************}
  45. procedure secondload(var p : ptree);
  46. var
  47. hregister : tregister;
  48. i : longint;
  49. symtabletype: tsymtabletype;
  50. hp : preference;
  51. begin
  52. simple_loadn:=true;
  53. reset_reference(p^.location.reference);
  54. case p^.symtableentry^.typ of
  55. { this is only for toasm and toaddr }
  56. absolutesym :
  57. begin
  58. stringdispose(p^.location.reference.symbol);
  59. p^.location.reference.symbol:=stringdup(p^.symtableentry^.mangledname);
  60. if p^.symtableentry^.owner^.symtabletype=unitsymtable then
  61. concat_external(p^.symtableentry^.mangledname,EXT_NEAR);
  62. end;
  63. varsym :
  64. begin
  65. hregister:=R_NO;
  66. symtabletype:=p^.symtable^.symtabletype;
  67. { in case it is a register variable: }
  68. { we simply set the location to the }
  69. { correct register. }
  70. if pvarsym(p^.symtableentry)^.reg<>R_NO then
  71. begin
  72. p^.location.loc:=LOC_CREGISTER;
  73. p^.location.register:=pvarsym(p^.symtableentry)^.reg;
  74. unused:=unused-[pvarsym(p^.symtableentry)^.reg];
  75. end
  76. else
  77. begin
  78. { --------------------- LOCAL AND TEMP VARIABLES ------------- }
  79. if (symtabletype=parasymtable) or (symtabletype=localsymtable) then
  80. begin
  81. p^.location.reference.base:=procinfo.framepointer;
  82. p^.location.reference.offset:=pvarsym(p^.symtableentry)^.address;
  83. if (symtabletype=localsymtable) then
  84. p^.location.reference.offset:=-p^.location.reference.offset;
  85. if (symtabletype=parasymtable) then
  86. inc(p^.location.reference.offset,p^.symtable^.call_offset);
  87. if (lexlevel>(p^.symtable^.symtablelevel)) then
  88. begin
  89. hregister:=getaddressreg;
  90. { make a reference }
  91. new(hp);
  92. reset_reference(hp^);
  93. hp^.offset:=procinfo.framepointer_offset;
  94. hp^.base:=procinfo.framepointer;
  95. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,hp,hregister)));
  96. simple_loadn:=false;
  97. i:=lexlevel-1;
  98. while i>(p^.symtable^.symtablelevel) do
  99. begin
  100. { make a reference }
  101. new(hp);
  102. reset_reference(hp^);
  103. hp^.offset:=8;
  104. hp^.base:=hregister;
  105. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,hp,hregister)));
  106. dec(i);
  107. end;
  108. p^.location.reference.base:=hregister;
  109. end;
  110. end
  111. { --------------------- END OF LOCAL AND TEMP VARS ---------------- }
  112. else
  113. case symtabletype of
  114. unitsymtable,globalsymtable,
  115. staticsymtable : begin
  116. stringdispose(p^.location.reference.symbol);
  117. p^.location.reference.symbol:=stringdup(p^.symtableentry^.mangledname);
  118. if symtabletype=unitsymtable then
  119. concat_external(p^.symtableentry^.mangledname,EXT_NEAR);
  120. end;
  121. objectsymtable : begin
  122. if (pvarsym(p^.symtableentry)^.properties and sp_static)<>0 then
  123. begin
  124. stringdispose(p^.location.reference.symbol);
  125. p^.location.reference.symbol:=stringdup(p^.symtableentry^.mangledname);
  126. if p^.symtable^.defowner^.owner^.symtabletype=unitsymtable then
  127. concat_external(p^.symtableentry^.mangledname,EXT_NEAR);
  128. end
  129. else
  130. begin
  131. p^.location.reference.base:=R_A5;
  132. p^.location.reference.offset:=pvarsym(p^.symtableentry)^.address;
  133. end;
  134. end;
  135. withsymtable : begin
  136. hregister:=getaddressreg;
  137. p^.location.reference.base:=hregister;
  138. { make a reference }
  139. new(hp);
  140. reset_reference(hp^);
  141. hp^.offset:=p^.symtable^.datasize;
  142. hp^.base:=procinfo.framepointer;
  143. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,hp,hregister)));
  144. p^.location.reference.offset:=
  145. pvarsym(p^.symtableentry)^.address;
  146. end;
  147. end;
  148. { in case call by reference, then calculate: }
  149. if (pvarsym(p^.symtableentry)^.varspez=vs_var) or
  150. ((pvarsym(p^.symtableentry)^.varspez=vs_const) and
  151. dont_copy_const_param(pvarsym(p^.symtableentry)^.definition)) then
  152. begin
  153. simple_loadn:=false;
  154. if hregister=R_NO then
  155. hregister:=getaddressreg;
  156. { ADDED FOR OPEN ARRAY SUPPORT. }
  157. if (p^.location.reference.base=procinfo.framepointer) then
  158. begin
  159. highframepointer:=p^.location.reference.base;
  160. highoffset:=p^.location.reference.offset;
  161. end
  162. else
  163. begin
  164. highframepointer:=R_A1;
  165. highoffset:=p^.location.reference.offset;
  166. exprasmlist^.concat(new(pai68k,op_reg_reg(A_MOVE,S_L,
  167. p^.location.reference.base,R_A1)));
  168. end;
  169. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,newreference(p^.location.reference),
  170. hregister)));
  171. { END ADDITION }
  172. clear_reference(p^.location.reference);
  173. p^.location.reference.base:=hregister;
  174. end;
  175. { should be dereferenced later (FK)
  176. if (pvarsym(p^.symtableentry)^.definition^.deftype=objectdef) and
  177. ((pobjectdef(pvarsym(p^.symtableentry)^.definition)^.options and oois_class)<>0) then
  178. begin
  179. simple_loadn:=false;
  180. if hregister=R_NO then
  181. hregister:=getaddressreg;
  182. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,newreference(p^.location.reference),
  183. hregister)));
  184. clear_reference(p^.location.reference);
  185. p^.location.reference.base:=hregister;
  186. end;
  187. }
  188. end;
  189. end;
  190. procsym:
  191. begin
  192. {!!!!! Be aware, work on virtual methods too }
  193. stringdispose(p^.location.reference.symbol);
  194. p^.location.reference.symbol:=
  195. stringdup(pprocsym(p^.symtableentry)^.definition^.mangledname);
  196. if p^.symtable^.symtabletype=unitsymtable then
  197. concat_external(p^.symtableentry^.mangledname,EXT_NEAR);
  198. end;
  199. typedconstsym :
  200. begin
  201. stringdispose(p^.location.reference.symbol);
  202. p^.location.reference.symbol:=stringdup(p^.symtableentry^.mangledname);
  203. if p^.symtable^.symtabletype=unitsymtable then
  204. concat_external(p^.symtableentry^.mangledname,EXT_NEAR);
  205. end;
  206. else internalerror(4);
  207. end;
  208. end;
  209. {*****************************************************************************
  210. SecondAssignment
  211. *****************************************************************************}
  212. procedure secondassignment(var p : ptree);
  213. var
  214. opsize : topsize;
  215. withresult : boolean;
  216. otlabel,hlabel,oflabel : plabel;
  217. hregister : tregister;
  218. loc : tloc;
  219. begin
  220. otlabel:=truelabel;
  221. oflabel:=falselabel;
  222. getlabel(truelabel);
  223. getlabel(falselabel);
  224. withresult:=false;
  225. { calculate left sides }
  226. secondpass(p^.left);
  227. case p^.left^.location.loc of
  228. LOC_REFERENCE : begin
  229. { in case left operator uses too many registers }
  230. { but to few are free then LEA }
  231. if (p^.left^.location.reference.base<>R_NO) and
  232. (p^.left^.location.reference.index<>R_NO) and
  233. (usableaddress<p^.right^.registers32) then
  234. begin
  235. del_reference(p^.left^.location.reference);
  236. hregister:=getaddressreg;
  237. exprasmlist^.concat(new(pai68k,op_ref_reg(A_LEA,S_L,newreference(
  238. p^.left^.location.reference),
  239. hregister)));
  240. clear_reference(p^.left^.location.reference);
  241. p^.left^.location.reference.base:=hregister;
  242. p^.left^.location.reference.index:=R_NO;
  243. end;
  244. loc:=LOC_REFERENCE;
  245. end;
  246. LOC_CREGISTER : loc:=LOC_CREGISTER;
  247. else
  248. begin
  249. CGMessage(cg_e_illegal_expression);
  250. exit;
  251. end;
  252. end;
  253. { lets try to optimize this (PM) }
  254. { define a dest_loc that is the location }
  255. { and a ptree to verify that it is the right }
  256. { place to insert it }
  257. {$ifdef test_dest_loc}
  258. if (aktexprlevel<4) then
  259. begin
  260. dest_loc_known:=true;
  261. dest_loc:=p^.left^.location;
  262. dest_loc_tree:=p^.right;
  263. end;
  264. {$endif test_dest_loc}
  265. if (p^.right^.treetype=realconstn) then
  266. begin
  267. if p^.left^.resulttype^.deftype=floatdef then
  268. begin
  269. case pfloatdef(p^.left^.resulttype)^.typ of
  270. s32real : p^.right^.realtyp:=ait_real_32bit;
  271. s64real : p^.right^.realtyp:=ait_real_64bit;
  272. s80real : p^.right^.realtyp:=ait_real_extended;
  273. { what about f32bit and s64bit }
  274. end;
  275. end;
  276. end;
  277. secondpass(p^.right);
  278. {$ifdef test_dest_loc}
  279. dest_loc_known:=false;
  280. if in_dest_loc then
  281. begin
  282. truelabel:=otlabel;
  283. falselabel:=oflabel;
  284. in_dest_loc:=false;
  285. exit;
  286. end;
  287. {$endif test_dest_loc}
  288. if p^.left^.resulttype^.deftype=stringdef then
  289. begin
  290. { we do not need destination anymore }
  291. del_reference(p^.left^.location.reference);
  292. { only source if withresult is set }
  293. if not(withresult) then
  294. del_reference(p^.right^.location.reference);
  295. loadstring(p);
  296. ungetiftemp(p^.right^.location.reference);
  297. end
  298. else case p^.right^.location.loc of
  299. LOC_REFERENCE,
  300. LOC_MEM : begin
  301. { handle ordinal constants trimmed }
  302. if (p^.right^.treetype in [ordconstn,fixconstn]) or
  303. (loc=LOC_CREGISTER) then
  304. begin
  305. case p^.left^.resulttype^.size of
  306. 1 : opsize:=S_B;
  307. 2 : opsize:=S_W;
  308. 4 : opsize:=S_L;
  309. end;
  310. if loc=LOC_CREGISTER then
  311. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,opsize,
  312. newreference(p^.right^.location.reference),
  313. p^.left^.location.register)))
  314. else
  315. exprasmlist^.concat(new(pai68k,op_const_ref(A_MOVE,opsize,
  316. p^.right^.location.reference.offset,
  317. newreference(p^.left^.location.reference))));
  318. {exprasmlist^.concat(new(pai68k,op_const_loc(A_MOV,opsize,
  319. p^.right^.location.reference.offset,
  320. p^.left^.location)));}
  321. end
  322. else
  323. begin
  324. concatcopy(p^.right^.location.reference,
  325. p^.left^.location.reference,p^.left^.resulttype^.size,
  326. withresult);
  327. ungetiftemp(p^.right^.location.reference);
  328. end;
  329. end;
  330. LOC_REGISTER,
  331. LOC_CREGISTER : begin
  332. case p^.right^.resulttype^.size of
  333. 1 : opsize:=S_B;
  334. 2 : opsize:=S_W;
  335. 4 : opsize:=S_L;
  336. end;
  337. { simplified with op_reg_loc }
  338. if loc=LOC_CREGISTER then
  339. exprasmlist^.concat(new(pai68k,op_reg_reg(A_MOVE,opsize,
  340. p^.right^.location.register,
  341. p^.left^.location.register)))
  342. else
  343. exprasmlist^.concat(new(pai68k,op_reg_ref(A_MOVE,opsize,
  344. p^.right^.location.register,
  345. newreference(p^.left^.location.reference))));
  346. {exprasmlist^.concat(new(pai68k,op_reg_loc(A_MOV,opsize,
  347. p^.right^.location.register,
  348. p^.left^.location))); }
  349. end;
  350. LOC_FPU : begin
  351. if loc<>LOC_REFERENCE then
  352. internalerror(10010)
  353. else
  354. floatstore(pfloatdef(p^.left^.resulttype)^.typ,
  355. p^.right^.location,p^.left^.location.reference);
  356. end;
  357. LOC_JUMP : begin
  358. getlabel(hlabel);
  359. emitl(A_LABEL,truelabel);
  360. if loc=LOC_CREGISTER then
  361. exprasmlist^.concat(new(pai68k,op_const_reg(A_MOVE,S_B,
  362. 1,p^.left^.location.register)))
  363. else
  364. exprasmlist^.concat(new(pai68k,op_const_ref(A_MOVE,S_B,
  365. 1,newreference(p^.left^.location.reference))));
  366. {exprasmlist^.concat(new(pai68k,op_const_loc(A_MOV,S_B,
  367. 1,p^.left^.location)));}
  368. emitl(A_JMP,hlabel);
  369. emitl(A_LABEL,falselabel);
  370. if loc=LOC_CREGISTER then
  371. exprasmlist^.concat(new(pai68k,op_reg(A_CLR,S_B,
  372. p^.left^.location.register)))
  373. else
  374. exprasmlist^.concat(new(pai68k,op_const_ref(A_MOVE,S_B,
  375. 0,newreference(p^.left^.location.reference))));
  376. emitl(A_LABEL,hlabel);
  377. end;
  378. LOC_FLAGS : begin
  379. if loc=LOC_CREGISTER then
  380. begin
  381. exprasmlist^.concat(new(pai68k,op_reg(flag_2_set[p^.right^.location.resflags],S_B,
  382. p^.left^.location.register)));
  383. exprasmlist^.concat(new(pai68k,op_reg(A_NEG,S_B,p^.left^.location.register)));
  384. end
  385. else
  386. begin
  387. exprasmlist^.concat(new(pai68k,op_ref(flag_2_set[p^.right^.location.resflags],S_B,
  388. newreference(p^.left^.location.reference))));
  389. exprasmlist^.concat(new(pai68k,op_ref(A_NEG,S_B,newreference(p^.left^.location.reference))));
  390. end;
  391. end;
  392. end;
  393. truelabel:=otlabel;
  394. falselabel:=oflabel;
  395. end;
  396. {*****************************************************************************
  397. SecondFuncRetN
  398. *****************************************************************************}
  399. procedure secondfuncret(var p : ptree);
  400. var
  401. hr : tregister;
  402. hp : preference;
  403. pp : pprocinfo;
  404. hr_valid : boolean;
  405. begin
  406. clear_reference(p^.location.reference);
  407. hr_valid:=false;
  408. { !!!!!!! }
  409. (* if @procinfo<>pprocinfo(p^.funcretprocinfo) then
  410. begin
  411. hr:=getregister32;
  412. hr_valid:=false;
  413. hp:=new_reference(procinfo.framepointer,
  414. procinfo.framepointer_offset);
  415. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,hp,hr)));
  416. pp:=procinfo.parent;
  417. { walk up the stack frame }
  418. while pp<>pprocinfo(p^.funcretprocinfo) do
  419. begin
  420. hp:=new_reference(hr,
  421. pp^.framepointer_offset);
  422. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,hp,hr)));
  423. pp:=pp^.parent;
  424. end;
  425. p^.location.reference.base:=hr;
  426. end
  427. else *)
  428. p^.location.reference.base:=procinfo.framepointer;
  429. p^.location.reference.offset:=procinfo.retoffset;
  430. if ret_in_param(p^.retdef) then
  431. begin
  432. if not hr_valid then
  433. hr:=getregister32;
  434. exprasmlist^.concat(new(pai68k,op_ref_reg(A_MOVE,S_L,newreference(p^.location.reference),hr)));
  435. p^.location.reference.base:=hr;
  436. p^.location.reference.offset:=0;
  437. end;
  438. end;
  439. {*****************************************************************************
  440. SecondArrayConstruct
  441. *****************************************************************************}
  442. const
  443. vtInteger = 0;
  444. vtBoolean = 1;
  445. vtChar = 2;
  446. vtExtended = 3;
  447. vtString = 4;
  448. vtPointer = 5;
  449. vtPChar = 6;
  450. vtObject = 7;
  451. vtClass = 8;
  452. vtWideChar = 9;
  453. vtPWideChar = 10;
  454. vtAnsiString = 11;
  455. vtCurrency = 12;
  456. vtVariant = 13;
  457. vtInterface = 14;
  458. vtWideString = 15;
  459. vtInt64 = 16;
  460. procedure secondarrayconstruct(var p : ptree);
  461. begin
  462. end;
  463. end.
  464. {
  465. $Log$
  466. Revision 1.3 1998-10-06 20:48:59 peter
  467. * m68k compiler compiles again
  468. Revision 1.2 1998/09/17 09:42:27 peter
  469. + pass_2 for cg386
  470. * Message() -> CGMessage() for pass_1/pass_2
  471. Revision 1.1 1998/09/01 09:07:09 peter
  472. * m68k fixes, splitted cg68k like cgi386
  473. }