mtcrf (untested).

This commit is contained in:
Ben Vanik 2015-02-10 22:04:02 -08:00
parent 3573840c5f
commit 486d0beea3
3 changed files with 55 additions and 10 deletions

View File

@ -533,12 +533,12 @@ XEEMITTER(mfcr, 0x7C000026, XFX)(PPCHIRBuilder& f, InstrData& i) {
// mfocrf RT,FXM
// RT <- undefined
// count <- 0
// do i = 0 to 7
// if FXMi = 1 then
// n <- i
// count <- count + 1
// if count = 1 then
// RT4un + 32:4un + 35 <- CR4un + 32 : 4un + 35
// do i = 0 to 7
// if FXMi = 1 then
// n <- i
// count <- count + 1
// if count = 1 then
// RT4un + 32:4un + 35 <- CR4un + 32 : 4un + 35
// TODO(benvanik): optimize mfcr sequences.
// Often look something like this:
@ -621,8 +621,36 @@ XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) {
}
XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
// mtocrf FXM,RS
// count <- 0
// do i = 0 to 7
// if FXMi = 1 then
// n <- i
// count <- count + 1
// if count = 1 then
// CR4un + 32 : 4un + 35 <- RS4un + 32:4un + 35
Value* v = f.LoadGPR(i.XFX.RT);
if (i.XFX.spr & (1 << 9)) {
uint32_t bits = (i.XFX.spr & 0x1FF) >> 1;
int count = 0;
int cri = 0;
for (int b = 0; b <= 7; ++b) {
if (bits & (1 << b)) {
cri = 7 - b;
++count;
}
}
if (count == 1) {
f.StoreCR(cri, v);
} else {
// Invalid; store zero to CR.
f.StoreCR(f.LoadZero(INT64_TYPE));
}
} else {
f.StoreCR(v);
}
return 0;
}
XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {

View File

@ -289,9 +289,25 @@ Value* PPCHIRBuilder::LoadCRField(uint32_t n, uint32_t bit) {
return LoadContext(offsetof(PPCContext, cr0) + (4 * n) + bit, INT8_TYPE);
}
void PPCHIRBuilder::StoreCR(Value* value) {
// All bits. This is expensive, but seems to be less used than the
// field-specific StoreCR.
for (int i = 0; i <= 7; ++i) {
StoreCR(i, value);
}
}
void PPCHIRBuilder::StoreCR(uint32_t n, Value* value) {
// TODO(benvanik): split bits out and store in values.
assert_always();
// Pull out the bits we are interested in.
// Optimization passes will kill any unneeded stores (mostly).
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 0,
Truncate(Shr(value, 4 * (7 - n) + 3), INT8_TYPE));
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 1,
Truncate(Shr(value, 4 * (7 - n) + 2), INT8_TYPE));
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 2,
Truncate(Shr(value, 4 * (7 - n) + 1), INT8_TYPE));
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 3,
Truncate(Shr(value, 4 * (7 - n) + 0), INT8_TYPE));
}
void PPCHIRBuilder::StoreCRField(uint32_t n, uint32_t bit, Value* value) {

View File

@ -53,6 +53,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
Value* LoadCR();
Value* LoadCR(uint32_t n);
Value* LoadCRField(uint32_t n, uint32_t bit);
void StoreCR(Value* value);
void StoreCR(uint32_t n, Value* value);
void StoreCRField(uint32_t n, uint32_t bit, Value* value);
void UpdateCR(uint32_t n, Value* lhs, bool is_signed = true);