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 cpu {
|
||||||
namespace ppc {
|
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) {
|
std::string PPCContext::GetRegisterName(PPCRegister reg) {
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
case PPCRegister::kLR:
|
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);
|
this->f[n] = string_util::from_string<double>(value);
|
||||||
} else if (sscanf(name, "v%d", &n) == 1) {
|
} else if (sscanf(name, "v%d", &n) == 1) {
|
||||||
this->v[n] = string_util::from_string<vec128_t>(value);
|
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 {
|
} else {
|
||||||
printf("Unrecognized register name: %s\n", name);
|
printf("Unrecognized register name: %s\n", name);
|
||||||
}
|
}
|
||||||
|
@ -144,6 +163,14 @@ bool PPCContext::CompareRegWithString(const char* name, const char* value,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
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 {
|
} else {
|
||||||
assert_always("Unrecognized register name: %s\n", name);
|
assert_always("Unrecognized register name: %s\n", name);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -260,14 +260,16 @@ typedef struct PPCContext_s {
|
||||||
double f[32]; // Floating-point registers
|
double f[32]; // Floating-point registers
|
||||||
vec128_t v[128]; // VMX128 vector registers
|
vec128_t v[128]; // VMX128 vector registers
|
||||||
|
|
||||||
// XER register
|
// XER register:
|
||||||
// Split to make it easier to do individual updates.
|
// Split to make it easier to do individual updates.
|
||||||
uint8_t xer_ca;
|
uint8_t xer_ca;
|
||||||
uint8_t xer_ov;
|
uint8_t xer_ov;
|
||||||
uint8_t xer_so;
|
uint8_t xer_so;
|
||||||
|
|
||||||
// Condition registers
|
// Condition registers:
|
||||||
// These are split to make it easier to do DCE on unused stores.
|
// These are split to make it easier to do DCE on unused stores.
|
||||||
|
uint64_t cr() const;
|
||||||
|
void set_cr(uint64_t value);
|
||||||
union {
|
union {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -234,7 +234,7 @@ int InstrEmit_divdux(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (i.XO.Rc) {
|
if (i.XO.Rc) {
|
||||||
f.UpdateCR(0, v, false);
|
f.UpdateCR(0, v);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ int InstrEmit_divwux(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (i.XO.Rc) {
|
if (i.XO.Rc) {
|
||||||
f.UpdateCR(0, v, false);
|
f.UpdateCR(0, v);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,7 @@ int InstrEmit_mulhwux(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
INT64_TYPE);
|
INT64_TYPE);
|
||||||
f.StoreGPR(i.XO.RT, v);
|
f.StoreGPR(i.XO.RT, v);
|
||||||
if (i.XO.Rc) {
|
if (i.XO.Rc) {
|
||||||
f.UpdateCR(0, v, false);
|
f.UpdateCR(0, v);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,3 +163,21 @@ test_divdu_9_constant:
|
||||||
#_ REGISTER_OUT r3 0
|
#_ REGISTER_OUT r3 0
|
||||||
#_ REGISTER_OUT r4 0x8000000000000000
|
#_ REGISTER_OUT r4 0x8000000000000000
|
||||||
#_ REGISTER_OUT r5 -1
|
#_ 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 r3 0
|
||||||
#_ REGISTER_OUT r4 0x80000000
|
#_ REGISTER_OUT r4 0x80000000
|
||||||
#_ REGISTER_OUT r5 -1
|
#_ 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 r3 0x00000000FFFFFFFE
|
||||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||||
#_ REGISTER_OUT r5 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