cga.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Helper routines for the i386 code generator
  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 cga;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cpuinfo,cpubase,cpuasm,cginfo,
  23. symconst,symtype,symdef,aasm;
  24. {$define TESTGETTEMP to store const that
  25. are written into temps for later release PM }
  26. function def_opsize(p1:tdef):topsize;
  27. function def_getreg(p1:tdef):tregister;
  28. procedure emitjmp(c : tasmcond;var l : tasmlabel);
  29. procedure emit_none(i : tasmop;s : topsize);
  30. procedure emit_const(i : tasmop;s : topsize;c : longint);
  31. procedure emit_reg(i : tasmop;s : topsize;reg : tregister);
  32. procedure emit_ref(i : tasmop;s : topsize;const ref : treference);
  33. procedure emit_const_reg(i : tasmop;s : topsize;c : longint;reg : tregister);
  34. procedure emit_const_ref(i : tasmop;s : topsize;c : longint;const ref : treference);
  35. procedure emit_ref_reg(i : tasmop;s : topsize;const ref : treference;reg : tregister);
  36. procedure emit_reg_ref(i : tasmop;s : topsize;reg : tregister;const ref : treference);
  37. procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
  38. procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
  39. procedure emit_reg_reg_reg(i : tasmop;s : topsize;reg1,reg2,reg3 : tregister);
  40. procedure emit_sym(i : tasmop;s : topsize;op : tasmsymbol);
  41. implementation
  42. uses
  43. cutils,
  44. systems,globals,verbose,
  45. cgbase,cgobj,tgobj,rgobj,rgcpu;
  46. {*****************************************************************************
  47. Helpers
  48. *****************************************************************************}
  49. function def_opsize(p1:tdef):topsize;
  50. begin
  51. case p1.size of
  52. 1 : def_opsize:=S_B;
  53. 2 : def_opsize:=S_W;
  54. 4 : def_opsize:=S_L;
  55. { I don't know if we need it (FK) }
  56. 8 : def_opsize:=S_L;
  57. else
  58. internalerror(130820001);
  59. end;
  60. end;
  61. function def_getreg(p1:tdef):tregister;
  62. begin
  63. def_getreg:=rg.makeregsize(rg.getregisterint(exprasmlist),int_cgsize(p1.size));
  64. end;
  65. {*****************************************************************************
  66. Emit Assembler
  67. *****************************************************************************}
  68. procedure emitjmp(c : tasmcond;var l : tasmlabel);
  69. var
  70. ai : taicpu;
  71. begin
  72. if c=C_None then
  73. ai := Taicpu.Op_sym(A_JMP,S_NO,l)
  74. else
  75. begin
  76. ai:=Taicpu.Op_sym(A_Jcc,S_NO,l);
  77. ai.SetCondition(c);
  78. end;
  79. ai.is_jmp:=true;
  80. exprasmList.concat(ai);
  81. end;
  82. procedure emit_none(i : tasmop;s : topsize);
  83. begin
  84. exprasmList.concat(Taicpu.Op_none(i,s));
  85. end;
  86. procedure emit_reg(i : tasmop;s : topsize;reg : tregister);
  87. begin
  88. exprasmList.concat(Taicpu.Op_reg(i,s,reg));
  89. end;
  90. procedure emit_ref(i : tasmop;s : topsize;const ref : treference);
  91. begin
  92. exprasmList.concat(Taicpu.Op_ref(i,s,ref));
  93. end;
  94. procedure emit_const(i : tasmop;s : topsize;c : longint);
  95. begin
  96. exprasmList.concat(Taicpu.Op_const(i,s,aword(c)));
  97. end;
  98. procedure emit_const_reg(i : tasmop;s : topsize;c : longint;reg : tregister);
  99. begin
  100. exprasmList.concat(Taicpu.Op_const_reg(i,s,aword(c),reg));
  101. end;
  102. procedure emit_const_ref(i : tasmop;s : topsize;c : longint;const ref : treference);
  103. begin
  104. exprasmList.concat(Taicpu.Op_const_ref(i,s,aword(c),ref));
  105. end;
  106. procedure emit_ref_reg(i : tasmop;s : topsize;const ref : treference;reg : tregister);
  107. begin
  108. exprasmList.concat(Taicpu.Op_ref_reg(i,s,ref,reg));
  109. end;
  110. procedure emit_reg_ref(i : tasmop;s : topsize;reg : tregister;const ref : treference);
  111. begin
  112. exprasmList.concat(Taicpu.Op_reg_ref(i,s,reg,ref));
  113. end;
  114. procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
  115. begin
  116. if (reg1<>reg2) or (i<>A_MOV) then
  117. exprasmList.concat(Taicpu.Op_reg_reg(i,s,reg1,reg2));
  118. end;
  119. procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
  120. begin
  121. exprasmList.concat(Taicpu.Op_const_reg_reg(i,s,c,reg1,reg2));
  122. end;
  123. procedure emit_reg_reg_reg(i : tasmop;s : topsize;reg1,reg2,reg3 : tregister);
  124. begin
  125. exprasmList.concat(Taicpu.Op_reg_reg_reg(i,s,reg1,reg2,reg3));
  126. end;
  127. procedure emit_sym(i : tasmop;s : topsize;op : tasmsymbol);
  128. begin
  129. exprasmList.concat(Taicpu.Op_sym(i,s,op));
  130. end;
  131. end.
  132. {
  133. $Log$
  134. Revision 1.31 2002-05-16 19:46:50 carl
  135. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  136. + try to fix temp allocation (still in ifdef)
  137. + generic constructor calls
  138. + start of tassembler / tmodulebase class cleanup
  139. Revision 1.29 2002/05/13 19:54:37 peter
  140. * removed n386ld and n386util units
  141. * maybe_save/maybe_restore added instead of the old maybe_push
  142. Revision 1.28 2002/05/12 16:53:16 peter
  143. * moved entry and exitcode to ncgutil and cgobj
  144. * foreach gets extra argument for passing local data to the
  145. iterator function
  146. * -CR checks also class typecasts at runtime by changing them
  147. into as
  148. * fixed compiler to cycle with the -CR option
  149. * fixed stabs with elf writer, finally the global variables can
  150. be watched
  151. * removed a lot of routines from cga unit and replaced them by
  152. calls to cgobj
  153. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  154. u32bit then the other is typecasted also to u32bit without giving
  155. a rangecheck warning/error.
  156. * fixed pascal calling method with reversing also the high tree in
  157. the parast, detected by tcalcst3 test
  158. Revision 1.27 2002/04/25 20:16:39 peter
  159. * moved more routines from cga/n386util
  160. Revision 1.26 2002/04/21 15:29:53 carl
  161. * changeregsize -> rg.makeregsize
  162. Revision 1.25 2002/04/20 21:37:07 carl
  163. + generic FPC_CHECKPOINTER
  164. + first parameter offset in stack now portable
  165. * rename some constants
  166. + move some cpu stuff to other units
  167. - remove unused constents
  168. * fix stacksize for some targets
  169. * fix generic size problems which depend now on EXTEND_SIZE constant
  170. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  171. Revision 1.24 2002/04/19 15:39:34 peter
  172. * removed some more routines from cga
  173. * moved location_force_reg/mem to ncgutil
  174. * moved arrayconstructnode secondpass to ncgld
  175. Revision 1.23 2002/04/15 19:44:20 peter
  176. * fixed stackcheck that would be called recursively when a stack
  177. error was found
  178. * generic changeregsize(reg,size) for i386 register resizing
  179. * removed some more routines from cga unit
  180. * fixed returnvalue handling
  181. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  182. Revision 1.22 2002/04/14 20:54:17 carl
  183. + stack checking enabled for all targets (it is simulated now)
  184. Revision 1.21 2002/04/04 19:06:08 peter
  185. * removed unused units
  186. * use tlocation.size in cg.a_*loc*() routines
  187. Revision 1.20 2002/04/04 18:30:22 carl
  188. + added wdosx support (patch from Pavel)
  189. Revision 1.19 2002/04/02 17:11:33 peter
  190. * tlocation,treference update
  191. * LOC_CONSTANT added for better constant handling
  192. * secondadd splitted in multiple routines
  193. * location_force_reg added for loading a location to a register
  194. of a specified size
  195. * secondassignment parses now first the right and then the left node
  196. (this is compatible with Kylix). This saves a lot of push/pop especially
  197. with string operations
  198. * adapted some routines to use the new cg methods
  199. Revision 1.18 2002/03/31 20:26:37 jonas
  200. + a_loadfpu_* and a_loadmm_* methods in tcg
  201. * register allocation is now handled by a class and is mostly processor
  202. independent (+rgobj.pas and i386/rgcpu.pas)
  203. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  204. * some small improvements and fixes to the optimizer
  205. * some register allocation fixes
  206. * some fpuvaroffset fixes in the unary minus node
  207. * push/popusedregisters is now called rg.save/restoreusedregisters and
  208. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  209. also better optimizable)
  210. * fixed and optimized register saving/restoring for new/dispose nodes
  211. * LOC_FPU locations now also require their "register" field to be set to
  212. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  213. - list field removed of the tnode class because it's not used currently
  214. and can cause hard-to-find bugs
  215. Revision 1.17 2002/03/28 16:07:52 armin
  216. + initialize threadvars defined local in units
  217. Revision 1.16 2002/03/04 19:10:12 peter
  218. * removed compiler warnings
  219. Revision 1.15 2002/01/24 18:25:53 peter
  220. * implicit result variable generation for assembler routines
  221. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  222. Revision 1.14 2002/01/19 14:21:17 peter
  223. * fixed init/final for value parameters
  224. Revision 1.13 2001/12/30 17:24:45 jonas
  225. * range checking is now processor independent (part in cgobj,
  226. part in cg64f32) and should work correctly again (it needed
  227. some changes after the changes of the low and high of
  228. tordef's to int64)
  229. * maketojumpbool() is now processor independent (in ncgutil)
  230. * getregister32 is now called getregisterint
  231. Revision 1.12 2001/12/29 15:28:58 jonas
  232. * powerpc/cgcpu.pas compiles :)
  233. * several powerpc-related fixes
  234. * cpuasm unit is now based on common tainst unit
  235. + nppcmat unit for powerpc (almost complete)
  236. Revision 1.11 2001/11/18 18:59:59 peter
  237. * changed aktprocsym to aktprocdef for stabs generation
  238. Revision 1.10 2001/11/06 16:39:02 jonas
  239. * moved call to "cleanup_regvars" to cga.pas for i386 because it has
  240. to insert "fstp %st0" instructions after the exit label
  241. Revision 1.9 2001/11/02 22:58:09 peter
  242. * procsym definition rewrite
  243. Revision 1.8 2001/10/25 21:22:41 peter
  244. * calling convention rewrite
  245. Revision 1.7 2001/10/20 17:22:57 peter
  246. * concatcopy could release a wrong reference because the offset was
  247. increased without restoring the original before the release of
  248. a temp
  249. Revision 1.6 2001/10/14 11:49:51 jonas
  250. * finetuned register allocation info for assignments
  251. Revision 1.5 2001/09/30 21:28:34 peter
  252. * int64->boolean fixed
  253. Revision 1.4 2001/08/30 20:13:57 peter
  254. * rtti/init table updates
  255. * rttisym for reusable global rtti/init info
  256. * support published for interfaces
  257. Revision 1.3 2001/08/29 12:01:47 jonas
  258. + support for int64 LOC_REGISTERS in remove_non_regvars_from_loc
  259. Revision 1.2 2001/08/26 13:36:52 florian
  260. * some cg reorganisation
  261. * some PPC updates
  262. Revision 1.29 2001/08/12 20:23:02 peter
  263. * netbsd doesn't use stackchecking
  264. Revision 1.28 2001/08/07 18:47:13 peter
  265. * merged netbsd start
  266. * profile for win32
  267. Revision 1.27 2001/08/06 21:40:49 peter
  268. * funcret moved from tprocinfo to tprocdef
  269. Revision 1.26 2001/07/30 20:59:28 peter
  270. * m68k updates from v10 merged
  271. Revision 1.25 2001/07/01 20:16:18 peter
  272. * alignmentinfo record added
  273. * -Oa argument supports more alignment settings that can be specified
  274. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  275. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  276. required alignment and the maximum usefull alignment. The final
  277. alignment will be choosen per variable size dependent on these
  278. settings
  279. Revision 1.24 2001/05/27 14:30:55 florian
  280. + some widestring stuff added
  281. Revision 1.23 2001/04/21 13:33:16 peter
  282. * move winstackpagesize const to cgai386 to remove uses t_win32
  283. Revision 1.22 2001/04/21 12:05:32 peter
  284. * add nop after popa (merged)
  285. Revision 1.21 2001/04/18 22:02:00 peter
  286. * registration of targets and assemblers
  287. Revision 1.20 2001/04/13 01:22:17 peter
  288. * symtable change to classes
  289. * range check generation and errors fixed, make cycle DEBUG=1 works
  290. * memory leaks fixed
  291. Revision 1.19 2001/04/05 21:33:07 peter
  292. * fast exit fix merged
  293. Revision 1.18 2001/04/02 21:20:35 peter
  294. * resulttype rewrite
  295. Revision 1.17 2001/01/05 17:36:58 florian
  296. * the info about exception frames is stored now on the stack
  297. instead on the heap
  298. Revision 1.16 2000/12/25 00:07:31 peter
  299. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  300. tlinkedlist objects)
  301. Revision 1.15 2000/12/05 11:44:32 jonas
  302. + new integer regvar handling, should be much more efficient
  303. Revision 1.14 2000/11/29 00:30:43 florian
  304. * unused units removed from uses clause
  305. * some changes for widestrings
  306. Revision 1.13 2000/11/28 00:28:07 pierre
  307. * stabs fixing
  308. Revision 1.12 2000/11/22 15:12:06 jonas
  309. * fixed inline-related problems (partially "merges")
  310. Revision 1.11 2000/11/17 10:30:24 florian
  311. * passing interfaces as parameters fixed
  312. Revision 1.10 2000/11/07 23:40:48 florian
  313. + AfterConstruction and BeforeDestruction impemented
  314. Revision 1.9 2000/11/06 23:49:20 florian
  315. * fixed init_paras call
  316. Revision 1.8 2000/11/06 23:15:01 peter
  317. * added copyvaluepara call again
  318. Revision 1.7 2000/11/04 14:25:23 florian
  319. + merged Attila's changes for interfaces, not tested yet
  320. Revision 1.6 2000/10/31 22:02:55 peter
  321. * symtable splitted, no real code changes
  322. Revision 1.5 2000/10/24 22:23:04 peter
  323. * emitcall -> emitinsertcall for profiling (merged)
  324. Revision 1.4 2000/10/24 12:47:45 jonas
  325. * allocate registers which hold function result
  326. Revision 1.3 2000/10/24 08:54:25 michael
  327. + Extra patch from peter
  328. Revision 1.2 2000/10/24 07:20:03 pierre
  329. * fix for bug 1193 (merged)
  330. Revision 1.1 2000/10/15 09:47:42 peter
  331. * moved to i386/
  332. Revision 1.19 2000/10/14 10:14:46 peter
  333. * moehrendorf oct 2000 rewrite
  334. Revision 1.18 2000/10/10 14:55:28 jonas
  335. * added missing regallocs for edi in emit_mov_ref_reg64 (merged)
  336. Revision 1.17 2000/10/01 19:48:23 peter
  337. * lot of compile updates for cg11
  338. Revision 1.16 2000/09/30 16:08:45 peter
  339. * more cg11 updates
  340. Revision 1.15 2000/09/24 15:06:12 peter
  341. * use defines.inc
  342. Revision 1.14 2000/09/16 12:22:52 peter
  343. * freebsd support merged
  344. Revision 1.13 2000/08/27 16:11:49 peter
  345. * moved some util functions from globals,cobjects to cutils
  346. * splitted files into finput,fmodule
  347. Revision 1.12 2000/08/24 19:07:54 peter
  348. * don't initialize if localvarsym is set because that varsym will
  349. already be initialized
  350. * first initialize local data before copy of value para's (merged)
  351. Revision 1.11 2000/08/19 20:09:33 peter
  352. * check size after checking openarray in push_value_para (merged)
  353. Revision 1.10 2000/08/16 13:06:06 florian
  354. + support of 64 bit integer constants
  355. Revision 1.9 2000/08/10 18:42:03 peter
  356. * fixed for constants in emit_push_mem_size for go32v2 (merged)
  357. Revision 1.8 2000/08/07 11:29:40 jonas
  358. + emit_push_mem_size() which pushes a value in memory of a certain size
  359. * pushsetelement() and pushvaluepara() use this new procedure, because
  360. otherwise they could sometimes try to push data past the end of the
  361. heap, causing a crash
  362. (merged from fixes branch)
  363. Revision 1.7 2000/08/03 13:17:25 jonas
  364. + allow regvars to be used inside inlined procs, which required the
  365. following changes:
  366. + load regvars in genentrycode/free them in genexitcode (cgai386)
  367. * moved all regvar related code to new regvars unit
  368. + added pregvarinfo type to hcodegen
  369. + added regvarinfo field to tprocinfo (symdef/symdefh)
  370. * deallocate the regvars of the caller in secondprocinline before
  371. inlining the called procedure and reallocate them afterwards
  372. Revision 1.6 2000/08/02 08:05:04 jonas
  373. * fixed web bug1087
  374. * allocate R_ECX explicitely if it's used
  375. (merged from fixes branch)
  376. Revision 1.5 2000/07/27 09:25:05 jonas
  377. * moved locflags2reg() procedure from cg386add to cgai386
  378. + added locjump2reg() procedure to cgai386
  379. * fixed internalerror(2002) when the result of a case expression has
  380. LOC_JUMP
  381. (all merged from fixes branch)
  382. Revision 1.4 2000/07/21 15:14:02 jonas
  383. + added is_addr field for labels, if they are only used for getting the address
  384. (e.g. for io checks) and corresponding getaddrlabel() procedure
  385. Revision 1.3 2000/07/13 12:08:25 michael
  386. + patched to 1.1.0 with former 1.09patch from peter
  387. Revision 1.2 2000/07/13 11:32:37 michael
  388. + removed logs
  389. }