Fixing CR update for divwu/divdu/mulhwu.

This commit is contained in:
Ben Vanik 2015-12-30 10:04:57 -08:00
parent 69c7bac8db
commit cbc74c92f4
6 changed files with 88 additions and 5 deletions

View File

@ -19,6 +19,23 @@ namespace xe {
namespace cpu {
namespace ppc {
uint64_t PPCContext::cr() const {
uint64_t final_bits = 0;
for (int i = 0; i < 8; ++i) {
uint32_t crf = *(&cr0.value + i);
uint64_t bits = (crf & 0x1) << (4 * (7 - i) + 3) |
((crf >> 8) & 0x1) << (4 * (7 - i) + 2) |
((crf >> 16) & 0x1) << (4 * (7 - i) + 1) |
((crf >> 24) & 0x1) << (4 * (7 - i) + 0);
final_bits |= bits << (i * 4);
}
return final_bits;
}
void PPCContext::set_cr(uint64_t value) {
assert_always("not yet implemented");
}
std::string PPCContext::GetRegisterName(PPCRegister reg) {
switch (reg) {
case PPCRegister::kLR:
@ -111,6 +128,8 @@ void PPCContext::SetRegFromString(const char* name, const char* value) {
this->f[n] = string_util::from_string<double>(value);
} else if (sscanf(name, "v%d", &n) == 1) {
this->v[n] = string_util::from_string<vec128_t>(value);
} else if (std::strcmp(name, "cr") == 0) {
this->set_cr(string_util::from_string<uint64_t>(value));
} else {
printf("Unrecognized register name: %s\n", name);
}
@ -144,6 +163,14 @@ bool PPCContext::CompareRegWithString(const char* name, const char* value,
return false;
}
return true;
} else if (std::strcmp(name, "cr") == 0) {
uint64_t actual = this->cr();
uint64_t expected = string_util::from_string<uint64_t>(value);
if (actual != expected) {
std::snprintf(out_value, out_value_size, "%016" PRIX64, actual);
return false;
}
return true;
} else {
assert_always("Unrecognized register name: %s\n", name);
return false;

View File

@ -260,14 +260,16 @@ typedef struct PPCContext_s {
double f[32]; // Floating-point registers
vec128_t v[128]; // VMX128 vector registers
// XER register
// XER register:
// Split to make it easier to do individual updates.
uint8_t xer_ca;
uint8_t xer_ov;
uint8_t xer_so;
// Condition registers
// Condition registers:
// These are split to make it easier to do DCE on unused stores.
uint64_t cr() const;
void set_cr(uint64_t value);
union {
uint32_t value;
struct {

View File

@ -234,7 +234,7 @@ int InstrEmit_divdux(PPCHIRBuilder& f, const InstrData& i) {
return 1;
}
if (i.XO.Rc) {
f.UpdateCR(0, v, false);
f.UpdateCR(0, v);
}
return 0;
}
@ -291,7 +291,7 @@ int InstrEmit_divwux(PPCHIRBuilder& f, const InstrData& i) {
return 1;
}
if (i.XO.Rc) {
f.UpdateCR(0, v, false);
f.UpdateCR(0, v);
}
return 0;
}
@ -357,7 +357,7 @@ int InstrEmit_mulhwux(PPCHIRBuilder& f, const InstrData& i) {
INT64_TYPE);
f.StoreGPR(i.XO.RT, v);
if (i.XO.Rc) {
f.UpdateCR(0, v, false);
f.UpdateCR(0, v);
}
return 0;
}

View File

@ -163,3 +163,21 @@ test_divdu_9_constant:
#_ REGISTER_OUT r3 0
#_ REGISTER_OUT r4 0x8000000000000000
#_ REGISTER_OUT r5 -1
test_divdu_10:
#_ REGISTER_IN r0 0x1
#_ REGISTER_IN r3 0xFFFFFFFF
divdu. r0, r3, r0
blr
#_ REGISTER_OUT r0 0xFFFFFFFF
#_ REGISTER_OUT r3 0xFFFFFFFF
#_ REGISTER_OUT cr 0x0000000080000000
test_divdu_11:
#_ REGISTER_IN r0 0
#_ REGISTER_IN r3 0xFFFFFFFF
divdu. r0, r0, r3
blr
#_ REGISTER_OUT r0 0xFFFFFFFF
#_ REGISTER_OUT r3 0xFFFFFFFF
#_ REGISTER_OUT cr 0x0000000020000000

View File

@ -219,3 +219,21 @@ test_divwu_12_constant:
#_ REGISTER_OUT r3 0
#_ REGISTER_OUT r4 0x80000000
#_ REGISTER_OUT r5 -1
test_divwu_13:
#_ REGISTER_IN r0 0x1
#_ REGISTER_IN r3 0xFFFFFFFF
divwu. r0, r3, r0
blr
#_ REGISTER_OUT r0 0xFFFFFFFF
#_ REGISTER_OUT r3 0xFFFFFFFF
#_ REGISTER_OUT cr 0x0000000080000000
test_divwu_14:
#_ REGISTER_IN r0 0x1
#_ REGISTER_IN r3 0xFFFFFFFF
divwu. r0, r0, r3
blr
#_ REGISTER_OUT r0 0
#_ REGISTER_OUT r3 0xFFFFFFFF
#_ REGISTER_OUT cr 0x0000000020000000

View File

@ -111,3 +111,21 @@ test_mulhwu_6_constant:
#_ REGISTER_OUT r3 0x00000000FFFFFFFE
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
test_mulhwu_7:
#_ REGISTER_IN r0 0x1
#_ REGISTER_IN r3 0xFFFFFFFF
mulhwu. r0, r3, r0
blr
#_ REGISTER_OUT r0 0
#_ REGISTER_OUT r3 0xFFFFFFFF
#_ REGISTER_OUT cr 0x0000000020000000
test_mulhwu_8:
#_ REGISTER_IN r0 0x1
#_ REGISTER_IN r3 0x1FFFFFFFF
mulhwu. r0, r3, r0
blr
#_ REGISTER_OUT r0 0
#_ REGISTER_OUT r3 0x1FFFFFFFF
#_ REGISTER_OUT cr 0x0000000020000000