mtcrf (untested).
This commit is contained in:
parent
3573840c5f
commit
486d0beea3
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue