cpubase.pas 23 KB

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