armsupp.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701
  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 3 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, see <http://www.gnu.org/licenses/>. */
  13. #include "armdefs.h"
  14. #include "armemu.h"
  15. #include "ansidecl.h"
  16. #include <math.h>
  17. /* Definitions for the support routines. */
  18. static ARMword ModeToBank (ARMword);
  19. static void EnvokeList (ARMul_State *, unsigned long, unsigned long);
  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] + isize;
  60. else
  61. return (state->Reg[15] + isize) & 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. {
  90. state->Reg[15] = value;
  91. ARMul_R15Altered (state);
  92. }
  93. FLUSHPIPE;
  94. }
  95. /* This routine returns the value of the CPSR. */
  96. ARMword
  97. ARMul_GetCPSR (ARMul_State * state)
  98. {
  99. return (CPSR | state->Cpsr);
  100. }
  101. /* This routine sets the value of the CPSR. */
  102. void
  103. ARMul_SetCPSR (ARMul_State * state, ARMword value)
  104. {
  105. state->Cpsr = value;
  106. ARMul_CPSRAltered (state);
  107. }
  108. /* This routine does all the nasty bits involved in a write to the CPSR,
  109. including updating the register bank, given a MSR instruction. */
  110. void
  111. ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
  112. {
  113. state->Cpsr = ARMul_GetCPSR (state);
  114. if (state->Mode != USER26MODE
  115. && state->Mode != USER32MODE)
  116. {
  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. {
  152. if (BIT (16))
  153. SETPSR_C (state->Spsr[state->Bank], rhs);
  154. if (BIT (17))
  155. SETPSR_X (state->Spsr[state->Bank], rhs);
  156. if (BIT (18))
  157. SETPSR_S (state->Spsr[state->Bank], rhs);
  158. if (BIT (19))
  159. SETPSR_F (state->Spsr[state->Bank], rhs);
  160. }
  161. }
  162. /* This routine updates the state of the emulator after the Cpsr has been
  163. changed. Both the processor flags and register bank are updated. */
  164. void
  165. ARMul_CPSRAltered (ARMul_State * state)
  166. {
  167. ARMword oldmode;
  168. if (state->prog32Sig == LOW)
  169. state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
  170. oldmode = state->Mode;
  171. if (state->Mode != (state->Cpsr & MODEBITS))
  172. {
  173. state->Mode =
  174. ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
  175. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  176. }
  177. state->Cpsr &= ~MODEBITS;
  178. ASSIGNINT (state->Cpsr & INTBITS);
  179. state->Cpsr &= ~INTBITS;
  180. ASSIGNN ((state->Cpsr & NBIT) != 0);
  181. state->Cpsr &= ~NBIT;
  182. ASSIGNZ ((state->Cpsr & ZBIT) != 0);
  183. state->Cpsr &= ~ZBIT;
  184. ASSIGNC ((state->Cpsr & CBIT) != 0);
  185. state->Cpsr &= ~CBIT;
  186. ASSIGNV ((state->Cpsr & VBIT) != 0);
  187. state->Cpsr &= ~VBIT;
  188. ASSIGNS ((state->Cpsr & SBIT) != 0);
  189. state->Cpsr &= ~SBIT;
  190. #ifdef MODET
  191. ASSIGNT ((state->Cpsr & TBIT) != 0);
  192. state->Cpsr &= ~TBIT;
  193. #endif
  194. if (oldmode > SVC26MODE)
  195. {
  196. if (state->Mode <= SVC26MODE)
  197. {
  198. state->Emulate = CHANGEMODE;
  199. state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
  200. }
  201. }
  202. else
  203. {
  204. if (state->Mode > SVC26MODE)
  205. {
  206. state->Emulate = CHANGEMODE;
  207. state->Reg[15] = R15PC;
  208. }
  209. else
  210. state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
  211. }
  212. }
  213. /* This routine updates the state of the emulator after register 15 has
  214. been changed. Both the processor flags and register bank are updated.
  215. This routine should only be called from a 26 bit mode. */
  216. void
  217. ARMul_R15Altered (ARMul_State * state)
  218. {
  219. if (state->Mode != R15MODE)
  220. {
  221. state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
  222. state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
  223. }
  224. if (state->Mode > SVC26MODE)
  225. state->Emulate = CHANGEMODE;
  226. ASSIGNR15INT (R15INT);
  227. ASSIGNN ((state->Reg[15] & NBIT) != 0);
  228. ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
  229. ASSIGNC ((state->Reg[15] & CBIT) != 0);
  230. ASSIGNV ((state->Reg[15] & VBIT) != 0);
  231. }
  232. /* This routine controls the saving and restoring of registers across mode
  233. changes. The regbank matrix is largely unused, only rows 13 and 14 are
  234. used across all modes, 8 to 14 are used for FIQ, all others use the USER
  235. column. It's easier this way. old and new parameter are modes numbers.
  236. Notice the side effect of changing the Bank variable. */
  237. ARMword
  238. ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
  239. {
  240. unsigned i;
  241. ARMword oldbank;
  242. ARMword newbank;
  243. oldbank = ModeToBank (oldmode);
  244. newbank = state->Bank = ModeToBank (newmode);
  245. /* Do we really need to do it? */
  246. if (oldbank != newbank)
  247. {
  248. /* Save away the old registers. */
  249. switch (oldbank)
  250. {
  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] = state->Reg[i];
  259. state->RegBank[oldbank][13] = state->Reg[13];
  260. state->RegBank[oldbank][14] = state->Reg[14];
  261. break;
  262. case FIQBANK:
  263. for (i = 8; i < 15; i++)
  264. state->RegBank[FIQBANK][i] = state->Reg[i];
  265. break;
  266. case DUMMYBANK:
  267. for (i = 8; i < 15; i++)
  268. state->RegBank[DUMMYBANK][i] = 0;
  269. break;
  270. default:
  271. abort ();
  272. }
  273. /* Restore the new registers. */
  274. switch (newbank)
  275. {
  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] = state->RegBank[USERBANK][i];
  284. state->Reg[13] = state->RegBank[newbank][13];
  285. state->Reg[14] = state->RegBank[newbank][14];
  286. break;
  287. case FIQBANK:
  288. for (i = 8; i < 15; i++)
  289. state->Reg[i] = state->RegBank[FIQBANK][i];
  290. break;
  291. case DUMMYBANK:
  292. for (i = 8; i < 15; i++)
  293. state->Reg[i] = 0;
  294. break;
  295. default:
  296. abort ();
  297. }
  298. }
  299. return newmode;
  300. }
  301. /* Given a processor mode, this routine returns the
  302. register bank that will be accessed in that mode. */
  303. static ARMword
  304. ModeToBank (ARMword mode)
  305. {
  306. static ARMword bankofmode[] =
  307. {
  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. /* Assigns the N and Z flags depending on the value of result. */
  332. void
  333. ARMul_NegZero (ARMul_State * state, ARMword result)
  334. {
  335. if (NEG (result))
  336. {
  337. SETN;
  338. CLEARZ;
  339. }
  340. else if (result == 0)
  341. {
  342. CLEARN;
  343. SETZ;
  344. }
  345. else
  346. {
  347. CLEARN;
  348. CLEARZ;
  349. }
  350. }
  351. /* Compute whether an addition of A and B, giving RESULT, overflowed. */
  352. int
  353. AddOverflow (ARMword a, ARMword b, ARMword result)
  354. {
  355. return ((NEG (a) && NEG (b) && POS (result))
  356. || (POS (a) && POS (b) && NEG (result)));
  357. }
  358. /* Compute whether a subtraction of A and B, giving RESULT, overflowed. */
  359. int
  360. 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. /* Assigns the C flag after an subtraction of a and b to give result. */
  379. void
  380. ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
  381. {
  382. ASSIGNC ((NEG (a) && POS (b)) ||
  383. (NEG (a) && POS (result)) || (POS (b) && POS (result)));
  384. }
  385. /* Assigns the V flag after an subtraction of a and b to give result. */
  386. void
  387. ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
  388. {
  389. ASSIGNV (SubOverflow (a, b, result));
  390. }
  391. static void
  392. handle_VFP_xfer (ARMul_State * state, ARMword instr)
  393. {
  394. if (TOPBITS (28) == NV)
  395. {
  396. fprintf (stderr, "SIM: UNDEFINED VFP instruction\n");
  397. return;
  398. }
  399. if (BITS (25, 27) != 0x6)
  400. {
  401. fprintf (stderr, "SIM: ISE: VFP handler called incorrectly\n");
  402. return;
  403. }
  404. switch (BITS (20, 24))
  405. {
  406. case 0x04:
  407. case 0x05:
  408. {
  409. /* VMOV double precision to/from two ARM registers. */
  410. int vm = BITS (0, 3);
  411. int rt1 = BITS (12, 15);
  412. int rt2 = BITS (16, 19);
  413. /* FIXME: UNPREDICTABLE if rt1 == 15 or rt2 == 15. */
  414. if (BIT (20))
  415. {
  416. /* Transfer to ARM. */
  417. /* FIXME: UPPREDICTABLE if rt1 == rt2. */
  418. state->Reg[rt1] = VFP_dword (vm) & 0xffffffff;
  419. state->Reg[rt2] = VFP_dword (vm) >> 32;
  420. }
  421. else
  422. {
  423. VFP_dword (vm) = state->Reg[rt2];
  424. VFP_dword (vm) <<= 32;
  425. VFP_dword (vm) |= (state->Reg[rt1] & 0xffffffff);
  426. }
  427. return;
  428. }
  429. case 0x08:
  430. case 0x0A:
  431. case 0x0C:
  432. case 0x0E:
  433. {
  434. /* VSTM with PUW=011 or PUW=010. */
  435. int n = BITS (16, 19);
  436. int imm8 = BITS (0, 7);
  437. ARMword address = state->Reg[n];
  438. if (BIT (21))
  439. state->Reg[n] = address + (imm8 << 2);
  440. if (BIT (8))
  441. {
  442. int src = (BIT (22) << 4) | BITS (12, 15);
  443. imm8 >>= 1;
  444. while (imm8--)
  445. {
  446. if (state->bigendSig)
  447. {
  448. ARMul_StoreWordN (state, address, VFP_dword (src) >> 32);
  449. ARMul_StoreWordN (state, address + 4, VFP_dword (src));
  450. }
  451. else
  452. {
  453. ARMul_StoreWordN (state, address, VFP_dword (src));
  454. ARMul_StoreWordN (state, address + 4, VFP_dword (src) >> 32);
  455. }
  456. address += 8;
  457. src += 1;
  458. }
  459. }
  460. else
  461. {
  462. int src = (BITS (12, 15) << 1) | BIT (22);
  463. while (imm8--)
  464. {
  465. ARMul_StoreWordN (state, address, VFP_uword (src));
  466. address += 4;
  467. src += 1;
  468. }
  469. }
  470. }
  471. return;
  472. case 0x10:
  473. case 0x14:
  474. case 0x18:
  475. case 0x1C:
  476. {
  477. /* VSTR */
  478. ARMword imm32 = BITS (0, 7) << 2;
  479. int base = state->Reg[LHSReg];
  480. ARMword address;
  481. int dest;
  482. if (LHSReg == 15)
  483. base = (base + 3) & ~3;
  484. address = base + (BIT (23) ? imm32 : - imm32);
  485. if (CPNum == 10)
  486. {
  487. dest = (DESTReg << 1) + BIT (22);
  488. ARMul_StoreWordN (state, address, VFP_uword (dest));
  489. }
  490. else
  491. {
  492. dest = (BIT (22) << 4) + DESTReg;
  493. if (state->bigendSig)
  494. {
  495. ARMul_StoreWordN (state, address, VFP_dword (dest) >> 32);
  496. ARMul_StoreWordN (state, address + 4, VFP_dword (dest));
  497. }
  498. else
  499. {
  500. ARMul_StoreWordN (state, address, VFP_dword (dest));
  501. ARMul_StoreWordN (state, address + 4, VFP_dword (dest) >> 32);
  502. }
  503. }
  504. }
  505. return;
  506. case 0x12:
  507. case 0x16:
  508. if (BITS (16, 19) == 13)
  509. {
  510. /* VPUSH */
  511. ARMword address = state->Reg[13] - (BITS (0, 7) << 2);
  512. state->Reg[13] = address;
  513. if (BIT (8))
  514. {
  515. int dreg = (BIT (22) << 4) | BITS (12, 15);
  516. int num = BITS (0, 7) >> 1;
  517. while (num--)
  518. {
  519. if (state->bigendSig)
  520. {
  521. ARMul_StoreWordN (state, address, VFP_dword (dreg) >> 32);
  522. ARMul_StoreWordN (state, address + 4, VFP_dword (dreg));
  523. }
  524. else
  525. {
  526. ARMul_StoreWordN (state, address, VFP_dword (dreg));
  527. ARMul_StoreWordN (state, address + 4, VFP_dword (dreg) >> 32);
  528. }
  529. address += 8;
  530. dreg += 1;
  531. }
  532. }
  533. else
  534. {
  535. int sreg = (BITS (12, 15) << 1) | BIT (22);
  536. int num = BITS (0, 7);
  537. while (num--)
  538. {
  539. ARMul_StoreWordN (state, address, VFP_uword (sreg));
  540. address += 4;
  541. sreg += 1;
  542. }
  543. }
  544. }
  545. else if (BITS (9, 11) != 0x5)
  546. break;
  547. else
  548. {
  549. /* VSTM PUW=101 */
  550. int n = BITS (16, 19);
  551. int imm8 = BITS (0, 7);
  552. ARMword address = state->Reg[n] - (imm8 << 2);
  553. state->Reg[n] = address;
  554. if (BIT (8))
  555. {
  556. int src = (BIT (22) << 4) | BITS (12, 15);
  557. imm8 >>= 1;
  558. while (imm8--)
  559. {
  560. if (state->bigendSig)
  561. {
  562. ARMul_StoreWordN (state, address, VFP_dword (src) >> 32);
  563. ARMul_StoreWordN (state, address + 4, VFP_dword (src));
  564. }
  565. else
  566. {
  567. ARMul_StoreWordN (state, address, VFP_dword (src));
  568. ARMul_StoreWordN (state, address + 4, VFP_dword (src) >> 32);
  569. }
  570. address += 8;
  571. src += 1;
  572. }
  573. }
  574. else
  575. {
  576. int src = (BITS (12, 15) << 1) | BIT (22);
  577. while (imm8--)
  578. {
  579. ARMul_StoreWordN (state, address, VFP_uword (src));
  580. address += 4;
  581. src += 1;
  582. }
  583. }
  584. }
  585. return;
  586. case 0x13:
  587. case 0x17:
  588. /* VLDM PUW=101 */
  589. case 0x09:
  590. case 0x0D:
  591. /* VLDM PUW=010 */
  592. {
  593. int n = BITS (16, 19);
  594. int imm8 = BITS (0, 7);
  595. ARMword address = state->Reg[n];
  596. if (BIT (23) == 0)
  597. address -= imm8 << 2;
  598. if (BIT (21))
  599. state->Reg[n] = BIT (23) ? address + (imm8 << 2) : address;
  600. if (BIT (8))
  601. {
  602. int dest = (BIT (22) << 4) | BITS (12, 15);
  603. imm8 >>= 1;
  604. while (imm8--)
  605. {
  606. if (state->bigendSig)
  607. {
  608. VFP_dword (dest) = ARMul_LoadWordN (state, address);
  609. VFP_dword (dest) <<= 32;
  610. VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
  611. }
  612. else
  613. {
  614. VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
  615. VFP_dword (dest) <<= 32;
  616. VFP_dword (dest) |= ARMul_LoadWordN (state, address);
  617. }
  618. if (trace)
  619. fprintf (stderr, " VFP: VLDM: D%d = %g\n", dest, VFP_dval (dest));
  620. address += 8;
  621. dest += 1;
  622. }
  623. }
  624. else
  625. {
  626. int dest = (BITS (12, 15) << 1) | BIT (22);
  627. while (imm8--)
  628. {
  629. VFP_uword (dest) = ARMul_LoadWordN (state, address);
  630. address += 4;
  631. dest += 1;
  632. }
  633. }
  634. }
  635. return;
  636. case 0x0B:
  637. case 0x0F:
  638. if (BITS (16, 19) == 13)
  639. {
  640. /* VPOP */
  641. ARMword address = state->Reg[13];
  642. state->Reg[13] = address + (BITS (0, 7) << 2);
  643. if (BIT (8))
  644. {
  645. int dest = (BIT (22) << 4) | BITS (12, 15);
  646. int num = BITS (0, 7) >> 1;
  647. while (num--)
  648. {
  649. if (state->bigendSig)
  650. {
  651. VFP_dword (dest) = ARMul_LoadWordN (state, address);
  652. VFP_dword (dest) <<= 32;
  653. VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
  654. }
  655. else
  656. {
  657. VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
  658. VFP_dword (dest) <<= 32;
  659. VFP_dword (dest) |= ARMul_LoadWordN (state, address);
  660. }
  661. if (trace)
  662. fprintf (stderr, " VFP: VPOP: D%d = %g\n", dest, VFP_dval (dest));
  663. address += 8;
  664. dest += 1;
  665. }
  666. }
  667. else
  668. {
  669. int sreg = (BITS (12, 15) << 1) | BIT (22);
  670. int num = BITS (0, 7);
  671. while (num--)
  672. {
  673. VFP_uword (sreg) = ARMul_LoadWordN (state, address);
  674. address += 4;
  675. sreg += 1;
  676. }
  677. }
  678. }
  679. else if (BITS (9, 11) != 0x5)
  680. break;
  681. else
  682. {
  683. /* VLDM PUW=011 */
  684. int n = BITS (16, 19);
  685. int imm8 = BITS (0, 7);
  686. ARMword address = state->Reg[n];
  687. state->Reg[n] += imm8 << 2;
  688. if (BIT (8))
  689. {
  690. int dest = (BIT (22) << 4) | BITS (12, 15);
  691. imm8 >>= 1;
  692. while (imm8--)
  693. {
  694. if (state->bigendSig)
  695. {
  696. VFP_dword (dest) = ARMul_LoadWordN (state, address);
  697. VFP_dword (dest) <<= 32;
  698. VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
  699. }
  700. else
  701. {
  702. VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
  703. VFP_dword (dest) <<= 32;
  704. VFP_dword (dest) |= ARMul_LoadWordN (state, address);
  705. }
  706. if (trace)
  707. fprintf (stderr, " VFP: VLDM: D%d = %g\n", dest, VFP_dval (dest));
  708. address += 8;
  709. dest += 1;
  710. }
  711. }
  712. else
  713. {
  714. int dest = (BITS (12, 15) << 1) | BIT (22);
  715. while (imm8--)
  716. {
  717. VFP_uword (dest) = ARMul_LoadWordN (state, address);
  718. address += 4;
  719. dest += 1;
  720. }
  721. }
  722. }
  723. return;
  724. case 0x11:
  725. case 0x15:
  726. case 0x19:
  727. case 0x1D:
  728. {
  729. /* VLDR */
  730. ARMword imm32 = BITS (0, 7) << 2;
  731. int base = state->Reg[LHSReg];
  732. ARMword address;
  733. int dest;
  734. if (LHSReg == 15)
  735. base = (base + 3) & ~3;
  736. address = base + (BIT (23) ? imm32 : - imm32);
  737. if (CPNum == 10)
  738. {
  739. dest = (DESTReg << 1) + BIT (22);
  740. VFP_uword (dest) = ARMul_LoadWordN (state, address);
  741. }
  742. else
  743. {
  744. dest = (BIT (22) << 4) + DESTReg;
  745. if (state->bigendSig)
  746. {
  747. VFP_dword (dest) = ARMul_LoadWordN (state, address);
  748. VFP_dword (dest) <<= 32;
  749. VFP_dword (dest) |= ARMul_LoadWordN (state, address + 4);
  750. }
  751. else
  752. {
  753. VFP_dword (dest) = ARMul_LoadWordN (state, address + 4);
  754. VFP_dword (dest) <<= 32;
  755. VFP_dword (dest) |= ARMul_LoadWordN (state, address);
  756. }
  757. if (trace)
  758. fprintf (stderr, " VFP: VLDR: D%d = %g\n", dest, VFP_dval (dest));
  759. }
  760. }
  761. return;
  762. }
  763. fprintf (stderr, "SIM: VFP: Unimplemented: %0x\n", BITS (20, 24));
  764. }
  765. /* This function does the work of generating the addresses used in an
  766. LDC instruction. The code here is always post-indexed, it's up to the
  767. caller to get the input address correct and to handle base register
  768. modification. It also handles the Busy-Waiting. */
  769. void
  770. ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
  771. {
  772. unsigned cpab;
  773. ARMword data;
  774. if (CPNum == 10 || CPNum == 11)
  775. {
  776. handle_VFP_xfer (state, instr);
  777. return;
  778. }
  779. UNDEF_LSCPCBaseWb;
  780. if (! CP_ACCESS_ALLOWED (state, CPNum))
  781. {
  782. ARMul_UndefInstr (state, instr);
  783. return;
  784. }
  785. if (ADDREXCEPT (address))
  786. INTERNALABORT (address);
  787. cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
  788. while (cpab == ARMul_BUSY)
  789. {
  790. ARMul_Icycles (state, 1, 0);
  791. if (IntPending (state))
  792. {
  793. cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
  794. return;
  795. }
  796. else
  797. cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0);
  798. }
  799. if (cpab == ARMul_CANT)
  800. {
  801. CPTAKEABORT;
  802. return;
  803. }
  804. cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
  805. data = ARMul_LoadWordN (state, address);
  806. BUSUSEDINCPCN;
  807. if (BIT (21))
  808. LSBase = state->Base;
  809. cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
  810. while (cpab == ARMul_INC)
  811. {
  812. address += 4;
  813. data = ARMul_LoadWordN (state, address);
  814. cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
  815. }
  816. if (state->abortSig || state->Aborted)
  817. TAKEABORT;
  818. }
  819. /* This function does the work of generating the addresses used in an
  820. STC instruction. The code here is always post-indexed, it's up to the
  821. caller to get the input address correct and to handle base register
  822. modification. It also handles the Busy-Waiting. */
  823. void
  824. ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
  825. {
  826. unsigned cpab;
  827. ARMword data;
  828. if (CPNum == 10 || CPNum == 11)
  829. {
  830. handle_VFP_xfer (state, instr);
  831. return;
  832. }
  833. UNDEF_LSCPCBaseWb;
  834. if (! CP_ACCESS_ALLOWED (state, CPNum))
  835. {
  836. ARMul_UndefInstr (state, instr);
  837. return;
  838. }
  839. if (ADDREXCEPT (address) || VECTORACCESS (address))
  840. INTERNALABORT (address);
  841. cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
  842. while (cpab == ARMul_BUSY)
  843. {
  844. ARMul_Icycles (state, 1, 0);
  845. if (IntPending (state))
  846. {
  847. cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
  848. return;
  849. }
  850. else
  851. cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data);
  852. }
  853. if (cpab == ARMul_CANT)
  854. {
  855. CPTAKEABORT;
  856. return;
  857. }
  858. #ifndef MODE32
  859. if (ADDREXCEPT (address) || VECTORACCESS (address))
  860. INTERNALABORT (address);
  861. #endif
  862. BUSUSEDINCPCN;
  863. if (BIT (21))
  864. LSBase = state->Base;
  865. cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
  866. ARMul_StoreWordN (state, address, data);
  867. while (cpab == ARMul_INC)
  868. {
  869. address += 4;
  870. cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
  871. ARMul_StoreWordN (state, address, data);
  872. }
  873. if (state->abortSig || state->Aborted)
  874. TAKEABORT;
  875. }
  876. /* This function does the Busy-Waiting for an MCR instruction. */
  877. void
  878. ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
  879. {
  880. unsigned cpab;
  881. if (! CP_ACCESS_ALLOWED (state, CPNum))
  882. {
  883. ARMul_UndefInstr (state, instr);
  884. return;
  885. }
  886. cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
  887. while (cpab == ARMul_BUSY)
  888. {
  889. ARMul_Icycles (state, 1, 0);
  890. if (IntPending (state))
  891. {
  892. cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
  893. return;
  894. }
  895. else
  896. cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);
  897. }
  898. if (cpab == ARMul_CANT)
  899. ARMul_Abort (state, ARMul_UndefinedInstrV);
  900. else
  901. {
  902. BUSUSEDINCPCN;
  903. ARMul_Ccycles (state, 1, 0);
  904. }
  905. }
  906. /* This function does the Busy-Waiting for an MRC instruction. */
  907. ARMword
  908. ARMul_MRC (ARMul_State * state, ARMword instr)
  909. {
  910. unsigned cpab;
  911. ARMword result = 0;
  912. if (! CP_ACCESS_ALLOWED (state, CPNum))
  913. {
  914. ARMul_UndefInstr (state, instr);
  915. return result;
  916. }
  917. cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
  918. while (cpab == ARMul_BUSY)
  919. {
  920. ARMul_Icycles (state, 1, 0);
  921. if (IntPending (state))
  922. {
  923. cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);
  924. return (0);
  925. }
  926. else
  927. cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result);
  928. }
  929. if (cpab == ARMul_CANT)
  930. {
  931. ARMul_Abort (state, ARMul_UndefinedInstrV);
  932. /* Parent will destroy the flags otherwise. */
  933. result = ECC;
  934. }
  935. else
  936. {
  937. BUSUSEDINCPCN;
  938. ARMul_Ccycles (state, 1, 0);
  939. ARMul_Icycles (state, 1, 0);
  940. }
  941. return result;
  942. }
  943. static void
  944. handle_VFP_op (ARMul_State * state, ARMword instr)
  945. {
  946. int dest;
  947. int srcN;
  948. int srcM;
  949. if (BITS (9, 11) != 0x5 || BIT (4) != 0)
  950. {
  951. fprintf (stderr, "SIM: VFP: Unimplemented: Float op: %08x\n", BITS (0,31));
  952. return;
  953. }
  954. if (BIT (8))
  955. {
  956. dest = BITS(12,15) + (BIT (22) << 4);
  957. srcN = LHSReg + (BIT (7) << 4);
  958. srcM = BITS (0,3) + (BIT (5) << 4);
  959. }
  960. else
  961. {
  962. dest = (BITS(12,15) << 1) + BIT (22);
  963. srcN = (LHSReg << 1) + BIT (7);
  964. srcM = (BITS (0,3) << 1) + BIT (5);
  965. }
  966. switch (BITS (20, 27))
  967. {
  968. case 0xE0:
  969. case 0xE4:
  970. /* VMLA VMLS */
  971. if (BIT (8))
  972. {
  973. ARMdval val = VFP_dval (srcN) * VFP_dval (srcM);
  974. if (BIT (6))
  975. {
  976. if (trace)
  977. fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n",
  978. VFP_dval (dest) - val,
  979. VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
  980. VFP_dval (dest) -= val;
  981. }
  982. else
  983. {
  984. if (trace)
  985. fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n",
  986. VFP_dval (dest) + val,
  987. VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
  988. VFP_dval (dest) += val;
  989. }
  990. }
  991. else
  992. {
  993. ARMfval val = VFP_fval (srcN) * VFP_fval (srcM);
  994. if (BIT (6))
  995. {
  996. if (trace)
  997. fprintf (stderr, " VFP: VMLS: %g = %g - %g * %g\n",
  998. VFP_fval (dest) - val,
  999. VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM));
  1000. VFP_fval (dest) -= val;
  1001. }
  1002. else
  1003. {
  1004. if (trace)
  1005. fprintf (stderr, " VFP: VMLA: %g = %g + %g * %g\n",
  1006. VFP_fval (dest) + val,
  1007. VFP_fval (dest), VFP_fval (srcN), VFP_fval (srcM));
  1008. VFP_fval (dest) += val;
  1009. }
  1010. }
  1011. return;
  1012. case 0xE1:
  1013. case 0xE5:
  1014. if (BIT (8))
  1015. {
  1016. ARMdval product = VFP_dval (srcN) * VFP_dval (srcM);
  1017. if (BIT (6))
  1018. {
  1019. /* VNMLA */
  1020. if (trace)
  1021. fprintf (stderr, " VFP: VNMLA: %g = -(%g + (%g * %g))\n",
  1022. -(VFP_dval (dest) + product),
  1023. VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
  1024. VFP_dval (dest) = -(product + VFP_dval (dest));
  1025. }
  1026. else
  1027. {
  1028. /* VNMLS */
  1029. if (trace)
  1030. fprintf (stderr, " VFP: VNMLS: %g = -(%g + (%g * %g))\n",
  1031. -(VFP_dval (dest) + product),
  1032. VFP_dval (dest), VFP_dval (srcN), VFP_dval (srcM));
  1033. VFP_dval (dest) = product - VFP_dval (dest);
  1034. }
  1035. }
  1036. else
  1037. {
  1038. ARMfval product = VFP_fval (srcN) * VFP_fval (srcM);
  1039. if (BIT (6))
  1040. /* VNMLA */
  1041. VFP_fval (dest) = -(product + VFP_fval (dest));
  1042. else
  1043. /* VNMLS */
  1044. VFP_fval (dest) = product - VFP_fval (dest);
  1045. }
  1046. return;
  1047. case 0xE2:
  1048. case 0xE6:
  1049. if (BIT (8))
  1050. {
  1051. ARMdval product = VFP_dval (srcN) * VFP_dval (srcM);
  1052. if (BIT (6))
  1053. {
  1054. if (trace)
  1055. fprintf (stderr, " VFP: VMUL: %g = %g * %g\n",
  1056. - product, VFP_dval (srcN), VFP_dval (srcM));
  1057. /* VNMUL */
  1058. VFP_dval (dest) = - product;
  1059. }
  1060. else
  1061. {
  1062. if (trace)
  1063. fprintf (stderr, " VFP: VMUL: %g = %g * %g\n",
  1064. product, VFP_dval (srcN), VFP_dval (srcM));
  1065. /* VMUL */
  1066. VFP_dval (dest) = product;
  1067. }
  1068. }
  1069. else
  1070. {
  1071. ARMfval product = VFP_fval (srcN) * VFP_fval (srcM);
  1072. if (BIT (6))
  1073. {
  1074. if (trace)
  1075. fprintf (stderr, " VFP: VNMUL: %g = %g * %g\n",
  1076. - product, VFP_fval (srcN), VFP_fval (srcM));
  1077. VFP_fval (dest) = - product;
  1078. }
  1079. else
  1080. {
  1081. if (trace)
  1082. fprintf (stderr, " VFP: VMUL: %g = %g * %g\n",
  1083. product, VFP_fval (srcN), VFP_fval (srcM));
  1084. VFP_fval (dest) = product;
  1085. }
  1086. }
  1087. return;
  1088. case 0xE3:
  1089. case 0xE7:
  1090. if (BIT (6) == 0)
  1091. {
  1092. /* VADD */
  1093. if (BIT(8))
  1094. {
  1095. if (trace)
  1096. fprintf (stderr, " VFP: VADD %g = %g + %g\n",
  1097. VFP_dval (srcN) + VFP_dval (srcM),
  1098. VFP_dval (srcN),
  1099. VFP_dval (srcM));
  1100. VFP_dval (dest) = VFP_dval (srcN) + VFP_dval (srcM);
  1101. }
  1102. else
  1103. VFP_fval (dest) = VFP_fval (srcN) + VFP_fval (srcM);
  1104. }
  1105. else
  1106. {
  1107. /* VSUB */
  1108. if (BIT(8))
  1109. {
  1110. if (trace)
  1111. fprintf (stderr, " VFP: VSUB %g = %g - %g\n",
  1112. VFP_dval (srcN) - VFP_dval (srcM),
  1113. VFP_dval (srcN),
  1114. VFP_dval (srcM));
  1115. VFP_dval (dest) = VFP_dval (srcN) - VFP_dval (srcM);
  1116. }
  1117. else
  1118. VFP_fval (dest) = VFP_fval (srcN) - VFP_fval (srcM);
  1119. }
  1120. return;
  1121. case 0xE8:
  1122. case 0xEC:
  1123. if (BIT (6) == 1)
  1124. break;
  1125. /* VDIV */
  1126. if (BIT (8))
  1127. {
  1128. ARMdval res = VFP_dval (srcN) / VFP_dval (srcM);
  1129. if (trace)
  1130. fprintf (stderr, " VFP: VDIV (64bit): %g = %g / %g\n",
  1131. res, VFP_dval (srcN), VFP_dval (srcM));
  1132. VFP_dval (dest) = res;
  1133. }
  1134. else
  1135. {
  1136. if (trace)
  1137. fprintf (stderr, " VFP: VDIV: %g = %g / %g\n",
  1138. VFP_fval (srcN) / VFP_fval (srcM),
  1139. VFP_fval (srcN), VFP_fval (srcM));
  1140. VFP_fval (dest) = VFP_fval (srcN) / VFP_fval (srcM);
  1141. }
  1142. return;
  1143. case 0xEB:
  1144. case 0xEF:
  1145. if (BIT (6) != 1)
  1146. break;
  1147. switch (BITS (16, 19))
  1148. {
  1149. case 0x0:
  1150. if (BIT (7) == 0)
  1151. {
  1152. if (BIT (8))
  1153. {
  1154. /* VMOV.F64 <Dd>, <Dm>. */
  1155. VFP_dval (dest) = VFP_dval (srcM);
  1156. if (trace)
  1157. fprintf (stderr, " VFP: VMOV d%d, d%d: %g\n", dest, srcM, VFP_dval (srcM));
  1158. }
  1159. else
  1160. {
  1161. /* VMOV.F32 <Sd>, <Sm>. */
  1162. VFP_fval (dest) = VFP_fval (srcM);
  1163. if (trace)
  1164. fprintf (stderr, " VFP: VMOV s%d, s%d: %g\n", dest, srcM, VFP_fval (srcM));
  1165. }
  1166. }
  1167. else
  1168. {
  1169. /* VABS */
  1170. if (BIT (8))
  1171. {
  1172. ARMdval src = VFP_dval (srcM);
  1173. VFP_dval (dest) = fabs (src);
  1174. if (trace)
  1175. fprintf (stderr, " VFP: VABS (%g) = %g\n", src, VFP_dval (dest));
  1176. }
  1177. else
  1178. {
  1179. ARMfval src = VFP_fval (srcM);
  1180. VFP_fval (dest) = fabsf (src);
  1181. if (trace)
  1182. fprintf (stderr, " VFP: VABS (%g) = %g\n", src, VFP_fval (dest));
  1183. }
  1184. }
  1185. return;
  1186. case 0x1:
  1187. if (BIT (7) == 0)
  1188. {
  1189. /* VNEG */
  1190. if (BIT (8))
  1191. VFP_dval (dest) = - VFP_dval (srcM);
  1192. else
  1193. VFP_fval (dest) = - VFP_fval (srcM);
  1194. }
  1195. else
  1196. {
  1197. /* VSQRT */
  1198. if (BIT (8))
  1199. {
  1200. if (trace)
  1201. fprintf (stderr, " VFP: %g = root(%g)\n",
  1202. sqrt (VFP_dval (srcM)), VFP_dval (srcM));
  1203. VFP_dval (dest) = sqrt (VFP_dval (srcM));
  1204. }
  1205. else
  1206. {
  1207. if (trace)
  1208. fprintf (stderr, " VFP: %g = root(%g)\n",
  1209. sqrtf (VFP_fval (srcM)), VFP_fval (srcM));
  1210. VFP_fval (dest) = sqrtf (VFP_fval (srcM));
  1211. }
  1212. }
  1213. return;
  1214. case 0x4:
  1215. case 0x5:
  1216. /* VCMP, VCMPE */
  1217. if (BIT(8))
  1218. {
  1219. ARMdval res = VFP_dval (dest);
  1220. if (BIT (16) == 0)
  1221. {
  1222. ARMdval src = VFP_dval (srcM);
  1223. if (isinf (res) && isinf (src))
  1224. {
  1225. if (res > 0.0 && src > 0.0)
  1226. res = 0.0;
  1227. else if (res < 0.0 && src < 0.0)
  1228. res = 0.0;
  1229. /* else leave res alone. */
  1230. }
  1231. else
  1232. res -= src;
  1233. }
  1234. /* FIXME: Add handling of signalling NaNs and the E bit. */
  1235. state->FPSCR &= 0x0FFFFFFF;
  1236. if (res < 0.0)
  1237. state->FPSCR |= NBIT;
  1238. else
  1239. state->FPSCR |= CBIT;
  1240. if (res == 0.0)
  1241. state->FPSCR |= ZBIT;
  1242. if (isnan (res))
  1243. state->FPSCR |= VBIT;
  1244. if (trace)
  1245. fprintf (stderr, " VFP: VCMP (64bit) %g vs %g res %g, flags: %c%c%c%c\n",
  1246. VFP_dval (dest), BIT (16) ? 0.0 : VFP_dval (srcM), res,
  1247. state->FPSCR & NBIT ? 'N' : '-',
  1248. state->FPSCR & ZBIT ? 'Z' : '-',
  1249. state->FPSCR & CBIT ? 'C' : '-',
  1250. state->FPSCR & VBIT ? 'V' : '-');
  1251. }
  1252. else
  1253. {
  1254. ARMfval res = VFP_fval (dest);
  1255. if (BIT (16) == 0)
  1256. {
  1257. ARMfval src = VFP_fval (srcM);
  1258. if (isinf (res) && isinf (src))
  1259. {
  1260. if (res > 0.0 && src > 0.0)
  1261. res = 0.0;
  1262. else if (res < 0.0 && src < 0.0)
  1263. res = 0.0;
  1264. /* else leave res alone. */
  1265. }
  1266. else
  1267. res -= src;
  1268. }
  1269. /* FIXME: Add handling of signalling NaNs and the E bit. */
  1270. state->FPSCR &= 0x0FFFFFFF;
  1271. if (res < 0.0)
  1272. state->FPSCR |= NBIT;
  1273. else
  1274. state->FPSCR |= CBIT;
  1275. if (res == 0.0)
  1276. state->FPSCR |= ZBIT;
  1277. if (isnan (res))
  1278. state->FPSCR |= VBIT;
  1279. if (trace)
  1280. fprintf (stderr, " VFP: VCMP (32bit) %g vs %g res %g, flags: %c%c%c%c\n",
  1281. VFP_fval (dest), BIT (16) ? 0.0 : VFP_fval (srcM), res,
  1282. state->FPSCR & NBIT ? 'N' : '-',
  1283. state->FPSCR & ZBIT ? 'Z' : '-',
  1284. state->FPSCR & CBIT ? 'C' : '-',
  1285. state->FPSCR & VBIT ? 'V' : '-');
  1286. }
  1287. return;
  1288. case 0x7:
  1289. if (BIT (8))
  1290. {
  1291. dest = (DESTReg << 1) + BIT (22);
  1292. VFP_fval (dest) = VFP_dval (srcM);
  1293. }
  1294. else
  1295. {
  1296. dest = DESTReg + (BIT (22) << 4);
  1297. VFP_dval (dest) = VFP_fval (srcM);
  1298. }
  1299. return;
  1300. case 0x8:
  1301. case 0xC:
  1302. case 0xD:
  1303. /* VCVT integer <-> FP */
  1304. if (BIT (18))
  1305. {
  1306. /* To integer. */
  1307. if (BIT (8))
  1308. {
  1309. dest = (BITS(12,15) << 1) + BIT (22);
  1310. if (BIT (16))
  1311. VFP_sword (dest) = VFP_dval (srcM);
  1312. else
  1313. VFP_uword (dest) = VFP_dval (srcM);
  1314. }
  1315. else
  1316. {
  1317. if (BIT (16))
  1318. VFP_sword (dest) = VFP_fval (srcM);
  1319. else
  1320. VFP_uword (dest) = VFP_fval (srcM);
  1321. }
  1322. }
  1323. else
  1324. {
  1325. /* From integer. */
  1326. if (BIT (8))
  1327. {
  1328. srcM = (BITS (0,3) << 1) + BIT (5);
  1329. if (BIT (7))
  1330. VFP_dval (dest) = VFP_sword (srcM);
  1331. else
  1332. VFP_dval (dest) = VFP_uword (srcM);
  1333. }
  1334. else
  1335. {
  1336. if (BIT (7))
  1337. VFP_fval (dest) = VFP_sword (srcM);
  1338. else
  1339. VFP_fval (dest) = VFP_uword (srcM);
  1340. }
  1341. }
  1342. return;
  1343. }
  1344. fprintf (stderr, "SIM: VFP: Unimplemented: Float op3: %03x\n", BITS (16,27));
  1345. return;
  1346. }
  1347. fprintf (stderr, "SIM: VFP: Unimplemented: Float op2: %02x\n", BITS (20, 27));
  1348. return;
  1349. }
  1350. /* This function does the Busy-Waiting for an CDP instruction. */
  1351. void
  1352. ARMul_CDP (ARMul_State * state, ARMword instr)
  1353. {
  1354. unsigned cpab;
  1355. if (CPNum == 10 || CPNum == 11)
  1356. {
  1357. handle_VFP_op (state, instr);
  1358. return;
  1359. }
  1360. if (! CP_ACCESS_ALLOWED (state, CPNum))
  1361. {
  1362. ARMul_UndefInstr (state, instr);
  1363. return;
  1364. }
  1365. cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
  1366. while (cpab == ARMul_BUSY)
  1367. {
  1368. ARMul_Icycles (state, 1, 0);
  1369. if (IntPending (state))
  1370. {
  1371. cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr);
  1372. return;
  1373. }
  1374. else
  1375. cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
  1376. }
  1377. if (cpab == ARMul_CANT)
  1378. ARMul_Abort (state, ARMul_UndefinedInstrV);
  1379. else
  1380. BUSUSEDN;
  1381. }
  1382. /* This function handles Undefined instructions, as CP isntruction. */
  1383. void
  1384. ARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED)
  1385. {
  1386. ARMul_Abort (state, ARMul_UndefinedInstrV);
  1387. }
  1388. /* Return TRUE if an interrupt is pending, FALSE otherwise. */
  1389. unsigned
  1390. IntPending (ARMul_State * state)
  1391. {
  1392. if (state->Exception)
  1393. {
  1394. /* Any exceptions. */
  1395. if (state->NresetSig == LOW)
  1396. {
  1397. ARMul_Abort (state, ARMul_ResetV);
  1398. return TRUE;
  1399. }
  1400. else if (!state->NfiqSig && !FFLAG)
  1401. {
  1402. ARMul_Abort (state, ARMul_FIQV);
  1403. return TRUE;
  1404. }
  1405. else if (!state->NirqSig && !IFLAG)
  1406. {
  1407. ARMul_Abort (state, ARMul_IRQV);
  1408. return TRUE;
  1409. }
  1410. }
  1411. return FALSE;
  1412. }
  1413. /* Align a word access to a non word boundary. */
  1414. ARMword
  1415. ARMul_Align (ARMul_State *state ATTRIBUTE_UNUSED, ARMword address, ARMword data)
  1416. {
  1417. /* This code assumes the address is really unaligned,
  1418. as a shift by 32 is undefined in C. */
  1419. address = (address & 3) << 3; /* Get the word address. */
  1420. return ((data >> address) | (data << (32 - address))); /* rot right */
  1421. }
  1422. /* This routine is used to call another routine after a certain number of
  1423. cycles have been executed. The first parameter is the number of cycles
  1424. delay before the function is called, the second argument is a pointer
  1425. to the function. A delay of zero doesn't work, just call the function. */
  1426. void
  1427. ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay,
  1428. unsigned (*what) (ARMul_State *))
  1429. {
  1430. unsigned long when;
  1431. struct EventNode *event;
  1432. if (state->EventSet++ == 0)
  1433. state->Now = ARMul_Time (state);
  1434. when = (state->Now + delay) % EVENTLISTSIZE;
  1435. event = (struct EventNode *) malloc (sizeof (struct EventNode));
  1436. event->func = what;
  1437. event->next = *(state->EventPtr + when);
  1438. *(state->EventPtr + when) = event;
  1439. }
  1440. /* This routine is called at the beginning of
  1441. every cycle, to envoke scheduled events. */
  1442. void
  1443. ARMul_EnvokeEvent (ARMul_State * state)
  1444. {
  1445. static unsigned long then;
  1446. then = state->Now;
  1447. state->Now = ARMul_Time (state) % EVENTLISTSIZE;
  1448. if (then < state->Now)
  1449. /* Schedule events. */
  1450. EnvokeList (state, then, state->Now);
  1451. else if (then > state->Now)
  1452. {
  1453. /* Need to wrap around the list. */
  1454. EnvokeList (state, then, EVENTLISTSIZE - 1L);
  1455. EnvokeList (state, 0L, state->Now);
  1456. }
  1457. }
  1458. /* Envokes all the entries in a range. */
  1459. static void
  1460. EnvokeList (ARMul_State * state, unsigned long from, unsigned long to)
  1461. {
  1462. for (; from <= to; from++)
  1463. {
  1464. struct EventNode *anevent;
  1465. anevent = *(state->EventPtr + from);
  1466. while (anevent)
  1467. {
  1468. (anevent->func) (state);
  1469. state->EventSet--;
  1470. anevent = anevent->next;
  1471. }
  1472. *(state->EventPtr + from) = NULL;
  1473. }
  1474. }
  1475. /* This routine is returns the number of clock ticks since the last reset. */
  1476. unsigned long
  1477. ARMul_Time (ARMul_State * state)
  1478. {
  1479. return (state->NumScycles + state->NumNcycles +
  1480. state->NumIcycles + state->NumCcycles + state->NumFcycles);
  1481. }