cpubase.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. globals,cutils,cclasses,aasm,cpuinfo,cginfo;
  30. const
  31. { Size of the instruction table converted by nasmconv.pas }
  32. instabentries = {$i i386nop.inc}
  33. maxinfolen = 8;
  34. { By default we want everything }
  35. {$define ATTOP}
  36. {$define INTELOP}
  37. {$define ITTABLE}
  38. { We Don't need the intel style opcodes if we don't have a intel
  39. reader or generator }
  40. {$ifdef NORA386INT}
  41. {$ifdef NOAG386NSM}
  42. {$ifdef NOAG386INT}
  43. {$undef INTELOP}
  44. {$endif}
  45. {$endif}
  46. {$endif}
  47. { We Don't need the AT&T style opcodes if we don't have a AT&T
  48. reader or generator }
  49. {$ifdef NORA386ATT}
  50. {$ifdef NOAG386ATT}
  51. {$undef ATTOP}
  52. {$ifdef NOAG386DIR}
  53. {$undef ATTREG}
  54. {$endif}
  55. {$endif}
  56. {$endif}
  57. { We need the AT&T suffix table for both asm readers and AT&T writer }
  58. {$define ATTSUF}
  59. {$ifdef NORA386INT}
  60. {$ifdef NORA386ATT}
  61. {$ifdef NOAG386ATT}
  62. {$undef ATTSUF}
  63. {$endif}
  64. {$endif}
  65. {$endif}
  66. const
  67. { Operand types }
  68. OT_NONE = $00000000;
  69. OT_BITS8 = $00000001; { size, and other attributes, of the operand }
  70. OT_BITS16 = $00000002;
  71. OT_BITS32 = $00000004;
  72. OT_BITS64 = $00000008; { FPU only }
  73. OT_BITS80 = $00000010;
  74. OT_FAR = $00000020; { this means 16:16 or 16:32, like in CALL/JMP }
  75. OT_NEAR = $00000040;
  76. OT_SHORT = $00000080;
  77. OT_SIZE_MASK = $000000FF; { all the size attributes }
  78. OT_NON_SIZE = longint(not OT_SIZE_MASK);
  79. OT_SIGNED = $00000100; { the operand need to be signed -128-127 }
  80. OT_TO = $00000200; { operand is followed by a colon }
  81. { reverse effect in FADD, FSUB &c }
  82. OT_COLON = $00000400;
  83. OT_REGISTER = $00001000;
  84. OT_IMMEDIATE = $00002000;
  85. OT_IMM8 = $00002001;
  86. OT_IMM16 = $00002002;
  87. OT_IMM32 = $00002004;
  88. OT_IMM64 = $00002008;
  89. OT_IMM80 = $00002010;
  90. OT_REGMEM = $00200000; { for r/m, ie EA, operands }
  91. OT_REGNORM = $00201000; { 'normal' reg, qualifies as EA }
  92. OT_REG8 = $00201001;
  93. OT_REG16 = $00201002;
  94. OT_REG32 = $00201004;
  95. OT_MMXREG = $00201008; { MMX registers }
  96. OT_XMMREG = $00201010; { Katmai registers }
  97. OT_MEMORY = $00204000; { register number in 'basereg' }
  98. OT_MEM8 = $00204001;
  99. OT_MEM16 = $00204002;
  100. OT_MEM32 = $00204004;
  101. OT_MEM64 = $00204008;
  102. OT_MEM80 = $00204010;
  103. OT_FPUREG = $01000000; { floating point stack registers }
  104. OT_FPU0 = $01000800; { FPU stack register zero }
  105. OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
  106. { a mask for the following }
  107. OT_REG_ACCUM = $00211000; { accumulator: AL, AX or EAX }
  108. OT_REG_AL = $00211001; { REG_ACCUM | BITSxx }
  109. OT_REG_AX = $00211002; { ditto }
  110. OT_REG_EAX = $00211004; { and again }
  111. OT_REG_COUNT = $00221000; { counter: CL, CX or ECX }
  112. OT_REG_CL = $00221001; { REG_COUNT | BITSxx }
  113. OT_REG_CX = $00221002; { ditto }
  114. OT_REG_ECX = $00221004; { another one }
  115. OT_REG_DX = $00241002;
  116. OT_REG_SREG = $00081002; { any segment register }
  117. OT_REG_CS = $01081002; { CS }
  118. OT_REG_DESS = $02081002; { DS, ES, SS (non-CS 86 registers) }
  119. OT_REG_FSGS = $04081002; { FS, GS (386 extended registers) }
  120. OT_REG_CDT = $00101004; { CRn, DRn and TRn }
  121. OT_REG_CREG = $08101004; { CRn }
  122. OT_REG_CR4 = $08101404; { CR4 (Pentium only) }
  123. OT_REG_DREG = $10101004; { DRn }
  124. OT_REG_TREG = $20101004; { TRn }
  125. OT_MEM_OFFS = $00604000; { special type of EA }
  126. { simple [address] offset }
  127. OT_ONENESS = $00800000; { special type of immediate operand }
  128. { so UNITY == IMMEDIATE | ONENESS }
  129. OT_UNITY = $00802000; { for shift/rotate instructions }
  130. {Instruction flags }
  131. IF_NONE = $00000000;
  132. IF_SM = $00000001; { size match first two operands }
  133. IF_SM2 = $00000002;
  134. IF_SB = $00000004; { unsized operands can't be non-byte }
  135. IF_SW = $00000008; { unsized operands can't be non-word }
  136. IF_SD = $00000010; { unsized operands can't be nondword }
  137. IF_AR0 = $00000020; { SB, SW, SD applies to argument 0 }
  138. IF_AR1 = $00000040; { SB, SW, SD applies to argument 1 }
  139. IF_AR2 = $00000060; { SB, SW, SD applies to argument 2 }
  140. IF_ARMASK = $00000060; { mask for unsized argument spec }
  141. IF_PRIV = $00000100; { it's a privileged instruction }
  142. IF_SMM = $00000200; { it's only valid in SMM }
  143. IF_PROT = $00000400; { it's protected mode only }
  144. IF_UNDOC = $00001000; { it's an undocumented instruction }
  145. IF_FPU = $00002000; { it's an FPU instruction }
  146. IF_MMX = $00004000; { it's an MMX instruction }
  147. IF_3DNOW = $00008000; { it's a 3DNow! instruction }
  148. IF_SSE = $00010000; { it's a SSE (KNI, MMX2) instruction }
  149. IF_PMASK =
  150. longint($FF000000); { the mask for processor types }
  151. IF_PFMASK =
  152. longint($F001FF00); { the mask for disassembly "prefer" }
  153. IF_8086 = $00000000; { 8086 instruction }
  154. IF_186 = $01000000; { 186+ instruction }
  155. IF_286 = $02000000; { 286+ instruction }
  156. IF_386 = $03000000; { 386+ instruction }
  157. IF_486 = $04000000; { 486+ instruction }
  158. IF_PENT = $05000000; { Pentium instruction }
  159. IF_P6 = $06000000; { P6 instruction }
  160. IF_KATMAI = $07000000; { Katmai instructions }
  161. IF_CYRIX = $10000000; { Cyrix-specific instruction }
  162. IF_AMD = $20000000; { AMD-specific instruction }
  163. { added flags }
  164. IF_PRE = $40000000; { it's a prefix instruction }
  165. IF_PASS2 =
  166. longint($80000000); { if the instruction can change in a second pass }
  167. type
  168. TAsmOp={$i i386op.inc}
  169. {# This should define the array of instructions as string }
  170. op2strtable=array[tasmop] of string[11];
  171. Const
  172. {# First value of opcode enumeration }
  173. firstop = low(tasmop);
  174. {# Last value of opcode enumeration }
  175. lastop = high(tasmop);
  176. {*****************************************************************************
  177. Operand Sizes
  178. *****************************************************************************}
  179. type
  180. topsize = (S_NO,
  181. S_B,S_W,S_L,S_BW,S_BL,S_WL,
  182. S_IS,S_IL,S_IQ,
  183. S_FS,S_FL,S_FX,S_D,S_Q,S_FV,
  184. S_NEAR,S_FAR,S_SHORT
  185. );
  186. const
  187. { Intel style operands ! }
  188. opsize_2_type:array[0..2,topsize] of longint=(
  189. (OT_NONE,
  190. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
  191. OT_BITS16,OT_BITS32,OT_BITS64,
  192. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
  193. OT_NEAR,OT_FAR,OT_SHORT
  194. ),
  195. (OT_NONE,
  196. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
  197. OT_BITS16,OT_BITS32,OT_BITS64,
  198. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
  199. OT_NEAR,OT_FAR,OT_SHORT
  200. ),
  201. (OT_NONE,
  202. OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
  203. OT_BITS16,OT_BITS32,OT_BITS64,
  204. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
  205. OT_NEAR,OT_FAR,OT_SHORT
  206. )
  207. );
  208. {*****************************************************************************
  209. Conditions
  210. *****************************************************************************}
  211. type
  212. TAsmCond=(C_None,
  213. C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
  214. C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
  215. C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
  216. );
  217. const
  218. cond2str:array[TAsmCond] of string[3]=('',
  219. 'a','ae','b','be','c','e','g','ge','l','le','na','nae',
  220. 'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
  221. 'ns','nz','o','p','pe','po','s','z'
  222. );
  223. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  224. C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
  225. C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
  226. C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
  227. );
  228. {*****************************************************************************
  229. Registers
  230. *****************************************************************************}
  231. type
  232. {# Enumeration for all possible registers for cpu. It
  233. is to note that all registers of the same type
  234. (for example all FPU registers), should be grouped
  235. together.
  236. }
  237. { don't change the order }
  238. { it's used by the register size conversions }
  239. tregister = (R_NO,
  240. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  241. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  242. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  243. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  244. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  245. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  246. R_CR0,R_CR2,R_CR3,R_CR4,
  247. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  248. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  249. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
  250. );
  251. {# Set type definition for registers }
  252. tregisterset = set of tregister;
  253. {# Type definition for the array of string of register nnames }
  254. reg2strtable = array[tregister] of string[6];
  255. const
  256. {# First register in the tregister enumeration }
  257. firstreg = low(tregister);
  258. {# Last register in the tregister enumeration }
  259. lastreg = high(tregister);
  260. firstsreg = R_CS;
  261. lastsreg = R_GS;
  262. regset8bit : tregisterset = [R_AL..R_DH];
  263. regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
  264. regset32bit : tregisterset = [R_EAX..R_EDI];
  265. { Convert reg to opsize }
  266. reg2opsize : array[firstreg..lastreg] of topsize = (S_NO,
  267. S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
  268. S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
  269. S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
  270. S_W,S_W,S_W,S_W,S_W,S_W,
  271. S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
  272. S_L,S_L,S_L,S_L,S_L,S_L,
  273. S_L,S_L,S_L,S_L,
  274. S_L,S_L,S_L,S_L,S_L,
  275. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
  276. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
  277. );
  278. { Convert reg to operand type }
  279. reg2type : array[firstreg..lastreg] of longint = (OT_NONE,
  280. OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
  281. OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
  282. OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
  283. OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
  284. OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
  285. OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
  286. OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
  287. OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
  288. OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
  289. OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
  290. );
  291. {# Standard opcode string table (for each tasmop enumeration). The
  292. opcode strings should conform to the names as defined by the
  293. processor manufacturer.
  294. }
  295. std_op2str:op2strtable={$i i386int.inc}
  296. {# Standard register table (for each tregister enumeration). The
  297. register strings should conform to the the names as defined
  298. by the processor manufacturer
  299. }
  300. std_reg2str : reg2strtable = ('',
  301. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  302. 'ax','cx','dx','bx','sp','bp','si','di',
  303. 'al','cl','dl','bl','ah','ch','bh','dh',
  304. 'cs','ds','es','ss','fs','gs',
  305. 'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
  306. 'dr0','dr1','dr2','dr3','dr6','dr7',
  307. 'cr0','cr2','cr3','cr4',
  308. 'tr3','tr4','tr5','tr6','tr7',
  309. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  310. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  311. );
  312. {*****************************************************************************
  313. Flags
  314. *****************************************************************************}
  315. type
  316. 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);
  317. {*****************************************************************************
  318. Reference
  319. *****************************************************************************}
  320. type
  321. trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
  322. type
  323. { immediate/reference record }
  324. poperreference = ^treference;
  325. treference = packed record
  326. segment,
  327. base,
  328. index : tregister;
  329. scalefactor : byte;
  330. offset : longint;
  331. symbol : tasmsymbol;
  332. offsetfixup : longint;
  333. options : trefoptions;
  334. end;
  335. {*****************************************************************************
  336. Operands
  337. *****************************************************************************}
  338. { Types of operand }
  339. toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
  340. toper=record
  341. ot : longint;
  342. case typ : toptype of
  343. top_none : ();
  344. top_reg : (reg:tregister);
  345. top_ref : (ref:poperreference);
  346. top_const : (val:aword);
  347. top_symbol : (sym:tasmsymbol;symofs:longint);
  348. end;
  349. {*****************************************************************************
  350. Argument Classification
  351. *****************************************************************************}
  352. {*****************************************************************************
  353. Generic Location
  354. *****************************************************************************}
  355. type
  356. TLoc=(
  357. LOC_INVALID, { added for tracking problems}
  358. LOC_CONSTANT, { constant value }
  359. LOC_JUMP, { boolean results only, jump to false or true label }
  360. LOC_FLAGS, { boolean results only, flags are set }
  361. LOC_CREFERENCE, { in memory constant value reference (cannot change) }
  362. LOC_REFERENCE, { in memory value }
  363. LOC_REGISTER, { in a processor register }
  364. LOC_CREGISTER, { Constant register which shouldn't be modified }
  365. LOC_FPUREGISTER, { FPU stack }
  366. LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack }
  367. LOC_MMXREGISTER, { MMX register }
  368. LOC_CMMXREGISTER, { MMX register variable }
  369. LOC_SSEREGISTER,
  370. LOC_CSSEREGISTER
  371. );
  372. plocation = ^tlocation;
  373. tlocation = packed record
  374. loc : TLoc;
  375. size : TCGSize;
  376. case TLoc of
  377. LOC_FLAGS : (resflags : tresflags);
  378. LOC_CONSTANT : (
  379. case longint of
  380. 1 : (value : AWord);
  381. 2 : (valuelow, valuehigh:AWord);
  382. );
  383. LOC_CREFERENCE,
  384. LOC_REFERENCE : (reference : treference);
  385. { segment in reference at the same place as in loc_register }
  386. LOC_REGISTER,LOC_CREGISTER : (
  387. case longint of
  388. 1 : (register,segment,registerhigh : tregister);
  389. { overlay a registerlow }
  390. 2 : (registerlow : tregister);
  391. );
  392. { it's only for better handling }
  393. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  394. end;
  395. {*****************************************************************************
  396. Constants
  397. *****************************************************************************}
  398. const
  399. general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
  400. {# Table of registers which can be allocated by the code generator
  401. internally, when generating the code.
  402. }
  403. { legend: }
  404. { xxxregs = set of all possibly used registers of that type in the code }
  405. { generator }
  406. { usableregsxxx = set of all 32bit components of registers that can be }
  407. { possible allocated to a regvar or using getregisterxxx (this }
  408. { excludes registers which can be only used for parameter }
  409. { passing on ABI's that define this) }
  410. { c_countusableregsxxx = amount of registers in the usableregsxxx set }
  411. intregs = [R_EAX..R_BL];
  412. usableregsint = general_registers;
  413. c_countusableregsint = 4;
  414. fpuregs = [R_ST0..R_ST7];
  415. usableregsfpu = [];
  416. c_countusableregsfpu = 0;
  417. mmregs = [R_MM0..R_MM7];
  418. usableregsmm = [R_MM0..R_MM7];
  419. c_countusableregsmm = 8;
  420. firstsaveintreg = R_EAX;
  421. lastsaveintreg = R_EBX;
  422. firstsavefpureg = R_NO;
  423. lastsavefpureg = R_NO;
  424. firstsavemmreg = R_MM0;
  425. lastsavemmreg = R_MM7;
  426. {# Constant defining possibly all registers which might require saving }
  427. ALL_REGISTERS = [firstreg..lastreg];
  428. lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
  429. LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
  430. {*****************************************************************************
  431. Default generic sizes
  432. *****************************************************************************}
  433. {# Defines the default address size for a processor, }
  434. OS_ADDR = OS_32;
  435. {# the natural int size for a processor, }
  436. OS_INT = OS_32;
  437. {# the maximum float size for a processor, }
  438. OS_FLOAT = OS_F80;
  439. {# the size of a vector register for a processor }
  440. OS_VECTOR = OS_M64;
  441. {*****************************************************************************
  442. Generic Register names
  443. *****************************************************************************}
  444. {# Stack pointer register }
  445. stack_pointer_reg = R_ESP;
  446. {# Frame pointer register }
  447. frame_pointer_reg = R_EBP;
  448. {# Self pointer register : contains the instance address of an
  449. object or class. }
  450. self_pointer_reg = R_ESI;
  451. {# Register for addressing absolute data in a position independant way,
  452. such as in PIC code. The exact meaning is ABI specific }
  453. pic_offset_reg = R_EBX;
  454. {# Results are returned in this register (32-bit values) }
  455. accumulator = R_EAX;
  456. {# Hi-Results are returned in this register (64-bit value high register) }
  457. accumulatorhigh = R_EDX;
  458. { WARNING: don't change to R_ST0!! See comments above implementation of }
  459. { a_loadfpu* methods in rgcpu (JM) }
  460. fpuresultreg = R_ST;
  461. mmresultreg = R_MM0;
  462. {# Registers which are defined as scratch and no need to save across
  463. routine calls or in assembler blocks.
  464. }
  465. scratch_regs : array[1..1] of tregister = (R_EDI);
  466. {*****************************************************************************
  467. GCC /ABI linking information
  468. *****************************************************************************}
  469. {# Registers which must be saved when calling a routine declared as
  470. cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
  471. saved should be the ones as defined in the target ABI and / or GCC.
  472. This value can be deduced from the CALLED_USED_REGISTERS array in the
  473. GCC source.
  474. }
  475. std_saved_registers = [R_ESI,R_EDI,R_EBX];
  476. {# Required parameter alignment when calling a routine declared as
  477. stdcall and cdecl. The alignment value should be the one defined
  478. by GCC or the target ABI.
  479. The value of this constant is equal to the constant
  480. PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
  481. }
  482. std_param_align = 4;
  483. {*****************************************************************************
  484. Helpers
  485. *****************************************************************************}
  486. const
  487. maxvarregs = 4;
  488. varregs : array[1..maxvarregs] of tregister =
  489. (R_EBX,R_EDX,R_ECX,R_EAX);
  490. maxfpuvarregs = 8;
  491. max_operands = 3;
  492. maxintregs = maxvarregs;
  493. maxfpuregs = maxfpuvarregs;
  494. function is_calljmp(o:tasmop):boolean;
  495. function flags_to_cond(const f: TResFlags) : TAsmCond;
  496. implementation
  497. {$ifdef heaptrc}
  498. uses
  499. ppheap;
  500. {$endif heaptrc}
  501. {*****************************************************************************
  502. Helpers
  503. *****************************************************************************}
  504. function is_calljmp(o:tasmop):boolean;
  505. begin
  506. case o of
  507. A_CALL,
  508. A_JCXZ,
  509. A_JECXZ,
  510. A_JMP,
  511. A_LOOP,
  512. A_LOOPE,
  513. A_LOOPNE,
  514. A_LOOPNZ,
  515. A_LOOPZ,
  516. A_Jcc :
  517. is_calljmp:=true;
  518. else
  519. is_calljmp:=false;
  520. end;
  521. end;
  522. function flags_to_cond(const f: TResFlags) : TAsmCond;
  523. const
  524. flags_2_cond : array[TResFlags] of TAsmCond =
  525. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  526. begin
  527. result := flags_2_cond[f];
  528. end;
  529. end.
  530. {
  531. $Log$
  532. Revision 1.22 2002-05-16 19:46:50 carl
  533. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  534. + try to fix temp allocation (still in ifdef)
  535. + generic constructor calls
  536. + start of tassembler / tmodulebase class cleanup
  537. Revision 1.19 2002/05/12 16:53:16 peter
  538. * moved entry and exitcode to ncgutil and cgobj
  539. * foreach gets extra argument for passing local data to the
  540. iterator function
  541. * -CR checks also class typecasts at runtime by changing them
  542. into as
  543. * fixed compiler to cycle with the -CR option
  544. * fixed stabs with elf writer, finally the global variables can
  545. be watched
  546. * removed a lot of routines from cga unit and replaced them by
  547. calls to cgobj
  548. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  549. u32bit then the other is typecasted also to u32bit without giving
  550. a rangecheck warning/error.
  551. * fixed pascal calling method with reversing also the high tree in
  552. the parast, detected by tcalcst3 test
  553. Revision 1.18 2002/04/21 15:31:40 carl
  554. - removed some other stuff to their units
  555. Revision 1.17 2002/04/20 21:37:07 carl
  556. + generic FPC_CHECKPOINTER
  557. + first parameter offset in stack now portable
  558. * rename some constants
  559. + move some cpu stuff to other units
  560. - remove unused constents
  561. * fix stacksize for some targets
  562. * fix generic size problems which depend now on EXTEND_SIZE constant
  563. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  564. Revision 1.16 2002/04/15 19:53:54 peter
  565. * fixed conflicts between the last 2 commits
  566. Revision 1.15 2002/04/15 19:44:20 peter
  567. * fixed stackcheck that would be called recursively when a stack
  568. error was found
  569. * generic changeregsize(reg,size) for i386 register resizing
  570. * removed some more routines from cga unit
  571. * fixed returnvalue handling
  572. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  573. Revision 1.14 2002/04/15 19:12:09 carl
  574. + target_info.size_of_pointer -> pointer_size
  575. + some cleanup of unused types/variables
  576. * move several constants from cpubase to their specific units
  577. (where they are used)
  578. + att_Reg2str -> gas_reg2str
  579. + int_reg2str -> std_reg2str
  580. Revision 1.13 2002/04/14 16:59:41 carl
  581. + att_reg2str -> gas_reg2str
  582. Revision 1.12 2002/04/02 17:11:34 peter
  583. * tlocation,treference update
  584. * LOC_CONSTANT added for better constant handling
  585. * secondadd splitted in multiple routines
  586. * location_force_reg added for loading a location to a register
  587. of a specified size
  588. * secondassignment parses now first the right and then the left node
  589. (this is compatible with Kylix). This saves a lot of push/pop especially
  590. with string operations
  591. * adapted some routines to use the new cg methods
  592. Revision 1.11 2002/03/31 20:26:37 jonas
  593. + a_loadfpu_* and a_loadmm_* methods in tcg
  594. * register allocation is now handled by a class and is mostly processor
  595. independent (+rgobj.pas and i386/rgcpu.pas)
  596. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  597. * some small improvements and fixes to the optimizer
  598. * some register allocation fixes
  599. * some fpuvaroffset fixes in the unary minus node
  600. * push/popusedregisters is now called rg.save/restoreusedregisters and
  601. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  602. also better optimizable)
  603. * fixed and optimized register saving/restoring for new/dispose nodes
  604. * LOC_FPU locations now also require their "register" field to be set to
  605. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  606. - list field removed of the tnode class because it's not used currently
  607. and can cause hard-to-find bugs
  608. Revision 1.10 2002/03/04 19:10:12 peter
  609. * removed compiler warnings
  610. Revision 1.9 2001/12/30 17:24:46 jonas
  611. * range checking is now processor independent (part in cgobj,
  612. part in cg64f32) and should work correctly again (it needed
  613. some changes after the changes of the low and high of
  614. tordef's to int64)
  615. * maketojumpbool() is now processor independent (in ncgutil)
  616. * getregister32 is now called getregisterint
  617. Revision 1.8 2001/12/29 15:29:59 jonas
  618. * powerpc/cgcpu.pas compiles :)
  619. * several powerpc-related fixes
  620. * cpuasm unit is now based on common tainst unit
  621. + nppcmat unit for powerpc (almost complete)
  622. Revision 1.7 2001/12/06 17:57:40 florian
  623. + parasym to tparaitem added
  624. Revision 1.6 2001/09/28 20:39:33 jonas
  625. * changed all flow control structures (except for exception handling
  626. related things) to processor independent code (in new ncgflw unit)
  627. + generic cgobj unit which contains lots of code generator helpers with
  628. global "cg" class instance variable
  629. + cgcpu unit for i386 (implements processor specific routines of the above
  630. unit)
  631. * updated cgbase and cpubase for the new code generator units
  632. * include ncgflw unit in cpunode unit
  633. Revision 1.5 2001/05/18 23:01:13 peter
  634. * portable constants
  635. Revision 1.4 2001/04/13 01:22:18 peter
  636. * symtable change to classes
  637. * range check generation and errors fixed, make cycle DEBUG=1 works
  638. * memory leaks fixed
  639. Revision 1.3 2001/02/20 21:34:04 peter
  640. * iret, lret fixes
  641. Revision 1.2 2000/12/07 17:19:45 jonas
  642. * new constant handling: from now on, hex constants >$7fffffff are
  643. parsed as unsigned constants (otherwise, $80000000 got sign extended
  644. and became $ffffffff80000000), all constants in the longint range
  645. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  646. are cardinals and the rest are int64's.
  647. * added lots of longint typecast to prevent range check errors in the
  648. compiler and rtl
  649. * type casts of symbolic ordinal constants are now preserved
  650. * fixed bug where the original resulttype wasn't restored correctly
  651. after doing a 64bit rangecheck
  652. Revision 1.1 2000/10/15 09:39:37 peter
  653. * moved cpu*.pas to i386/
  654. * renamed n386 to common cpunode
  655. Revision 1.7 2000/09/26 20:06:13 florian
  656. * hmm, still a lot of work to get things compilable
  657. Revision 1.6 2000/09/24 15:06:14 peter
  658. * use defines.inc
  659. Revision 1.5 2000/08/27 16:11:50 peter
  660. * moved some util functions from globals,cobjects to cutils
  661. * splitted files into finput,fmodule
  662. Revision 1.4 2000/08/05 13:25:06 peter
  663. * packenum 1 fixes (merged)
  664. Revision 1.3 2000/07/14 05:11:48 michael
  665. + Patch to 1.1
  666. Revision 1.2 2000/07/13 11:32:39 michael
  667. + removed logs
  668. }