n386mem.pas 12 KB

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