n386mem.pas 11 KB

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