cpubase.pas 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl and Peter Vreman
  4. Contains the base types for the i386
  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. TAsmOp={$i i386op.inc}
  43. {# This should define the array of instructions as string }
  44. op2strtable=array[tasmop] of string[11];
  45. Const
  46. {# First value of opcode enumeration }
  47. firstop = low(tasmop);
  48. {# Last value of opcode enumeration }
  49. lastop = high(tasmop);
  50. {*****************************************************************************
  51. Operand Sizes
  52. *****************************************************************************}
  53. type
  54. topsize = (S_NO,
  55. S_B,S_W,S_L,S_BW,S_BL,S_WL,
  56. S_IS,S_IL,S_IQ,
  57. S_FS,S_FL,S_FX,S_D,S_Q,S_FV,S_FXX,
  58. S_NEAR,S_FAR,S_SHORT
  59. );
  60. {*****************************************************************************
  61. Registers
  62. *****************************************************************************}
  63. {The new register coding:
  64. For now we'll use this, when the old register coding is away, we
  65. can change this into a cardinal or something so the amount of
  66. possible registers increases.
  67. High byte: Register number
  68. Low byte: Subregister
  69. Example:
  70. $0100 AL
  71. $0101 AH
  72. $0102 AX
  73. $0103 EAX
  74. $0104 RAX
  75. $0201 BL
  76. $0203 EBX}
  77. {Super register numbers:}
  78. const RS_SPECIAL = $00; {Special register}
  79. RS_EAX = $01; {EAX}
  80. RS_EBX = $02; {EBX}
  81. RS_ECX = $03; {ECX}
  82. RS_EDX = $04; {EDX}
  83. RS_ESI = $05; {ESI}
  84. RS_EDI = $06; {EDI}
  85. RS_EBP = $07; {EBP}
  86. RS_ESP = $08; {ESP}
  87. RS_R8 = $09; {R8}
  88. RS_R9 = $0a; {R9}
  89. RS_R10 = $0b; {R10}
  90. RS_R11 = $0c; {R11}
  91. RS_R12 = $0d; {R12}
  92. RS_R13 = $0e; {R13}
  93. RS_R14 = $0f; {R14}
  94. RS_R15 = $10; {R15}
  95. {Number of first and last superregister.}
  96. first_supreg = $01;
  97. last_supreg = $10;
  98. {Number of first and last imaginary register.}
  99. first_imreg = $12;
  100. last_imreg = $ff;
  101. {Sub register numbers:}
  102. R_SUBL = $00; {Like AL}
  103. R_SUBH = $01; {Like AH}
  104. R_SUBW = $02; {Like AX}
  105. R_SUBD = $03; {Like EAX}
  106. R_SUBQ = $04; {Like RAX}
  107. {The subregister that specifies the entire register.}
  108. R_SUBWHOLE = R_SUBD; {i386}
  109. {R_SUBWHOLE = R_SUBQ;} {Hammer}
  110. {Special registers:}
  111. const NR_NO = $0000; {Invalid register}
  112. NR_CS = $0001; {CS}
  113. NR_DS = $0002; {DS}
  114. NR_ES = $0003; {ES}
  115. NR_SS = $0004; {SS}
  116. NR_FS = $0005; {FS}
  117. NR_GS = $0006; {GS}
  118. NR_RIP = $000F; {RIP}
  119. NR_DR0 = $0010; {DR0}
  120. NR_DR1 = $0011; {DR1}
  121. NR_DR2 = $0012; {DR2}
  122. NR_DR3 = $0013; {DR3}
  123. NR_DR6 = $0016; {DR6}
  124. NR_DR7 = $0017; {DR7}
  125. NR_CR0 = $0020; {CR0}
  126. NR_CR2 = $0021; {CR1}
  127. NR_CR3 = $0022; {CR2}
  128. NR_CR4 = $0023; {CR3}
  129. NR_TR3 = $0030; {R_TR3}
  130. NR_TR4 = $0031; {R_TR4}
  131. NR_TR5 = $0032; {R_TR5}
  132. NR_TR6 = $0033; {R_TR6}
  133. NR_TR7 = $0034; {R_TR7}
  134. {Normal registers.}
  135. const NR_AL = $0100; {AL}
  136. NR_AH = $0101; {AH}
  137. NR_AX = $0102; {AX}
  138. NR_EAX = $0103; {EAX}
  139. NR_RAX = $0104; {RAX}
  140. NR_BL = $0200; {BL}
  141. NR_BH = $0201; {BH}
  142. NR_BX = $0202; {BX}
  143. NR_EBX = $0203; {EBX}
  144. NR_RBX = $0204; {RBX}
  145. NR_CL = $0300; {CL}
  146. NR_CH = $0301; {CH}
  147. NR_CX = $0302; {CX}
  148. NR_ECX = $0303; {ECX}
  149. NR_RCX = $0304; {RCX}
  150. NR_DL = $0400; {DL}
  151. NR_DH = $0401; {DH}
  152. NR_DX = $0402; {DX}
  153. NR_EDX = $0403; {EDX}
  154. NR_RDX = $0404; {RDX}
  155. NR_SIL = $0500; {SIL}
  156. NR_SI = $0502; {SI}
  157. NR_ESI = $0503; {ESI}
  158. NR_RSI = $0504; {RSI}
  159. NR_DIL = $0600; {DIL}
  160. NR_DI = $0602; {DI}
  161. NR_EDI = $0603; {EDI}
  162. NR_RDI = $0604; {RDI}
  163. NR_BPL = $0700; {BPL}
  164. NR_BP = $0702; {BP}
  165. NR_EBP = $0703; {EBP}
  166. NR_RBP = $0704; {RBP}
  167. NR_SPL = $0800; {SPL}
  168. NR_SP = $0802; {SP}
  169. NR_ESP = $0803; {ESP}
  170. NR_RSP = $0804; {RSP}
  171. NR_R8L = $0900; {R8L}
  172. NR_R8W = $0902; {R8W}
  173. NR_R8D = $0903; {R8D}
  174. NR_R9L = $0a00; {R9D}
  175. NR_R9W = $0a02; {R9W}
  176. NR_R9D = $0a03; {R9D}
  177. NR_R10L = $0b00; {R10L}
  178. NR_R10W = $0b02; {R10W}
  179. NR_R10D = $0b03; {R10D}
  180. NR_R11L = $0c00; {R11L}
  181. NR_R11W = $0c02; {R11W}
  182. NR_R11D = $0c03; {R11D}
  183. NR_R12L = $0d00; {R12L}
  184. NR_R12W = $0d02; {R12W}
  185. NR_R12D = $0d03; {R12D}
  186. NR_R13L = $0e00; {R13L}
  187. NR_R13W = $0e02; {R13W}
  188. NR_R13D = $0e03; {R13D}
  189. NR_R14L = $0f00; {R14L}
  190. NR_R14W = $0f02; {R14W}
  191. NR_R14D = $0f03; {R14D}
  192. NR_R15L = $1000; {R15L}
  193. NR_R15W = $1002; {R15W}
  194. NR_R15D = $1003; {R15D}
  195. type
  196. {# Enumeration for all possible registers for cpu. It
  197. is to note that all registers of the same type
  198. (for example all FPU registers), should be grouped
  199. together.
  200. }
  201. { don't change the order }
  202. { it's used by the register size conversions }
  203. Toldregister = (R_NO,
  204. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  205. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  206. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  207. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  208. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  209. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  210. R_CR0,R_CR2,R_CR3,R_CR4,
  211. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  212. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  213. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7,
  214. R_INTREGISTER,R_FLOATREGISTER,R_MMXREGISTER,R_KNIREGISTER
  215. );
  216. type Tnewregister=word;
  217. Tregister = packed record
  218. enum:Toldregister;
  219. number:Tnewregister; {This is a word for now, change to cardinal
  220. when the old register coding is away.}
  221. end;
  222. Tsuperregister=byte;
  223. Tsubregister=byte;
  224. { A type to store register locations for 64 Bit values. }
  225. tregister64 = packed record
  226. reglo,reghi : tregister;
  227. end;
  228. { alias for compact code }
  229. treg64 = tregister64;
  230. {# Set type definition for registers }
  231. tregisterset = set of Toldregister;
  232. Tsupregset = set of Tsuperregister;
  233. const
  234. {# First register in the tregister enumeration }
  235. firstreg = low(Toldregister);
  236. {# Last register in the tregister enumeration }
  237. lastreg = R_XMM7;
  238. firstsreg = R_CS;
  239. lastsreg = R_GS;
  240. nfirstsreg = NR_CS;
  241. nlastsreg = NR_GS;
  242. regset8bit : tregisterset = [R_AL..R_DH];
  243. regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
  244. regset32bit : tregisterset = [R_EAX..R_EDI];
  245. {# Standard opcode string table (for each tasmop enumeration). The
  246. opcode strings should conform to the names as defined by the
  247. processor manufacturer.
  248. }
  249. std_op2str:op2strtable={$i i386int.inc}
  250. type
  251. {# Type definition for the array of string of register names }
  252. reg2strtable = array[firstreg..lastreg] of string[6];
  253. regname2regnumrec = record
  254. name:string[6];
  255. number:Tnewregister;
  256. end;
  257. const
  258. {# Standard register table (for each tregister enumeration). The
  259. register strings should conform to the the names as defined
  260. by the processor manufacturer
  261. }
  262. std_reg2str : reg2strtable = ('',
  263. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  264. 'ax','cx','dx','bx','sp','bp','si','di',
  265. 'al','cl','dl','bl','ah','ch','bh','dh',
  266. 'cs','ds','es','ss','fs','gs',
  267. 'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
  268. 'dr0','dr1','dr2','dr3','dr6','dr7',
  269. 'cr0','cr2','cr3','cr4',
  270. 'tr3','tr4','tr5','tr6','tr7',
  271. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  272. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  273. );
  274. {*****************************************************************************
  275. Conditions
  276. *****************************************************************************}
  277. type
  278. TAsmCond=(C_None,
  279. C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
  280. C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
  281. C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
  282. );
  283. const
  284. cond2str:array[TAsmCond] of string[3]=('',
  285. 'a','ae','b','be','c','e','g','ge','l','le','na','nae',
  286. 'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
  287. 'ns','nz','o','p','pe','po','s','z'
  288. );
  289. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  290. C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
  291. C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
  292. C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
  293. );
  294. {*****************************************************************************
  295. Flags
  296. *****************************************************************************}
  297. type
  298. 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);
  299. {*****************************************************************************
  300. Reference
  301. *****************************************************************************}
  302. type
  303. trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
  304. { reference record }
  305. preference = ^treference;
  306. treference = packed record
  307. segment,
  308. base,
  309. index : tregister;
  310. scalefactor : byte;
  311. offset : longint;
  312. symbol : tasmsymbol;
  313. offsetfixup : longint;
  314. options : trefoptions;
  315. end;
  316. { reference record }
  317. pparareference = ^tparareference;
  318. tparareference = packed record
  319. index : tregister;
  320. offset : longint;
  321. end;
  322. {*****************************************************************************
  323. Operands
  324. *****************************************************************************}
  325. { Types of operand }
  326. toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
  327. toper=record
  328. ot : longint;
  329. case typ : toptype of
  330. top_none : ();
  331. top_reg : (reg:tregister);
  332. top_ref : (ref:preference);
  333. top_const : (val:aword);
  334. top_symbol : (sym:tasmsymbol;symofs:longint);
  335. end;
  336. {*****************************************************************************
  337. Generic Location
  338. *****************************************************************************}
  339. type
  340. { tparamlocation describes where a parameter for a procedure is stored.
  341. References are given from the caller's point of view. The usual
  342. TLocation isn't used, because contains a lot of unnessary fields.
  343. }
  344. tparalocation = packed record
  345. size : TCGSize;
  346. loc : TCGLoc;
  347. sp_fixup : longint;
  348. case TCGLoc of
  349. LOC_REFERENCE : (reference : tparareference);
  350. { segment in reference at the same place as in loc_register }
  351. LOC_REGISTER,LOC_CREGISTER : (
  352. case longint of
  353. 1 : (register,registerhigh : tregister);
  354. { overlay a registerlow }
  355. 2 : (registerlow : tregister);
  356. { overlay a 64 Bit register type }
  357. 3 : (reg64 : tregister64);
  358. 4 : (register64 : tregister64);
  359. );
  360. { it's only for better handling }
  361. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  362. end;
  363. tlocation = packed record
  364. loc : TCGLoc;
  365. size : TCGSize;
  366. case TCGLoc of
  367. LOC_FLAGS : (resflags : tresflags);
  368. LOC_CONSTANT : (
  369. case longint of
  370. 1 : (value : AWord);
  371. { can't do this, this layout depends on the host cpu. Use }
  372. { lo(valueqword)/hi(valueqword) instead (JM) }
  373. { 2 : (valuelow, valuehigh:AWord); }
  374. { overlay a complete 64 Bit value }
  375. 3 : (valueqword : qword);
  376. );
  377. LOC_CREFERENCE,
  378. LOC_REFERENCE : (reference : treference);
  379. { segment in reference at the same place as in loc_register }
  380. LOC_REGISTER,LOC_CREGISTER : (
  381. case longint of
  382. 1 : (register,registerhigh,segment : tregister);
  383. { overlay a registerlow }
  384. 2 : (registerlow : tregister);
  385. { overlay a 64 Bit register type }
  386. 3 : (reg64 : tregister64);
  387. 4 : (register64 : tregister64);
  388. );
  389. { it's only for better handling }
  390. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  391. end;
  392. {*****************************************************************************
  393. Constants
  394. *****************************************************************************}
  395. const
  396. { declare aliases }
  397. LOC_MMREGISTER = LOC_SSEREGISTER;
  398. LOC_CMMREGISTER = LOC_CSSEREGISTER;
  399. max_operands = 3;
  400. lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
  401. LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
  402. {# Constant defining possibly all registers which might require saving }
  403. ALL_REGISTERS = [firstreg..lastreg];
  404. ALL_INTREGISTERS = [1..255];
  405. general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
  406. general_superregisters = [RS_EAX,RS_EBX,RS_ECX,RS_EDX];
  407. {# low and high of the available maximum width integer general purpose }
  408. { registers }
  409. LoGPReg = R_EAX;
  410. HiGPReg = R_EDX;
  411. {# low and high of every possible width general purpose register (same as }
  412. { above on most architctures apart from the 80x86) }
  413. LoReg = R_EAX;
  414. HiReg = R_DH;
  415. {# Table of registers which can be allocated by the code generator
  416. internally, when generating the code.
  417. }
  418. { legend: }
  419. { xxxregs = set of all possibly used registers of that type in the code }
  420. { generator }
  421. { usableregsxxx = set of all 32bit components of registers that can be }
  422. { possible allocated to a regvar or using getregisterxxx (this }
  423. { excludes registers which can be only used for parameter }
  424. { passing on ABI's that define this) }
  425. { c_countusableregsxxx = amount of registers in the usableregsxxx set }
  426. maxintregs = 4;
  427. intregs = [R_EAX..R_BL]-[R_ESI,R_SI];
  428. {$ifdef newra}
  429. usableregsint = [first_imreg..last_imreg];
  430. {$else}
  431. usableregsint = [RS_EAX,RS_EBX,RS_ECX,RS_EDX];
  432. {$endif}
  433. c_countusableregsint = 4;
  434. maxfpuregs = 8;
  435. fpuregs = [R_ST0..R_ST7];
  436. usableregsfpu = [];
  437. c_countusableregsfpu = 0;
  438. mmregs = [R_MM0..R_MM7];
  439. usableregsmm = [R_MM0..R_MM7];
  440. c_countusableregsmm = 8;
  441. maxaddrregs = 1;
  442. addrregs = [R_ESI];
  443. usableregsaddr = [RS_ESI];
  444. c_countusableregsaddr = 1;
  445. firstsaveintreg = RS_EAX;
  446. lastsaveintreg = RS_EDX;
  447. firstsavefpureg = R_NO;
  448. lastsavefpureg = R_NO;
  449. firstsavemmreg = R_MM0;
  450. lastsavemmreg = R_MM7;
  451. maxvarregs = 4;
  452. varregs : array[1..maxvarregs] of Toldregister =
  453. (R_EBX,R_EDX,R_ECX,R_EAX);
  454. maxfpuvarregs = 8;
  455. {# Registers which are defined as scratch and no need to save across
  456. routine calls or in assembler blocks.
  457. }
  458. {$ifndef newra}
  459. max_scratch_regs = 1;
  460. scratch_regs : array[1..max_scratch_regs] of Tsuperregister = (RS_EDI);
  461. {$endif}
  462. {*****************************************************************************
  463. GDB Information
  464. *****************************************************************************}
  465. {# Register indexes for stabs information, when some
  466. parameters or variables are stored in registers.
  467. Taken from i386.c (dbx_register_map) and i386.h
  468. (FIXED_REGISTERS) from GCC 3.x source code
  469. }
  470. stab_regindex : array[firstreg..lastreg] of shortint =
  471. (-1,
  472. 0,1,2,3,4,5,6,7,
  473. 0,1,2,3,4,5,6,7,
  474. 0,1,2,3,0,1,2,3,
  475. -1,-1,-1,-1,-1,-1,
  476. 12,12,13,14,15,16,17,18,19,
  477. -1,-1,-1,-1,-1,-1,
  478. -1,-1,-1,-1,
  479. -1,-1,-1,-1,-1,
  480. 29,30,31,32,33,34,35,36,
  481. 21,22,23,24,25,26,27,28
  482. );
  483. {*****************************************************************************
  484. Default generic sizes
  485. *****************************************************************************}
  486. {# Defines the default address size for a processor, }
  487. OS_ADDR = OS_32;
  488. {# the natural int size for a processor, }
  489. OS_INT = OS_32;
  490. {# the maximum float size for a processor, }
  491. OS_FLOAT = OS_F80;
  492. {# the size of a vector register for a processor }
  493. OS_VECTOR = OS_M64;
  494. {*****************************************************************************
  495. Generic Register names
  496. *****************************************************************************}
  497. {# Stack pointer register }
  498. stack_pointer_reg = R_ESP;
  499. NR_STACK_POINTER_REG = NR_ESP;
  500. {# Frame pointer register }
  501. frame_pointer_reg = R_EBP;
  502. NR_FRAME_POINTER_REG = NR_EBP;
  503. {# Register for addressing absolute data in a position independant way,
  504. such as in PIC code. The exact meaning is ABI specific. For
  505. further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
  506. }
  507. pic_offset_reg = R_EBX;
  508. {# Results are returned in this register (32-bit values) }
  509. accumulator = R_EAX;
  510. RS_ACCUMULATOR = RS_EAX;
  511. NR_ACCUMULATOR = NR_EAX;
  512. {the return_result_reg, is used inside the called function to store its return
  513. value when that is a scalar value otherwise a pointer to the address of the
  514. result is placed inside it}
  515. return_result_reg = accumulator;
  516. RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
  517. NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
  518. {the function_result_reg contains the function result after a call to a scalar
  519. function othewise it contains a pointer to the returned result}
  520. function_result_reg = accumulator;
  521. {# Hi-Results are returned in this register (64-bit value high register) }
  522. accumulatorhigh = R_EDX;
  523. RS_ACCUMULATORHIGH = RS_EDX;
  524. NR_ACCUMULATORHIGH = NR_EDX;
  525. { WARNING: don't change to R_ST0!! See comments above implementation of }
  526. { a_loadfpu* methods in rgcpu (JM) }
  527. fpu_result_reg = R_ST;
  528. mmresultreg = R_MM0;
  529. {*****************************************************************************
  530. GCC /ABI linking information
  531. *****************************************************************************}
  532. const
  533. {# Registers which must be saved when calling a routine declared as
  534. cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
  535. saved should be the ones as defined in the target ABI and / or GCC.
  536. This value can be deduced from the CALLED_USED_REGISTERS array in the
  537. GCC source.
  538. }
  539. std_saved_registers = [R_ESI,R_EDI,R_EBX];
  540. {# Required parameter alignment when calling a routine declared as
  541. stdcall and cdecl. The alignment value should be the one defined
  542. by GCC or the target ABI.
  543. The value of this constant is equal to the constant
  544. PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
  545. }
  546. std_param_align = 4;
  547. {*****************************************************************************
  548. CPU Dependent Constants
  549. *****************************************************************************}
  550. {*****************************************************************************
  551. Helpers
  552. *****************************************************************************}
  553. procedure convert_register_to_enum(var r:Tregister);
  554. function cgsize2subreg(s:Tcgsize):Tsubregister;
  555. function reg2opsize(r:Tregister):topsize;
  556. function is_calljmp(o:tasmop):boolean;
  557. function flags_to_cond(const f: TResFlags) : TAsmCond;
  558. implementation
  559. uses verbose;
  560. {*****************************************************************************
  561. Helpers
  562. *****************************************************************************}
  563. procedure convert_register_to_enum(var r:Tregister);
  564. begin
  565. if r.enum=R_INTREGISTER then
  566. case r.number of
  567. NR_NO: r.enum:=R_NO;
  568. NR_EAX: r.enum:=R_EAX; NR_EBX: r.enum:=R_EBX;
  569. NR_ECX: r.enum:=R_ECX; NR_EDX: r.enum:=R_EDX;
  570. NR_ESI: r.enum:=R_ESI; NR_EDI: r.enum:=R_EDI;
  571. NR_ESP: r.enum:=R_ESP; NR_EBP: r.enum:=R_EBP;
  572. NR_AX: r.enum:=R_AX; NR_BX: r.enum:=R_BX;
  573. NR_CX: r.enum:=R_CX; NR_DX: r.enum:=R_DX;
  574. NR_SI: r.enum:=R_SI; NR_DI: r.enum:=R_DI;
  575. NR_SP: r.enum:=R_SP; NR_BP: r.enum:=R_BP;
  576. NR_AL: r.enum:=R_AL; NR_BL: r.enum:=R_BL;
  577. NR_CL: r.enum:=R_CL; NR_DL: r.enum:=R_DL;
  578. NR_AH: r.enum:=R_AH; NR_BH: r.enum:=R_BH;
  579. NR_CH: r.enum:=R_CH; NR_DH: r.enum:=R_DH;
  580. NR_CS: r.enum:=R_CS; NR_DS: r.enum:=R_DS;
  581. NR_ES: r.enum:=R_ES; NR_FS: r.enum:=R_FS;
  582. NR_GS: r.enum:=R_GS; NR_SS: r.enum:=R_SS;
  583. else
  584. { internalerror(200301082);}
  585. r.enum:=R_TR3;
  586. end;
  587. end;
  588. function cgsize2subreg(s:Tcgsize):Tsubregister;
  589. begin
  590. case s of
  591. OS_8,OS_S8:
  592. cgsize2subreg:=R_SUBL;
  593. OS_16,OS_S16:
  594. cgsize2subreg:=R_SUBW;
  595. OS_32,OS_S32:
  596. cgsize2subreg:=R_SUBD;
  597. OS_64,OS_S64:
  598. cgsize2subreg:=R_SUBQ;
  599. else
  600. internalerror(200301231);
  601. end;
  602. end;
  603. function reg2opsize(r:Tregister):topsize;
  604. const
  605. subreg2opsize : array[0..4] of Topsize = (S_B,S_B,S_W,S_L,S_D);
  606. enum2opsize : array[firstreg..lastreg] of topsize = (S_NO,
  607. S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
  608. S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
  609. S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
  610. S_W,S_W,S_W,S_W,S_W,S_W,
  611. S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
  612. S_L,S_L,S_L,S_L,S_L,S_L,
  613. S_L,S_L,S_L,S_L,
  614. S_L,S_L,S_L,S_L,S_L,
  615. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
  616. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
  617. );
  618. begin
  619. reg2opsize:=S_L;
  620. if (r.enum=R_INTREGISTER) then
  621. begin
  622. if (r.number shr 8)=0 then
  623. begin
  624. case r.number of
  625. NR_CS,NR_DS,NR_ES,
  626. NR_SS,NR_FS,NR_GS :
  627. reg2opsize:=S_W;
  628. end;
  629. end
  630. else
  631. begin
  632. if (r.number and $ff)>4 then
  633. internalerror(200303181);
  634. reg2opsize:=subreg2opsize[r.number and $ff];
  635. end;
  636. end
  637. else
  638. begin
  639. reg2opsize:=enum2opsize[r.enum];
  640. end;
  641. end;
  642. {$ifdef unused}
  643. function supreg_name(r:Tsuperregister):string;
  644. var s:string[4];
  645. const supreg_names:array[0..last_supreg] of string[4]=
  646. ('INV',
  647. 'eax','ebx','ecx','edx','esi','edi','ebp','esp',
  648. 'r8' ,'r9', 'r10','r11','r12','r13','r14','r15');
  649. begin
  650. if r in [0..last_supreg] then
  651. supreg_name:=supreg_names[r]
  652. else
  653. begin
  654. str(r,s);
  655. supreg_name:='reg'+s;
  656. end;
  657. end;
  658. {$endif unused}
  659. function is_calljmp(o:tasmop):boolean;
  660. begin
  661. case o of
  662. A_CALL,
  663. A_JCXZ,
  664. A_JECXZ,
  665. A_JMP,
  666. A_LOOP,
  667. A_LOOPE,
  668. A_LOOPNE,
  669. A_LOOPNZ,
  670. A_LOOPZ,
  671. A_Jcc :
  672. is_calljmp:=true;
  673. else
  674. is_calljmp:=false;
  675. end;
  676. end;
  677. function flags_to_cond(const f: TResFlags) : TAsmCond;
  678. const
  679. flags_2_cond : array[TResFlags] of TAsmCond =
  680. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  681. begin
  682. result := flags_2_cond[f];
  683. end;
  684. end.
  685. {
  686. $Log$
  687. Revision 1.50 2003-04-25 08:25:26 daniel
  688. * Ifdefs around a lot of calls to cleartempgen
  689. * Fixed registers that are allocated but not freed in several nodes
  690. * Tweak to register allocator to cause less spills
  691. * 8-bit registers now interfere with esi,edi and ebp
  692. Compiler can now compile rtl successfully when using new register
  693. allocator
  694. Revision 1.49 2003/04/22 23:50:23 peter
  695. * firstpass uses expectloc
  696. * checks if there are differences between the expectloc and
  697. location.loc from secondpass in EXTDEBUG
  698. Revision 1.48 2003/04/22 14:33:38 peter
  699. * removed some notes/hints
  700. Revision 1.47 2003/04/22 10:09:35 daniel
  701. + Implemented the actual register allocator
  702. + Scratch registers unavailable when new register allocator used
  703. + maybe_save/maybe_restore unavailable when new register allocator used
  704. Revision 1.46 2003/04/21 19:16:50 peter
  705. * count address regs separate
  706. Revision 1.45 2003/03/28 19:16:57 peter
  707. * generic constructor working for i386
  708. * remove fixed self register
  709. * esi added as address register for i386
  710. Revision 1.44 2003/03/18 18:15:53 peter
  711. * changed reg2opsize to function
  712. Revision 1.43 2003/03/08 08:59:07 daniel
  713. + $define newra will enable new register allocator
  714. + getregisterint will return imaginary registers with $newra
  715. + -sr switch added, will skip register allocation so you can see
  716. the direct output of the code generator before register allocation
  717. Revision 1.42 2003/02/19 22:00:15 daniel
  718. * Code generator converted to new register notation
  719. - Horribily outdated todo.txt removed
  720. Revision 1.41 2003/02/02 19:25:54 carl
  721. * Several bugfixes for m68k target (register alloc., opcode emission)
  722. + VIS target
  723. + Generic add more complete (still not verified)
  724. Revision 1.40 2003/01/13 18:37:44 daniel
  725. * Work on register conversion
  726. Revision 1.39 2003/01/09 20:41:00 daniel
  727. * Converted some code in cgx86.pas to new register numbering
  728. Revision 1.38 2003/01/09 15:49:56 daniel
  729. * Added register conversion
  730. Revision 1.37 2003/01/08 22:32:36 daniel
  731. * Added register convesrion procedure
  732. Revision 1.36 2003/01/08 18:43:57 daniel
  733. * Tregister changed into a record
  734. Revision 1.35 2003/01/05 13:36:53 florian
  735. * x86-64 compiles
  736. + very basic support for float128 type (x86-64 only)
  737. Revision 1.34 2002/11/17 18:26:16 mazen
  738. * fixed a compilation bug accmulator-->accumulator, in definition of return_result_reg
  739. Revision 1.33 2002/11/17 17:49:08 mazen
  740. + 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
  741. Revision 1.32 2002/10/05 12:43:29 carl
  742. * fixes for Delphi 6 compilation
  743. (warning : Some features do not work under Delphi)
  744. Revision 1.31 2002/08/14 18:41:48 jonas
  745. - remove valuelow/valuehigh fields from tlocation, because they depend
  746. on the endianess of the host operating system -> difficult to get
  747. right. Use lo/hi(location.valueqword) instead (remember to use
  748. valueqword and not value!!)
  749. Revision 1.30 2002/08/13 21:40:58 florian
  750. * more fixes for ppc calling conventions
  751. Revision 1.29 2002/08/12 15:08:41 carl
  752. + stab register indexes for powerpc (moved from gdb to cpubase)
  753. + tprocessor enumeration moved to cpuinfo
  754. + linker in target_info is now a class
  755. * many many updates for m68k (will soon start to compile)
  756. - removed some ifdef or correct them for correct cpu
  757. Revision 1.28 2002/08/06 20:55:23 florian
  758. * first part of ppc calling conventions fix
  759. Revision 1.27 2002/07/25 18:01:29 carl
  760. + FPURESULTREG -> FPU_RESULT_REG
  761. Revision 1.26 2002/07/07 09:52:33 florian
  762. * powerpc target fixed, very simple units can be compiled
  763. * some basic stuff for better callparanode handling, far from being finished
  764. Revision 1.25 2002/07/01 18:46:30 peter
  765. * internal linker
  766. * reorganized aasm layer
  767. Revision 1.24 2002/07/01 16:23:55 peter
  768. * cg64 patch
  769. * basics for currency
  770. * asnode updates for class and interface (not finished)
  771. Revision 1.23 2002/05/18 13:34:22 peter
  772. * readded missing revisions
  773. Revision 1.22 2002/05/16 19:46:50 carl
  774. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  775. + try to fix temp allocation (still in ifdef)
  776. + generic constructor calls
  777. + start of tassembler / tmodulebase class cleanup
  778. Revision 1.19 2002/05/12 16:53:16 peter
  779. * moved entry and exitcode to ncgutil and cgobj
  780. * foreach gets extra argument for passing local data to the
  781. iterator function
  782. * -CR checks also class typecasts at runtime by changing them
  783. into as
  784. * fixed compiler to cycle with the -CR option
  785. * fixed stabs with elf writer, finally the global variables can
  786. be watched
  787. * removed a lot of routines from cga unit and replaced them by
  788. calls to cgobj
  789. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  790. u32bit then the other is typecasted also to u32bit without giving
  791. a rangecheck warning/error.
  792. * fixed pascal calling method with reversing also the high tree in
  793. the parast, detected by tcalcst3 test
  794. Revision 1.18 2002/04/21 15:31:40 carl
  795. - removed some other stuff to their units
  796. Revision 1.17 2002/04/20 21:37:07 carl
  797. + generic FPC_CHECKPOINTER
  798. + first parameter offset in stack now portable
  799. * rename some constants
  800. + move some cpu stuff to other units
  801. - remove unused constents
  802. * fix stacksize for some targets
  803. * fix generic size problems which depend now on EXTEND_SIZE constant
  804. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  805. Revision 1.16 2002/04/15 19:53:54 peter
  806. * fixed conflicts between the last 2 commits
  807. Revision 1.15 2002/04/15 19:44:20 peter
  808. * fixed stackcheck that would be called recursively when a stack
  809. error was found
  810. * generic changeregsize(reg,size) for i386 register resizing
  811. * removed some more routines from cga unit
  812. * fixed returnvalue handling
  813. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  814. Revision 1.14 2002/04/15 19:12:09 carl
  815. + target_info.size_of_pointer -> pointer_size
  816. + some cleanup of unused types/variables
  817. * move several constants from cpubase to their specific units
  818. (where they are used)
  819. + att_Reg2str -> gas_reg2str
  820. + int_reg2str -> std_reg2str
  821. Revision 1.13 2002/04/14 16:59:41 carl
  822. + att_reg2str -> gas_reg2str
  823. Revision 1.12 2002/04/02 17:11:34 peter
  824. * tlocation,treference update
  825. * LOC_CONSTANT added for better constant handling
  826. * secondadd splitted in multiple routines
  827. * location_force_reg added for loading a location to a register
  828. of a specified size
  829. * secondassignment parses now first the right and then the left node
  830. (this is compatible with Kylix). This saves a lot of push/pop especially
  831. with string operations
  832. * adapted some routines to use the new cg methods
  833. Revision 1.11 2002/03/31 20:26:37 jonas
  834. + a_loadfpu_* and a_loadmm_* methods in tcg
  835. * register allocation is now handled by a class and is mostly processor
  836. independent (+rgobj.pas and i386/rgcpu.pas)
  837. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  838. * some small improvements and fixes to the optimizer
  839. * some register allocation fixes
  840. * some fpuvaroffset fixes in the unary minus node
  841. * push/popusedregisters is now called rg.save/restoreusedregisters and
  842. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  843. also better optimizable)
  844. * fixed and optimized register saving/restoring for new/dispose nodes
  845. * LOC_FPU locations now also require their "register" field to be set to
  846. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  847. - list field removed of the tnode class because it's not used currently
  848. and can cause hard-to-find bugs
  849. Revision 1.10 2002/03/04 19:10:12 peter
  850. * removed compiler warnings
  851. }