cpubase.pas 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  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. 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. Register numbers:
  78. $00 Special register
  79. $01 EAX
  80. $02 EBX
  81. $03 ECX
  82. $04 EDX
  83. $05 ESI
  84. $06 EDI
  85. $07 EBP
  86. $08 ESP
  87. $09 R08
  88. $0a R09
  89. $0b R10
  90. $0c R11
  91. $0d R12
  92. $0e R13
  93. $0f R14
  94. $10 R15}
  95. {Special registers:}
  96. const NR_NO = $0000; {Invalid register}
  97. NR_CS = $0001; {CS}
  98. NR_DS = $0002; {DS}
  99. NR_ES = $0003; {ES}
  100. NR_SS = $0004; {SS}
  101. NR_FS = $0005; {FS}
  102. NR_GS = $0006; {GS}
  103. NR_RIP = $000F; {RIP}
  104. NR_DR0 = $0010; {DR0}
  105. NR_DR1 = $0011; {DR1}
  106. NR_DR2 = $0012; {DR2}
  107. NR_DR3 = $0013; {DR3}
  108. NR_DR6 = $0016; {DR6}
  109. NR_DR7 = $0017; {DR7}
  110. NR_CR0 = $0020; {CR0}
  111. NR_CR1 = $0021; {CR1}
  112. NR_CR2 = $0022; {CR2}
  113. NR_CR3 = $0023; {CR3}
  114. NR_TR3 = $0030; {R_TR3}
  115. NR_TR4 = $0031; {R_TR4}
  116. NR_TR5 = $0032; {R_TR5}
  117. NR_TR6 = $0033; {R_TR6}
  118. NR_TR7 = $0034; {R_TR7}
  119. {Normal registers.}
  120. const NR_AL = $0100; {AL}
  121. NR_AH = $0101; {AH}
  122. NR_AX = $0102; {AX}
  123. NR_EAX = $0103; {EAX}
  124. NR_RAX = $0104; {RAX}
  125. NR_BL = $0200; {BL}
  126. NR_BH = $0201; {BH}
  127. NR_BX = $0202; {BX}
  128. NR_EBX = $0203; {EBX}
  129. NR_RBX = $0204; {RBX}
  130. NR_CL = $0300; {CL}
  131. NR_CH = $0301; {CH}
  132. NR_CX = $0302; {CX}
  133. NR_ECX = $0303; {ECX}
  134. NR_RCX = $0304; {RCX}
  135. NR_DL = $0400; {DL}
  136. NR_DH = $0401; {DH}
  137. NR_DX = $0402; {DX}
  138. NR_EDX = $0403; {EDX}
  139. NR_RDX = $0404; {RDX}
  140. NR_SIL = $0500; {SIL}
  141. NR_SI = $0502; {SI}
  142. NR_ESI = $0503; {ESI}
  143. NR_RSI = $0504; {RSI}
  144. NR_DIL = $0600; {DIL}
  145. NR_DI = $0602; {DI}
  146. NR_EDI = $0603; {EDI}
  147. NR_RDI = $0604; {RDI}
  148. NR_BPL = $0700; {BPL}
  149. NR_BP = $0702; {BP}
  150. NR_EBP = $0703; {EBP}
  151. NR_RBP = $0704; {RBP}
  152. NR_SPL = $0800; {SPL}
  153. NR_SP = $0802; {SP}
  154. NR_ESP = $0803; {ESP}
  155. NR_RSP = $0804; {RSP}
  156. NR_R8L = $0900; {R8L}
  157. NR_R8W = $0902; {R8W}
  158. NR_R8D = $0903; {R8D}
  159. NR_R9L = $0a00; {R9D}
  160. NR_R9W = $0a02; {R9W}
  161. NR_R9D = $0a03; {R9D}
  162. NR_R10L = $0b00; {R10L}
  163. NR_R10W = $0b02; {R10W}
  164. NR_R10D = $0b03; {R10D}
  165. NR_R11L = $0c00; {R11L}
  166. NR_R11W = $0c02; {R11W}
  167. NR_R11D = $0c03; {R11D}
  168. NR_R12L = $0d00; {R12L}
  169. NR_R12W = $0d02; {R12W}
  170. NR_R12D = $0d03; {R12D}
  171. NR_R13L = $0e00; {R13L}
  172. NR_R13W = $0e02; {R13W}
  173. NR_R13D = $0e03; {R13D}
  174. NR_R14L = $0f00; {R14L}
  175. NR_R14W = $0f02; {R14W}
  176. NR_R14D = $0f03; {R14D}
  177. NR_R15L = $1000; {R15L}
  178. NR_R15W = $1002; {R15W}
  179. NR_R15D = $1003; {R15D}
  180. type
  181. {# Enumeration for all possible registers for cpu. It
  182. is to note that all registers of the same type
  183. (for example all FPU registers), should be grouped
  184. together.
  185. }
  186. { don't change the order }
  187. { it's used by the register size conversions }
  188. {$packenum 1}
  189. Toldregister = (R_NO,
  190. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  191. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  192. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  193. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  194. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  195. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  196. R_CR0,R_CR2,R_CR3,R_CR4,
  197. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  198. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  199. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7,
  200. R_INTREGISTER,R_FLOATREGISTER,R_MMXREGISTER,R_KNIREGISTER
  201. );
  202. {Constants for subregisters.}
  203. const RS_L8 = 0; {Like AL}
  204. RS_H8 = 1; {Like AH}
  205. RS_16 = 2; {Like AX}
  206. RS_32 = 3; {Like EAX}
  207. RS_64 = 4; {Like RAX}
  208. type Tnewregister=word;
  209. Tregister = packed record
  210. enum:Toldregister;
  211. number:Tnewregister; {This is a word for now, change to cardinal
  212. when the old register coding is away.}
  213. end;
  214. {$packenum normal}
  215. { A type to store register locations for 64 Bit values. }
  216. tregister64 = packed record
  217. reglo,reghi : tregister;
  218. end;
  219. { alias for compact code }
  220. treg64 = tregister64;
  221. {# Set type definition for registers }
  222. tregisterset = set of Toldregister;
  223. Tsupregset = set of byte;
  224. const
  225. {# First register in the tregister enumeration }
  226. firstreg = low(Toldregister);
  227. {# Last register in the tregister enumeration }
  228. lastreg = R_XMM7;
  229. firstsreg = R_CS;
  230. lastsreg = R_GS;
  231. regset8bit : tregisterset = [R_AL..R_DH];
  232. regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
  233. regset32bit : tregisterset = [R_EAX..R_EDI];
  234. { Convert reg to opsize }
  235. reg2opsize : array[firstreg..lastreg] of topsize = (S_NO,
  236. S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
  237. S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
  238. S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
  239. S_W,S_W,S_W,S_W,S_W,S_W,
  240. S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
  241. S_L,S_L,S_L,S_L,S_L,S_L,
  242. S_L,S_L,S_L,S_L,
  243. S_L,S_L,S_L,S_L,S_L,
  244. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
  245. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
  246. );
  247. {Converts subregister number to opsize}
  248. subreg2opsize:array[0..4] of Topsize = (S_B,S_B,S_W,S_L,S_D);
  249. {# Standard opcode string table (for each tasmop enumeration). The
  250. opcode strings should conform to the names as defined by the
  251. processor manufacturer.
  252. }
  253. std_op2str:op2strtable={$i i386int.inc}
  254. type
  255. {# Type definition for the array of string of register names }
  256. reg2strtable = array[firstreg..lastreg] of string[6];
  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. TLoc=(
  341. LOC_INVALID, { added for tracking problems}
  342. LOC_CONSTANT, { constant value }
  343. LOC_JUMP, { boolean results only, jump to false or true label }
  344. LOC_FLAGS, { boolean results only, flags are set }
  345. LOC_CREFERENCE, { in memory constant value reference (cannot change) }
  346. LOC_REFERENCE, { in memory value }
  347. LOC_REGISTER, { in a processor register }
  348. LOC_CREGISTER, { Constant register which shouldn't be modified }
  349. LOC_FPUREGISTER, { FPU stack }
  350. LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack }
  351. LOC_MMXREGISTER, { MMX register }
  352. LOC_CMMXREGISTER, { MMX register variable }
  353. LOC_SSEREGISTER,
  354. LOC_CSSEREGISTER
  355. );
  356. { tparamlocation describes where a parameter for a procedure is stored.
  357. References are given from the caller's point of view. The usual
  358. TLocation isn't used, because contains a lot of unnessary fields.
  359. }
  360. tparalocation = packed record
  361. size : TCGSize;
  362. loc : TLoc;
  363. sp_fixup : longint;
  364. case TLoc of
  365. LOC_REFERENCE : (reference : tparareference);
  366. { segment in reference at the same place as in loc_register }
  367. LOC_REGISTER,LOC_CREGISTER : (
  368. case longint of
  369. 1 : (register,registerhigh : tregister);
  370. { overlay a registerlow }
  371. 2 : (registerlow : tregister);
  372. { overlay a 64 Bit register type }
  373. 3 : (reg64 : tregister64);
  374. 4 : (register64 : tregister64);
  375. );
  376. { it's only for better handling }
  377. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  378. end;
  379. tlocation = packed record
  380. loc : TLoc;
  381. size : TCGSize;
  382. case TLoc of
  383. LOC_FLAGS : (resflags : tresflags);
  384. LOC_CONSTANT : (
  385. case longint of
  386. 1 : (value : AWord);
  387. { can't do this, this layout depends on the host cpu. Use }
  388. { lo(valueqword)/hi(valueqword) instead (JM) }
  389. { 2 : (valuelow, valuehigh:AWord); }
  390. { overlay a complete 64 Bit value }
  391. 3 : (valueqword : qword);
  392. );
  393. LOC_CREFERENCE,
  394. LOC_REFERENCE : (reference : treference);
  395. { segment in reference at the same place as in loc_register }
  396. LOC_REGISTER,LOC_CREGISTER : (
  397. case longint of
  398. 1 : (register,registerhigh,segment : tregister);
  399. { overlay a registerlow }
  400. 2 : (registerlow : tregister);
  401. { overlay a 64 Bit register type }
  402. 3 : (reg64 : tregister64);
  403. 4 : (register64 : tregister64);
  404. );
  405. { it's only for better handling }
  406. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  407. end;
  408. {*****************************************************************************
  409. Constants
  410. *****************************************************************************}
  411. const
  412. { declare aliases }
  413. LOC_MMREGISTER = LOC_SSEREGISTER;
  414. LOC_CMMREGISTER = LOC_CSSEREGISTER;
  415. max_operands = 3;
  416. lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
  417. LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
  418. {# Constant defining possibly all registers which might require saving }
  419. ALL_REGISTERS = [firstreg..lastreg];
  420. general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
  421. {# low and high of the available maximum width integer general purpose }
  422. { registers }
  423. LoGPReg = R_EAX;
  424. HiGPReg = R_EDX;
  425. {# low and high of every possible width general purpose register (same as }
  426. { above on most architctures apart from the 80x86) }
  427. LoReg = R_EAX;
  428. HiReg = R_DH;
  429. {# Table of registers which can be allocated by the code generator
  430. internally, when generating the code.
  431. }
  432. { legend: }
  433. { xxxregs = set of all possibly used registers of that type in the code }
  434. { generator }
  435. { usableregsxxx = set of all 32bit components of registers that can be }
  436. { possible allocated to a regvar or using getregisterxxx (this }
  437. { excludes registers which can be only used for parameter }
  438. { passing on ABI's that define this) }
  439. { c_countusableregsxxx = amount of registers in the usableregsxxx set }
  440. maxintregs = 4;
  441. intregs = [R_EAX..R_BL];
  442. usableregsint = [R_EAX,R_EBX,R_ECX,R_EDX];
  443. c_countusableregsint = 4;
  444. maxfpuregs = 8;
  445. fpuregs = [R_ST0..R_ST7];
  446. usableregsfpu = [];
  447. c_countusableregsfpu = 0;
  448. mmregs = [R_MM0..R_MM7];
  449. usableregsmm = [R_MM0..R_MM7];
  450. c_countusableregsmm = 8;
  451. maxaddrregs = 0;
  452. addrregs = [];
  453. usableregsaddr = [];
  454. c_countusableregsaddr = 0;
  455. firstsaveintreg = R_EAX;
  456. lastsaveintreg = R_EBX;
  457. firstsavefpureg = R_NO;
  458. lastsavefpureg = R_NO;
  459. firstsavemmreg = R_MM0;
  460. lastsavemmreg = R_MM7;
  461. maxvarregs = 4;
  462. varregs : array[1..maxvarregs] of Toldregister =
  463. (R_EBX,R_EDX,R_ECX,R_EAX);
  464. maxfpuvarregs = 8;
  465. {# Registers which are defined as scratch and no need to save across
  466. routine calls or in assembler blocks.
  467. }
  468. max_scratch_regs = 1;
  469. scratch_regs : array[1..max_scratch_regs] of Toldregister = (R_EDI);
  470. {*****************************************************************************
  471. GDB Information
  472. *****************************************************************************}
  473. {# Register indexes for stabs information, when some
  474. parameters or variables are stored in registers.
  475. Taken from i386.c (dbx_register_map) and i386.h
  476. (FIXED_REGISTERS) from GCC 3.x source code
  477. }
  478. stab_regindex : array[firstreg..lastreg] of shortint =
  479. (-1,
  480. 0,1,2,3,4,5,6,7,
  481. 0,1,2,3,4,5,6,7,
  482. 0,1,2,3,0,1,2,3,
  483. -1,-1,-1,-1,-1,-1,
  484. 12,12,13,14,15,16,17,18,19,
  485. -1,-1,-1,-1,-1,-1,
  486. -1,-1,-1,-1,
  487. -1,-1,-1,-1,-1,
  488. 29,30,31,32,33,34,35,36,
  489. 21,22,23,24,25,26,27,28
  490. );
  491. {*****************************************************************************
  492. Default generic sizes
  493. *****************************************************************************}
  494. {# Defines the default address size for a processor, }
  495. OS_ADDR = OS_32;
  496. {# the natural int size for a processor, }
  497. OS_INT = OS_32;
  498. {# the maximum float size for a processor, }
  499. OS_FLOAT = OS_F80;
  500. {# the size of a vector register for a processor }
  501. OS_VECTOR = OS_M64;
  502. {*****************************************************************************
  503. Generic Register names
  504. *****************************************************************************}
  505. {# Stack pointer register }
  506. stack_pointer_reg = R_ESP;
  507. {# Frame pointer register }
  508. frame_pointer_reg = R_EBP;
  509. {# Self pointer register : contains the instance address of an
  510. object or class. }
  511. self_pointer_reg = R_ESI;
  512. {# Register for addressing absolute data in a position independant way,
  513. such as in PIC code. The exact meaning is ABI specific. For
  514. further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
  515. }
  516. pic_offset_reg = R_EBX;
  517. {# Results are returned in this register (32-bit values) }
  518. accumulator = R_EAX;
  519. {the return_result_reg, is used inside the called function to store its return
  520. value when that is a scalar value otherwise a pointer to the address of the
  521. result is placed inside it}
  522. return_result_reg = accumulator;
  523. {the function_result_reg contains the function result after a call to a scalar
  524. function othewise it contains a pointer to the returned result}
  525. function_result_reg = accumulator;
  526. {# Hi-Results are returned in this register (64-bit value high register) }
  527. accumulatorhigh = R_EDX;
  528. { WARNING: don't change to R_ST0!! See comments above implementation of }
  529. { a_loadfpu* methods in rgcpu (JM) }
  530. fpu_result_reg = R_ST;
  531. mmresultreg = R_MM0;
  532. {*****************************************************************************
  533. GCC /ABI linking information
  534. *****************************************************************************}
  535. const
  536. {# Registers which must be saved when calling a routine declared as
  537. cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
  538. saved should be the ones as defined in the target ABI and / or GCC.
  539. This value can be deduced from the CALLED_USED_REGISTERS array in the
  540. GCC source.
  541. }
  542. std_saved_registers = [R_ESI,R_EDI,R_EBX];
  543. {# Required parameter alignment when calling a routine declared as
  544. stdcall and cdecl. The alignment value should be the one defined
  545. by GCC or the target ABI.
  546. The value of this constant is equal to the constant
  547. PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
  548. }
  549. std_param_align = 4;
  550. {*****************************************************************************
  551. CPU Dependent Constants
  552. *****************************************************************************}
  553. {*****************************************************************************
  554. Helpers
  555. *****************************************************************************}
  556. procedure convert_register_to_enum(var r:Tregister);
  557. function is_calljmp(o:tasmop):boolean;
  558. function flags_to_cond(const f: TResFlags) : TAsmCond;
  559. implementation
  560. uses verbose;
  561. {*****************************************************************************
  562. Helpers
  563. *****************************************************************************}
  564. procedure convert_register_to_enum(var r:Tregister);
  565. begin
  566. if r.enum=R_INTREGISTER then
  567. case r.number of
  568. NR_NO: r.enum:=R_NO;
  569. NR_EAX: r.enum:=R_EAX; NR_EBX: r.enum:=R_EBX;
  570. NR_ECX: r.enum:=R_ECX; NR_EDX: r.enum:=R_EDX;
  571. NR_ESI: r.enum:=R_ESI; NR_EDI: r.enum:=R_EDI;
  572. NR_ESP: r.enum:=R_ESP; NR_EBP: r.enum:=R_EBP;
  573. NR_AX: r.enum:=R_AX; NR_BX: r.enum:=R_BX;
  574. NR_CX: r.enum:=R_CX; NR_DX: r.enum:=R_DX;
  575. NR_SI: r.enum:=R_SI; NR_DI: r.enum:=R_DI;
  576. NR_SP: r.enum:=R_SP; NR_BP: r.enum:=R_BP;
  577. NR_AL: r.enum:=R_AL; NR_BL: r.enum:=R_BL;
  578. NR_CL: r.enum:=R_CL; NR_DL: r.enum:=R_DL;
  579. NR_AH: r.enum:=R_AH; NR_BH: r.enum:=R_BH;
  580. NR_CH: r.enum:=R_CH; NR_DH: r.enum:=R_DH;
  581. NR_CS: r.enum:=R_CS; NR_DS: r.enum:=R_DS;
  582. NR_ES: r.enum:=R_ES; NR_FS: r.enum:=R_FS;
  583. NR_GS: r.enum:=R_GS; NR_SS: r.enum:=R_SS;
  584. else
  585. internalerror(200301082);
  586. end;
  587. end;
  588. function is_calljmp(o:tasmop):boolean;
  589. begin
  590. case o of
  591. A_CALL,
  592. A_JCXZ,
  593. A_JECXZ,
  594. A_JMP,
  595. A_LOOP,
  596. A_LOOPE,
  597. A_LOOPNE,
  598. A_LOOPNZ,
  599. A_LOOPZ,
  600. A_Jcc :
  601. is_calljmp:=true;
  602. else
  603. is_calljmp:=false;
  604. end;
  605. end;
  606. function flags_to_cond(const f: TResFlags) : TAsmCond;
  607. const
  608. flags_2_cond : array[TResFlags] of TAsmCond =
  609. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  610. begin
  611. result := flags_2_cond[f];
  612. end;
  613. end.
  614. {
  615. $Log$
  616. Revision 1.41 2003-02-02 19:25:54 carl
  617. * Several bugfixes for m68k target (register alloc., opcode emission)
  618. + VIS target
  619. + Generic add more complete (still not verified)
  620. Revision 1.40 2003/01/13 18:37:44 daniel
  621. * Work on register conversion
  622. Revision 1.39 2003/01/09 20:41:00 daniel
  623. * Converted some code in cgx86.pas to new register numbering
  624. Revision 1.38 2003/01/09 15:49:56 daniel
  625. * Added register conversion
  626. Revision 1.37 2003/01/08 22:32:36 daniel
  627. * Added register convesrion procedure
  628. Revision 1.36 2003/01/08 18:43:57 daniel
  629. * Tregister changed into a record
  630. Revision 1.35 2003/01/05 13:36:53 florian
  631. * x86-64 compiles
  632. + very basic support for float128 type (x86-64 only)
  633. Revision 1.34 2002/11/17 18:26:16 mazen
  634. * fixed a compilation bug accmulator-->accumulator, in definition of return_result_reg
  635. Revision 1.33 2002/11/17 17:49:08 mazen
  636. + 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
  637. Revision 1.32 2002/10/05 12:43:29 carl
  638. * fixes for Delphi 6 compilation
  639. (warning : Some features do not work under Delphi)
  640. Revision 1.31 2002/08/14 18:41:48 jonas
  641. - remove valuelow/valuehigh fields from tlocation, because they depend
  642. on the endianess of the host operating system -> difficult to get
  643. right. Use lo/hi(location.valueqword) instead (remember to use
  644. valueqword and not value!!)
  645. Revision 1.30 2002/08/13 21:40:58 florian
  646. * more fixes for ppc calling conventions
  647. Revision 1.29 2002/08/12 15:08:41 carl
  648. + stab register indexes for powerpc (moved from gdb to cpubase)
  649. + tprocessor enumeration moved to cpuinfo
  650. + linker in target_info is now a class
  651. * many many updates for m68k (will soon start to compile)
  652. - removed some ifdef or correct them for correct cpu
  653. Revision 1.28 2002/08/06 20:55:23 florian
  654. * first part of ppc calling conventions fix
  655. Revision 1.27 2002/07/25 18:01:29 carl
  656. + FPURESULTREG -> FPU_RESULT_REG
  657. Revision 1.26 2002/07/07 09:52:33 florian
  658. * powerpc target fixed, very simple units can be compiled
  659. * some basic stuff for better callparanode handling, far from being finished
  660. Revision 1.25 2002/07/01 18:46:30 peter
  661. * internal linker
  662. * reorganized aasm layer
  663. Revision 1.24 2002/07/01 16:23:55 peter
  664. * cg64 patch
  665. * basics for currency
  666. * asnode updates for class and interface (not finished)
  667. Revision 1.23 2002/05/18 13:34:22 peter
  668. * readded missing revisions
  669. Revision 1.22 2002/05/16 19:46:50 carl
  670. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  671. + try to fix temp allocation (still in ifdef)
  672. + generic constructor calls
  673. + start of tassembler / tmodulebase class cleanup
  674. Revision 1.19 2002/05/12 16:53:16 peter
  675. * moved entry and exitcode to ncgutil and cgobj
  676. * foreach gets extra argument for passing local data to the
  677. iterator function
  678. * -CR checks also class typecasts at runtime by changing them
  679. into as
  680. * fixed compiler to cycle with the -CR option
  681. * fixed stabs with elf writer, finally the global variables can
  682. be watched
  683. * removed a lot of routines from cga unit and replaced them by
  684. calls to cgobj
  685. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  686. u32bit then the other is typecasted also to u32bit without giving
  687. a rangecheck warning/error.
  688. * fixed pascal calling method with reversing also the high tree in
  689. the parast, detected by tcalcst3 test
  690. Revision 1.18 2002/04/21 15:31:40 carl
  691. - removed some other stuff to their units
  692. Revision 1.17 2002/04/20 21:37:07 carl
  693. + generic FPC_CHECKPOINTER
  694. + first parameter offset in stack now portable
  695. * rename some constants
  696. + move some cpu stuff to other units
  697. - remove unused constents
  698. * fix stacksize for some targets
  699. * fix generic size problems which depend now on EXTEND_SIZE constant
  700. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  701. Revision 1.16 2002/04/15 19:53:54 peter
  702. * fixed conflicts between the last 2 commits
  703. Revision 1.15 2002/04/15 19:44:20 peter
  704. * fixed stackcheck that would be called recursively when a stack
  705. error was found
  706. * generic changeregsize(reg,size) for i386 register resizing
  707. * removed some more routines from cga unit
  708. * fixed returnvalue handling
  709. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  710. Revision 1.14 2002/04/15 19:12:09 carl
  711. + target_info.size_of_pointer -> pointer_size
  712. + some cleanup of unused types/variables
  713. * move several constants from cpubase to their specific units
  714. (where they are used)
  715. + att_Reg2str -> gas_reg2str
  716. + int_reg2str -> std_reg2str
  717. Revision 1.13 2002/04/14 16:59:41 carl
  718. + att_reg2str -> gas_reg2str
  719. Revision 1.12 2002/04/02 17:11:34 peter
  720. * tlocation,treference update
  721. * LOC_CONSTANT added for better constant handling
  722. * secondadd splitted in multiple routines
  723. * location_force_reg added for loading a location to a register
  724. of a specified size
  725. * secondassignment parses now first the right and then the left node
  726. (this is compatible with Kylix). This saves a lot of push/pop especially
  727. with string operations
  728. * adapted some routines to use the new cg methods
  729. Revision 1.11 2002/03/31 20:26:37 jonas
  730. + a_loadfpu_* and a_loadmm_* methods in tcg
  731. * register allocation is now handled by a class and is mostly processor
  732. independent (+rgobj.pas and i386/rgcpu.pas)
  733. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  734. * some small improvements and fixes to the optimizer
  735. * some register allocation fixes
  736. * some fpuvaroffset fixes in the unary minus node
  737. * push/popusedregisters is now called rg.save/restoreusedregisters and
  738. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  739. also better optimizable)
  740. * fixed and optimized register saving/restoring for new/dispose nodes
  741. * LOC_FPU locations now also require their "register" field to be set to
  742. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  743. - list field removed of the tnode class because it's not used currently
  744. and can cause hard-to-find bugs
  745. Revision 1.10 2002/03/04 19:10:12 peter
  746. * removed compiler warnings
  747. }