n386mem.pas 12 KB

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