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