dyncode_mips.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:11k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: dyncode_mips.c 585 2006-01-16 09:48:55Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #include "dyncode.h"
  25. #if defined(MIPS) && defined(CONFIG_DYNCODE)
  26. //format coded in 'code' at 8bit position
  27. //00: rs,rt,offset(s16<<2) (branch)
  28. //01: rs,rt,rd
  29. //02: rs,rt,immd(s16) write rt
  30. //03: rs,offset(s16<<2)
  31. //04: rs,rt ->lo,hi
  32. //05: rt,rd,sa
  33. //06: rt,rs,rd
  34. //07: addr(s26<<2)
  35. //08: rs,rt (branch)
  36. //09: rs (branch)
  37. //0A: rs,immd(s16)
  38. //0B: rd <-> lo,hi
  39. //0C: rs,rt,immd(s16) read rt
  40. #define LO 1
  41. #define HI 2
  42. static const reg SaveRegs[11] =
  43. {
  44. R16,R17,R18,R19,R20,R21,R22,R23,
  45. R30,R28,R31
  46. };
  47. void InstInit()
  48. {
  49. }
  50. static INLINE int Format(int i) { return (i >> 8) & 15; }
  51. static INLINE int C(int i) { return i & ~0xFF00; }
  52. void I3(int Code, reg Dest, reg Op1, reg Op2)
  53. {
  54. dyninst* p = NULL;
  55. if (Format(Code)==1)
  56. p = InstCreate32(C(Code) | (Dest << 11) | (Op1 << 21) | (Op2 << 16),Dest,Op1,Op2,0,0);
  57. if (Format(Code)==6)
  58. p = InstCreate32(C(Code) | (Dest << 11) | (Op2 << 21) | (Op1 << 16),Dest,Op1,Op2,0,0);
  59. InstPost(p);
  60. }
  61. void I2C(int Code, reg Dest, reg Op1, int Const)
  62. {
  63. dyninst* p = NULL;
  64. if (Code == DSLL && Const < 0)
  65. {
  66. Code = DSRL;
  67. Const = -Const;
  68. }
  69. if (Code == DSRL && Const < 0)
  70. {
  71. Code = DSLL;
  72. Const = -Const;
  73. }
  74. if (Code == SLL && Const < 0)
  75. {
  76. Code = SRL;
  77. Const = -Const;
  78. }
  79. if (Code == SRL && Const < 0)
  80. {
  81. Code = SLL;
  82. Const = -Const;
  83. }
  84. if (Code == SRA && Const < 0)
  85. {
  86. Code = SLL;
  87. Const = -Const;
  88. }
  89. if (Code == DSLL && Const >= 32)
  90. {
  91. Code = DSLL32;
  92. Const -= 32;
  93. }
  94. if (Code == DSRA && Const >= 32)
  95. {
  96. Code = DSRA32;
  97. Const -= 32;
  98. }
  99. if (Code == DSRL && Const >= 32)
  100. {
  101. Code = DSRL32;
  102. Const -= 32;
  103. }
  104. assert(Format(Code)!=4 || Const==0);
  105. if (Format(Code)==4 && Const == 0)
  106. {
  107. p = InstCreate32(C(Code) | (Dest << 21) | (Op1 << 16),NONE,Dest,Op1,0,LO|HI);
  108. }
  109. assert(Format(Code)!=8 || Const==0);
  110. if (Format(Code)==8 && Const == 0)
  111. {
  112. p = InstCreate32(C(Code) | (Dest << 11) | (Op1 << 21),Dest,Op1,NONE,0,0);
  113. if (p)
  114. p->Branch = 1;
  115. }
  116. assert(Format(Code)!=5 || (Const >= 0 && Const < 32));
  117. if (Format(Code)==5 && Const >= 0 && Const < 32)
  118. {
  119. p = InstCreate32(C(Code) | (Dest << 11) | (Op1 << 16) | (Const << 6),Dest,Op1,NONE,0,0);
  120. }
  121. if ((Code == ANDI || Code == ORI || Code == XORI) && Const >= 32768)
  122. Const -= 65536;
  123. assert(Format(Code)!=2 || (Const >= -32768 && Const < 32768));
  124. if (Format(Code)==2 && Const >= -32768 && Const < 32768)
  125. {
  126. p = InstCreate32(C(Code) | (Dest << 16) | (Op1 << 21) | (Const & 0xFFFF),Dest,Op1,NONE,0,0);
  127. }
  128. assert(Format(Code)!=12 || (Const >= -32768 && Const < 32768));
  129. if (Format(Code)==12 && Const >= -32768 && Const < 32768)
  130. {
  131. p = InstCreate32(C(Code) | (Dest << 16) | (Op1 << 21) | (Const & 0xFFFF),NONE,Op1,Dest,0,0);
  132. }
  133. InstPost(p);
  134. }
  135. void I2(int Code, reg Rm, reg Rn)
  136. {
  137. I2C(Code,Rm,Rn,0);
  138. }
  139. void I2P(int Code, reg Op1, reg Op2, dyninst* Block)
  140. {
  141. dyninst* p = NULL;
  142. if (Format(Code)==0)
  143. {
  144. p = InstCreate32(C(Code) | (Op2 << 16) | (Op1 << 21),NONE,Op1,Op2,0,0);
  145. if (p)
  146. {
  147. p->Tag = Format(Code);
  148. p->ReAlloc = Block;
  149. p->Branch = 1;
  150. }
  151. }
  152. InstPost(p);
  153. }
  154. void I1C(int Code, reg Reg, int Const)
  155. {
  156. dyninst* p = NULL;
  157. if (Format(Code)==10 && Const >= -32768 && Const < 32768)
  158. {
  159. p = InstCreate32(C(Code) | (Reg << 16) | (Const & 0xFFFF),Reg,NONE,NONE,0,0);
  160. }
  161. if (Format(Code)==11 && Const==0)
  162. {
  163. if (Code == MFHI) p = InstCreate32(C(Code) | (Reg << 11),Reg,NONE,NONE,HI,0);
  164. if (Code == MFLO) p = InstCreate32(C(Code) | (Reg << 11),Reg,NONE,NONE,LO,0);
  165. if (Code == MTHI) p = InstCreate32(C(Code) | (Reg << 21),NONE,Reg,NONE,0,HI);
  166. if (Code == MTLO) p = InstCreate32(C(Code) | (Reg << 21),NONE,Reg,NONE,0,LO);
  167. }
  168. if (Format(Code)==9 && Const==0)
  169. {
  170. p = InstCreate32(C(Code) | (Reg << 21),NONE,Reg,NONE,0,0);
  171. if (p)
  172. p->Branch = 1;
  173. }
  174. InstPost(p);
  175. }
  176. void I1(int Code, reg Rn)
  177. {
  178. I1C(Code,Rn,0);
  179. }
  180. void I1P(int Code, reg Reg, dyninst* Block, int Ofs)
  181. {
  182. dyninst* p = NULL;
  183. if (Format(Code)==3)
  184. {
  185. p = InstCreate32(C(Code) | (Reg << 21),NONE,Reg,NONE,0,0);
  186. if (p)
  187. {
  188. p->Tag = Format(Code);
  189. p->ReAlloc = Block;
  190. }
  191. }
  192. InstPost(p);
  193. }
  194. bool_t InstReAlloc(dyninst* p,dyninst* ReAlloc)
  195. {
  196. int Diff = ReAlloc->Address - (p->Address+4);
  197. int* Code = (int*) InstCode(p);
  198. if (p->CodeSize > 4)
  199. {
  200. // address table
  201. int i;
  202. for (i=0;i<p->CodeSize;i+=4,++Code)
  203. *Code += (int)ReAlloc->Address;
  204. return 1;
  205. }
  206. Diff >>= 2;
  207. assert(Diff <= 32767 && Diff >= -32768);
  208. if (Diff > 32767 || Diff < -32768)
  209. {
  210. DEBUG_MSG1(-1,T("Realloc failed %d"),Diff);
  211. return 0;
  212. }
  213. assert(p->Tag==0 || p->Tag==3);
  214. if (p->Tag == 0)
  215. {
  216. *Code &= ~0xFFFF;
  217. *Code |= (uint16_t)Diff;
  218. return 1;
  219. }
  220. else
  221. if (p->Tag == 3)
  222. {
  223. *Code &= ~0xFFFF;
  224. *Code |= (uint16_t)Diff;
  225. return 1;
  226. }
  227. DEBUG_MSG(-1,T("Realloc failed unknown tag"));
  228. return 0;
  229. }
  230. void CodeBegin(int Save,int Local,bool_t Align64)
  231. {
  232. int i;
  233. assert(Save <= 11);
  234. if (Align64)
  235. {
  236. I3(OR,R2,SP,SP);
  237. I2C(ADDIU,SP,SP,-8);
  238. I2C(ANDI,R8,SP,4);
  239. I3(ADDU,SP,SP,R8);
  240. I2C(SW,R8,SP,0);
  241. }
  242. if (Save || Local)
  243. {
  244. I2C(ADDIU,SP,SP,-Save*4-Local);
  245. for (i=0;i<Save;++i)
  246. I2C(SW,SaveRegs[i],SP,i*4+Local);
  247. }
  248. }
  249. void CodeEnd(int Save,int Local,bool_t Align64)
  250. {
  251. if (Save || Local)
  252. {
  253. int i;
  254. assert(Save <= 11);
  255. for (i=Save-1;i>=0;--i)
  256. I2C(LW,SaveRegs[i],SP,i*4+Local);
  257. I2C(ADDIU,SP,SP,Save*4+Local);
  258. }
  259. if (Align64)
  260. {
  261. I2C(LW,R8,SP,0);
  262. I3(SUBU,SP,SP,R8);
  263. I2C(ADDIU,SP,SP,8);
  264. }
  265. DS(); I1(JR,RA);
  266. }
  267. void NOP()
  268. {
  269. dyninst* p = InstCreate32(0,NONE,NONE,NONE,0,0);
  270. if (p)
  271. p->Branch = 1;
  272. InstPost(p);
  273. }
  274. void Break()
  275. {
  276. dyninst* p = InstCreate32(0x0000000D,NONE,NONE,NONE,0,0);
  277. if (p)
  278. p->Branch = 1;
  279. InstPost(p);
  280. }
  281. void InstPost(dyninst* p)
  282. {
  283. context* c = Context();
  284. InstAdd(p,c);
  285. }
  286. void IConst(reg Dst,int Const)
  287. {
  288. I1C(LUI,Dst,Const >> 16);
  289. I2C(ORI,Dst,Dst,(int16_t)Const);
  290. }
  291. reg IMul(reg Op1, int Mul, reg Tmp1, reg Tmp2, reg Tmp3, bool_t* Neg)
  292. {
  293. reg Result = Tmp3;
  294. if (Neg) 
  295. *Neg = 0;
  296. if (Mul>=0)
  297. switch (Mul)
  298. {
  299. case 0: Result=ZERO; break;
  300. case 1: Result=Op1; break;
  301. case 2: I3(ADDU,Result,Op1,Op1); break;
  302. case 3: I2C(SLL,Tmp1,Op1,1); I3(ADDU,Result,Tmp1,Op1); break;
  303. case 4: I2C(SLL,Result,Op1,2); break;
  304. case 5: I2C(SLL,Tmp1,Op1,2); I3(ADDU,Result,Tmp1,Op1); break;
  305. case 6: I2C(SLL,Tmp1,Op1,2); I2C(SLL,Tmp2,Op1,1); I3(ADDU,Result,Tmp1,Tmp2); break;
  306. case 7: I2C(SLL,Tmp1,Op1,3); I3(SUBU,Result,Tmp1,Op1); break;
  307. case 8: I2C(SLL,Result,Op1,3); break;
  308. case 9: I2C(SLL,Tmp1,Op1,3); I3(ADDU,Result,Tmp1,Op1); break;
  309. case 10: I2C(SLL,Tmp1,Op1,3); I2C(SLL,Tmp2,Op1,1); I3(ADDU,Result,Tmp1,Tmp2); break;
  310. case 11: I2C(SLL,Tmp1,Op1,3); I2C(SLL,Tmp2,Op1,1); I3(ADDU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); break;
  311. case 12: I2C(SLL,Tmp1,Op1,3); I2C(SLL,Tmp2,Op1,2); I3(ADDU,Result,Tmp1,Tmp2); break; 
  312. case 13: I2C(SLL,Tmp1,Op1,3); I2C(SLL,Tmp2,Op1,2); I3(ADDU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); break;
  313. case 14: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,1); I3(SUBU,Result,Tmp1,Tmp2); break; 
  314. case 15: I2C(SLL,Tmp1,Op1,4); I3(SUBU,Result,Tmp1,Op1); break;
  315. case 16: I2C(SLL,Result,Op1,4); break;
  316. case 17: I2C(SLL,Tmp1,Op1,4); I3(ADDU,Result,Tmp1,Op1); break;
  317. case 18: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,1); I3(ADDU,Result,Tmp1,Tmp2); break;
  318. case 19: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,1); I3(ADDU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); break;
  319. case 20: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,2); I3(ADDU,Result,Tmp1,Tmp2); break;
  320. case 21: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,2); I3(ADDU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); break;
  321. case 22: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,2); I3(ADDU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); I3(ADDU,Result,Result,Op1); break;
  322. case 23: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,3); I3(ADDU,Result,Tmp1,Tmp2); I3(SUBU,Result,Result,Op1); break;
  323. case 24: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,3); I3(ADDU,Result,Tmp1,Tmp2); break;
  324. case 25: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,3); I3(ADDU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); break;
  325. case 26: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,3); I3(ADDU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); I3(ADDU,Result,Result,Op1); break;
  326. case 27: I2C(SLL,Tmp1,Op1,5); I2C(SLL,Tmp2,Op1,2); I3(SUBU,Result,Tmp1,Tmp2); I3(SUBU,Result,Result,Op1); break;
  327. case 28: I2C(SLL,Tmp1,Op1,5); I2C(SLL,Tmp2,Op1,2); I3(SUBU,Result,Tmp1,Tmp2); break;
  328. case 29: I2C(SLL,Tmp1,Op1,5); I2C(SLL,Tmp2,Op1,2); I3(SUBU,Result,Tmp1,Tmp2); I3(ADDU,Result,Result,Op1); break;
  329. case 30: I2C(SLL,Tmp1,Op1,5); I2C(SLL,Tmp2,Op1,1); I3(SUBU,Result,Tmp1,Tmp2); break;
  330. case 31: I2C(SLL,Tmp1,Op1,5); I3(SUBU,Result,Tmp1,Op1); break;
  331. default: I2C(SLL,Result,Op1,5); break;
  332. }
  333. else
  334. switch (Mul)
  335. {
  336. case -1: I3(SUBU,Result,ZERO,Op1); break;
  337. case -3: I2C(SLL,Tmp1,Op1,2); I3(SUBU,Result,Op1,Tmp1); break;
  338. case -6: I2C(SLL,Tmp1,Op1,1); I2C(SLL,Tmp2,Op1,3); I3(SUBU,Result,Tmp1,Tmp2); break;
  339. case -7: I2C(SLL,Tmp1,Op1,3); I3(SUBU,Result,Op1,Tmp1); break;
  340. case -11: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,2); I3(ADDU,Tmp2,Tmp2,Op1); I3(SUBU,Result,Tmp2,Tmp1); break;
  341. case -12: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,2); I3(SUBU,Result,Tmp2,Tmp1); break; 
  342. case -13: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,1); I3(ADDU,Tmp2,Tmp2,Op1); I3(SUBU,Result,Tmp2,Tmp1); break;
  343. case -14: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,1); I3(SUBU,Result,Tmp2,Tmp1); break; 
  344. case -15: I2C(SLL,Tmp1,Op1,4); I3(SUBU,Result,Op1,Tmp1); break;
  345. case -19: I2C(SLL,Tmp1,Op1,4); I2C(SLL,Tmp2,Op1,2); I3(SUBU,Result,Op1,Tmp1); I3(SUBU,Result,Result,Tmp2); break;
  346. default: 
  347. Result = IMul(Op1,-Mul,Tmp1,Tmp2,Tmp3,NULL);
  348. if (Neg)
  349.  *Neg = 1;
  350. else
  351. I3(SUBU,Result,ZERO,Result); 
  352. break;
  353. }
  354. return Result;
  355. }
  356. #endif