cpubase.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  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. globals,cutils,cclasses,aasm,cpuinfo,cginfo;
  30. {*****************************************************************************
  31. Assembler Opcodes
  32. *****************************************************************************}
  33. type
  34. TAsmOp={$i i386op.inc}
  35. {# This should define the array of instructions as string }
  36. op2strtable=array[tasmop] of string[11];
  37. Const
  38. {# First value of opcode enumeration }
  39. firstop = low(tasmop);
  40. {# Last value of opcode enumeration }
  41. lastop = high(tasmop);
  42. {*****************************************************************************
  43. Operand Sizes
  44. *****************************************************************************}
  45. type
  46. topsize = (S_NO,
  47. S_B,S_W,S_L,S_BW,S_BL,S_WL,
  48. S_IS,S_IL,S_IQ,
  49. S_FS,S_FL,S_FX,S_D,S_Q,S_FV,
  50. S_NEAR,S_FAR,S_SHORT
  51. );
  52. {*****************************************************************************
  53. Registers
  54. *****************************************************************************}
  55. type
  56. {# Enumeration for all possible registers for cpu. It
  57. is to note that all registers of the same type
  58. (for example all FPU registers), should be grouped
  59. together.
  60. }
  61. { don't change the order }
  62. { it's used by the register size conversions }
  63. tregister = (R_NO,
  64. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  65. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  66. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  67. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  68. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  69. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  70. R_CR0,R_CR2,R_CR3,R_CR4,
  71. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  72. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  73. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
  74. );
  75. {# A type to store register locations for 64 Bit values. }
  76. tregister64 = packed record
  77. reglo,reghi : tregister;
  78. end;
  79. {# alias for compact code }
  80. treg64 = tregister64;
  81. {# Set type definition for registers }
  82. tregisterset = set of tregister;
  83. {# Type definition for the array of string of register names }
  84. reg2strtable = array[tregister] of string[6];
  85. const
  86. {# First register in the tregister enumeration }
  87. firstreg = low(tregister);
  88. {# Last register in the tregister enumeration }
  89. lastreg = high(tregister);
  90. firstsreg = R_CS;
  91. lastsreg = R_GS;
  92. regset8bit : tregisterset = [R_AL..R_DH];
  93. regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
  94. regset32bit : tregisterset = [R_EAX..R_EDI];
  95. { Convert reg to opsize }
  96. reg2opsize : array[firstreg..lastreg] of topsize = (S_NO,
  97. S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
  98. S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
  99. S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
  100. S_W,S_W,S_W,S_W,S_W,S_W,
  101. S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
  102. S_L,S_L,S_L,S_L,S_L,S_L,
  103. S_L,S_L,S_L,S_L,
  104. S_L,S_L,S_L,S_L,S_L,
  105. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
  106. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
  107. );
  108. {# Standard opcode string table (for each tasmop enumeration). The
  109. opcode strings should conform to the names as defined by the
  110. processor manufacturer.
  111. }
  112. std_op2str:op2strtable={$i i386int.inc}
  113. {# Standard register table (for each tregister enumeration). The
  114. register strings should conform to the the names as defined
  115. by the processor manufacturer
  116. }
  117. std_reg2str : reg2strtable = ('',
  118. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  119. 'ax','cx','dx','bx','sp','bp','si','di',
  120. 'al','cl','dl','bl','ah','ch','bh','dh',
  121. 'cs','ds','es','ss','fs','gs',
  122. 'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
  123. 'dr0','dr1','dr2','dr3','dr6','dr7',
  124. 'cr0','cr2','cr3','cr4',
  125. 'tr3','tr4','tr5','tr6','tr7',
  126. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  127. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  128. );
  129. {*****************************************************************************
  130. Conditions
  131. *****************************************************************************}
  132. type
  133. TAsmCond=(C_None,
  134. C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
  135. C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
  136. C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
  137. );
  138. const
  139. cond2str:array[TAsmCond] of string[3]=('',
  140. 'a','ae','b','be','c','e','g','ge','l','le','na','nae',
  141. 'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
  142. 'ns','nz','o','p','pe','po','s','z'
  143. );
  144. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  145. C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
  146. C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
  147. C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
  148. );
  149. {*****************************************************************************
  150. Flags
  151. *****************************************************************************}
  152. type
  153. 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);
  154. {*****************************************************************************
  155. Reference
  156. *****************************************************************************}
  157. type
  158. trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
  159. { reference record }
  160. preference = ^treference;
  161. treference = packed record
  162. segment,
  163. base,
  164. index : tregister;
  165. scalefactor : byte;
  166. offset : longint;
  167. symbol : tasmsymbol;
  168. offsetfixup : longint;
  169. options : trefoptions;
  170. end;
  171. {*****************************************************************************
  172. Operands
  173. *****************************************************************************}
  174. { Types of operand }
  175. toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
  176. toper=record
  177. ot : longint;
  178. case typ : toptype of
  179. top_none : ();
  180. top_reg : (reg:tregister);
  181. top_ref : (ref:preference);
  182. top_const : (val:aword);
  183. top_symbol : (sym:tasmsymbol;symofs:longint);
  184. end;
  185. {*****************************************************************************
  186. Generic Location
  187. *****************************************************************************}
  188. type
  189. TLoc=(
  190. LOC_INVALID, { added for tracking problems}
  191. LOC_CONSTANT, { constant value }
  192. LOC_JUMP, { boolean results only, jump to false or true label }
  193. LOC_FLAGS, { boolean results only, flags are set }
  194. LOC_CREFERENCE, { in memory constant value reference (cannot change) }
  195. LOC_REFERENCE, { in memory value }
  196. LOC_REGISTER, { in a processor register }
  197. LOC_CREGISTER, { Constant register which shouldn't be modified }
  198. LOC_FPUREGISTER, { FPU stack }
  199. LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack }
  200. LOC_MMXREGISTER, { MMX register }
  201. LOC_CMMXREGISTER, { MMX register variable }
  202. LOC_SSEREGISTER,
  203. LOC_CSSEREGISTER
  204. );
  205. tlocation = packed record
  206. loc : TLoc;
  207. size : TCGSize;
  208. case TLoc of
  209. LOC_FLAGS : (resflags : tresflags);
  210. LOC_CONSTANT : (
  211. case longint of
  212. 1 : (value : AWord);
  213. 2 : (valuelow, valuehigh:AWord);
  214. { overlay a complete 64 Bit value }
  215. 3 : (valueqword : qword);
  216. );
  217. LOC_CREFERENCE,
  218. LOC_REFERENCE : (reference : treference);
  219. { segment in reference at the same place as in loc_register }
  220. LOC_REGISTER,LOC_CREGISTER : (
  221. case longint of
  222. 1 : (register,registerhigh,segment : tregister);
  223. { overlay a registerlow }
  224. 2 : (registerlow : tregister);
  225. { overlay a 64 Bit register type }
  226. 3 : (reg64 : tregister64);
  227. 4 : (register64 : tregister64);
  228. );
  229. { it's only for better handling }
  230. LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
  231. end;
  232. {*****************************************************************************
  233. Constants
  234. *****************************************************************************}
  235. const
  236. max_operands = 3;
  237. lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
  238. LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
  239. {# Constant defining possibly all registers which might require saving }
  240. ALL_REGISTERS = [firstreg..lastreg];
  241. general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
  242. {# low and high of the available maximum width integer general purpose }
  243. { registers }
  244. LoGPReg = R_EAX;
  245. HiGPReg = R_EDX;
  246. {# low and high of every possible width general purpose register (same as }
  247. { above on most architctures apart from the 80x86) }
  248. LoReg = R_EAX;
  249. HiReg = R_DH;
  250. {# Table of registers which can be allocated by the code generator
  251. internally, when generating the code.
  252. }
  253. { legend: }
  254. { xxxregs = set of all possibly used registers of that type in the code }
  255. { generator }
  256. { usableregsxxx = set of all 32bit components of registers that can be }
  257. { possible allocated to a regvar or using getregisterxxx (this }
  258. { excludes registers which can be only used for parameter }
  259. { passing on ABI's that define this) }
  260. { c_countusableregsxxx = amount of registers in the usableregsxxx set }
  261. maxintregs = 4;
  262. intregs = [R_EAX..R_BL];
  263. usableregsint = [R_EAX,R_EBX,R_ECX,R_EDX];
  264. c_countusableregsint = 4;
  265. maxfpuregs = 8;
  266. fpuregs = [R_ST0..R_ST7];
  267. usableregsfpu = [];
  268. c_countusableregsfpu = 0;
  269. mmregs = [R_MM0..R_MM7];
  270. usableregsmm = [R_MM0..R_MM7];
  271. c_countusableregsmm = 8;
  272. firstsaveintreg = R_EAX;
  273. lastsaveintreg = R_EBX;
  274. firstsavefpureg = R_NO;
  275. lastsavefpureg = R_NO;
  276. firstsavemmreg = R_MM0;
  277. lastsavemmreg = R_MM7;
  278. maxvarregs = 4;
  279. varregs : array[1..maxvarregs] of tregister =
  280. (R_EBX,R_EDX,R_ECX,R_EAX);
  281. maxfpuvarregs = 8;
  282. {# Registers which are defined as scratch and no need to save across
  283. routine calls or in assembler blocks.
  284. }
  285. max_scratch_regs = 1;
  286. scratch_regs : array[1..max_scratch_regs] of tregister = (R_EDI);
  287. {*****************************************************************************
  288. Default generic sizes
  289. *****************************************************************************}
  290. {# Defines the default address size for a processor, }
  291. OS_ADDR = OS_32;
  292. {# the natural int size for a processor, }
  293. OS_INT = OS_32;
  294. {# the maximum float size for a processor, }
  295. OS_FLOAT = OS_F80;
  296. {# the size of a vector register for a processor }
  297. OS_VECTOR = OS_M64;
  298. {*****************************************************************************
  299. Generic Register names
  300. *****************************************************************************}
  301. {# Stack pointer register }
  302. stack_pointer_reg = R_ESP;
  303. {# Frame pointer register }
  304. frame_pointer_reg = R_EBP;
  305. {# Self pointer register : contains the instance address of an
  306. object or class. }
  307. self_pointer_reg = R_ESI;
  308. {# Register for addressing absolute data in a position independant way,
  309. such as in PIC code. The exact meaning is ABI specific }
  310. pic_offset_reg = R_EBX;
  311. {# Results are returned in this register (32-bit values) }
  312. accumulator = R_EAX;
  313. {# Hi-Results are returned in this register (64-bit value high register) }
  314. accumulatorhigh = R_EDX;
  315. { WARNING: don't change to R_ST0!! See comments above implementation of }
  316. { a_loadfpu* methods in rgcpu (JM) }
  317. fpuresultreg = R_ST;
  318. mmresultreg = R_MM0;
  319. {*****************************************************************************
  320. GCC /ABI linking information
  321. *****************************************************************************}
  322. const
  323. {# Registers which must be saved when calling a routine declared as
  324. cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
  325. saved should be the ones as defined in the target ABI and / or GCC.
  326. This value can be deduced from the CALLED_USED_REGISTERS array in the
  327. GCC source.
  328. }
  329. std_saved_registers = [R_ESI,R_EDI,R_EBX];
  330. {# Required parameter alignment when calling a routine declared as
  331. stdcall and cdecl. The alignment value should be the one defined
  332. by GCC or the target ABI.
  333. The value of this constant is equal to the constant
  334. PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
  335. }
  336. std_param_align = 4;
  337. {*****************************************************************************
  338. CPU Dependent Constants
  339. *****************************************************************************}
  340. {*****************************************************************************
  341. Helpers
  342. *****************************************************************************}
  343. function is_calljmp(o:tasmop):boolean;
  344. function flags_to_cond(const f: TResFlags) : TAsmCond;
  345. implementation
  346. {*****************************************************************************
  347. Helpers
  348. *****************************************************************************}
  349. function is_calljmp(o:tasmop):boolean;
  350. begin
  351. case o of
  352. A_CALL,
  353. A_JCXZ,
  354. A_JECXZ,
  355. A_JMP,
  356. A_LOOP,
  357. A_LOOPE,
  358. A_LOOPNE,
  359. A_LOOPNZ,
  360. A_LOOPZ,
  361. A_Jcc :
  362. is_calljmp:=true;
  363. else
  364. is_calljmp:=false;
  365. end;
  366. end;
  367. function flags_to_cond(const f: TResFlags) : TAsmCond;
  368. const
  369. flags_2_cond : array[TResFlags] of TAsmCond =
  370. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  371. begin
  372. result := flags_2_cond[f];
  373. end;
  374. end.
  375. {
  376. $Log$
  377. Revision 1.24 2002-07-01 16:23:55 peter
  378. * cg64 patch
  379. * basics for currency
  380. * asnode updates for class and interface (not finished)
  381. Revision 1.23 2002/05/18 13:34:22 peter
  382. * readded missing revisions
  383. Revision 1.22 2002/05/16 19:46:50 carl
  384. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  385. + try to fix temp allocation (still in ifdef)
  386. + generic constructor calls
  387. + start of tassembler / tmodulebase class cleanup
  388. Revision 1.19 2002/05/12 16:53:16 peter
  389. * moved entry and exitcode to ncgutil and cgobj
  390. * foreach gets extra argument for passing local data to the
  391. iterator function
  392. * -CR checks also class typecasts at runtime by changing them
  393. into as
  394. * fixed compiler to cycle with the -CR option
  395. * fixed stabs with elf writer, finally the global variables can
  396. be watched
  397. * removed a lot of routines from cga unit and replaced them by
  398. calls to cgobj
  399. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  400. u32bit then the other is typecasted also to u32bit without giving
  401. a rangecheck warning/error.
  402. * fixed pascal calling method with reversing also the high tree in
  403. the parast, detected by tcalcst3 test
  404. Revision 1.18 2002/04/21 15:31:40 carl
  405. - removed some other stuff to their units
  406. Revision 1.17 2002/04/20 21:37:07 carl
  407. + generic FPC_CHECKPOINTER
  408. + first parameter offset in stack now portable
  409. * rename some constants
  410. + move some cpu stuff to other units
  411. - remove unused constents
  412. * fix stacksize for some targets
  413. * fix generic size problems which depend now on EXTEND_SIZE constant
  414. * removing frame pointer in routines is only available for : i386,m68k and vis targets
  415. Revision 1.16 2002/04/15 19:53:54 peter
  416. * fixed conflicts between the last 2 commits
  417. Revision 1.15 2002/04/15 19:44:20 peter
  418. * fixed stackcheck that would be called recursively when a stack
  419. error was found
  420. * generic changeregsize(reg,size) for i386 register resizing
  421. * removed some more routines from cga unit
  422. * fixed returnvalue handling
  423. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  424. Revision 1.14 2002/04/15 19:12:09 carl
  425. + target_info.size_of_pointer -> pointer_size
  426. + some cleanup of unused types/variables
  427. * move several constants from cpubase to their specific units
  428. (where they are used)
  429. + att_Reg2str -> gas_reg2str
  430. + int_reg2str -> std_reg2str
  431. Revision 1.13 2002/04/14 16:59:41 carl
  432. + att_reg2str -> gas_reg2str
  433. Revision 1.12 2002/04/02 17:11:34 peter
  434. * tlocation,treference update
  435. * LOC_CONSTANT added for better constant handling
  436. * secondadd splitted in multiple routines
  437. * location_force_reg added for loading a location to a register
  438. of a specified size
  439. * secondassignment parses now first the right and then the left node
  440. (this is compatible with Kylix). This saves a lot of push/pop especially
  441. with string operations
  442. * adapted some routines to use the new cg methods
  443. Revision 1.11 2002/03/31 20:26:37 jonas
  444. + a_loadfpu_* and a_loadmm_* methods in tcg
  445. * register allocation is now handled by a class and is mostly processor
  446. independent (+rgobj.pas and i386/rgcpu.pas)
  447. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  448. * some small improvements and fixes to the optimizer
  449. * some register allocation fixes
  450. * some fpuvaroffset fixes in the unary minus node
  451. * push/popusedregisters is now called rg.save/restoreusedregisters and
  452. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  453. also better optimizable)
  454. * fixed and optimized register saving/restoring for new/dispose nodes
  455. * LOC_FPU locations now also require their "register" field to be set to
  456. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  457. - list field removed of the tnode class because it's not used currently
  458. and can cause hard-to-find bugs
  459. Revision 1.10 2002/03/04 19:10:12 peter
  460. * removed compiler warnings
  461. }