cpupara.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. {
  2. $Id$
  3. Copyright (c) 2002 by Florian Klaempfl
  4. Generates the argument location information for i386
  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 bymethodpointer
  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. { Generates the argument location information for i386.
  19. }
  20. unit cpupara;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. cclasses,globtype,
  25. aasmtai,
  26. cpubase,
  27. cgbase,
  28. symconst,symtype,symdef,paramgr;
  29. type
  30. ti386paramanager = class(tparamanager)
  31. function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
  32. function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
  33. function get_para_align(calloption : tproccalloption):byte;override;
  34. function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
  35. function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
  36. function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
  37. { Returns the location for the nr-st 32 Bit int parameter
  38. if every parameter before is an 32 Bit int parameter as well
  39. and if the calling conventions for the helper routines of the
  40. rtl are used.
  41. }
  42. function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
  43. function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
  44. function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override;
  45. private
  46. procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
  47. function create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  48. function create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  49. end;
  50. implementation
  51. uses
  52. cutils,
  53. systems,verbose,
  54. defutil,
  55. cpuinfo;
  56. const
  57. parasupregs : array[0..2] of tsuperregister = (RS_EAX,RS_EDX,RS_ECX);
  58. {****************************************************************************
  59. TI386PARAMANAGER
  60. ****************************************************************************}
  61. function ti386paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
  62. begin
  63. case target_info.system of
  64. system_i386_win32 :
  65. begin
  66. case def.deftype of
  67. recorddef :
  68. begin
  69. { Win32 GCC returns small records in the FUNCTION_RETURN_REG.
  70. For stdcall we follow delphi instead of GCC }
  71. if (calloption in [pocall_cdecl,pocall_cppdecl]) and
  72. (def.size<=8) then
  73. begin
  74. result:=false;
  75. exit;
  76. end;
  77. end;
  78. end;
  79. end;
  80. end;
  81. result:=inherited ret_in_param(def,calloption);
  82. end;
  83. function ti386paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
  84. begin
  85. case target_info.system of
  86. system_i386_win32 :
  87. begin
  88. case def.deftype of
  89. recorddef :
  90. begin
  91. { Win32 passes small records on the stack for call by
  92. value }
  93. if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
  94. (varspez=vs_value) and
  95. (def.size<=8) then
  96. begin
  97. result:=false;
  98. exit;
  99. end;
  100. end;
  101. arraydef :
  102. begin
  103. { Win32 passes arrays on the stack for call by
  104. value }
  105. if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
  106. (varspez=vs_value) and
  107. (tarraydef(def).highrange>=tarraydef(def).lowrange) then
  108. begin
  109. result:=true;
  110. exit;
  111. end;
  112. end;
  113. end;
  114. end;
  115. end;
  116. result:=inherited push_addr_param(varspez,def,calloption);
  117. end;
  118. function ti386paramanager.get_para_align(calloption : tproccalloption):byte;
  119. begin
  120. if calloption=pocall_oldfpccall then
  121. begin
  122. if target_info.system in [system_i386_go32v2,system_i386_watcom] then
  123. result:=2
  124. else
  125. result:=4;
  126. end
  127. else
  128. result:=std_param_align;
  129. end;
  130. function ti386paramanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
  131. begin
  132. case calloption of
  133. pocall_internproc :
  134. result:=[];
  135. pocall_compilerproc :
  136. begin
  137. if pocall_default=pocall_oldfpccall then
  138. result:=[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI,RS_EBX]
  139. else
  140. result:=[RS_EAX,RS_EDX,RS_ECX];
  141. end;
  142. pocall_inline,
  143. pocall_register,
  144. pocall_safecall,
  145. pocall_stdcall,
  146. pocall_cdecl,
  147. pocall_cppdecl :
  148. result:=[RS_EAX,RS_EDX,RS_ECX];
  149. pocall_far16,
  150. pocall_pascal,
  151. pocall_oldfpccall :
  152. result:=[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI,RS_EBX];
  153. else
  154. internalerror(200309071);
  155. end;
  156. end;
  157. function ti386paramanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;
  158. begin
  159. result:=[0..first_fpu_imreg-1];
  160. end;
  161. function ti386paramanager.get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;
  162. begin
  163. result:=[0..first_sse_imreg-1];
  164. end;
  165. function ti386paramanager.getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;
  166. begin
  167. fillchar(result,sizeof(tparalocation),0);
  168. result.size:=OS_INT;
  169. if calloption=pocall_register then
  170. begin
  171. if (nr<=high(parasupregs)+1) then
  172. begin
  173. if nr=0 then
  174. internalerror(200309271);
  175. result.loc:=LOC_REGISTER;
  176. result.register:=newreg(R_INTREGISTER,parasupregs[nr-1],R_SUBWHOLE);
  177. end
  178. else
  179. begin
  180. result.loc:=LOC_REFERENCE;
  181. result.reference.index:=NR_STACK_POINTER_REG;
  182. result.reference.offset:=POINTER_SIZE*nr;
  183. end;
  184. end
  185. else
  186. begin
  187. result.loc:=LOC_REFERENCE;
  188. result.reference.index:=NR_STACK_POINTER_REG;
  189. result.reference.offset:=POINTER_SIZE*nr;
  190. end;
  191. end;
  192. procedure ti386paramanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
  193. var
  194. paraloc : tparalocation;
  195. begin
  196. { Function return }
  197. fillchar(paraloc,sizeof(tparalocation),0);
  198. paraloc.size:=def_cgsize(p.rettype.def);
  199. { Return in FPU register? }
  200. if p.rettype.def.deftype=floatdef then
  201. begin
  202. paraloc.loc:=LOC_FPUREGISTER;
  203. paraloc.register:=NR_FPU_RESULT_REG;
  204. end
  205. else
  206. { Return in register? }
  207. if not ret_in_param(p.rettype.def,p.proccalloption) then
  208. begin
  209. paraloc.loc:=LOC_REGISTER;
  210. {$ifndef cpu64bit}
  211. if paraloc.size in [OS_64,OS_S64] then
  212. begin
  213. paraloc.register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
  214. paraloc.register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
  215. end
  216. else
  217. {$endif cpu64bit}
  218. begin
  219. paraloc.register:=NR_FUNCTION_RETURN_REG;
  220. end;
  221. end
  222. else
  223. begin
  224. paraloc.loc:=LOC_REFERENCE;
  225. end;
  226. p.funcret_paraloc[side]:=paraloc;
  227. end;
  228. function ti386paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;
  229. var
  230. hp : tparaitem;
  231. paraloc : tparalocation;
  232. l,
  233. varalign,
  234. paraalign,
  235. parasize : longint;
  236. begin
  237. parasize:=0;
  238. paraalign:=get_para_align(p.proccalloption);
  239. { Retrieve last know info from normal parameters }
  240. hp:=tparaitem(p.para.last);
  241. if assigned(hp) then
  242. parasize:=hp.paraloc[callerside].reference.offset;
  243. { Assign varargs }
  244. hp:=tparaitem(varargspara.first);
  245. while assigned(hp) do
  246. begin
  247. paraloc.size:=def_cgsize(hp.paratype.def);
  248. paraloc.loc:=LOC_REFERENCE;
  249. paraloc.alignment:=paraalign;
  250. paraloc.reference.index:=NR_STACK_POINTER_REG;
  251. l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
  252. varalign:=size_2_align(l);
  253. paraloc.reference.offset:=parasize;
  254. varalign:=used_align(varalign,paraalign,paraalign);
  255. parasize:=align(parasize+l,varalign);
  256. hp.paraloc[callerside]:=paraloc;
  257. hp:=tparaitem(hp.next);
  258. end;
  259. { We need to return the size allocated }
  260. result:=parasize;
  261. end;
  262. function ti386paramanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  263. var
  264. hp : tparaitem;
  265. paraloc : tparalocation;
  266. l,
  267. varalign,
  268. paraalign,
  269. parasize : longint;
  270. begin
  271. parasize:=0;
  272. paraalign:=get_para_align(p.proccalloption);
  273. { we push Flags and CS as long
  274. to cope with the IRETD
  275. and we save 6 register + 4 selectors }
  276. if po_interrupt in p.procoptions then
  277. inc(parasize,8+6*4+4*2);
  278. { Offset is calculated like:
  279. sub esp,12
  280. mov [esp+8],para3
  281. mov [esp+4],para2
  282. mov [esp],para1
  283. call function
  284. That means the for pushes the para with the
  285. highest offset (see para3) needs to be pushed first
  286. }
  287. hp:=tparaitem(p.para.first);
  288. while assigned(hp) do
  289. begin
  290. if hp.paratyp in [vs_var,vs_out] then
  291. paraloc.size:=OS_ADDR
  292. else
  293. paraloc.size:=def_cgsize(hp.paratype.def);
  294. paraloc.loc:=LOC_REFERENCE;
  295. paraloc.alignment:=paraalign;
  296. if side=callerside then
  297. paraloc.reference.index:=NR_STACK_POINTER_REG
  298. else
  299. paraloc.reference.index:=NR_FRAME_POINTER_REG;
  300. l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
  301. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  302. paraloc.reference.offset:=parasize;
  303. parasize:=align(parasize+l,varalign);
  304. hp.paraloc[side]:=paraloc;
  305. hp:=tparaitem(hp.next);
  306. end;
  307. { Adapt offsets for left-to-right calling }
  308. if p.proccalloption in pushleftright_pocalls then
  309. begin
  310. hp:=tparaitem(p.para.first);
  311. while assigned(hp) do
  312. begin
  313. l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
  314. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  315. l:=align(l,varalign);
  316. hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
  317. if side=calleeside then
  318. inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
  319. hp:=tparaitem(hp.next);
  320. end;
  321. end
  322. else
  323. begin
  324. { Only need to adapt the callee side to include the
  325. standard stackframe size }
  326. if side=calleeside then
  327. begin
  328. hp:=tparaitem(p.para.first);
  329. while assigned(hp) do
  330. begin
  331. inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
  332. hp:=tparaitem(hp.next);
  333. end;
  334. end;
  335. end;
  336. { We need to return the size allocated }
  337. result:=parasize;
  338. end;
  339. function ti386paramanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  340. var
  341. hp : tparaitem;
  342. paraloc : tparalocation;
  343. subreg : tsubregister;
  344. pushaddr,
  345. is_64bit : boolean;
  346. l,parareg,
  347. varalign,
  348. paraalign,
  349. parasize : longint;
  350. begin
  351. parareg:=0;
  352. parasize:=0;
  353. paraalign:=get_para_align(p.proccalloption);
  354. { Register parameters are assigned from left to right }
  355. hp:=tparaitem(p.para.first);
  356. while assigned(hp) do
  357. begin
  358. pushaddr:=push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption);
  359. if pushaddr then
  360. paraloc.size:=OS_ADDR
  361. else
  362. paraloc.size:=def_cgsize(hp.paratype.def);
  363. paraloc.alignment:=paraalign;
  364. is_64bit:=(paraloc.size in [OS_64,OS_S64,OS_F64]);
  365. {
  366. EAX
  367. EDX
  368. ECX
  369. Stack
  370. Stack
  371. 64bit values,floats,arrays and records are always
  372. on the stack.
  373. }
  374. if (parareg<=high(parasupregs)) and
  375. not(
  376. is_64bit or
  377. ((hp.paratype.def.deftype in [floatdef,recorddef,arraydef]) and
  378. (not pushaddr))
  379. ) then
  380. begin
  381. paraloc.loc:=LOC_REGISTER;
  382. if (paraloc.size=OS_NO) or is_64bit then
  383. subreg:=R_SUBWHOLE
  384. else
  385. subreg:=cgsize2subreg(paraloc.size);
  386. paraloc.alignment:=paraalign;
  387. paraloc.register:=newreg(R_INTREGISTER,parasupregs[parareg],subreg);
  388. inc(parareg);
  389. end
  390. else
  391. begin
  392. paraloc.loc:=LOC_REFERENCE;
  393. if side=callerside then
  394. paraloc.reference.index:=NR_STACK_POINTER_REG
  395. else
  396. paraloc.reference.index:=NR_FRAME_POINTER_REG;
  397. l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
  398. varalign:=size_2_align(l);
  399. paraloc.reference.offset:=parasize;
  400. varalign:=used_align(varalign,paraalign,paraalign);
  401. parasize:=align(parasize+l,varalign);
  402. end;
  403. hp.paraloc[side]:=paraloc;
  404. hp:=tparaitem(hp.next);
  405. end;
  406. { Register parameters are assigned from left-to-right, adapt offset
  407. for calleeside to be reversed }
  408. hp:=tparaitem(p.para.first);
  409. while assigned(hp) do
  410. begin
  411. if (hp.paraloc[side].loc=LOC_REFERENCE) then
  412. begin
  413. l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
  414. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  415. l:=align(l,varalign);
  416. hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
  417. if side=calleeside then
  418. inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
  419. end;
  420. hp:=tparaitem(hp.next);
  421. end;
  422. { We need to return the size allocated }
  423. result:=parasize;
  424. end;
  425. function ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  426. begin
  427. result:=0;
  428. case p.proccalloption of
  429. pocall_register :
  430. result:=create_register_paraloc_info(p,side);
  431. pocall_inline,
  432. pocall_compilerproc,
  433. pocall_internproc :
  434. begin
  435. { Use default calling }
  436. if (pocall_default=pocall_register) then
  437. result:=create_register_paraloc_info(p,side)
  438. else
  439. result:=create_stdcall_paraloc_info(p,side);
  440. end;
  441. else
  442. result:=create_stdcall_paraloc_info(p,side);
  443. end;
  444. create_funcret_paraloc_info(p,side);
  445. end;
  446. begin
  447. paramanager:=ti386paramanager.create;
  448. end.
  449. {
  450. $Log$
  451. Revision 1.48 2003-12-28 22:09:12 florian
  452. + setting of bit 6 of cr for c var args on ppc implemented
  453. Revision 1.47 2003/12/03 23:13:20 peter
  454. * delayed paraloc allocation, a_param_*() gets extra parameter
  455. if it needs to allocate temp or real paralocation
  456. * optimized/simplified int-real loading
  457. Revision 1.46 2003/12/01 18:44:15 peter
  458. * fixed some crashes
  459. * fixed varargs and register calling probs
  460. Revision 1.45 2003/11/28 17:24:22 peter
  461. * reversed offset calculation for caller side so it works
  462. correctly for interfaces
  463. Revision 1.44 2003/11/23 17:05:16 peter
  464. * register calling is left-right
  465. * parameter ordering
  466. * left-right calling inserts result parameter last
  467. Revision 1.43 2003/11/11 21:11:23 peter
  468. * check for push_addr
  469. Revision 1.42 2003/10/19 01:34:30 florian
  470. * some ppc stuff fixed
  471. * memory leak fixed
  472. Revision 1.41 2003/10/17 14:38:32 peter
  473. * 64k registers supported
  474. * fixed some memory leaks
  475. Revision 1.40 2003/10/11 16:06:42 florian
  476. * fixed some MMX<->SSE
  477. * started to fix ppc, needs an overhaul
  478. + stabs info improve for spilling, not sure if it works correctly/completly
  479. - MMX_SUPPORT removed from Makefile.fpc
  480. Revision 1.39 2003/10/10 17:48:14 peter
  481. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  482. * tregisteralloctor renamed to trgobj
  483. * removed rgobj from a lot of units
  484. * moved location_* and reference_* to cgobj
  485. * first things for mmx register allocation
  486. Revision 1.38 2003/10/07 15:17:07 peter
  487. * inline supported again, LOC_REFERENCEs are used to pass the
  488. parameters
  489. * inlineparasymtable,inlinelocalsymtable removed
  490. * exitlabel inserting fixed
  491. Revision 1.37 2003/10/05 21:21:52 peter
  492. * c style array of const generates callparanodes
  493. * varargs paraloc fixes
  494. Revision 1.36 2003/10/03 22:00:33 peter
  495. * parameter alignment fixes
  496. Revision 1.35 2003/10/01 20:34:49 peter
  497. * procinfo unit contains tprocinfo
  498. * cginfo renamed to cgbase
  499. * moved cgmessage to verbose
  500. * fixed ppc and sparc compiles
  501. Revision 1.34 2003/09/30 21:02:37 peter
  502. * updates for inlining
  503. Revision 1.33 2003/09/28 17:55:04 peter
  504. * parent framepointer changed to hidden parameter
  505. * tloadparentfpnode added
  506. Revision 1.32 2003/09/28 13:35:24 peter
  507. * register calling updates
  508. Revision 1.31 2003/09/25 21:30:11 peter
  509. * parameter fixes
  510. Revision 1.30 2003/09/23 17:56:06 peter
  511. * locals and paras are allocated in the code generation
  512. * tvarsym.localloc contains the location of para/local when
  513. generating code for the current procedure
  514. Revision 1.29 2003/09/16 16:17:01 peter
  515. * varspez in calls to push_addr_param
  516. Revision 1.28 2003/09/10 08:31:47 marco
  517. * Patch from Peter for paraloc
  518. Revision 1.27 2003/09/09 21:03:17 peter
  519. * basics for x86 register calling
  520. Revision 1.26 2003/09/09 15:55:05 peter
  521. * winapi doesn't like pushing 8 byte record
  522. Revision 1.25 2003/09/08 18:28:51 peter
  523. * fix compilerproc for default=oldfpccall
  524. Revision 1.24 2003/09/07 22:09:35 peter
  525. * preparations for different default calling conventions
  526. * various RA fixes
  527. Revision 1.23 2003/09/03 15:55:01 peter
  528. * NEWRA branch merged
  529. Revision 1.22.2.2 2003/08/28 18:35:08 peter
  530. * tregister changed to cardinal
  531. Revision 1.22.2.1 2003/08/27 19:55:54 peter
  532. * first tregister patch
  533. Revision 1.22 2003/08/11 21:18:20 peter
  534. * start of sparc support for newra
  535. Revision 1.21 2003/07/05 20:11:41 jonas
  536. * create_paraloc_info() is now called separately for the caller and
  537. callee info
  538. * fixed ppc cycle
  539. Revision 1.20 2003/07/02 22:18:04 peter
  540. * paraloc splitted in callerparaloc,calleeparaloc
  541. * sparc calling convention updates
  542. Revision 1.19 2003/06/17 16:34:19 peter
  543. * freeintparaloc added
  544. Revision 1.18 2003/06/07 18:57:04 jonas
  545. + added freeintparaloc
  546. * ppc get/freeintparaloc now check whether the parameter regs are
  547. properly allocated/deallocated (and get an extra list para)
  548. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  549. * fixed lot of missing pi_do_call's
  550. Revision 1.17 2003/06/06 14:41:22 peter
  551. * needs cpuinfo
  552. Revision 1.16 2003/06/06 07:36:06 michael
  553. + Forgot a line in patch from peter
  554. Revision 1.15 2003/06/06 07:35:14 michael
  555. + Patch to Patch from peter
  556. Revision 1.14 2003/06/06 07:34:11 michael
  557. + Patch from peter
  558. Revision 1.13 2003/06/05 20:58:05 peter
  559. * updated
  560. Revision 1.12 2003/05/30 23:57:08 peter
  561. * more sparc cleanup
  562. * accumulator removed, splitted in function_return_reg (called) and
  563. function_result_reg (caller)
  564. Revision 1.11 2003/05/13 15:16:13 peter
  565. * removed ret_in_acc, it's the reverse of ret_in_param
  566. * fixed ret_in_param for win32 cdecl array
  567. Revision 1.10 2003/04/22 23:50:23 peter
  568. * firstpass uses expectloc
  569. * checks if there are differences between the expectloc and
  570. location.loc from secondpass in EXTDEBUG
  571. Revision 1.9 2003/04/22 14:33:38 peter
  572. * removed some notes/hints
  573. Revision 1.8 2003/01/08 18:43:57 daniel
  574. * Tregister changed into a record
  575. Revision 1.7 2002/12/24 15:56:50 peter
  576. * stackpointer_alloc added for adjusting ESP. Win32 needs
  577. this for the pageprotection
  578. Revision 1.6 2002/12/17 22:19:33 peter
  579. * fixed pushing of records>8 bytes with stdcall
  580. * simplified hightree loading
  581. Revision 1.5 2002/11/18 17:32:00 peter
  582. * pass proccalloption to ret_in_xxx and push_xxx functions
  583. Revision 1.4 2002/11/15 01:58:56 peter
  584. * merged changes from 1.0.7 up to 04-11
  585. - -V option for generating bug report tracing
  586. - more tracing for option parsing
  587. - errors for cdecl and high()
  588. - win32 import stabs
  589. - win32 records<=8 are returned in eax:edx (turned off by default)
  590. - heaptrc update
  591. - more info for temp management in .s file with EXTDEBUG
  592. Revision 1.3 2002/08/09 07:33:04 florian
  593. * a couple of interface related fixes
  594. Revision 1.2 2002/07/11 14:41:32 florian
  595. * start of the new generic parameter handling
  596. Revision 1.1 2002/07/07 09:52:33 florian
  597. * powerpc target fixed, very simple units can be compiled
  598. * some basic stuff for better callparanode handling, far from being finished
  599. }