#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <strings.h>
#include "decode.h"
#include "core.h"
#include "misc.h"
int xadd(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->result = rg->gprs[is->sourcea] + rg->gprs[is->sourceb];
is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], rg->trakGpr[is->sourceb], 0, 0);
return 1;
}
int xaddc(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t ca, p0, ps;
uint32_t bcar;
ca = rg->gprs[is->sourcea] & rg->gprs[is->sourceb];
p0 = rg->gprs[is->sourcea] ^ rg->gprs[is->sourceb];
ps = rg->gprs[is->sourcea] + rg->gprs[is->sourceb];
ca = ca | (p0 & ~ps);
bcar = ((ca >> 61) & statCA64) | ((ca >> 30) & statCA32);
is->status = (is->status & ~(statCA64 | statCA32)) | bcar;
is->result = ps;
is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], rg->trakGpr[is->sourceb], 0, 0);
return 1;
}
int xadde(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t ca, p0, ps, cain;
uint32_t bcar;
cain = (((is->status >> 2) & is->status) | ((is->status >> 1) & ~is->status)) & 1;
ca = rg->gprs[is->sourcea] & rg->gprs[is->sourceb];
p0 = rg->gprs[is->sourcea] ^ rg->gprs[is->sourceb];
ps = rg->gprs[is->sourcea] + rg->gprs[is->sourceb];
is->result = ps + cain;
ca = ca | (p0 & ~ps);
bcar = ((ca >> 61) & statCA64) | ((ca >> 30) & statCA32);
is->status = (is->status & ~(statCA64 | statCA32)) | bcar;
is->result = ps;
is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], rg->trakGpr[is->sourceb], 0, 0);
strcpy(is->op, instb->opcode);
return 1;
}
int xaddi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->result = is->btarg;
is->trakResult = is->trakBtarg;
return 1;
}
int xaddic(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t ca, p0, ps;
uint32_t bcar;
ca = rg->gprs[is->sourcea] & is->immediate;
p0 = rg->gprs[is->sourcea] ^ is->immediate;
ps = rg->gprs[is->sourcea] + is->immediate;
ca = ca | (p0 & ~ps);
bcar = ((ca >> 61) & statCA64) | ((ca >> 30) & statCA32);
is->status = (is->status & ~(statCA64 | statCA32)) | bcar;
is->result = ps;
is->trakResult = is->trakBtarg;
return 1;
}
int xaddicdot(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t ca, p0, ps;
uint32_t bcar;
ca = rg->gprs[is->sourcea] & is->immediate;
p0 = rg->gprs[is->sourcea] ^ is->immediate;
ps = rg->gprs[is->sourcea] + is->immediate;
ca = ca | (p0 & ~ps);
bcar = ((ca >> 61) & statCA64) | ((ca >> 30) & statCA32);
is->status = (is->status & ~(statCA64 | statCA32)) | bcar;
is->result = ps;
is->trakResult = is->trakBtarg;
return 1;
}
int xaddis(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->result = (is->btarg - is->immediate) + (is->immediate << 16);
is->trakResult |= gTset;
return 1;
}
int xaddme(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t ca, p0, ps, cain;
uint32_t bcar;
cain = (((is->status >> 2) & is->status) | ((is->status >> 1) & ~is->status)) & 1;
cain = cain - 1;
ca = rg->gprs[is->sourcea] & cain;
p0 = rg->gprs[is->sourcea] ^ cain;
ps = rg->gprs[is->sourcea] + cain;
ca = ca | (p0 & ~ps);
bcar = ((ca >> 61) & statCA64) | ((ca >> 30) & statCA32);
is->status = (is->status & ~(statCA64 | statCA32)) | bcar;
is->result = ps + bcar;
is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], 0, 0, 0);
return 1;
}
int xaddze(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t ca, ps, cain;
uint32_t bcar;
cain = (((is->status >> 2) & is->status) | ((is->status >> 1) & ~is->status)) & 1;
ps = rg->gprs[is->sourcea] + cain;
ca = rg->gprs[is->sourcea] & ~ps;
bcar = ((ca >> 61) & statCA64) | ((ca >> 30) & statCA32);
is->status = (is->status & ~(statCA64 | statCA32)) | bcar;
is->result = ps;
is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], 0, 0, 0);
return 1;
}
int xb(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int32_t bdi;
bdi = inst & 0x03FFFFFC;
if(0x02000000 & bdi) bdi = bdi | 0xFC000000;
is->immediate = (int32_t)bdi;
is->btarg = (int64_t)bdi;
strcpy(is->op, instb->opcode);
if(inst & 1) {
strcat(is->op, "l");
is->mods |= modSetLR;
}
is->trakBtarg = trackReg(is, 0, gTset, 0, gTgen, 0, 0, 0);
if(inst & 2) {
strcat(is->op, "a");
is->mods |= modBrAbs;
sprintf(is->oper, "0x%X", (uint32_t)is->immediate);
return 1;
}
is->btarg = is->btarg + addr;
sprintf(is->oper, ".+0x%X", (uint32_t)is->immediate);
return 1;
}
int xbc(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
short bd;
char xoper[64];
int64_t bdi;
is->target = (inst >> (31 - 10)) & 0x1F;
if((is->target & 0x14) != 0x14) is->opr = isBrCond;
else is->opr = isBranch;
is->sourcea = (inst >> (31 - 15)) & 0x1F;
bd = inst & 0xFFFC;
is->immediate = inst & 0xFFFC;
bdi = bd;
is->btarg = bdi;
if(inst & 1) {
is->mods |= modSetLR;
}
is->trakBtarg = gTset;
if(inst & 2) {
is->mods |= modBrAbs;
is->trakBtarg |= gTgen;
genbr("", is->target, is->sourcea, inst, bd, is->op, xoper);
sprintf(is->oper, "%s0x%X", xoper, bd);
}
is->btarg = is->btarg + addr;
is->trakBtarg = trackReg(is, 0, gTset, 0, gTgen, 0, 0, 0);
genbr("", is->target, is->sourcea, inst, bd, is->op, xoper);
sprintf(is->oper, "%s.+0x%X", xoper, bd);
return 1;
}
int xbclr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->target = (inst >> (31 - 10)) & 0x1F;
if((is->target & 0x14) != 0x14) is->opr = isBrCond;
else is->opr = isBranch;
is->sourcea = (inst >> (31 - 15)) & 0x1F;
is->btarg = rg->sprs[sPlr];
is->trakBtarg = trackReg(is, 0, gTset, 0, rg->trakSpr[sPlr], 0, 0, 0);
if(inst & 1) {
is->mods |= modSetLR;
}
genbr("lr", is->target, is->sourcea, inst, 0, is->op, is->oper);
return 1;
}
int xbctr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->target = (inst >> (31 - 10)) & 0x1F;
is->sourcea = (inst >> (31 - 15)) & 0x1F;
is->btarg = rg->sprs[sPctr];
is->trakBtarg = trackReg(is, 0, gTset, 0, rg->trakSpr[sPctr], 0, 0, 0);
if(inst & 1) {
is->mods |= modSetLR;
}
genbr("ctr", is->target, is->sourcea, inst, 0, is->op, is->oper);
return 1;
}
int xicbi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int ra, rb;
ra = (inst >> (31 - 15)) & 0x1F;
rb = (inst >> (31 - 20)) & 0x1F;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,r%d", ra, rb);
return 1;
}
int xisync(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
return 1;
}
int xlogi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t imm;
uint8_t trak = gTset;
imm = is->immediate;
if(is->mods & modshft) imm = imm << 16;
switch(is->mods & modlop) {
case modand:
is->result = rg->gprs[is->sourcea] & imm;
if(imm != 0) break;
trak = gTgen;
break;
case modor:
is->result = rg->gprs[is->sourcea] | imm;
break;
case modxor:
is->result = rg->gprs[is->sourcea] ^ imm;
break;
default:
printf("Invalid decode: inst = %08X\n", inst);
exit(1);
}
is->trakResult = trackReg(is, 0, trak, 0, rg->trakGpr[is->sourcea], gTgen, 0, 0);
return 1;
}
int xlogx(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int samereg, genres;
samereg = is->sourcea == is->sourceb;
genres = 0;
switch(is->mods & modlop) {
case modand:
is->result = rg->gprs[is->sourcea] & rg->gprs[is->sourceb];
break;
case modor:
is->result = rg->gprs[is->sourcea] | rg->gprs[is->sourceb];
break;
case modxor:
is->result = rg->gprs[is->sourcea] ^ rg->gprs[is->sourceb];
genres = samereg;
break;
case modandc:
is->result = rg->gprs[is->sourcea] & ~rg->gprs[is->sourceb];
genres = samereg;
break;
case modeqv:
is->result = ~(rg->gprs[is->sourcea] ^ rg->gprs[is->sourceb]);
genres = samereg;
break;
case modnand:
is->result = ~(rg->gprs[is->sourcea] & rg->gprs[is->sourceb]);
break;
case modnor:
is->result = ~(rg->gprs[is->sourcea] | rg->gprs[is->sourceb]);
break;
case modorc:
is->result = rg->gprs[is->sourcea] | ~rg->gprs[is->sourceb];
genres = samereg;
break;
default:
printf("Invalid decode: inst = %08X\n", inst);
exit(1);
}
if(!genres) is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], rg->trakGpr[is->sourceb], 0, 0);
else is->trakResult = trackReg(is, 0, gTset | gTgen, 0, rg->trakGpr[is->sourcea], rg->trakGpr[is->sourceb], 0, 0);
return 1;
}
int xrot(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t mask, source;
int bigshift;
is->trakSourceb = gTnu;
if(is->mods & modUseRB) {
is->trakSourceb = rg->trakGpr[is->sourceb];
if((is->trakSourceb == gTnu) || (is->trakSourceb & gTundef)) {
is->trakResult = trackReg(is, 0, gTset | gTundef, 0, rg->trakGpr[is->sourcea], rg->trakGpr[is->sourceb], 0, 0);
return 1;
}
is->sourceb = rg->gprs[is->sourceb];
}
if(is->mods & modROTL32) {
source =
(rg->gprs[is->sourcea] << 32) | (rg->gprs[is->sourcea] & 0x00000000FFFFFFFFULL);
bigshift = (is->sourceb >> 5) & 1;
is->sourceb = is->sourceb & 0x1F;
}
else {
source = rg->gprs[is->sourcea];
bigshift = (is->sourceb >> 6) & 1;
is->sourceb = is->sourceb & 0x3F;
}
if(is->mods & modShift) {
if(bigshift) {
is->trakResult = gTset | gTgen;
return 1;
}
if(is->mods & modShRight) {
is->sourcec = is->sourceb;
is->sourceb = 64 - is->sourceb;
is->sourced = 63;
}
else {
is->sourcec = 0;
is->sourced = 63 - is->sourceb;
}
if(is->mods & modROTL32) is->sourcec += 32;
}
if(is->mods & modZeroc) is->sourcec = 0;
if(is->mods & mod63d) is->sourced = 63;
if(is->mods & mod63minusd) {
is->sourced = 63 - is->sourceb;
is->trakSourced = is->trakSourceb;
}
is->result = (source << is->sourceb) | (source >> (64 - is->sourceb));
mask = (0xFFFFFFFFFFFFFFFFULL >> is->sourcec) & (0xFFFFFFFFFFFFFFFFULL << (63 - is->sourced));
if(is->sourcec > is->sourced) mask = ~mask;
is->result = is->result & mask;
is->trakTarget = gTnu;
if(is->mods & modInsert) {
is->result |= (rg->gprs[is->target] & ~mask);
is->trakTarget = rg->trakGpr[is->target];
}
is->trakResult = trackReg(is, 0, gTset, is->trakTarget, rg->trakGpr[is->sourcea], is->trakSourceb, 0, 0);
return 1;
}
int xrfx(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
return 1;
}
int xsc(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->immediate = (inst >> (31 - 26)) & 0x3F;
strcpy(is->op, instb->opcode);
if(is->immediate) sprintf(is->oper, "%lld", is->immediate);
return 1;
}
int xtdi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
sprintf(is->oper, "%d,r%d,0x%llX", is->target, is->sourcea, is->immediate);
return 1;
}
int xtwi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
sprintf(is->oper, "%d,r%d,0x%llX", is->target, is->sourcea, is->immediate);
return 1;
}
int xmtmsrx(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int l;
l = (inst >> (31 - 15)) & 1;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,%d", is->target, l);
is->target = (instb->dflags & dTrgnum) >> 8;
return 1;
}
int xmw(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->memsize = (32 - is->target) * 4;
return 1;
}
int xrt(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->trakResult = gTundef;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d", is->target);
is->target = (instb->dflags & dTrgnum) >> 8;
return 1;
}
int xrtra(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->trakResult = gTundef;
strcpy(is->op, instb->opcode);
if(is->mods & modSetCRF) strcat(is->op, ".");
sprintf(is->oper, "r%d,r%d", is->target, is->sourcea);
return 1;
}
int xrtrb(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->trakResult = gTundef;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,r%d", is->target, is->sourceb);
return 1;
}
int xftfb(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
sprintf(is->oper, "f%d,f%d", is->target, is->sourceb);
return 1;
}
int xext(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint64_t mask, sign;
sign = 1 << ((is->memsize * 8) - 1);
mask = -sign;
sign = (rg->gprs[is->sourcea] & sign) ^ sign;
is->result = (rg->gprs[is->sourcea] | mask) + sign;
is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], 0, 0, 0);
strcpy(is->op, instb->opcode);
if(is->mods & modSetCRF) strcat(is->op, ".");
sprintf(is->oper, "r%d,r%d", is->target, is->sourcea);
return 1;
}
int xcmpi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint16_t xxx;
is->target = is->target >> 2;
if(inst & 0x00200000) strcpy(is->op, "cmpdi");
else strcpy(is->op, "cmpwi");
xxx = (uint16_t)is->immediate;
sprintf(is->oper, "cr%d,r%d,0x%04X", is->target, is->sourcea, xxx);
return 1;
}
int xcmpli(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
uint16_t xxx;
is->target = is->target >> 2;
is->immediate = is->immediate & 0xFFFF;
if(inst & 0x00200000) strcpy(is->op, "cmpldi");
else strcpy(is->op, "cmplwi");
xxx = (uint16_t)is->immediate;
sprintf(is->oper, "cr%d,r%d,0x%04X", is->target, is->sourcea, xxx);
return 1;
}
int xmfcr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int crf;
is->sourcea = sPcr;
is->targtype = rfGpr;
if(!(inst & 0x00100000)) {
crf = 0xFF;
strcpy(is->op, "mfcr");
sprintf(is->oper, "r%d", is->target);
}
else {
crf = (inst >> (31 - 19)) & 0xFF;
strcpy(is->op, "mfocrf");
sprintf(is->oper, "r%d,0x%02X", is->target, crf);
}
return 1;
}
int xmtcrf(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int crf;
is->target = sPcr;
is->targtype = rfSpr;
is->sourcea = (inst >> (31 - 10)) & 0x1F;
crf = (inst >> (31 - 19)) & 0xFF;
if(!(inst & 0x00100000)) {
strcpy(is->op, "mtcrf");
}
else {
strcpy(is->op, "mtocrf");
}
sprintf(is->oper, "0x%02X,r%d", crf, is->sourcea);
return 1;
}
int xmfspr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int spr;
sprtb *sprp;
spr = (inst >> (31 - 20)) & 0x3FF;
spr = ((spr << 5) & 0x3E0) | ((spr >> 5) & 0x1F);
is->sourcea = spr;
sprp = decodeSPR(spr);
if(((uint32_t)sprp == 0) || (sprp->sprname[0] == 0)) {
sprintf(is->oper, "r%d,%d", is->target, spr);
is->trakSourcea = gTundef;
}
else {
if(sprp->sprflags & sprPriv) is->mods |= modPrv;
sprintf(is->oper, "r%d,%s", is->target, sprp->sprname);
is->sourcea = sprp->sprint;
if(is->sourcea == -1) {
is->result = 0;
is->trakSourcea = gTundef;
}
else {
is->result = rg->sprs[sprp->sprint];
is->trakSourcea = gTset | rg->trakSpr[sprp->sprint];
if(is->target == sPlr) {
is->mods |= modLRs;
}
else if(is->result == sPctr) {
is->mods |= modCTRs;
}
}
}
is->trakResult = trackReg(is, 0, gTset, rg->trakGpr[is->target], is->trakSourcea, 0, 0, 0);
return 1;
}
int xmfsr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int sr;
sr = (inst >> (31 - 15)) & 0x0F;
is->trakResult = gTset | gTundef;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,sr%d", is->target, sr);
return 1;
}
int xmtsr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int sr;
sr = (inst >> (31 - 15)) & 0x0F;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "sr%d,r%d", sr, is->target);
return 1;
}
int xmftb(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int tbr;
is->target = (inst >> (31 - 10)) & 0x1F;
tbr = (inst >> (31 - 20)) & 0x3FF;
tbr = ((tbr << 5) & 0x3E0) | ((tbr >> 5) & 0x1F);
is->sourcea = tbr;
if((tbr < 268) || (tbr > 269)) return 0;
is->result = 0;
is->trakResult = gTset | gTundef;
strcpy(is->op, instb->opcode);
if(tbr == 269) strcat(is->op, "u");
sprintf(is->oper, "r%d", is->target);
return 1;
}
int xmtspr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int spr;
sprtb *sprp;
is->sourcea = is->target;
is->result = rg->gprs[is->sourcea];
spr = (inst >> (31 - 20)) & 0x3FF;
spr = ((spr << 5) & 0x3E0) | ((spr >> 5) & 0x1F);
is->target = spr;
sprp = decodeSPR(spr);
if(((uint32_t)sprp == 0) || (sprp->sprname[0] == 0)) {
sprintf(is->oper, "%d,r%d", is->target, is->sourcea);
is->trakResult = trackReg(is, 0, gTundef | gTset, 0, rg->trakGpr[is->sourcea], 0, 0, 0);
}
else {
if(sprp->sprflags & sprPriv) is->mods |= modPrv;
sprintf(is->oper, "%s,r%d", sprp->sprname, is->sourcea);
is->target = sprp->sprint;
if(is->target == -1) {
is->result = 0;
is->trakResult = trackReg(is, 0, gTundef | gTset, 0, rg->trakGpr[is->sourcea], 0, 0, 0);
}
if(is->target == sPlr) {
is->mods |= modLRs;
is->trakResult = trackReg(is, 0, gTset | gTlr, 0, rg->trakGpr[is->sourcea], 0, 0, 0);
}
else if(is->target == sPctr) {
is->mods |= modCTRs;
is->trakResult = trackReg(is, 0, gTset, 0, rg->trakGpr[is->sourcea], 0, 0, 0);
}
}
return 1;
}
int xmcrf(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int crs, crd;
is->target = sPcr;
is->targtype = rfSpr;
crd = (inst >> (31 - 8)) & 7;
crs = (inst >> (31 - 13)) & 7;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "cr%d,cr%d", crd, crs);
return 1;
}
int xattn(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->immediate = (inst >> (31 - 20)) & 0x7FFF;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "0x%llX", is->immediate);
return 1;
}
int xsrawi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int sh;
sh = (inst >> (31 - 20)) & 0x1F;
strcpy(is->op, instb->opcode);
if(is->mods & modSetCRF) {
strcat(is->op, ".");
}
sprintf(is->oper, "r%d,r%d,%d", is->target, is->sourcea, sh);
is->trakResult = gTset| gTundef;
return 1;
}
int xfcmpx(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int bf;
bf = (inst >> (31 - 8)) & 7;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "cr%d,f%d,f%d", bf, is->sourcea, is->sourceb);
return 1;
}
int xmcrfs(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int bf, bfa;
bf = (inst >> (31 - 8)) & 7;
bfa = (inst >> (31 - 13)) & 7;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "cr%d,%d", bf, bfa);
return 1;
}
int xmcrxr(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int bf;
bf = (inst >> (31 - 8)) & 7;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "cr%d", bf);
return 1;
}
int xmffs(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
if(is->mods & modSetCRF) strcat(is->op, ".");
sprintf(is->oper, "f%d", is->target);
is->sourcea = (instb->dflags & dTrgnum) >> 8;
return 1;
}
int xmtfsfi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int bf, u;
bf = (inst >> (31 - 8)) & 7;
u = (inst >> (31 - 20)) & 0xF;
strcpy(is->op, instb->opcode);
if(is->mods & modSetCRF) strcat(is->op, ".");
sprintf(is->oper, "%d,%d", bf, u);
is->target = sPfpscr;
is->targtype = rfSpr;
return 1;
}
int xlswi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
if(!is->sourceb) is->sourceb = 32;
is->memsize = is->sourceb;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,r%d,%d", is->target, is->sourcea, is->sourceb);
is->trakResult = gTundef | gTset;
return 1;
}
int xstswi(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
if(!is->sourceb) is->sourceb = 32;
is->memsize = is->sourceb;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,r%d,%d", is->target, is->sourcea, is->sourceb);
return 1;
}
int xcmp(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->target = is->target >> 2;
if(inst & 0x00200000) strcpy(is->op, "cmpd");
else strcpy(is->op, "cmpw");
sprintf(is->oper, "cr%d,r%d,r%d", is->target, is->sourcea, is->sourceb);
return 1;
}
int xcmpl(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
is->target = is->target >> 2;
if(inst & 0x00200000) strcpy(is->op, "cmpld");
else strcpy(is->op, "cmplw");
sprintf(is->oper, "cr%d,r%d,r%d", is->target, is->sourcea, is->sourceb);
return 1;
}
char *synctypes[] = {"sync", "lwsync", "ptesync", "badsync"};
int xsync(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int l;
l = (inst >> (31 - 10)) & 3;
if(l > 2) return 0;
strcpy(is->op, synctypes[l]);
return 1;
}
int xdss(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int strm;
if(inst & 0x02000000) strcpy(is->op, "dssall");
else {
strm = (inst >> (31 - 10)) & 0x1F;
strcpy(is->op, "dss");
sprintf(is->oper, "%d", strm);
}
return 1;
}
int xdstx(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int strm;
strm = (inst >> (31 - 10)) & 3;
strcpy(is->op, instb->opcode);
if(inst & 0x02000000) strcat(is->op, "t");
sprintf(is->oper, "r%d,r%d,%d", is->sourcea, is->sourceb, strm);
return 1;
}
int xtlbiex(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
int l;
l = (inst >> (31 - 10)) & 1;
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,%d", is->sourceb, l);
return 1;
}
int xtrap(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
sprintf(is->oper, "%d,r%d,r%d", is->target, is->sourcea, is->sourceb);
return 1;
}
int xrb(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d", is->sourceb);
return 1;
}
int xrarb(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
sprintf(is->oper, "r%d,r%d", is->sourcea, is->sourceb);
return 1;
}
int xoponly(uint32_t inst, ppcinst *instb, uint64_t addr, istate *is, regfile *rg) {
strcpy(is->op, instb->opcode);
return 1;
}
char *bops[] = {
"bdnz", "bdnz", "bdz", "bdz", "b", "b", "b", "b", "bdnz", "bdnz", "bdz", "bdz", "b", "b", "b", "b", "bdnz", "bdnz", "bdz", "bdz", "b", "b", "b", "b", "bdnz", "bdnz", "bdz", "bdz", "b", "b", "b", "b" };
char *conds[] = {
"ge",
"le",
"ne",
"ns",
"lt",
"gt",
"eq",
"so"
};
void genbr(char *src, int bo, int bi, uint32_t inst, int disp, char *op, char *oper) {
int cr, cond;
oper[0] = 0;
cr = (bi >> 2) & 7;
cond = bi & 3;
strcpy(op, bops[bo]);
if(!(bo & 0x10)) {
strcat(op, conds[cond | ((bo >> 1) & 4)]);
}
strcat(op, src);
if(inst & 1) strcat(op, "l");
if(inst & 2) strcat(op, "a");
if((bo & 0x14) == 0x14) {
if((bo != 0x14) || (bi != 31) || !(inst & 1)) return;
strcpy(op,"bcl");
strcpy(oper, "20,31,");
return;
}
if(cr) {
if(src[0] != 0) sprintf(oper, "cr%d", cr);
else sprintf(oper, "cr%d,", cr);
}
return;
}