cpubase.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. {
  2. $Id$
  3. Copyright (c) 1999 by Florian Klaempfl
  4. Contains the base types for the PowerPC
  5. * This code was inspired by the NASM sources
  6. The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  7. Julian Hall. All rights reserved.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. ****************************************************************************
  20. }
  21. unit cpubase;
  22. interface
  23. {$ifdef TP}
  24. {$L-,Y-}
  25. {$endif}
  26. uses
  27. strings,cobjects,aasm;
  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. {$ifndef ASMDEBUG}
  44. {$ifdef NORA386INT}
  45. {$ifdef NOAG386NSM}
  46. {$ifdef NOAG386INT}
  47. {$undef INTELOP}
  48. {$endif}
  49. {$endif}
  50. {$endif}
  51. {$endif}
  52. { We Don't need the AT&T style opcodes if we don't have a AT&T
  53. reader or generator }
  54. {$ifdef NORA386ATT}
  55. {$ifdef NOAG386ATT}
  56. {$undef ATTOP}
  57. {$ifdef NOAG386DIR}
  58. {$undef ATTREG}
  59. {$endif}
  60. {$endif}
  61. {$endif}
  62. type
  63. TAsmOp=(A_None,
  64. { normal opcodes }
  65. a_add, a_add_, a_addo, a_addo_, a_addc, a_addc_, a_addco, a_addco_,
  66. a_adde, a_adde_, a_addeo, a_addeo_, a_addi, a_addic, a_addic_, a_addis,
  67. a_addme, a_addme_, a_addmeo, a_addmeo_, a_addze, a_addze_, a_addzeo,
  68. a_addzeo_, a_and, a_and_, a_andc, a_andc_, a_andi_, a_andis_, a_b,
  69. a_ba, a_bl, a_bla, a_bc, a_bca, a_bcl, a_bcla, a_bcctr, a_bcctrl, a_bclr,
  70. a_bclrl, a_cmp, a_cmpi, a_cmpl, a_cmpli, a_cntlzw, a_cntlzw_, a_crand,
  71. a_crandc, a_creqv, a_crnand, a_crnor, a_cror, a_crorc, a_crxor, a_dcba,
  72. a_dcbf, a_dcbi, a_dcbst, a_dcbt, a_divw, a_divw_, a_divwo, a_divwo_,
  73. a_divwu, a_divwu_, a_divwuo, a_divwuo_, a_eciwx, a_ecowx, a_eieio, a_eqv,
  74. a_eqv_, a_extsb, a_extsb_, a_extsh, a_extsh_, a_fabs, a_fabs_, a_fadd,
  75. a_fadd_, a_fadds, a_fadds_, a_fcompo, a_fcmpu, a_fctiw, a_fctw_, a_fctwz,
  76. a_fctwz_, a_fdiv, a_fdiv_, a_fdivs, a_fdivs_, a_fmadd, a_fmadd_, a_fmadds,
  77. a_fmadds_, a_fmr, a_fmsub, a_fmsub_, a_fmsubs, a_fmsubs_, a_fmul, a_fmul_,
  78. a_fmuls, a_fmuls_, a_fnabs, a_fnabs_, a_fneg, a_fneg_, a_fnmadd,
  79. a_fnmadd_, a_fnmadds, a_fnmadds_, a_fnmsub, a_fnmsub_, a_fnmsubs,
  80. a_fnmsubs_, a_fres, a_fres_, a_frsp, a_frsp_, a_frsqrte, a_frsqrte_,
  81. a_fsel, a_fsel_, a_fsqrt, a_fsqrt_, a_fsqrts, a_fsqrts_, a_fsub, a_fsub_,
  82. a_fsubs, a_fsubs_, a_icbi, a_isync, a_lbz, a_lbzu, a_lbzux, a_lbzx,
  83. a_lfd, a_lfdu, a_lfdux, a_lfdx, a_lfs, a_lfsu, a_lfsux, a_lfsx, a_lha,
  84. a_lhau, a_lhaux, a_lhax, a_hbrx, a_lhz, a_lhzu, a_lhzux, a_lhzx, a_lmw,
  85. a_lswi, a_lswx, a_lwarx, a_lwbrx, a_lwz, a_lwzu, a_lwzux, a_lwzx, a_mcrf,
  86. a_mcrfs, a_lcrxe, a_mfcr, a_mffs, a_maffs_, a_mfmsr, a_mfspr, a_mfsr,
  87. a_mfsrin, a_mftb, a_mtfcrf, a_a_mtfd0, a_mtfsb1, a_mtfsf, a_mtfsf_,
  88. a_mtfsfi, a_mtfsfi_, a_mtmsr, a_mtspr, a_mtsr, a_mtsrin, a_mulhw,
  89. a_mulhw_, a_mulhwu, a_mulhwu_, a_mulli, a_mullh, a_mullw_, a_mullwo,
  90. a_mullwo_, a_nand, a_nand_, a_neg, a_neg_, a_nego, a_nego_, a_nor, a_nor_,
  91. a_or, a_or_, a_orc, a_orc_, a_ori, a_oris, a_rfi, a_rlwimi, a_rlwimi_,
  92. a_rlwinm, a_tlwinm_, a_rlwnm, a_sc, a_slw, a_slw_, a_sraw, a_sraw_,
  93. a_srawi, a_srawi_,a_srw, a_srw_, a_stb, a_stbu, a_stbux, a_a_stbx, a_stfd,
  94. a_stfdu, a_stfdux, a_stfdx, a_stfiwx, a_stfs, a_stfsu, a_stfsux, a_stfsx,
  95. a_sth, a_sthbrx, a_sthu, a_sthux, a_sthx, a_stmw, a_stswi, a_stswx, a_stw,
  96. a_stwbrx, a_stwx_, a_stwu, a_stwux, a_stwx, a_subf, a_subf_, a_subfo,
  97. a_subfo_, a_subfc, a_subc_, a_subfco, a_subfco_, a_subfe, a_subfe_,
  98. a_subfeo, a_subfeo_, a_subfic, a_subfme, a_subfme_, a_subfmeo, a_subfmeo_,
  99. a_subfze, a_subfze_, a_subfzeo, a_subfzeo_, a_sync, a_tlbia, a_tlbie,
  100. a_tlbsync, a_tw, twi, a_xor, a_xor_, a_xori, a_xoris,
  101. { simplified mnemonics }
  102. a_subi, a_subis, a_subic, a_subic_, a_sub, a_sub_, a_subo, a_subo_,
  103. a_subc, a_subc_, a_subco, _subco_, a_cmpwi, a_cmpw, a_cmplwi, a_cmplw,
  104. a_extlwi, a_extlwi_, a_extrwi, a_extrwi_, a_inslwi, a_inslwi_, a_insrwi,
  105. a_insrwi_, a_rotlwi, a_rotlwi_, a_rotlw, a_rotlw_, a_slwi, a_slwi_,
  106. a_srwi, a_srwi_, a_clrlwi, a_clrlwi_, a_clrrwi, a_clrrwi_, a_clrslwi,
  107. a_clrslwi_, a_blr, a_bctr, a_blrl, a_bctrl, a_crset, a_crclr, a_crmove,
  108. a_crnot, a_mt {move to special prupose reg}, a_mf {move from special purpose reg},
  109. nop, a_li, a_la, a_mr, a_not, a_mtcr);
  110. op2strtable=array[tasmop] of string[8];
  111. const
  112. firstop = low(tasmop);
  113. lastop = high(tasmop);
  114. {*****************************************************************************
  115. Conditions
  116. *****************************************************************************}
  117. (* still needs to be implmented in a generic way somehow
  118. type
  119. TAsmCond=(C_None,
  120. C_LT,C_LE,C_EQ,C_GE,C_GT,C_NL,C_NE,C_NG,C_SO,C_NS,C_UN,C_NU
  121. );
  122. TAsmCondBO = (B_T,B_F,B_DNZ,B_DNZT,B_DNZF,B_DZ,B_DZT,B_DZF);
  123. TasmCondSuffix = (SU_NO,SU_A,SU_LR,SU_CTR,SU_L,SU_LA,SU_LRL,SU_CTRL);
  124. const
  125. cond2str:array[TAsmCond] of string[2]=('',
  126. 'lt','le','eq','ge','gt','nl','ne','ng','so','ns','un','nu'
  127. );
  128. condbo2str:array[TasmCondBO] of String[4] = (
  129. 't','f','dnz','dnzt','dnzf','dz','dzt','dzf'
  130. );
  131. condsuffix2str:array[TAsmCondSuffix] of String[4] = (
  132. '','a','lr','ctr','l','la','lrl','ctrl'
  133. );
  134. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  135. C_GE,C_GT,C_NE,C_LT,C_LE,C_LT,C_EQ,C_GT,C_NS,C_SO,C_NU,C_UN
  136. );
  137. AllowedCond = Array[TAsmCondBO,TAsmCondSuffix] of Boolean = (
  138. {t} (
  139. {f}
  140. {dnz}
  141. {dnzt}
  142. {dnzf}
  143. {dz}
  144. {dzt}
  145. {dzf}
  146. const
  147. CondAsmOps=3;
  148. CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
  149. A_BC, A_TW, A_TWI
  150. );
  151. *)
  152. {*****************************************************************************
  153. Registers
  154. *****************************************************************************}
  155. type
  156. { enumeration for registers, don't change the order }
  157. { it's used by the register size conversions }
  158. tregister = (R_NO,
  159. R_0,R_1,R_2,R_3,R_4,R_5,R_6,R_7, R_9,R_10,R_11,R_12,R_13,R_14,R_15,R_16,
  160. 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,
  161. 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,
  162. R_F13,R_F14,R_F15,R_F16,R_F17, R_F18,R_F19,R_F20,R_F21,R_F22, R_F23,R_F24,
  163. R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31,
  164. 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,
  165. R_M13,R_M14,R_M15,R_M16,R_M17,R_M18,R_M19,R_M20,R_M21,R_M22, R_M23,R_M24,
  166. R_M25,R_M26,R_M27,R_M28,R_M29,R_M30,R_M31,
  167. R_CR,R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7,
  168. R_XER,R_LR,R_CTR,R_FPSCR
  169. );
  170. Const
  171. R_SPR1 = R_XER;
  172. R_SPR8 = R_LR;
  173. R_SPR9 = R_CTR;
  174. R_TOC = R_2;
  175. CR0 = 0;
  176. CR1 = 4;
  177. CR2 = 8;
  178. CR3 = 12;
  179. CR4 = 16;
  180. CR5 = 20;
  181. CR6 = 24;
  182. CR7 = 28;
  183. LT = 0;
  184. GT = 1;
  185. EQ = 2;
  186. SO = 3;
  187. FX = 4;
  188. FEX = 5;
  189. VX = 6;
  190. OX = 7;
  191. Type
  192. tregisterset = set of tregister;
  193. reg2strtable = array[tregister] of string[5];
  194. const
  195. firstreg = low(tregister);
  196. lastreg = high(tregister);
  197. gnu_reg2str : reg2strtable = ('',
  198. '0','1','2','3','4','5','6','7', '9','10','11','12','13','14','15','16',
  199. '17','18','19','20','21','22','23','24','25','26','27','28','29','30','31',
  200. 'F0','F1','F2','F3','F4','F5','F6','F7', 'F8','F9','F10','F11','F12',
  201. 'F13','F14','F15','F16','F17', 'F18','F19','F20','F21','F22', 'F23','F24',
  202. 'F25','F26','F27','F28','F29','F30','F31',
  203. 'CR','CR0','CR1','CR2','CR3','CR4','CR5','CR6','CR7',
  204. 'XER','LR','CTR','FPSCR'
  205. );
  206. mot_reg2str : reg2strtable = ('',
  207. 'R0','R1','R2','R3','R4','R5','R6','R7', 'R9','R10','R11','R12','R13',
  208. 'R14','R15','R16','R17','R18','R19','R20','R21','R22','R23','R24','R25',
  209. 'R26','R27','R28','R29','R30','R31',
  210. 'F0','F1','F2','F3','F4','F5','F6','F7', 'F8','F9','F10','F11','F12',
  211. 'F13','F14','F15','F16','F17', 'F18','F19','F20','F21','F22', 'F23','F24',
  212. 'F25','F26','F27','F28','F29','F30','F31',
  213. 'CR','CR0','CR1','CR2','CR3','CR4','CR5','CR6','CR7',
  214. 'XER','LR','CTR','FPSCR'
  215. );
  216. {*****************************************************************************
  217. Flags
  218. *****************************************************************************}
  219. type
  220. TResFlags = (F_LT,F_GT,F_EQ,F_SO,F_FX,F_FEX,F_VX,F_OX);
  221. const
  222. { arrays for boolean location conversions }
  223. flag_2_cond : array[TResFlags] of TAsmCond =
  224. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  225. {*****************************************************************************
  226. Reference
  227. *****************************************************************************}
  228. type
  229. trefoptions=(ref_none,ref_parafixup,ref_localfixup);
  230. { immediate/reference record }
  231. preference = ^treference;
  232. treference = packed record
  233. is_immediate : boolean; { is this used as reference or immediate }
  234. base: tregister;
  235. offset : longint;
  236. symbol : pasmsymbol;
  237. offsetfixup : longint;
  238. options : trefoptions;
  239. end;
  240. {*****************************************************************************
  241. Operand
  242. *****************************************************************************}
  243. type
  244. toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
  245. toper=record
  246. ot : longint;
  247. case typ : toptype of
  248. top_none : ();
  249. top_reg : (reg:tregister);
  250. top_ref : (ref:preference);
  251. top_const : (val:longint);
  252. top_symbol : (sym:pasmsymbol;symofs:longint);
  253. end;
  254. {*****************************************************************************
  255. Generic Location
  256. *****************************************************************************}
  257. type
  258. TLoc=(
  259. LOC_INVALID, { added for tracking problems}
  260. LOC_REGISTER, { in a processor register }
  261. LOC_CREGISTER { Constant register which shouldn't be modified }
  262. LOC_FPUREGISTER, { FPU register }
  263. LOC_CFPUREGISTER,{ Constant FPU register which shouldn't be modified }
  264. LOC_MMREGISTER, { multimedia register }
  265. LOC_CMMREGISTER, { Constant multimedia reg which shouldn't be modified }
  266. LOC_MEM, { in memory }
  267. LOC_REFERENCE, { like LOC_MEM, but lvalue }
  268. LOC_JUMP, { boolean results only, jump to false or true label }
  269. LOC_FLAGS, { boolean results only, flags are set }
  270. );
  271. plocation = ^tlocation;
  272. tlocation = packed record
  273. case loc : tloc of
  274. LOC_MEM,LOC_REFERENCE : (reference : treference);
  275. LOC_FPUREGISTER, LOC_CFPUREGISTER : (register: tregister);
  276. LOC_MMREGISTER, LOC_CMMREGISTER : (register: tregister);
  277. LOC_JUMP : ();
  278. LOC_FLAGS : (resflags : tresflags);
  279. LOC_INVALID : ();
  280. { segment in reference at the same place as in loc_register }
  281. LOC_REGISTER,LOC_CREGISTER : (
  282. case longint of
  283. 1 : (register,registerhigh : tregister);
  284. { overlay a registerlow }
  285. 2 : (registerlow : tregister);
  286. );
  287. end;
  288. {*****************************************************************************
  289. Constants
  290. *****************************************************************************}
  291. {type
  292. tcpuflags = (cf_registers64);}
  293. const
  294. availabletempregsint = [R_0,R_11..R_30];
  295. availabletempregsfpu = [F_14..F_31];
  296. availabletempregsmm = [M_0..M_31];
  297. intregs = [R_0..R_31];
  298. fpuregs = [R_F0..R_F31];
  299. mmregs = [R_M0..R_M31];
  300. registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];
  301. { generic register names }
  302. stack_pointer = R_1;
  303. frame_pointer = R_31;
  304. self_pointer = R_9;
  305. accumulator = R_3;
  306. cpuflags : set of tcpuflags = [];
  307. { sizes }
  308. pointersize = 4;
  309. extended_size = 8;
  310. {*****************************************************************************
  311. Helpers
  312. *****************************************************************************}
  313. { resets all values of ref to defaults }
  314. procedure reset_reference(var ref : treference);
  315. { set mostly used values of a new reference }
  316. function new_reference(base : tregister;offset : longint) : preference;
  317. function newreference(const r : treference) : preference;
  318. procedure disposereference(var r : preference);
  319. function reg2str(r : tregister) : string;
  320. function is_calljmp(o:tasmop):boolean;
  321. implementation
  322. {$ifdef heaptrc}
  323. uses
  324. ppheap;
  325. {$endif heaptrc}
  326. {*****************************************************************************
  327. Helpers
  328. *****************************************************************************}
  329. function reg2str(r : tregister) : string;
  330. begin
  331. reg2str:=mot_reg2str[r];
  332. end;
  333. function is_calljmp(o:tasmop):boolean;
  334. begin
  335. case o of
  336. A_B,
  337. A_BA,
  338. A_BLR,
  339. A_BCTR,
  340. A_BC:
  341. is_calljmp:=true;
  342. else
  343. is_calljmp:=false;
  344. end;
  345. end;
  346. procedure disposereference(var r : preference);
  347. begin
  348. dispose(r);
  349. r:=nil;
  350. end;
  351. function newreference(const r : treference) : preference;
  352. var
  353. p : preference;
  354. begin
  355. new(p);
  356. p^:=r;
  357. newreference:=p;
  358. end;
  359. procedure reset_reference(var ref : treference);
  360. begin
  361. FillChar(ref,sizeof(treference),0);
  362. end;
  363. function new_reference(base : tregister;offset : longint) : preference;
  364. var
  365. r : preference;
  366. begin
  367. new(r);
  368. FillChar(r^,sizeof(treference),0);
  369. r^.base:=base;
  370. r^.offset:=offset;
  371. new_reference:=r;
  372. end;
  373. end.
  374. {
  375. $Log$
  376. Revision 1.1 1999-08-03 23:37:53 jonas
  377. + initial implementation for PowerPC based on the Alpha stuff
  378. }