12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <mach.h>
- #define Extern extern
- #include "power.h"
- void add(ulong);
- void addc(ulong);
- void adde(ulong);
- void addme(ulong);
- void addze(ulong);
- void and(ulong);
- void andc(ulong);
- void cmp(ulong);
- void cmpl(ulong);
- void cntlzw(ulong);
- void dcbf(ulong);
- void dcbi(ulong);
- void dcbst(ulong);
- void dcbt(ulong);
- void dcbtst(ulong);
- void dcbz(ulong);
- void divw(ulong);
- void divwu(ulong);
- void eciwx(ulong);
- void ecowx(ulong);
- void eieio(ulong);
- void eqv(ulong);
- void extsb(ulong);
- void extsh(ulong);
- void icbi(ulong);
- void lbzx(ulong);
- void lfdx(ulong);
- void lfsx(ulong);
- void lhax(ulong);
- void lhbrx(ulong);
- void lhzx(ulong);
- void lswi(ulong);
- void lswx(ulong);
- void lwarx(ulong);
- void lwbrx(ulong);
- void lwzx(ulong);
- void mcrxr(ulong);
- void mfcr(ulong);
- void mfmsr(ulong);
- void mfpmr(ulong);
- void mfspr(ulong);
- void mfsr(ulong);
- void mfsrin(ulong);
- void mftb(ulong);
- void mftbu(ulong);
- void mspr(ulong);
- void mtcrf(ulong);
- void mtmsr(ulong);
- void mtpmr(ulong);
- void mtspr(ulong);
- void mtsr(ulong);
- void mtsrin(ulong);
- void mttb(ulong);
- void mttbu(ulong);
- void mulhw(ulong);
- void mulhwu(ulong);
- void mullw(ulong);
- void nand(ulong);
- void neg(ulong);
- void nor(ulong);
- void or(ulong);
- void orc(ulong);
- void slbia(ulong);
- void slbia(ulong);
- void slw(ulong);
- void sraw(ulong);
- void srawi(ulong);
- void srw(ulong);
- void stbx(ulong);
- void stfdx(ulong);
- void stfiwx(ulong);
- void stfsx(ulong);
- void sthbrx(ulong);
- void sthx(ulong);
- void stswi(ulong);
- void stswx(ulong);
- void stwbrx(ulong);
- void stwcx(ulong);
- void stwx(ulong);
- void subf(ulong);
- void subfc(ulong);
- void subfe(ulong);
- void subfme(ulong);
- void subfze(ulong);
- void sync(ulong);
- void tlbie(ulong);
- void tw(ulong);
- void xor(ulong);
- Inst op31[] = {
- [0] {cmp, "cmp", Iarith},
- [4] {tw, "tw", Iarith},
- [8] {subfc, "subfc", Iarith},
- [10] {addc, "addc", Iarith},
- [11] {mulhwu, "mulhwu", Iarith},
- [19] {mfcr, "mfcr", Iarith},
- [20] {lwarx, "lwarx", Iload},
- [23] {lwzx, "lwzx", Iload},
- [24] {slw, "slw", Ilog},
- [26] {cntlzw, "cntlzw", Ilog},
- [28] {and, "and", Ilog},
- [32] {cmpl, "cmpl", Iarith},
- [40] {subf, "subf", Iarith},
- [54] {dcbst, "dcbst", Icontrol},
- [55] {lwzx, "lwzux", Iload},
- [60] {andc, "andc", Ilog},
- [75] {mulhw, "mulhw", Iarith},
- [83] {0, "mfmsr", Icontrol},
- [86] {dcbf, "dcbf", Icontrol},
- [87] {lbzx, "lbzx", Iload},
- [104] {neg, "neg", Iarith},
- [115] {0, "mfpmr", Iarith},
- [119] {lbzx, "lbzux", Iload},
- [124] {nor, "nor", Iarith},
- [136] {subfe, "subfe", Iarith},
- [138] {adde, "adde", Iarith},
- [144] {mtcrf, "mtcrf", Ireg},
- [146] {0, "mtmsr", Icontrol},
- [150] {stwcx, "stwcx.", Istore},
- [151] {stwx, "stwx", Istore},
- [178] {0, "mtpmr", Icontrol},
- [183] {stwx, "stwux", Istore},
- [200] {subfze, "subfze", Iarith},
- [202] {addze, "addze", Iarith},
- [210] {0, "mtsr", Ireg},
- [215] {stbx, "stbx", Istore},
- [232] {subfme, "subfme", Iarith},
- [234] {addme, "addme", Iarith},
- [235] {mullw, "mullw", Iarith},
- [242] {0, "mtsrin", Ireg},
- [246] {dcbtst, "dcbtst", Icontrol},
- [247] {stbx, "stbux", Istore},
- [266] {add, "add", Iarith},
- [275] {0, "mftb", Icontrol},
- [278] {dcbt, "dcbt", Icontrol},
- [279] {lhzx, "lhzx", Iload},
- [284] {eqv, "eqv", Ilog},
- [306] {0, "tlbie", Icontrol},
- [307] {0, "mftbu", Icontrol},
- [310] {0, "eciwx", Icontrol},
- [311] {lhzx, "lhzux", Iload},
- [316] {xor, "xor", Ilog},
- [339] {mspr, "mfspr", Ireg},
- [343] {lhax, "lhax", Iload},
- [375] {lhax, "lhaux", Iload},
- [403] {0, "mttb", Icontrol},
- [407] {sthx, "sthx", Istore},
- [412] {orc, "orc", Ilog},
- [434] {0, "slbia", Iarith},
- [435] {0, "mttbu", Icontrol},
- [438] {0, "ecowx", Icontrol},
- [439] {sthx, "sthux", Istore},
- [444] {or, "or", Ilog},
- [459] {divwu, "divwu", Iarith},
- [467] {mspr, "mtspr", Ireg},
- [470] {0, "dcbi", Icontrol},
- [476] {nand, "nand", Ilog},
- [491] {divw, "divw", Iarith},
- [498] {0, "slbia", Icontrol},
- [512] {mcrxr, "mcrxr", Ireg},
- [533] {lswx, "lswx", Iload},
- [534] {lwbrx, "lwbrx", Iload},
- [535] {lfsx, "lfsx", Ifloat},
- [536] {srw, "srw", Ilog},
- [567] {lfsx, "lfsux", Ifloat},
- [595] {0, "mfsr", Iarith},
- [597] {lswi, "lswi", Iarith},
- [598] {sync, "sync", Iarith},
- [599] {lfdx, "lfdx", Ifloat},
- [631] {lfdx, "lfdux", Ifloat},
- [659] {0, "mfsrin", Ireg},
- [661] {stswx, "stswx", Istore},
- [662] {stwbrx, "stwbrx", Istore},
- [663] {stfsx, "stfsx", Istore},
- [695] {stfsx, "stfsux", Istore},
- [725] {stswi, "stswi", Istore},
- [727] {stfdx, "stfdx", Istore},
- [759] {stfdx, "stfdux", Istore},
- [790] {lhbrx, "lhbrx", Iload},
- [792] {sraw, "sraw", Ilog},
- [824] {srawi, "srawi", Ilog},
- [854] {0, "eieio", Icontrol},
- [918] {sthbrx, "sthbrx", Istore},
- [922] {extsh, "extsh", Iarith},
- [954] {extsb, "extsb", Iarith},
- [982] {icbi, "icbi", Icontrol},
- [983] {unimp, "stfiwx", Istore},
- [1014] {dcbz, "dcbz", Icontrol},
- };
- Inset ops31 = {op31, nelem(op31)};
- void
- mspr(ulong ir)
- {
- int rd, ra, rb;
- ulong *d;
- char *n;
- char buf[20];
- getarrr(ir);
- switch((rb<<5) | ra) {
- case 0:
- undef(ir); /* was mq */
- return;
- case 1:
- d = ®.xer; n = "xer";
- break;
- case 268:
- case 284:
- d = ®.tbl; n = "tbl";
- break;
- case 269:
- case 285:
- d = ®.tbu; n = "tbu";
- break;
- case 22:
- d = ®.dec; n = "dec";
- break;
- case 8:
- d = ®.lr; n = "lr";
- break;
- case 9:
- d = ®.ctr; n = "ctr";
- break;
- default:
- d = 0; sprint(n = buf, "spr%d", rd);
- break;
- }
- if(getxo(ir) == 339) {
- if(trace)
- itrace("%s\tr%d,%s", ci->name, rd, n);
- reg.r[rd] = *d;
- } else {
- if(trace)
- itrace("%s\t%s,r%d", ci->name, n, rd);
- *d = reg.r[rd];
- }
- }
- static void
- setcr(int d, long r)
- {
- int c;
- c = 0;
- if(reg.xer & XER_SO)
- c |= 1;
- if(r == 0)
- c |= 2;
- else if(r > 0)
- c |= 4;
- else
- c |= 8;
- reg.cr = (reg.cr & ~mkCR(d, 0xF)) | mkCR(d, c);
- }
- void
- addi(ulong ir)
- {
- int rd, ra;
- long imm;
- getairr(ir);
- if(trace) {
- if(ra)
- itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm);
- else
- itrace("li\tr%d,$0x%lux", rd, imm);
- }
- if(ra)
- imm += reg.r[ra];
- reg.r[rd] = imm;
- }
- void
- addis(ulong ir)
- {
- int rd, ra;
- long imm;
- getairr(ir);
- if(trace) {
- if(ra)
- itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm);
- else
- itrace("lis\tr%d,$0x%lux", rd, imm);
- }
- imm <<= 16;
- if(ra)
- imm += reg.r[ra];
- reg.r[rd] = imm;
- }
- void
- and(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = reg.r[rs] & reg.r[rb];
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- andc(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = reg.r[rs] & ~reg.r[rb];
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- andicc(ulong ir)
- {
- int rs, ra;
- ulong imm;
- getlirr(ir);
- reg.r[ra] = reg.r[rs] & imm;
- if(trace)
- itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
- setcr(0, reg.r[ra]);
- }
- void
- andiscc(ulong ir)
- {
- int rs, ra;
- ulong imm;
- getlirr(ir);
- reg.r[ra] = reg.r[rs] & (imm<<16);
- if(trace)
- itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
- setcr(0, reg.r[ra]);
- }
- void
- cmpli(ulong ir)
- {
- int rd, ra;
- ulong c;
- ulong imm, v;
- getairr(ir);
- imm &= 0xFFFF;
- if(rd & 3)
- undef(ir);
- rd >>= 2;
- v = reg.r[ra];
- c = 0;
- if(reg.xer & XER_SO)
- c |= CRSO;
- if(v < imm)
- c |= CRLT;
- else if(v == imm)
- c |= CREQ;
- else
- c |= CRGT;
- c >>= 28;
- reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
- if(trace)
- itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c);
- }
- void
- cmp(ulong ir)
- {
- int rd, ra, rb;
- ulong c;
- long va, vb;
- getarrr(ir);
- if(rd & 3)
- undef(ir);
- rd >>= 2;
- c = 0;
- if(reg.xer & XER_SO)
- c |= CRSO;
- va = reg.r[ra];
- vb = reg.r[rb];
- if(va < vb)
- c |= CRLT;
- else if(va == vb)
- c |= CREQ;
- else
- c |= CRGT;
- c >>= 28;
- reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
- if(trace)
- itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c);
- }
- void
- cmpi(ulong ir)
- {
- int rd, ra;
- ulong c;
- long imm, v;
- getairr(ir);
- if(rd & 3)
- undef(ir);
- rd >>= 2;
- v = reg.r[ra];
- c = 0;
- if(reg.xer & XER_SO)
- c |= CRSO;
- if(v < imm)
- c |= CRLT;
- else if(v == imm)
- c |= CREQ;
- else
- c |= CRGT;
- c >>= 28;
- reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
- if(trace)
- itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c);
- }
- void
- cmpl(ulong ir)
- {
- int rd, ra, rb;
- ulong c;
- ulong va, vb;
- getarrr(ir);
- if(rd & 3)
- undef(ir);
- rd >>= 2;
- c = 0;
- if(reg.xer & XER_SO)
- c |= CRSO;
- va = reg.r[ra];
- vb = reg.r[rb];
- if(va < vb)
- c |= CRLT;
- else if(va == vb)
- c |= CREQ;
- else
- c |= CRGT;
- c >>= 28;
- reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
- if(trace)
- itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c);
- }
- void
- cntlzw(ulong ir)
- {
- int rs, ra, rb, n;
- getlrrr(ir);
- if(rb)
- undef(ir);
- for(n=0; n<32 && (reg.r[rs] & (1L<<(31-n))) == 0; n++)
- ;
- reg.r[ra] = n;
- if(trace)
- itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- eqv(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = ~(reg.r[rs] ^ reg.r[rb]);
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- extsb(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- if(rb)
- undef(ir);
- reg.r[ra] = (schar)reg.r[rs];
- if(trace)
- itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- extsh(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- if(rb)
- undef(ir);
- reg.r[ra] = (short)reg.r[rs];
- if(trace)
- itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- add(ulong ir)
- {
- int rd, ra, rb;
- uvlong r;
- getarrr(ir);
- r = (uvlong)(ulong)reg.r[ra] + reg.r[rb];
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(r >> 16)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- addc(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- r = (uvlong)(ulong)reg.r[ra] + reg.r[rb];
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- adde(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- r = (uvlong)(ulong)reg.r[ra] + reg.r[rb] + (reg.xer&XER_CA)!=0;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- addic(ulong ir)
- {
- int rd, ra;
- long imm;
- ulong v;
- uvlong r;
- getairr(ir);
- r = (uvlong)(ulong)reg.r[ra] + imm;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- reg.r[rd] = (ulong)r;
- if(trace)
- itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
- }
- void
- addiccc(ulong ir)
- {
- int rd, ra;
- long imm;
- ulong v;
- uvlong r;
- getairr(ir);
- r = (uvlong)(ulong)reg.r[ra] + imm;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- reg.r[rd] = (ulong)r;
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
- }
- void
- addme(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- if(rb)
- undef(ir);
- r = (uvlong)(ulong)reg.r[ra] + 0xFFFFFFFF + (reg.xer&XER_CA)!=0;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
- }
- void
- addze(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- if(rb)
- undef(ir);
- r = (uvlong)(ulong)reg.r[ra] + (reg.xer&XER_CA)!=0;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
- }
- void
- divw(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- if(reg.r[rb] != 0 && ((ulong)reg.r[ra] != 0x80000000 || reg.r[rb] != -1))
- reg.r[rd] = reg.r[ra]/reg.r[rb];
- else if(ir & OE)
- reg.xer |= XER_SO | XER_OV;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- divwu(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- if(reg.r[rb] != 0)
- reg.r[rd] = (ulong)reg.r[ra]/(ulong)reg.r[rb];
- else if(ir & OE)
- reg.xer |= XER_SO | XER_OV;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- mcrxr(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- if(rd & 3 || ra != 0 || rb != 0 || ir & Rc)
- undef(ir);
- rd >>= 2;
- reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, reg.xer>>28);
- reg.xer &= ~(0xF<<28);
- }
- void
- mtcrf(ulong ir)
- {
- int rs, crm, i;
- ulong m;
- if(ir & ((1<<20)|(1<<11)|Rc))
- undef(ir);
- rs = (ir>>21)&0x1F;
- crm = (ir>>12)&0xFF;
- m = 0;
- for(i = 0x80; i; i >>= 1) {
- m <<= 4;
- if(crm & i)
- m |= 0xF;
- }
- reg.cr = (reg.cr & ~m) | (reg.r[rs] & m);
- }
- void
- mfcr(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- if(ra != 0 || rb != 0 || ir & Rc)
- undef(ir);
- reg.r[rd] = reg.cr;
- }
- void
- mulhw(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- reg.r[rd] = ((vlong)(long)reg.r[ra]*(long)reg.r[rb])>>32;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
- /* BUG: doesn't set OV */
- }
- void
- mulhwu(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- reg.r[rd] = ((uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb])>>32;
- if(ir & Rc)
- setcr(0, reg.r[rd]); /* not sure whether CR setting is signed or unsigned */
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
- /* BUG: doesn't set OV */
- }
- void
- mullw(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb];
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
- /* BUG: doesn't set OV */
- }
- void
- mulli(ulong ir)
- {
- int rd, ra;
- long imm;
- getairr(ir);
- reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)imm;
- if(trace)
- itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
- }
- void
- nand(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = ~(reg.r[rs] & reg.r[rb]);
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- }
- void
- neg(ulong ir)
- {
- int rd, ra, rb;
- getarrr(ir);
- if(rb)
- undef(ir);
- if(ir & OE)
- reg.xer &= ~XER_OV;
- if((ulong)reg.r[ra] == 0x80000000) {
- if(ir & OE)
- reg.xer |= XER_SO | XER_OV;
- reg.r[rd] = reg.r[ra];
- } else
- reg.r[rd] = -reg.r[ra];
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- }
- void
- nor(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = ~(reg.r[rs] | reg.r[rb]);
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- }
- void
- or(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = reg.r[rs] | reg.r[rb];
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace) {
- if(rs == rb)
- itrace("mr%s\tr%d,r%d", ir&1?".":"", ra, rs);
- else
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- }
- }
- void
- orc(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = reg.r[rs] | ~reg.r[rb];
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- }
- void
- ori(ulong ir)
- {
- int rs, ra;
- ulong imm;
- getlirr(ir);
- reg.r[ra] = reg.r[rs] | imm;
- if(trace)
- itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
- }
- void
- oris(ulong ir)
- {
- int rs, ra;
- ulong imm;
- getlirr(ir);
- reg.r[ra] = reg.r[rs] | (imm<<16);
- if(trace)
- itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
- }
- static ulong
- mkmask(int mb, int me)
- {
- int i;
- ulong v;
- if(mb > me)
- return mkmask(0, me) | mkmask(mb, 31);
- v = 0;
- for(i=mb; i<=me; i++)
- v |= 1L << (31-i); /* don't need a loop, but i'm lazy */
- return v;
- }
- static ulong
- rotl(ulong v, int sh)
- {
- if(sh == 0)
- return v;
- return (v<<sh) | (v>>(32-sh));
- }
- void
- rlwimi(ulong ir)
- {
- int rs, ra, rb, sh;
- ulong m;
- getlrrr(ir);
- sh = rb;
- m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
- reg.r[ra] = (reg.r[ra] & ~m) | (rotl(reg.r[rs], sh) & m);
- if(trace)
- itrace("%s\tr%d,r%d,%d,#%lux", ci->name, ra, rs, sh, m);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- rlwinm(ulong ir)
- {
- int rs, ra, rb, sh;
- ulong m;
- getlrrr(ir);
- sh = rb;
- m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
- reg.r[ra] = rotl(reg.r[rs], sh) & m;
- if(trace)
- itrace("%s%s\tr%d,r%d,%d,#%lux", ci->name, ir&Rc?".":"", ra, rs, sh, m);
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- }
- void
- rlwnm(ulong ir)
- {
- int rs, ra, rb, sh;
- ulong m;
- getlrrr(ir);
- sh = reg.r[rb] & 0x1F;
- m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
- reg.r[ra] = rotl(reg.r[rs], sh) & m;
- if(trace)
- itrace("%s\tr%d,r%d,r%d,#%lux", ci->name, ra, rs, rb, m);
- if(ir & 1)
- setcr(0, reg.r[ra]);
- }
- void
- slw(ulong ir)
- {
- int rs, ra, rb;
- long v;
- getlrrr(ir);
- v = reg.r[rb];
- if((v & 0x20) == 0) {
- v &= 0x1F;
- reg.r[ra] = (ulong)reg.r[rs] << v;
- } else
- reg.r[ra] = 0;
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- }
- void
- sraw(ulong ir)
- {
- int rs, ra, rb;
- long v;
- getlrrr(ir);
- v = reg.r[rb];
- if((v & 0x20) == 0) {
- v &= 0x1F;
- if(reg.r[rs]&SIGNBIT && v)
- reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1);
- else
- reg.r[ra] = reg.r[rs]>>v;
- } else
- reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0;
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- }
- void
- srawi(ulong ir)
- {
- int rs, ra, rb;
- long v;
- getlrrr(ir);
- v = rb;
- if((v & 0x20) == 0) {
- v &= 0x1F;
- if(reg.r[rs]&SIGNBIT && v)
- reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1);
- else
- reg.r[ra] = reg.r[rs]>>v;
- } else
- reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0;
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace)
- itrace("%s%s\tr%d,r%d,$%d", ci->name, ir&1?".":"", ra, rs, v);
- }
- void
- srw(ulong ir)
- {
- int rs, ra, rb;
- long v;
- getlrrr(ir);
- v = reg.r[rb];
- if((v & 0x20) == 0)
- reg.r[ra] = (ulong)reg.r[rs] >> (v&0x1F);
- else
- reg.r[ra] = 0;
- if(ir & Rc)
- setcr(0, reg.r[ra]);
- if(trace)
- itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
- }
- void
- subf(ulong ir)
- {
- int rd, ra, rb;
- uvlong r;
- getarrr(ir);
- r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + 1;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(r >> 16)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- subfc(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + 1;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- subfe(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + (reg.xer&XER_CA)!=0;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
- }
- void
- subfic(ulong ir)
- {
- int rd, ra;
- long imm;
- ulong v;
- uvlong r;
- getairr(ir);
- r = (uvlong)((ulong)~reg.r[ra]) + imm + 1;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- reg.r[rd] = (ulong)r;
- if(trace)
- itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
- }
- void
- subfme(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- if(rb)
- undef(ir);
- r = (uvlong)((ulong)~reg.r[ra]) + 0xFFFFFFFF + (reg.xer&XER_CA)!=0;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
- }
- void
- subfze(ulong ir)
- {
- int rd, ra, rb;
- ulong v;
- uvlong r;
- getarrr(ir);
- if(rb)
- undef(ir);
- r = (uvlong)((ulong)~reg.r[ra]) + (reg.xer&XER_CA)!=0;
- v = r>>32;
- reg.xer &= ~XER_CA;
- if(v)
- reg.xer |= XER_CA;
- if(ir & OE) {
- reg.xer &= ~XER_OV;
- if(v>>1)
- reg.xer |= XER_SO | XER_OV;
- }
- reg.r[rd] = (ulong)r;
- if(ir & Rc)
- setcr(0, reg.r[rd]);
- if(trace)
- itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
- }
- void
- xor(ulong ir)
- {
- int rs, ra, rb;
- getlrrr(ir);
- reg.r[ra] = reg.r[rs] ^ reg.r[rb];
- if(trace)
- itrace("%s\tr%d,r%d,r%d", ci->name, ra, rs, rb);
- }
- void
- xori(ulong ir)
- {
- int rs, ra;
- ulong imm;
- getlirr(ir);
- reg.r[ra] = reg.r[rs] ^ imm;
- if(trace)
- itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
- }
- void
- xoris(ulong ir)
- {
- int rs, ra;
- ulong imm;
- getlirr(ir);
- reg.r[ra] = reg.r[rs] ^ (imm<<16);
- if(trace)
- itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
- }
- void
- lwz(ulong ir)
- {
- ulong ea;
- int ra, rd, upd;
- long imm;
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- } else {
- if(upd)
- undef(ir);
- }
- if(trace)
- itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
- reg.r[rd] = getmem_w(ea);
- }
- void
- lwzx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, upd;
- getarrr(ir);
- ea = reg.r[rb];
- upd = getxo(ir)==55;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
- } else {
- if(upd)
- undef(ir);
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
- }
- reg.r[rd] = getmem_w(ea);
- }
- void
- lwarx(ulong ir)
- {
- lwzx(ir);
- }
- void
- lbz(ulong ir)
- {
- ulong ea;
- int ra, rd, upd;
- long imm;
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- } else {
- if(upd)
- undef(ir);
- }
- if(trace)
- itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
- reg.r[rd] = getmem_b(ea);
- }
- void
- lbzx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, upd;
- getarrr(ir);
- ea = reg.r[rb];
- upd = getxo(ir)==119;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
- } else {
- if(upd)
- undef(ir);
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
- }
- reg.r[rd] = getmem_b(ea);
- }
- void
- stw(ulong ir)
- {
- ulong ea;
- int ra, rd, upd;
- long imm;
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- } else {
- if(upd)
- undef(ir);
- }
- if(trace)
- itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, imm, ra, ea, reg.r[rd], reg.r[rd]);
- putmem_w(ea, reg.r[rd]);
- }
- void
- stwx(ulong ir)
- {
- ulong ea;
- int ra, rd, upd, rb;
- getarrr(ir);
- ea = reg.r[rb];
- upd = getxo(ir)==183;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
- ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]);
- } else {
- if(upd)
- undef(ir);
- if(trace)
- itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]);
- }
- putmem_w(ea, reg.r[rd]);
- }
- void
- stwcx(ulong ir)
- {
- ulong ea;
- int ra, rd, rb;
- if((ir & Rc) == 0)
- undef(ir);
- getarrr(ir);
- ea = reg.r[rb];
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
- ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]);
- } else {
- if(trace)
- itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]);
- }
- putmem_w(ea, reg.r[rd]); /* assume a reservation exists; store succeeded */
- setcr(0, 0);
- }
- void
- stb(ulong ir)
- {
- ulong ea;
- int ra, rd, upd, v;
- long imm;
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- } else {
- if(upd)
- undef(ir);
- }
- v = reg.r[rd] & 0xFF;
- if(trace)
- itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, imm, ra, ea, v, v);
- putmem_b(ea, v);
- }
- void
- stbx(ulong ir)
- {
- ulong ea;
- int ra, rd, upd, rb, v;
- getarrr(ir);
- ea = reg.r[rb];
- upd = getxo(ir)==247;
- v = reg.r[rd] & 0xFF;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
- ci->name, rd, ra, rb, ea, v, v);
- } else {
- if(upd)
- undef(ir);
- if(trace)
- itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, rb, ea, v, v);
- }
- putmem_b(ea, v);
- }
- void
- lhz(ulong ir)
- {
- ulong ea;
- int imm, ra, rd, upd;
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- } else {
- if(upd)
- undef(ir);
- }
- if(trace)
- itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
- reg.r[rd] = getmem_h(ea);
- }
- void
- lhzx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, upd;
- getarrr(ir);
- ea = reg.r[rb];
- upd = getxo(ir)==311;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
- } else {
- if(upd)
- undef(ir);
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
- }
- reg.r[rd] = getmem_h(ea);
- }
- void
- lha(ulong ir)
- {
- ulong ea;
- int imm, ra, rd, upd;
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- } else {
- if(upd)
- undef(ir);
- }
- if(trace)
- itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
- reg.r[rd] = (short)getmem_h(ea);
- }
- void
- lhax(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, upd;
- getarrr(ir);
- ea = reg.r[rb];
- upd = getxo(ir)==311;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
- } else {
- if(upd)
- undef(ir);
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
- }
- reg.r[rd] = (short)getmem_h(ea);
- }
- void
- lhbrx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd;
- ulong v;
- getarrr(ir);
- ea = reg.r[rb];
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
- } else {
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
- }
- v = getmem_h(ea);
- reg.r[rd] = ((v&0xFF)<<8)|(v&0xFF);
- }
- void
- sth(ulong ir)
- {
- ulong ea;
- int imm, ra, rd, upd, v;
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- } else {
- if(upd)
- undef(ir);
- }
- v = reg.r[rd] & 0xFFFF;
- if(trace)
- itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, imm, ra, ea, v, v);
- putmem_h(ea, v);
- }
- void
- sthx(ulong ir)
- {
- ulong ea;
- int ra, rd, upd, rb, v;
- getarrr(ir);
- ea = reg.r[rb];
- upd = getxo(ir)==247;
- v = reg.r[rd] & 0xFFFF;
- if(ra) {
- ea += reg.r[ra];
- if(upd)
- reg.r[ra] = ea;
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
- ci->name, rd, ra, rb, ea, v, v);
- } else {
- if(upd)
- undef(ir);
- if(trace)
- itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, rb, ea, v, v);
- }
- putmem_h(ea, v);
- }
- void
- sthbrx(ulong ir)
- {
- ulong ea;
- int ra, rd, rb;
- ulong v;
- getarrr(ir);
- ea = reg.r[rb];
- v = reg.r[rd];
- v = ((v&0xFF)<<8)|(v&0xFF);
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
- ci->name, rd, ra, rb, ea, v, v);
- } else {
- if(trace)
- itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
- ci->name, rd, rb, ea, v, v);
- }
- putmem_h(ea, v);
- }
- void
- lwbrx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, i;
- ulong v;
- getarrr(ir);
- if(ir & Rc)
- undef(ir);
- ea = reg.r[rb];
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
- } else {
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
- }
- v = 0;
- for(i = 0; i < 4; i++)
- v = v>>8 | getmem_b(ea++); /* assume unaligned load is allowed */
- reg.r[rd] = v;
- }
- void
- stwbrx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, i;
- ulong v;
- getarrr(ir);
- if(ir & Rc)
- undef(ir);
- ea = reg.r[rb];
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
- } else {
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
- }
- v = 0;
- for(i = 0; i < 4; i++) {
- putmem_b(ea++, v & 0xFF); /* assume unaligned store is allowed */
- v >>= 8;
- }
- }
- void
- lswi(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, n, i, r, b;
- getarrr(ir);
- if(ir & Rc)
- undef(ir);
- n = rb;
- if(n == 0)
- n = 32;
- ea = 0;
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea);
- } else {
- if(trace)
- itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n);
- }
- i = -1;
- r = rd-1;
- while(--n >= 0) {
- if(i < 0) {
- r = (r+1)&0x1F;
- if(ra == 0 || r != ra)
- reg.r[r] = 0;
- i = 24;
- }
- b = getmem_b(ea++);
- if(ra == 0 || r != ra)
- reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i);
- i -= 8;
- }
- }
- void
- lswx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, n, i, r, b;
- getarrr(ir);
- if(ir & Rc)
- undef(ir);
- n = reg.xer & 0x7F;
- ea = reg.r[rb];
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n);
- } else {
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n);
- }
- i = -1;
- r = rd-1;
- while(--n >= 0) {
- if(i < 0) {
- r = (r+1)&0x1F;
- if((ra == 0 || r != ra) && r != rb)
- reg.r[r] = 0;
- i = 24;
- }
- b = getmem_b(ea++);
- if((ra == 0 || r != ra) && r != rb)
- reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i);
- i -= 8;
- }
- }
- void
- stswx(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, n, i, r;
- getarrr(ir);
- if(ir & Rc)
- undef(ir);
- n = reg.xer & 0x7F;
- ea = reg.r[rb];
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n);
- } else {
- if(trace)
- itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n);
- }
- i = -1;
- r = rd-1;
- while(--n >= 0) {
- if(i < 0) {
- r = (r+1)&0x1F;
- i = 24;
- }
- putmem_b(ea++, (reg.r[r]>>i)&0xFF);
- i -= 8;
- }
- }
- void
- stswi(ulong ir)
- {
- ulong ea;
- int rb, ra, rd, n, i, r;
- getarrr(ir);
- if(ir & Rc)
- undef(ir);
- n = rb;
- if(n == 0)
- n = 32;
- ea = 0;
- if(ra) {
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea);
- } else {
- if(trace)
- itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n);
- }
- i = -1;
- r = rd-1;
- while(--n >= 0) {
- if(i < 0) {
- r = (r+1)&0x1F;
- i = 24;
- }
- putmem_b(ea++, (reg.r[r]>>i)&0xFF);
- i -= 8;
- }
- }
- void
- lmw(ulong ir)
- {
- ulong ea;
- int ra, rd, r;
- long imm;
- getairr(ir);
- ea = imm;
- if(ra)
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
- for(r = rd; r <= 31; r++) {
- if(r != 0 && r != rd)
- reg.r[rd] = getmem_w(ea);
- ea += 4;
- }
- }
- void
- stmw(ulong ir)
- {
- ulong ea;
- int ra, rd, r;
- long imm;
- getairr(ir);
- ea = imm;
- if(ra)
- ea += reg.r[ra];
- if(trace)
- itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
- for(r = rd; r <= 31; r++) {
- putmem_w(ea, reg.r[rd]);
- ea += 4;
- }
- }
- void
- twi(ulong ir)
- {
- int rd, ra;
- long a, imm;
- getairr(ir);
- a = reg.r[ra];
- if(trace)
- itrace("twi\t#%.2x,r%d,$0x%lux (%ld)", rd, ra, imm, imm);
- if(a < imm && rd&0x10 ||
- a > imm && rd&0x08 ||
- a == imm && rd&0x04 ||
- (ulong)a < imm && rd&0x02 ||
- (ulong)a > imm && rd&0x01) {
- Bprint(bioout, "program_exception (trap type)\n");
- longjmp(errjmp, 0);
- }
- }
- void
- tw(ulong ir)
- {
- int rd, ra, rb;
- long a, b;
- getarrr(ir);
- a = reg.r[ra];
- b = reg.r[rb];
- if(trace)
- itrace("tw\t#%.2x,r%d,r%d", rd, ra, rb);
- if(a < b && rd&0x10 ||
- a > b && rd&0x08 ||
- a == b && rd&0x04 ||
- (ulong)a < b && rd&0x02 ||
- (ulong)a > b && rd&0x01) {
- Bprint(bioout, "program_exception (trap type)\n");
- longjmp(errjmp, 0);
- }
- }
- void
- sync(ulong ir)
- {
- USED(ir);
- if(trace)
- itrace("sync");
- }
- void
- icbi(ulong ir)
- {
- int rd, ra, rb;
- if(ir & Rc)
- undef(ir);
- getarrr(ir);
- USED(rd);
- if(trace)
- itrace("%s\tr%d,r%d", ci->name, ra, rb);
- }
- void
- dcbf(ulong ir)
- {
- int rd, ra, rb;
- if(ir & Rc)
- undef(ir);
- getarrr(ir);
- USED(rd);
- if(trace)
- itrace("%s\tr%d,r%d", ci->name, ra, rb);
- }
- void
- dcbst(ulong ir)
- {
- int rd, ra, rb;
- if(ir & Rc)
- undef(ir);
- getarrr(ir);
- USED(rd);
- if(trace)
- itrace("%s\tr%d,r%d", ci->name, ra, rb);
- }
- void
- dcbt(ulong ir)
- {
- int rd, ra, rb;
- if(ir & Rc)
- undef(ir);
- getarrr(ir);
- USED(rd);
- if(trace)
- itrace("%s\tr%d,r%d", ci->name, ra, rb);
- }
- void
- dcbtst(ulong ir)
- {
- int rd, ra, rb;
- if(ir & Rc)
- undef(ir);
- getarrr(ir);
- USED(rd);
- if(trace)
- itrace("%s\tr%d,r%d", ci->name, ra, rb);
- }
- void
- dcbz(ulong ir)
- {
- int rd, ra, rb;
- if(ir & Rc)
- undef(ir);
- getarrr(ir);
- USED(rd);
- if(trace)
- itrace("%s\tr%d,r%d", ci->name, ra, rb);
- }
|