cga.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. {*****************************************************************************}
  2. { File : cga.pas }
  3. { Author : Mazen NEIFER }
  4. { Project : Free Pascal Compiler (FPC) }
  5. { Creation date : 2002\26\26 }
  6. { Last modification date : 2002\07\13 }
  7. { Licence : GPL }
  8. { Bug report : [email protected] }
  9. {*****************************************************************************}
  10. {
  11. $Id$
  12. Copyright (c) 1998-2002 by Florian Klaempfl
  13. Helper routines for the i386 code generator
  14. This program is free software; you can redistribute it and/or modify
  15. it under the terms of the GNU General Public License as published by
  16. the Free Software Foundation; either version 2 of the License, or
  17. (at your option) any later version.
  18. This program is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. GNU General Public License for more details.
  22. You should have received a copy of the GNU General Public License
  23. along with this program; if not, write to the Free Software
  24. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25. ****************************************************************************
  26. }
  27. unit cga;
  28. {$i fpcdefs.inc}
  29. interface
  30. uses
  31. cpuinfo,cpubase,cginfo,
  32. symconst,symtype,symdef,aasmbase,aasmtai,aasmcpu;
  33. {$define TESTGETTEMP to store const that
  34. are written into temps for later release PM }
  35. function def_opsize(p1:tdef):topsize;
  36. function def_getreg(p1:tdef):tregister;
  37. procedure emitjmp(c : tasmcond;var l : tasmlabel);
  38. procedure emit_none(i : tasmop;s : topsize);
  39. procedure emit_const(i : tasmop;s : topsize;c : longint);
  40. procedure emit_reg(i : tasmop;s : topsize;reg : tregister);
  41. procedure emit_ref(i : tasmop;s : topsize;const ref : treference);
  42. procedure emit_const_reg(i : tasmop;s : topsize;c : longint;reg : tregister);
  43. procedure emit_const_ref(i : tasmop;s : topsize;c : longint;const ref : treference);
  44. procedure emit_ref_reg(i : tasmop;s : topsize;const ref : treference;reg : tregister);
  45. procedure emit_reg_ref(i : tasmop;s : topsize;reg : tregister;const ref : treference);
  46. procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
  47. procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
  48. procedure emit_reg_reg_reg(i : tasmop;s : topsize;reg1,reg2,reg3 : tregister);
  49. procedure emit_sym(i : tasmop;s : topsize;op : tasmsymbol);
  50. implementation
  51. uses
  52. cutils,
  53. systems,globals,verbose,
  54. cgbase,cgobj,tgobj,rgobj,rgcpu;
  55. {*****************************************************************************
  56. Helpers
  57. *****************************************************************************}
  58. function def_opsize(p1:tdef):topsize;
  59. begin
  60. case p1.size of
  61. 1 : def_opsize:=S_B;
  62. 2 : def_opsize:=S_W;
  63. 4 : def_opsize:=S_L;
  64. { I don't know if we need it (FK) }
  65. 8 : def_opsize:=S_L;
  66. else
  67. internalerror(130820001);
  68. end;
  69. end;
  70. function def_getreg(p1:tdef):tregister;
  71. begin
  72. def_getreg:=rg.makeregsize(rg.getregisterint(exprasmlist),int_cgsize(p1.size));
  73. end;
  74. {*****************************************************************************
  75. Emit Assembler
  76. *****************************************************************************}
  77. procedure emitjmp(c : tasmcond;var l : tasmlabel);
  78. var
  79. ai : taicpu;
  80. begin
  81. if c=C_None then
  82. ai := Taicpu.Op_sym(A_JMPL,S_NO,l)
  83. else
  84. begin
  85. ai:=Taicpu.Op_sym(A_JMPL,S_NO,l);
  86. ai.SetCondition(c);
  87. end;
  88. ai.is_jmp:=true;
  89. exprasmList.concat(ai);
  90. end;
  91. procedure emit_none(i : tasmop;s : topsize);
  92. begin
  93. exprasmList.concat(Taicpu.Op_none(i,s));
  94. end;
  95. procedure emit_reg(i : tasmop;s : topsize;reg : tregister);
  96. begin
  97. exprasmList.concat(Taicpu.Op_reg(i,s,reg));
  98. end;
  99. procedure emit_ref(i : tasmop;s : topsize;const ref : treference);
  100. begin
  101. exprasmList.concat(Taicpu.Op_ref(i,s,ref));
  102. end;
  103. procedure emit_const(i : tasmop;s : topsize;c : longint);
  104. begin
  105. exprasmList.concat(Taicpu.Op_const(i,s,aword(c)));
  106. end;
  107. procedure emit_const_reg(i : tasmop;s : topsize;c : longint;reg : tregister);
  108. begin
  109. exprasmList.concat(Taicpu.Op_const_reg(i,s,aword(c),reg));
  110. end;
  111. procedure emit_const_ref(i : tasmop;s : topsize;c : longint;const ref : treference);
  112. begin
  113. exprasmList.concat(Taicpu.Op_const_ref(i,s,aword(c),ref));
  114. end;
  115. procedure emit_ref_reg(i : tasmop;s : topsize;const ref : treference;reg : tregister);
  116. begin
  117. exprasmList.concat(Taicpu.Op_ref_reg(i,s,ref,reg));
  118. end;
  119. procedure emit_reg_ref(i : tasmop;s : topsize;reg : tregister;const ref : treference);
  120. begin
  121. exprasmList.concat(Taicpu.Op_reg_ref(i,s,reg,ref));
  122. end;
  123. PROCEDURE emit_reg_reg(i:tasmop;s:topsize;reg1,reg2:tregister);
  124. BEGIN
  125. IF reg1<>reg2
  126. THEN
  127. exprasmList.concat(Taicpu.Op_reg_reg(i,s,reg1,reg2));
  128. END;
  129. procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
  130. begin
  131. exprasmList.concat(Taicpu.Op_reg_const_reg(i,s,reg1,c,reg2));
  132. end;
  133. procedure emit_reg_reg_reg(i : tasmop;s : topsize;reg1,reg2,reg3 : tregister);
  134. begin
  135. exprasmList.concat(Taicpu.Op_reg_reg_reg(i,s,reg1,reg2,reg3));
  136. end;
  137. procedure emit_sym(i : tasmop;s : topsize;op : tasmsymbol);
  138. begin
  139. exprasmList.concat(Taicpu.Op_sym(i,s,op));
  140. end;
  141. end.
  142. {
  143. $Log$
  144. Revision 1.1 2002-08-22 08:30:50 mazen
  145. first insertion 2002\08\22
  146. Revision 1.32 2002/05/18 13:34:21 peter
  147. * readded missing revisions
  148. Revision 1.31 2002/05/16 19:46:50 carl
  149. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  150. + try to fix temp allocation (still in ifdef)
  151. + generic constructor calls
  152. + start of tassembler / tmodulebase class cleanup
  153. Revision 1.29 2002/05/13 19:54:37 peter
  154. * removed n386ld and n386util units
  155. * maybe_save/maybe_restore added instead of the old maybe_push
  156. Revision 1.28 2002/05/12 16:53:16 peter
  157. * moved entry and exitcode to ncgutil and cgobj
  158. * foreach gets extra argument for passing local data to the
  159. iterator function
  160. * -CR checks also class typecasts at runtime by changing them
  161. into as
  162. * fixed compiler to cycle with the -CR option
  163. * fixed stabs with elf writer, finally the global variables can
  164. be watched
  165. * removed a lot of routines from cga unit and replaced them by
  166. calls to cgobj
  167. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  168. u32bit then the other is typecasted also to u32bit without giving
  169. a rangecheck warning/error.
  170. * fixed pascal calling method with reversing also the high tree in
  171. the parast, detected by tcalcst3 test
  172. Revision 1.27 2002/04/25 20:16:39 peter
  173. * moved more routines from cga/n386util
  174. Revision 1.26 2002/04/21 15:29:53 carl
  175. * changeregsize -> rg.makeregsize
  176. Revision 1.25 2002/04/20 21:37:07 carl
  177. + generic FPC_CHECKPOINTER
  178. + first parameter offset in stack now portable
  179. * rename some constants
  180. + move some cpu stuff to other units
  181. - remove unused constents
  182. * fix stacksize for some targets
  183. * fix generic size problems which depend now on EXTEND_SIZE constant
  184. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  185. Revision 1.24 2002/04/19 15:39:34 peter
  186. * removed some more routines from cga
  187. * moved location_force_reg/mem to ncgutil
  188. * moved arrayconstructnode secondpass to ncgld
  189. Revision 1.23 2002/04/15 19:44:20 peter
  190. * fixed stackcheck that would be called recursively when a stack
  191. error was found
  192. * generic changeregsize(reg,size) for i386 register resizing
  193. * removed some more routines from cga unit
  194. * fixed returnvalue handling
  195. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  196. Revision 1.22 2002/04/14 20:54:17 carl
  197. + stack checking enabled for all targets (it is simulated now)
  198. Revision 1.21 2002/04/04 19:06:08 peter
  199. * removed unused units
  200. * use tlocation.size in cg.a_*loc*() routines
  201. Revision 1.20 2002/04/04 18:30:22 carl
  202. + added wdosx support (patch from Pavel)
  203. Revision 1.19 2002/04/02 17:11:33 peter
  204. * tlocation,treference update
  205. * LOC_CONSTANT added for better constant handling
  206. * secondadd splitted in multiple routines
  207. * location_force_reg added for loading a location to a register
  208. of a specified size
  209. * secondassignment parses now first the right and then the left node
  210. (this is compatible with Kylix). This saves a lot of push/pop especially
  211. with string operations
  212. * adapted some routines to use the new cg methods
  213. Revision 1.18 2002/03/31 20:26:37 jonas
  214. + a_loadfpu_* and a_loadmm_* methods in tcg
  215. * register allocation is now handled by a class and is mostly processor
  216. independent (+rgobj.pas and i386/rgcpu.pas)
  217. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  218. * some small improvements and fixes to the optimizer
  219. * some register allocation fixes
  220. * some fpuvaroffset fixes in the unary minus node
  221. * push/popusedregisters is now called rg.save/restoreusedregisters and
  222. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  223. also better optimizable)
  224. * fixed and optimized register saving/restoring for new/dispose nodes
  225. * LOC_FPU locations now also require their "register" field to be set to
  226. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  227. - list field removed of the tnode class because it's not used currently
  228. and can cause hard-to-find bugs
  229. Revision 1.17 2002/03/28 16:07:52 armin
  230. + initialize threadvars defined local in units
  231. Revision 1.16 2002/03/04 19:10:12 peter
  232. * removed compiler warnings
  233. Revision 1.15 2002/01/24 18:25:53 peter
  234. * implicit result variable generation for assembler routines
  235. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  236. Revision 1.14 2002/01/19 14:21:17 peter
  237. * fixed init/final for value parameters
  238. }