n386mem.pas 9.8 KB

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