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

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_sh3.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(SH3) && defined(CONFIG_DYNCODE)
  26. //format coded in 'code' at 16bit position
  27. //00: rn,imm
  28. //01: rn,label,disp8*2
  29. //02: rn,label,disp8*4
  30. //03: rm,rn
  31. //04: rn,disp4*1
  32. //05: rn,disp4*2
  33. //06: rm,rn,disp4*4
  34. //07: rn
  35. //08: imm
  36. //09: -
  37. //0A: label8
  38. //0B: label12
  39. //0C: rn (branch)
  40. //0D: - (branch)
  41. //read at 20bit / write at 24bit
  42. //01: r1
  43. //02: r2
  44. //04: R0
  45. //08: T
  46. //spec at 28bit
  47. //01: read mac
  48. //02: read pr
  49. //04: write mac
  50. //08: write pr
  51. static INLINE int Format(int i) { return (i >> 16) & 15; }
  52. static INLINE int C(int i) { return i & 0xFFFF; }
  53. void InstInit()
  54. {
  55. }
  56. void InstPost(dyninst* p)
  57. {
  58. context* c = Context();
  59. InstAdd(p,c);
  60. }
  61. void PostAdj(dyninst* p,int Code,reg Rn,reg Rm)
  62. {
  63. if (p)
  64. {
  65. if (Code & (1<<20)) p->RdRegs |= 1 << Rn;
  66. if (Code & (2<<20)) p->RdRegs |= 1 << Rm;
  67. if (Code & (4<<20)) p->RdRegs |= 1 << R0;
  68. if (Code & (1<<28)) p->RdRegs |= 1 << MACL;
  69. if (Code & (2<<28)) p->RdRegs |= 1 << PR;
  70. p->RdFlags = Code & (8<<20) ? 1:0;
  71. if (Code & (1<<24)) p->WrRegs |= 1 << Rn;
  72. if (Code & (2<<24)) p->WrRegs |= 1 << Rm;
  73. if (Code & (4<<24)) p->WrRegs |= 1 << R0;
  74. if (Code & (4<<28)) p->WrRegs |= 1 << MACL;
  75. if (Code & (8<<28)) p->WrRegs |= 1 << PR;
  76. p->WrFlags = Code & (8<<24) ? 1:0;
  77. }
  78. InstPost(p);
  79. }
  80. void IShift(reg Rn, reg Tmp, int Left)
  81. {
  82. switch (Left)
  83. {
  84. default:
  85. if (Tmp != NONE)
  86. {
  87. I1C(MOVI,Tmp,Left);
  88. I2(SHLD,Tmp,Rn);
  89. break;
  90. }
  91. // no break;
  92. case 16+8:
  93. case 16+2:
  94. case 16+1:
  95. case 16:
  96. case 8+2:
  97. case 8+1:
  98. case 8:
  99. case 2+1:
  100. case 2:
  101. case 1:
  102. case 0:
  103. case -16-8:
  104. case -16-2:
  105. case -16-1:
  106. case -16:
  107. case -8-2:
  108. case -8-1:
  109. case -8:
  110. case -2-1:
  111. case -2:
  112. case -1:
  113. while (Left <= -16) { I1(SHLR16,Rn); Left += 16; }
  114. while (Left >= 16) { I1(SHLL16,Rn); Left -= 16; }
  115. while (Left <= -8) { I1(SHLR8,Rn); Left += 8; }
  116. while (Left >= 8) { I1(SHLL8,Rn); Left -= 8; }
  117. while (Left <= -2) { I1(SHLR2,Rn); Left += 2; }
  118. while (Left >= 2) { I1(SHLL2,Rn); Left -= 2; }
  119. while (Left <= -1) { I1(SHLR,Rn); Left += 1; }
  120. while (Left >= 1) { I1(SHLL,Rn); Left -= 1; }
  121. break;
  122. }
  123. }
  124. void I0C(int Code, int Const)
  125. {
  126. dyninst* p = NULL;
  127. if (Format(Code)==8 && Const >= -128 && Const <= 127)
  128. p = InstCreate16(C(Code) | (Const & 255),NONE,NONE,NONE,0,0);
  129. if (Format(Code)==9 && Const == 0)
  130. p = InstCreate16(C(Code),NONE,NONE,NONE,0,0);
  131. if (Format(Code)==13 && Const == 0)
  132. {
  133. p = InstCreate16(C(Code),NONE,NONE,NONE,0,0);
  134. if (p)
  135. p->Branch = 1;
  136. }
  137. PostAdj(p,Code,NONE,NONE);
  138. }
  139. void I0(int Code)
  140. {
  141. I0C(Code,0);
  142. }
  143. void I1C(int Code, reg Rn, int Const)
  144. {
  145. dyninst* p = NULL;
  146. if (Format(Code)==0 && Const >= -128 && Const <= 127)
  147. p = InstCreate16(C(Code) | (Rn << 8) | (Const & 255),NONE,NONE,NONE,0,0);
  148. if (Format(Code)==4 && Const >= -8 && Const <= 7)
  149. p = InstCreate16(C(Code) | (Rn << 4) | (Const & 15),NONE,NONE,NONE,0,0);
  150. if (Format(Code)==5 && !(Const & 1) && Const >= -16 && Const <= 14)
  151. p = InstCreate16(C(Code) | (Rn << 4) | ((Const >> 1) & 15),NONE,NONE,NONE,0,0);
  152. if (Format(Code)==7 && Const == 0)
  153. p = InstCreate16(C(Code) | (Rn << 8),NONE,NONE,NONE,0,0);
  154. if (Format(Code)==12 && Const == 0)
  155. {
  156. p = InstCreate16(C(Code) | (Rn << 8),NONE,NONE,NONE,0,0);
  157. if (p)
  158. p->Branch = 1;
  159. }
  160. PostAdj(p,Code,Rn,NONE);
  161. }
  162. void I1(int Code, reg Rn)
  163. {
  164. I1C(Code,Rn,0);
  165. }
  166. void I2C(int Code, reg Rm, reg Rn, int Const)
  167. {
  168. dyninst* p = NULL;
  169. if (Format(Code)==3 && Const == 0)
  170. p = InstCreate16(C(Code) | (Rn << 8) | (Rm << 4),NONE,NONE,NONE,0,0);
  171. if (Format(Code)==6 && !(Const & 3) && Const >= -32 && Const <= 28)
  172. p = InstCreate16(C(Code) | (Rn << 8) | (Rm << 4) | ((Const >> 2) & 15),NONE,NONE,NONE,0,0);
  173. PostAdj(p,Code,Rm,Rn);
  174. }
  175. void I2(int Code, reg Rm, reg Rn)
  176. {
  177. I2C(Code,Rm,Rn,0);
  178. }
  179. dyninst* ICode(dyninst* Block, int Ofs)
  180. {
  181. dyninst* p = InstCreate32(Ofs,NONE,NONE,NONE,0,0);
  182. if (p)
  183. {
  184. p->Tag = -1;
  185. p->ReAlloc = Block;
  186. p->Branch = 1;
  187. }
  188. return p;
  189. }
  190. void I1P(int Code, reg Rn, dyninst* Block, int Ofs)
  191. {
  192. dyninst* p = NULL;
  193. if (Format(Code)==1 && !(Ofs & 1) && Ofs >= -128*2 && Ofs <= 127*2)
  194. {
  195. p = InstCreate16(C(Code) | (Rn << 8) | ((Ofs >> 1) & 255),Rn,NONE,NONE,0,0);
  196. if (p)
  197. {
  198. p->Tag = Format(Code);
  199. p->ReAlloc = Block;
  200. p->Branch = 1;
  201. }
  202. }
  203. if (Format(Code)==2 && !(Ofs & 3) && Ofs >= -128*4 && Ofs <= 127*4)
  204. {
  205. p = InstCreate16(C(Code) | (Rn << 8) | ((Ofs >> 2) & 255),Rn,NONE,NONE,0,0);
  206. if (p)
  207. {
  208. p->Tag = Format(Code);
  209. p->ReAlloc = Block;
  210. p->Branch = 1;
  211. }
  212. }
  213. PostAdj(p,Code,Rn,NONE);
  214. }
  215. void I0P(int Code, dyninst* Block)
  216. {
  217. dyninst* p = NULL;
  218. if (Format(Code)==10 || Format(Code)==11)
  219. {
  220. p = InstCreate16(C(Code),NONE,NONE,NONE,0,0);
  221. if (p)
  222. {
  223. p->Tag = Format(Code);
  224. p->ReAlloc = Block;
  225. p->Branch = 1;
  226. }
  227. }
  228. PostAdj(p,Code,NONE,NONE);
  229. }
  230. bool_t InstReAlloc(dyninst* p,dyninst* ReAlloc)
  231. {
  232. int Diff = ReAlloc->Address - (p->Address+4);
  233. uint16_t* Code = (uint16_t*) InstCode(p);
  234. Diff >>= 1;
  235. assert(p->Tag == 10 || p->Tag == 1 || p->Tag == 2 || p->Tag == 11 || p->Tag == -1);
  236. if (p->Tag == -1) // 32bit code address
  237. {
  238. *(uint32_t*)Code += (uint32_t)ReAlloc->Address;
  239. return 1;
  240. }
  241. else
  242. if (p->Tag == 10 || p->Tag == 1 || p->Tag == 2) //8bit
  243. {
  244. if (p->Tag == 2)
  245. {
  246. assert(((int)ReAlloc->Address & 3)==0);
  247. Diff = ((int)ReAlloc->Address >> 2) - (((int)p->Address+4) >> 2);
  248. }
  249. Diff += *(int8_t*)Code;
  250. assert(Diff <= 127 && Diff >= -128);
  251. if (Diff > 127 || Diff < -128)
  252. return 0;
  253. *Code &= 0xFF00;
  254. *Code |= (uint16_t)(Diff & 0xFF);
  255. return 1;
  256. }
  257. else
  258. if (p->Tag == 11) //12bit
  259. {
  260. assert(Diff <= 2047 && Diff >= -2048);
  261. if (Diff > 2047 || Diff < -2048)
  262. return 0;
  263. *Code &= 0xF000;
  264. *Code |= (uint16_t)(Diff & 0xFFF);
  265. return 1;
  266. }
  267. return 0;
  268. }
  269. void CodeBegin(int Save,int Local)
  270. {
  271. int i;
  272. assert(Save <= 7);
  273. for (i=0;i<Save;++i)
  274. I2(MOVL_STSUB,(reg)(R8+i),SP);
  275. if (Local)
  276. I1C(ADDI,SP,-Local);
  277. }
  278. void CodeEnd(int Save,int Local)
  279. {
  280. int i;
  281. assert(Save <= 7);
  282. if (Local)
  283. I1C(ADDI,SP,Local);
  284. for (i=Save-1;i>=0;--i)
  285. I2(MOVL_LDADD,SP,(reg)(R8+i));
  286. DS(); I0(RTS);
  287. }
  288. void NOP()
  289. {
  290. dyninst* p = InstCreate16(0x0009,NONE,NONE,NONE,0,0);
  291. if (p)
  292. p->Branch = 1;
  293. InstPost(p);
  294. }
  295. void Break()
  296. {
  297. dyninst* p = InstCreate16(0xC300,NONE,NONE,NONE,0,0);
  298. if (p)
  299. p->Branch = 1;
  300. InstPost(p);
  301. }
  302. #endif