vfpinstr.cpp 106 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854
  1. /*
  2. vfp/vfpinstr.c - ARM VFPv3 emulation unit - Individual instructions data
  3. Copyright (C) 2003 Skyeye Develop Group
  4. for help please send mail to <skyeye-developer@lists.gro.clinux.org>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. /* Notice: this file should not be compiled as is, and is meant to be
  18. included in other files only. */
  19. /* ----------------------------------------------------------------------- */
  20. /* CDP instructions */
  21. /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
  22. /* ----------------------------------------------------------------------- */
  23. /* VMLA */
  24. /* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */
  25. #ifdef VFP_INTERPRETER_STRUCT
  26. typedef struct _vmla_inst {
  27. unsigned int instr;
  28. unsigned int dp_operation;
  29. } vmla_inst;
  30. #endif
  31. #ifdef VFP_INTERPRETER_TRANS
  32. ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index)
  33. {
  34. VFP_DEBUG_TRANSLATE;
  35. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst));
  36. vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
  37. inst_base->cond = BITS(inst, 28, 31);
  38. inst_base->idx = index;
  39. inst_base->br = NON_BRANCH;
  40. inst_base->load_r15 = 0;
  41. inst_cream->dp_operation = BIT(inst, 8);
  42. inst_cream->instr = inst;
  43. return inst_base;
  44. }
  45. #endif
  46. #ifdef VFP_INTERPRETER_IMPL
  47. VMLA_INST:
  48. {
  49. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  50. CHECK_VFP_ENABLED;
  51. DBG("VMLA :\n");
  52. vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
  53. int ret;
  54. if (inst_cream->dp_operation)
  55. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  56. else
  57. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  58. CHECK_VFP_CDP_RET;
  59. }
  60. cpu->Reg[15] += GET_INST_SIZE(cpu);
  61. INC_PC(sizeof(vmla_inst));
  62. FETCH_INST;
  63. GOTO_NEXT_INST;
  64. }
  65. #endif
  66. #ifdef VFP_DYNCOM_TABLE
  67. DYNCOM_FILL_ACTION(vmla),
  68. #endif
  69. #ifdef VFP_DYNCOM_TAG
  70. int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  71. {
  72. int instr_size = INSTR_SIZE;
  73. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  74. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  75. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  76. return instr_size;
  77. }
  78. #endif
  79. #ifdef VFP_DYNCOM_TRANS
  80. int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  81. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  82. //arch_arm_undef(cpu, bb, instr);
  83. int m;
  84. int n;
  85. int d ;
  86. int add = (BIT(6) == 0);
  87. int s = BIT(8) == 0;
  88. Value *mm;
  89. Value *nn;
  90. Value *tmp;
  91. if(s){
  92. m = BIT(5) | BITS(0,3) << 1;
  93. n = BIT(7) | BITS(16,19) << 1;
  94. d = BIT(22) | BITS(12,15) << 1;
  95. mm = FR32(m);
  96. nn = FR32(n);
  97. tmp = FPMUL(nn,mm);
  98. if(!add)
  99. tmp = FPNEG32(tmp);
  100. mm = FR32(d);
  101. tmp = FPADD(mm,tmp);
  102. //LETS(d,tmp);
  103. LETFPS(d,tmp);
  104. }else {
  105. m = BITS(0,3) | BIT(5) << 4;
  106. n = BITS(16,19) | BIT(7) << 4;
  107. d = BIT(22) << 4 | BITS(12,15);
  108. //mm = SITOFP(32,RSPR(m));
  109. //LETS(d,tmp);
  110. mm = ZEXT64(IBITCAST32(FR32(2 * m)));
  111. nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
  112. tmp = OR(SHL(nn,CONST64(32)),mm);
  113. mm = FPBITCAST64(tmp);
  114. tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
  115. nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
  116. nn = OR(SHL(nn,CONST64(32)),tmp);
  117. nn = FPBITCAST64(nn);
  118. tmp = FPMUL(nn,mm);
  119. if(!add)
  120. tmp = FPNEG64(tmp);
  121. mm = ZEXT64(IBITCAST32(FR32(2 * d)));
  122. nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
  123. mm = OR(SHL(nn,CONST64(32)),mm);
  124. mm = FPBITCAST64(mm);
  125. tmp = FPADD(mm,tmp);
  126. mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
  127. nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
  128. LETFPS(2*d ,FPBITCAST32(nn));
  129. LETFPS(d*2 + 1 , FPBITCAST32(mm));
  130. }
  131. return No_exp;
  132. }
  133. #endif
  134. /* ----------------------------------------------------------------------- */
  135. /* VNMLS */
  136. /* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */
  137. #ifdef VFP_INTERPRETER_STRUCT
  138. typedef struct _vmls_inst {
  139. unsigned int instr;
  140. unsigned int dp_operation;
  141. } vmls_inst;
  142. #endif
  143. #ifdef VFP_INTERPRETER_TRANS
  144. ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index)
  145. {
  146. VFP_DEBUG_TRANSLATE;
  147. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst));
  148. vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
  149. inst_base->cond = BITS(inst, 28, 31);
  150. inst_base->idx = index;
  151. inst_base->br = NON_BRANCH;
  152. inst_base->load_r15 = 0;
  153. inst_cream->dp_operation = BIT(inst, 8);
  154. inst_cream->instr = inst;
  155. return inst_base;
  156. }
  157. #endif
  158. #ifdef VFP_INTERPRETER_IMPL
  159. VMLS_INST:
  160. {
  161. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  162. CHECK_VFP_ENABLED;
  163. DBG("VMLS :\n");
  164. vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
  165. int ret;
  166. if (inst_cream->dp_operation)
  167. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  168. else
  169. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  170. CHECK_VFP_CDP_RET;
  171. }
  172. cpu->Reg[15] += GET_INST_SIZE(cpu);
  173. INC_PC(sizeof(vmls_inst));
  174. FETCH_INST;
  175. GOTO_NEXT_INST;
  176. }
  177. #endif
  178. #ifdef VFP_DYNCOM_TABLE
  179. DYNCOM_FILL_ACTION(vmls),
  180. #endif
  181. #ifdef VFP_DYNCOM_TAG
  182. int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  183. {
  184. int instr_size = INSTR_SIZE;
  185. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  186. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  187. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  188. return instr_size;
  189. }
  190. #endif
  191. #ifdef VFP_DYNCOM_TRANS
  192. int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  193. DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__);
  194. //arch_arm_undef(cpu, bb, instr);
  195. int m;
  196. int n;
  197. int d ;
  198. int add = (BIT(6) == 0);
  199. int s = BIT(8) == 0;
  200. Value *mm;
  201. Value *nn;
  202. Value *tmp;
  203. if(s){
  204. m = BIT(5) | BITS(0,3) << 1;
  205. n = BIT(7) | BITS(16,19) << 1;
  206. d = BIT(22) | BITS(12,15) << 1;
  207. mm = FR32(m);
  208. nn = FR32(n);
  209. tmp = FPMUL(nn,mm);
  210. if(!add)
  211. tmp = FPNEG32(tmp);
  212. mm = FR32(d);
  213. tmp = FPADD(mm,tmp);
  214. //LETS(d,tmp);
  215. LETFPS(d,tmp);
  216. }else {
  217. m = BITS(0,3) | BIT(5) << 4;
  218. n = BITS(16,19) | BIT(7) << 4;
  219. d = BIT(22) << 4 | BITS(12,15);
  220. //mm = SITOFP(32,RSPR(m));
  221. //LETS(d,tmp);
  222. mm = ZEXT64(IBITCAST32(FR32(2 * m)));
  223. nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
  224. tmp = OR(SHL(nn,CONST64(32)),mm);
  225. mm = FPBITCAST64(tmp);
  226. tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
  227. nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
  228. nn = OR(SHL(nn,CONST64(32)),tmp);
  229. nn = FPBITCAST64(nn);
  230. tmp = FPMUL(nn,mm);
  231. if(!add)
  232. tmp = FPNEG64(tmp);
  233. mm = ZEXT64(IBITCAST32(FR32(2 * d)));
  234. nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
  235. mm = OR(SHL(nn,CONST64(32)),mm);
  236. mm = FPBITCAST64(mm);
  237. tmp = FPADD(mm,tmp);
  238. mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
  239. nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
  240. LETFPS(2*d ,FPBITCAST32(nn));
  241. LETFPS(d*2 + 1 , FPBITCAST32(mm));
  242. }
  243. return No_exp;
  244. }
  245. #endif
  246. /* ----------------------------------------------------------------------- */
  247. /* VNMLA */
  248. /* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */
  249. #ifdef VFP_INTERPRETER_STRUCT
  250. typedef struct _vnmla_inst {
  251. unsigned int instr;
  252. unsigned int dp_operation;
  253. } vnmla_inst;
  254. #endif
  255. #ifdef VFP_INTERPRETER_TRANS
  256. ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index)
  257. {
  258. VFP_DEBUG_TRANSLATE;
  259. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst));
  260. vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
  261. inst_base->cond = BITS(inst, 28, 31);
  262. inst_base->idx = index;
  263. inst_base->br = NON_BRANCH;
  264. inst_base->load_r15 = 0;
  265. inst_cream->dp_operation = BIT(inst, 8);
  266. inst_cream->instr = inst;
  267. return inst_base;
  268. }
  269. #endif
  270. #ifdef VFP_INTERPRETER_IMPL
  271. VNMLA_INST:
  272. {
  273. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  274. CHECK_VFP_ENABLED;
  275. DBG("VNMLA :\n");
  276. vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
  277. int ret;
  278. if (inst_cream->dp_operation)
  279. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  280. else
  281. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  282. CHECK_VFP_CDP_RET;
  283. }
  284. cpu->Reg[15] += GET_INST_SIZE(cpu);
  285. INC_PC(sizeof(vnmla_inst));
  286. FETCH_INST;
  287. GOTO_NEXT_INST;
  288. }
  289. #endif
  290. #ifdef VFP_DYNCOM_TABLE
  291. DYNCOM_FILL_ACTION(vnmla),
  292. DYNCOM_FILL_ACTION(vnmla),
  293. #endif
  294. #ifdef VFP_DYNCOM_TAG
  295. int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  296. {
  297. int instr_size = INSTR_SIZE;
  298. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  299. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  300. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  301. return instr_size;
  302. }
  303. #endif
  304. #ifdef VFP_DYNCOM_TRANS
  305. int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  306. DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__);
  307. //arch_arm_undef(cpu, bb, instr);
  308. int m;
  309. int n;
  310. int d ;
  311. int add = (BIT(6) == 0);
  312. int s = BIT(8) == 0;
  313. Value *mm;
  314. Value *nn;
  315. Value *tmp;
  316. if(s){
  317. m = BIT(5) | BITS(0,3) << 1;
  318. n = BIT(7) | BITS(16,19) << 1;
  319. d = BIT(22) | BITS(12,15) << 1;
  320. mm = FR32(m);
  321. nn = FR32(n);
  322. tmp = FPMUL(nn,mm);
  323. if(!add)
  324. tmp = FPNEG32(tmp);
  325. mm = FR32(d);
  326. tmp = FPADD(FPNEG32(mm),tmp);
  327. //LETS(d,tmp);
  328. LETFPS(d,tmp);
  329. }else {
  330. m = BITS(0,3) | BIT(5) << 4;
  331. n = BITS(16,19) | BIT(7) << 4;
  332. d = BIT(22) << 4 | BITS(12,15);
  333. //mm = SITOFP(32,RSPR(m));
  334. //LETS(d,tmp);
  335. mm = ZEXT64(IBITCAST32(FR32(2 * m)));
  336. nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
  337. tmp = OR(SHL(nn,CONST64(32)),mm);
  338. mm = FPBITCAST64(tmp);
  339. tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
  340. nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
  341. nn = OR(SHL(nn,CONST64(32)),tmp);
  342. nn = FPBITCAST64(nn);
  343. tmp = FPMUL(nn,mm);
  344. if(!add)
  345. tmp = FPNEG64(tmp);
  346. mm = ZEXT64(IBITCAST32(FR32(2 * d)));
  347. nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
  348. mm = OR(SHL(nn,CONST64(32)),mm);
  349. mm = FPBITCAST64(mm);
  350. tmp = FPADD(FPNEG64(mm),tmp);
  351. mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
  352. nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
  353. LETFPS(2*d ,FPBITCAST32(nn));
  354. LETFPS(d*2 + 1 , FPBITCAST32(mm));
  355. }
  356. return No_exp;
  357. }
  358. #endif
  359. /* ----------------------------------------------------------------------- */
  360. /* VNMLS */
  361. /* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */
  362. #ifdef VFP_INTERPRETER_STRUCT
  363. typedef struct _vnmls_inst {
  364. unsigned int instr;
  365. unsigned int dp_operation;
  366. } vnmls_inst;
  367. #endif
  368. #ifdef VFP_INTERPRETER_TRANS
  369. ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index)
  370. {
  371. VFP_DEBUG_TRANSLATE;
  372. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
  373. vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
  374. inst_base->cond = BITS(inst, 28, 31);
  375. inst_base->idx = index;
  376. inst_base->br = NON_BRANCH;
  377. inst_base->load_r15 = 0;
  378. inst_cream->dp_operation = BIT(inst, 8);
  379. inst_cream->instr = inst;
  380. return inst_base;
  381. }
  382. #endif
  383. #ifdef VFP_INTERPRETER_IMPL
  384. VNMLS_INST:
  385. {
  386. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  387. CHECK_VFP_ENABLED;
  388. DBG("VNMLS :\n");
  389. vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
  390. int ret;
  391. if (inst_cream->dp_operation)
  392. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  393. else
  394. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  395. CHECK_VFP_CDP_RET;
  396. }
  397. cpu->Reg[15] += GET_INST_SIZE(cpu);
  398. INC_PC(sizeof(vnmls_inst));
  399. FETCH_INST;
  400. GOTO_NEXT_INST;
  401. }
  402. #endif
  403. #ifdef VFP_DYNCOM_TABLE
  404. DYNCOM_FILL_ACTION(vnmls),
  405. #endif
  406. #ifdef VFP_DYNCOM_TAG
  407. int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  408. {
  409. int instr_size = INSTR_SIZE;
  410. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  411. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  412. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  413. return instr_size;
  414. }
  415. #endif
  416. #ifdef VFP_DYNCOM_TRANS
  417. int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  418. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  419. //arch_arm_undef(cpu, bb, instr);
  420. int m;
  421. int n;
  422. int d ;
  423. int add = (BIT(6) == 0);
  424. int s = BIT(8) == 0;
  425. Value *mm;
  426. Value *nn;
  427. Value *tmp;
  428. if(s){
  429. m = BIT(5) | BITS(0,3) << 1;
  430. n = BIT(7) | BITS(16,19) << 1;
  431. d = BIT(22) | BITS(12,15) << 1;
  432. mm = FR32(m);
  433. nn = FR32(n);
  434. tmp = FPMUL(nn,mm);
  435. if(!add)
  436. tmp = FPNEG32(tmp);
  437. mm = FR32(d);
  438. tmp = FPADD(FPNEG32(mm),tmp);
  439. //LETS(d,tmp);
  440. LETFPS(d,tmp);
  441. }else {
  442. m = BITS(0,3) | BIT(5) << 4;
  443. n = BITS(16,19) | BIT(7) << 4;
  444. d = BIT(22) << 4 | BITS(12,15);
  445. //mm = SITOFP(32,RSPR(m));
  446. //LETS(d,tmp);
  447. mm = ZEXT64(IBITCAST32(FR32(2 * m)));
  448. nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
  449. tmp = OR(SHL(nn,CONST64(32)),mm);
  450. mm = FPBITCAST64(tmp);
  451. tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
  452. nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
  453. nn = OR(SHL(nn,CONST64(32)),tmp);
  454. nn = FPBITCAST64(nn);
  455. tmp = FPMUL(nn,mm);
  456. if(!add)
  457. tmp = FPNEG64(tmp);
  458. mm = ZEXT64(IBITCAST32(FR32(2 * d)));
  459. nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
  460. mm = OR(SHL(nn,CONST64(32)),mm);
  461. mm = FPBITCAST64(mm);
  462. tmp = FPADD(FPNEG64(mm),tmp);
  463. mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
  464. nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
  465. LETFPS(2*d ,FPBITCAST32(nn));
  466. LETFPS(d*2 + 1 , FPBITCAST32(mm));
  467. }
  468. return No_exp;
  469. }
  470. #endif
  471. /* ----------------------------------------------------------------------- */
  472. /* VNMUL */
  473. /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
  474. #ifdef VFP_INTERPRETER_STRUCT
  475. typedef struct _vnmul_inst {
  476. unsigned int instr;
  477. unsigned int dp_operation;
  478. } vnmul_inst;
  479. #endif
  480. #ifdef VFP_INTERPRETER_TRANS
  481. ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index)
  482. {
  483. VFP_DEBUG_TRANSLATE;
  484. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
  485. vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
  486. inst_base->cond = BITS(inst, 28, 31);
  487. inst_base->idx = index;
  488. inst_base->br = NON_BRANCH;
  489. inst_base->load_r15 = 0;
  490. inst_cream->dp_operation = BIT(inst, 8);
  491. inst_cream->instr = inst;
  492. return inst_base;
  493. }
  494. #endif
  495. #ifdef VFP_INTERPRETER_IMPL
  496. VNMUL_INST:
  497. {
  498. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  499. CHECK_VFP_ENABLED;
  500. DBG("VNMUL :\n");
  501. vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
  502. int ret;
  503. if (inst_cream->dp_operation)
  504. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  505. else
  506. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  507. CHECK_VFP_CDP_RET;
  508. }
  509. cpu->Reg[15] += GET_INST_SIZE(cpu);
  510. INC_PC(sizeof(vnmul_inst));
  511. FETCH_INST;
  512. GOTO_NEXT_INST;
  513. }
  514. #endif
  515. #ifdef VFP_DYNCOM_TABLE
  516. DYNCOM_FILL_ACTION(vnmul),
  517. #endif
  518. #ifdef VFP_DYNCOM_TAG
  519. int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  520. {
  521. int instr_size = INSTR_SIZE;
  522. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  523. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  524. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  525. return instr_size;
  526. }
  527. #endif
  528. #ifdef VFP_DYNCOM_TRANS
  529. int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  530. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  531. //arch_arm_undef(cpu, bb, instr);
  532. int m;
  533. int n;
  534. int d ;
  535. int add = (BIT(6) == 0);
  536. int s = BIT(8) == 0;
  537. Value *mm;
  538. Value *nn;
  539. Value *tmp;
  540. if(s){
  541. m = BIT(5) | BITS(0,3) << 1;
  542. n = BIT(7) | BITS(16,19) << 1;
  543. d = BIT(22) | BITS(12,15) << 1;
  544. mm = FR32(m);
  545. nn = FR32(n);
  546. tmp = FPMUL(nn,mm);
  547. //LETS(d,tmp);
  548. LETFPS(d,FPNEG32(tmp));
  549. }else {
  550. m = BITS(0,3) | BIT(5) << 4;
  551. n = BITS(16,19) | BIT(7) << 4;
  552. d = BIT(22) << 4 | BITS(12,15);
  553. //mm = SITOFP(32,RSPR(m));
  554. //LETS(d,tmp);
  555. mm = ZEXT64(IBITCAST32(FR32(2 * m)));
  556. nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
  557. tmp = OR(SHL(nn,CONST64(32)),mm);
  558. mm = FPBITCAST64(tmp);
  559. tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
  560. nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
  561. nn = OR(SHL(nn,CONST64(32)),tmp);
  562. nn = FPBITCAST64(nn);
  563. tmp = FPMUL(nn,mm);
  564. tmp = FPNEG64(tmp);
  565. mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
  566. nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
  567. LETFPS(2*d ,FPBITCAST32(nn));
  568. LETFPS(d*2 + 1 , FPBITCAST32(mm));
  569. }
  570. return No_exp;
  571. }
  572. #endif
  573. /* ----------------------------------------------------------------------- */
  574. /* VMUL */
  575. /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
  576. #ifdef VFP_INTERPRETER_STRUCT
  577. typedef struct _vmul_inst {
  578. unsigned int instr;
  579. unsigned int dp_operation;
  580. } vmul_inst;
  581. #endif
  582. #ifdef VFP_INTERPRETER_TRANS
  583. ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index)
  584. {
  585. VFP_DEBUG_TRANSLATE;
  586. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
  587. vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
  588. inst_base->cond = BITS(inst, 28, 31);
  589. inst_base->idx = index;
  590. inst_base->br = NON_BRANCH;
  591. inst_base->load_r15 = 0;
  592. inst_cream->dp_operation = BIT(inst, 8);
  593. inst_cream->instr = inst;
  594. return inst_base;
  595. }
  596. #endif
  597. #ifdef VFP_INTERPRETER_IMPL
  598. VMUL_INST:
  599. {
  600. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  601. CHECK_VFP_ENABLED;
  602. DBG("VMUL :\n");
  603. vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
  604. int ret;
  605. if (inst_cream->dp_operation)
  606. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  607. else
  608. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  609. CHECK_VFP_CDP_RET;
  610. }
  611. cpu->Reg[15] += GET_INST_SIZE(cpu);
  612. INC_PC(sizeof(vmul_inst));
  613. FETCH_INST;
  614. GOTO_NEXT_INST;
  615. }
  616. #endif
  617. #ifdef VFP_DYNCOM_TABLE
  618. DYNCOM_FILL_ACTION(vmul),
  619. #endif
  620. #ifdef VFP_DYNCOM_TAG
  621. int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  622. {
  623. int instr_size = INSTR_SIZE;
  624. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  625. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  626. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  627. return instr_size;
  628. }
  629. #endif
  630. #ifdef VFP_DYNCOM_TRANS
  631. int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  632. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  633. //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__);
  634. //arch_arm_undef(cpu, bb, instr);
  635. int m;
  636. int n;
  637. int d ;
  638. int s = BIT(8) == 0;
  639. Value *mm;
  640. Value *nn;
  641. Value *tmp;
  642. if(s){
  643. m = BIT(5) | BITS(0,3) << 1;
  644. n = BIT(7) | BITS(16,19) << 1;
  645. d = BIT(22) | BITS(12,15) << 1;
  646. //mm = SITOFP(32,FR(m));
  647. //nn = SITOFP(32,FRn));
  648. mm = FR32(m);
  649. nn = FR32(n);
  650. tmp = FPMUL(nn,mm);
  651. //LETS(d,tmp);
  652. LETFPS(d,tmp);
  653. }else {
  654. m = BITS(0,3) | BIT(5) << 4;
  655. n = BITS(16,19) | BIT(7) << 4;
  656. d = BIT(22) << 4 | BITS(12,15);
  657. //mm = SITOFP(32,RSPR(m));
  658. //LETS(d,tmp);
  659. Value *lo = FR32(2 * m);
  660. Value *hi = FR32(2 * m + 1);
  661. hi = IBITCAST32(hi);
  662. lo = IBITCAST32(lo);
  663. Value *hi64 = ZEXT64(hi);
  664. Value* lo64 = ZEXT64(lo);
  665. Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
  666. Value* m0 = FPBITCAST64(v64);
  667. lo = FR32(2 * n);
  668. hi = FR32(2 * n + 1);
  669. hi = IBITCAST32(hi);
  670. lo = IBITCAST32(lo);
  671. hi64 = ZEXT64(hi);
  672. lo64 = ZEXT64(lo);
  673. v64 = OR(SHL(hi64,CONST64(32)),lo64);
  674. Value *n0 = FPBITCAST64(v64);
  675. tmp = FPMUL(n0,m0);
  676. Value *val64 = IBITCAST64(tmp);
  677. hi = LSHR(val64,CONST64(32));
  678. lo = AND(val64,CONST64(0xffffffff));
  679. hi = TRUNC32(hi);
  680. lo = TRUNC32(lo);
  681. hi = FPBITCAST32(hi);
  682. lo = FPBITCAST32(lo);
  683. LETFPS(2*d ,lo);
  684. LETFPS(d*2 + 1 , hi);
  685. }
  686. return No_exp;
  687. }
  688. #endif
  689. /* ----------------------------------------------------------------------- */
  690. /* VADD */
  691. /* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */
  692. #ifdef VFP_INTERPRETER_STRUCT
  693. typedef struct _vadd_inst {
  694. unsigned int instr;
  695. unsigned int dp_operation;
  696. } vadd_inst;
  697. #endif
  698. #ifdef VFP_INTERPRETER_TRANS
  699. ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index)
  700. {
  701. VFP_DEBUG_TRANSLATE;
  702. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
  703. vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
  704. inst_base->cond = BITS(inst, 28, 31);
  705. inst_base->idx = index;
  706. inst_base->br = NON_BRANCH;
  707. inst_base->load_r15 = 0;
  708. inst_cream->dp_operation = BIT(inst, 8);
  709. inst_cream->instr = inst;
  710. return inst_base;
  711. }
  712. #endif
  713. #ifdef VFP_INTERPRETER_IMPL
  714. VADD_INST:
  715. {
  716. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  717. CHECK_VFP_ENABLED;
  718. DBG("VADD :\n");
  719. vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
  720. int ret;
  721. if (inst_cream->dp_operation)
  722. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  723. else
  724. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  725. CHECK_VFP_CDP_RET;
  726. }
  727. cpu->Reg[15] += GET_INST_SIZE(cpu);
  728. INC_PC(sizeof(vadd_inst));
  729. FETCH_INST;
  730. GOTO_NEXT_INST;
  731. }
  732. #endif
  733. #ifdef VFP_DYNCOM_TABLE
  734. DYNCOM_FILL_ACTION(vadd),
  735. #endif
  736. #ifdef VFP_DYNCOM_TAG
  737. int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  738. {
  739. int instr_size = INSTR_SIZE;
  740. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  741. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  742. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  743. return instr_size;
  744. }
  745. #endif
  746. #ifdef VFP_DYNCOM_TRANS
  747. int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  748. DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__);
  749. //arch_arm_undef(cpu, bb, instr);
  750. int m;
  751. int n;
  752. int d ;
  753. int s = BIT(8) == 0;
  754. Value *mm;
  755. Value *nn;
  756. Value *tmp;
  757. if(s){
  758. m = BIT(5) | BITS(0,3) << 1;
  759. n = BIT(7) | BITS(16,19) << 1;
  760. d = BIT(22) | BITS(12,15) << 1;
  761. mm = FR32(m);
  762. nn = FR32(n);
  763. tmp = FPADD(nn,mm);
  764. LETFPS(d,tmp);
  765. }else {
  766. m = BITS(0,3) | BIT(5) << 4;
  767. n = BITS(16,19) | BIT(7) << 4;
  768. d = BIT(22) << 4 | BITS(12,15);
  769. Value *lo = FR32(2 * m);
  770. Value *hi = FR32(2 * m + 1);
  771. hi = IBITCAST32(hi);
  772. lo = IBITCAST32(lo);
  773. Value *hi64 = ZEXT64(hi);
  774. Value* lo64 = ZEXT64(lo);
  775. Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
  776. Value* m0 = FPBITCAST64(v64);
  777. lo = FR32(2 * n);
  778. hi = FR32(2 * n + 1);
  779. hi = IBITCAST32(hi);
  780. lo = IBITCAST32(lo);
  781. hi64 = ZEXT64(hi);
  782. lo64 = ZEXT64(lo);
  783. v64 = OR(SHL(hi64,CONST64(32)),lo64);
  784. Value *n0 = FPBITCAST64(v64);
  785. tmp = FPADD(n0,m0);
  786. Value *val64 = IBITCAST64(tmp);
  787. hi = LSHR(val64,CONST64(32));
  788. lo = AND(val64,CONST64(0xffffffff));
  789. hi = TRUNC32(hi);
  790. lo = TRUNC32(lo);
  791. hi = FPBITCAST32(hi);
  792. lo = FPBITCAST32(lo);
  793. LETFPS(2*d ,lo);
  794. LETFPS(d*2 + 1 , hi);
  795. }
  796. return No_exp;
  797. }
  798. #endif
  799. /* ----------------------------------------------------------------------- */
  800. /* VSUB */
  801. /* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */
  802. #ifdef VFP_INTERPRETER_STRUCT
  803. typedef struct _vsub_inst {
  804. unsigned int instr;
  805. unsigned int dp_operation;
  806. } vsub_inst;
  807. #endif
  808. #ifdef VFP_INTERPRETER_TRANS
  809. ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index)
  810. {
  811. VFP_DEBUG_TRANSLATE;
  812. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst));
  813. vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
  814. inst_base->cond = BITS(inst, 28, 31);
  815. inst_base->idx = index;
  816. inst_base->br = NON_BRANCH;
  817. inst_base->load_r15 = 0;
  818. inst_cream->dp_operation = BIT(inst, 8);
  819. inst_cream->instr = inst;
  820. return inst_base;
  821. }
  822. #endif
  823. #ifdef VFP_INTERPRETER_IMPL
  824. VSUB_INST:
  825. {
  826. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  827. CHECK_VFP_ENABLED;
  828. DBG("VSUB :\n");
  829. vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
  830. int ret;
  831. if (inst_cream->dp_operation)
  832. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  833. else
  834. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  835. CHECK_VFP_CDP_RET;
  836. }
  837. cpu->Reg[15] += GET_INST_SIZE(cpu);
  838. INC_PC(sizeof(vsub_inst));
  839. FETCH_INST;
  840. GOTO_NEXT_INST;
  841. }
  842. #endif
  843. #ifdef VFP_DYNCOM_TABLE
  844. DYNCOM_FILL_ACTION(vsub),
  845. #endif
  846. #ifdef VFP_DYNCOM_TAG
  847. int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  848. {
  849. int instr_size = INSTR_SIZE;
  850. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  851. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  852. return instr_size;
  853. }
  854. #endif
  855. #ifdef VFP_DYNCOM_TRANS
  856. int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  857. DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr);
  858. //arch_arm_undef(cpu, bb, instr);
  859. int m;
  860. int n;
  861. int d ;
  862. int s = BIT(8) == 0;
  863. Value *mm;
  864. Value *nn;
  865. Value *tmp;
  866. if(s){
  867. m = BIT(5) | BITS(0,3) << 1;
  868. n = BIT(7) | BITS(16,19) << 1;
  869. d = BIT(22) | BITS(12,15) << 1;
  870. mm = FR32(m);
  871. nn = FR32(n);
  872. tmp = FPSUB(nn,mm);
  873. LETFPS(d,tmp);
  874. }else {
  875. m = BITS(0,3) | BIT(5) << 4;
  876. n = BITS(16,19) | BIT(7) << 4;
  877. d = BIT(22) << 4 | BITS(12,15);
  878. Value *lo = FR32(2 * m);
  879. Value *hi = FR32(2 * m + 1);
  880. hi = IBITCAST32(hi);
  881. lo = IBITCAST32(lo);
  882. Value *hi64 = ZEXT64(hi);
  883. Value* lo64 = ZEXT64(lo);
  884. Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
  885. Value* m0 = FPBITCAST64(v64);
  886. lo = FR32(2 * n);
  887. hi = FR32(2 * n + 1);
  888. hi = IBITCAST32(hi);
  889. lo = IBITCAST32(lo);
  890. hi64 = ZEXT64(hi);
  891. lo64 = ZEXT64(lo);
  892. v64 = OR(SHL(hi64,CONST64(32)),lo64);
  893. Value *n0 = FPBITCAST64(v64);
  894. tmp = FPSUB(n0,m0);
  895. Value *val64 = IBITCAST64(tmp);
  896. hi = LSHR(val64,CONST64(32));
  897. lo = AND(val64,CONST64(0xffffffff));
  898. hi = TRUNC32(hi);
  899. lo = TRUNC32(lo);
  900. hi = FPBITCAST32(hi);
  901. lo = FPBITCAST32(lo);
  902. LETFPS(2*d ,lo);
  903. LETFPS(d*2 + 1 , hi);
  904. }
  905. return No_exp;
  906. }
  907. #endif
  908. /* ----------------------------------------------------------------------- */
  909. /* VDIV */
  910. /* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */
  911. #ifdef VFP_INTERPRETER_STRUCT
  912. typedef struct _vdiv_inst {
  913. unsigned int instr;
  914. unsigned int dp_operation;
  915. } vdiv_inst;
  916. #endif
  917. #ifdef VFP_INTERPRETER_TRANS
  918. ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index)
  919. {
  920. VFP_DEBUG_TRANSLATE;
  921. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst));
  922. vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
  923. inst_base->cond = BITS(inst, 28, 31);
  924. inst_base->idx = index;
  925. inst_base->br = NON_BRANCH;
  926. inst_base->load_r15 = 0;
  927. inst_cream->dp_operation = BIT(inst, 8);
  928. inst_cream->instr = inst;
  929. return inst_base;
  930. }
  931. #endif
  932. #ifdef VFP_INTERPRETER_IMPL
  933. VDIV_INST:
  934. {
  935. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  936. CHECK_VFP_ENABLED;
  937. DBG("VDIV :\n");
  938. vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
  939. int ret;
  940. if (inst_cream->dp_operation)
  941. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  942. else
  943. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  944. CHECK_VFP_CDP_RET;
  945. }
  946. cpu->Reg[15] += GET_INST_SIZE(cpu);
  947. INC_PC(sizeof(vdiv_inst));
  948. FETCH_INST;
  949. GOTO_NEXT_INST;
  950. }
  951. #endif
  952. #ifdef VFP_DYNCOM_TABLE
  953. DYNCOM_FILL_ACTION(vdiv),
  954. #endif
  955. #ifdef VFP_DYNCOM_TAG
  956. int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  957. {
  958. int instr_size = INSTR_SIZE;
  959. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  960. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  961. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  962. return instr_size;
  963. }
  964. #endif
  965. #ifdef VFP_DYNCOM_TRANS
  966. int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  967. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  968. //arch_arm_undef(cpu, bb, instr);
  969. int m;
  970. int n;
  971. int d ;
  972. int s = BIT(8) == 0;
  973. Value *mm;
  974. Value *nn;
  975. Value *tmp;
  976. if(s){
  977. m = BIT(5) | BITS(0,3) << 1;
  978. n = BIT(7) | BITS(16,19) << 1;
  979. d = BIT(22) | BITS(12,15) << 1;
  980. mm = FR32(m);
  981. nn = FR32(n);
  982. tmp = FPDIV(nn,mm);
  983. LETFPS(d,tmp);
  984. }else {
  985. m = BITS(0,3) | BIT(5) << 4;
  986. n = BITS(16,19) | BIT(7) << 4;
  987. d = BIT(22) << 4 | BITS(12,15);
  988. Value *lo = FR32(2 * m);
  989. Value *hi = FR32(2 * m + 1);
  990. hi = IBITCAST32(hi);
  991. lo = IBITCAST32(lo);
  992. Value *hi64 = ZEXT64(hi);
  993. Value* lo64 = ZEXT64(lo);
  994. Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
  995. Value* m0 = FPBITCAST64(v64);
  996. lo = FR32(2 * n);
  997. hi = FR32(2 * n + 1);
  998. hi = IBITCAST32(hi);
  999. lo = IBITCAST32(lo);
  1000. hi64 = ZEXT64(hi);
  1001. lo64 = ZEXT64(lo);
  1002. v64 = OR(SHL(hi64,CONST64(32)),lo64);
  1003. Value *n0 = FPBITCAST64(v64);
  1004. tmp = FPDIV(n0,m0);
  1005. Value *val64 = IBITCAST64(tmp);
  1006. hi = LSHR(val64,CONST64(32));
  1007. lo = AND(val64,CONST64(0xffffffff));
  1008. hi = TRUNC32(hi);
  1009. lo = TRUNC32(lo);
  1010. hi = FPBITCAST32(hi);
  1011. lo = FPBITCAST32(lo);
  1012. LETFPS(2*d ,lo);
  1013. LETFPS(d*2 + 1 , hi);
  1014. }
  1015. return No_exp;
  1016. }
  1017. #endif
  1018. /* ----------------------------------------------------------------------- */
  1019. /* VMOVI move immediate */
  1020. /* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */
  1021. /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
  1022. #ifdef VFP_INTERPRETER_STRUCT
  1023. typedef struct _vmovi_inst {
  1024. unsigned int single;
  1025. unsigned int d;
  1026. unsigned int imm;
  1027. } vmovi_inst;
  1028. #endif
  1029. #ifdef VFP_INTERPRETER_TRANS
  1030. ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index)
  1031. {
  1032. VFP_DEBUG_TRANSLATE;
  1033. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst));
  1034. vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
  1035. inst_base->cond = BITS(inst, 28, 31);
  1036. inst_base->idx = index;
  1037. inst_base->br = NON_BRANCH;
  1038. inst_base->load_r15 = 0;
  1039. inst_cream->single = BIT(inst, 8) == 0;
  1040. inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
  1041. unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3);
  1042. if (inst_cream->single)
  1043. inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19;
  1044. else
  1045. inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16;
  1046. return inst_base;
  1047. }
  1048. #endif
  1049. #ifdef VFP_INTERPRETER_IMPL
  1050. VMOVI_INST:
  1051. {
  1052. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1053. CHECK_VFP_ENABLED;
  1054. vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
  1055. VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
  1056. }
  1057. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1058. INC_PC(sizeof(vmovi_inst));
  1059. FETCH_INST;
  1060. GOTO_NEXT_INST;
  1061. }
  1062. #endif
  1063. #ifdef VFP_DYNCOM_TABLE
  1064. DYNCOM_FILL_ACTION(vmovi),
  1065. #endif
  1066. #ifdef VFP_DYNCOM_TAG
  1067. int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1068. {
  1069. int instr_size = INSTR_SIZE;
  1070. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1071. arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1072. return instr_size;
  1073. }
  1074. #endif
  1075. #ifdef VFP_DYNCOM_TRANS
  1076. int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1077. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1078. //arch_arm_undef(cpu, bb, instr);
  1079. int single = (BIT(8) == 0);
  1080. int d;
  1081. int imm32;
  1082. Value *v;
  1083. Value *tmp;
  1084. v = CONST32(BITS(0,3) | BITS(16,19) << 4);
  1085. //v = CONST64(0x3ff0000000000000);
  1086. if(single){
  1087. d = BIT(22) | BITS(12,15) << 1;
  1088. }else {
  1089. d = BITS(12,15) | BIT(22) << 4;
  1090. }
  1091. if(single){
  1092. LETFPS(d,FPBITCAST32(v));
  1093. }else {
  1094. //v = UITOFP(64,v);
  1095. //tmp = IBITCAST64(v);
  1096. LETFPS(d*2 ,FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff)))));
  1097. LETFPS(d * 2 + 1,FPBITCAST32(TRUNC32(LSHR(v,CONST64(32)))));
  1098. }
  1099. return No_exp;
  1100. }
  1101. #endif
  1102. /* ----------------------------------------------------------------------- */
  1103. /* VMOVR move register */
  1104. /* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */
  1105. /* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
  1106. #ifdef VFP_INTERPRETER_STRUCT
  1107. typedef struct _vmovr_inst {
  1108. unsigned int single;
  1109. unsigned int d;
  1110. unsigned int m;
  1111. } vmovr_inst;
  1112. #endif
  1113. #ifdef VFP_INTERPRETER_TRANS
  1114. ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
  1115. {
  1116. VFP_DEBUG_TRANSLATE;
  1117. VFP_DEBUG_UNTESTED(VMOVR);
  1118. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
  1119. vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
  1120. inst_base->cond = BITS(inst, 28, 31);
  1121. inst_base->idx = index;
  1122. inst_base->br = NON_BRANCH;
  1123. inst_base->load_r15 = 0;
  1124. inst_cream->single = BIT(inst, 8) == 0;
  1125. inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
  1126. inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4);
  1127. return inst_base;
  1128. }
  1129. #endif
  1130. #ifdef VFP_INTERPRETER_IMPL
  1131. VMOVR_INST:
  1132. {
  1133. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1134. CHECK_VFP_ENABLED;
  1135. vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
  1136. VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
  1137. }
  1138. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1139. INC_PC(sizeof(vmovr_inst));
  1140. FETCH_INST;
  1141. GOTO_NEXT_INST;
  1142. }
  1143. #endif
  1144. #ifdef VFP_DYNCOM_TABLE
  1145. DYNCOM_FILL_ACTION(vmovr),
  1146. #endif
  1147. #ifdef VFP_DYNCOM_TAG
  1148. int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1149. {
  1150. int instr_size = INSTR_SIZE;
  1151. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1152. DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
  1153. if(instr >> 28 != 0xe)
  1154. *tag |= TAG_CONDITIONAL;
  1155. return instr_size;
  1156. }
  1157. #endif
  1158. #ifdef VFP_DYNCOM_TRANS
  1159. int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1160. DBG("\t\tin %s VMOV \n", __FUNCTION__);
  1161. int single = BIT(8) == 0;
  1162. int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
  1163. int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
  1164. if (single)
  1165. {
  1166. LETFPS(d, FR32(m));
  1167. }
  1168. else
  1169. {
  1170. /* Check endian please */
  1171. LETFPS((d*2 + 1), FR32(m*2 + 1));
  1172. LETFPS((d * 2), FR32(m * 2));
  1173. }
  1174. return No_exp;
  1175. }
  1176. #endif
  1177. /* ----------------------------------------------------------------------- */
  1178. /* VABS */
  1179. /* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */
  1180. #ifdef VFP_INTERPRETER_STRUCT
  1181. typedef struct _vabs_inst {
  1182. unsigned int instr;
  1183. unsigned int dp_operation;
  1184. } vabs_inst;
  1185. #endif
  1186. #ifdef VFP_INTERPRETER_TRANS
  1187. ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
  1188. {
  1189. VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS);
  1190. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
  1191. vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
  1192. inst_base->cond = BITS(inst, 28, 31);
  1193. inst_base->idx = index;
  1194. inst_base->br = NON_BRANCH;
  1195. inst_base->load_r15 = 0;
  1196. inst_cream->dp_operation = BIT(inst, 8);
  1197. inst_cream->instr = inst;
  1198. return inst_base;
  1199. }
  1200. #endif
  1201. #ifdef VFP_INTERPRETER_IMPL
  1202. VABS_INST:
  1203. {
  1204. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1205. CHECK_VFP_ENABLED;
  1206. DBG("VABS :\n");
  1207. vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
  1208. int ret;
  1209. if (inst_cream->dp_operation)
  1210. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1211. else
  1212. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1213. CHECK_VFP_CDP_RET;
  1214. }
  1215. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1216. INC_PC(sizeof(vabs_inst));
  1217. FETCH_INST;
  1218. GOTO_NEXT_INST;
  1219. }
  1220. #endif
  1221. #ifdef VFP_DYNCOM_TABLE
  1222. DYNCOM_FILL_ACTION(vabs),
  1223. #endif
  1224. #ifdef VFP_DYNCOM_TAG
  1225. int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1226. {
  1227. int instr_size = INSTR_SIZE;
  1228. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1229. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1230. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1231. return instr_size;
  1232. }
  1233. #endif
  1234. #ifdef VFP_DYNCOM_TRANS
  1235. int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1236. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1237. //arch_arm_undef(cpu, bb, instr);
  1238. int single = BIT(8) == 0;
  1239. int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
  1240. int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
  1241. Value* m0;
  1242. if (single)
  1243. {
  1244. m0 = FR32(m);
  1245. m0 = SELECT(FPCMP_OLT(m0,FPCONST32(0.0)),FPNEG32(m0),m0);
  1246. LETFPS(d,m0);
  1247. }
  1248. else
  1249. {
  1250. /* Check endian please */
  1251. Value *lo = FR32(2 * m);
  1252. Value *hi = FR32(2 * m + 1);
  1253. hi = IBITCAST32(hi);
  1254. lo = IBITCAST32(lo);
  1255. Value *hi64 = ZEXT64(hi);
  1256. Value* lo64 = ZEXT64(lo);
  1257. Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
  1258. m0 = FPBITCAST64(v64);
  1259. m0 = SELECT(FPCMP_OLT(m0,FPCONST64(0.0)),FPNEG64(m0),m0);
  1260. Value *val64 = IBITCAST64(m0);
  1261. hi = LSHR(val64,CONST64(32));
  1262. lo = AND(val64,CONST64(0xffffffff));
  1263. hi = TRUNC32(hi);
  1264. lo = TRUNC32(lo);
  1265. hi = FPBITCAST32(hi);
  1266. lo = FPBITCAST32(lo);
  1267. LETFPS(2*d ,lo);
  1268. LETFPS(d*2 + 1 , hi);
  1269. }
  1270. return No_exp;
  1271. }
  1272. #endif
  1273. /* ----------------------------------------------------------------------- */
  1274. /* VNEG */
  1275. /* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
  1276. #ifdef VFP_INTERPRETER_STRUCT
  1277. typedef struct _vneg_inst {
  1278. unsigned int instr;
  1279. unsigned int dp_operation;
  1280. } vneg_inst;
  1281. #endif
  1282. #ifdef VFP_INTERPRETER_TRANS
  1283. ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
  1284. {
  1285. VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG);
  1286. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
  1287. vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
  1288. inst_base->cond = BITS(inst, 28, 31);
  1289. inst_base->idx = index;
  1290. inst_base->br = NON_BRANCH;
  1291. inst_base->load_r15 = 0;
  1292. inst_cream->dp_operation = BIT(inst, 8);
  1293. inst_cream->instr = inst;
  1294. return inst_base;
  1295. }
  1296. #endif
  1297. #ifdef VFP_INTERPRETER_IMPL
  1298. VNEG_INST:
  1299. {
  1300. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1301. CHECK_VFP_ENABLED;
  1302. DBG("VNEG :\n");
  1303. vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
  1304. int ret;
  1305. if (inst_cream->dp_operation)
  1306. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1307. else
  1308. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1309. CHECK_VFP_CDP_RET;
  1310. }
  1311. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1312. INC_PC(sizeof(vneg_inst));
  1313. FETCH_INST;
  1314. GOTO_NEXT_INST;
  1315. }
  1316. #endif
  1317. #ifdef VFP_DYNCOM_TABLE
  1318. DYNCOM_FILL_ACTION(vneg),
  1319. #endif
  1320. #ifdef VFP_DYNCOM_TAG
  1321. int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1322. {
  1323. int instr_size = INSTR_SIZE;
  1324. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1325. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1326. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1327. return instr_size;
  1328. }
  1329. #endif
  1330. #ifdef VFP_DYNCOM_TRANS
  1331. int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1332. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1333. //arch_arm_undef(cpu, bb, instr);
  1334. int single = BIT(8) == 0;
  1335. int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
  1336. int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
  1337. Value* m0;
  1338. if (single)
  1339. {
  1340. m0 = FR32(m);
  1341. m0 = FPNEG32(m0);
  1342. LETFPS(d,m0);
  1343. }
  1344. else
  1345. {
  1346. /* Check endian please */
  1347. Value *lo = FR32(2 * m);
  1348. Value *hi = FR32(2 * m + 1);
  1349. hi = IBITCAST32(hi);
  1350. lo = IBITCAST32(lo);
  1351. Value *hi64 = ZEXT64(hi);
  1352. Value* lo64 = ZEXT64(lo);
  1353. Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
  1354. m0 = FPBITCAST64(v64);
  1355. m0 = FPNEG64(m0);
  1356. Value *val64 = IBITCAST64(m0);
  1357. hi = LSHR(val64,CONST64(32));
  1358. lo = AND(val64,CONST64(0xffffffff));
  1359. hi = TRUNC32(hi);
  1360. lo = TRUNC32(lo);
  1361. hi = FPBITCAST32(hi);
  1362. lo = FPBITCAST32(lo);
  1363. LETFPS(2*d ,lo);
  1364. LETFPS(d*2 + 1 , hi);
  1365. }
  1366. return No_exp;
  1367. }
  1368. #endif
  1369. /* ----------------------------------------------------------------------- */
  1370. /* VSQRT */
  1371. /* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
  1372. #ifdef VFP_INTERPRETER_STRUCT
  1373. typedef struct _vsqrt_inst {
  1374. unsigned int instr;
  1375. unsigned int dp_operation;
  1376. } vsqrt_inst;
  1377. #endif
  1378. #ifdef VFP_INTERPRETER_TRANS
  1379. ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index)
  1380. {
  1381. VFP_DEBUG_TRANSLATE;
  1382. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst));
  1383. vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
  1384. inst_base->cond = BITS(inst, 28, 31);
  1385. inst_base->idx = index;
  1386. inst_base->br = NON_BRANCH;
  1387. inst_base->load_r15 = 0;
  1388. inst_cream->dp_operation = BIT(inst, 8);
  1389. inst_cream->instr = inst;
  1390. return inst_base;
  1391. }
  1392. #endif
  1393. #ifdef VFP_INTERPRETER_IMPL
  1394. VSQRT_INST:
  1395. {
  1396. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1397. CHECK_VFP_ENABLED;
  1398. DBG("VSQRT :\n");
  1399. vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
  1400. int ret;
  1401. if (inst_cream->dp_operation)
  1402. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1403. else
  1404. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1405. CHECK_VFP_CDP_RET;
  1406. }
  1407. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1408. INC_PC(sizeof(vsqrt_inst));
  1409. FETCH_INST;
  1410. GOTO_NEXT_INST;
  1411. }
  1412. #endif
  1413. #ifdef VFP_DYNCOM_TABLE
  1414. DYNCOM_FILL_ACTION(vsqrt),
  1415. #endif
  1416. #ifdef VFP_DYNCOM_TAG
  1417. int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1418. {
  1419. int instr_size = INSTR_SIZE;
  1420. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1421. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1422. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1423. return instr_size;
  1424. }
  1425. #endif
  1426. #ifdef VFP_DYNCOM_TRANS
  1427. int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1428. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1429. //arch_arm_undef(cpu, bb, instr);
  1430. int dp_op = (BIT(8) == 1);
  1431. int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
  1432. int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
  1433. Value* v;
  1434. Value* tmp;
  1435. if(dp_op){
  1436. v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
  1437. tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
  1438. v = OR(v,tmp);
  1439. v = FPSQRT(FPBITCAST64(v));
  1440. tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32)));
  1441. v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff)));
  1442. LETFPS(2 * d , FPBITCAST32(v));
  1443. LETFPS(2 * d + 1, FPBITCAST32(tmp));
  1444. }else {
  1445. v = FR32(m);
  1446. v = FPSQRT(FPEXT(64,v));
  1447. v = FPTRUNC(32,v);
  1448. LETFPS(d,v);
  1449. }
  1450. return No_exp;
  1451. }
  1452. #endif
  1453. /* ----------------------------------------------------------------------- */
  1454. /* VCMP VCMPE */
  1455. /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */
  1456. #ifdef VFP_INTERPRETER_STRUCT
  1457. typedef struct _vcmp_inst {
  1458. unsigned int instr;
  1459. unsigned int dp_operation;
  1460. } vcmp_inst;
  1461. #endif
  1462. #ifdef VFP_INTERPRETER_TRANS
  1463. ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index)
  1464. {
  1465. VFP_DEBUG_TRANSLATE;
  1466. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst));
  1467. vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
  1468. inst_base->cond = BITS(inst, 28, 31);
  1469. inst_base->idx = index;
  1470. inst_base->br = NON_BRANCH;
  1471. inst_base->load_r15 = 0;
  1472. inst_cream->dp_operation = BIT(inst, 8);
  1473. inst_cream->instr = inst;
  1474. return inst_base;
  1475. }
  1476. #endif
  1477. #ifdef VFP_INTERPRETER_IMPL
  1478. VCMP_INST:
  1479. {
  1480. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1481. CHECK_VFP_ENABLED;
  1482. DBG("VCMP(1) :\n");
  1483. vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
  1484. int ret;
  1485. if (inst_cream->dp_operation)
  1486. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1487. else
  1488. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1489. CHECK_VFP_CDP_RET;
  1490. }
  1491. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1492. INC_PC(sizeof(vcmp_inst));
  1493. FETCH_INST;
  1494. GOTO_NEXT_INST;
  1495. }
  1496. #endif
  1497. #ifdef VFP_DYNCOM_TABLE
  1498. DYNCOM_FILL_ACTION(vcmp),
  1499. #endif
  1500. #ifdef VFP_DYNCOM_TAG
  1501. int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1502. {
  1503. int instr_size = INSTR_SIZE;
  1504. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1505. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1506. return instr_size;
  1507. }
  1508. #endif
  1509. #ifdef VFP_DYNCOM_TRANS
  1510. int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1511. DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__);
  1512. //arch_arm_undef(cpu, bb, instr);
  1513. int dp_op = (BIT(8) == 1);
  1514. int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
  1515. int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
  1516. Value* v;
  1517. Value* tmp;
  1518. Value* n;
  1519. Value* z;
  1520. Value* c;
  1521. Value* vt;
  1522. Value* v1;
  1523. Value* nzcv;
  1524. if(dp_op){
  1525. v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
  1526. tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
  1527. v1 = OR(v,tmp);
  1528. v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
  1529. tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
  1530. v = OR(v,tmp);
  1531. z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
  1532. n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
  1533. c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
  1534. tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
  1535. v1 = tmp;
  1536. c = OR(c,tmp);
  1537. n = SHL(ZEXT32(n),CONST32(31));
  1538. z = SHL(ZEXT32(z),CONST32(30));
  1539. c = SHL(ZEXT32(c),CONST32(29));
  1540. v1 = SHL(ZEXT32(v1),CONST(28));
  1541. nzcv = OR(OR(OR(n,z),c),v1);
  1542. v = R(VFP_FPSCR);
  1543. tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
  1544. LET(VFP_FPSCR,tmp);
  1545. }else {
  1546. z = FPCMP_OEQ(FR32(d),FR32(m));
  1547. n = FPCMP_OLT(FR32(d),FR32(m));
  1548. c = FPCMP_OGE(FR32(d),FR32(m));
  1549. tmp = FPCMP_UNO(FR32(d),FR32(m));
  1550. c = OR(c,tmp);
  1551. v1 = tmp;
  1552. n = SHL(ZEXT32(n),CONST32(31));
  1553. z = SHL(ZEXT32(z),CONST32(30));
  1554. c = SHL(ZEXT32(c),CONST32(29));
  1555. v1 = SHL(ZEXT32(v1),CONST(28));
  1556. nzcv = OR(OR(OR(n,z),c),v1);
  1557. v = R(VFP_FPSCR);
  1558. tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
  1559. LET(VFP_FPSCR,tmp);
  1560. }
  1561. return No_exp;
  1562. }
  1563. #endif
  1564. /* ----------------------------------------------------------------------- */
  1565. /* VCMP VCMPE */
  1566. /* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */
  1567. #ifdef VFP_INTERPRETER_STRUCT
  1568. typedef struct _vcmp2_inst {
  1569. unsigned int instr;
  1570. unsigned int dp_operation;
  1571. } vcmp2_inst;
  1572. #endif
  1573. #ifdef VFP_INTERPRETER_TRANS
  1574. ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index)
  1575. {
  1576. VFP_DEBUG_TRANSLATE;
  1577. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst));
  1578. vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
  1579. inst_base->cond = BITS(inst, 28, 31);
  1580. inst_base->idx = index;
  1581. inst_base->br = NON_BRANCH;
  1582. inst_base->load_r15 = 0;
  1583. inst_cream->dp_operation = BIT(inst, 8);
  1584. inst_cream->instr = inst;
  1585. return inst_base;
  1586. }
  1587. #endif
  1588. #ifdef VFP_INTERPRETER_IMPL
  1589. VCMP2_INST:
  1590. {
  1591. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1592. CHECK_VFP_ENABLED;
  1593. DBG("VCMP(2) :\n");
  1594. vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
  1595. int ret;
  1596. if (inst_cream->dp_operation)
  1597. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1598. else
  1599. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1600. CHECK_VFP_CDP_RET;
  1601. }
  1602. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1603. INC_PC(sizeof(vcmp2_inst));
  1604. FETCH_INST;
  1605. GOTO_NEXT_INST;
  1606. }
  1607. #endif
  1608. #ifdef VFP_DYNCOM_TABLE
  1609. DYNCOM_FILL_ACTION(vcmp2),
  1610. #endif
  1611. #ifdef VFP_DYNCOM_TAG
  1612. int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1613. {
  1614. int instr_size = INSTR_SIZE;
  1615. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1616. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1617. return instr_size;
  1618. }
  1619. #endif
  1620. #ifdef VFP_DYNCOM_TRANS
  1621. int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1622. DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__);
  1623. //arch_arm_undef(cpu, bb, instr);
  1624. int dp_op = (BIT(8) == 1);
  1625. int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
  1626. //int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
  1627. Value* v;
  1628. Value* tmp;
  1629. Value* n;
  1630. Value* z;
  1631. Value* c;
  1632. Value* vt;
  1633. Value* v1;
  1634. Value* nzcv;
  1635. if(dp_op){
  1636. v1 = CONST64(0);
  1637. v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
  1638. tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
  1639. v = OR(v,tmp);
  1640. z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
  1641. n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
  1642. c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
  1643. tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
  1644. v1 = tmp;
  1645. c = OR(c,tmp);
  1646. n = SHL(ZEXT32(n),CONST32(31));
  1647. z = SHL(ZEXT32(z),CONST32(30));
  1648. c = SHL(ZEXT32(c),CONST32(29));
  1649. v1 = SHL(ZEXT32(v1),CONST(28));
  1650. nzcv = OR(OR(OR(n,z),c),v1);
  1651. v = R(VFP_FPSCR);
  1652. tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
  1653. LET(VFP_FPSCR,tmp);
  1654. }else {
  1655. v1 = CONST(0);
  1656. v1 = FPBITCAST32(v1);
  1657. z = FPCMP_OEQ(FR32(d),v1);
  1658. n = FPCMP_OLT(FR32(d),v1);
  1659. c = FPCMP_OGE(FR32(d),v1);
  1660. tmp = FPCMP_UNO(FR32(d),v1);
  1661. c = OR(c,tmp);
  1662. v1 = tmp;
  1663. n = SHL(ZEXT32(n),CONST32(31));
  1664. z = SHL(ZEXT32(z),CONST32(30));
  1665. c = SHL(ZEXT32(c),CONST32(29));
  1666. v1 = SHL(ZEXT32(v1),CONST(28));
  1667. nzcv = OR(OR(OR(n,z),c),v1);
  1668. v = R(VFP_FPSCR);
  1669. tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
  1670. LET(VFP_FPSCR,tmp);
  1671. }
  1672. return No_exp;
  1673. }
  1674. #endif
  1675. /* ----------------------------------------------------------------------- */
  1676. /* VCVTBDS between double and single */
  1677. /* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */
  1678. #ifdef VFP_INTERPRETER_STRUCT
  1679. typedef struct _vcvtbds_inst {
  1680. unsigned int instr;
  1681. unsigned int dp_operation;
  1682. } vcvtbds_inst;
  1683. #endif
  1684. #ifdef VFP_INTERPRETER_TRANS
  1685. ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index)
  1686. {
  1687. VFP_DEBUG_TRANSLATE;
  1688. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst));
  1689. vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
  1690. inst_base->cond = BITS(inst, 28, 31);
  1691. inst_base->idx = index;
  1692. inst_base->br = NON_BRANCH;
  1693. inst_base->load_r15 = 0;
  1694. inst_cream->dp_operation = BIT(inst, 8);
  1695. inst_cream->instr = inst;
  1696. return inst_base;
  1697. }
  1698. #endif
  1699. #ifdef VFP_INTERPRETER_IMPL
  1700. VCVTBDS_INST:
  1701. {
  1702. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1703. CHECK_VFP_ENABLED;
  1704. DBG("VCVT(BDS) :\n");
  1705. vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
  1706. int ret;
  1707. if (inst_cream->dp_operation)
  1708. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1709. else
  1710. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1711. CHECK_VFP_CDP_RET;
  1712. }
  1713. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1714. INC_PC(sizeof(vcvtbds_inst));
  1715. FETCH_INST;
  1716. GOTO_NEXT_INST;
  1717. }
  1718. #endif
  1719. #ifdef VFP_DYNCOM_TABLE
  1720. DYNCOM_FILL_ACTION(vcvtbds),
  1721. #endif
  1722. #ifdef VFP_DYNCOM_TAG
  1723. int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1724. {
  1725. int instr_size = INSTR_SIZE;
  1726. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1727. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1728. return instr_size;
  1729. }
  1730. #endif
  1731. #ifdef VFP_DYNCOM_TRANS
  1732. int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1733. DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__);
  1734. //arch_arm_undef(cpu, bb, instr);
  1735. int dp_op = (BIT(8) == 1);
  1736. int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15);
  1737. int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
  1738. int d2s = dp_op;
  1739. Value* v;
  1740. Value* tmp;
  1741. Value* v1;
  1742. if(d2s){
  1743. v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
  1744. tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
  1745. v1 = OR(v,tmp);
  1746. tmp = FPTRUNC(32,FPBITCAST64(v1));
  1747. LETFPS(d,tmp);
  1748. }else {
  1749. v = FR32(m);
  1750. tmp = FPEXT(64,v);
  1751. v = IBITCAST64(tmp);
  1752. tmp = TRUNC32(AND(v,CONST64(0xffffffff)));
  1753. v1 = TRUNC32(LSHR(v,CONST64(32)));
  1754. LETFPS(2 * d, FPBITCAST32(tmp) );
  1755. LETFPS(2 * d + 1, FPBITCAST32(v1));
  1756. }
  1757. return No_exp;
  1758. }
  1759. #endif
  1760. /* ----------------------------------------------------------------------- */
  1761. /* VCVTBFF between floating point and fixed point */
  1762. /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
  1763. #ifdef VFP_INTERPRETER_STRUCT
  1764. typedef struct _vcvtbff_inst {
  1765. unsigned int instr;
  1766. unsigned int dp_operation;
  1767. } vcvtbff_inst;
  1768. #endif
  1769. #ifdef VFP_INTERPRETER_TRANS
  1770. ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index)
  1771. {
  1772. VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF);
  1773. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst));
  1774. vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
  1775. inst_base->cond = BITS(inst, 28, 31);
  1776. inst_base->idx = index;
  1777. inst_base->br = NON_BRANCH;
  1778. inst_base->load_r15 = 0;
  1779. inst_cream->dp_operation = BIT(inst, 8);
  1780. inst_cream->instr = inst;
  1781. return inst_base;
  1782. }
  1783. #endif
  1784. #ifdef VFP_INTERPRETER_IMPL
  1785. VCVTBFF_INST:
  1786. {
  1787. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1788. CHECK_VFP_ENABLED;
  1789. DBG("VCVT(BFF) :\n");
  1790. vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
  1791. int ret;
  1792. if (inst_cream->dp_operation)
  1793. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1794. else
  1795. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1796. CHECK_VFP_CDP_RET;
  1797. }
  1798. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1799. INC_PC(sizeof(vcvtbff_inst));
  1800. FETCH_INST;
  1801. GOTO_NEXT_INST;
  1802. }
  1803. #endif
  1804. #ifdef VFP_DYNCOM_TABLE
  1805. DYNCOM_FILL_ACTION(vcvtbff),
  1806. #endif
  1807. #ifdef VFP_DYNCOM_TAG
  1808. int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1809. {
  1810. int instr_size = INSTR_SIZE;
  1811. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1812. arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1813. return instr_size;
  1814. }
  1815. #endif
  1816. #ifdef VFP_DYNCOM_TRANS
  1817. int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1818. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1819. arch_arm_undef(cpu, bb, instr);
  1820. return No_exp;
  1821. }
  1822. #endif
  1823. /* ----------------------------------------------------------------------- */
  1824. /* VCVTBFI between floating point and integer */
  1825. /* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
  1826. #ifdef VFP_INTERPRETER_STRUCT
  1827. typedef struct _vcvtbfi_inst {
  1828. unsigned int instr;
  1829. unsigned int dp_operation;
  1830. } vcvtbfi_inst;
  1831. #endif
  1832. #ifdef VFP_INTERPRETER_TRANS
  1833. ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index)
  1834. {
  1835. VFP_DEBUG_TRANSLATE;
  1836. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst));
  1837. vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
  1838. inst_base->cond = BITS(inst, 28, 31);
  1839. inst_base->idx = index;
  1840. inst_base->br = NON_BRANCH;
  1841. inst_base->load_r15 = 0;
  1842. inst_cream->dp_operation = BIT(inst, 8);
  1843. inst_cream->instr = inst;
  1844. return inst_base;
  1845. }
  1846. #endif
  1847. #ifdef VFP_INTERPRETER_IMPL
  1848. VCVTBFI_INST:
  1849. {
  1850. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  1851. CHECK_VFP_ENABLED;
  1852. DBG("VCVT(BFI) :\n");
  1853. vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
  1854. int ret;
  1855. if (inst_cream->dp_operation)
  1856. ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1857. else
  1858. ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1859. CHECK_VFP_CDP_RET;
  1860. }
  1861. cpu->Reg[15] += GET_INST_SIZE(cpu);
  1862. INC_PC(sizeof(vcvtbfi_inst));
  1863. FETCH_INST;
  1864. GOTO_NEXT_INST;
  1865. }
  1866. #endif
  1867. #ifdef VFP_DYNCOM_TABLE
  1868. DYNCOM_FILL_ACTION(vcvtbfi),
  1869. #endif
  1870. #ifdef VFP_DYNCOM_TAG
  1871. int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  1872. {
  1873. int instr_size = INSTR_SIZE;
  1874. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  1875. DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
  1876. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  1877. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  1878. return instr_size;
  1879. }
  1880. #endif
  1881. #ifdef VFP_DYNCOM_TRANS
  1882. int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  1883. DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
  1884. //arch_arm_undef(cpu, bb, instr);
  1885. unsigned int opc2 = BITS(16,18);
  1886. int to_integer = ((opc2 >> 2) == 1);
  1887. int dp_op = (BIT(8) == 1);
  1888. unsigned int op = BIT(7);
  1889. int m,d;
  1890. Value* v;
  1891. Value* hi;
  1892. Value* lo;
  1893. Value* v64;
  1894. if(to_integer){
  1895. d = BIT(22) | (BITS(12,15) << 1);
  1896. if(dp_op)
  1897. m = BITS(0,3) | BIT(5) << 4;
  1898. else
  1899. m = BIT(5) | BITS(0,3) << 1;
  1900. }else {
  1901. m = BIT(5) | BITS(0,3) << 1;
  1902. if(dp_op)
  1903. d = BITS(12,15) | BIT(22) << 4;
  1904. else
  1905. d = BIT(22) | BITS(12,15) << 1;
  1906. }
  1907. if(to_integer){
  1908. if(dp_op){
  1909. lo = FR32(m * 2);
  1910. hi = FR32(m * 2 + 1);
  1911. hi = ZEXT64(IBITCAST32(hi));
  1912. lo = ZEXT64(IBITCAST32(lo));
  1913. v64 = OR(SHL(hi,CONST64(32)),lo);
  1914. if(BIT(16)){
  1915. v = FPTOSI(32,FPBITCAST64(v64));
  1916. }
  1917. else
  1918. v = FPTOUI(32,FPBITCAST64(v64));
  1919. v = FPBITCAST32(v);
  1920. LETFPS(d,v);
  1921. }else {
  1922. v = FR32(m);
  1923. if(BIT(16)){
  1924. v = FPTOSI(32,v);
  1925. }
  1926. else
  1927. v = FPTOUI(32,v);
  1928. LETFPS(d,FPBITCAST32(v));
  1929. }
  1930. }else {
  1931. if(dp_op){
  1932. v = IBITCAST32(FR32(m));
  1933. if(BIT(7))
  1934. v64 = SITOFP(64,v);
  1935. else
  1936. v64 = UITOFP(64,v);
  1937. v = IBITCAST64(v64);
  1938. hi = FPBITCAST32(TRUNC32(LSHR(v,CONST64(32))));
  1939. lo = FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff))));
  1940. LETFPS(2 * d , lo);
  1941. LETFPS(2 * d + 1, hi);
  1942. }else {
  1943. v = IBITCAST32(FR32(m));
  1944. if(BIT(7))
  1945. v = SITOFP(32,v);
  1946. else
  1947. v = UITOFP(32,v);
  1948. LETFPS(d,v);
  1949. }
  1950. }
  1951. return No_exp;
  1952. }
  1953. /**
  1954. * @brief The implementation of c language for vcvtbfi instruction of dyncom
  1955. *
  1956. * @param cpu
  1957. * @param instr
  1958. *
  1959. * @return
  1960. */
  1961. int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
  1962. int dp_operation = BIT(8);
  1963. int ret;
  1964. if (dp_operation)
  1965. ret = vfp_double_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1966. else
  1967. ret = vfp_single_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1968. vfp_raise_exceptions(cpu, ret, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  1969. return 0;
  1970. }
  1971. #endif
  1972. /* ----------------------------------------------------------------------- */
  1973. /* MRC / MCR instructions */
  1974. /* cond 1110 AAAL XXXX XXXX 101C XBB1 XXXX */
  1975. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- */
  1976. /* ----------------------------------------------------------------------- */
  1977. /* VMOVBRS between register and single precision */
  1978. /* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */
  1979. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
  1980. #ifdef VFP_INTERPRETER_STRUCT
  1981. typedef struct _vmovbrs_inst {
  1982. unsigned int to_arm;
  1983. unsigned int t;
  1984. unsigned int n;
  1985. } vmovbrs_inst;
  1986. #endif
  1987. #ifdef VFP_INTERPRETER_TRANS
  1988. ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index)
  1989. {
  1990. VFP_DEBUG_TRANSLATE;
  1991. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst));
  1992. vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
  1993. inst_base->cond = BITS(inst, 28, 31);
  1994. inst_base->idx = index;
  1995. inst_base->br = NON_BRANCH;
  1996. inst_base->load_r15 = 0;
  1997. inst_cream->to_arm = BIT(inst, 20) == 1;
  1998. inst_cream->t = BITS(inst, 12, 15);
  1999. inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1;
  2000. return inst_base;
  2001. }
  2002. #endif
  2003. #ifdef VFP_INTERPRETER_IMPL
  2004. VMOVBRS_INST:
  2005. {
  2006. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2007. CHECK_VFP_ENABLED;
  2008. vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
  2009. VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
  2010. }
  2011. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2012. INC_PC(sizeof(vmovbrs_inst));
  2013. FETCH_INST;
  2014. GOTO_NEXT_INST;
  2015. }
  2016. #endif
  2017. #ifdef VFP_DYNCOM_TABLE
  2018. DYNCOM_FILL_ACTION(vmovbrs),
  2019. #endif
  2020. #ifdef VFP_DYNCOM_TAG
  2021. int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2022. {
  2023. int instr_size = INSTR_SIZE;
  2024. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2025. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  2026. return instr_size;
  2027. }
  2028. #endif
  2029. #ifdef VFP_DYNCOM_TRANS
  2030. int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2031. DBG("VMOV(BRS) :\n");
  2032. int to_arm = BIT(20) == 1;
  2033. int t = BITS(12, 15);
  2034. int n = BIT(7) | BITS(16, 19)<<1;
  2035. if (to_arm)
  2036. {
  2037. DBG("\tr%d <= s%d\n", t, n);
  2038. LET(t, IBITCAST32(FR32(n)));
  2039. }
  2040. else
  2041. {
  2042. DBG("\ts%d <= r%d\n", n, t);
  2043. LETFPS(n, FPBITCAST32(R(t)));
  2044. }
  2045. return No_exp;
  2046. }
  2047. #endif
  2048. /* ----------------------------------------------------------------------- */
  2049. /* VMSR */
  2050. /* cond 1110 1110 reg- Rt-- 1010 0001 0000 */
  2051. /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
  2052. #ifdef VFP_INTERPRETER_STRUCT
  2053. typedef struct _vmsr_inst {
  2054. unsigned int reg;
  2055. unsigned int Rd;
  2056. } vmsr_inst;
  2057. #endif
  2058. #ifdef VFP_INTERPRETER_TRANS
  2059. ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
  2060. {
  2061. VFP_DEBUG_TRANSLATE;
  2062. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst));
  2063. vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
  2064. inst_base->cond = BITS(inst, 28, 31);
  2065. inst_base->idx = index;
  2066. inst_base->br = NON_BRANCH;
  2067. inst_base->load_r15 = 0;
  2068. inst_cream->reg = BITS(inst, 16, 19);
  2069. inst_cream->Rd = BITS(inst, 12, 15);
  2070. return inst_base;
  2071. }
  2072. #endif
  2073. #ifdef VFP_INTERPRETER_IMPL
  2074. VMSR_INST:
  2075. {
  2076. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2077. /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled ,
  2078. and in privilegied mode */
  2079. /* Exceptions must be checked, according to v7 ref manual */
  2080. CHECK_VFP_ENABLED;
  2081. vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
  2082. VMSR(cpu, inst_cream->reg, inst_cream->Rd);
  2083. }
  2084. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2085. INC_PC(sizeof(vmsr_inst));
  2086. FETCH_INST;
  2087. GOTO_NEXT_INST;
  2088. }
  2089. #endif
  2090. #ifdef VFP_DYNCOM_TABLE
  2091. DYNCOM_FILL_ACTION(vmsr),
  2092. #endif
  2093. #ifdef VFP_DYNCOM_TAG
  2094. int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2095. {
  2096. int instr_size = INSTR_SIZE;
  2097. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2098. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  2099. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  2100. return instr_size;
  2101. }
  2102. #endif
  2103. #ifdef VFP_DYNCOM_TRANS
  2104. int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2105. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2106. //arch_arm_undef(cpu, bb, instr);
  2107. DBG("VMSR :");
  2108. if(RD == 15) {
  2109. printf("in %s is not implementation.\n", __FUNCTION__);
  2110. exit(-1);
  2111. }
  2112. Value *data = NULL;
  2113. int reg = RN;
  2114. int Rt = RD;
  2115. if (reg == 1)
  2116. {
  2117. LET(VFP_FPSCR, R(Rt));
  2118. DBG("\tflags <= fpscr\n");
  2119. }
  2120. else
  2121. {
  2122. switch (reg)
  2123. {
  2124. case 8:
  2125. LET(VFP_FPEXC, R(Rt));
  2126. DBG("\tfpexc <= r%d \n", Rt);
  2127. break;
  2128. default:
  2129. DBG("\tSUBARCHITECTURE DEFINED\n");
  2130. break;
  2131. }
  2132. }
  2133. return No_exp;
  2134. }
  2135. #endif
  2136. /* ----------------------------------------------------------------------- */
  2137. /* VMOVBRC register to scalar */
  2138. /* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */
  2139. /* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
  2140. #ifdef VFP_INTERPRETER_STRUCT
  2141. typedef struct _vmovbrc_inst {
  2142. unsigned int esize;
  2143. unsigned int index;
  2144. unsigned int d;
  2145. unsigned int t;
  2146. } vmovbrc_inst;
  2147. #endif
  2148. #ifdef VFP_INTERPRETER_TRANS
  2149. ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
  2150. {
  2151. VFP_DEBUG_TRANSLATE;
  2152. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst));
  2153. vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
  2154. inst_base->cond = BITS(inst, 28, 31);
  2155. inst_base->idx = index;
  2156. inst_base->br = NON_BRANCH;
  2157. inst_base->load_r15 = 0;
  2158. inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
  2159. inst_cream->t = BITS(inst, 12, 15);
  2160. /* VFP variant of instruction */
  2161. inst_cream->esize = 32;
  2162. inst_cream->index = BIT(inst, 21);
  2163. return inst_base;
  2164. }
  2165. #endif
  2166. #ifdef VFP_INTERPRETER_IMPL
  2167. VMOVBRC_INST:
  2168. {
  2169. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2170. CHECK_VFP_ENABLED;
  2171. vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
  2172. VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
  2173. }
  2174. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2175. INC_PC(sizeof(vmovbrc_inst));
  2176. FETCH_INST;
  2177. GOTO_NEXT_INST;
  2178. }
  2179. #endif
  2180. #ifdef VFP_DYNCOM_TABLE
  2181. DYNCOM_FILL_ACTION(vmovbrc),
  2182. #endif
  2183. #ifdef VFP_DYNCOM_TAG
  2184. int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2185. {
  2186. int instr_size = INSTR_SIZE;
  2187. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2188. arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  2189. return instr_size;
  2190. }
  2191. #endif
  2192. #ifdef VFP_DYNCOM_TRANS
  2193. int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2194. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2195. arch_arm_undef(cpu, bb, instr);
  2196. return No_exp;
  2197. }
  2198. #endif
  2199. /* ----------------------------------------------------------------------- */
  2200. /* VMRS */
  2201. /* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */
  2202. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
  2203. #ifdef VFP_INTERPRETER_STRUCT
  2204. typedef struct _vmrs_inst {
  2205. unsigned int reg;
  2206. unsigned int Rt;
  2207. } vmrs_inst;
  2208. #endif
  2209. #ifdef VFP_INTERPRETER_TRANS
  2210. ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
  2211. {
  2212. VFP_DEBUG_TRANSLATE;
  2213. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst));
  2214. vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
  2215. inst_base->cond = BITS(inst, 28, 31);
  2216. inst_base->idx = index;
  2217. inst_base->br = NON_BRANCH;
  2218. inst_base->load_r15 = 0;
  2219. inst_cream->reg = BITS(inst, 16, 19);
  2220. inst_cream->Rt = BITS(inst, 12, 15);
  2221. return inst_base;
  2222. }
  2223. #endif
  2224. #ifdef VFP_INTERPRETER_IMPL
  2225. VMRS_INST:
  2226. {
  2227. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2228. /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled,
  2229. and in privilegied mode */
  2230. /* Exceptions must be checked, according to v7 ref manual */
  2231. CHECK_VFP_ENABLED;
  2232. vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
  2233. DBG("VMRS :");
  2234. if (inst_cream->reg == 1) /* FPSCR */
  2235. {
  2236. if (inst_cream->Rt != 15)
  2237. {
  2238. cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)];
  2239. DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
  2240. }
  2241. else
  2242. {
  2243. cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1;
  2244. cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1;
  2245. cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1;
  2246. cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1;
  2247. DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
  2248. }
  2249. }
  2250. else
  2251. {
  2252. switch (inst_cream->reg)
  2253. {
  2254. case 0:
  2255. cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)];
  2256. DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]);
  2257. break;
  2258. case 6:
  2259. /* MVFR1, VFPv3 only ? */
  2260. DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt);
  2261. break;
  2262. case 7:
  2263. /* MVFR0, VFPv3 only? */
  2264. DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt);
  2265. break;
  2266. case 8:
  2267. cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)];
  2268. DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]);
  2269. break;
  2270. default:
  2271. DBG("\tSUBARCHITECTURE DEFINED\n");
  2272. break;
  2273. }
  2274. }
  2275. }
  2276. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2277. INC_PC(sizeof(vmrs_inst));
  2278. FETCH_INST;
  2279. GOTO_NEXT_INST;
  2280. }
  2281. #endif
  2282. #ifdef VFP_DYNCOM_TABLE
  2283. DYNCOM_FILL_ACTION(vmrs),
  2284. #endif
  2285. #ifdef VFP_DYNCOM_TAG
  2286. int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2287. {
  2288. int instr_size = INSTR_SIZE;
  2289. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2290. DBG("\t\tin %s .\n", __FUNCTION__);
  2291. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  2292. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  2293. return instr_size;
  2294. }
  2295. #endif
  2296. #ifdef VFP_DYNCOM_TRANS
  2297. int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2298. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2299. //arch_arm_undef(cpu, bb, instr);
  2300. Value *data = NULL;
  2301. int reg = BITS(16, 19);;
  2302. int Rt = BITS(12, 15);
  2303. DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt);
  2304. if (reg == 1)
  2305. {
  2306. if (Rt != 15)
  2307. {
  2308. LET(Rt, R(VFP_FPSCR));
  2309. DBG("\tr%d <= fpscr\n", Rt);
  2310. }
  2311. else
  2312. {
  2313. //LET(Rt, R(VFP_FPSCR));
  2314. update_cond_from_fpscr(cpu, instr, bb, pc);
  2315. DBG("In %s, \tflags <= fpscr\n", __FUNCTION__);
  2316. }
  2317. }
  2318. else
  2319. {
  2320. switch (reg)
  2321. {
  2322. case 0:
  2323. LET(Rt, R(VFP_FPSID));
  2324. DBG("\tr%d <= fpsid\n", Rt);
  2325. break;
  2326. case 6:
  2327. /* MVFR1, VFPv3 only ? */
  2328. DBG("\tr%d <= MVFR1 unimplemented\n", Rt);
  2329. break;
  2330. case 7:
  2331. /* MVFR0, VFPv3 only? */
  2332. DBG("\tr%d <= MVFR0 unimplemented\n", Rt);
  2333. break;
  2334. case 8:
  2335. LET(Rt, R(VFP_FPEXC));
  2336. DBG("\tr%d <= fpexc\n", Rt);
  2337. break;
  2338. default:
  2339. DBG("\tSUBARCHITECTURE DEFINED\n");
  2340. break;
  2341. }
  2342. }
  2343. return No_exp;
  2344. }
  2345. #endif
  2346. /* ----------------------------------------------------------------------- */
  2347. /* VMOVBCR scalar to register */
  2348. /* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */
  2349. /* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */
  2350. #ifdef VFP_INTERPRETER_STRUCT
  2351. typedef struct _vmovbcr_inst {
  2352. unsigned int esize;
  2353. unsigned int index;
  2354. unsigned int d;
  2355. unsigned int t;
  2356. } vmovbcr_inst;
  2357. #endif
  2358. #ifdef VFP_INTERPRETER_TRANS
  2359. ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
  2360. {
  2361. VFP_DEBUG_TRANSLATE;
  2362. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst));
  2363. vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
  2364. inst_base->cond = BITS(inst, 28, 31);
  2365. inst_base->idx = index;
  2366. inst_base->br = NON_BRANCH;
  2367. inst_base->load_r15 = 0;
  2368. inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
  2369. inst_cream->t = BITS(inst, 12, 15);
  2370. /* VFP variant of instruction */
  2371. inst_cream->esize = 32;
  2372. inst_cream->index = BIT(inst, 21);
  2373. return inst_base;
  2374. }
  2375. #endif
  2376. #ifdef VFP_INTERPRETER_IMPL
  2377. VMOVBCR_INST:
  2378. {
  2379. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2380. CHECK_VFP_ENABLED;
  2381. vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
  2382. VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
  2383. }
  2384. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2385. INC_PC(sizeof(vmovbcr_inst));
  2386. FETCH_INST;
  2387. GOTO_NEXT_INST;
  2388. }
  2389. #endif
  2390. #ifdef VFP_DYNCOM_TABLE
  2391. DYNCOM_FILL_ACTION(vmovbcr),
  2392. #endif
  2393. #ifdef VFP_DYNCOM_TAG
  2394. int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2395. {
  2396. int instr_size = INSTR_SIZE;
  2397. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2398. arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  2399. return instr_size;
  2400. }
  2401. #endif
  2402. #ifdef VFP_DYNCOM_TRANS
  2403. int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2404. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2405. arch_arm_undef(cpu, bb, instr);
  2406. return No_exp;
  2407. }
  2408. #endif
  2409. /* ----------------------------------------------------------------------- */
  2410. /* MRRC / MCRR instructions */
  2411. /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
  2412. /* cond 1100 0100 Rt2- Rt-- copr opc1 CRm- MCRR */
  2413. /* ----------------------------------------------------------------------- */
  2414. /* VMOVBRRSS between 2 registers to 2 singles */
  2415. /* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */
  2416. /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
  2417. #ifdef VFP_INTERPRETER_STRUCT
  2418. typedef struct _vmovbrrss_inst {
  2419. unsigned int to_arm;
  2420. unsigned int t;
  2421. unsigned int t2;
  2422. unsigned int m;
  2423. } vmovbrrss_inst;
  2424. #endif
  2425. #ifdef VFP_INTERPRETER_TRANS
  2426. ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index)
  2427. {
  2428. VFP_DEBUG_TRANSLATE;
  2429. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst));
  2430. vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
  2431. inst_base->cond = BITS(inst, 28, 31);
  2432. inst_base->idx = index;
  2433. inst_base->br = NON_BRANCH;
  2434. inst_base->load_r15 = 0;
  2435. inst_cream->to_arm = BIT(inst, 20) == 1;
  2436. inst_cream->t = BITS(inst, 12, 15);
  2437. inst_cream->t2 = BITS(inst, 16, 19);
  2438. inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5);
  2439. return inst_base;
  2440. }
  2441. #endif
  2442. #ifdef VFP_INTERPRETER_IMPL
  2443. VMOVBRRSS_INST:
  2444. {
  2445. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2446. CHECK_VFP_ENABLED;
  2447. vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
  2448. VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
  2449. }
  2450. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2451. INC_PC(sizeof(vmovbrrss_inst));
  2452. FETCH_INST;
  2453. GOTO_NEXT_INST;
  2454. }
  2455. #endif
  2456. #ifdef VFP_DYNCOM_TABLE
  2457. DYNCOM_FILL_ACTION(vmovbrrss),
  2458. #endif
  2459. #ifdef VFP_DYNCOM_TAG
  2460. int DYNCOM_TAG(vmovbrrss)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2461. {
  2462. int instr_size = INSTR_SIZE;
  2463. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2464. arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  2465. return instr_size;
  2466. }
  2467. #endif
  2468. #ifdef VFP_DYNCOM_TRANS
  2469. int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2470. DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2471. arch_arm_undef(cpu, bb, instr);
  2472. return No_exp;
  2473. }
  2474. #endif
  2475. /* ----------------------------------------------------------------------- */
  2476. /* VMOVBRRD between 2 registers and 1 double */
  2477. /* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */
  2478. /* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
  2479. #ifdef VFP_INTERPRETER_STRUCT
  2480. typedef struct _vmovbrrd_inst {
  2481. unsigned int to_arm;
  2482. unsigned int t;
  2483. unsigned int t2;
  2484. unsigned int m;
  2485. } vmovbrrd_inst;
  2486. #endif
  2487. #ifdef VFP_INTERPRETER_TRANS
  2488. ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index)
  2489. {
  2490. VFP_DEBUG_TRANSLATE;
  2491. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
  2492. vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
  2493. inst_base->cond = BITS(inst, 28, 31);
  2494. inst_base->idx = index;
  2495. inst_base->br = NON_BRANCH;
  2496. inst_base->load_r15 = 0;
  2497. inst_cream->to_arm = BIT(inst, 20) == 1;
  2498. inst_cream->t = BITS(inst, 12, 15);
  2499. inst_cream->t2 = BITS(inst, 16, 19);
  2500. inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3);
  2501. return inst_base;
  2502. }
  2503. #endif
  2504. #ifdef VFP_INTERPRETER_IMPL
  2505. VMOVBRRD_INST:
  2506. {
  2507. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2508. CHECK_VFP_ENABLED;
  2509. vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
  2510. VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
  2511. &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
  2512. }
  2513. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2514. INC_PC(sizeof(vmovbrrd_inst));
  2515. FETCH_INST;
  2516. GOTO_NEXT_INST;
  2517. }
  2518. #endif
  2519. #ifdef VFP_DYNCOM_TABLE
  2520. DYNCOM_FILL_ACTION(vmovbrrd),
  2521. #endif
  2522. #ifdef VFP_DYNCOM_TAG
  2523. int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2524. {
  2525. int instr_size = INSTR_SIZE;
  2526. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2527. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  2528. if(instr >> 28 != 0xe)
  2529. *tag |= TAG_CONDITIONAL;
  2530. return instr_size;
  2531. }
  2532. #endif
  2533. #ifdef VFP_DYNCOM_TRANS
  2534. int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2535. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2536. //arch_arm_undef(cpu, bb, instr);
  2537. int to_arm = BIT(20) == 1;
  2538. int t = BITS(12, 15);
  2539. int t2 = BITS(16, 19);
  2540. int n = BIT(5)<<4 | BITS(0, 3);
  2541. if(to_arm){
  2542. LET(t, IBITCAST32(FR32(n * 2)));
  2543. LET(t2, IBITCAST32(FR32(n * 2 + 1)));
  2544. }
  2545. else{
  2546. LETFPS(n * 2, FPBITCAST32(R(t)));
  2547. LETFPS(n * 2 + 1, FPBITCAST32(R(t2)));
  2548. }
  2549. return No_exp;
  2550. }
  2551. #endif
  2552. /* ----------------------------------------------------------------------- */
  2553. /* LDC/STC between 2 registers and 1 double */
  2554. /* cond 110X XXX1 Rn-- CRd- copr imm- imm- LDC */
  2555. /* cond 110X XXX0 Rn-- CRd- copr imm8 imm8 STC */
  2556. /* ----------------------------------------------------------------------- */
  2557. /* VSTR */
  2558. /* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */
  2559. #ifdef VFP_INTERPRETER_STRUCT
  2560. typedef struct _vstr_inst {
  2561. unsigned int single;
  2562. unsigned int n;
  2563. unsigned int d;
  2564. unsigned int imm32;
  2565. unsigned int add;
  2566. } vstr_inst;
  2567. #endif
  2568. #ifdef VFP_INTERPRETER_TRANS
  2569. ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index)
  2570. {
  2571. VFP_DEBUG_TRANSLATE;
  2572. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst));
  2573. vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
  2574. inst_base->cond = BITS(inst, 28, 31);
  2575. inst_base->idx = index;
  2576. inst_base->br = NON_BRANCH;
  2577. inst_base->load_r15 = 0;
  2578. inst_cream->single = BIT(inst, 8) == 0;
  2579. inst_cream->add = BIT(inst, 23);
  2580. inst_cream->imm32 = BITS(inst, 0,7) << 2;
  2581. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  2582. inst_cream->n = BITS(inst, 16, 19);
  2583. return inst_base;
  2584. }
  2585. #endif
  2586. #ifdef VFP_INTERPRETER_IMPL
  2587. VSTR_INST:
  2588. {
  2589. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2590. CHECK_VFP_ENABLED;
  2591. vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
  2592. unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
  2593. addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
  2594. DBG("VSTR :\n");
  2595. if (inst_cream->single)
  2596. {
  2597. fault = check_address_validity(cpu, addr, &phys_addr, 0);
  2598. if (fault) goto MMU_EXCEPTION;
  2599. fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
  2600. if (fault) goto MMU_EXCEPTION;
  2601. DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d, cpu->ExtReg[inst_cream->d]);
  2602. }
  2603. else
  2604. {
  2605. fault = check_address_validity(cpu, addr, &phys_addr, 0);
  2606. if (fault) goto MMU_EXCEPTION;
  2607. /* Check endianness */
  2608. fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32);
  2609. if (fault) goto MMU_EXCEPTION;
  2610. fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
  2611. if (fault) goto MMU_EXCEPTION;
  2612. fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32);
  2613. if (fault) goto MMU_EXCEPTION;
  2614. DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, inst_cream->d*2+1, inst_cream->d*2, cpu->ExtReg[inst_cream->d*2+1], cpu->ExtReg[inst_cream->d*2]);
  2615. }
  2616. }
  2617. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2618. INC_PC(sizeof(vstr_inst));
  2619. FETCH_INST;
  2620. GOTO_NEXT_INST;
  2621. }
  2622. #endif
  2623. #ifdef VFP_DYNCOM_TABLE
  2624. DYNCOM_FILL_ACTION(vstr),
  2625. #endif
  2626. #ifdef VFP_DYNCOM_TAG
  2627. int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2628. {
  2629. int instr_size = INSTR_SIZE;
  2630. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  2631. DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
  2632. *tag |= TAG_NEW_BB;
  2633. if(instr >> 28 != 0xe)
  2634. *tag |= TAG_CONDITIONAL;
  2635. return instr_size;
  2636. }
  2637. #endif
  2638. #ifdef VFP_DYNCOM_TRANS
  2639. int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2640. int single = BIT(8) == 0;
  2641. int add = BIT(23);
  2642. int imm32 = BITS(0,7) << 2;
  2643. int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
  2644. int n = BITS(16, 19);
  2645. Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n);
  2646. Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32));
  2647. DBG("VSTR :\n");
  2648. //if(single)
  2649. // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap);
  2650. //else
  2651. // bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap);
  2652. //Value* phys_addr;
  2653. if(single){
  2654. #if 0
  2655. phys_addr = get_phys_addr(cpu, bb, Addr, 0);
  2656. bb = cpu->dyncom_engine->bb;
  2657. arch_write_memory(cpu, bb, phys_addr, RSPR(d), 32);
  2658. #endif
  2659. //memory_write(cpu, bb, Addr, RSPR(d), 32);
  2660. memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32);
  2661. bb = cpu->dyncom_engine->bb;
  2662. }
  2663. else{
  2664. #if 0
  2665. phys_addr = get_phys_addr(cpu, bb, Addr, 0);
  2666. bb = cpu->dyncom_engine->bb;
  2667. arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2), 32);
  2668. #endif
  2669. //memory_write(cpu, bb, Addr, RSPR(d * 2), 32);
  2670. memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32);
  2671. bb = cpu->dyncom_engine->bb;
  2672. #if 0
  2673. phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
  2674. bb = cpu->dyncom_engine->bb;
  2675. arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2 + 1), 32);
  2676. #endif
  2677. //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32);
  2678. memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32);
  2679. bb = cpu->dyncom_engine->bb;
  2680. }
  2681. return No_exp;
  2682. }
  2683. #endif
  2684. /* ----------------------------------------------------------------------- */
  2685. /* VPUSH */
  2686. /* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */
  2687. #ifdef VFP_INTERPRETER_STRUCT
  2688. typedef struct _vpush_inst {
  2689. unsigned int single;
  2690. unsigned int d;
  2691. unsigned int imm32;
  2692. unsigned int regs;
  2693. } vpush_inst;
  2694. #endif
  2695. #ifdef VFP_INTERPRETER_TRANS
  2696. ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index)
  2697. {
  2698. VFP_DEBUG_TRANSLATE;
  2699. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
  2700. vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
  2701. inst_base->cond = BITS(inst, 28, 31);
  2702. inst_base->idx = index;
  2703. inst_base->br = NON_BRANCH;
  2704. inst_base->load_r15 = 0;
  2705. inst_cream->single = BIT(inst, 8) == 0;
  2706. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  2707. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  2708. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  2709. return inst_base;
  2710. }
  2711. #endif
  2712. #ifdef VFP_INTERPRETER_IMPL
  2713. VPUSH_INST:
  2714. {
  2715. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2716. CHECK_VFP_ENABLED;
  2717. int i;
  2718. vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
  2719. DBG("VPUSH :\n");
  2720. addr = cpu->Reg[R13] - inst_cream->imm32;
  2721. for (i = 0; i < inst_cream->regs; i++)
  2722. {
  2723. if (inst_cream->single)
  2724. {
  2725. fault = check_address_validity(cpu, addr, &phys_addr, 0);
  2726. if (fault) goto MMU_EXCEPTION;
  2727. fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
  2728. if (fault) goto MMU_EXCEPTION;
  2729. DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
  2730. addr += 4;
  2731. }
  2732. else
  2733. {
  2734. /* Careful of endianness, little by default */
  2735. fault = check_address_validity(cpu, addr, &phys_addr, 0);
  2736. if (fault) goto MMU_EXCEPTION;
  2737. fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
  2738. if (fault) goto MMU_EXCEPTION;
  2739. fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
  2740. if (fault) goto MMU_EXCEPTION;
  2741. fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
  2742. if (fault) goto MMU_EXCEPTION;
  2743. DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
  2744. addr += 8;
  2745. }
  2746. }
  2747. DBG("\tsp[%x]", cpu->Reg[R13]);
  2748. cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32;
  2749. DBG("=>[%x]\n", cpu->Reg[R13]);
  2750. }
  2751. cpu->Reg[15] += GET_INST_SIZE(cpu);
  2752. INC_PC(sizeof(vpush_inst));
  2753. FETCH_INST;
  2754. GOTO_NEXT_INST;
  2755. }
  2756. #endif
  2757. #ifdef VFP_DYNCOM_TABLE
  2758. DYNCOM_FILL_ACTION(vpush),
  2759. #endif
  2760. #ifdef VFP_DYNCOM_TAG
  2761. int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2762. {
  2763. int instr_size = INSTR_SIZE;
  2764. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  2765. DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
  2766. *tag |= TAG_NEW_BB;
  2767. if(instr >> 28 != 0xe)
  2768. *tag |= TAG_CONDITIONAL;
  2769. return instr_size;
  2770. }
  2771. #endif
  2772. #ifdef VFP_DYNCOM_TRANS
  2773. int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2774. int single = BIT(8) == 0;
  2775. int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
  2776. int imm32 = BITS(0, 7)<<2;
  2777. int regs = (single ? BITS(0, 7) : BITS(1, 7));
  2778. DBG("\t\tin %s \n", __FUNCTION__);
  2779. Value* Addr = SUB(R(13), CONST(imm32));
  2780. //if(single)
  2781. // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
  2782. //else
  2783. // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
  2784. //Value* phys_addr;
  2785. int i;
  2786. for (i = 0; i < regs; i++)
  2787. {
  2788. if (single)
  2789. {
  2790. //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
  2791. #if 0
  2792. phys_addr = get_phys_addr(cpu, bb, Addr, 0);
  2793. bb = cpu->dyncom_engine->bb;
  2794. arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32);
  2795. #endif
  2796. //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
  2797. memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32);
  2798. bb = cpu->dyncom_engine->bb;
  2799. Addr = ADD(Addr, CONST(4));
  2800. }
  2801. else
  2802. {
  2803. /* Careful of endianness, little by default */
  2804. #if 0
  2805. phys_addr = get_phys_addr(cpu, bb, Addr, 0);
  2806. bb = cpu->dyncom_engine->bb;
  2807. arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32);
  2808. #endif
  2809. //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
  2810. memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32);
  2811. bb = cpu->dyncom_engine->bb;
  2812. #if 0
  2813. phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
  2814. bb = cpu->dyncom_engine->bb;
  2815. arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32);
  2816. #endif
  2817. //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
  2818. memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
  2819. bb = cpu->dyncom_engine->bb;
  2820. Addr = ADD(Addr, CONST(8));
  2821. }
  2822. }
  2823. LET(13, SUB(R(13), CONST(imm32)));
  2824. return No_exp;
  2825. }
  2826. #endif
  2827. /* ----------------------------------------------------------------------- */
  2828. /* VSTM */
  2829. /* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */
  2830. #ifdef VFP_INTERPRETER_STRUCT
  2831. typedef struct _vstm_inst {
  2832. unsigned int single;
  2833. unsigned int add;
  2834. unsigned int wback;
  2835. unsigned int d;
  2836. unsigned int n;
  2837. unsigned int imm32;
  2838. unsigned int regs;
  2839. } vstm_inst;
  2840. #endif
  2841. #ifdef VFP_INTERPRETER_TRANS
  2842. ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
  2843. {
  2844. VFP_DEBUG_TRANSLATE;
  2845. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst));
  2846. vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
  2847. inst_base->cond = BITS(inst, 28, 31);
  2848. inst_base->idx = index;
  2849. inst_base->br = NON_BRANCH;
  2850. inst_base->load_r15 = 0;
  2851. inst_cream->single = BIT(inst, 8) == 0;
  2852. inst_cream->add = BIT(inst, 23);
  2853. inst_cream->wback = BIT(inst, 21);
  2854. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  2855. inst_cream->n = BITS(inst, 16, 19);
  2856. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  2857. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  2858. return inst_base;
  2859. }
  2860. #endif
  2861. #ifdef VFP_INTERPRETER_IMPL
  2862. VSTM_INST: /* encoding 1 */
  2863. {
  2864. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  2865. CHECK_VFP_ENABLED;
  2866. int i;
  2867. vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
  2868. addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
  2869. DBG("VSTM : addr[%x]\n", addr);
  2870. for (i = 0; i < inst_cream->regs; i++)
  2871. {
  2872. if (inst_cream->single)
  2873. {
  2874. fault = check_address_validity(cpu, addr, &phys_addr, 0);
  2875. if (fault) goto MMU_EXCEPTION;
  2876. fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
  2877. if (fault) goto MMU_EXCEPTION;
  2878. DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
  2879. addr += 4;
  2880. }
  2881. else
  2882. {
  2883. /* Careful of endianness, little by default */
  2884. fault = check_address_validity(cpu, addr, &phys_addr, 0);
  2885. if (fault) goto MMU_EXCEPTION;
  2886. fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
  2887. if (fault) goto MMU_EXCEPTION;
  2888. fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
  2889. if (fault) goto MMU_EXCEPTION;
  2890. fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
  2891. if (fault) goto MMU_EXCEPTION;
  2892. DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
  2893. addr += 8;
  2894. }
  2895. }
  2896. if (inst_cream->wback){
  2897. cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
  2898. cpu->Reg[inst_cream->n] - inst_cream->imm32);
  2899. DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]);
  2900. }
  2901. }
  2902. cpu->Reg[15] += 4;
  2903. INC_PC(sizeof(vstm_inst));
  2904. FETCH_INST;
  2905. GOTO_NEXT_INST;
  2906. }
  2907. #endif
  2908. #ifdef VFP_DYNCOM_TABLE
  2909. DYNCOM_FILL_ACTION(vstm),
  2910. #endif
  2911. #ifdef VFP_DYNCOM_TAG
  2912. int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  2913. {
  2914. int instr_size = INSTR_SIZE;
  2915. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  2916. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  2917. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  2918. DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
  2919. *tag |= TAG_NEW_BB;
  2920. if(instr >> 28 != 0xe)
  2921. *tag |= TAG_CONDITIONAL;
  2922. return instr_size;
  2923. }
  2924. #endif
  2925. #ifdef VFP_DYNCOM_TRANS
  2926. int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  2927. //arch_arm_undef(cpu, bb, instr);
  2928. int single = BIT(8) == 0;
  2929. int add = BIT(23);
  2930. int wback = BIT(21);
  2931. int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4);
  2932. int n = BITS(16, 19);
  2933. int imm32 = BITS(0, 7)<<2;
  2934. int regs = single ? BITS(0, 7) : BITS(1, 7);
  2935. Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
  2936. DBG("VSTM \n");
  2937. //if(single)
  2938. // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
  2939. //else
  2940. // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
  2941. int i;
  2942. Value* phys_addr;
  2943. for (i = 0; i < regs; i++)
  2944. {
  2945. if (single)
  2946. {
  2947. //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
  2948. /* if R(i) is R15? */
  2949. #if 0
  2950. phys_addr = get_phys_addr(cpu, bb, Addr, 0);
  2951. bb = cpu->dyncom_engine->bb;
  2952. arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32);
  2953. #endif
  2954. //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
  2955. memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32);
  2956. bb = cpu->dyncom_engine->bb;
  2957. //if (fault) goto MMU_EXCEPTION;
  2958. //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
  2959. Addr = ADD(Addr, CONST(4));
  2960. }
  2961. else
  2962. {
  2963. //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
  2964. #if 0
  2965. phys_addr = get_phys_addr(cpu, bb, Addr, 0);
  2966. bb = cpu->dyncom_engine->bb;
  2967. arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32);
  2968. #endif
  2969. //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
  2970. memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32);
  2971. bb = cpu->dyncom_engine->bb;
  2972. //if (fault) goto MMU_EXCEPTION;
  2973. //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
  2974. #if 0
  2975. phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
  2976. bb = cpu->dyncom_engine->bb;
  2977. arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32);
  2978. #endif
  2979. //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
  2980. memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
  2981. bb = cpu->dyncom_engine->bb;
  2982. //if (fault) goto MMU_EXCEPTION;
  2983. //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
  2984. //addr += 8;
  2985. Addr = ADD(Addr, CONST(8));
  2986. }
  2987. }
  2988. if (wback){
  2989. //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
  2990. // cpu->Reg[n] - imm32);
  2991. LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
  2992. DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
  2993. }
  2994. return No_exp;
  2995. }
  2996. #endif
  2997. /* ----------------------------------------------------------------------- */
  2998. /* VPOP */
  2999. /* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */
  3000. #ifdef VFP_INTERPRETER_STRUCT
  3001. typedef struct _vpop_inst {
  3002. unsigned int single;
  3003. unsigned int d;
  3004. unsigned int imm32;
  3005. unsigned int regs;
  3006. } vpop_inst;
  3007. #endif
  3008. #ifdef VFP_INTERPRETER_TRANS
  3009. ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index)
  3010. {
  3011. VFP_DEBUG_TRANSLATE;
  3012. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst));
  3013. vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
  3014. inst_base->cond = BITS(inst, 28, 31);
  3015. inst_base->idx = index;
  3016. inst_base->br = NON_BRANCH;
  3017. inst_base->load_r15 = 0;
  3018. inst_cream->single = BIT(inst, 8) == 0;
  3019. inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4));
  3020. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  3021. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  3022. return inst_base;
  3023. }
  3024. #endif
  3025. #ifdef VFP_INTERPRETER_IMPL
  3026. VPOP_INST:
  3027. {
  3028. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  3029. CHECK_VFP_ENABLED;
  3030. int i;
  3031. unsigned int value1, value2;
  3032. vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
  3033. DBG("VPOP :\n");
  3034. addr = cpu->Reg[R13];
  3035. for (i = 0; i < inst_cream->regs; i++)
  3036. {
  3037. if (inst_cream->single)
  3038. {
  3039. fault = check_address_validity(cpu, addr, &phys_addr, 1);
  3040. if (fault) goto MMU_EXCEPTION;
  3041. fault = interpreter_read_memory(addr, phys_addr, value1, 32);
  3042. if (fault) goto MMU_EXCEPTION;
  3043. DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, value1, addr);
  3044. cpu->ExtReg[inst_cream->d+i] = value1;
  3045. addr += 4;
  3046. }
  3047. else
  3048. {
  3049. /* Careful of endianness, little by default */
  3050. fault = check_address_validity(cpu, addr, &phys_addr, 1);
  3051. if (fault) goto MMU_EXCEPTION;
  3052. fault = interpreter_read_memory(addr, phys_addr, value1, 32);
  3053. if (fault) goto MMU_EXCEPTION;
  3054. fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
  3055. if (fault) goto MMU_EXCEPTION;
  3056. fault = interpreter_read_memory(addr + 4, phys_addr, value2, 32);
  3057. if (fault) goto MMU_EXCEPTION;
  3058. DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, value2, value1, addr+4, addr);
  3059. cpu->ExtReg[(inst_cream->d+i)*2] = value1;
  3060. cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2;
  3061. addr += 8;
  3062. }
  3063. }
  3064. DBG("\tsp[%x]", cpu->Reg[R13]);
  3065. cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32;
  3066. DBG("=>[%x]\n", cpu->Reg[R13]);
  3067. }
  3068. cpu->Reg[15] += GET_INST_SIZE(cpu);
  3069. INC_PC(sizeof(vpop_inst));
  3070. FETCH_INST;
  3071. GOTO_NEXT_INST;
  3072. }
  3073. #endif
  3074. #ifdef VFP_DYNCOM_TABLE
  3075. DYNCOM_FILL_ACTION(vpop),
  3076. #endif
  3077. #ifdef VFP_DYNCOM_TAG
  3078. int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  3079. {
  3080. int instr_size = INSTR_SIZE;
  3081. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  3082. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  3083. /* Should check if PC is destination register */
  3084. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  3085. DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
  3086. *tag |= TAG_NEW_BB;
  3087. if(instr >> 28 != 0xe)
  3088. *tag |= TAG_CONDITIONAL;
  3089. return instr_size;
  3090. }
  3091. #endif
  3092. #ifdef VFP_DYNCOM_TRANS
  3093. int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  3094. DBG("\t\tin %s instruction .\n", __FUNCTION__);
  3095. //arch_arm_undef(cpu, bb, instr);
  3096. int single = BIT(8) == 0;
  3097. int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
  3098. int imm32 = BITS(0, 7)<<2;
  3099. int regs = (single ? BITS(0, 7) : BITS(1, 7));
  3100. int i;
  3101. unsigned int value1, value2;
  3102. DBG("VPOP :\n");
  3103. Value* Addr = R(13);
  3104. Value* val;
  3105. //if(single)
  3106. // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
  3107. //else
  3108. // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
  3109. //Value* phys_addr;
  3110. for (i = 0; i < regs; i++)
  3111. {
  3112. if (single)
  3113. {
  3114. #if 0
  3115. phys_addr = get_phys_addr(cpu, bb, Addr, 1);
  3116. bb = cpu->dyncom_engine->bb;
  3117. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3118. #endif
  3119. memory_read(cpu, bb, Addr, 0, 32);
  3120. bb = cpu->dyncom_engine->bb;
  3121. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3122. LETFPS(d + i, FPBITCAST32(val));
  3123. Addr = ADD(Addr, CONST(4));
  3124. }
  3125. else
  3126. {
  3127. /* Careful of endianness, little by default */
  3128. #if 0
  3129. phys_addr = get_phys_addr(cpu, bb, Addr, 1);
  3130. bb = cpu->dyncom_engine->bb;
  3131. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3132. #endif
  3133. memory_read(cpu, bb, Addr, 0, 32);
  3134. bb = cpu->dyncom_engine->bb;
  3135. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3136. LETFPS((d + i) * 2, FPBITCAST32(val));
  3137. #if 0
  3138. phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
  3139. bb = cpu->dyncom_engine->bb;
  3140. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3141. #endif
  3142. memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32);
  3143. bb = cpu->dyncom_engine->bb;
  3144. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3145. LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
  3146. Addr = ADD(Addr, CONST(8));
  3147. }
  3148. }
  3149. LET(13, ADD(R(13), CONST(imm32)));
  3150. return No_exp;
  3151. }
  3152. #endif
  3153. /* ----------------------------------------------------------------------- */
  3154. /* VLDR */
  3155. /* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */
  3156. #ifdef VFP_INTERPRETER_STRUCT
  3157. typedef struct _vldr_inst {
  3158. unsigned int single;
  3159. unsigned int n;
  3160. unsigned int d;
  3161. unsigned int imm32;
  3162. unsigned int add;
  3163. } vldr_inst;
  3164. #endif
  3165. #ifdef VFP_INTERPRETER_TRANS
  3166. ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index)
  3167. {
  3168. VFP_DEBUG_TRANSLATE;
  3169. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst));
  3170. vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
  3171. inst_base->cond = BITS(inst, 28, 31);
  3172. inst_base->idx = index;
  3173. inst_base->br = NON_BRANCH;
  3174. inst_base->load_r15 = 0;
  3175. inst_cream->single = BIT(inst, 8) == 0;
  3176. inst_cream->add = BIT(inst, 23);
  3177. inst_cream->imm32 = BITS(inst, 0,7) << 2;
  3178. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  3179. inst_cream->n = BITS(inst, 16, 19);
  3180. return inst_base;
  3181. }
  3182. #endif
  3183. #ifdef VFP_INTERPRETER_IMPL
  3184. VLDR_INST:
  3185. {
  3186. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  3187. CHECK_VFP_ENABLED;
  3188. vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
  3189. unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
  3190. addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
  3191. DBG("VLDR :\n", addr);
  3192. if (inst_cream->single)
  3193. {
  3194. fault = check_address_validity(cpu, addr, &phys_addr, 1);
  3195. if (fault) goto MMU_EXCEPTION;
  3196. fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
  3197. if (fault) goto MMU_EXCEPTION;
  3198. DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d, cpu->ExtReg[inst_cream->d], addr);
  3199. }
  3200. else
  3201. {
  3202. unsigned int word1, word2;
  3203. fault = check_address_validity(cpu, addr, &phys_addr, 1);
  3204. if (fault) goto MMU_EXCEPTION;
  3205. fault = interpreter_read_memory(addr, phys_addr, word1, 32);
  3206. if (fault) goto MMU_EXCEPTION;
  3207. fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
  3208. if (fault) goto MMU_EXCEPTION;
  3209. fault = interpreter_read_memory(addr + 4, phys_addr, word2, 32);
  3210. if (fault) goto MMU_EXCEPTION;
  3211. /* Check endianness */
  3212. cpu->ExtReg[inst_cream->d*2] = word1;
  3213. cpu->ExtReg[inst_cream->d*2+1] = word2;
  3214. DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", inst_cream->d*2+1, inst_cream->d*2, word2, word1, addr+4, addr);
  3215. }
  3216. }
  3217. cpu->Reg[15] += GET_INST_SIZE(cpu);
  3218. INC_PC(sizeof(vldr_inst));
  3219. FETCH_INST;
  3220. GOTO_NEXT_INST;
  3221. }
  3222. #endif
  3223. #ifdef VFP_DYNCOM_TABLE
  3224. DYNCOM_FILL_ACTION(vldr),
  3225. #endif
  3226. #ifdef VFP_DYNCOM_TAG
  3227. int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  3228. {
  3229. int instr_size = INSTR_SIZE;
  3230. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  3231. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  3232. /* Should check if PC is destination register */
  3233. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  3234. DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
  3235. *tag |= TAG_NEW_BB;
  3236. if(instr >> 28 != 0xe)
  3237. *tag |= TAG_CONDITIONAL;
  3238. return instr_size;
  3239. }
  3240. #endif
  3241. #ifdef VFP_DYNCOM_TRANS
  3242. int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  3243. int single = BIT(8) == 0;
  3244. int add = BIT(23);
  3245. int wback = BIT(21);
  3246. int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
  3247. int n = BITS(16, 19);
  3248. int imm32 = BITS(0, 7)<<2;
  3249. int regs = (single ? BITS(0, 7) : BITS(1, 7));
  3250. Value* base = R(n);
  3251. DBG("\t\tin %s .\n", __FUNCTION__);
  3252. if(n == 15){
  3253. base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8));
  3254. }
  3255. Value* Addr = add ? (ADD(base, CONST(imm32))) : (SUB(base, CONST(imm32)));
  3256. //if(single)
  3257. // bb = arch_check_mm(cpu, bb, Addr, 4, 1, cpu->dyncom_engine->bb_trap);
  3258. //else
  3259. // bb = arch_check_mm(cpu, bb, Addr, 8, 1, cpu->dyncom_engine->bb_trap);
  3260. //Value* phys_addr;
  3261. Value* val;
  3262. if(single){
  3263. #if 0
  3264. phys_addr = get_phys_addr(cpu, bb, Addr, 1);
  3265. bb = cpu->dyncom_engine->bb;
  3266. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3267. #endif
  3268. memory_read(cpu, bb, Addr, 0, 32);
  3269. bb = cpu->dyncom_engine->bb;
  3270. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3271. //LETS(d, val);
  3272. LETFPS(d,FPBITCAST32(val));
  3273. }
  3274. else{
  3275. #if 0
  3276. phys_addr = get_phys_addr(cpu, bb, Addr, 1);
  3277. bb = cpu->dyncom_engine->bb;
  3278. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3279. #endif
  3280. memory_read(cpu, bb, Addr, 0, 32);
  3281. bb = cpu->dyncom_engine->bb;
  3282. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3283. //LETS(d * 2, val);
  3284. LETFPS(d * 2,FPBITCAST32(val));
  3285. #if 0
  3286. phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
  3287. bb = cpu->dyncom_engine->bb;
  3288. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3289. #endif
  3290. memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32);
  3291. bb = cpu->dyncom_engine->bb;
  3292. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3293. //LETS(d * 2 + 1, val);
  3294. LETFPS( d * 2 + 1,FPBITCAST32(val));
  3295. }
  3296. return No_exp;
  3297. }
  3298. #endif
  3299. /* ----------------------------------------------------------------------- */
  3300. /* VLDM */
  3301. /* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */
  3302. #ifdef VFP_INTERPRETER_STRUCT
  3303. typedef struct _vldm_inst {
  3304. unsigned int single;
  3305. unsigned int add;
  3306. unsigned int wback;
  3307. unsigned int d;
  3308. unsigned int n;
  3309. unsigned int imm32;
  3310. unsigned int regs;
  3311. } vldm_inst;
  3312. #endif
  3313. #ifdef VFP_INTERPRETER_TRANS
  3314. ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
  3315. {
  3316. VFP_DEBUG_TRANSLATE;
  3317. arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst));
  3318. vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
  3319. inst_base->cond = BITS(inst, 28, 31);
  3320. inst_base->idx = index;
  3321. inst_base->br = NON_BRANCH;
  3322. inst_base->load_r15 = 0;
  3323. inst_cream->single = BIT(inst, 8) == 0;
  3324. inst_cream->add = BIT(inst, 23);
  3325. inst_cream->wback = BIT(inst, 21);
  3326. inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
  3327. inst_cream->n = BITS(inst, 16, 19);
  3328. inst_cream->imm32 = BITS(inst, 0, 7)<<2;
  3329. inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
  3330. return inst_base;
  3331. }
  3332. #endif
  3333. #ifdef VFP_INTERPRETER_IMPL
  3334. VLDM_INST:
  3335. {
  3336. if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
  3337. CHECK_VFP_ENABLED;
  3338. int i;
  3339. vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
  3340. addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
  3341. DBG("VLDM : addr[%x]\n", addr);
  3342. for (i = 0; i < inst_cream->regs; i++)
  3343. {
  3344. if (inst_cream->single)
  3345. {
  3346. fault = check_address_validity(cpu, addr, &phys_addr, 1);
  3347. if (fault) goto MMU_EXCEPTION;
  3348. fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
  3349. if (fault) goto MMU_EXCEPTION;
  3350. DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, cpu->ExtReg[inst_cream->d+i], addr);
  3351. addr += 4;
  3352. }
  3353. else
  3354. {
  3355. /* Careful of endianness, little by default */
  3356. fault = check_address_validity(cpu, addr, &phys_addr, 1);
  3357. if (fault) goto MMU_EXCEPTION;
  3358. fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
  3359. if (fault) goto MMU_EXCEPTION;
  3360. fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
  3361. if (fault) goto MMU_EXCEPTION;
  3362. fault = interpreter_read_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
  3363. if (fault) goto MMU_EXCEPTION;
  3364. DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2], addr+4, addr);
  3365. addr += 8;
  3366. }
  3367. }
  3368. if (inst_cream->wback){
  3369. cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
  3370. cpu->Reg[inst_cream->n] - inst_cream->imm32);
  3371. DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]);
  3372. }
  3373. }
  3374. cpu->Reg[15] += GET_INST_SIZE(cpu);
  3375. INC_PC(sizeof(vldm_inst));
  3376. FETCH_INST;
  3377. GOTO_NEXT_INST;
  3378. }
  3379. #endif
  3380. #ifdef VFP_DYNCOM_TABLE
  3381. DYNCOM_FILL_ACTION(vldm),
  3382. #endif
  3383. #ifdef VFP_DYNCOM_TAG
  3384. int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
  3385. {
  3386. int instr_size = INSTR_SIZE;
  3387. //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
  3388. //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
  3389. arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
  3390. DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
  3391. *tag |= TAG_NEW_BB;
  3392. if(instr >> 28 != 0xe)
  3393. *tag |= TAG_CONDITIONAL;
  3394. return instr_size;
  3395. }
  3396. #endif
  3397. #ifdef VFP_DYNCOM_TRANS
  3398. int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
  3399. int single = BIT(8) == 0;
  3400. int add = BIT(23);
  3401. int wback = BIT(21);
  3402. int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|BIT(22)<<4;
  3403. int n = BITS(16, 19);
  3404. int imm32 = BITS(0, 7)<<2;
  3405. int regs = single ? BITS(0, 7) : BITS(1, 7);
  3406. Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
  3407. //if(single)
  3408. // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
  3409. //else
  3410. // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
  3411. DBG("VLDM \n");
  3412. int i;
  3413. //Value* phys_addr;
  3414. Value* val;
  3415. for (i = 0; i < regs; i++)
  3416. {
  3417. if (single)
  3418. {
  3419. //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
  3420. /* if R(i) is R15? */
  3421. #if 0
  3422. phys_addr = get_phys_addr(cpu, bb, Addr, 1);
  3423. bb = cpu->dyncom_engine->bb;
  3424. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3425. #endif
  3426. memory_read(cpu, bb, Addr, 0, 32);
  3427. bb = cpu->dyncom_engine->bb;
  3428. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3429. //LETS(d + i, val);
  3430. LETFPS(d + i, FPBITCAST32(val));
  3431. //if (fault) goto MMU_EXCEPTION;
  3432. //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
  3433. Addr = ADD(Addr, CONST(4));
  3434. }
  3435. else
  3436. {
  3437. #if 0
  3438. phys_addr = get_phys_addr(cpu, bb, Addr, 1);
  3439. bb = cpu->dyncom_engine->bb;
  3440. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3441. #endif
  3442. memory_read(cpu, bb, Addr, 0, 32);
  3443. bb = cpu->dyncom_engine->bb;
  3444. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3445. LETFPS((d + i) * 2, FPBITCAST32(val));
  3446. #if 0
  3447. phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
  3448. bb = cpu->dyncom_engine->bb;
  3449. val = arch_read_memory(cpu,bb,phys_addr,0,32);
  3450. #endif
  3451. memory_read(cpu, bb, Addr, 0, 32);
  3452. bb = cpu->dyncom_engine->bb;
  3453. val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
  3454. LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
  3455. //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
  3456. //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
  3457. //addr += 8;
  3458. Addr = ADD(Addr, CONST(8));
  3459. }
  3460. }
  3461. if (wback){
  3462. //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
  3463. // cpu->Reg[n] - imm32);
  3464. LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
  3465. DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
  3466. }
  3467. return No_exp;
  3468. }
  3469. #endif