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

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.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. #ifdef CONFIG_DYNCODE
  26. void MB() { Context()->CodeMoveBack = 1; }
  27. void DS() { Context()->CodeDelaySlot = 1; }
  28. void DynCode_Init()
  29. {
  30. Context()->CodeLock = LockCreate();
  31. }
  32. void DynCode_Done()
  33. {
  34. LockDelete(Context()->CodeLock);
  35. Context()->CodeLock = NULL;
  36. }
  37. static void FreeInst()
  38. {
  39. context* c = Context();
  40. dyninst* p;
  41. for (p=(dyninst*)c->CodeInstBegin;p;)
  42. {
  43. dyninst* q = p;
  44. p = p->Next;
  45. if (q->CodeLarge)
  46. free(q->CodeLarge);
  47. free(q);
  48. }
  49. c->CodeInstBegin = NULL;
  50. c->CodeInstEnd = NULL;
  51. LockLeave(c->CodeLock);
  52. }
  53. static void FreeCode(dyncode* p)
  54. {
  55. if (p->Code)
  56. CodeFree(p->Code,p->Allocated);
  57. p->Allocated = 0;
  58. p->Code = NULL;
  59. }
  60. void CodeInit(dyncode* p)
  61. {
  62. p->Code = NULL;
  63. p->Allocated = p->Size = 0;
  64. }
  65. void CodeDone(dyncode* p)
  66. {
  67. FreeCode(p);
  68. }
  69. void CodeStart(dyncode* p)
  70. {
  71. context* c = Context();
  72. LockEnter(c->CodeLock);
  73. p->Size = 0;
  74. c->CodeFailed = 0;
  75. c->CodeMoveBack = 0;
  76. c->CodeDelaySlot = 0;
  77. InstInit();
  78. }
  79. void CodeBuild(dyncode* Code)
  80. {
  81. dyninst* p;
  82. context* c = Context();
  83. Code->Size = 0;
  84. if (c->CodeFailed)
  85. {
  86. FreeInst();
  87. return;
  88. }
  89. for (p=(dyninst*)c->CodeInstBegin;p;p=p->Next)
  90. Code->Size += InstSize(p,Code->Size);
  91. if (Code->Size > Code->Allocated)
  92. {
  93. FreeCode(Code);
  94. Code->Allocated = (Code->Size + 511) & ~511;
  95. Code->Code = (char*) CodeAlloc(Code->Allocated);
  96. }
  97. if (Code->Code)
  98. {
  99. char* Addr;
  100. CodeLock(Code->Code,Code->Allocated);
  101. Addr = Code->Code;
  102. for (p=(dyninst*)c->CodeInstBegin;p;p=p->Next)
  103. {
  104. p->Address = Addr;
  105. Addr += InstSize(p,Addr - Code->Code);
  106. }
  107. for (p=(dyninst*)c->CodeInstBegin;p;p=p->Next)
  108. {
  109. if (p->ReAlloc && (!p->ReAlloc->Address || !InstReAlloc(p,p->ReAlloc)))
  110. {
  111. Code->Size = 0;
  112. assert(Code->Size);
  113. break;
  114. }
  115. if (p->CodeLarge)
  116. memcpy(p->Address,p->CodeLarge,p->CodeSize);
  117. else
  118. if (p->CodeSize>0)
  119. {
  120. if (p->CodeSize == sizeof(int32_t))
  121. *(int32_t*)p->Address = p->CodeSmall;
  122. else
  123. if (p->CodeSize == sizeof(int16_t))
  124. *(int16_t*)p->Address = (int16_t)p->CodeSmall;
  125. else
  126. memcpy(p->Address,&p->CodeSmall,p->CodeSize);
  127. }
  128. }
  129. if (Code->Code)
  130. CodeUnlock(Code->Code,Code->Allocated);
  131. #ifdef DUMPCODE
  132. if (Code->Code)
  133. {
  134. char Name[64];
  135. FILE* f;
  136. sprintf(Name,"\code%04x.bin",Code->Size);
  137. f = fopen(Name,"wb+");
  138. fwrite(Code->Code,1,Code->Size,f);
  139. fclose(f);
  140. }
  141. #endif
  142. }
  143. else
  144. Code->Size = 0;
  145. FreeInst();
  146. }
  147. dyninst* InstCreate(const void* Code,int CodeSize, reg Wr, reg Rd1, reg Rd2, int RdFlags, int WrFlags)
  148. {
  149. dyninst* p = (dyninst*) malloc(sizeof(dyninst));
  150. if (p)
  151. {
  152. p->Tag = 0;
  153. p->Next = NULL;
  154. p->Prev = NULL;
  155. p->Address = 0;
  156. p->Branch = 0;
  157. p->ReAlloc = NULL;
  158. p->RdFlags = RdFlags;
  159. p->WrFlags = WrFlags;
  160. p->RdRegs = 0;
  161. p->WrRegs = 0;
  162. p->CodeSize = CodeSize;
  163. if (CodeSize <= (int)sizeof(p->CodeSmall))
  164. {
  165. p->CodeLarge = NULL;
  166. if (Code)
  167. p->CodeSmall = *(int*)Code;
  168. else
  169. p->CodeSmall = 0;
  170. }
  171. else
  172. {
  173. p->CodeLarge = (char*) malloc(CodeSize);
  174. if (!p->CodeLarge)
  175. {
  176. free(p);
  177. return NULL;
  178. }
  179. if (Code)
  180. memcpy(p->CodeLarge,Code,CodeSize);
  181. else
  182. memset(p->CodeLarge,0,CodeSize);
  183. }
  184. if (Wr != NONE) { if (Wr<32) p->WrRegs |= 1 << Wr; else p->WrFlags |= 256 << (Wr-32); }
  185. if (Rd1 != NONE) { if (Rd1<32) p->RdRegs |= 1 << Rd1; else p->RdFlags |= 256 << (Rd1-32); }
  186. if (Rd2 != NONE) { if (Rd2<32) p->RdRegs |= 1 << Rd2; else p->RdFlags |= 256 << (Rd2-32); }
  187. }
  188. return p;
  189. }
  190. dyninst* InstCreate32(int Code32, reg Wr, reg Rd1, reg Rd2, int RdFlags, int WrFlags)
  191. {
  192. return InstCreate(&Code32,4,Wr,Rd1,Rd2,RdFlags,WrFlags);
  193. }
  194. dyninst* InstCreate16(int Code16, reg Wr, reg Rd1, reg Rd2, int RdFlags, int WrFlags)
  195. {
  196. return InstCreate(&Code16,2,Wr,Rd1,Rd2,RdFlags,WrFlags);
  197. }
  198. void InstAdd(dyninst* New,context* c)
  199. {
  200. assert(New);
  201. if (New)
  202. {
  203. dyninst* p = c->CodeInstEnd; //insert after p
  204. if (c->CodeDelaySlot)
  205. {
  206. assert(p && !p->Branch && !InstReadWrite(p,New) && !InstReadWrite(New,p) && !InstBothWrite(p,New));
  207. p->Branch = 1;
  208. p = p->Prev;
  209. }
  210. if (c->CodeMoveBack)
  211. while (p && !p->Branch && !InstReadWrite(p,New) && !InstReadWrite(New,p) && !InstBothWrite(p,New))
  212. p = p->Prev;
  213. if (p)
  214. {
  215. if (p->Next) 
  216. p->Next->Prev = New;
  217. else
  218. c->CodeInstEnd = New;
  219. New->Next = p->Next;
  220. New->Prev = p;
  221. p->Next = New;
  222. }
  223. else
  224. {
  225. if (c->CodeInstBegin)
  226. ((dyninst*)c->CodeInstBegin)->Prev = New;
  227. else
  228. c->CodeInstEnd = New;
  229. New->Next = (dyninst*)c->CodeInstBegin;
  230. New->Prev = NULL;
  231. c->CodeInstBegin = New;
  232. }
  233. }
  234. else
  235. c->CodeFailed = 1;
  236. c->CodeMoveBack = 0;
  237. c->CodeDelaySlot = 0;
  238. }
  239. dyninst* Label(bool_t DoPost)
  240. {
  241. dyninst* p = InstCreate(NULL,0,NONE,NONE,NONE,0,0);
  242. if (p) p->Branch = 1;
  243. if (DoPost) InstPost(p);
  244. return p;
  245. }
  246. void Align(int i)
  247. {
  248. dyninst* p = InstCreate(NULL,-i,NONE,NONE,NONE,0,0);
  249. if (p) p->Branch = 1;
  250. InstPost(p);
  251. }
  252. #else
  253. void DynCode_Init() {}
  254. void DynCode_Done() {}
  255. #endif