n386mem.pas 11 KB

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