n386mem.pas 10 KB

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