cpubase.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl and Peter Vreman
  4. Contains the base types for the i386 and x86-64 architecture
  5. * This code was inspired by the NASM sources
  6. The Netwide Assembler is Copyright (c) 1996 Simon Tatham and
  7. Julian Hall. All rights reserved.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. ****************************************************************************
  20. }
  21. {# Base unit for processor information. This unit contains
  22. enumerations of registers, opcodes, sizes, and other
  23. such things which are processor specific.
  24. }
  25. unit cpubase;
  26. {$i fpcdefs.inc}
  27. interface
  28. uses
  29. cutils,cclasses,
  30. globtype,globals,
  31. cpuinfo,
  32. aasmbase,
  33. cgbase
  34. {$ifdef delphi}
  35. ,dmisc
  36. {$endif}
  37. ;
  38. {*****************************************************************************
  39. Assembler Opcodes
  40. *****************************************************************************}
  41. type
  42. {$ifdef x86_64}
  43. TAsmOp={$i x86_64op.inc}
  44. {$else x86_64}
  45. TAsmOp={$i i386op.inc}
  46. {$endif x86_64}
  47. { This should define the array of instructions as string }
  48. op2strtable=array[tasmop] of string[11];
  49. const
  50. { First value of opcode enumeration }
  51. firstop = low(tasmop);
  52. { Last value of opcode enumeration }
  53. lastop = high(tasmop);
  54. {*****************************************************************************
  55. Registers
  56. *****************************************************************************}
  57. const
  58. { Invalid register number }
  59. RS_INVALID = $ff;
  60. { Integer Super registers }
  61. RS_RAX = $00; {EAX}
  62. RS_RCX = $01; {ECX}
  63. RS_RDX = $02; {EDX}
  64. RS_RBX = $03; {EBX}
  65. RS_RSI = $04; {ESI}
  66. RS_RDI = $05; {EDI}
  67. RS_RBP = $06; {EBP}
  68. RS_RSP = $07; {ESP}
  69. RS_R8 = $08; {R8}
  70. RS_R9 = $09; {R9}
  71. RS_R10 = $0a; {R10}
  72. RS_R11 = $0b; {R11}
  73. RS_R12 = $0c; {R12}
  74. RS_R13 = $0d; {R13}
  75. RS_R14 = $0e; {R14}
  76. RS_R15 = $0f; {R15}
  77. { create aliases to allow code sharing between x86-64 and i386 }
  78. RS_EAX = RS_RAX;
  79. RS_EBX = RS_RBX;
  80. RS_ECX = RS_RCX;
  81. RS_EDX = RS_RDX;
  82. RS_ESI = RS_RSI;
  83. RS_EDI = RS_RDI;
  84. RS_EBP = RS_RBP;
  85. RS_ESP = RS_RSP;
  86. { Number of first imaginary register }
  87. first_int_imreg = $10;
  88. { Float Super registers }
  89. RS_ST0 = $00;
  90. RS_ST1 = $01;
  91. RS_ST2 = $02;
  92. RS_ST3 = $03;
  93. RS_ST4 = $04;
  94. RS_ST5 = $05;
  95. RS_ST6 = $06;
  96. RS_ST7 = $07;
  97. { Number of first imaginary register }
  98. first_fpu_imreg = $08;
  99. { MM Super registers }
  100. RS_MM0 = $00;
  101. RS_MM1 = $01;
  102. RS_MM2 = $02;
  103. RS_MM3 = $03;
  104. RS_MM4 = $04;
  105. RS_MM5 = $05;
  106. RS_MM6 = $06;
  107. RS_MM7 = $07;
  108. RS_MM8 = $08;
  109. RS_MM9 = $09;
  110. RS_MM10 = $0a;
  111. RS_MM11 = $0b;
  112. RS_MM12 = $0c;
  113. RS_MM13 = $0d;
  114. RS_MM14 = $0e;
  115. RS_MM15 = $0f;
  116. { Number of first imaginary register }
  117. {$ifdef x86_64}
  118. first_sse_imreg = $10;
  119. {$else x86_64}
  120. first_sse_imreg = $08;
  121. {$endif x86_64}
  122. { The subregister that specifies the entire register }
  123. {$ifdef x86_64}
  124. R_SUBWHOLE = R_SUBQ; {Hammer}
  125. {$else x86_64}
  126. R_SUBWHOLE = R_SUBD; {i386}
  127. {$endif x86_64}
  128. { Available Registers }
  129. {$ifdef x86_64}
  130. {$i r8664con.inc}
  131. {$else x86_64}
  132. {$i r386con.inc}
  133. {$endif x86_64}
  134. type
  135. { Number of registers used for indexing in tables }
  136. {$ifdef x86_64}
  137. tregisterindex=0..{$i r8664nor.inc}-1;
  138. {$else x86_64}
  139. tregisterindex=0..{$i r386nor.inc}-1;
  140. {$endif x86_64}
  141. const
  142. {$warning TODO Calculate bsstart}
  143. regnumber_count_bsstart = 64;
  144. regnumber_table : array[tregisterindex] of tregister = (
  145. {$ifdef x86_64}
  146. {$i r8664num.inc}
  147. {$else x86_64}
  148. {$i r386num.inc}
  149. {$endif x86_64}
  150. );
  151. regstabs_table : array[tregisterindex] of tregister = (
  152. {$ifdef x86_64}
  153. {$i r8664stab.inc}
  154. {$else x86_64}
  155. {$i r386stab.inc}
  156. {$endif x86_64}
  157. );
  158. type
  159. totherregisterset = set of tregisterindex;
  160. {*****************************************************************************
  161. Conditions
  162. *****************************************************************************}
  163. type
  164. TAsmCond=(C_None,
  165. C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
  166. C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
  167. C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
  168. );
  169. const
  170. cond2str:array[TAsmCond] of string[3]=('',
  171. 'a','ae','b','be','c','e','g','ge','l','le','na','nae',
  172. 'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
  173. 'ns','nz','o','p','pe','po','s','z'
  174. );
  175. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  176. C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
  177. C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
  178. C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
  179. );
  180. {*****************************************************************************
  181. Flags
  182. *****************************************************************************}
  183. type
  184. TResFlags = (F_E,F_NE,F_G,F_L,F_GE,F_LE,F_C,F_NC,
  185. F_A,F_AE,F_B,F_BE,
  186. F_S,F_NS,F_O,F_NO);
  187. {*****************************************************************************
  188. Reference
  189. *****************************************************************************}
  190. type
  191. { reference record }
  192. preference = ^treference;
  193. treference = packed record
  194. segment,
  195. base,
  196. index : tregister;
  197. scalefactor : byte;
  198. offset : longint;
  199. symbol : tasmsymbol;
  200. end;
  201. { reference record }
  202. pparareference = ^tparareference;
  203. tparareference = packed record
  204. index : tregister;
  205. offset : longint;
  206. end;
  207. {*****************************************************************************
  208. Generic Location
  209. *****************************************************************************}
  210. type
  211. { tparamlocation describes where a parameter for a procedure is stored.
  212. References are given from the caller's point of view. The usual
  213. TLocation isn't used, because contains a lot of unnessary fields.
  214. }
  215. tparalocation = packed record
  216. size : TCGSize;
  217. loc : TCGLoc;
  218. alignment : byte;
  219. case TCGLoc of
  220. LOC_REFERENCE : (reference : tparareference);
  221. { segment in reference at the same place as in loc_register }
  222. LOC_REGISTER,LOC_CREGISTER : (
  223. case longint of
  224. 1 : (register,registerhigh : tregister);
  225. { overlay a registerlow }
  226. 2 : (registerlow : tregister);
  227. { overlay a 64 Bit register type }
  228. 3 : (reg64 : tregister64);
  229. 4 : (register64 : tregister64);
  230. );
  231. { it's only for better handling }
  232. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  233. end;
  234. tlocation = packed record
  235. loc : TCGLoc;
  236. size : TCGSize;
  237. case TCGLoc of
  238. LOC_FLAGS : (resflags : tresflags);
  239. LOC_CONSTANT : (
  240. case longint of
  241. 1 : (value : AWord);
  242. { can't do this, this layout depends on the host cpu. Use }
  243. { lo(valueqword)/hi(valueqword) instead (JM) }
  244. { 2 : (valuelow, valuehigh:AWord); }
  245. { overlay a complete 64 Bit value }
  246. 3 : (valueqword : qword);
  247. );
  248. LOC_CREFERENCE,
  249. LOC_REFERENCE : (reference : treference);
  250. { segment in reference at the same place as in loc_register }
  251. LOC_REGISTER,LOC_CREGISTER : (
  252. case longint of
  253. 1 : (register,registerhigh,segment : tregister);
  254. { overlay a registerlow }
  255. 2 : (registerlow : tregister);
  256. { overlay a 64 Bit register type }
  257. 3 : (reg64 : tregister64);
  258. 4 : (register64 : tregister64);
  259. );
  260. { it's only for better handling }
  261. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  262. end;
  263. {*****************************************************************************
  264. Constants
  265. *****************************************************************************}
  266. const
  267. { declare aliases }
  268. LOC_MMREGISTER = LOC_SSEREGISTER;
  269. LOC_CMMREGISTER = LOC_CSSEREGISTER;
  270. max_operands = 3;
  271. maxfpuregs = 8;
  272. (*
  273. { low and high of the available maximum width integer general purpose }
  274. { registers }
  275. LoGPReg = RS_EAX;
  276. HiGPReg = RS_EDX;
  277. { Table of registers which can be allocated by the code generator
  278. internally, when generating the code.
  279. }
  280. { legend: }
  281. { xxxregs = set of all possibly used registers of that type in the code }
  282. { generator }
  283. { usableregsxxx = set of all 32bit components of registers that can be }
  284. { possible allocated to a regvar or using getregisterxxx (this }
  285. { excludes registers which can be only used for parameter }
  286. { passing on ABI's that define this) }
  287. { c_countusableregsxxx = amount of registers in the usableregsxxx set }
  288. // maxintregs = 4;
  289. // intregs = [R_EAX..R_BL]-[R_ESI,R_SI];
  290. { to determine how many registers to use for regvars }
  291. maxintscratchregs = 1;
  292. maxfpuregs = 8;
  293. usableregsfpu = [];
  294. c_countusableregsfpu = 0;
  295. usableregsmm = [RS_MM0..RS_MM7];
  296. c_countusableregsmm = 8;
  297. *)
  298. {*****************************************************************************
  299. CPU Dependent Constants
  300. *****************************************************************************}
  301. {$i cpubase.inc}
  302. {*****************************************************************************
  303. Helpers
  304. *****************************************************************************}
  305. function cgsize2subreg(s:Tcgsize):Tsubregister;
  306. function reg2opsize(r:Tregister):topsize;
  307. function is_calljmp(o:tasmop):boolean;
  308. procedure inverse_flags(var f: TResFlags);
  309. function flags_to_cond(const f: TResFlags) : TAsmCond;
  310. function is_segment_reg(r:tregister):boolean;
  311. function findreg_by_number(r:Tregister):tregisterindex;
  312. function std_regnum_search(const s:string):Tregister;
  313. function std_regname(r:Tregister):string;
  314. implementation
  315. uses
  316. verbose;
  317. const
  318. {$ifdef x86_64}
  319. std_regname_table : array[tregisterindex] of string[7] = (
  320. {$i r8664std.inc}
  321. );
  322. regnumber_index : array[tregisterindex] of tregisterindex = (
  323. {$i r8664rni.inc}
  324. );
  325. std_regname_index : array[tregisterindex] of tregisterindex = (
  326. {$i r8664sri.inc}
  327. );
  328. {$else x86_64}
  329. std_regname_table : array[tregisterindex] of string[7] = (
  330. {$i r386std.inc}
  331. );
  332. regnumber_index : array[tregisterindex] of tregisterindex = (
  333. {$i r386rni.inc}
  334. );
  335. std_regname_index : array[tregisterindex] of tregisterindex = (
  336. {$i r386sri.inc}
  337. );
  338. {$endif x86_64}
  339. {*****************************************************************************
  340. Helpers
  341. *****************************************************************************}
  342. function cgsize2subreg(s:Tcgsize):Tsubregister;
  343. begin
  344. case s of
  345. OS_8,OS_S8:
  346. cgsize2subreg:=R_SUBL;
  347. OS_16,OS_S16:
  348. cgsize2subreg:=R_SUBW;
  349. OS_32,OS_S32:
  350. cgsize2subreg:=R_SUBD;
  351. OS_64,OS_S64:
  352. cgsize2subreg:=R_SUBQ;
  353. else
  354. internalerror(200301231);
  355. end;
  356. end;
  357. function reg2opsize(r:Tregister):topsize;
  358. const
  359. subreg2opsize : array[tsubregister] of topsize =
  360. (S_NO,S_B,S_B,S_W,S_L,S_D,S_NO);
  361. begin
  362. reg2opsize:=S_L;
  363. case getregtype(r) of
  364. R_INTREGISTER :
  365. reg2opsize:=subreg2opsize[getsubreg(r)];
  366. R_FPUREGISTER :
  367. reg2opsize:=S_FL;
  368. R_MMXREGISTER,
  369. R_MMREGISTER :
  370. reg2opsize:=S_D;
  371. R_SPECIALREGISTER :
  372. begin
  373. case r of
  374. NR_CS,NR_DS,NR_ES,
  375. NR_SS,NR_FS,NR_GS :
  376. reg2opsize:=S_W;
  377. end;
  378. end;
  379. else
  380. internalerror(200303181);
  381. end;
  382. end;
  383. function is_calljmp(o:tasmop):boolean;
  384. begin
  385. case o of
  386. A_CALL,
  387. A_JCXZ,
  388. A_JECXZ,
  389. A_JMP,
  390. A_LOOP,
  391. A_LOOPE,
  392. A_LOOPNE,
  393. A_LOOPNZ,
  394. A_LOOPZ,
  395. A_Jcc :
  396. is_calljmp:=true;
  397. else
  398. is_calljmp:=false;
  399. end;
  400. end;
  401. procedure inverse_flags(var f: TResFlags);
  402. const
  403. inv_flags: array[TResFlags] of TResFlags =
  404. (F_NE,F_E,F_LE,F_GE,F_L,F_G,F_NC,F_C,
  405. F_BE,F_B,F_AE,F_A,
  406. F_NS,F_S,F_NO,F_O);
  407. begin
  408. f:=inv_flags[f];
  409. end;
  410. function flags_to_cond(const f: TResFlags) : TAsmCond;
  411. const
  412. flags_2_cond : array[TResFlags] of TAsmCond =
  413. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE,C_S,C_NS,C_O,C_NO);
  414. begin
  415. result := flags_2_cond[f];
  416. end;
  417. function is_segment_reg(r:tregister):boolean;
  418. begin
  419. result:=false;
  420. case r of
  421. NR_CS,NR_DS,NR_ES,
  422. NR_SS,NR_FS,NR_GS :
  423. result:=true;
  424. end;
  425. end;
  426. function findreg_by_stdname(const s:string):byte;
  427. var
  428. i,p : tregisterindex;
  429. begin
  430. {Binary search.}
  431. p:=0;
  432. i:=regnumber_count_bsstart;
  433. repeat
  434. if (p+i<=high(tregisterindex)) and (std_regname_table[std_regname_index[p+i]]<=s) then
  435. p:=p+i;
  436. i:=i shr 1;
  437. until i=0;
  438. if std_regname_table[std_regname_index[p]]=s then
  439. result:=std_regname_index[p]
  440. else
  441. result:=0;
  442. end;
  443. function findreg_by_number(r:Tregister):tregisterindex;
  444. var
  445. i,p : tregisterindex;
  446. begin
  447. {Binary search.}
  448. p:=0;
  449. i:=regnumber_count_bsstart;
  450. repeat
  451. if (p+i<=high(tregisterindex)) and (regnumber_table[regnumber_index[p+i]]<=r) then
  452. p:=p+i;
  453. i:=i shr 1;
  454. until i=0;
  455. if regnumber_table[regnumber_index[p]]=r then
  456. result:=regnumber_index[p]
  457. else
  458. result:=0;
  459. end;
  460. function std_regnum_search(const s:string):Tregister;
  461. begin
  462. result:=regnumber_table[findreg_by_stdname(s)];
  463. end;
  464. function std_regname(r:Tregister):string;
  465. var
  466. p : tregisterindex;
  467. begin
  468. p:=findreg_by_number(r);
  469. if p<>0 then
  470. result:=std_regname_table[p]
  471. else
  472. result:=generic_regname(r);
  473. end;
  474. end.
  475. {
  476. $Log$
  477. Revision 1.27 2003-10-17 15:08:34 peter
  478. * commented out more obsolete constants
  479. Revision 1.26 2003/10/17 14:38:32 peter
  480. * 64k registers supported
  481. * fixed some memory leaks
  482. Revision 1.25 2003/10/11 16:06:42 florian
  483. * fixed some MMX<->SSE
  484. * started to fix ppc, needs an overhaul
  485. + stabs info improve for spilling, not sure if it works correctly/completly
  486. - MMX_SUPPORT removed from Makefile.fpc
  487. Revision 1.24 2003/10/09 21:31:37 daniel
  488. * Register allocator splitted, ans abstract now
  489. Revision 1.23 2003/10/03 22:00:33 peter
  490. * parameter alignment fixes
  491. Revision 1.22 2003/10/01 20:34:51 peter
  492. * procinfo unit contains tprocinfo
  493. * cginfo renamed to cgbase
  494. * moved cgmessage to verbose
  495. * fixed ppc and sparc compiles
  496. Revision 1.21 2003/09/28 21:49:39 peter
  497. * removed emitjmp
  498. Revision 1.20 2003/09/25 21:29:23 peter
  499. * remove sp_fixup
  500. Revision 1.19 2003/09/24 17:12:36 florian
  501. * x86-64 adaptions
  502. Revision 1.18 2003/09/23 17:56:06 peter
  503. * locals and paras are allocated in the code generation
  504. * tvarsym.localloc contains the location of para/local when
  505. generating code for the current procedure
  506. Revision 1.17 2003/09/07 22:09:35 peter
  507. * preparations for different default calling conventions
  508. * various RA fixes
  509. Revision 1.16 2003/09/04 21:07:03 florian
  510. * ARM compiler compiles again
  511. Revision 1.15 2003/09/03 15:55:02 peter
  512. * NEWRA branch merged
  513. Revision 1.14 2003/09/03 11:18:37 florian
  514. * fixed arm concatcopy
  515. + arm support in the common compiler sources added
  516. * moved some generic cg code around
  517. + tfputype added
  518. * ...
  519. Revision 1.13.2.8 2003/08/31 19:31:51 daniel
  520. * FIxed superregister constants
  521. Revision 1.13.2.7 2003/08/31 16:18:05 peter
  522. * more fixes
  523. Revision 1.13.2.6 2003/08/31 15:46:26 peter
  524. * more updates for tregister
  525. Revision 1.13.2.5 2003/08/31 13:50:16 daniel
  526. * Remove sorting and use pregenerated indexes
  527. * Some work on making things compile
  528. Revision 1.13.2.4 2003/08/29 17:29:00 peter
  529. * next batch of updates
  530. Revision 1.13.2.3 2003/08/28 18:35:08 peter
  531. * tregister changed to cardinal
  532. Revision 1.13.2.2 2003/08/27 21:06:34 peter
  533. * more updates
  534. Revision 1.13.2.1 2003/08/27 19:55:54 peter
  535. * first tregister patch
  536. Revision 1.13 2003/08/20 07:48:04 daniel
  537. * Made internal assembler use new register coding
  538. Revision 1.12 2003/08/17 16:59:20 jonas
  539. * fixed regvars so they work with newra (at least for ppc)
  540. * fixed some volatile register bugs
  541. + -dnotranslation option for -dnewra, which causes the registers not to
  542. be translated from virtual to normal registers. Requires support in
  543. the assembler writer as well, which is only implemented in aggas/
  544. agppcgas currently
  545. Revision 1.11 2003/07/06 21:50:33 jonas
  546. * fixed ppc compilation problems and changed VOLATILE_REGISTERS for x86
  547. so that it doesn't include ebp and esp anymore
  548. Revision 1.10 2003/06/17 16:34:45 jonas
  549. * lots of newra fixes (need getfuncretparaloc implementation for i386)!
  550. * renamed all_intregisters to volatile_intregisters and made it
  551. processor dependent
  552. Revision 1.9 2003/06/13 21:19:33 peter
  553. * current_procdef removed, use current_procinfo.procdef instead
  554. Revision 1.8 2003/06/12 19:11:34 jonas
  555. - removed ALL_INTREGISTERS (only the one in rgobj is valid)
  556. Revision 1.7 2003/06/03 21:11:09 peter
  557. * cg.a_load_* get a from and to size specifier
  558. * makeregsize only accepts newregister
  559. * i386 uses generic tcgnotnode,tcgunaryminus
  560. Revision 1.6 2003/06/03 13:01:59 daniel
  561. * Register allocator finished
  562. Revision 1.5 2003/05/30 23:57:08 peter
  563. * more sparc cleanup
  564. * accumulator removed, splitted in function_return_reg (called) and
  565. function_result_reg (caller)
  566. Revision 1.4 2003/04/30 20:53:32 florian
  567. * error when address of an abstract method is taken
  568. * fixed some x86-64 problems
  569. * merged some more x86-64 and i386 code
  570. Revision 1.3 2002/04/25 20:15:40 florian
  571. * block nodes within expressions shouldn't release the used registers,
  572. fixed using a flag till the new rg is ready
  573. Revision 1.2 2002/04/25 16:12:09 florian
  574. * fixed more problems with cpubase and x86-64
  575. Revision 1.1 2003/04/25 11:12:09 florian
  576. * merged i386/cpubase and x86_64/cpubase to x86/cpubase;
  577. different stuff went to cpubase.inc
  578. Revision 1.50 2003/04/25 08:25:26 daniel
  579. * Ifdefs around a lot of calls to cleartempgen
  580. * Fixed registers that are allocated but not freed in several nodes
  581. * Tweak to register allocator to cause less spills
  582. * 8-bit registers now interfere with esi,edi and ebp
  583. Compiler can now compile rtl successfully when using new register
  584. allocator
  585. Revision 1.49 2003/04/22 23:50:23 peter
  586. * firstpass uses expectloc
  587. * checks if there are differences between the expectloc and
  588. location.loc from secondpass in EXTDEBUG
  589. Revision 1.48 2003/04/22 14:33:38 peter
  590. * removed some notes/hints
  591. Revision 1.47 2003/04/22 10:09:35 daniel
  592. + Implemented the actual register allocator
  593. + Scratch registers unavailable when new register allocator used
  594. + maybe_save/maybe_restore unavailable when new register allocator used
  595. Revision 1.46 2003/04/21 19:16:50 peter
  596. * count address regs separate
  597. Revision 1.45 2003/03/28 19:16:57 peter
  598. * generic constructor working for i386
  599. * remove fixed self register
  600. * esi added as address register for i386
  601. Revision 1.44 2003/03/18 18:15:53 peter
  602. * changed reg2opsize to function
  603. Revision 1.43 2003/03/08 08:59:07 daniel
  604. + $define newra will enable new register allocator
  605. + getregisterint will return imaginary registers with $newra
  606. + -sr switch added, will skip register allocation so you can see
  607. the direct output of the code generator before register allocation
  608. Revision 1.42 2003/02/19 22:00:15 daniel
  609. * Code generator converted to new register notation
  610. - Horribily outdated todo.txt removed
  611. Revision 1.41 2003/02/02 19:25:54 carl
  612. * Several bugfixes for m68k target (register alloc., opcode emission)
  613. + VIS target
  614. + Generic add more complete (still not verified)
  615. Revision 1.40 2003/01/13 18:37:44 daniel
  616. * Work on register conversion
  617. Revision 1.39 2003/01/09 20:41:00 daniel
  618. * Converted some code in cgx86.pas to new register numbering
  619. Revision 1.38 2003/01/09 15:49:56 daniel
  620. * Added register conversion
  621. Revision 1.37 2003/01/08 22:32:36 daniel
  622. * Added register convesrion procedure
  623. Revision 1.36 2003/01/08 18:43:57 daniel
  624. * Tregister changed into a record
  625. Revision 1.35 2003/01/05 13:36:53 florian
  626. * x86-64 compiles
  627. + very basic support for float128 type (x86-64 only)
  628. Revision 1.34 2002/11/17 18:26:16 mazen
  629. * fixed a compilation bug accmulator-->FUNCTION_RETURN_REG, in definition of return_result_reg
  630. Revision 1.33 2002/11/17 17:49:08 mazen
  631. + return_result_reg and FUNCTION_RESULT_REG are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
  632. Revision 1.32 2002/10/05 12:43:29 carl
  633. * fixes for Delphi 6 compilation
  634. (warning : Some features do not work under Delphi)
  635. Revision 1.31 2002/08/14 18:41:48 jonas
  636. - remove valuelow/valuehigh fields from tlocation, because they depend
  637. on the endianess of the host operating system -> difficult to get
  638. right. Use lo/hi(location.valueqword) instead (remember to use
  639. valueqword and not value!!)
  640. Revision 1.30 2002/08/13 21:40:58 florian
  641. * more fixes for ppc calling conventions
  642. Revision 1.29 2002/08/12 15:08:41 carl
  643. + stab register indexes for powerpc (moved from gdb to cpubase)
  644. + tprocessor enumeration moved to cpuinfo
  645. + linker in target_info is now a class
  646. * many many updates for m68k (will soon start to compile)
  647. - removed some ifdef or correct them for correct cpu
  648. Revision 1.28 2002/08/06 20:55:23 florian
  649. * first part of ppc calling conventions fix
  650. Revision 1.27 2002/07/25 18:01:29 carl
  651. + FPURESULTREG -> FPU_RESULT_REG
  652. Revision 1.26 2002/07/07 09:52:33 florian
  653. * powerpc target fixed, very simple units can be compiled
  654. * some basic stuff for better callparanode handling, far from being finished
  655. Revision 1.25 2002/07/01 18:46:30 peter
  656. * internal linker
  657. * reorganized aasm layer
  658. Revision 1.24 2002/07/01 16:23:55 peter
  659. * cg64 patch
  660. * basics for currency
  661. * asnode updates for class and interface (not finished)
  662. Revision 1.23 2002/05/18 13:34:22 peter
  663. * readded missing revisions
  664. Revision 1.22 2002/05/16 19:46:50 carl
  665. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  666. + try to fix temp allocation (still in ifdef)
  667. + generic constructor calls
  668. + start of tassembler / tmodulebase class cleanup
  669. Revision 1.19 2002/05/12 16:53:16 peter
  670. * moved entry and exitcode to ncgutil and cgobj
  671. * foreach gets extra argument for passing local data to the
  672. iterator function
  673. * -CR checks also class typecasts at runtime by changing them
  674. into as
  675. * fixed compiler to cycle with the -CR option
  676. * fixed stabs with elf writer, finally the global variables can
  677. be watched
  678. * removed a lot of routines from cga unit and replaced them by
  679. calls to cgobj
  680. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  681. u32bit then the other is typecasted also to u32bit without giving
  682. a rangecheck warning/error.
  683. * fixed pascal calling method with reversing also the high tree in
  684. the parast, detected by tcalcst3 test
  685. Revision 1.18 2002/04/21 15:31:40 carl
  686. - removed some other stuff to their units
  687. Revision 1.17 2002/04/20 21:37:07 carl
  688. + generic FPC_CHECKPOINTER
  689. + first parameter offset in stack now portable
  690. * rename some constants
  691. + move some cpu stuff to other units
  692. - remove unused constents
  693. * fix stacksize for some targets
  694. * fix generic size problems which depend now on EXTEND_SIZE constant
  695. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  696. Revision 1.16 2002/04/15 19:53:54 peter
  697. * fixed conflicts between the last 2 commits
  698. Revision 1.15 2002/04/15 19:44:20 peter
  699. * fixed stackcheck that would be called recursively when a stack
  700. error was found
  701. * generic changeregsize(reg,size) for i386 register resizing
  702. * removed some more routines from cga unit
  703. * fixed returnvalue handling
  704. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  705. Revision 1.14 2002/04/15 19:12:09 carl
  706. + target_info.size_of_pointer -> pointer_size
  707. + some cleanup of unused types/variables
  708. * move several constants from cpubase to their specific units
  709. (where they are used)
  710. + att_Reg2str -> gas_reg2str
  711. + int_reg2str -> std_reg2str
  712. Revision 1.13 2002/04/14 16:59:41 carl
  713. + att_reg2str -> gas_reg2str
  714. Revision 1.12 2002/04/02 17:11:34 peter
  715. * tlocation,treference update
  716. * LOC_CONSTANT added for better constant handling
  717. * secondadd splitted in multiple routines
  718. * location_force_reg added for loading a location to a register
  719. of a specified size
  720. * secondassignment parses now first the right and then the left node
  721. (this is compatible with Kylix). This saves a lot of push/pop especially
  722. with string operations
  723. * adapted some routines to use the new cg methods
  724. Revision 1.11 2002/03/31 20:26:37 jonas
  725. + a_loadfpu_* and a_loadmm_* methods in tcg
  726. * register allocation is now handled by a class and is mostly processor
  727. independent (+rgobj.pas and i386/rgcpu.pas)
  728. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  729. * some small improvements and fixes to the optimizer
  730. * some register allocation fixes
  731. * some fpuvaroffset fixes in the unary minus node
  732. * push/popusedregisters is now called rg.save/restoreusedregisters and
  733. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  734. also better optimizable)
  735. * fixed and optimized register saving/restoring for new/dispose nodes
  736. * LOC_FPU locations now also require their "register" field to be set to
  737. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  738. - list field removed of the tnode class because it's not used currently
  739. and can cause hard-to-find bugs
  740. Revision 1.10 2002/03/04 19:10:12 peter
  741. * removed compiler warnings
  742. }