cpubase.pas 29 KB

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