cpubase.pas 28 KB

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