armsupp.cpp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127
  1. /* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
  2. Copyright (C) 1994 Advanced RISC Machines Ltd.
  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. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. #include "core/arm/skyeye_common/armdefs.h"
  15. #include "core/arm/skyeye_common/armemu.h"
  16. #include "core/arm/disassembler/arm_disasm.h"
  17. #include "core/mem_map.h"
  18. static ARMword ModeToBank (ARMword);
  19. static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
  20. struct EventNode {
  21. /* An event list node. */
  22. unsigned (*func) (ARMul_State *); /* The function to call. */
  23. struct EventNode *next;
  24. };
  25. /* This routine returns the value of a register from a mode. */
  26. ARMword
  27. ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
  28. {
  29. mode &= MODEBITS;
  30. if (mode != state->Mode)
  31. return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
  32. else
  33. return (state->Reg[reg]);
  34. }
  35. /* This routine sets the value of a register for a mode. */
  36. void
  37. ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
  38. {
  39. mode &= MODEBITS;
  40. if (mode != state->Mode)
  41. state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
  42. else
  43. state->Reg[reg] = value;
  44. }
  45. /* This routine returns the value of the PC, mode independently. */
  46. ARMword
  47. ARMul_GetPC (ARMul_State * state)
  48. {
  49. if (state->Mode > SVC26MODE)
  50. return state->Reg[15];
  51. else
  52. return R15PC;
  53. }
  54. /* This routine returns the value of the PC, mode independently. */
  55. ARMword
  56. ARMul_GetNextPC (ARMul_State * state)
  57. {
  58. if (state->Mode > SVC26MODE)
  59. return state->Reg[15] + INSN_SIZE;
  60. else
  61. return (state->Reg[15] + INSN_SIZE) & R15PCBITS;
  62. }
  63. /* This routine sets the value of the PC. */
  64. void
  65. ARMul_SetPC (ARMul_State * state, ARMword value)
  66. {
  67. if (ARMul_MODE32BIT)
  68. state->Reg[15] = value & PCBITS;
  69. else
  70. state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
  71. FLUSHPIPE;
  72. }
  73. /* This routine returns the value of register 15, mode independently. */
  74. ARMword
  75. ARMul_GetR15 (ARMul_State * state)
  76. {
  77. if (state->Mode > SVC26MODE)
  78. return (state->Reg[15]);
  79. else
  80. return (R15PC | ECC | ER15INT | EMODE);
  81. }
  82. /* This routine sets the value of Register 15. */
  83. void
  84. ARMul_SetR15 (ARMul_State * state, ARMword value)
  85. {
  86. if (ARMul_MODE32BIT)
  87. state->Reg[15] = value & PCBITS;
  88. else {
  89. state->Reg[15] = value;
  90. ARMul_R15Altered (state);
  91. }
  92. FLUSHPIPE;
  93. }
  94. /* This routine returns the value of the CPSR. */
  95. ARMword
  96. ARMul_GetCPSR (ARMul_State * state)
  97. {
  98. //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator
  99. //return (CPSR | state->Cpsr); for gdb20030716
  100. return (CPSR); //had be tested in old skyeye with gdb5.0-5.3
  101. }
  102. /* This routine sets the value of the CPSR. */
  103. void
  104. ARMul_SetCPSR (ARMul_State * state, ARMword value)
  105. {
  106. state->Cpsr = value;
  107. ARMul_CPSRAltered (state);
  108. }
  109. /* This routine does all the nasty bits involved in a write to the CPSR,
  110. including updating the register bank, given a MSR instruction. */
  111. void
  112. ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
  113. {
  114. state->Cpsr = ARMul_GetCPSR (state);
  115. //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
  116. if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
  117. /* In user mode, only write flags. */
  118. if (BIT (16))
  119. SETPSR_C (state->Cpsr, rhs);
  120. if (BIT (17))
  121. SETPSR_X (state->Cpsr, rhs);
  122. if (BIT (18))
  123. SETPSR_S (state->Cpsr, rhs);
  124. }
  125. if (BIT (19))
  126. SETPSR_F (state->Cpsr, rhs);
  127. ARMul_CPSRAltered (state);
  128. }
  129. /* Get an SPSR from the specified mode. */
  130. ARMword
  131. ARMul_GetSPSR (ARMul_State * state, ARMword mode)
  132. {
  133. ARMword bank = ModeToBank (mode & MODEBITS);
  134. if (!BANK_CAN_ACCESS_SPSR (bank))
  135. return ARMul_GetCPSR (state);
  136. return state->Spsr[bank];
  137. }
  138. /* This routine does a write to an SPSR. */
  139. void
  140. ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
  141. {
  142. ARMword bank = ModeToBank (mode & MODEBITS);
  143. if (BANK_CAN_ACCESS_SPSR (bank))
  144. state->Spsr[bank] = value;
  145. }
  146. /* This routine does a write to the current SPSR, given an MSR instruction. */
  147. void
  148. ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
  149. {
  150. if (BANK_CAN_ACCESS_SPSR (state->Bank)) {
  151. if (BIT (16))
  152. SETPSR_C (state->Spsr[state->Bank], rhs);
  153. if (BIT (17))
  154. SETPSR_X (state->Spsr[state->Bank], rhs);
  155. if (BIT (18))
  156. SETPSR_S (state->Spsr[state->Bank], rhs);
  157. if (BIT (19))
  158. SETPSR_F (state->Spsr[state->Bank], rhs);
  159. }
  160. }
  161. /* This routine updates the state of the emulator after the Cpsr has been
  162. changed. Both the processor flags and register bank are updated. */
  163. void
  164. ARMul_CPSRAltered (ARMul_State * state)
  165. {
  166. ARMword oldmode;
  167. if (state->prog32Sig == LOW)
  168. state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
  169. oldmode = state->Mode;
  170. /*if (state->Mode != (state->Cpsr & MODEBITS)) {
  171. state->Mode =
  172. ARMul_SwitchMode (state, state->Mode,
  173. state->Cpsr & MODEBITS);
  174. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  175. }*/
  176. //state->Cpsr &= ~MODEBITS;
  177. ASSIGNINT (state->Cpsr & INTBITS);
  178. //state->Cpsr &= ~INTBITS;
  179. ASSIGNN ((state->Cpsr & NBIT) != 0);
  180. //state->Cpsr &= ~NBIT;
  181. ASSIGNZ ((state->Cpsr & ZBIT) != 0);
  182. //state->Cpsr &= ~ZBIT;
  183. ASSIGNC ((state->Cpsr & CBIT) != 0);
  184. //state->Cpsr &= ~CBIT;
  185. ASSIGNV ((state->Cpsr & VBIT) != 0);
  186. //state->Cpsr &= ~VBIT;
  187. ASSIGNQ ((state->Cpsr & QBIT) != 0);
  188. //state->Cpsr &= ~QBIT;
  189. state->GEFlag = (state->Cpsr & 0x000F0000);
  190. #ifdef MODET
  191. ASSIGNT ((state->Cpsr & TBIT) != 0);
  192. //state->Cpsr &= ~TBIT;
  193. #endif
  194. if (oldmode > SVC26MODE) {
  195. if (state->Mode <= SVC26MODE) {
  196. state->Emulate = CHANGEMODE;
  197. state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
  198. }
  199. } else {
  200. if (state->Mode > SVC26MODE) {
  201. state->Emulate = CHANGEMODE;
  202. state->Reg[15] = R15PC;
  203. } else
  204. state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
  205. }
  206. }
  207. /* This routine updates the state of the emulator after register 15 has
  208. been changed. Both the processor flags and register bank are updated.
  209. This routine should only be called from a 26 bit mode. */
  210. void
  211. ARMul_R15Altered (ARMul_State * state)
  212. {
  213. if (state->Mode != R15MODE) {
  214. state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
  215. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  216. }
  217. if (state->Mode > SVC26MODE)
  218. state->Emulate = CHANGEMODE;
  219. ASSIGNR15INT (R15INT);
  220. ASSIGNN ((state->Reg[15] & NBIT) != 0);
  221. ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
  222. ASSIGNC ((state->Reg[15] & CBIT) != 0);
  223. ASSIGNV ((state->Reg[15] & VBIT) != 0);
  224. }
  225. /* This routine controls the saving and restoring of registers across mode
  226. changes. The regbank matrix is largely unused, only rows 13 and 14 are
  227. used across all modes, 8 to 14 are used for FIQ, all others use the USER
  228. column. It's easier this way. old and new parameter are modes numbers.
  229. Notice the side effect of changing the Bank variable. */
  230. ARMword
  231. ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
  232. {
  233. unsigned i;
  234. ARMword oldbank;
  235. ARMword newbank;
  236. static int revision_value = 53;
  237. oldbank = ModeToBank (oldmode);
  238. newbank = state->Bank = ModeToBank (newmode);
  239. /* Do we really need to do it? */
  240. if (oldbank != newbank) {
  241. if (oldbank == 3 && newbank == 2) {
  242. //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank);
  243. if (state->NumInstrs >= 5832487) {
  244. // printf("%d, ", state->NumInstrs + revision_value);
  245. // printf("revision_value : %d\n", revision_value);
  246. revision_value ++;
  247. }
  248. }
  249. /* Save away the old registers. */
  250. switch (oldbank) {
  251. case USERBANK:
  252. case IRQBANK:
  253. case SVCBANK:
  254. case ABORTBANK:
  255. case UNDEFBANK:
  256. if (newbank == FIQBANK)
  257. for (i = 8; i < 13; i++)
  258. state->RegBank[USERBANK][i] =
  259. state->Reg[i];
  260. state->RegBank[oldbank][13] = state->Reg[13];
  261. state->RegBank[oldbank][14] = state->Reg[14];
  262. break;
  263. case FIQBANK:
  264. for (i = 8; i < 15; i++)
  265. state->RegBank[FIQBANK][i] = state->Reg[i];
  266. break;
  267. case DUMMYBANK:
  268. for (i = 8; i < 15; i++)
  269. state->RegBank[DUMMYBANK][i] = 0;
  270. break;
  271. default:
  272. abort ();
  273. }
  274. /* Restore the new registers. */
  275. switch (newbank) {
  276. case USERBANK:
  277. case IRQBANK:
  278. case SVCBANK:
  279. case ABORTBANK:
  280. case UNDEFBANK:
  281. if (oldbank == FIQBANK)
  282. for (i = 8; i < 13; i++)
  283. state->Reg[i] =
  284. state->RegBank[USERBANK][i];
  285. state->Reg[13] = state->RegBank[newbank][13];
  286. state->Reg[14] = state->RegBank[newbank][14];
  287. break;
  288. case FIQBANK:
  289. for (i = 8; i < 15; i++)
  290. state->Reg[i] = state->RegBank[FIQBANK][i];
  291. break;
  292. case DUMMYBANK:
  293. for (i = 8; i < 15; i++)
  294. state->Reg[i] = 0;
  295. break;
  296. default:
  297. abort ();
  298. }
  299. }
  300. return newmode;
  301. }
  302. /* Given a processor mode, this routine returns the
  303. register bank that will be accessed in that mode. */
  304. static ARMword
  305. ModeToBank (ARMword mode)
  306. {
  307. static ARMword bankofmode[] = {
  308. USERBANK, FIQBANK, IRQBANK, SVCBANK,
  309. DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
  310. DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
  311. DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
  312. USERBANK, FIQBANK, IRQBANK, SVCBANK,
  313. DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
  314. DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
  315. DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
  316. };
  317. if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
  318. return DUMMYBANK;
  319. return bankofmode[mode];
  320. }
  321. /* Returns the register number of the nth register in a reg list. */
  322. unsigned
  323. ARMul_NthReg (ARMword instr, unsigned number)
  324. {
  325. unsigned bit, upto;
  326. for (bit = 0, upto = 0; upto <= number; bit++)
  327. if (BIT (bit))
  328. upto++;
  329. return (bit - 1);
  330. }
  331. /* Unsigned sum of absolute difference */
  332. u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
  333. {
  334. if (left > right)
  335. return left - right;
  336. return right - left;
  337. }
  338. /* Assigns the N and Z flags depending on the value of result. */
  339. void
  340. ARMul_NegZero (ARMul_State * state, ARMword result)
  341. {
  342. if (NEG (result)) {
  343. SETN;
  344. CLEARZ;
  345. } else if (result == 0) {
  346. CLEARN;
  347. SETZ;
  348. } else {
  349. CLEARN;
  350. CLEARZ;
  351. }
  352. }
  353. // Compute whether an addition of A and B, giving RESULT, overflowed.
  354. bool AddOverflow(ARMword a, ARMword b, ARMword result)
  355. {
  356. return ((NEG(a) && NEG(b) && POS(result)) ||
  357. (POS(a) && POS(b) && NEG(result)));
  358. }
  359. // Compute whether a subtraction of A and B, giving RESULT, overflowed.
  360. bool SubOverflow(ARMword a, ARMword b, ARMword result)
  361. {
  362. return ((NEG(a) && POS(b) && POS(result)) ||
  363. (POS(a) && NEG(b) && NEG(result)));
  364. }
  365. /* Assigns the C flag after an addition of a and b to give result. */
  366. void
  367. ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
  368. {
  369. ASSIGNC ((NEG (a) && NEG (b)) ||
  370. (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
  371. }
  372. /* Assigns the V flag after an addition of a and b to give result. */
  373. void
  374. ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
  375. {
  376. ASSIGNV (AddOverflow (a, b, result));
  377. }
  378. // Returns true if the Q flag should be set as a result of overflow.
  379. bool ARMul_AddOverflowQ(ARMword a, ARMword b)
  380. {
  381. u32 result = a + b;
  382. if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
  383. return true;
  384. return false;
  385. }
  386. /* Assigns the C flag after an subtraction of a and b to give result. */
  387. void
  388. ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
  389. {
  390. ASSIGNC ((NEG (a) && POS (b)) ||
  391. (NEG (a) && POS (result)) || (POS (b) && POS (result)));
  392. }
  393. /* Assigns the V flag after an subtraction of a and b to give result. */
  394. void
  395. ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
  396. {
  397. ASSIGNV (SubOverflow (a, b, result));
  398. }
  399. /* 8-bit signed saturated addition */
  400. u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
  401. {
  402. u8 result = left + right;
  403. if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) {
  404. if (left & 0x80)
  405. result = 0x80;
  406. else
  407. result = 0x7F;
  408. }
  409. return result;
  410. }
  411. /* 8-bit signed saturated subtraction */
  412. u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
  413. {
  414. u8 result = left - right;
  415. if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) {
  416. if (left & 0x80)
  417. result = 0x80;
  418. else
  419. result = 0x7F;
  420. }
  421. return result;
  422. }
  423. /* 16-bit signed saturated addition */
  424. u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
  425. {
  426. u16 result = left + right;
  427. if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) {
  428. if (left & 0x8000)
  429. result = 0x8000;
  430. else
  431. result = 0x7FFF;
  432. }
  433. return result;
  434. }
  435. /* 16-bit signed saturated subtraction */
  436. u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
  437. {
  438. u16 result = left - right;
  439. if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) {
  440. if (left & 0x8000)
  441. result = 0x8000;
  442. else
  443. result = 0x7FFF;
  444. }
  445. return result;
  446. }
  447. /* 8-bit unsigned saturated addition */
  448. u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
  449. {
  450. u8 result = left + right;
  451. if (result < left)
  452. result = 0xFF;
  453. return result;
  454. }
  455. /* 16-bit unsigned saturated addition */
  456. u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
  457. {
  458. u16 result = left + right;
  459. if (result < left)
  460. result = 0xFFFF;
  461. return result;
  462. }
  463. /* 8-bit unsigned saturated subtraction */
  464. u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
  465. {
  466. if (left <= right)
  467. return 0;
  468. return left - right;
  469. }
  470. /* 16-bit unsigned saturated subtraction */
  471. u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
  472. {
  473. if (left <= right)
  474. return 0;
  475. return left - right;
  476. }
  477. // Signed saturation.
  478. u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
  479. {
  480. const u32 max = (1 << shift) - 1;
  481. const s32 top = (value >> shift);
  482. if (top > 0) {
  483. *saturation_occurred = true;
  484. return max;
  485. }
  486. else if (top < -1) {
  487. *saturation_occurred = true;
  488. return ~max;
  489. }
  490. *saturation_occurred = false;
  491. return (u32)value;
  492. }
  493. // Unsigned saturation
  494. u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
  495. {
  496. const u32 max = (1 << shift) - 1;
  497. if (value < 0) {
  498. *saturation_occurred = true;
  499. return 0;
  500. } else if ((u32)value > max) {
  501. *saturation_occurred = true;
  502. return max;
  503. }
  504. *saturation_occurred = false;
  505. return (u32)value;
  506. }
  507. /* This function does the work of generating the addresses used in an
  508. LDC instruction. The code here is always post-indexed, it's up to the
  509. caller to get the input address correct and to handle base register
  510. modification. It also handles the Busy-Waiting. */
  511. void
  512. ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
  513. {
  514. unsigned cpab;
  515. ARMword data;
  516. UNDEF_LSCPCBaseWb;
  517. //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
  518. /*chy 2004-05-23 should update this function in the future,should concern dataabort*/
  519. // chy 2004-05-25 , fix it now,so needn't printf
  520. // printf("SKYEYE ARMul_LDC, should update this function!!!!!\n");
  521. //exit(-1);
  522. //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  523. if (!state->LDC[CPNum]) {
  524. /*
  525. printf
  526. ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n",
  527. CPNum, instr, address);
  528. */
  529. ARMul_UndefInstr (state, instr);
  530. return;
  531. }
  532. /*if (ADDREXCEPT (address))
  533. INTERNALABORT (address);*/
  534. cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
  535. while (cpab == ARMul_BUSY) {
  536. ARMul_Icycles (state, 1, 0);
  537. if (IntPending (state)) {
  538. cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT,
  539. instr, 0);
  540. return;
  541. } else
  542. cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr,
  543. 0);
  544. }
  545. if (cpab == ARMul_CANT) {
  546. /*
  547. printf
  548. ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n",
  549. CPNum, instr, address);
  550. */
  551. CPTAKEABORT;
  552. return;
  553. }
  554. cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
  555. data = ARMul_LoadWordN (state, address);
  556. //chy 2004-05-25
  557. if (state->abortSig || state->Aborted)
  558. goto L_ldc_takeabort;
  559. BUSUSEDINCPCN;
  560. //chy 2004-05-25
  561. /*
  562. if (BIT (21))
  563. LSBase = state->Base;
  564. */
  565. cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
  566. while (cpab == ARMul_INC) {
  567. address += 4;
  568. data = ARMul_LoadWordN (state, address);
  569. //chy 2004-05-25
  570. if (state->abortSig || state->Aborted)
  571. goto L_ldc_takeabort;
  572. cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
  573. }
  574. //chy 2004-05-25
  575. L_ldc_takeabort:
  576. if (BIT (21)) {
  577. if (!
  578. ((state->abortSig || state->Aborted)
  579. && state->lateabtSig == LOW))
  580. LSBase = state->Base;
  581. }
  582. if (state->abortSig || state->Aborted)
  583. TAKEABORT;
  584. }
  585. /* This function does the work of generating the addresses used in an
  586. STC instruction. The code here is always post-indexed, it's up to the
  587. caller to get the input address correct and to handle base register
  588. modification. It also handles the Busy-Waiting. */
  589. void
  590. ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
  591. {
  592. unsigned cpab;
  593. ARMword data;
  594. UNDEF_LSCPCBaseWb;
  595. //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
  596. /*chy 2004-05-23 should update this function in the future,should concern dataabort */
  597. // skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n");
  598. // chy 2004-05-25 , fix it now,so needn't printf
  599. // printf("SKYEYE ARMul_STC, should update this function!!!!!\n");
  600. //exit(-1);
  601. //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  602. if (!state->STC[CPNum]) {
  603. /*
  604. printf
  605. ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n",
  606. CPNum, instr, address);
  607. */
  608. ARMul_UndefInstr (state, instr);
  609. return;
  610. }
  611. /*if (ADDREXCEPT (address) || VECTORACCESS (address))
  612. INTERNALABORT (address);*/
  613. cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
  614. while (cpab == ARMul_BUSY) {
  615. ARMul_Icycles (state, 1, 0);
  616. if (IntPending (state)) {
  617. cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT,
  618. instr, 0);
  619. return;
  620. } else
  621. cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr,
  622. &data);
  623. }
  624. if (cpab == ARMul_CANT) {
  625. /*
  626. printf
  627. ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n",
  628. CPNum, instr, address);
  629. */
  630. CPTAKEABORT;
  631. return;
  632. }
  633. /*#ifndef MODE32
  634. if (ADDREXCEPT (address) || VECTORACCESS (address))
  635. INTERNALABORT (address);
  636. #endif*/
  637. BUSUSEDINCPCN;
  638. //chy 2004-05-25
  639. /*
  640. if (BIT (21))
  641. LSBase = state->Base;
  642. */
  643. cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
  644. ARMul_StoreWordN (state, address, data);
  645. //chy 2004-05-25
  646. if (state->abortSig || state->Aborted)
  647. goto L_stc_takeabort;
  648. while (cpab == ARMul_INC) {
  649. address += 4;
  650. cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
  651. ARMul_StoreWordN (state, address, data);
  652. //chy 2004-05-25
  653. if (state->abortSig || state->Aborted)
  654. goto L_stc_takeabort;
  655. }
  656. //chy 2004-05-25
  657. L_stc_takeabort:
  658. if (BIT (21)) {
  659. if (!
  660. ((state->abortSig || state->Aborted)
  661. && state->lateabtSig == LOW))
  662. LSBase = state->Base;
  663. }
  664. if (state->abortSig || state->Aborted)
  665. TAKEABORT;
  666. }
  667. /* This function does the Busy-Waiting for an MCR instruction. */
  668. void
  669. ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
  670. {
  671. unsigned cpab;
  672. int cm = BITS(0, 3) & 0xf;
  673. int cp = BITS(5, 7) & 0x7;
  674. int rd = BITS(12, 15) & 0xf;
  675. int cn = BITS(16, 19) & 0xf;
  676. int cpopc = BITS(21, 23) & 0x7;
  677. if (CPNum == 15 && source == 0) //Cache flush
  678. {
  679. return;
  680. }
  681. //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source);
  682. //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  683. if (!state->MCR[CPNum]) {
  684. //chy 2004-07-19 should fix in the future ????!!!!
  685. LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x",CPNum, source);
  686. ARMul_UndefInstr (state, instr);
  687. return;
  688. }
  689. //DEBUG("SKYEYE ARMul_MCR p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp);
  690. //DEBUG("plutoo: MCR not implemented\n");
  691. //exit(1);
  692. //return;
  693. cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
  694. while (cpab == ARMul_BUSY) {
  695. ARMul_Icycles (state, 1, 0);
  696. if (IntPending (state)) {
  697. cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT,
  698. instr, 0);
  699. return;
  700. } else
  701. cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr,
  702. source);
  703. }
  704. if (cpab == ARMul_CANT) {
  705. LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x", instr, CPNum, source); //ichfly todo
  706. //ARMul_Abort (state, ARMul_UndefinedInstrV);
  707. } else {
  708. BUSUSEDINCPCN;
  709. ARMul_Ccycles (state, 1, 0);
  710. }
  711. }
  712. /* This function does the Busy-Waiting for an MCRR instruction. */
  713. void
  714. ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2)
  715. {
  716. unsigned cpab;
  717. //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  718. if (!state->MCRR[CPNum]) {
  719. ARMul_UndefInstr (state, instr);
  720. return;
  721. }
  722. cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2);
  723. while (cpab == ARMul_BUSY) {
  724. ARMul_Icycles (state, 1, 0);
  725. if (IntPending (state)) {
  726. cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT,
  727. instr, 0, 0);
  728. return;
  729. } else
  730. cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr,
  731. source1, source2);
  732. }
  733. if (cpab == ARMul_CANT) {
  734. printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2);
  735. ARMul_Abort (state, ARMul_UndefinedInstrV);
  736. } else {
  737. BUSUSEDINCPCN;
  738. ARMul_Ccycles (state, 1, 0);
  739. }
  740. }
  741. /* This function does the Busy-Waiting for an MRC instruction. */
  742. ARMword ARMul_MRC (ARMul_State * state, ARMword instr)
  743. {
  744. int cm = BITS(0, 3) & 0xf;
  745. int cp = BITS(5, 7) & 0x7;
  746. int rd = BITS(12, 15) & 0xf;
  747. int cn = BITS(16, 19) & 0xf;
  748. int cpopc = BITS(21, 23) & 0x7;
  749. if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer
  750. ARMword result = Memory::KERNEL_MEMORY_VADDR;
  751. if (result != -1) {
  752. return result;
  753. }
  754. }
  755. //DEBUG("SKYEYE ARMul_MRC p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp);
  756. //DEBUG("plutoo: MRC not implemented\n");
  757. //return;
  758. unsigned cpab;
  759. ARMword result = 0;
  760. //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
  761. //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  762. if (!state->MRC[CPNum]) {
  763. //chy 2004-07-19 should fix in the future????!!!!
  764. LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x", CPNum, instr);
  765. ARMul_UndefInstr (state, instr);
  766. return -1;
  767. }
  768. cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
  769. while (cpab == ARMul_BUSY) {
  770. ARMul_Icycles (state, 1, 0);
  771. if (IntPending (state)) {
  772. cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
  773. instr, 0);
  774. return (0);
  775. } else
  776. cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
  777. &result);
  778. }
  779. if (cpab == ARMul_CANT) {
  780. printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
  781. ARMul_Abort (state, ARMul_UndefinedInstrV);
  782. /* Parent will destroy the flags otherwise. */
  783. result = ECC;
  784. } else {
  785. BUSUSEDINCPCN;
  786. ARMul_Ccycles (state, 1, 0);
  787. ARMul_Icycles (state, 1, 0);
  788. }
  789. return result;
  790. }
  791. /* This function does the Busy-Waiting for an MRRC instruction. (to verify) */
  792. void
  793. ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2)
  794. {
  795. unsigned cpab;
  796. ARMword result1 = 0;
  797. ARMword result2 = 0;
  798. //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  799. if (!state->MRRC[CPNum]) {
  800. ARMul_UndefInstr (state, instr);
  801. return;
  802. }
  803. cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2);
  804. while (cpab == ARMul_BUSY) {
  805. ARMul_Icycles (state, 1, 0);
  806. if (IntPending (state)) {
  807. cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT,
  808. instr, 0, 0);
  809. return;
  810. } else
  811. cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr,
  812. &result1, &result2);
  813. }
  814. if (cpab == ARMul_CANT) {
  815. printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr);
  816. ARMul_Abort (state, ARMul_UndefinedInstrV);
  817. } else {
  818. BUSUSEDINCPCN;
  819. ARMul_Ccycles (state, 1, 0);
  820. ARMul_Icycles (state, 1, 0);
  821. }
  822. *dest1 = result1;
  823. *dest2 = result2;
  824. }
  825. /* This function does the Busy-Waiting for an CDP instruction. */
  826. void
  827. ARMul_CDP (ARMul_State * state, ARMword instr)
  828. {
  829. unsigned cpab;
  830. //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
  831. if (!state->CDP[CPNum]) {
  832. ARMul_UndefInstr (state, instr);
  833. return;
  834. }
  835. cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
  836. while (cpab == ARMul_BUSY) {
  837. ARMul_Icycles (state, 1, 0);
  838. if (IntPending (state)) {
  839. cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT,
  840. instr);
  841. return;
  842. } else
  843. cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
  844. }
  845. if (cpab == ARMul_CANT)
  846. ARMul_Abort (state, ARMul_UndefinedInstrV);
  847. else
  848. BUSUSEDN;
  849. }
  850. /* This function handles Undefined instructions, as CP isntruction. */
  851. void
  852. ARMul_UndefInstr (ARMul_State * state, ARMword instr)
  853. {
  854. std::string disasm = ARM_Disasm::Disassemble(state->pc, instr);
  855. LOG_ERROR(Core_ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr);
  856. ARMul_Abort (state, ARMul_UndefinedInstrV);
  857. }
  858. /* Return TRUE if an interrupt is pending, FALSE otherwise. */
  859. unsigned
  860. IntPending (ARMul_State * state)
  861. {
  862. /* Any exceptions. */
  863. if (state->NresetSig == LOW) {
  864. ARMul_Abort (state, ARMul_ResetV);
  865. return TRUE;
  866. } else if (!state->NfiqSig && !FFLAG) {
  867. ARMul_Abort (state, ARMul_FIQV);
  868. return TRUE;
  869. } else if (!state->NirqSig && !IFLAG) {
  870. ARMul_Abort (state, ARMul_IRQV);
  871. return TRUE;
  872. }
  873. return FALSE;
  874. }
  875. /* Align a word access to a non word boundary. */
  876. ARMword
  877. ARMul_Align (ARMul_State* state, ARMword address, ARMword data)
  878. {
  879. /* This code assumes the address is really unaligned,
  880. as a shift by 32 is undefined in C. */
  881. address = (address & 3) << 3; /* Get the word address. */
  882. return ((data >> address) | (data << (32 - address))); /* rot right */
  883. }
  884. /* This routine is used to call another routine after a certain number of
  885. cycles have been executed. The first parameter is the number of cycles
  886. delay before the function is called, the second argument is a pointer
  887. to the function. A delay of zero doesn't work, just call the function. */
  888. void
  889. ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
  890. unsigned (*what) (ARMul_State *))
  891. {
  892. unsigned int when;
  893. struct EventNode *event;
  894. if (state->EventSet++ == 0)
  895. state->Now = ARMul_Time (state);
  896. when = (state->Now + delay) % EVENTLISTSIZE;
  897. event = (struct EventNode *) malloc (sizeof (struct EventNode));
  898. if (!event) {
  899. printf ("SKYEYE:ARMul_ScheduleEvent: malloc event error\n");
  900. exit(-1);
  901. //skyeye_exit (-1);
  902. }
  903. event->func = what;
  904. event->next = *(state->EventPtr + when);
  905. *(state->EventPtr + when) = event;
  906. }
  907. /* This routine is called at the beginning of
  908. every cycle, to envoke scheduled events. */
  909. void
  910. ARMul_EnvokeEvent (ARMul_State * state)
  911. {
  912. static unsigned int then;
  913. then = state->Now;
  914. state->Now = ARMul_Time (state) % EVENTLISTSIZE;
  915. if (then < state->Now)
  916. /* Schedule events. */
  917. EnvokeList (state, then, state->Now);
  918. else if (then > state->Now) {
  919. /* Need to wrap around the list. */
  920. EnvokeList (state, then, EVENTLISTSIZE - 1L);
  921. EnvokeList (state, 0L, state->Now);
  922. }
  923. }
  924. /* Envokes all the entries in a range. */
  925. static void
  926. EnvokeList (ARMul_State * state, unsigned int from, unsigned int to)
  927. {
  928. for (; from <= to; from++) {
  929. struct EventNode *anevent;
  930. anevent = *(state->EventPtr + from);
  931. while (anevent) {
  932. (anevent->func) (state);
  933. state->EventSet--;
  934. anevent = anevent->next;
  935. }
  936. *(state->EventPtr + from) = NULL;
  937. }
  938. }
  939. /* This routine is returns the number of clock ticks since the last reset. */
  940. unsigned int
  941. ARMul_Time (ARMul_State * state)
  942. {
  943. return (state->NumScycles + state->NumNcycles +
  944. state->NumIcycles + state->NumCcycles + state->NumFcycles);
  945. }