n386mem.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate i386 assembler for in memory related 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 n386mem;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cginfo,cpuinfo,cpubase,
  23. node,nmem,ncgmem;
  24. type
  25. ti386addrnode = class(tcgaddrnode)
  26. procedure pass_2;override;
  27. end;
  28. ti386derefnode = class(tcgderefnode)
  29. procedure pass_2;override;
  30. end;
  31. ti386vecnode = class(tcgvecnode)
  32. procedure update_reference_reg_mul(reg:tregister;l:aword);override;
  33. procedure pass_2;override;
  34. end;
  35. implementation
  36. uses
  37. {$ifdef delphi}
  38. sysutils,
  39. {$endif}
  40. systems,
  41. cutils,verbose,
  42. symdef,paramgr,
  43. aasmtai,
  44. nld,ncon,nadd,
  45. cgobj,tgobj,rgobj;
  46. {*****************************************************************************
  47. TI386ADDRNODE
  48. *****************************************************************************}
  49. procedure ti386addrnode.pass_2;
  50. begin
  51. inherited pass_2;
  52. { for use of other segments }
  53. if left.location.reference.segment<>NR_NO then
  54. location.segment:=left.location.reference.segment;
  55. end;
  56. {*****************************************************************************
  57. TI386DEREFNODE
  58. *****************************************************************************}
  59. procedure ti386derefnode.pass_2;
  60. begin
  61. inherited pass_2;
  62. if tpointerdef(left.resulttype.def).is_far then
  63. location.reference.segment:=NR_FS;
  64. end;
  65. {*****************************************************************************
  66. TI386VECNODE
  67. *****************************************************************************}
  68. procedure ti386vecnode.update_reference_reg_mul(reg:tregister;l:aword);
  69. var
  70. l2 : integer;
  71. begin
  72. { Optimized for x86 to use the index register and scalefactor }
  73. if location.reference.index=NR_NO then
  74. begin
  75. { no preparations needed }
  76. end
  77. else if location.reference.base=NR_NO then
  78. begin
  79. case location.reference.scalefactor of
  80. 2 : cg.a_op_const_reg(exprasmlist,OP_SHL,OS_ADDR,1,location.reference.index);
  81. 4 : cg.a_op_const_reg(exprasmlist,OP_SHL,OS_ADDR,2,location.reference.index);
  82. 8 : cg.a_op_const_reg(exprasmlist,OP_SHL,OS_ADDR,3,location.reference.index);
  83. end;
  84. location.reference.base:=location.reference.index;
  85. end
  86. else
  87. begin
  88. rg.ungetregisterint(exprasmlist,location.reference.base);
  89. cg.a_loadaddr_ref_reg(exprasmlist,location.reference,location.reference.index);
  90. reference_reset_base(location.reference,location.reference.index,0);
  91. end;
  92. { insert the new index register and scalefactor or
  93. do the multiplication manual }
  94. case l of
  95. 1,2,4,8 : location.reference.scalefactor:=l;
  96. else
  97. begin
  98. if ispowerof2(l,l2) then
  99. cg.a_op_const_reg(exprasmlist,OP_SHL,OS_ADDR,l2,reg)
  100. else
  101. cg.a_op_const_reg(exprasmlist,OP_IMUL,OS_ADDR,l,reg);
  102. end;
  103. end;
  104. location.reference.index:=reg;
  105. end;
  106. procedure ti386vecnode.pass_2;
  107. begin
  108. inherited pass_2;
  109. if nf_memseg in flags then
  110. location.reference.segment:=NR_FS;
  111. end;
  112. begin
  113. caddrnode:=ti386addrnode;
  114. cderefnode:=ti386derefnode;
  115. cvecnode:=ti386vecnode;
  116. end.
  117. {
  118. $Log$
  119. Revision 1.55 2003-09-29 20:58:56 peter
  120. * optimized releasing of registers
  121. Revision 1.54 2003/09/03 15:55:01 peter
  122. * NEWRA branch merged
  123. Revision 1.53.2.2 2003/08/31 15:46:26 peter
  124. * more updates for tregister
  125. Revision 1.53.2.1 2003/08/29 17:29:00 peter
  126. * next batch of updates
  127. Revision 1.53 2003/06/01 21:38:06 peter
  128. * getregisterfpu size parameter added
  129. * op_const_reg size parameter added
  130. * sparc updates
  131. Revision 1.52 2003/04/22 14:33:38 peter
  132. * removed some notes/hints
  133. Revision 1.51 2003/03/28 19:16:57 peter
  134. * generic constructor working for i386
  135. * remove fixed self register
  136. * esi added as address register for i386
  137. Revision 1.50 2003/02/19 22:00:15 daniel
  138. * Code generator converted to new register notation
  139. - Horribily outdated todo.txt removed
  140. Revision 1.49 2003/01/13 18:37:44 daniel
  141. * Work on register conversion
  142. Revision 1.48 2003/01/08 18:43:57 daniel
  143. * Tregister changed into a record
  144. Revision 1.47 2002/12/03 22:14:12 carl
  145. + use FPC_CHECKPOINTER once again
  146. Revision 1.46 2002/11/25 17:43:27 peter
  147. * splitted defbase in defutil,symutil,defcmp
  148. * merged isconvertable and is_equal into compare_defs(_ext)
  149. * made operator search faster by walking the list only once
  150. Revision 1.45 2002/11/23 22:50:09 carl
  151. * some small speed optimizations
  152. + added several new warnings/hints
  153. Revision 1.44 2002/09/07 15:25:11 peter
  154. * old logs removed and tabs fixed
  155. Revision 1.43 2002/09/01 19:27:35 peter
  156. * use index register when available for generating a reference with
  157. only a signle register. Using the base register could possibly
  158. destroy the framepointer
  159. Revision 1.42 2002/09/01 18:46:01 peter
  160. * fixed generic tcgvecnode
  161. * move code that updates a reference with index register and multiplier
  162. to separate method so it can be overriden for scaled indexing
  163. * i386 uses generic tcgvecnode
  164. Revision 1.41 2002/08/11 14:32:30 peter
  165. * renamed current_library to objectlibrary
  166. Revision 1.40 2002/08/11 13:24:17 peter
  167. * saving of asmsymbols in ppu supported
  168. * asmsymbollist global is removed and moved into a new class
  169. tasmlibrarydata that will hold the info of a .a file which
  170. corresponds with a single module. Added librarydata to tmodule
  171. to keep the library info stored for the module. In the future the
  172. objectfiles will also be stored to the tasmlibrarydata class
  173. * all getlabel/newasmsymbol and friends are moved to the new class
  174. Revision 1.39 2002/07/28 21:34:31 florian
  175. * more powerpc fixes
  176. + dummy tcgvecnode
  177. Revision 1.38 2002/07/20 11:58:04 florian
  178. * types.pas renamed to defbase.pas because D6 contains a types
  179. unit so this would conflicts if D6 programms are compiled
  180. + Willamette/SSE2 instructions to assembler added
  181. Revision 1.37 2002/07/11 14:41:33 florian
  182. * start of the new generic parameter handling
  183. Revision 1.36 2002/07/07 09:52:34 florian
  184. * powerpc target fixed, very simple units can be compiled
  185. * some basic stuff for better callparanode handling, far from being finished
  186. Revision 1.35 2002/07/01 18:46:33 peter
  187. * internal linker
  188. * reorganized aasm layer
  189. Revision 1.34 2002/06/24 12:43:01 jonas
  190. * fixed errors found with new -CR code from Peter when cycling with -O2p3r
  191. Revision 1.33 2002/05/18 13:34:25 peter
  192. * readded missing revisions
  193. Revision 1.32 2002/05/16 19:46:51 carl
  194. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  195. + try to fix temp allocation (still in ifdef)
  196. + generic constructor calls
  197. + start of tassembler / tmodulebase class cleanup
  198. Revision 1.30 2002/05/13 19:54:38 peter
  199. * removed n386ld and n386util units
  200. * maybe_save/maybe_restore added instead of the old maybe_push
  201. Revision 1.29 2002/05/12 16:53:17 peter
  202. * moved entry and exitcode to ncgutil and cgobj
  203. * foreach gets extra argument for passing local data to the
  204. iterator function
  205. * -CR checks also class typecasts at runtime by changing them
  206. into as
  207. * fixed compiler to cycle with the -CR option
  208. * fixed stabs with elf writer, finally the global variables can
  209. be watched
  210. * removed a lot of routines from cga unit and replaced them by
  211. calls to cgobj
  212. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  213. u32bit then the other is typecasted also to u32bit without giving
  214. a rangecheck warning/error.
  215. * fixed pascal calling method with reversing also the high tree in
  216. the parast, detected by tcalcst3 test
  217. Revision 1.28 2002/04/21 19:02:07 peter
  218. * removed newn and disposen nodes, the code is now directly
  219. inlined from pexpr
  220. * -an option that will write the secondpass nodes to the .s file, this
  221. requires EXTDEBUG define to actually write the info
  222. * fixed various internal errors and crashes due recent code changes
  223. Revision 1.27 2002/04/20 21:37:07 carl
  224. + generic FPC_CHECKPOINTER
  225. + first parameter offset in stack now portable
  226. * rename some constants
  227. + move some cpu stuff to other units
  228. - remove unused constents
  229. * fix stacksize for some targets
  230. * fix generic size problems which depend now on EXTEND_SIZE constant
  231. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  232. Revision 1.26 2002/04/19 15:39:35 peter
  233. * removed some more routines from cga
  234. * moved location_force_reg/mem to ncgutil
  235. * moved arrayconstructnode secondpass to ncgld
  236. Revision 1.25 2002/04/15 19:12:09 carl
  237. + target_info.size_of_pointer -> pointer_size
  238. + some cleanup of unused types/variables
  239. * move several constants from cpubase to their specific units
  240. (where they are used)
  241. + att_Reg2str -> gas_reg2str
  242. + int_reg2str -> std_reg2str
  243. Revision 1.24 2002/04/04 19:06:12 peter
  244. * removed unused units
  245. * use tlocation.size in cg.a_*loc*() routines
  246. Revision 1.23 2002/04/02 17:11:36 peter
  247. * tlocation,treference update
  248. * LOC_CONSTANT added for better constant handling
  249. * secondadd splitted in multiple routines
  250. * location_force_reg added for loading a location to a register
  251. of a specified size
  252. * secondassignment parses now first the right and then the left node
  253. (this is compatible with Kylix). This saves a lot of push/pop especially
  254. with string operations
  255. * adapted some routines to use the new cg methods
  256. }