n386mem.pas 10.0 KB

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