cgcpu.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit implements the code generator for the 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 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 cgcpu;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,
  23. cgbase,cgobj,cg64f32,cgx86,
  24. aasmbase,aasmtai,aasmcpu,
  25. cpubase,cpuinfo,parabase,cgutils,
  26. node,symconst
  27. ;
  28. type
  29. tcg386 = class(tcgx86)
  30. procedure init_register_allocators;override;
  31. { passing parameter using push instead of mov }
  32. procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);override;
  33. procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const cgpara : tcgpara);override;
  34. procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const cgpara : tcgpara);override;
  35. procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const cgpara : tcgpara);override;
  36. procedure g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);override;
  37. procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;const lenloc:tlocation;elesize:aint;destreg:tregister);override;
  38. procedure g_exception_reason_save(list : taasmoutput; const href : treference);override;
  39. procedure g_exception_reason_save_const(list : taasmoutput; const href : treference; a: aint);override;
  40. procedure g_exception_reason_load(list : taasmoutput; const href : treference);override;
  41. end;
  42. tcg64f386 = class(tcg64f32)
  43. procedure a_op64_ref_reg(list : taasmoutput;op:TOpCG;const ref : treference;reg : tregister64);override;
  44. procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);override;
  45. procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);override;
  46. procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);override;
  47. private
  48. procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
  49. end;
  50. implementation
  51. uses
  52. globals,verbose,systems,cutils,
  53. paramgr,procinfo,
  54. rgcpu,rgx86,tgobj;
  55. procedure Tcg386.init_register_allocators;
  56. begin
  57. inherited init_register_allocators;
  58. if cs_create_pic in aktmoduleswitches then
  59. rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP,RS_EBX])
  60. else
  61. rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
  62. rg[R_MMXREGISTER]:=trgcpu.create(R_MMXREGISTER,R_SUBNONE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
  63. rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
  64. rgfpu:=Trgx86fpu.create;
  65. end;
  66. procedure tcg386.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);
  67. var
  68. pushsize : tcgsize;
  69. begin
  70. check_register_size(size,r);
  71. with cgpara do
  72. if assigned(location) and
  73. (location^.loc=LOC_REFERENCE) and
  74. (location^.reference.index=NR_STACK_POINTER_REG) then
  75. begin
  76. pushsize:=int_cgsize(alignment);
  77. list.concat(taicpu.op_reg(A_PUSH,tcgsize2opsize[pushsize],makeregsize(list,r,pushsize)));
  78. end
  79. else
  80. inherited a_param_reg(list,size,r,cgpara);
  81. end;
  82. procedure tcg386.a_param_const(list : taasmoutput;size : tcgsize;a : aint;const cgpara : tcgpara);
  83. var
  84. pushsize : tcgsize;
  85. begin
  86. with cgpara do
  87. if assigned(location) and
  88. (location^.loc=LOC_REFERENCE) and
  89. (location^.reference.index=NR_STACK_POINTER_REG) then
  90. begin
  91. pushsize:=int_cgsize(alignment);
  92. list.concat(taicpu.op_const(A_PUSH,tcgsize2opsize[pushsize],a));
  93. end
  94. else
  95. inherited a_param_const(list,size,a,cgpara);
  96. end;
  97. procedure tcg386.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const cgpara : tcgpara);
  98. var
  99. pushsize : tcgsize;
  100. tmpreg : tregister;
  101. begin
  102. with cgpara do
  103. if assigned(location) and
  104. (location^.loc=LOC_REFERENCE) and
  105. (location^.reference.index=NR_STACK_POINTER_REG) then
  106. begin
  107. pushsize:=int_cgsize(alignment);
  108. if tcgsize2size[size]<alignment then
  109. begin
  110. tmpreg:=getintregister(list,pushsize);
  111. a_load_ref_reg(list,size,pushsize,r,tmpreg);
  112. list.concat(taicpu.op_reg(A_PUSH,TCgsize2opsize[pushsize],tmpreg));
  113. end
  114. else
  115. list.concat(taicpu.op_ref(A_PUSH,TCgsize2opsize[pushsize],r));
  116. end
  117. else
  118. inherited a_param_ref(list,size,r,cgpara);
  119. end;
  120. procedure tcg386.a_paramaddr_ref(list : taasmoutput;const r : treference;const cgpara : tcgpara);
  121. var
  122. tmpreg : tregister;
  123. opsize : topsize;
  124. begin
  125. with r do
  126. begin
  127. if (segment<>NR_NO) then
  128. cgmessage(cg_e_cant_use_far_pointer_there);
  129. with cgpara do
  130. if assigned(location) and
  131. (location^.loc=LOC_REFERENCE) and
  132. (location^.reference.index=NR_STACK_POINTER_REG) then
  133. begin
  134. opsize:=tcgsize2opsize[OS_ADDR];
  135. if (base=NR_NO) and (index=NR_NO) then
  136. begin
  137. if assigned(symbol) then
  138. list.concat(Taicpu.Op_sym_ofs(A_PUSH,opsize,symbol,offset))
  139. else
  140. list.concat(Taicpu.Op_const(A_PUSH,opsize,offset));
  141. end
  142. else if (base=NR_NO) and (index<>NR_NO) and
  143. (offset=0) and (scalefactor=0) and (symbol=nil) then
  144. list.concat(Taicpu.Op_reg(A_PUSH,opsize,index))
  145. else if (base<>NR_NO) and (index=NR_NO) and
  146. (offset=0) and (symbol=nil) then
  147. list.concat(Taicpu.Op_reg(A_PUSH,opsize,base))
  148. else
  149. begin
  150. tmpreg:=getaddressregister(list);
  151. a_loadaddr_ref_reg(list,r,tmpreg);
  152. list.concat(taicpu.op_reg(A_PUSH,opsize,tmpreg));
  153. end;
  154. end
  155. else
  156. inherited a_paramaddr_ref(list,r,cgpara);
  157. end;
  158. end;
  159. procedure tcg386.g_proc_exit(list : taasmoutput;parasize:longint;nostackframe:boolean);
  160. var
  161. stacksize : longint;
  162. begin
  163. { Release PIC register }
  164. if cs_create_pic in aktmoduleswitches then
  165. list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
  166. { MMX needs to call EMMS }
  167. if assigned(rg[R_MMXREGISTER]) and
  168. (rg[R_MMXREGISTER].uses_registers) then
  169. list.concat(Taicpu.op_none(A_EMMS,S_NO));
  170. { remove stackframe }
  171. if not nostackframe then
  172. begin
  173. if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
  174. begin
  175. stacksize:=current_procinfo.calc_stackframe_size;
  176. if (stacksize<>0) then
  177. cg.a_op_const_reg(list,OP_ADD,OS_ADDR,stacksize,current_procinfo.framepointer);
  178. end
  179. else
  180. list.concat(Taicpu.op_none(A_LEAVE,S_NO));
  181. list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil));
  182. end;
  183. { return from proc }
  184. if (po_interrupt in current_procinfo.procdef.procoptions) then
  185. begin
  186. if (current_procinfo.procdef.funcretloc[calleeside].loc<>LOC_VOID) and
  187. (current_procinfo.procdef.funcretloc[calleeside].loc=LOC_REGISTER) then
  188. list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
  189. else
  190. list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EAX));
  191. list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EBX));
  192. list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ECX));
  193. if (current_procinfo.procdef.funcretloc[calleeside].loc=LOC_REGISTER) and
  194. (current_procinfo.procdef.funcretloc[calleeside].size in [OS_64,OS_S64]) then
  195. list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
  196. else
  197. list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDX));
  198. list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ESI));
  199. list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDI));
  200. { .... also the segment registers }
  201. list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DS));
  202. list.concat(Taicpu.Op_reg(A_POP,S_W,NR_ES));
  203. list.concat(Taicpu.Op_reg(A_POP,S_W,NR_FS));
  204. list.concat(Taicpu.Op_reg(A_POP,S_W,NR_GS));
  205. { this restores the flags }
  206. list.concat(Taicpu.Op_none(A_IRET,S_NO));
  207. end
  208. { Routines with the poclearstack flag set use only a ret }
  209. else if current_procinfo.procdef.proccalloption in clearstack_pocalls then
  210. begin
  211. { complex return values are removed from stack in C code PM }
  212. if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,
  213. current_procinfo.procdef.proccalloption) then
  214. list.concat(Taicpu.Op_const(A_RET,S_NO,sizeof(aint)))
  215. else
  216. list.concat(Taicpu.Op_none(A_RET,S_NO));
  217. end
  218. { ... also routines with parasize=0 }
  219. else if (parasize=0) then
  220. list.concat(Taicpu.Op_none(A_RET,S_NO))
  221. else
  222. begin
  223. { parameters are limited to 65535 bytes because ret allows only imm16 }
  224. if (parasize>65535) then
  225. CGMessage(cg_e_parasize_too_big);
  226. list.concat(Taicpu.Op_const(A_RET,S_NO,parasize));
  227. end;
  228. end;
  229. procedure tcg386.g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;const lenloc:tlocation;elesize:aint;destreg:tregister);
  230. var
  231. power,len : longint;
  232. opsize : topsize;
  233. {$ifndef __NOWINPECOFF__}
  234. again,ok : tasmlabel;
  235. {$endif}
  236. begin
  237. { get stack space }
  238. getcpuregister(list,NR_EDI);
  239. a_load_loc_reg(list,OS_INT,lenloc,NR_EDI);
  240. list.concat(Taicpu.op_reg(A_INC,S_L,NR_EDI));
  241. if (elesize<>1) then
  242. begin
  243. if ispowerof2(elesize, power) then
  244. list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_EDI))
  245. else
  246. list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,NR_EDI));
  247. end;
  248. {$ifndef __NOWINPECOFF__}
  249. { windows guards only a few pages for stack growing, }
  250. { so we have to access every page first }
  251. if target_info.system=system_i386_win32 then
  252. begin
  253. objectlibrary.getlabel(again);
  254. objectlibrary.getlabel(ok);
  255. a_label(list,again);
  256. list.concat(Taicpu.op_const_reg(A_CMP,S_L,winstackpagesize,NR_EDI));
  257. a_jmp_cond(list,OC_B,ok);
  258. list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,NR_ESP));
  259. list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EDI));
  260. list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize,NR_EDI));
  261. a_jmp_always(list,again);
  262. a_label(list,ok);
  263. list.concat(Taicpu.op_reg_reg(A_SUB,S_L,NR_EDI,NR_ESP));
  264. ungetcpuregister(list,NR_EDI);
  265. { now reload EDI }
  266. getcpuregister(list,NR_EDI);
  267. a_load_loc_reg(list,OS_INT,lenloc,NR_EDI);
  268. list.concat(Taicpu.op_reg(A_INC,S_L,NR_EDI));
  269. if (elesize<>1) then
  270. begin
  271. if ispowerof2(elesize, power) then
  272. list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_EDI))
  273. else
  274. list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,NR_EDI));
  275. end;
  276. end
  277. else
  278. {$endif __NOWINPECOFF__}
  279. list.concat(Taicpu.op_reg_reg(A_SUB,S_L,NR_EDI,NR_ESP));
  280. { align stack on 4 bytes }
  281. list.concat(Taicpu.op_const_reg(A_AND,S_L,aint($fffffff4),NR_ESP));
  282. { load destination, don't use a_load_reg_reg, that will add a move instruction
  283. that can confuse the reg allocator }
  284. list.concat(Taicpu.Op_reg_reg(A_MOV,S_L,NR_ESP,NR_EDI));
  285. { Allocate other registers }
  286. getcpuregister(list,NR_ECX);
  287. getcpuregister(list,NR_ESI);
  288. { load count }
  289. a_load_loc_reg(list,OS_INT,lenloc,NR_ECX);
  290. { load source }
  291. a_loadaddr_ref_reg(list,ref,NR_ESI);
  292. { scheduled .... }
  293. list.concat(Taicpu.op_reg(A_INC,S_L,NR_ECX));
  294. { calculate size }
  295. len:=elesize;
  296. opsize:=S_B;
  297. if (len and 3)=0 then
  298. begin
  299. opsize:=S_L;
  300. len:=len shr 2;
  301. end
  302. else
  303. if (len and 1)=0 then
  304. begin
  305. opsize:=S_W;
  306. len:=len shr 1;
  307. end;
  308. if len<>0 then
  309. begin
  310. if ispowerof2(len, power) then
  311. list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_ECX))
  312. else
  313. list.concat(Taicpu.op_const_reg(A_IMUL,S_L,len,NR_ECX));
  314. end;
  315. list.concat(Taicpu.op_none(A_REP,S_NO));
  316. case opsize of
  317. S_B : list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
  318. S_W : list.concat(Taicpu.Op_none(A_MOVSW,S_NO));
  319. S_L : list.concat(Taicpu.Op_none(A_MOVSD,S_NO));
  320. end;
  321. ungetcpuregister(list,NR_EDI);
  322. ungetcpuregister(list,NR_ECX);
  323. ungetcpuregister(list,NR_ESI);
  324. { patch the new address, but don't use a_load_reg_reg, that will add a move instruction
  325. that can confuse the reg allocator }
  326. list.concat(Taicpu.Op_reg_reg(A_MOV,S_L,NR_ESP,destreg));
  327. end;
  328. procedure tcg386.g_exception_reason_save(list : taasmoutput; const href : treference);
  329. begin
  330. list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_INT],NR_FUNCTION_RESULT_REG));
  331. end;
  332. procedure tcg386.g_exception_reason_save_const(list : taasmoutput;const href : treference; a: aint);
  333. begin
  334. list.concat(Taicpu.op_const(A_PUSH,tcgsize2opsize[OS_INT],a));
  335. end;
  336. procedure tcg386.g_exception_reason_load(list : taasmoutput; const href : treference);
  337. begin
  338. list.concat(Taicpu.op_reg(A_POP,tcgsize2opsize[OS_INT],NR_FUNCTION_RESULT_REG));
  339. end;
  340. { ************* 64bit operations ************ }
  341. procedure tcg64f386.get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
  342. begin
  343. case op of
  344. OP_ADD :
  345. begin
  346. op1:=A_ADD;
  347. op2:=A_ADC;
  348. end;
  349. OP_SUB :
  350. begin
  351. op1:=A_SUB;
  352. op2:=A_SBB;
  353. end;
  354. OP_XOR :
  355. begin
  356. op1:=A_XOR;
  357. op2:=A_XOR;
  358. end;
  359. OP_OR :
  360. begin
  361. op1:=A_OR;
  362. op2:=A_OR;
  363. end;
  364. OP_AND :
  365. begin
  366. op1:=A_AND;
  367. op2:=A_AND;
  368. end;
  369. else
  370. internalerror(200203241);
  371. end;
  372. end;
  373. procedure tcg64f386.a_op64_ref_reg(list : taasmoutput;op:TOpCG;const ref : treference;reg : tregister64);
  374. var
  375. op1,op2 : TAsmOp;
  376. tempref : treference;
  377. begin
  378. get_64bit_ops(op,op1,op2);
  379. list.concat(taicpu.op_ref_reg(op1,S_L,ref,reg.reglo));
  380. tempref:=ref;
  381. inc(tempref.offset,4);
  382. list.concat(taicpu.op_ref_reg(op2,S_L,tempref,reg.reghi));
  383. end;
  384. procedure tcg64f386.a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);
  385. var
  386. op1,op2 : TAsmOp;
  387. begin
  388. case op of
  389. OP_NEG :
  390. begin
  391. if (regsrc.reglo<>regdst.reglo) then
  392. a_load64_reg_reg(list,regsrc,regdst);
  393. list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reghi));
  394. list.concat(taicpu.op_reg(A_NEG,S_L,regdst.reglo));
  395. list.concat(taicpu.op_const_reg(A_SBB,S_L,-1,regdst.reghi));
  396. exit;
  397. end;
  398. OP_NOT :
  399. begin
  400. if (regsrc.reglo<>regdst.reglo) then
  401. a_load64_reg_reg(list,regsrc,regdst);
  402. list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reghi));
  403. list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reglo));
  404. exit;
  405. end;
  406. end;
  407. get_64bit_ops(op,op1,op2);
  408. list.concat(taicpu.op_reg_reg(op1,S_L,regsrc.reglo,regdst.reglo));
  409. list.concat(taicpu.op_reg_reg(op2,S_L,regsrc.reghi,regdst.reghi));
  410. end;
  411. procedure tcg64f386.a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);
  412. var
  413. op1,op2 : TAsmOp;
  414. begin
  415. case op of
  416. OP_AND,OP_OR,OP_XOR:
  417. begin
  418. cg.a_op_const_reg(list,op,OS_32,aint(lo(value)),reg.reglo);
  419. cg.a_op_const_reg(list,op,OS_32,aint(hi(value)),reg.reghi);
  420. end;
  421. OP_ADD, OP_SUB:
  422. begin
  423. // can't use a_op_const_ref because this may use dec/inc
  424. get_64bit_ops(op,op1,op2);
  425. list.concat(taicpu.op_const_reg(op1,S_L,aint(lo(value)),reg.reglo));
  426. list.concat(taicpu.op_const_reg(op2,S_L,aint(hi(value)),reg.reghi));
  427. end;
  428. else
  429. internalerror(200204021);
  430. end;
  431. end;
  432. procedure tcg64f386.a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);
  433. var
  434. op1,op2 : TAsmOp;
  435. tempref : treference;
  436. begin
  437. case op of
  438. OP_AND,OP_OR,OP_XOR:
  439. begin
  440. cg.a_op_const_ref(list,op,OS_32,lo(value),ref);
  441. tempref:=ref;
  442. inc(tempref.offset,4);
  443. cg.a_op_const_ref(list,op,OS_32,hi(value),tempref);
  444. end;
  445. OP_ADD, OP_SUB:
  446. begin
  447. get_64bit_ops(op,op1,op2);
  448. // can't use a_op_const_ref because this may use dec/inc
  449. list.concat(taicpu.op_const_ref(op1,S_L,lo(value),ref));
  450. tempref:=ref;
  451. inc(tempref.offset,4);
  452. list.concat(taicpu.op_const_ref(op2,S_L,hi(value),tempref));
  453. end;
  454. else
  455. internalerror(200204022);
  456. end;
  457. end;
  458. begin
  459. cg := tcg386.create;
  460. cg64 := tcg64f386.create;
  461. end.
  462. {
  463. $Log$
  464. Revision 1.62 2004-11-21 17:54:59 peter
  465. * ttempcreatenode.create_reg merged into .create with parameter
  466. whether a register is allowed
  467. * funcret_paraloc renamed to funcretloc
  468. Revision 1.61 2004/11/21 17:17:04 florian
  469. * changed funcret location back to tlocation
  470. Revision 1.60 2004/10/31 21:45:03 peter
  471. * generic tlocation
  472. * move tlocation to cgutils
  473. Revision 1.59 2004/10/24 20:01:08 peter
  474. * remove saveregister calling convention
  475. Revision 1.58 2004/10/24 11:44:28 peter
  476. * small regvar fixes
  477. * loadref parameter removed from concatcopy,incrrefcount,etc
  478. Revision 1.57 2004/10/15 09:16:21 mazen
  479. - remove $IFDEF DELPHI and related code
  480. - remove $IFDEF FPCPROCVAR and related code
  481. Revision 1.56 2004/10/13 21:12:51 peter
  482. * -Or fixes for open array
  483. Revision 1.55 2004/10/11 15:46:45 peter
  484. * length parameter for copyvaluearray changed to tlocation
  485. Revision 1.54 2004/10/05 20:41:01 peter
  486. * more spilling rewrites
  487. Revision 1.53 2004/09/25 14:23:54 peter
  488. * ungetregister is now only used for cpuregisters, renamed to
  489. ungetcpuregister
  490. * renamed (get|unget)explicitregister(s) to ..cpuregister
  491. * removed location-release/reference_release
  492. Revision 1.52 2004/09/21 17:25:12 peter
  493. * paraloc branch merged
  494. Revision 1.51.4.1 2004/08/31 20:43:06 peter
  495. * paraloc patch
  496. Revision 1.51 2004/07/09 23:30:13 jonas
  497. * changed first_sse_imreg to first_mm_imreg
  498. Revision 1.50 2004/06/20 08:55:31 florian
  499. * logs truncated
  500. Revision 1.49 2004/06/16 20:07:10 florian
  501. * dwarf branch merged
  502. Revision 1.48 2004/04/09 14:36:05 peter
  503. * A_MOVSL renamed to A_MOVSD
  504. Revision 1.47.2.9 2004/05/30 10:45:50 peter
  505. * merged fixes from main branch
  506. Revision 1.47.2.8 2004/05/02 21:34:01 florian
  507. * i386 compilation fixed
  508. Revision 1.47.2.7 2004/05/02 12:45:32 peter
  509. * enabled cpuhasfixedstack for x86-64 again
  510. * fixed size of temp allocation for parameters
  511. }