n386mem.pas 9.9 KB

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