vfpinstr.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774
  1. // Copyright 2012 Michael Kang, 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. /* Notice: this file should not be compiled as is, and is meant to be
  5. included in other files only. */
  6. /* ----------------------------------------------------------------------- */
  7. /* CDP instructions */
  8. /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
  9. /* ----------------------------------------------------------------------- */
  10. /* VMLA */
  11. /* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */
  12. #ifdef VFP_INTERPRETER_STRUCT
  13. struct vmla_inst {
  14. unsigned int instr;
  15. unsigned int dp_operation;
  16. };
  17. #endif
  18. #ifdef VFP_INTERPRETER_TRANS
  19. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index)
  20. {
  21. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst));
  22. vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
  23. inst_base->cond = BITS(inst, 28, 31);
  24. inst_base->idx = index;
  25. inst_base->br = NON_BRANCH;
  26. inst_cream->dp_operation = BIT(inst, 8);
  27. inst_cream->instr = inst;
  28. return inst_base;
  29. }
  30. #endif
  31. #ifdef VFP_INTERPRETER_IMPL
  32. VMLA_INST:
  33. {
  34. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  35. CHECK_VFP_ENABLED;
  36. vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
  37. int ret;
  38. if (inst_cream->dp_operation)
  39. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  40. else
  41. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  42. CHECK_VFP_CDP_RET;
  43. }
  44. cpu->Reg[15] += cpu->GetInstructionSize();
  45. INC_PC(sizeof(vmla_inst));
  46. FETCH_INST;
  47. GOTO_NEXT_INST;
  48. }
  49. #endif
  50. /* ----------------------------------------------------------------------- */
  51. /* VNMLS */
  52. /* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */
  53. #ifdef VFP_INTERPRETER_STRUCT
  54. struct vmls_inst {
  55. unsigned int instr;
  56. unsigned int dp_operation;
  57. };
  58. #endif
  59. #ifdef VFP_INTERPRETER_TRANS
  60. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index)
  61. {
  62. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst));
  63. vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
  64. inst_base->cond = BITS(inst, 28, 31);
  65. inst_base->idx = index;
  66. inst_base->br = NON_BRANCH;
  67. inst_cream->dp_operation = BIT(inst, 8);
  68. inst_cream->instr = inst;
  69. return inst_base;
  70. }
  71. #endif
  72. #ifdef VFP_INTERPRETER_IMPL
  73. VMLS_INST:
  74. {
  75. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  76. CHECK_VFP_ENABLED;
  77. vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
  78. int ret;
  79. if (inst_cream->dp_operation)
  80. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  81. else
  82. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  83. CHECK_VFP_CDP_RET;
  84. }
  85. cpu->Reg[15] += cpu->GetInstructionSize();
  86. INC_PC(sizeof(vmls_inst));
  87. FETCH_INST;
  88. GOTO_NEXT_INST;
  89. }
  90. #endif
  91. /* ----------------------------------------------------------------------- */
  92. /* VNMLA */
  93. /* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */
  94. #ifdef VFP_INTERPRETER_STRUCT
  95. struct vnmla_inst {
  96. unsigned int instr;
  97. unsigned int dp_operation;
  98. };
  99. #endif
  100. #ifdef VFP_INTERPRETER_TRANS
  101. static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index)
  102. {
  103. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst));
  104. vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
  105. inst_base->cond = BITS(inst, 28, 31);
  106. inst_base->idx = index;
  107. inst_base->br = NON_BRANCH;
  108. inst_cream->dp_operation = BIT(inst, 8);
  109. inst_cream->instr = inst;
  110. return inst_base;
  111. }
  112. #endif
  113. #ifdef VFP_INTERPRETER_IMPL
  114. VNMLA_INST:
  115. {
  116. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  117. CHECK_VFP_ENABLED;
  118. vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
  119. int ret;
  120. if (inst_cream->dp_operation)
  121. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  122. else
  123. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  124. CHECK_VFP_CDP_RET;
  125. }
  126. cpu->Reg[15] += cpu->GetInstructionSize();
  127. INC_PC(sizeof(vnmla_inst));
  128. FETCH_INST;
  129. GOTO_NEXT_INST;
  130. }
  131. #endif
  132. /* ----------------------------------------------------------------------- */
  133. /* VNMLS */
  134. /* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */
  135. #ifdef VFP_INTERPRETER_STRUCT
  136. struct vnmls_inst {
  137. unsigned int instr;
  138. unsigned int dp_operation;
  139. };
  140. #endif
  141. #ifdef VFP_INTERPRETER_TRANS
  142. static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index)
  143. {
  144. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
  145. vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
  146. inst_base->cond = BITS(inst, 28, 31);
  147. inst_base->idx = index;
  148. inst_base->br = NON_BRANCH;
  149. inst_cream->dp_operation = BIT(inst, 8);
  150. inst_cream->instr = inst;
  151. return inst_base;
  152. }
  153. #endif
  154. #ifdef VFP_INTERPRETER_IMPL
  155. VNMLS_INST:
  156. {
  157. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  158. CHECK_VFP_ENABLED;
  159. vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
  160. int ret;
  161. if (inst_cream->dp_operation)
  162. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  163. else
  164. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  165. CHECK_VFP_CDP_RET;
  166. }
  167. cpu->Reg[15] += cpu->GetInstructionSize();
  168. INC_PC(sizeof(vnmls_inst));
  169. FETCH_INST;
  170. GOTO_NEXT_INST;
  171. }
  172. #endif
  173. /* ----------------------------------------------------------------------- */
  174. /* VNMUL */
  175. /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
  176. #ifdef VFP_INTERPRETER_STRUCT
  177. struct vnmul_inst {
  178. unsigned int instr;
  179. unsigned int dp_operation;
  180. };
  181. #endif
  182. #ifdef VFP_INTERPRETER_TRANS
  183. static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index)
  184. {
  185. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
  186. vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
  187. inst_base->cond = BITS(inst, 28, 31);
  188. inst_base->idx = index;
  189. inst_base->br = NON_BRANCH;
  190. inst_cream->dp_operation = BIT(inst, 8);
  191. inst_cream->instr = inst;
  192. return inst_base;
  193. }
  194. #endif
  195. #ifdef VFP_INTERPRETER_IMPL
  196. VNMUL_INST:
  197. {
  198. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  199. CHECK_VFP_ENABLED;
  200. vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
  201. int ret;
  202. if (inst_cream->dp_operation)
  203. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  204. else
  205. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  206. CHECK_VFP_CDP_RET;
  207. }
  208. cpu->Reg[15] += cpu->GetInstructionSize();
  209. INC_PC(sizeof(vnmul_inst));
  210. FETCH_INST;
  211. GOTO_NEXT_INST;
  212. }
  213. #endif
  214. /* ----------------------------------------------------------------------- */
  215. /* VMUL */
  216. /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
  217. #ifdef VFP_INTERPRETER_STRUCT
  218. struct vmul_inst {
  219. unsigned int instr;
  220. unsigned int dp_operation;
  221. };
  222. #endif
  223. #ifdef VFP_INTERPRETER_TRANS
  224. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index)
  225. {
  226. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
  227. vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
  228. inst_base->cond = BITS(inst, 28, 31);
  229. inst_base->idx = index;
  230. inst_base->br = NON_BRANCH;
  231. inst_cream->dp_operation = BIT(inst, 8);
  232. inst_cream->instr = inst;
  233. return inst_base;
  234. }
  235. #endif
  236. #ifdef VFP_INTERPRETER_IMPL
  237. VMUL_INST:
  238. {
  239. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  240. CHECK_VFP_ENABLED;
  241. vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
  242. int ret;
  243. if (inst_cream->dp_operation)
  244. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  245. else
  246. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  247. CHECK_VFP_CDP_RET;
  248. }
  249. cpu->Reg[15] += cpu->GetInstructionSize();
  250. INC_PC(sizeof(vmul_inst));
  251. FETCH_INST;
  252. GOTO_NEXT_INST;
  253. }
  254. #endif
  255. /* ----------------------------------------------------------------------- */
  256. /* VADD */
  257. /* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */
  258. #ifdef VFP_INTERPRETER_STRUCT
  259. struct vadd_inst {
  260. unsigned int instr;
  261. unsigned int dp_operation;
  262. };
  263. #endif
  264. #ifdef VFP_INTERPRETER_TRANS
  265. static ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index)
  266. {
  267. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
  268. vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
  269. inst_base->cond = BITS(inst, 28, 31);
  270. inst_base->idx = index;
  271. inst_base->br = NON_BRANCH;
  272. inst_cream->dp_operation = BIT(inst, 8);
  273. inst_cream->instr = inst;
  274. return inst_base;
  275. }
  276. #endif
  277. #ifdef VFP_INTERPRETER_IMPL
  278. VADD_INST:
  279. {
  280. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  281. CHECK_VFP_ENABLED;
  282. vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
  283. int ret;
  284. if (inst_cream->dp_operation)
  285. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  286. else
  287. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  288. CHECK_VFP_CDP_RET;
  289. }
  290. cpu->Reg[15] += cpu->GetInstructionSize();
  291. INC_PC(sizeof(vadd_inst));
  292. FETCH_INST;
  293. GOTO_NEXT_INST;
  294. }
  295. #endif
  296. /* ----------------------------------------------------------------------- */
  297. /* VSUB */
  298. /* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */
  299. #ifdef VFP_INTERPRETER_STRUCT
  300. struct vsub_inst {
  301. unsigned int instr;
  302. unsigned int dp_operation;
  303. };
  304. #endif
  305. #ifdef VFP_INTERPRETER_TRANS
  306. static ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index)
  307. {
  308. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst));
  309. vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
  310. inst_base->cond = BITS(inst, 28, 31);
  311. inst_base->idx = index;
  312. inst_base->br = NON_BRANCH;
  313. inst_cream->dp_operation = BIT(inst, 8);
  314. inst_cream->instr = inst;
  315. return inst_base;
  316. }
  317. #endif
  318. #ifdef VFP_INTERPRETER_IMPL
  319. VSUB_INST:
  320. {
  321. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  322. CHECK_VFP_ENABLED;
  323. vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
  324. int ret;
  325. if (inst_cream->dp_operation)
  326. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  327. else
  328. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  329. CHECK_VFP_CDP_RET;
  330. }
  331. cpu->Reg[15] += cpu->GetInstructionSize();
  332. INC_PC(sizeof(vsub_inst));
  333. FETCH_INST;
  334. GOTO_NEXT_INST;
  335. }
  336. #endif
  337. /* ----------------------------------------------------------------------- */
  338. /* VDIV */
  339. /* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */
  340. #ifdef VFP_INTERPRETER_STRUCT
  341. struct vdiv_inst {
  342. unsigned int instr;
  343. unsigned int dp_operation;
  344. };
  345. #endif
  346. #ifdef VFP_INTERPRETER_TRANS
  347. static ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index)
  348. {
  349. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst));
  350. vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
  351. inst_base->cond = BITS(inst, 28, 31);
  352. inst_base->idx = index;
  353. inst_base->br = NON_BRANCH;
  354. inst_cream->dp_operation = BIT(inst, 8);
  355. inst_cream->instr = inst;
  356. return inst_base;
  357. }
  358. #endif
  359. #ifdef VFP_INTERPRETER_IMPL
  360. VDIV_INST:
  361. {
  362. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  363. CHECK_VFP_ENABLED;
  364. vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
  365. int ret;
  366. if (inst_cream->dp_operation)
  367. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  368. else
  369. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  370. CHECK_VFP_CDP_RET;
  371. }
  372. cpu->Reg[15] += cpu->GetInstructionSize();
  373. INC_PC(sizeof(vdiv_inst));
  374. FETCH_INST;
  375. GOTO_NEXT_INST;
  376. }
  377. #endif
  378. /* ----------------------------------------------------------------------- */
  379. /* VMOVI move immediate */
  380. /* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */
  381. /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
  382. #ifdef VFP_INTERPRETER_STRUCT
  383. struct vmovi_inst {
  384. unsigned int single;
  385. unsigned int d;
  386. unsigned int imm;
  387. };
  388. #endif
  389. #ifdef VFP_INTERPRETER_TRANS
  390. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index)
  391. {
  392. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst));
  393. vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
  394. inst_base->cond = BITS(inst, 28, 31);
  395. inst_base->idx = index;
  396. inst_base->br = NON_BRANCH;
  397. inst_cream->single = BIT(inst, 8) == 0;
  398. inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
  399. unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3);
  400. if (inst_cream->single)
  401. inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19;
  402. else
  403. inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16;
  404. return inst_base;
  405. }
  406. #endif
  407. #ifdef VFP_INTERPRETER_IMPL
  408. VMOVI_INST:
  409. {
  410. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  411. CHECK_VFP_ENABLED;
  412. vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
  413. VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
  414. }
  415. cpu->Reg[15] += cpu->GetInstructionSize();
  416. INC_PC(sizeof(vmovi_inst));
  417. FETCH_INST;
  418. GOTO_NEXT_INST;
  419. }
  420. #endif
  421. /* ----------------------------------------------------------------------- */
  422. /* VMOVR move register */
  423. /* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */
  424. /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
  425. #ifdef VFP_INTERPRETER_STRUCT
  426. struct vmovr_inst {
  427. unsigned int single;
  428. unsigned int d;
  429. unsigned int m;
  430. };
  431. #endif
  432. #ifdef VFP_INTERPRETER_TRANS
  433. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
  434. {
  435. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
  436. vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
  437. inst_base->cond = BITS(inst, 28, 31);
  438. inst_base->idx = index;
  439. inst_base->br = NON_BRANCH;
  440. inst_cream->single = BIT(inst, 8) == 0;
  441. inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
  442. inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4);
  443. return inst_base;
  444. }
  445. #endif
  446. #ifdef VFP_INTERPRETER_IMPL
  447. VMOVR_INST:
  448. {
  449. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  450. CHECK_VFP_ENABLED;
  451. vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
  452. VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
  453. }
  454. cpu->Reg[15] += cpu->GetInstructionSize();
  455. INC_PC(sizeof(vmovr_inst));
  456. FETCH_INST;
  457. GOTO_NEXT_INST;
  458. }
  459. #endif
  460. /* ----------------------------------------------------------------------- */
  461. /* VABS */
  462. /* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */
  463. #ifdef VFP_INTERPRETER_STRUCT
  464. typedef struct _vabs_inst {
  465. unsigned int instr;
  466. unsigned int dp_operation;
  467. } vabs_inst;
  468. #endif
  469. #ifdef VFP_INTERPRETER_TRANS
  470. static ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
  471. {
  472. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
  473. vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
  474. inst_base->cond = BITS(inst, 28, 31);
  475. inst_base->idx = index;
  476. inst_base->br = NON_BRANCH;
  477. inst_cream->dp_operation = BIT(inst, 8);
  478. inst_cream->instr = inst;
  479. return inst_base;
  480. }
  481. #endif
  482. #ifdef VFP_INTERPRETER_IMPL
  483. VABS_INST:
  484. {
  485. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  486. CHECK_VFP_ENABLED;
  487. vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
  488. int ret;
  489. if (inst_cream->dp_operation)
  490. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  491. else
  492. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  493. CHECK_VFP_CDP_RET;
  494. }
  495. cpu->Reg[15] += cpu->GetInstructionSize();
  496. INC_PC(sizeof(vabs_inst));
  497. FETCH_INST;
  498. GOTO_NEXT_INST;
  499. }
  500. #endif
  501. /* ----------------------------------------------------------------------- */
  502. /* VNEG */
  503. /* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
  504. #ifdef VFP_INTERPRETER_STRUCT
  505. struct vneg_inst {
  506. unsigned int instr;
  507. unsigned int dp_operation;
  508. };
  509. #endif
  510. #ifdef VFP_INTERPRETER_TRANS
  511. static ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
  512. {
  513. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
  514. vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
  515. inst_base->cond = BITS(inst, 28, 31);
  516. inst_base->idx = index;
  517. inst_base->br = NON_BRANCH;
  518. inst_cream->dp_operation = BIT(inst, 8);
  519. inst_cream->instr = inst;
  520. return inst_base;
  521. }
  522. #endif
  523. #ifdef VFP_INTERPRETER_IMPL
  524. VNEG_INST:
  525. {
  526. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  527. CHECK_VFP_ENABLED;
  528. vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
  529. int ret;
  530. if (inst_cream->dp_operation)
  531. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  532. else
  533. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  534. CHECK_VFP_CDP_RET;
  535. }
  536. cpu->Reg[15] += cpu->GetInstructionSize();
  537. INC_PC(sizeof(vneg_inst));
  538. FETCH_INST;
  539. GOTO_NEXT_INST;
  540. }
  541. #endif
  542. /* ----------------------------------------------------------------------- */
  543. /* VSQRT */
  544. /* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
  545. #ifdef VFP_INTERPRETER_STRUCT
  546. struct vsqrt_inst {
  547. unsigned int instr;
  548. unsigned int dp_operation;
  549. };
  550. #endif
  551. #ifdef VFP_INTERPRETER_TRANS
  552. static ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index)
  553. {
  554. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst));
  555. vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
  556. inst_base->cond = BITS(inst, 28, 31);
  557. inst_base->idx = index;
  558. inst_base->br = NON_BRANCH;
  559. inst_cream->dp_operation = BIT(inst, 8);
  560. inst_cream->instr = inst;
  561. return inst_base;
  562. }
  563. #endif
  564. #ifdef VFP_INTERPRETER_IMPL
  565. VSQRT_INST:
  566. {
  567. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  568. CHECK_VFP_ENABLED;
  569. vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
  570. int ret;
  571. if (inst_cream->dp_operation)
  572. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  573. else
  574. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  575. CHECK_VFP_CDP_RET;
  576. }
  577. cpu->Reg[15] += cpu->GetInstructionSize();
  578. INC_PC(sizeof(vsqrt_inst));
  579. FETCH_INST;
  580. GOTO_NEXT_INST;
  581. }
  582. #endif
  583. /* ----------------------------------------------------------------------- */
  584. /* VCMP VCMPE */
  585. /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */
  586. #ifdef VFP_INTERPRETER_STRUCT
  587. struct vcmp_inst {
  588. unsigned int instr;
  589. unsigned int dp_operation;
  590. };
  591. #endif
  592. #ifdef VFP_INTERPRETER_TRANS
  593. static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index)
  594. {
  595. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst));
  596. vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
  597. inst_base->cond = BITS(inst, 28, 31);
  598. inst_base->idx = index;
  599. inst_base->br = NON_BRANCH;
  600. inst_cream->dp_operation = BIT(inst, 8);
  601. inst_cream->instr = inst;
  602. return inst_base;
  603. }
  604. #endif
  605. #ifdef VFP_INTERPRETER_IMPL
  606. VCMP_INST:
  607. {
  608. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  609. CHECK_VFP_ENABLED;
  610. vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
  611. int ret;
  612. if (inst_cream->dp_operation)
  613. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  614. else
  615. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  616. CHECK_VFP_CDP_RET;
  617. }
  618. cpu->Reg[15] += cpu->GetInstructionSize();
  619. INC_PC(sizeof(vcmp_inst));
  620. FETCH_INST;
  621. GOTO_NEXT_INST;
  622. }
  623. #endif
  624. /* ----------------------------------------------------------------------- */
  625. /* VCMP VCMPE */
  626. /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */
  627. #ifdef VFP_INTERPRETER_STRUCT
  628. struct vcmp2_inst {
  629. unsigned int instr;
  630. unsigned int dp_operation;
  631. };
  632. #endif
  633. #ifdef VFP_INTERPRETER_TRANS
  634. static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index)
  635. {
  636. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst));
  637. vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
  638. inst_base->cond = BITS(inst, 28, 31);
  639. inst_base->idx = index;
  640. inst_base->br = NON_BRANCH;
  641. inst_cream->dp_operation = BIT(inst, 8);
  642. inst_cream->instr = inst;
  643. return inst_base;
  644. }
  645. #endif
  646. #ifdef VFP_INTERPRETER_IMPL
  647. VCMP2_INST:
  648. {
  649. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  650. CHECK_VFP_ENABLED;
  651. vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
  652. int ret;
  653. if (inst_cream->dp_operation)
  654. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  655. else
  656. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  657. CHECK_VFP_CDP_RET;
  658. }
  659. cpu->Reg[15] += cpu->GetInstructionSize();
  660. INC_PC(sizeof(vcmp2_inst));
  661. FETCH_INST;
  662. GOTO_NEXT_INST;
  663. }
  664. #endif
  665. /* ----------------------------------------------------------------------- */
  666. /* VCVTBDS between double and single */
  667. /* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */
  668. #ifdef VFP_INTERPRETER_STRUCT
  669. struct vcvtbds_inst {
  670. unsigned int instr;
  671. unsigned int dp_operation;
  672. };
  673. #endif
  674. #ifdef VFP_INTERPRETER_TRANS
  675. static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index)
  676. {
  677. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst));
  678. vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
  679. inst_base->cond = BITS(inst, 28, 31);
  680. inst_base->idx = index;
  681. inst_base->br = NON_BRANCH;
  682. inst_cream->dp_operation = BIT(inst, 8);
  683. inst_cream->instr = inst;
  684. return inst_base;
  685. }
  686. #endif
  687. #ifdef VFP_INTERPRETER_IMPL
  688. VCVTBDS_INST:
  689. {
  690. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  691. CHECK_VFP_ENABLED;
  692. vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
  693. int ret;
  694. if (inst_cream->dp_operation)
  695. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  696. else
  697. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  698. CHECK_VFP_CDP_RET;
  699. }
  700. cpu->Reg[15] += cpu->GetInstructionSize();
  701. INC_PC(sizeof(vcvtbds_inst));
  702. FETCH_INST;
  703. GOTO_NEXT_INST;
  704. }
  705. #endif
  706. /* ----------------------------------------------------------------------- */
  707. /* VCVTBFF between floating point and fixed point */
  708. /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
  709. #ifdef VFP_INTERPRETER_STRUCT
  710. struct vcvtbff_inst {
  711. unsigned int instr;
  712. unsigned int dp_operation;
  713. };
  714. #endif
  715. #ifdef VFP_INTERPRETER_TRANS
  716. static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index)
  717. {
  718. VFP_DEBUG_UNTESTED(VCVTBFF);
  719. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst));
  720. vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
  721. inst_base->cond = BITS(inst, 28, 31);
  722. inst_base->idx = index;
  723. inst_base->br = NON_BRANCH;
  724. inst_cream->dp_operation = BIT(inst, 8);
  725. inst_cream->instr = inst;
  726. return inst_base;
  727. }
  728. #endif
  729. #ifdef VFP_INTERPRETER_IMPL
  730. VCVTBFF_INST:
  731. {
  732. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  733. CHECK_VFP_ENABLED;
  734. vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
  735. int ret;
  736. if (inst_cream->dp_operation)
  737. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  738. else
  739. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  740. CHECK_VFP_CDP_RET;
  741. }
  742. cpu->Reg[15] += cpu->GetInstructionSize();
  743. INC_PC(sizeof(vcvtbff_inst));
  744. FETCH_INST;
  745. GOTO_NEXT_INST;
  746. }
  747. #endif
  748. /* ----------------------------------------------------------------------- */
  749. /* VCVTBFI between floating point and integer */
  750. /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
  751. #ifdef VFP_INTERPRETER_STRUCT
  752. struct vcvtbfi_inst {
  753. unsigned int instr;
  754. unsigned int dp_operation;
  755. };
  756. #endif
  757. #ifdef VFP_INTERPRETER_TRANS
  758. static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index)
  759. {
  760. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst));
  761. vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
  762. inst_base->cond = BITS(inst, 28, 31);
  763. inst_base->idx = index;
  764. inst_base->br = NON_BRANCH;
  765. inst_cream->dp_operation = BIT(inst, 8);
  766. inst_cream->instr = inst;
  767. return inst_base;
  768. }
  769. #endif
  770. #ifdef VFP_INTERPRETER_IMPL
  771. VCVTBFI_INST:
  772. {
  773. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  774. CHECK_VFP_ENABLED;
  775. vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
  776. int ret;
  777. if (inst_cream->dp_operation)
  778. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  779. else
  780. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_FPSCR]);
  781. CHECK_VFP_CDP_RET;
  782. }
  783. cpu->Reg[15] += cpu->GetInstructionSize();
  784. INC_PC(sizeof(vcvtbfi_inst));
  785. FETCH_INST;
  786. GOTO_NEXT_INST;
  787. }
  788. #endif
  789. /* ----------------------------------------------------------------------- */
  790. /* MRC / MCR instructions */
  791. /* cond 1110 AAAL XXXX XXXX 101C XBB1 XXXX */
  792. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- */
  793. /* ----------------------------------------------------------------------- */
  794. /* VMOVBRS between register and single precision */
  795. /* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */
  796. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
  797. #ifdef VFP_INTERPRETER_STRUCT
  798. struct vmovbrs_inst {
  799. unsigned int to_arm;
  800. unsigned int t;
  801. unsigned int n;
  802. };
  803. #endif
  804. #ifdef VFP_INTERPRETER_TRANS
  805. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index)
  806. {
  807. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst));
  808. vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
  809. inst_base->cond = BITS(inst, 28, 31);
  810. inst_base->idx = index;
  811. inst_base->br = NON_BRANCH;
  812. inst_cream->to_arm = BIT(inst, 20) == 1;
  813. inst_cream->t = BITS(inst, 12, 15);
  814. inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1;
  815. return inst_base;
  816. }
  817. #endif
  818. #ifdef VFP_INTERPRETER_IMPL
  819. VMOVBRS_INST:
  820. {
  821. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  822. CHECK_VFP_ENABLED;
  823. vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
  824. VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
  825. }
  826. cpu->Reg[15] += cpu->GetInstructionSize();
  827. INC_PC(sizeof(vmovbrs_inst));
  828. FETCH_INST;
  829. GOTO_NEXT_INST;
  830. }
  831. #endif
  832. /* ----------------------------------------------------------------------- */
  833. /* VMSR */
  834. /* cond 1110 1110 reg- Rt-- 1010 0001 0000 */
  835. /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
  836. #ifdef VFP_INTERPRETER_STRUCT
  837. struct vmsr_inst {
  838. unsigned int reg;
  839. unsigned int Rt;
  840. };
  841. #endif
  842. #ifdef VFP_INTERPRETER_TRANS
  843. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
  844. {
  845. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst));
  846. vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
  847. inst_base->cond = BITS(inst, 28, 31);
  848. inst_base->idx = index;
  849. inst_base->br = NON_BRANCH;
  850. inst_cream->reg = BITS(inst, 16, 19);
  851. inst_cream->Rt = BITS(inst, 12, 15);
  852. return inst_base;
  853. }
  854. #endif
  855. #ifdef VFP_INTERPRETER_IMPL
  856. VMSR_INST:
  857. {
  858. if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
  859. /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled ,
  860. and in privileged mode */
  861. /* Exceptions must be checked, according to v7 ref manual */
  862. CHECK_VFP_ENABLED;
  863. vmsr_inst* const inst_cream = (vmsr_inst*)inst_base->component;
  864. unsigned int reg = inst_cream->reg;
  865. unsigned int rt = inst_cream->Rt;
  866. if (reg == 1)
  867. {
  868. cpu->VFP[VFP_FPSCR] = cpu->Reg[rt];
  869. }
  870. else if (cpu->InAPrivilegedMode())
  871. {
  872. if (reg == 8)
  873. cpu->VFP[VFP_FPEXC] = cpu->Reg[rt];
  874. else if (reg == 9)
  875. cpu->VFP[VFP_FPINST] = cpu->Reg[rt];
  876. else if (reg == 10)
  877. cpu->VFP[VFP_FPINST2] = cpu->Reg[rt];
  878. }
  879. }
  880. cpu->Reg[15] += cpu->GetInstructionSize();
  881. INC_PC(sizeof(vmsr_inst));
  882. FETCH_INST;
  883. GOTO_NEXT_INST;
  884. }
  885. #endif
  886. /* ----------------------------------------------------------------------- */
  887. /* VMOVBRC register to scalar */
  888. /* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */
  889. /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
  890. #ifdef VFP_INTERPRETER_STRUCT
  891. struct vmovbrc_inst {
  892. unsigned int esize;
  893. unsigned int index;
  894. unsigned int d;
  895. unsigned int t;
  896. };
  897. #endif
  898. #ifdef VFP_INTERPRETER_TRANS
  899. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
  900. {
  901. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst));
  902. vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
  903. inst_base->cond = BITS(inst, 28, 31);
  904. inst_base->idx = index;
  905. inst_base->br = NON_BRANCH;
  906. inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
  907. inst_cream->t = BITS(inst, 12, 15);
  908. /* VFP variant of instruction */
  909. inst_cream->esize = 32;
  910. inst_cream->index = BIT(inst, 21);
  911. return inst_base;
  912. }
  913. #endif
  914. #ifdef VFP_INTERPRETER_IMPL
  915. VMOVBRC_INST:
  916. {
  917. if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
  918. CHECK_VFP_ENABLED;
  919. vmovbrc_inst* const inst_cream = (vmovbrc_inst*)inst_base->component;
  920. cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t];
  921. }
  922. cpu->Reg[15] += cpu->GetInstructionSize();
  923. INC_PC(sizeof(vmovbrc_inst));
  924. FETCH_INST;
  925. GOTO_NEXT_INST;
  926. }
  927. #endif
  928. /* ----------------------------------------------------------------------- */
  929. /* VMRS */
  930. /* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */
  931. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
  932. #ifdef VFP_INTERPRETER_STRUCT
  933. struct vmrs_inst {
  934. unsigned int reg;
  935. unsigned int Rt;
  936. };
  937. #endif
  938. #ifdef VFP_INTERPRETER_TRANS
  939. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
  940. {
  941. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst));
  942. vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
  943. inst_base->cond = BITS(inst, 28, 31);
  944. inst_base->idx = index;
  945. inst_base->br = NON_BRANCH;
  946. inst_cream->reg = BITS(inst, 16, 19);
  947. inst_cream->Rt = BITS(inst, 12, 15);
  948. return inst_base;
  949. }
  950. #endif
  951. #ifdef VFP_INTERPRETER_IMPL
  952. VMRS_INST:
  953. {
  954. if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
  955. /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled,
  956. and in privileged mode */
  957. /* Exceptions must be checked, according to v7 ref manual */
  958. CHECK_VFP_ENABLED;
  959. vmrs_inst* const inst_cream = (vmrs_inst*)inst_base->component;
  960. unsigned int reg = inst_cream->reg;
  961. unsigned int rt = inst_cream->Rt;
  962. if (reg == 1) // FPSCR
  963. {
  964. if (rt != 15)
  965. {
  966. cpu->Reg[rt] = cpu->VFP[VFP_FPSCR];
  967. }
  968. else
  969. {
  970. cpu->NFlag = (cpu->VFP[VFP_FPSCR] >> 31) & 1;
  971. cpu->ZFlag = (cpu->VFP[VFP_FPSCR] >> 30) & 1;
  972. cpu->CFlag = (cpu->VFP[VFP_FPSCR] >> 29) & 1;
  973. cpu->VFlag = (cpu->VFP[VFP_FPSCR] >> 28) & 1;
  974. }
  975. }
  976. else if (reg == 0)
  977. {
  978. cpu->Reg[rt] = cpu->VFP[VFP_FPSID];
  979. }
  980. else if (reg == 6)
  981. {
  982. cpu->Reg[rt] = cpu->VFP[VFP_MVFR1];
  983. }
  984. else if (reg == 7)
  985. {
  986. cpu->Reg[rt] = cpu->VFP[VFP_MVFR0];
  987. }
  988. else if (cpu->InAPrivilegedMode())
  989. {
  990. if (reg == 8)
  991. cpu->Reg[rt] = cpu->VFP[VFP_FPEXC];
  992. else if (reg == 9)
  993. cpu->Reg[rt] = cpu->VFP[VFP_FPINST];
  994. else if (reg == 10)
  995. cpu->Reg[rt] = cpu->VFP[VFP_FPINST2];
  996. }
  997. }
  998. cpu->Reg[15] += cpu->GetInstructionSize();
  999. INC_PC(sizeof(vmrs_inst));
  1000. FETCH_INST;
  1001. GOTO_NEXT_INST;
  1002. }
  1003. #endif
  1004. /* ----------------------------------------------------------------------- */
  1005. /* VMOVBCR scalar to register */
  1006. /* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */
  1007. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */
  1008. #ifdef VFP_INTERPRETER_STRUCT
  1009. struct vmovbcr_inst {
  1010. unsigned int esize;
  1011. unsigned int index;
  1012. unsigned int d;
  1013. unsigned int t;
  1014. };
  1015. #endif
  1016. #ifdef VFP_INTERPRETER_TRANS
  1017. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
  1018. {
  1019. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst));
  1020. vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
  1021. inst_base->cond = BITS(inst, 28, 31);
  1022. inst_base->idx = index;
  1023. inst_base->br = NON_BRANCH;
  1024. inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
  1025. inst_cream->t = BITS(inst, 12, 15);
  1026. /* VFP variant of instruction */
  1027. inst_cream->esize = 32;
  1028. inst_cream->index = BIT(inst, 21);
  1029. return inst_base;
  1030. }
  1031. #endif
  1032. #ifdef VFP_INTERPRETER_IMPL
  1033. VMOVBCR_INST:
  1034. {
  1035. if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
  1036. CHECK_VFP_ENABLED;
  1037. vmovbcr_inst* const inst_cream = (vmovbcr_inst*) inst_base->component;
  1038. cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index];
  1039. }
  1040. cpu->Reg[15] += cpu->GetInstructionSize();
  1041. INC_PC(sizeof(vmovbcr_inst));
  1042. FETCH_INST;
  1043. GOTO_NEXT_INST;
  1044. }
  1045. #endif
  1046. /* ----------------------------------------------------------------------- */
  1047. /* MRRC / MCRR instructions */
  1048. /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
  1049. /* cond 1100 0100 Rt2- Rt-- copr opc1 CRm- MCRR */
  1050. /* ----------------------------------------------------------------------- */
  1051. /* VMOVBRRSS between 2 registers to 2 singles */
  1052. /* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */
  1053. /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
  1054. #ifdef VFP_INTERPRETER_STRUCT
  1055. struct vmovbrrss_inst {
  1056. unsigned int to_arm;
  1057. unsigned int t;
  1058. unsigned int t2;
  1059. unsigned int m;
  1060. };
  1061. #endif
  1062. #ifdef VFP_INTERPRETER_TRANS
  1063. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index)
  1064. {
  1065. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst));
  1066. vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
  1067. inst_base->cond = BITS(inst, 28, 31);
  1068. inst_base->idx = index;
  1069. inst_base->br = NON_BRANCH;
  1070. inst_cream->to_arm = BIT(inst, 20) == 1;
  1071. inst_cream->t = BITS(inst, 12, 15);
  1072. inst_cream->t2 = BITS(inst, 16, 19);
  1073. inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5);
  1074. return inst_base;
  1075. }
  1076. #endif
  1077. #ifdef VFP_INTERPRETER_IMPL
  1078. VMOVBRRSS_INST:
  1079. {
  1080. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1081. CHECK_VFP_ENABLED;
  1082. vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component;
  1083. VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
  1084. &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]);
  1085. }
  1086. cpu->Reg[15] += cpu->GetInstructionSize();
  1087. INC_PC(sizeof(vmovbrrss_inst));
  1088. FETCH_INST;
  1089. GOTO_NEXT_INST;
  1090. }
  1091. #endif
  1092. /* ----------------------------------------------------------------------- */
  1093. /* VMOVBRRD between 2 registers and 1 double */
  1094. /* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */
  1095. /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
  1096. #ifdef VFP_INTERPRETER_STRUCT
  1097. struct vmovbrrd_inst {
  1098. unsigned int to_arm;
  1099. unsigned int t;
  1100. unsigned int t2;
  1101. unsigned int m;
  1102. };
  1103. #endif
  1104. #ifdef VFP_INTERPRETER_TRANS
  1105. static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index)
  1106. {
  1107. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
  1108. vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
  1109. inst_base->cond = BITS(inst, 28, 31);
  1110. inst_base->idx = index;
  1111. inst_base->br = NON_BRANCH;
  1112. inst_cream->to_arm = BIT(inst, 20) == 1;
  1113. inst_cream->t = BITS(inst, 12, 15);
  1114. inst_cream->t2 = BITS(inst, 16, 19);
  1115. inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3);
  1116. return inst_base;
  1117. }
  1118. #endif
  1119. #ifdef VFP_INTERPRETER_IMPL
  1120. VMOVBRRD_INST:
  1121. {
  1122. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1123. CHECK_VFP_ENABLED;
  1124. vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
  1125. VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
  1126. &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
  1127. }
  1128. cpu->Reg[15] += cpu->GetInstructionSize();
  1129. INC_PC(sizeof(vmovbrrd_inst));
  1130. FETCH_INST;
  1131. GOTO_NEXT_INST;
  1132. }
  1133. #endif
  1134. /* ----------------------------------------------------------------------- */
  1135. /* LDC/STC between 2 registers and 1 double */
  1136. /* cond 110X XXX1 Rn-- CRd- copr imm- imm- LDC */
  1137. /* cond 110X XXX0 Rn-- CRd- copr imm8 imm8 STC */
  1138. /* ----------------------------------------------------------------------- */
  1139. /* VSTR */
  1140. /* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */
  1141. #ifdef VFP_INTERPRETER_STRUCT
  1142. struct vstr_inst {
  1143. unsigned int single;
  1144. unsigned int n;
  1145. unsigned int d;
  1146. unsigned int imm32;
  1147. unsigned int add;
  1148. };
  1149. #endif
  1150. #ifdef VFP_INTERPRETER_TRANS
  1151. static ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index)
  1152. {
  1153. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst));
  1154. vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
  1155. inst_base->cond = BITS(inst, 28, 31);
  1156. inst_base->idx = index;
  1157. inst_base->br = NON_BRANCH;
  1158. inst_cream->single = BIT(inst, 8) == 0;
  1159. inst_cream->add = BIT(inst, 23);
  1160. inst_cream->imm32 = BITS(inst, 0,7) << 2;
  1161. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  1162. inst_cream->n = BITS(inst, 16, 19);
  1163. return inst_base;
  1164. }
  1165. #endif
  1166. #ifdef VFP_INTERPRETER_IMPL
  1167. VSTR_INST:
  1168. {
  1169. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1170. CHECK_VFP_ENABLED;
  1171. vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
  1172. unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
  1173. addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
  1174. if (inst_cream->single)
  1175. {
  1176. cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d]);
  1177. }
  1178. else
  1179. {
  1180. const u32 word1 = cpu->ExtReg[inst_cream->d*2+0];
  1181. const u32 word2 = cpu->ExtReg[inst_cream->d*2+1];
  1182. if (cpu->InBigEndianMode()) {
  1183. cpu->WriteMemory32(addr + 0, word2);
  1184. cpu->WriteMemory32(addr + 4, word1);
  1185. } else {
  1186. cpu->WriteMemory32(addr + 0, word1);
  1187. cpu->WriteMemory32(addr + 4, word2);
  1188. }
  1189. }
  1190. }
  1191. cpu->Reg[15] += cpu->GetInstructionSize();
  1192. INC_PC(sizeof(vstr_inst));
  1193. FETCH_INST;
  1194. GOTO_NEXT_INST;
  1195. }
  1196. #endif
  1197. /* ----------------------------------------------------------------------- */
  1198. /* VPUSH */
  1199. /* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */
  1200. #ifdef VFP_INTERPRETER_STRUCT
  1201. struct vpush_inst {
  1202. unsigned int single;
  1203. unsigned int d;
  1204. unsigned int imm32;
  1205. unsigned int regs;
  1206. };
  1207. #endif
  1208. #ifdef VFP_INTERPRETER_TRANS
  1209. static ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index)
  1210. {
  1211. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
  1212. vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
  1213. inst_base->cond = BITS(inst, 28, 31);
  1214. inst_base->idx = index;
  1215. inst_base->br = NON_BRANCH;
  1216. inst_cream->single = BIT(inst, 8) == 0;
  1217. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  1218. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  1219. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  1220. return inst_base;
  1221. }
  1222. #endif
  1223. #ifdef VFP_INTERPRETER_IMPL
  1224. VPUSH_INST:
  1225. {
  1226. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1227. CHECK_VFP_ENABLED;
  1228. vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
  1229. addr = cpu->Reg[R13] - inst_cream->imm32;
  1230. for (unsigned int i = 0; i < inst_cream->regs; i++)
  1231. {
  1232. if (inst_cream->single)
  1233. {
  1234. cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
  1235. addr += 4;
  1236. }
  1237. else
  1238. {
  1239. const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
  1240. const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
  1241. if (cpu->InBigEndianMode()) {
  1242. cpu->WriteMemory32(addr + 0, word2);
  1243. cpu->WriteMemory32(addr + 4, word1);
  1244. } else {
  1245. cpu->WriteMemory32(addr + 0, word1);
  1246. cpu->WriteMemory32(addr + 4, word2);
  1247. }
  1248. addr += 8;
  1249. }
  1250. }
  1251. cpu->Reg[R13] -= inst_cream->imm32;
  1252. }
  1253. cpu->Reg[15] += cpu->GetInstructionSize();
  1254. INC_PC(sizeof(vpush_inst));
  1255. FETCH_INST;
  1256. GOTO_NEXT_INST;
  1257. }
  1258. #endif
  1259. /* ----------------------------------------------------------------------- */
  1260. /* VSTM */
  1261. /* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */
  1262. #ifdef VFP_INTERPRETER_STRUCT
  1263. struct vstm_inst {
  1264. unsigned int single;
  1265. unsigned int add;
  1266. unsigned int wback;
  1267. unsigned int d;
  1268. unsigned int n;
  1269. unsigned int imm32;
  1270. unsigned int regs;
  1271. };
  1272. #endif
  1273. #ifdef VFP_INTERPRETER_TRANS
  1274. static ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
  1275. {
  1276. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst));
  1277. vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
  1278. inst_base->cond = BITS(inst, 28, 31);
  1279. inst_base->idx = index;
  1280. inst_base->br = NON_BRANCH;
  1281. inst_cream->single = BIT(inst, 8) == 0;
  1282. inst_cream->add = BIT(inst, 23);
  1283. inst_cream->wback = BIT(inst, 21);
  1284. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  1285. inst_cream->n = BITS(inst, 16, 19);
  1286. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  1287. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  1288. return inst_base;
  1289. }
  1290. #endif
  1291. #ifdef VFP_INTERPRETER_IMPL
  1292. VSTM_INST: /* encoding 1 */
  1293. {
  1294. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1295. CHECK_VFP_ENABLED;
  1296. vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
  1297. addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
  1298. for (unsigned int i = 0; i < inst_cream->regs; i++)
  1299. {
  1300. if (inst_cream->single)
  1301. {
  1302. cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
  1303. addr += 4;
  1304. }
  1305. else
  1306. {
  1307. const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
  1308. const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
  1309. if (cpu->InBigEndianMode()) {
  1310. cpu->WriteMemory32(addr + 0, word2);
  1311. cpu->WriteMemory32(addr + 4, word1);
  1312. } else {
  1313. cpu->WriteMemory32(addr + 0, word1);
  1314. cpu->WriteMemory32(addr + 4, word2);
  1315. }
  1316. addr += 8;
  1317. }
  1318. }
  1319. if (inst_cream->wback){
  1320. cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
  1321. cpu->Reg[inst_cream->n] - inst_cream->imm32);
  1322. }
  1323. }
  1324. cpu->Reg[15] += 4;
  1325. INC_PC(sizeof(vstm_inst));
  1326. FETCH_INST;
  1327. GOTO_NEXT_INST;
  1328. }
  1329. #endif
  1330. /* ----------------------------------------------------------------------- */
  1331. /* VPOP */
  1332. /* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */
  1333. #ifdef VFP_INTERPRETER_STRUCT
  1334. struct vpop_inst {
  1335. unsigned int single;
  1336. unsigned int d;
  1337. unsigned int imm32;
  1338. unsigned int regs;
  1339. };
  1340. #endif
  1341. #ifdef VFP_INTERPRETER_TRANS
  1342. static ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index)
  1343. {
  1344. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst));
  1345. vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
  1346. inst_base->cond = BITS(inst, 28, 31);
  1347. inst_base->idx = index;
  1348. inst_base->br = NON_BRANCH;
  1349. inst_cream->single = BIT(inst, 8) == 0;
  1350. inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4));
  1351. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  1352. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  1353. return inst_base;
  1354. }
  1355. #endif
  1356. #ifdef VFP_INTERPRETER_IMPL
  1357. VPOP_INST:
  1358. {
  1359. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1360. CHECK_VFP_ENABLED;
  1361. vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
  1362. addr = cpu->Reg[R13];
  1363. for (unsigned int i = 0; i < inst_cream->regs; i++)
  1364. {
  1365. if (inst_cream->single)
  1366. {
  1367. cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
  1368. addr += 4;
  1369. }
  1370. else
  1371. {
  1372. const u32 word1 = cpu->ReadMemory32(addr + 0);
  1373. const u32 word2 = cpu->ReadMemory32(addr + 4);
  1374. if (cpu->InBigEndianMode()) {
  1375. cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
  1376. cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
  1377. } else {
  1378. cpu->ExtReg[(inst_cream->d+i)*2+0] = word1;
  1379. cpu->ExtReg[(inst_cream->d+i)*2+1] = word2;
  1380. }
  1381. addr += 8;
  1382. }
  1383. }
  1384. cpu->Reg[R13] += inst_cream->imm32;
  1385. }
  1386. cpu->Reg[15] += cpu->GetInstructionSize();
  1387. INC_PC(sizeof(vpop_inst));
  1388. FETCH_INST;
  1389. GOTO_NEXT_INST;
  1390. }
  1391. #endif
  1392. /* ----------------------------------------------------------------------- */
  1393. /* VLDR */
  1394. /* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */
  1395. #ifdef VFP_INTERPRETER_STRUCT
  1396. struct vldr_inst {
  1397. unsigned int single;
  1398. unsigned int n;
  1399. unsigned int d;
  1400. unsigned int imm32;
  1401. unsigned int add;
  1402. };
  1403. #endif
  1404. #ifdef VFP_INTERPRETER_TRANS
  1405. static ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index)
  1406. {
  1407. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst));
  1408. vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
  1409. inst_base->cond = BITS(inst, 28, 31);
  1410. inst_base->idx = index;
  1411. inst_base->br = NON_BRANCH;
  1412. inst_cream->single = BIT(inst, 8) == 0;
  1413. inst_cream->add = BIT(inst, 23);
  1414. inst_cream->imm32 = BITS(inst, 0,7) << 2;
  1415. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  1416. inst_cream->n = BITS(inst, 16, 19);
  1417. return inst_base;
  1418. }
  1419. #endif
  1420. #ifdef VFP_INTERPRETER_IMPL
  1421. VLDR_INST:
  1422. {
  1423. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1424. CHECK_VFP_ENABLED;
  1425. vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
  1426. unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
  1427. addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
  1428. if (inst_cream->single)
  1429. {
  1430. cpu->ExtReg[inst_cream->d] = cpu->ReadMemory32(addr);
  1431. }
  1432. else
  1433. {
  1434. const u32 word1 = cpu->ReadMemory32(addr + 0);
  1435. const u32 word2 = cpu->ReadMemory32(addr + 4);
  1436. if (cpu->InBigEndianMode()) {
  1437. cpu->ExtReg[inst_cream->d*2+0] = word2;
  1438. cpu->ExtReg[inst_cream->d*2+1] = word1;
  1439. } else {
  1440. cpu->ExtReg[inst_cream->d*2+0] = word1;
  1441. cpu->ExtReg[inst_cream->d*2+1] = word2;
  1442. }
  1443. }
  1444. }
  1445. cpu->Reg[15] += cpu->GetInstructionSize();
  1446. INC_PC(sizeof(vldr_inst));
  1447. FETCH_INST;
  1448. GOTO_NEXT_INST;
  1449. }
  1450. #endif
  1451. /* ----------------------------------------------------------------------- */
  1452. /* VLDM */
  1453. /* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */
  1454. #ifdef VFP_INTERPRETER_STRUCT
  1455. struct vldm_inst {
  1456. unsigned int single;
  1457. unsigned int add;
  1458. unsigned int wback;
  1459. unsigned int d;
  1460. unsigned int n;
  1461. unsigned int imm32;
  1462. unsigned int regs;
  1463. };
  1464. #endif
  1465. #ifdef VFP_INTERPRETER_TRANS
  1466. static ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
  1467. {
  1468. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst));
  1469. vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
  1470. inst_base->cond = BITS(inst, 28, 31);
  1471. inst_base->idx = index;
  1472. inst_base->br = NON_BRANCH;
  1473. inst_cream->single = BIT(inst, 8) == 0;
  1474. inst_cream->add = BIT(inst, 23);
  1475. inst_cream->wback = BIT(inst, 21);
  1476. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  1477. inst_cream->n = BITS(inst, 16, 19);
  1478. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  1479. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  1480. return inst_base;
  1481. }
  1482. #endif
  1483. #ifdef VFP_INTERPRETER_IMPL
  1484. VLDM_INST:
  1485. {
  1486. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1487. CHECK_VFP_ENABLED;
  1488. vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
  1489. addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
  1490. for (unsigned int i = 0; i < inst_cream->regs; i++)
  1491. {
  1492. if (inst_cream->single)
  1493. {
  1494. cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
  1495. addr += 4;
  1496. }
  1497. else
  1498. {
  1499. const u32 word1 = cpu->ReadMemory32(addr + 0);
  1500. const u32 word2 = cpu->ReadMemory32(addr + 4);
  1501. if (cpu->InBigEndianMode()) {
  1502. cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
  1503. cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
  1504. } else {
  1505. cpu->ExtReg[(inst_cream->d+i)*2+0] = word1;
  1506. cpu->ExtReg[(inst_cream->d+i)*2+1] = word2;
  1507. }
  1508. addr += 8;
  1509. }
  1510. }
  1511. if (inst_cream->wback){
  1512. cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
  1513. cpu->Reg[inst_cream->n] - inst_cream->imm32);
  1514. }
  1515. }
  1516. cpu->Reg[15] += cpu->GetInstructionSize();
  1517. INC_PC(sizeof(vldm_inst));
  1518. FETCH_INST;
  1519. GOTO_NEXT_INST;
  1520. }
  1521. #endif