n386mem.pas 11 KB

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