n386mem.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  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. cg.a_loadaddr_ref_reg(exprasmlist,location.reference,location.reference.index);
  89. rg.ungetregisterint(exprasmlist,location.reference.base);
  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.54 2003-09-03 15:55:01 peter
  120. * NEWRA branch merged
  121. Revision 1.53.2.2 2003/08/31 15:46:26 peter
  122. * more updates for tregister
  123. Revision 1.53.2.1 2003/08/29 17:29:00 peter
  124. * next batch of updates
  125. Revision 1.53 2003/06/01 21:38:06 peter
  126. * getregisterfpu size parameter added
  127. * op_const_reg size parameter added
  128. * sparc updates
  129. Revision 1.52 2003/04/22 14:33:38 peter
  130. * removed some notes/hints
  131. Revision 1.51 2003/03/28 19:16:57 peter
  132. * generic constructor working for i386
  133. * remove fixed self register
  134. * esi added as address register for i386
  135. Revision 1.50 2003/02/19 22:00:15 daniel
  136. * Code generator converted to new register notation
  137. - Horribily outdated todo.txt removed
  138. Revision 1.49 2003/01/13 18:37:44 daniel
  139. * Work on register conversion
  140. Revision 1.48 2003/01/08 18:43:57 daniel
  141. * Tregister changed into a record
  142. Revision 1.47 2002/12/03 22:14:12 carl
  143. + use FPC_CHECKPOINTER once again
  144. Revision 1.46 2002/11/25 17:43:27 peter
  145. * splitted defbase in defutil,symutil,defcmp
  146. * merged isconvertable and is_equal into compare_defs(_ext)
  147. * made operator search faster by walking the list only once
  148. Revision 1.45 2002/11/23 22:50:09 carl
  149. * some small speed optimizations
  150. + added several new warnings/hints
  151. Revision 1.44 2002/09/07 15:25:11 peter
  152. * old logs removed and tabs fixed
  153. Revision 1.43 2002/09/01 19:27:35 peter
  154. * use index register when available for generating a reference with
  155. only a signle register. Using the base register could possibly
  156. destroy the framepointer
  157. Revision 1.42 2002/09/01 18:46:01 peter
  158. * fixed generic tcgvecnode
  159. * move code that updates a reference with index register and multiplier
  160. to separate method so it can be overriden for scaled indexing
  161. * i386 uses generic tcgvecnode
  162. Revision 1.41 2002/08/11 14:32:30 peter
  163. * renamed current_library to objectlibrary
  164. Revision 1.40 2002/08/11 13:24:17 peter
  165. * saving of asmsymbols in ppu supported
  166. * asmsymbollist global is removed and moved into a new class
  167. tasmlibrarydata that will hold the info of a .a file which
  168. corresponds with a single module. Added librarydata to tmodule
  169. to keep the library info stored for the module. In the future the
  170. objectfiles will also be stored to the tasmlibrarydata class
  171. * all getlabel/newasmsymbol and friends are moved to the new class
  172. Revision 1.39 2002/07/28 21:34:31 florian
  173. * more powerpc fixes
  174. + dummy tcgvecnode
  175. Revision 1.38 2002/07/20 11:58:04 florian
  176. * types.pas renamed to defbase.pas because D6 contains a types
  177. unit so this would conflicts if D6 programms are compiled
  178. + Willamette/SSE2 instructions to assembler added
  179. Revision 1.37 2002/07/11 14:41:33 florian
  180. * start of the new generic parameter handling
  181. Revision 1.36 2002/07/07 09:52:34 florian
  182. * powerpc target fixed, very simple units can be compiled
  183. * some basic stuff for better callparanode handling, far from being finished
  184. Revision 1.35 2002/07/01 18:46:33 peter
  185. * internal linker
  186. * reorganized aasm layer
  187. Revision 1.34 2002/06/24 12:43:01 jonas
  188. * fixed errors found with new -CR code from Peter when cycling with -O2p3r
  189. Revision 1.33 2002/05/18 13:34:25 peter
  190. * readded missing revisions
  191. Revision 1.32 2002/05/16 19:46:51 carl
  192. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  193. + try to fix temp allocation (still in ifdef)
  194. + generic constructor calls
  195. + start of tassembler / tmodulebase class cleanup
  196. Revision 1.30 2002/05/13 19:54:38 peter
  197. * removed n386ld and n386util units
  198. * maybe_save/maybe_restore added instead of the old maybe_push
  199. Revision 1.29 2002/05/12 16:53:17 peter
  200. * moved entry and exitcode to ncgutil and cgobj
  201. * foreach gets extra argument for passing local data to the
  202. iterator function
  203. * -CR checks also class typecasts at runtime by changing them
  204. into as
  205. * fixed compiler to cycle with the -CR option
  206. * fixed stabs with elf writer, finally the global variables can
  207. be watched
  208. * removed a lot of routines from cga unit and replaced them by
  209. calls to cgobj
  210. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  211. u32bit then the other is typecasted also to u32bit without giving
  212. a rangecheck warning/error.
  213. * fixed pascal calling method with reversing also the high tree in
  214. the parast, detected by tcalcst3 test
  215. Revision 1.28 2002/04/21 19:02:07 peter
  216. * removed newn and disposen nodes, the code is now directly
  217. inlined from pexpr
  218. * -an option that will write the secondpass nodes to the .s file, this
  219. requires EXTDEBUG define to actually write the info
  220. * fixed various internal errors and crashes due recent code changes
  221. Revision 1.27 2002/04/20 21:37:07 carl
  222. + generic FPC_CHECKPOINTER
  223. + first parameter offset in stack now portable
  224. * rename some constants
  225. + move some cpu stuff to other units
  226. - remove unused constents
  227. * fix stacksize for some targets
  228. * fix generic size problems which depend now on EXTEND_SIZE constant
  229. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  230. Revision 1.26 2002/04/19 15:39:35 peter
  231. * removed some more routines from cga
  232. * moved location_force_reg/mem to ncgutil
  233. * moved arrayconstructnode secondpass to ncgld
  234. Revision 1.25 2002/04/15 19:12:09 carl
  235. + target_info.size_of_pointer -> pointer_size
  236. + some cleanup of unused types/variables
  237. * move several constants from cpubase to their specific units
  238. (where they are used)
  239. + att_Reg2str -> gas_reg2str
  240. + int_reg2str -> std_reg2str
  241. Revision 1.24 2002/04/04 19:06:12 peter
  242. * removed unused units
  243. * use tlocation.size in cg.a_*loc*() routines
  244. Revision 1.23 2002/04/02 17:11:36 peter
  245. * tlocation,treference update
  246. * LOC_CONSTANT added for better constant handling
  247. * secondadd splitted in multiple routines
  248. * location_force_reg added for loading a location to a register
  249. of a specified size
  250. * secondassignment parses now first the right and then the left node
  251. (this is compatible with Kylix). This saves a lot of push/pop especially
  252. with string operations
  253. * adapted some routines to use the new cg methods
  254. }