n386mem.pas 11 KB

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