n386mem.pas 11 KB

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