cpubase.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. unit cpubase;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. strings,cutils,cclasses,aasm,cpuinfo,cginfo;
  23. {$ifndef NOOPT}
  24. Type
  25. {What an instruction can change}
  26. TInsChange = (Ch_None);
  27. {$endif}
  28. const
  29. { Size of the instruction table converted by nasmconv.pas }
  30. instabentries = 1103;
  31. maxinfolen = 7;
  32. { By default we want everything }
  33. {$define ATTOP}
  34. {$define ATTREG}
  35. {$define INTELOP}
  36. {$define ITTABLE}
  37. { For TP we can't use asmdebug due the table sizes }
  38. {$ifndef TP}
  39. {$define ASMDEBUG}
  40. {$endif}
  41. { We Don't need the intel style opcodes if we don't have a intel }
  42. { reader or generator }
  43. {$undef INTELOP}
  44. { We Don't need the AT&T style opcodes if we don't have a AT&T
  45. reader or generator }
  46. {$ifdef NORA386ATT}
  47. {$ifdef NOAG386ATT}
  48. {$undef ATTOP}
  49. {$ifdef NOAG386DIR}
  50. {$undef ATTREG}
  51. {$endif}
  52. {$endif}
  53. {$endif}
  54. {*****************************************************************************
  55. Default generic sizes
  56. *****************************************************************************}
  57. {# Defines the default address size for a processor, }
  58. OS_ADDR = OS_32;
  59. {# the natural int size for a processor, }
  60. OS_INT = OS_32;
  61. {# the maximum float size for a processor, }
  62. OS_FLOAT = OS_F64;
  63. {# the size of a vector register for a processor }
  64. OS_VECTOR = OS_M128;
  65. type
  66. TAsmOp=(A_None,
  67. { normal opcodes }
  68. a_add, a_add_, a_addo, a_addo_, a_addc, a_addc_, a_addco, a_addco_,
  69. a_adde, a_adde_, a_addeo, a_addeo_, a_addi, a_addic, a_addic_, a_addis,
  70. a_addme, a_addme_, a_addmeo, a_addmeo_, a_addze, a_addze_, a_addzeo,
  71. a_addzeo_, a_and, a_and_, a_andc, a_andc_, a_andi_, a_andis_, a_b,
  72. a_ba, a_bl, a_bla, a_bc, a_bca, a_bcl, a_bcla, a_bcctr, a_bcctrl, a_bclr,
  73. a_bclrl, a_cmp, a_cmpi, a_cmpl, a_cmpli, a_cntlzw, a_cntlzw_, a_crand,
  74. a_crandc, a_creqv, a_crnand, a_crnor, a_cror, a_crorc, a_crxor, a_dcba,
  75. a_dcbf, a_dcbi, a_dcbst, a_dcbt, a_divw, a_divw_, a_divwo, a_divwo_,
  76. a_divwu, a_divwu_, a_divwuo, a_divwuo_, a_eciwx, a_ecowx, a_eieio, a_eqv,
  77. a_eqv_, a_extsb, a_extsb_, a_extsh, a_extsh_, a_fabs, a_fabs_, a_fadd,
  78. a_fadd_, a_fadds, a_fadds_, a_fcmpo, a_fcmpu, a_fctiw, a_fctw_, a_fctwz,
  79. a_fctwz_, a_fdiv, a_fdiv_, a_fdivs, a_fdivs_, a_fmadd, a_fmadd_, a_fmadds,
  80. a_fmadds_, a_fmr, a_fmsub, a_fmsub_, a_fmsubs, a_fmsubs_, a_fmul, a_fmul_,
  81. a_fmuls, a_fmuls_, a_fnabs, a_fnabs_, a_fneg, a_fneg_, a_fnmadd,
  82. a_fnmadd_, a_fnmadds, a_fnmadds_, a_fnmsub, a_fnmsub_, a_fnmsubs,
  83. a_fnmsubs_, a_fres, a_fres_, a_frsp, a_frsp_, a_frsqrte, a_frsqrte_,
  84. a_fsel, a_fsel_, a_fsqrt, a_fsqrt_, a_fsqrts, a_fsqrts_, a_fsub, a_fsub_,
  85. a_fsubs, a_fsubs_, a_icbi, a_isync, a_lbz, a_lbzu, a_lbzux, a_lbzx,
  86. a_lfd, a_lfdu, a_lfdux, a_lfdx, a_lfs, a_lfsu, a_lfsux, a_lfsx, a_lha,
  87. a_lhau, a_lhaux, a_lhax, a_hbrx, a_lhz, a_lhzu, a_lhzux, a_lhzx, a_lmw,
  88. a_lswi, a_lswx, a_lwarx, a_lwbrx, a_lwz, a_lwzu, a_lwzux, a_lwzx, a_mcrf,
  89. a_mcrfs, a_mcrxr, a_lcrxe, a_mfcr, a_mffs, a_maffs_, a_mfmsr, a_mfspr, a_mfsr,
  90. a_mfsrin, a_mftb, a_mtfcrf, a_a_mtfd0, a_mtfsb1, a_mtfsf, a_mtfsf_,
  91. a_mtfsfi, a_mtfsfi_, a_mtmsr, a_mtspr, a_mtsr, a_mtsrin, a_mulhw,
  92. a_mulhw_, a_mulhwu, a_mulhwu_, a_mulli, a_mullw, a_mullw_, a_mullwo,
  93. a_mullwo_, a_nand, a_nand_, a_neg, a_neg_, a_nego, a_nego_, a_nor, a_nor_,
  94. a_or, a_or_, a_orc, a_orc_, a_ori, a_oris, a_rfi, a_rlwimi, a_rlwimi_,
  95. a_rlwinm, a_tlwinm_, a_rlwnm, a_sc, a_slw, a_slw_, a_sraw, a_sraw_,
  96. a_srawi, a_srawi_,a_srw, a_srw_, a_stb, a_stbu, a_stbux, a_stbx, a_stfd,
  97. a_stfdu, a_stfdux, a_stfdx, a_stfiwx, a_stfs, a_stfsu, a_stfsux, a_stfsx,
  98. a_sth, a_sthbrx, a_sthu, a_sthux, a_sthx, a_stmw, a_stswi, a_stswx, a_stw,
  99. a_stwbrx, a_stwx_, a_stwu, a_stwux, a_stwx, a_subf, a_subf_, a_subfo,
  100. a_subfo_, a_subfc, a_subfc_, a_subfco, a_subfco_, a_subfe, a_subfe_,
  101. a_subfeo, a_subfeo_, a_subfic, a_subfme, a_subfme_, a_subfmeo, a_subfmeo_,
  102. a_subfze, a_subfze_, a_subfzeo, a_subfzeo_, a_sync, a_tlbia, a_tlbie,
  103. a_tlbsync, a_tw, a_twi, a_xor, a_xor_, a_xori, a_xoris,
  104. { simplified mnemonics }
  105. a_subi, a_subis, a_subic, a_subic_, a_sub, a_sub_, a_subo, a_subo_,
  106. a_subc, a_subc_, a_subco, _subco_, a_cmpwi, a_cmpw, a_cmplwi, a_cmplw,
  107. a_extlwi, a_extlwi_, a_extrwi, a_extrwi_, a_inslwi, a_inslwi_, a_insrwi,
  108. a_insrwi_, a_rotlwi, a_rotlwi_, a_rotlw, a_rotlw_, a_slwi, a_slwi_,
  109. a_srwi, a_srwi_, a_clrlwi, a_clrlwi_, a_clrrwi, a_clrrwi_, a_clrslwi,
  110. a_clrslwi_, a_blr, a_bctr, a_blrl, a_bctrl, a_crset, a_crclr, a_crmove,
  111. a_crnot, a_mt {move to special prupose reg}, a_mf {move from special purpose reg},
  112. a_nop, a_li, a_lis, a_la, a_mr, a_mr_, a_not, a_mtcr);
  113. op2strtable=array[tasmop] of string[8];
  114. const
  115. firstop = low(tasmop);
  116. lastop = high(tasmop);
  117. {*****************************************************************************
  118. Registers
  119. *****************************************************************************}
  120. type
  121. tregister = (R_NO,
  122. R_0,R_1,R_2,R_3,R_4,R_5,R_6,R_7,R_8,R_9,R_10,R_11,R_12,R_13,R_14,R_15,R_16,
  123. R_17,R_18,R_19,R_20,R_21,R_22,R_23,R_24,R_25,R_26,R_27,R_28,R_29,R_30,R_31,
  124. R_F0,R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,
  125. R_F13,R_F14,R_F15,R_F16,R_F17, R_F18,R_F19,R_F20,R_F21,R_F22, R_F23,R_F24,
  126. R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31,
  127. R_M0,R_M1,R_M2,R_M3,R_M4,R_M5,R_M6,R_M7,R_M8,R_M9,R_M10,R_M11,R_M12,
  128. R_M13,R_M14,R_M15,R_M16,R_M17,R_M18,R_M19,R_M20,R_M21,R_M22, R_M23,R_M24,
  129. R_M25,R_M26,R_M27,R_M28,R_M29,R_M30,R_M31,
  130. R_CR,R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7,
  131. R_XER,R_LR,R_CTR,R_FPSCR
  132. );
  133. tregisterset = set of tregister;
  134. reg2strtable = array[tregister] of string[5];
  135. Const
  136. R_SPR1 = R_XER;
  137. R_SPR8 = R_LR;
  138. R_SPR9 = R_CTR;
  139. R_TOC = R_2;
  140. { CR0 = 0;
  141. CR1 = 4;
  142. CR2 = 8;
  143. CR3 = 12;
  144. CR4 = 16;
  145. CR5 = 20;
  146. CR6 = 24;
  147. CR7 = 28;
  148. LT = 0;
  149. GT = 1;
  150. EQ = 2;
  151. SO = 3;
  152. FX = 4;
  153. FEX = 5;
  154. VX = 6;
  155. OX = 7;}
  156. firstreg = low(tregister);
  157. lastreg = high(tregister);
  158. att_reg2str : reg2strtable = ('',
  159. '0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16',
  160. '17','18','19','20','21','22','23','24','25','26','27','28','29','30','31',
  161. 'F0','F1','F2','F3','F4','F5','F6','F7', 'F8','F9','F10','F11','F12',
  162. 'F13','F14','F15','F16','F17', 'F18','F19','F20','F21','F22', 'F23','F24',
  163. 'F25','F26','F27','F28','F29','F30','F31',
  164. 'M0','M1','M2','M3','M4','M5','M6','M7','M8','M9','M10','M11','M12',
  165. 'M13','M14','M15','M16','M17','M18','M19','M20','M21','M22', 'M23','M24',
  166. 'M25','M26','M27','M28','M29','M30','M31',
  167. 'CR','CR0','CR1','CR2','CR3','CR4','CR5','CR6','CR7',
  168. 'XER','LR','CTR','FPSCR'
  169. );
  170. mot_reg2str : reg2strtable = ('',
  171. 'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12','r13',
  172. 'r14','r15','r16','r17','r18','r19','r20','r21','r22','r23','r24','r25',
  173. 'r26','r27','r28','r29','r30','r31',
  174. 'F0','F1','F2','F3','F4','F5','F6','F7', 'F8','F9','F10','F11','F12',
  175. 'F13','F14','F15','F16','F17', 'F18','F19','F20','F21','F22', 'F23','F24',
  176. 'F25','F26','F27','F28','F29','F30','F31',
  177. 'M0','M1','M2','M3','M4','M5','M6','M7','M8','M9','M10','M11','M12',
  178. 'M13','M14','M15','M16','M17','M18','M19','M20','M21','M22', 'M23','M24',
  179. 'M25','M26','M27','M28','M29','M30','M31',
  180. 'CR','CR0','CR1','CR2','CR3','CR4','CR5','CR6','CR7',
  181. 'XER','LR','CTR','FPSCR'
  182. );
  183. std_reg2str : reg2strtable = ('',
  184. 'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12','r13',
  185. 'r14','r15','r16','r17','r18','r19','r20','r21','r22','r23','r24','r25',
  186. 'r26','r27','r28','r29','r30','r31',
  187. 'F0','F1','F2','F3','F4','F5','F6','F7', 'F8','F9','F10','F11','F12',
  188. 'F13','F14','F15','F16','F17', 'F18','F19','F20','F21','F22', 'F23','F24',
  189. 'F25','F26','F27','F28','F29','F30','F31',
  190. 'M0','M1','M2','M3','M4','M5','M6','M7','M8','M9','M10','M11','M12',
  191. 'M13','M14','M15','M16','M17','M18','M19','M20','M21','M22', 'M23','M24',
  192. 'M25','M26','M27','M28','M29','M30','M31',
  193. 'CR','CR0','CR1','CR2','CR3','CR4','CR5','CR6','CR7',
  194. 'XER','LR','CTR','FPSCR'
  195. );
  196. { FIX ME !!!!!!!!! }
  197. ALL_REGISTERS = [R_0..R_FPSCR];
  198. {*****************************************************************************
  199. Conditions
  200. *****************************************************************************}
  201. type
  202. {$ifndef tp}
  203. {$minenumsize 1}
  204. {$endif tp}
  205. TAsmCondFlag = (C_None { unconditional jumps },
  206. { conditions when not using ctr decrement etc }
  207. C_LT,C_LE,C_EQ,C_GE,C_GT,C_NL,C_NE,C_NG,C_SO,C_NS,C_UN,C_NU,
  208. { conditions when using ctr decrement etc }
  209. C_T,C_F,C_DNZ,C_DNZT,C_DNZF,C_DZ,C_DZT,C_DZF);
  210. const
  211. { these are in the XER, but when moved to CR_x they correspond with the }
  212. { bits below (still needs to be verified!!!) }
  213. C_OV = C_EQ;
  214. C_CA = C_GT;
  215. type
  216. {$ifndef tp}
  217. {$minenumsize default}
  218. {$endif tp}
  219. TAsmCond = packed record
  220. case simple: boolean of
  221. false: (BO, BI: byte);
  222. true: (
  223. cond: TAsmCondFlag;
  224. case byte of
  225. 0: ();
  226. { specifies in which part of the cr the bit has to be }
  227. { tested for blt,bgt,beq,..,bnu }
  228. 1: (cr: R_CR0..R_CR7);
  229. { specifies the bit to test for bt,bf,bdz,..,bdzf }
  230. 2: (crbit: byte)
  231. );
  232. end;
  233. const
  234. AsmCondFlag2BO: Array[C_T..C_DZF] of Byte =
  235. (12,4,16,8,0,18,10,2);
  236. AsmCondFlag2BI: Array[C_LT..C_NU] of Byte =
  237. (0,1,2,0,1,0,2,1,3,3,3,3);
  238. AsmCondFlagTF: Array[TAsmCondFlag] of Boolean =
  239. (false,true,false,true,false,true,false,false,false,true,false,true,false,
  240. true,false,false,true,false,false,true,false);
  241. AsmCondFlag2Str: Array[TAsmCondFlag] of string[4] = ({cf_none}'',
  242. { conditions when not using ctr decrement etc}
  243. 'lt','le','eq','ge','gt','nl','ne','ng','so','ns','un','nu',
  244. 't','f','dnz','dzt','dnzf','dz','dzt','dzf');
  245. const
  246. CondAsmOps=3;
  247. CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
  248. A_BC, A_TW, A_TWI
  249. );
  250. {*****************************************************************************
  251. Flags
  252. *****************************************************************************}
  253. type
  254. TResFlagsEnum = (F_EQ,F_NE,F_LT,F_LE,F_GT,F_GE,F_SO,F_FX,F_FEX,F_VX,F_OX);
  255. TResFlags = record
  256. cr: R_CR0..R_CR7;
  257. flag: TResFlagsEnum;
  258. end;
  259. (*
  260. const
  261. { arrays for boolean location conversions }
  262. flag_2_cond : array[TResFlags] of TAsmCond =
  263. (C_E,C_NE,C_LT,C_LE,C_GT,C_GE,???????????????);
  264. *)
  265. {*****************************************************************************
  266. Reference
  267. *****************************************************************************}
  268. type
  269. trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
  270. { since we have only 16 offsets, we need to be able to specify the high }
  271. { and low 16 bits of the address of a symbol }
  272. trefsymaddr = (refs_full,refs_ha,refs_l);
  273. { immediate/reference record }
  274. preference = ^treference;
  275. treference = packed record
  276. is_immediate: boolean; { is this used as reference or immediate }
  277. base, index : tregister;
  278. offset : longint;
  279. symbol : tasmsymbol;
  280. symaddr : trefsymaddr;
  281. offsetfixup : longint;
  282. options : trefoptions;
  283. alignment : byte;
  284. end;
  285. const symaddr2str: array[trefsymaddr] of string[3] = ('','@ha','@l');
  286. {*****************************************************************************
  287. Operand
  288. *****************************************************************************}
  289. type
  290. toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_bool);
  291. toper=record
  292. ot : longint;
  293. case typ : toptype of
  294. top_none : ();
  295. top_reg : (reg:tregister);
  296. top_ref : (ref:preference);
  297. top_const : (val:aword);
  298. top_symbol : (sym:tasmsymbol;symofs:longint);
  299. top_bool : (b: boolean);
  300. end;
  301. {*****************************************************************************
  302. Generic Location
  303. *****************************************************************************}
  304. type
  305. TLoc=(
  306. LOC_INVALID, { added for tracking problems}
  307. LOC_CONSTANT, { ordinal constant }
  308. LOC_REGISTER, { in a processor register }
  309. LOC_CREGISTER, { Constant register which shouldn't be modified }
  310. LOC_FPUREGISTER, { FPU register}
  311. LOC_CFPUREGISTER,{ Constant FPU register which shouldn't be modified }
  312. LOC_MMREGISTER, { multimedia register }
  313. LOC_CMMREGISTER, { Constant multimedia reg which shouldn't be modified }
  314. LOC_REFERENCE, { in memory }
  315. LOC_CREFERENCE, { in memory (constant) }
  316. LOC_JUMP, { boolean results only, jump to false or true label }
  317. LOC_FLAGS { boolean results only, flags are set }
  318. );
  319. plocation = ^tlocation;
  320. tlocation = packed record
  321. size : TCGSize;
  322. case loc : tloc of
  323. LOC_CREFERENCE,LOC_REFERENCE : (reference : treference);
  324. LOC_CONSTANT : (
  325. case longint of
  326. 1 : (value : AWord);
  327. 2 : (valuelow, valuehigh:AWord);
  328. );
  329. LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
  330. LOC_REGISTER,LOC_CREGISTER : (
  331. case longint of
  332. 1 : (registerlow,registerhigh : tregister);
  333. { overlay a registerlow }
  334. 2 : (register : tregister);
  335. );
  336. LOC_JUMP : ();
  337. LOC_FLAGS : (resflags : tresflags);
  338. LOC_INVALID : ();
  339. { segment in reference at the same place as in loc_register }
  340. end;
  341. {*****************************************************************************
  342. Constants
  343. *****************************************************************************}
  344. const
  345. usableregsint = [R_13..R_30];
  346. usableregsfpu = [R_F14..R_F31];
  347. usableregsmm = [R_M14..R_M31];
  348. firstsaveintreg = R_13;
  349. lastsaveintreg = R_30;
  350. firstsavefpureg = R_F14;
  351. lastsavefpureg = R_F31;
  352. { no altivec support yet. Need to override tcgobj.a_loadmm_* first in tcgppc }
  353. firstsavemmreg = R_NO;
  354. lastsavemmreg = R_NO;
  355. lvaluelocations = [LOC_REFERENCE, LOC_CREGISTER, LOC_CFPUREGISTER,
  356. LOC_CMMREGISTER];
  357. c_countusableregsint = 21;
  358. c_countusableregsfpu = 32;
  359. c_countusableregsmm = 32;
  360. max_operands = 5;
  361. maxvarregs = 18;
  362. varregs : Array [1..maxvarregs] of Tregister =
  363. (R_13,R_14,R_15,R_16,R_17,R_18,R_19,R_20,R_21,R_22,R_23,R_24,R_25,
  364. R_26,R_27,R_28,R_29,R_30);
  365. maxfpuvarregs = 31-14+1;
  366. fpuvarregs : Array [1..maxfpuvarregs] of Tregister =
  367. (R_F14,R_F15,R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,
  368. R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31);
  369. max_param_regs_int = 8;
  370. param_regs_int: Array[1..max_param_regs_int] of tregister =
  371. (R_3,R_4,R_5,R_6,R_7,R_8,R_9,R_10);
  372. max_param_regs_fpu = 13;
  373. param_regs_fpu: Array[1..max_param_regs_fpu] of tregister =
  374. (R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,R_F13);
  375. max_param_regs_mm = 13;
  376. param_regs_mm: Array[1..max_param_regs_mm] of tregister =
  377. (R_M1,R_M2,R_M3,R_M4,R_M5,R_M6,R_M7,R_M8,R_M9,R_M10,R_M11,R_M12,R_M13);
  378. general_registers = [R_0..R_31];
  379. intregs = [R_0..R_31];
  380. fpuregs = [R_F0..R_F31];
  381. mmregs = [R_M0..R_M31];
  382. { generic register names }
  383. stack_pointer_reg= R_1;
  384. R_RTOC = R_2;
  385. frame_pointer_reg = stack_pointer_reg;
  386. self_pointer_reg = R_9;
  387. accumulator = R_3;
  388. accumulatorhigh = R_4;
  389. {$warning I don't know the exact values, please check (PFV) }
  390. fpuresultreg = R_F0;
  391. mmresultreg = R_M0;
  392. max_scratch_regs = 3;
  393. scratch_regs: Array[1..max_scratch_regs] of TRegister = (R_11,R_12,R_31);
  394. maxintregs = maxvarregs;
  395. maxfpuregs = maxfpuvarregs;
  396. { low and high of the available maximum width integer general purpose }
  397. { registers }
  398. LoGPReg = R_0;
  399. HiGPReg = R_31;
  400. { low and high of every possible width general purpose register (same as }
  401. { above on most architctures apart from the 80x86) }
  402. LoReg = R_0;
  403. HiReg = R_31;
  404. { sizes }
  405. extended_size = 8;
  406. LinkageAreaSize = 24;
  407. { offset in the linkage area for the saved stack pointer }
  408. LA_SP = 0;
  409. { offset in the linkage area for the saved conditional register}
  410. LA_CR = 4;
  411. { offset in the linkage area for the saved link register}
  412. LA_LR = 8;
  413. { offset in the linkage area for the saved RTOC register}
  414. LA_RTOC = 20;
  415. {*****************************************************************************
  416. GCC /ABI linking information
  417. *****************************************************************************}
  418. {# Registers which must be saved when calling a routine declared as
  419. cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
  420. saved should be the ones as defined in the target ABI and / or GCC.
  421. This value can be deduced from CALLED_USED_REGISTERS array in the
  422. GCC source.
  423. }
  424. std_saved_registers = [R_13..R_29];
  425. {# Required parameter alignment when calling a routine declared as
  426. stdcall and cdecl. The alignment value should be the one defined
  427. by GCC or the target ABI.
  428. The value of this constant is equal to the constant
  429. PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
  430. }
  431. std_param_align = 4; { for 32-bit version only }
  432. {*****************************************************************************
  433. Helpers
  434. *****************************************************************************}
  435. { resets all values of ref to defaults }
  436. procedure reset_reference(var ref : treference);
  437. { set mostly used values of a new reference }
  438. function new_reference(base : tregister;offset : longint) : preference;
  439. function newreference(const r : treference) : preference;
  440. procedure disposereference(var r : preference);
  441. function is_calljmp(o:tasmop):boolean;
  442. procedure inverse_cond(c: TAsmCond;var r : TAsmCond);
  443. function flags_to_cond(const f: TResFlags) : TAsmCond;
  444. procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
  445. procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
  446. procedure clear_location(var loc : tlocation);
  447. procedure set_location(var destloc,sourceloc : tlocation);
  448. procedure swap_location(var destloc,sourceloc : tlocation);
  449. {*****************************************************************************
  450. Init/Done
  451. *****************************************************************************}
  452. procedure InitCpu;
  453. procedure DoneCpu;
  454. implementation
  455. uses
  456. verbose
  457. {$ifdef heaptrc}
  458. ,ppheap
  459. {$endif heaptrc}
  460. ;
  461. {*****************************************************************************
  462. Helpers
  463. *****************************************************************************}
  464. function is_calljmp(o:tasmop):boolean;
  465. begin
  466. is_calljmp:=false;
  467. case o of
  468. A_B,A_BA,A_BL,A_BLA,A_BC,A_BCA,A_BCL,A_BCLA,A_BCCTR,A_BCCTRL,A_BCLR,
  469. A_BCLRL,A_TW,A_TWI: is_calljmp:=true;
  470. end;
  471. end;
  472. procedure disposereference(var r : preference);
  473. begin
  474. dispose(r);
  475. r:=nil;
  476. end;
  477. function newreference(const r : treference) : preference;
  478. var
  479. p : preference;
  480. begin
  481. new(p);
  482. p^:=r;
  483. newreference:=p;
  484. end;
  485. procedure reset_reference(var ref : treference);
  486. begin
  487. FillChar(ref,sizeof(treference),0)
  488. end;
  489. function new_reference(base : tregister;offset : longint) : preference;
  490. var
  491. r : preference;
  492. begin
  493. new(r);
  494. FillChar(r^,sizeof(treference),0);
  495. r^.base:=base;
  496. r^.offset:=offset;
  497. new_reference:=r;
  498. end;
  499. procedure inverse_cond(c: TAsmCond;var r : TAsmCond);
  500. const
  501. inv_condflags:array[TAsmCondFlag] of TAsmCondFlag=(C_None,
  502. C_GE,C_GT,C_NE,C_LT,C_LE,C_LT,C_EQ,C_GT,C_NS,C_SO,C_NU,C_UN,
  503. C_F,C_T,C_DNZ,C_DNZF,C_DNZT,C_DZ,C_DZF,C_DZT);
  504. begin
  505. c.cond := inv_condflags[c.cond];
  506. r := c;
  507. end;
  508. function flags_to_cond(const f: TResFlags) : TAsmCond;
  509. const
  510. flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag =
  511. (C_EQ,C_NE,C_LT,C_LE,C_GT,C_GE,C_SO);
  512. begin
  513. if f.flag > high(flag_2_cond) then
  514. internalerror(200112301);
  515. result.simple := true;
  516. result.cr := f.cr;
  517. result.cond := flag_2_cond[f.flag];
  518. end;
  519. procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
  520. begin
  521. r.simple := false;
  522. r.bo := bo;
  523. r.bi := bi;
  524. end;
  525. procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
  526. const cr2reg: array[0..7] of tregister =
  527. (R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7);
  528. begin
  529. r.simple := true;
  530. r.cond := cond;
  531. case cond of
  532. C_NONE:;
  533. C_T..C_DZF: r.crbit := cr
  534. else r.cr := cr2reg[cr];
  535. end;
  536. end;
  537. procedure clear_location(var loc : tlocation);
  538. begin
  539. loc.loc:=LOC_INVALID;
  540. end;
  541. {This is needed if you want to be able to delete the string with the nodes !!}
  542. procedure set_location(var destloc,sourceloc : tlocation);
  543. begin
  544. destloc:= sourceloc;
  545. end;
  546. procedure swap_location(var destloc,sourceloc : tlocation);
  547. var
  548. swapl : tlocation;
  549. begin
  550. swapl := destloc;
  551. destloc := sourceloc;
  552. sourceloc := swapl;
  553. end;
  554. {*****************************************************************************
  555. Init/Done
  556. *****************************************************************************}
  557. procedure InitCpu;
  558. begin
  559. end;
  560. procedure DoneCpu;
  561. begin
  562. end;
  563. end.
  564. {
  565. $Log$
  566. Revision 1.13 2002-05-16 19:46:53 carl
  567. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  568. + try to fix temp allocation (still in ifdef)
  569. + generic constructor calls
  570. + start of tassembler / tmodulebase class cleanup
  571. Revision 1.10 2002/05/13 19:52:46 peter
  572. * a ppcppc can be build again
  573. Revision 1.9 2002/04/21 15:48:39 carl
  574. * some small updates according to i386 version
  575. Revision 1.8 2002/04/20 21:41:51 carl
  576. * renamed some constants
  577. Revision 1.7 2002/04/06 18:13:02 jonas
  578. * several powerpc-related additions and fixes
  579. Revision 1.6 2001/12/30 17:24:48 jonas
  580. * range checking is now processor independent (part in cgobj, part in
  581. cg64f32) and should work correctly again (it needed some changes after
  582. the changes of the low and high of tordef's to int64)
  583. * maketojumpbool() is now processor independent (in ncgutil)
  584. * getregister32 is now called getregisterint
  585. Revision 1.5 2001/12/29 15:28:58 jonas
  586. * powerpc/cgcpu.pas compiles :)
  587. * several powerpc-related fixes
  588. * cpuasm unit is now based on common tainst unit
  589. + nppcmat unit for powerpc (almost complete)
  590. Revision 1.4 2001/09/28 20:40:05 jonas
  591. * several additions, almost complete (only some problems with resflags left)
  592. Revision 1.3 2001/09/06 15:25:56 jonas
  593. * changed type of tcg from object to class -> abstract methods are now
  594. a lot cleaner :)
  595. + more updates: load_*_loc methods, op_*_* methods, g_flags2reg method
  596. (if possible with geenric implementation and necessary ppc
  597. implementations)
  598. * worked a bit further on cgflw, now working on exitnode
  599. Revision 1.2 2001/08/26 13:31:04 florian
  600. * some cg reorganisation
  601. * some PPC updates
  602. Revision 1.2 2001/08/26 13:29:34 florian
  603. * some cg reorganisation
  604. * some PPC updates
  605. Revision 1.1 2000/07/13 06:30:12 michael
  606. + Initial import
  607. Revision 1.15 2000/05/01 11:04:49 jonas
  608. * changed NOT to A_NOP
  609. Revision 1.14 2000/04/29 09:01:06 jonas
  610. * nmem compiles again (at least for powerpc)
  611. Revision 1.13 2000/03/26 16:38:06 jonas
  612. * frame_pointer = stackpointer instead of R_NO
  613. Revision 1.12 2000/01/07 01:14:58 peter
  614. * updated copyright to 2000
  615. Revision 1.11 1999/12/24 22:48:10 jonas
  616. * compiles again
  617. Revision 1.10 1999/11/09 22:57:09 peter
  618. * compiles again both i386,alpha both with optimizer
  619. Revision 1.9 1999/10/20 12:21:34 jonas
  620. * changed scratch_registers to (R_11,_R12,R_30) because R_0 is a special
  621. case and R_31 is used as some kind of frame pointer under LinuxPPC
  622. Revision 1.8 1999/10/14 14:57:55 florian
  623. - removed the hcodegen use in the new cg, use cgbase instead
  624. Revision 1.7 1999/09/15 20:35:47 florian
  625. * small fix to operator overloading when in MMX mode
  626. + the compiler uses now fldz and fld1 if possible
  627. + some fixes to floating point registers
  628. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  629. * .... ???
  630. Revision 1.6 1999/09/03 13:11:59 jonas
  631. * several changes to the way conditional branches are handled\n * some typos fixed
  632. Revision 1.5 1999/08/23 23:27:54 pierre
  633. + dummy InitCpu/DoneCpu
  634. Revision 1.4 1999/08/06 16:41:12 jonas
  635. * PowerPC compiles again, several routines implemented in cgcpu.pas
  636. * added constant to cpubase of alpha and powerpc for maximum
  637. number of operands
  638. Revision 1.3 1999/08/05 14:58:18 florian
  639. * some fixes for the floating point registers
  640. * more things for the new code generator
  641. Revision 1.2 1999/08/04 12:59:25 jonas
  642. * all tokes now start with an underscore
  643. * PowerPC compiles!!
  644. Revision 1.1 1999/08/03 23:37:53 jonas
  645. + initial implementation for PowerPC based on the Alpha stuff
  646. }