n386cal.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate i386 assembler for in call 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 n386cal;
  19. {$i fpcdefs.inc}
  20. interface
  21. { $define AnsiStrRef}
  22. uses
  23. ncgcal;
  24. type
  25. ti386callnode = class(tcgcallnode)
  26. protected
  27. function align_parasize:longint;override;
  28. procedure pop_parasize(pop_size:longint);override;
  29. procedure extra_interrupt_code;override;
  30. end;
  31. implementation
  32. uses
  33. globtype,systems,
  34. cutils,verbose,globals,
  35. symconst,symbase,symdef,symsym,symtable,defutil,
  36. {$ifdef GDB}
  37. {$ifdef delphi}
  38. sysutils,
  39. {$else}
  40. strings,
  41. {$endif}
  42. gdb,
  43. {$endif GDB}
  44. cgbase,pass_2,
  45. cpubase,paramgr,procinfo,
  46. aasmbase,aasmtai,aasmcpu,
  47. node,ncal,nbas,nmem,nld,ncnv,
  48. ncgutil,cga,cgobj,tgobj,rgobj,cpuinfo;
  49. {*****************************************************************************
  50. TI386CALLNODE
  51. *****************************************************************************}
  52. procedure ti386callnode.extra_interrupt_code;
  53. begin
  54. emit_none(A_PUSHF,S_L);
  55. emit_reg(A_PUSH,S_L,NR_CS);
  56. end;
  57. function ti386callnode.align_parasize:longint;
  58. var
  59. pop_size : longint;
  60. {$ifdef OPTALIGN}
  61. pop_esp : boolean;
  62. push_size : longint;
  63. {$endif OPTALIGN}
  64. i : integer;
  65. begin
  66. pop_size:=0;
  67. { This parasize aligned on 4 ? }
  68. i:=pushedparasize and 3;
  69. if i>0 then
  70. inc(pop_size,4-i);
  71. { insert the opcode and update pushedparasize }
  72. { never push 4 or more !! }
  73. pop_size:=pop_size mod 4;
  74. if pop_size>0 then
  75. begin
  76. inc(pushedparasize,pop_size);
  77. exprasmlist.concat(taicpu.op_const_reg(A_SUB,S_L,pop_size,NR_ESP));
  78. {$ifdef GDB}
  79. if (cs_debuginfo in aktmoduleswitches) and
  80. (exprasmList.first=exprasmList.last) then
  81. exprasmList.concat(Tai_force_line.Create);
  82. {$endif GDB}
  83. end;
  84. {$ifdef OPTALIGN}
  85. if pop_allowed and (cs_align in aktglobalswitches) then
  86. begin
  87. pop_esp:=true;
  88. push_size:=pushedparasize;
  89. { !!!! here we have to take care of return type, self
  90. and nested procedures
  91. }
  92. inc(push_size,12);
  93. emit_reg_reg(A_MOV,S_L,rsp,R_EDI);
  94. if (push_size mod 8)=0 then
  95. emit_const_reg(A_AND,S_L,$fffffff8,rsp)
  96. else
  97. begin
  98. emit_const_reg(A_SUB,S_L,push_size,rsp);
  99. emit_const_reg(A_AND,S_L,$fffffff8,rsp);
  100. emit_const_reg(A_SUB,S_L,push_size,rsp);
  101. end;
  102. r.enum:=R_INTREGISTER;
  103. r.number:=R_EDI;
  104. emit_reg(A_PUSH,S_L,r);
  105. end
  106. else
  107. pop_esp:=false;
  108. {$endif OPTALIGN}
  109. align_parasize:=pop_size;
  110. end;
  111. procedure ti386callnode.pop_parasize(pop_size:longint);
  112. var
  113. hreg : tregister;
  114. begin
  115. { better than an add on all processors }
  116. if pop_size=4 then
  117. begin
  118. hreg:=rg.getregisterint(exprasmlist,OS_INT);
  119. exprasmlist.concat(taicpu.op_reg(A_POP,S_L,hreg));
  120. rg.ungetregisterint(exprasmlist,hreg);
  121. end
  122. { the pentium has two pipes and pop reg is pairable }
  123. { but the registers must be different! }
  124. else
  125. if (pop_size=8) and
  126. not(cs_littlesize in aktglobalswitches) and
  127. (aktoptprocessor=ClassP5) then
  128. begin
  129. hreg:=rg.getregisterint(exprasmlist,OS_INT);
  130. exprasmlist.concat(taicpu.op_reg(A_POP,S_L,hreg));
  131. rg.ungetregisterint(exprasmlist,hreg);
  132. hreg:=rg.getregisterint(exprasmlist,OS_INT);
  133. exprasmlist.concat(taicpu.op_reg(A_POP,S_L,hreg));
  134. rg.ungetregisterint(exprasmlist,hreg);
  135. end
  136. else
  137. if pop_size<>0 then
  138. exprasmlist.concat(taicpu.op_const_reg(A_ADD,S_L,pop_size,NR_ESP));
  139. {$ifdef OPTALIGN}
  140. if pop_esp then
  141. emit_reg(A_POP,S_L,NR_ESP);
  142. {$endif OPTALIGN}
  143. end;
  144. begin
  145. ccallnode:=ti386callnode;
  146. end.
  147. {
  148. $Log$
  149. Revision 1.96 2003-10-01 20:34:49 peter
  150. * procinfo unit contains tprocinfo
  151. * cginfo renamed to cgbase
  152. * moved cgmessage to verbose
  153. * fixed ppc and sparc compiles
  154. Revision 1.95 2003/09/23 17:56:06 peter
  155. * locals and paras are allocated in the code generation
  156. * tvarsym.localloc contains the location of para/local when
  157. generating code for the current procedure
  158. Revision 1.94 2003/09/03 15:55:01 peter
  159. * NEWRA branch merged
  160. Revision 1.93.2.1 2003/08/29 17:29:00 peter
  161. * next batch of updates
  162. Revision 1.93 2003/05/30 23:57:08 peter
  163. * more sparc cleanup
  164. * accumulator removed, splitted in function_return_reg (called) and
  165. function_result_reg (caller)
  166. Revision 1.92 2003/05/26 21:17:18 peter
  167. * procinlinenode removed
  168. * aktexit2label removed, fast exit removed
  169. + tcallnode.inlined_pass_2 added
  170. Revision 1.91 2003/05/22 21:32:29 peter
  171. * removed some unit dependencies
  172. Revision 1.90 2003/04/23 14:42:08 daniel
  173. * Further register allocator work. Compiler now smaller with new
  174. allocator than without.
  175. * Somebody forgot to adjust ppu version number
  176. Revision 1.89 2003/04/22 14:33:38 peter
  177. * removed some notes/hints
  178. Revision 1.88 2003/04/22 10:09:35 daniel
  179. + Implemented the actual register allocator
  180. + Scratch registers unavailable when new register allocator used
  181. + maybe_save/maybe_restore unavailable when new register allocator used
  182. Revision 1.87 2003/04/04 15:38:56 peter
  183. * moved generic code from n386cal to ncgcal, i386 now also
  184. uses the generic ncgcal
  185. Revision 1.86 2003/03/30 20:59:07 peter
  186. * fix classmethod from classmethod call
  187. * move BeforeDestruction/AfterConstruction calls to
  188. genentrycode/genexitcode instead of generating them on the fly
  189. after a call to a constructor
  190. Revision 1.85 2003/03/28 19:16:57 peter
  191. * generic constructor working for i386
  192. * remove fixed self register
  193. * esi added as address register for i386
  194. Revision 1.84 2003/03/13 19:52:23 jonas
  195. * and more new register allocator fixes (in the i386 code generator this
  196. time). At least now the ppc cross compiler can compile the linux
  197. system unit again, but I haven't tested it.
  198. Revision 1.83 2003/03/06 11:35:50 daniel
  199. * Fixed internalerror 7843 issue
  200. Revision 1.82 2003/02/19 22:00:15 daniel
  201. * Code generator converted to new register notation
  202. - Horribily outdated todo.txt removed
  203. Revision 1.81 2003/01/30 21:46:57 peter
  204. * self fixes for static methods (merged)
  205. Revision 1.80 2003/01/13 18:37:44 daniel
  206. * Work on register conversion
  207. Revision 1.79 2003/01/08 18:43:57 daniel
  208. * Tregister changed into a record
  209. Revision 1.78 2002/12/15 21:30:12 florian
  210. * tcallnode.paraitem introduced, all references to defcoll removed
  211. Revision 1.77 2002/11/27 20:05:06 peter
  212. * cdecl array of const fixes
  213. Revision 1.76 2002/11/25 17:43:26 peter
  214. * splitted defbase in defutil,symutil,defcmp
  215. * merged isconvertable and is_equal into compare_defs(_ext)
  216. * made operator search faster by walking the list only once
  217. Revision 1.75 2002/11/18 17:32:00 peter
  218. * pass proccalloption to ret_in_xxx and push_xxx functions
  219. Revision 1.74 2002/11/15 01:58:57 peter
  220. * merged changes from 1.0.7 up to 04-11
  221. - -V option for generating bug report tracing
  222. - more tracing for option parsing
  223. - errors for cdecl and high()
  224. - win32 import stabs
  225. - win32 records<=8 are returned in eax:edx (turned off by default)
  226. - heaptrc update
  227. - more info for temp management in .s file with EXTDEBUG
  228. Revision 1.73 2002/10/05 12:43:29 carl
  229. * fixes for Delphi 6 compilation
  230. (warning : Some features do not work under Delphi)
  231. Revision 1.72 2002/09/17 18:54:03 jonas
  232. * a_load_reg_reg() now has two size parameters: source and dest. This
  233. allows some optimizations on architectures that don't encode the
  234. register size in the register name.
  235. Revision 1.71 2002/09/16 19:07:37 peter
  236. * push 0 instead of VMT when calling a constructor from a member
  237. Revision 1.70 2002/09/07 15:25:10 peter
  238. * old logs removed and tabs fixed
  239. Revision 1.69 2002/09/01 18:43:27 peter
  240. * include FUNCTION_RETURN_REG in regs_to_push list
  241. Revision 1.68 2002/09/01 12:13:00 peter
  242. * use a_call_reg
  243. * ungetiftemp for procvar of object temp
  244. Revision 1.67 2002/08/25 19:25:21 peter
  245. * sym.insert_in_data removed
  246. * symtable.insertvardata/insertconstdata added
  247. * removed insert_in_data call from symtable.insert, it needs to be
  248. called separatly. This allows to deref the address calculation
  249. * procedures now calculate the parast addresses after the procedure
  250. directives are parsed. This fixes the cdecl parast problem
  251. * push_addr_param has an extra argument that specifies if cdecl is used
  252. or not
  253. Revision 1.66 2002/08/23 16:14:49 peter
  254. * tempgen cleanup
  255. * tt_noreuse temp type added that will be used in genentrycode
  256. Revision 1.65 2002/08/18 20:06:30 peter
  257. * inlining is now also allowed in interface
  258. * renamed write/load to ppuwrite/ppuload
  259. * tnode storing in ppu
  260. * nld,ncon,nbas are already updated for storing in ppu
  261. Revision 1.64 2002/08/17 09:23:45 florian
  262. * first part of procinfo rewrite
  263. Revision 1.63 2002/08/12 15:08:42 carl
  264. + stab register indexes for powerpc (moved from gdb to cpubase)
  265. + tprocessor enumeration moved to cpuinfo
  266. + linker in target_info is now a class
  267. * many many updates for m68k (will soon start to compile)
  268. - removed some ifdef or correct them for correct cpu
  269. Revision 1.62 2002/08/11 14:32:30 peter
  270. * renamed current_library to objectlibrary
  271. Revision 1.61 2002/08/11 13:24:16 peter
  272. * saving of asmsymbols in ppu supported
  273. * asmsymbollist global is removed and moved into a new class
  274. tasmlibrarydata that will hold the info of a .a file which
  275. corresponds with a single module. Added librarydata to tmodule
  276. to keep the library info stored for the module. In the future the
  277. objectfiles will also be stored to the tasmlibrarydata class
  278. * all getlabel/newasmsymbol and friends are moved to the new class
  279. Revision 1.60 2002/07/20 11:58:01 florian
  280. * types.pas renamed to defbase.pas because D6 contains a types
  281. unit so this would conflicts if D6 programms are compiled
  282. + Willamette/SSE2 instructions to assembler added
  283. Revision 1.59 2002/07/11 14:41:33 florian
  284. * start of the new generic parameter handling
  285. Revision 1.58 2002/07/07 09:52:34 florian
  286. * powerpc target fixed, very simple units can be compiled
  287. * some basic stuff for better callparanode handling, far from being finished
  288. Revision 1.57 2002/07/06 20:27:26 carl
  289. + generic set handling
  290. Revision 1.56 2002/07/01 18:46:31 peter
  291. * internal linker
  292. * reorganized aasm layer
  293. Revision 1.55 2002/07/01 16:23:56 peter
  294. * cg64 patch
  295. * basics for currency
  296. * asnode updates for class and interface (not finished)
  297. Revision 1.54 2002/05/20 13:30:40 carl
  298. * bugfix of hdisponen (base must be set, not index)
  299. * more portability fixes
  300. Revision 1.53 2002/05/18 13:34:23 peter
  301. * readded missing revisions
  302. Revision 1.52 2002/05/16 19:46:51 carl
  303. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  304. + try to fix temp allocation (still in ifdef)
  305. + generic constructor calls
  306. + start of tassembler / tmodulebase class cleanup
  307. Revision 1.50 2002/05/13 19:54:38 peter
  308. * removed n386ld and n386util units
  309. * maybe_save/maybe_restore added instead of the old maybe_push
  310. Revision 1.49 2002/05/12 16:53:17 peter
  311. * moved entry and exitcode to ncgutil and cgobj
  312. * foreach gets extra argument for passing local data to the
  313. iterator function
  314. * -CR checks also class typecasts at runtime by changing them
  315. into as
  316. * fixed compiler to cycle with the -CR option
  317. * fixed stabs with elf writer, finally the global variables can
  318. be watched
  319. * removed a lot of routines from cga unit and replaced them by
  320. calls to cgobj
  321. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  322. u32bit then the other is typecasted also to u32bit without giving
  323. a rangecheck warning/error.
  324. * fixed pascal calling method with reversing also the high tree in
  325. the parast, detected by tcalcst3 test
  326. }