n386cal.pas 14 KB

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