Fixing CR update for divwu/divdu/mulhwu.
This commit is contained in:
parent
69c7bac8db
commit
cbc74c92f4
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue