cpubase.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Contains the base types for the PowerPC
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. { This Unit contains the base types for the PowerPC
  19. }
  20. unit cpubase;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. strings,cutils,cclasses,aasmbase,cpuinfo,cgbase;
  25. {*****************************************************************************
  26. Assembler Opcodes
  27. *****************************************************************************}
  28. type
  29. TAsmOp=(A_None,
  30. { normal opcodes }
  31. a_add, a_add_, a_addo, a_addo_, a_addc, a_addc_, a_addco, a_addco_,
  32. a_adde, a_adde_, a_addeo, a_addeo_, a_addi, a_addic, a_addic_, a_addis,
  33. a_addme, a_addme_, a_addmeo, a_addmeo_, a_addze, a_addze_, a_addzeo,
  34. a_addzeo_, a_and, a_and_, a_andc, a_andc_, a_andi_, a_andis_, a_b,
  35. a_ba, a_bl, a_bla, a_bc, a_bca, a_bcl, a_bcla, a_bcctr, a_bcctrl, a_bclr,
  36. a_bclrl, a_cmp, a_cmpi, a_cmpl, a_cmpli, a_cntlzw, a_cntlzw_, a_crand,
  37. a_crandc, a_creqv, a_crnand, a_crnor, a_cror, a_crorc, a_crxor, a_dcba,
  38. a_dcbf, a_dcbi, a_dcbst, a_dcbt, a_dcbtst, a_dcbz, a_divw, a_divw_, a_divwo, a_divwo_,
  39. a_divwu, a_divwu_, a_divwuo, a_divwuo_, a_eciwx, a_ecowx, a_eieio, a_eqv,
  40. a_eqv_, a_extsb, a_extsb_, a_extsh, a_extsh_, a_fabs, a_fabs_, a_fadd,
  41. a_fadd_, a_fadds, a_fadds_, a_fcmpo, a_fcmpu, a_fctiw, a_fctw_, a_fctwz,
  42. a_fctwz_, a_fdiv, a_fdiv_, a_fdivs, a_fdivs_, a_fmadd, a_fmadd_, a_fmadds,
  43. a_fmadds_, a_fmr, a_fmsub, a_fmsub_, a_fmsubs, a_fmsubs_, a_fmul, a_fmul_,
  44. a_fmuls, a_fmuls_, a_fnabs, a_fnabs_, a_fneg, a_fneg_, a_fnmadd,
  45. a_fnmadd_, a_fnmadds, a_fnmadds_, a_fnmsub, a_fnmsub_, a_fnmsubs,
  46. a_fnmsubs_, a_fres, a_fres_, a_frsp, a_frsp_, a_frsqrte, a_frsqrte_,
  47. a_fsel, a_fsel_, a_fsqrt, a_fsqrt_, a_fsqrts, a_fsqrts_, a_fsub, a_fsub_,
  48. a_fsubs, a_fsubs_, a_icbi, a_isync, a_lbz, a_lbzu, a_lbzux, a_lbzx,
  49. a_lfd, a_lfdu, a_lfdux, a_lfdx, a_lfs, a_lfsu, a_lfsux, a_lfsx, a_lha,
  50. a_lhau, a_lhaux, a_lhax, a_hbrx, a_lhz, a_lhzu, a_lhzux, a_lhzx, a_lmw,
  51. a_lswi, a_lswx, a_lwarx, a_lwbrx, a_lwz, a_lwzu, a_lwzux, a_lwzx, a_mcrf,
  52. a_mcrfs, a_mcrxr, a_lcrxe, a_mfcr, a_mffs, a_maffs_, a_mfmsr, a_mfspr, a_mfsr,
  53. a_mfsrin, a_mftb, a_mtcrf, a_mtfsb0, a_mtfsb1, a_mtfsf, a_mtfsf_,
  54. a_mtfsfi, a_mtfsfi_, a_mtmsr, a_mtspr, a_mtsr, a_mtsrin, a_mulhw,
  55. a_mulhw_, a_mulhwu, a_mulhwu_, a_mulli, a_mullw, a_mullw_, a_mullwo,
  56. a_mullwo_, a_nand, a_nand_, a_neg, a_neg_, a_nego, a_nego_, a_nor, a_nor_,
  57. a_or, a_or_, a_orc, a_orc_, a_ori, a_oris, a_rfi, a_rlwimi, a_rlwimi_,
  58. a_rlwinm, a_rlwinm_, a_rlwnm, a_sc, a_slw, a_slw_, a_sraw, a_sraw_,
  59. a_srawi, a_srawi_,a_srw, a_srw_, a_stb, a_stbu, a_stbux, a_stbx, a_stfd,
  60. a_stfdu, a_stfdux, a_stfdx, a_stfiwx, a_stfs, a_stfsu, a_stfsux, a_stfsx,
  61. a_sth, a_sthbrx, a_sthu, a_sthux, a_sthx, a_stmw, a_stswi, a_stswx, a_stw,
  62. a_stwbrx, a_stwcx_, a_stwu, a_stwux, a_stwx, a_subf, a_subf_, a_subfo,
  63. a_subfo_, a_subfc, a_subfc_, a_subfco, a_subfco_, a_subfe, a_subfe_,
  64. a_subfeo, a_subfeo_, a_subfic, a_subfme, a_subfme_, a_subfmeo, a_subfmeo_,
  65. a_subfze, a_subfze_, a_subfzeo, a_subfzeo_, a_sync, a_tlbia, a_tlbie,
  66. a_tlbsync, a_tw, a_twi, a_xor, a_xor_, a_xori, a_xoris,
  67. { simplified mnemonics }
  68. a_subi, a_subis, a_subic, a_subic_, a_sub, a_sub_, a_subo, a_subo_,
  69. a_subc, a_subc_, a_subco, a_subco_, a_cmpwi, a_cmpw, a_cmplwi, a_cmplw,
  70. a_extlwi, a_extlwi_, a_extrwi, a_extrwi_, a_inslwi, a_inslwi_, a_insrwi,
  71. a_insrwi_, a_rotlwi, a_rotlwi_, a_rotlw, a_rotlw_, a_slwi, a_slwi_,
  72. a_srwi, a_srwi_, a_clrlwi, a_clrlwi_, a_clrrwi, a_clrrwi_, a_clrslwi,
  73. a_clrslwi_, a_blr, a_bctr, a_blrl, a_bctrl, a_crset, a_crclr, a_crmove,
  74. a_crnot, a_mt {move to special prupose reg}, a_mf {move from special purpose reg},
  75. a_nop, a_li, a_lis, a_la, a_mr, a_mr_, a_not, a_mtcr, a_mtlr, a_mflr,
  76. a_mtctr, a_mfctr);
  77. {# This should define the array of instructions as string }
  78. op2strtable=array[tasmop] of string[8];
  79. Const
  80. {# First value of opcode enumeration }
  81. firstop = low(tasmop);
  82. {# Last value of opcode enumeration }
  83. lastop = high(tasmop);
  84. {*****************************************************************************
  85. Registers
  86. *****************************************************************************}
  87. type
  88. { Number of registers used for indexing in tables }
  89. tregisterindex=0..{$i rppcnor.inc}-1;
  90. totherregisterset = set of tregisterindex;
  91. const
  92. maxvarregs = 32-6; { 32 int registers - r0 - stackpointer - r2 - 3 scratch registers }
  93. maxfpuvarregs = 28; { 32 fpuregisters - some scratch registers (minimally 2) }
  94. { Available Superregisters }
  95. {$i rppcsup.inc}
  96. { No Subregisters }
  97. R_SUBWHOLE=R_SUBNONE;
  98. { Available Registers }
  99. {$i rppccon.inc}
  100. { Integer Super registers first and last }
  101. first_int_imreg = $20;
  102. { Float Super register first and last }
  103. first_fpu_imreg = $20;
  104. { MM Super register first and last }
  105. first_mm_imreg = $20;
  106. {$warning TODO Calculate bsstart}
  107. regnumber_count_bsstart = 64;
  108. regnumber_table : array[tregisterindex] of tregister = (
  109. {$i rppcnum.inc}
  110. );
  111. regstabs_table : array[tregisterindex] of shortint = (
  112. {$i rppcstab.inc}
  113. );
  114. { registers which may be destroyed by calls }
  115. VOLATILE_INTREGISTERS = [RS_R3..RS_R12];
  116. {$warning FIXME!!}
  117. { FIXME: only R_F1..R_F8 under the SYSV ABI -> has to become a }
  118. { typed const (JM) }
  119. VOLATILE_FPUREGISTERS = [RS_F3..RS_F13];
  120. {*****************************************************************************
  121. Conditions
  122. *****************************************************************************}
  123. type
  124. TAsmCondFlag = (C_None { unconditional jumps },
  125. { conditions when not using ctr decrement etc }
  126. C_LT,C_LE,C_EQ,C_GE,C_GT,C_NL,C_NE,C_NG,C_SO,C_NS,C_UN,C_NU,
  127. { conditions when using ctr decrement etc }
  128. C_T,C_F,C_DNZ,C_DNZT,C_DNZF,C_DZ,C_DZT,C_DZF);
  129. TDirHint = (DH_None,DH_Minus,DH_Plus);
  130. const
  131. { these are in the XER, but when moved to CR_x they correspond with the }
  132. { bits below }
  133. C_OV = C_GT;
  134. C_CA = C_EQ;
  135. C_NO = C_NG;
  136. C_NC = C_NE;
  137. type
  138. TAsmCond = packed record
  139. dirhint : tdirhint;
  140. case simple: boolean of
  141. false: (BO, BI: byte);
  142. true: (
  143. cond: TAsmCondFlag;
  144. case byte of
  145. 0: ();
  146. { specifies in which part of the cr the bit has to be }
  147. { tested for blt,bgt,beq,..,bnu }
  148. 1: (cr: RS_CR0..RS_CR7);
  149. { specifies the bit to test for bt,bf,bdz,..,bdzf }
  150. 2: (crbit: byte)
  151. );
  152. end;
  153. const
  154. AsmCondFlag2BO: Array[C_T..C_DZF] of Byte =
  155. (12,4,16,8,0,18,10,2);
  156. AsmCondFlag2BOLT_NU: Array[C_LT..C_NU] of Byte =
  157. (12,4,12,4,12,4,4,4,12,4,12,4);
  158. AsmCondFlag2BI: Array[C_LT..C_NU] of Byte =
  159. (0,1,2,0,1,0,2,1,3,3,3,3);
  160. AsmCondFlagTF: Array[TAsmCondFlag] of Boolean =
  161. (false,true,false,true,false,true,false,false,false,true,false,true,false,
  162. true,false,false,true,false,false,true,false);
  163. AsmCondFlag2Str: Array[TAsmCondFlag] of string[4] = ({cf_none}'',
  164. { conditions when not using ctr decrement etc}
  165. 'lt','le','eq','ge','gt','nl','ne','ng','so','ns','un','nu',
  166. 't','f','dnz','dnzt','dnzf','dz','dzt','dzf');
  167. UpperAsmCondFlag2Str: Array[TAsmCondFlag] of string[4] = ({cf_none}'',
  168. { conditions when not using ctr decrement etc}
  169. 'LT','LE','EQ','GE','GT','NL','NE','NG','SO','NS','UN','NU',
  170. 'T','F','DNZ','DNZT','DNZF','DZ','DZT','DZF');
  171. const
  172. CondAsmOps=3;
  173. CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
  174. A_BC, A_TW, A_TWI
  175. );
  176. {*****************************************************************************
  177. Flags
  178. *****************************************************************************}
  179. type
  180. TResFlagsEnum = (F_EQ,F_NE,F_LT,F_LE,F_GT,F_GE,F_SO,F_FX,F_FEX,F_VX,F_OX);
  181. TResFlags = record
  182. cr: RS_CR0..RS_CR7;
  183. flag: TResFlagsEnum;
  184. end;
  185. (*
  186. const
  187. { arrays for boolean location conversions }
  188. flag_2_cond : array[TResFlags] of TAsmCond =
  189. (C_E,C_NE,C_LT,C_LE,C_GT,C_GE,???????????????);
  190. *)
  191. {*****************************************************************************
  192. Reference
  193. *****************************************************************************}
  194. type
  195. trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
  196. { reference record }
  197. preference = ^treference;
  198. treference = packed record
  199. { base register, R_NO if none }
  200. base,
  201. { index register, R_NO if none }
  202. index : tregister;
  203. { offset, 0 if none }
  204. offset : aint;
  205. { symbol this reference refers to, nil if none }
  206. symbol : tasmsymbol;
  207. { symbol the symbol of this reference is relative to, nil if none }
  208. relsymbol : tasmsymbol;
  209. { reference type addr or symbol itself }
  210. refaddr : trefaddr;
  211. { alignment this reference is guaranteed to have }
  212. alignment : byte;
  213. end;
  214. { reference record }
  215. pparareference = ^tparareference;
  216. tparareference = packed record
  217. index : tregister;
  218. offset : aword;
  219. end;
  220. const
  221. symaddr2str: array[trefaddr] of string[3] = ('','','@ha','@l');
  222. const
  223. { MacOS only. Whether the direct data area (TOC) directly contain
  224. global variables. Otherwise it contains pointers to global variables. }
  225. macos_direct_globals = false;
  226. {*****************************************************************************
  227. Operand Sizes
  228. *****************************************************************************}
  229. {*****************************************************************************
  230. Generic Location
  231. *****************************************************************************}
  232. type
  233. { tparamlocation describes where a parameter for a procedure is stored.
  234. References are given from the caller's point of view. The usual
  235. TLocation isn't used, because contains a lot of unnessary fields.
  236. }
  237. tparalocation = packed record
  238. size : TCGSize;
  239. { The location type where the parameter is passed, usually
  240. LOC_REFERENCE,LOC_REGISTER or LOC_FPUREGISTER
  241. }
  242. loc : TCGLoc;
  243. lochigh : TCGLoc;
  244. { Word alignment on stack 4 --> 32 bit }
  245. Alignment:Byte;
  246. case TCGLoc of
  247. LOC_REFERENCE : (reference : tparareference);
  248. LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
  249. LOC_REGISTER,LOC_CREGISTER : (
  250. case longint of
  251. 1 : (register,registerhigh : tregister);
  252. { overlay a registerlow }
  253. 2 : (registerlow : tregister);
  254. { overlay a 64 Bit register type }
  255. 3 : (reg64 : tregister64);
  256. 4 : (register64 : tregister64);
  257. );
  258. end;
  259. treglocation = packed record
  260. case longint of
  261. 1 : (register,registerhigh : tregister);
  262. { overlay a registerlow }
  263. 2 : (registerlow : tregister);
  264. { overlay a 64 Bit register type }
  265. 3 : (reg64 : tregister64);
  266. 4 : (register64 : tregister64);
  267. end;
  268. tlocation = packed record
  269. size : TCGSize;
  270. loc : tcgloc;
  271. case tcgloc of
  272. LOC_CREFERENCE,LOC_REFERENCE : (reference : treference);
  273. LOC_CONSTANT : (
  274. case longint of
  275. {$ifdef FPC_BIG_ENDIAN}
  276. 1 : (_valuedummy,value : AWord);
  277. {$else FPC_BIG_ENDIAN}
  278. 1 : (value : AWord);
  279. {$endif FPC_BIG_ENDIAN}
  280. { can't do this, this layout depends on the host cpu. Use }
  281. { lo(valueqword)/hi(valueqword) instead (JM) }
  282. { 2 : (valuelow, valuehigh:AWord); }
  283. { overlay a complete 64 Bit value }
  284. 3 : (valueqword : qword);
  285. );
  286. LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
  287. LOC_REGISTER,LOC_CREGISTER : (
  288. case longint of
  289. 1 : (registerlow,registerhigh : tregister);
  290. 2 : (register : tregister);
  291. { overlay a 64 Bit register type }
  292. 3 : (reg64 : tregister64);
  293. 4 : (register64 : tregister64);
  294. );
  295. LOC_FLAGS : (resflags : tresflags);
  296. end;
  297. {*****************************************************************************
  298. Constants
  299. *****************************************************************************}
  300. const
  301. max_operands = 5;
  302. {*****************************************************************************
  303. Default generic sizes
  304. *****************************************************************************}
  305. {# Defines the default address size for a processor, }
  306. OS_ADDR = OS_32;
  307. {# the natural int size for a processor, }
  308. OS_INT = OS_32;
  309. {# the maximum float size for a processor, }
  310. OS_FLOAT = OS_F64;
  311. {# the size of a vector register for a processor }
  312. OS_VECTOR = OS_M128;
  313. {*****************************************************************************
  314. GDB Information
  315. *****************************************************************************}
  316. {# Register indexes for stabs information, when some
  317. parameters or variables are stored in registers.
  318. Taken from rs6000.h (DBX_REGISTER_NUMBER)
  319. from GCC 3.x source code. PowerPC has 1:1 mapping
  320. according to the order of the registers defined
  321. in GCC
  322. }
  323. stab_regindex : array[tregisterindex] of shortint = (
  324. {$i rppcstab.inc}
  325. );
  326. {*****************************************************************************
  327. Generic Register names
  328. *****************************************************************************}
  329. {# Stack pointer register }
  330. NR_STACK_POINTER_REG = NR_R1;
  331. RS_STACK_POINTER_REG = RS_R1;
  332. {# Frame pointer register }
  333. NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
  334. RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
  335. {# Register for addressing absolute data in a position independant way,
  336. such as in PIC code. The exact meaning is ABI specific. For
  337. further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
  338. Taken from GCC rs6000.h
  339. }
  340. {$warning As indicated in rs6000.h, but can't find it anywhere else!}
  341. NR_PIC_OFFSET_REG = NR_R30;
  342. { Results are returned in this register (32-bit values) }
  343. NR_FUNCTION_RETURN_REG = NR_R3;
  344. RS_FUNCTION_RETURN_REG = RS_R3;
  345. { Low part of 64bit return value }
  346. NR_FUNCTION_RETURN64_LOW_REG = NR_R4;
  347. RS_FUNCTION_RETURN64_LOW_REG = RS_R4;
  348. { High part of 64bit return value }
  349. NR_FUNCTION_RETURN64_HIGH_REG = NR_R3;
  350. RS_FUNCTION_RETURN64_HIGH_REG = RS_R3;
  351. { The value returned from a function is available in this register }
  352. NR_FUNCTION_RESULT_REG = NR_FUNCTION_RETURN_REG;
  353. RS_FUNCTION_RESULT_REG = RS_FUNCTION_RETURN_REG;
  354. { The lowh part of 64bit value returned from a function }
  355. NR_FUNCTION_RESULT64_LOW_REG = NR_FUNCTION_RETURN64_LOW_REG;
  356. RS_FUNCTION_RESULT64_LOW_REG = RS_FUNCTION_RETURN64_LOW_REG;
  357. { The high part of 64bit value returned from a function }
  358. NR_FUNCTION_RESULT64_HIGH_REG = NR_FUNCTION_RETURN64_HIGH_REG;
  359. RS_FUNCTION_RESULT64_HIGH_REG = RS_FUNCTION_RETURN64_HIGH_REG;
  360. NR_FPU_RESULT_REG = NR_F1;
  361. NR_MM_RESULT_REG = NR_M0;
  362. {*****************************************************************************
  363. GCC /ABI linking information
  364. *****************************************************************************}
  365. {# Registers which must be saved when calling a routine declared as
  366. cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
  367. saved should be the ones as defined in the target ABI and / or GCC.
  368. This value can be deduced from CALLED_USED_REGISTERS array in the
  369. GCC source.
  370. }
  371. std_saved_registers = [RS_R13..RS_R29];
  372. {# Required parameter alignment when calling a routine declared as
  373. stdcall and cdecl. The alignment value should be the one defined
  374. by GCC or the target ABI.
  375. The value of this constant is equal to the constant
  376. PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
  377. }
  378. std_param_align = 4; { for 32-bit version only }
  379. {*****************************************************************************
  380. CPU Dependent Constants
  381. *****************************************************************************}
  382. LinkageAreaSizeAIX = 24;
  383. LinkageAreaSizeSYSV = 8;
  384. { offset in the linkage area for the saved stack pointer }
  385. LA_SP = 0;
  386. { offset in the linkage area for the saved conditional register}
  387. LA_CR_AIX = 4;
  388. { offset in the linkage area for the saved link register}
  389. LA_LR_AIX = 8;
  390. LA_LR_SYSV = 4;
  391. { offset in the linkage area for the saved RTOC register}
  392. LA_RTOC_AIX = 20;
  393. PARENT_FRAMEPOINTER_OFFSET = 12;
  394. NR_RTOC = NR_R2;
  395. {*****************************************************************************
  396. Helpers
  397. *****************************************************************************}
  398. function is_calljmp(o:tasmop):boolean;
  399. procedure inverse_flags(var r : TResFlags);
  400. procedure inverse_cond(const c: TAsmCond;var r : TAsmCond);
  401. function flags_to_cond(const f: TResFlags) : TAsmCond;
  402. procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
  403. procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
  404. function cgsize2subreg(s:Tcgsize):Tsubregister;
  405. function findreg_by_number(r:Tregister):tregisterindex;
  406. function std_regnum_search(const s:string):Tregister;
  407. function std_regname(r:Tregister):string;
  408. function is_condreg(r : tregister):boolean;
  409. implementation
  410. uses
  411. rgBase,verbose;
  412. const
  413. std_regname_table : array[tregisterindex] of string[7] = (
  414. {$i rppcstd.inc}
  415. );
  416. regnumber_index : array[tregisterindex] of tregisterindex = (
  417. {$i rppcrni.inc}
  418. );
  419. std_regname_index : array[tregisterindex] of tregisterindex = (
  420. {$i rppcsri.inc}
  421. );
  422. {*****************************************************************************
  423. Helpers
  424. *****************************************************************************}
  425. function is_calljmp(o:tasmop):boolean;
  426. begin
  427. is_calljmp:=false;
  428. case o of
  429. A_B,A_BA,A_BL,A_BLA,A_BC,A_BCA,A_BCL,A_BCLA,A_BCCTR,A_BCCTRL,A_BCLR,
  430. A_BCLRL,A_TW,A_TWI: is_calljmp:=true;
  431. end;
  432. end;
  433. procedure inverse_flags(var r: TResFlags);
  434. const
  435. inv_flags: array[F_EQ..F_GE] of TResFlagsEnum =
  436. (F_NE,F_EQ,F_GE,F_GE,F_LE,F_LT);
  437. begin
  438. r.flag := inv_flags[r.flag];
  439. end;
  440. procedure inverse_cond(const c: TAsmCond;var r : TAsmCond);
  441. const
  442. inv_condflags:array[TAsmCondFlag] of TAsmCondFlag=(C_None,
  443. C_GE,C_GT,C_NE,C_LT,C_LE,C_LT,C_EQ,C_GT,C_NS,C_SO,C_NU,C_UN,
  444. C_F,C_T,C_DNZ,C_DNZF,C_DNZT,C_DZ,C_DZF,C_DZT);
  445. begin
  446. r := c;
  447. r.cond := inv_condflags[c.cond];
  448. end;
  449. function flags_to_cond(const f: TResFlags) : TAsmCond;
  450. const
  451. flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag =
  452. (C_EQ,C_NE,C_LT,C_LE,C_GT,C_GE,C_SO);
  453. begin
  454. if f.flag > high(flag_2_cond) then
  455. internalerror(200112301);
  456. result.simple := true;
  457. result.cr := f.cr;
  458. result.cond := flag_2_cond[f.flag];
  459. end;
  460. procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
  461. begin
  462. r.simple := false;
  463. r.bo := bo;
  464. r.bi := bi;
  465. end;
  466. procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
  467. begin
  468. r.simple := true;
  469. r.cond := cond;
  470. case cond of
  471. C_NONE:;
  472. C_T..C_DZF: r.crbit := cr
  473. else r.cr := RS_CR0+cr;
  474. end;
  475. end;
  476. function is_condreg(r : tregister):boolean;
  477. var
  478. supreg: tsuperregister;
  479. begin
  480. result := false;
  481. if (getregtype(r) = R_SPECIALREGISTER) then
  482. begin
  483. supreg := getsupreg(r);
  484. result := (supreg >= RS_CR0) and (supreg <= RS_CR7);
  485. end;
  486. end;
  487. function cgsize2subreg(s:Tcgsize):Tsubregister;
  488. begin
  489. cgsize2subreg:=R_SUBWHOLE;
  490. end;
  491. function findreg_by_number(r:Tregister):tregisterindex;
  492. begin
  493. result:=rgBase.findreg_by_number_table(r,regnumber_index);
  494. end;
  495. function std_regnum_search(const s:string):Tregister;
  496. begin
  497. result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)];
  498. end;
  499. function std_regname(r:Tregister):string;
  500. var
  501. p : tregisterindex;
  502. begin
  503. p:=findreg_by_number_table(r,regnumber_index);
  504. if p<>0 then
  505. result:=std_regname_table[p]
  506. else
  507. result:=generic_regname(r);
  508. end;
  509. end.
  510. {
  511. $Log$
  512. Revision 1.86 2004-02-27 10:21:05 florian
  513. * top_symbol killed
  514. + refaddr to treference added
  515. + refsymbol to treference added
  516. * top_local stuff moved to an extra record to save memory
  517. + aint introduced
  518. * tppufile.get/putint64/aint implemented
  519. Revision 1.85 2004/02/09 22:45:49 florian
  520. * compilation fixed
  521. Revision 1.84 2004/02/08 18:08:59 jonas
  522. * fixed regvars support. Needs -doldregvars to activate. Only tested with
  523. ppc, other processors should however only require maxregvars and
  524. maxfpuregvars constants in cpubase.pas. Remember to take scratch-
  525. registers into account when defining that value.
  526. Revision 1.83 2004/01/30 13:42:03 florian
  527. * fixed more alignment issues
  528. Revision 1.82 2004/01/10 00:16:21 jonas
  529. * fixed mtfsb0 instruction for assembler reader/writer
  530. * fixed initialisation of fpscr register to avoid spurious SIGPFE's
  531. (uses mtfsb0 instruction, so added extra define in options.pas to avoid
  532. requiring to start with a cross compiler)
  533. Revision 1.81 2003/12/16 21:49:47 florian
  534. * fixed ppc compilation
  535. Revision 1.80 2003/12/09 20:39:43 jonas
  536. * forgot call to cg.g_overflowcheck() in nppcadd
  537. * fixed overflow flag definition
  538. * fixed cg.g_overflowcheck() for signed numbers (jump over call to
  539. FPC_OVERFLOW if *no* overflow instead of if overflow :)
  540. Revision 1.79 2003/11/29 16:27:19 jonas
  541. * fixed several ppc assembler reader related problems
  542. * local vars in assembler procedures now start at offset 4
  543. * fixed second_int_to_bool (apparently an integer can be in LOC_JUMP??)
  544. Revision 1.78 2003/11/23 20:00:39 jonas
  545. * fixed is_condreg
  546. * fixed branch condition parsing in assembler reader
  547. Revision 1.77 2003/11/15 19:00:10 florian
  548. * fixed ppc assembler reader
  549. Revision 1.76 2003/11/12 16:05:40 florian
  550. * assembler readers OOPed
  551. + typed currency constants
  552. + typed 128 bit float constants if the CPU supports it
  553. Revision 1.75 2003/10/31 08:42:28 mazen
  554. * rgHelper renamed to rgBase
  555. * using findreg_by_<name|number>_table directly to decrease heap overheading
  556. Revision 1.74 2003/10/30 15:03:18 mazen
  557. * now uses standard routines in rgBase unit to search registers by number and by name
  558. Revision 1.73 2003/10/19 01:34:31 florian
  559. * some ppc stuff fixed
  560. * memory leak fixed
  561. Revision 1.72 2003/10/17 15:08:34 peter
  562. * commented out more obsolete constants
  563. Revision 1.71 2003/10/11 16:06:42 florian
  564. * fixed some MMX<->SSE
  565. * started to fix ppc, needs an overhaul
  566. + stabs info improve for spilling, not sure if it works correctly/completly
  567. - MMX_SUPPORT removed from Makefile.fpc
  568. Revision 1.70 2003/10/08 14:11:36 mazen
  569. + Alignement field added to TParaLocation (=4 as 32 bits archs)
  570. Revision 1.69 2003/10/01 20:34:49 peter
  571. * procinfo unit contains tprocinfo
  572. * cginfo renamed to cgbase
  573. * moved cgmessage to verbose
  574. * fixed ppc and sparc compiles
  575. Revision 1.68 2003/09/14 16:37:20 jonas
  576. * fixed some ppc problems
  577. Revision 1.67 2003/09/03 21:04:14 peter
  578. * some fixes for ppc
  579. Revision 1.66 2003/09/03 19:35:24 peter
  580. * powerpc compiles again
  581. Revision 1.65 2003/09/03 11:18:37 florian
  582. * fixed arm concatcopy
  583. + arm support in the common compiler sources added
  584. * moved some generic cg code around
  585. + tfputype added
  586. * ...
  587. Revision 1.64 2003/08/17 16:59:20 jonas
  588. * fixed regvars so they work with newra (at least for ppc)
  589. * fixed some volatile register bugs
  590. + -dnotranslation option for -dnewra, which causes the registers not to
  591. be translated from virtual to normal registers. Requires support in
  592. the assembler writer as well, which is only implemented in aggas/
  593. agppcgas currently
  594. Revision 1.63 2003/08/08 15:51:16 olle
  595. * merged macos entry/exit code generation into the general one.
  596. Revision 1.62 2003/07/23 11:00:09 jonas
  597. * "lastsaveintreg" is RS_R31 instead of RS_R27 with -dnewra, because
  598. there are no scratch regs anymore
  599. Revision 1.61 2003/07/06 20:25:03 jonas
  600. * fixed ppc compiler
  601. Revision 1.60 2003/07/06 15:28:24 jonas
  602. * VOLATILE_REGISTERS was wrong (it was more or less the inverted set
  603. of what it had to be :/ )
  604. Revision 1.59 2003/06/17 16:34:44 jonas
  605. * lots of newra fixes (need getfuncretparaloc implementation for i386)!
  606. * renamed all_intregisters to volatile_intregisters and made it
  607. processor dependent
  608. Revision 1.58 2003/06/14 22:32:43 jonas
  609. * ppc compiles with -dnewra, haven't tried to compile anything with it
  610. yet though
  611. Revision 1.57 2003/06/13 17:44:44 jonas
  612. + added supreg_name function
  613. Revision 1.56 2003/06/12 19:11:34 jonas
  614. - removed ALL_INTREGISTERS (only the one in rgobj is valid)
  615. Revision 1.55 2003/05/31 15:05:28 peter
  616. * FUNCTION_RESULT64_LOW/HIGH_REG added for int64 results
  617. Revision 1.54 2003/05/30 23:57:08 peter
  618. * more sparc cleanup
  619. * accumulator removed, splitted in function_return_reg (called) and
  620. function_result_reg (caller)
  621. Revision 1.53 2003/05/30 18:49:59 jonas
  622. * changed scratchregs from r28-r30 to r29-r31
  623. * made sure the regvar registers don't overlap with the scratchregs
  624. anymore
  625. Revision 1.52 2003/05/24 16:02:01 jonas
  626. * fixed endian problem with tlocation.value/valueqword fields
  627. Revision 1.51 2003/05/16 16:26:05 jonas
  628. * adapted for Peter's regvar fixes
  629. Revision 1.50 2003/05/15 22:14:43 florian
  630. * fixed last commit, changing lastsaveintreg to r31 caused some strange problems
  631. Revision 1.49 2003/05/15 21:37:00 florian
  632. * sysv entry code saves r13 now as well
  633. Revision 1.48 2003/04/23 12:35:35 florian
  634. * fixed several issues with powerpc
  635. + applied a patch from Jonas for nested function calls (PowerPC only)
  636. * ...
  637. Revision 1.47 2003/04/22 11:27:48 florian
  638. + added first_ and last_imreg
  639. Revision 1.46 2003/03/19 14:26:26 jonas
  640. * fixed R_TOC bugs introduced by new register allocator conversion
  641. Revision 1.45 2003/03/11 21:46:24 jonas
  642. * lots of new regallocator fixes, both in generic and ppc-specific code
  643. (ppc compiler still can't compile the linux system unit though)
  644. Revision 1.44 2003/02/19 22:00:16 daniel
  645. * Code generator converted to new register notation
  646. - Horribily outdated todo.txt removed
  647. Revision 1.43 2003/02/02 19:25:54 carl
  648. * Several bugfixes for m68k target (register alloc., opcode emission)
  649. + VIS target
  650. + Generic add more complete (still not verified)
  651. Revision 1.42 2003/01/16 11:31:28 olle
  652. + added new register constants
  653. + implemented register convertion proc
  654. Revision 1.41 2003/01/13 17:17:50 olle
  655. * changed global var access, TOC now contain pointers to globals
  656. * fixed handling of function pointers
  657. Revision 1.40 2003/01/09 15:49:56 daniel
  658. * Added register conversion
  659. Revision 1.39 2003/01/08 18:43:58 daniel
  660. * Tregister changed into a record
  661. Revision 1.38 2002/11/25 17:43:27 peter
  662. * splitted defbase in defutil,symutil,defcmp
  663. * merged isconvertable and is_equal into compare_defs(_ext)
  664. * made operator search faster by walking the list only once
  665. Revision 1.37 2002/11/24 14:28:56 jonas
  666. + some comments describing the fields of treference
  667. Revision 1.36 2002/11/17 18:26:16 mazen
  668. * fixed a compilation bug accmulator-->FUNCTION_RETURN_REG, in definition of return_result_reg
  669. Revision 1.35 2002/11/17 17:49:09 mazen
  670. + 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
  671. Revision 1.34 2002/09/17 18:54:06 jonas
  672. * a_load_reg_reg() now has two size parameters: source and dest. This
  673. allows some optimizations on architectures that don't encode the
  674. register size in the register name.
  675. Revision 1.33 2002/09/07 17:54:59 florian
  676. * first part of PowerPC fixes
  677. Revision 1.32 2002/09/07 15:25:14 peter
  678. * old logs removed and tabs fixed
  679. Revision 1.31 2002/09/01 21:04:49 florian
  680. * several powerpc related stuff fixed
  681. Revision 1.30 2002/08/18 22:16:15 florian
  682. + the ppc gas assembler writer adds now registers aliases
  683. to the assembler file
  684. Revision 1.29 2002/08/18 21:36:42 florian
  685. + handling of local variables in direct reader implemented
  686. Revision 1.28 2002/08/14 18:41:47 jonas
  687. - remove valuelow/valuehigh fields from tlocation, because they depend
  688. on the endianess of the host operating system -> difficult to get
  689. right. Use lo/hi(location.valueqword) instead (remember to use
  690. valueqword and not value!!)
  691. Revision 1.27 2002/08/13 21:40:58 florian
  692. * more fixes for ppc calling conventions
  693. Revision 1.26 2002/08/12 15:08:44 carl
  694. + stab register indexes for powerpc (moved from gdb to cpubase)
  695. + tprocessor enumeration moved to cpuinfo
  696. + linker in target_info is now a class
  697. * many many updates for m68k (will soon start to compile)
  698. - removed some ifdef or correct them for correct cpu
  699. Revision 1.25 2002/08/10 17:15:06 jonas
  700. * endianess fix
  701. Revision 1.24 2002/08/06 20:55:24 florian
  702. * first part of ppc calling conventions fix
  703. Revision 1.23 2002/08/04 12:57:56 jonas
  704. * more misc. fixes, mostly constant-related
  705. Revision 1.22 2002/07/27 19:57:18 jonas
  706. * some typo corrections in the instruction tables
  707. * renamed the m* registers to v*
  708. Revision 1.21 2002/07/26 12:30:51 jonas
  709. * fixed typo in instruction table (_subco_ -> a_subco)
  710. Revision 1.20 2002/07/25 18:04:10 carl
  711. + FPURESULTREG -> FPU_RESULT_REG
  712. Revision 1.19 2002/07/13 19:38:44 florian
  713. * some more generic calling stuff fixed
  714. Revision 1.18 2002/07/11 14:41:34 florian
  715. * start of the new generic parameter handling
  716. Revision 1.17 2002/07/11 07:35:36 jonas
  717. * some available registers fixes
  718. Revision 1.16 2002/07/09 19:45:01 jonas
  719. * unarynminus and shlshr node fixed for 32bit and smaller ordinals
  720. * small fixes in the assembler writer
  721. * changed scratch registers, because they were used by the linker (r11
  722. and r12) and by the abi under linux (r31)
  723. Revision 1.15 2002/07/07 09:44:31 florian
  724. * powerpc target fixed, very simple units can be compiled
  725. Revision 1.14 2002/05/18 13:34:26 peter
  726. * readded missing revisions
  727. Revision 1.12 2002/05/14 19:35:01 peter
  728. * removed old logs and updated copyright year
  729. Revision 1.11 2002/05/14 17:28:10 peter
  730. * synchronized cpubase between powerpc and i386
  731. * moved more tables from cpubase to cpuasm
  732. * tai_align_abstract moved to tainst, cpuasm must define
  733. the tai_align class now, which may be empty
  734. }