mfocrf + test

This commit is contained in:
Ben Vanik 2015-02-01 11:22:56 -08:00
parent cfcd6118c2
commit f60677f359
7 changed files with 113 additions and 7 deletions

View File

@ -22,8 +22,8 @@ namespace ppc {
#define XEREGISTERINSTR(name, opcode) \
RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name);
#define XEINSTRNOTIMPLEMENTED()
//#define XEINSTRNOTIMPLEMENTED assert_trueALWAYS
//#define XEINSTRNOTIMPLEMENTED()
#define XEINSTRNOTIMPLEMENTED() assert_always("Instruction not implemented");
//#define XEINSTRNOTIMPLEMENTED() __debugbreak()
} // namespace ppc

View File

@ -529,9 +529,42 @@ XEEMITTER(twi, 0x0C000000, D)(PPCHIRBuilder& f, InstrData& i) {
// Processor control (A-26)
XEEMITTER(mfcr, 0x7C000026, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
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
// TODO(benvanik): optimize mfcr sequences.
// Often look something like this:
// mfocrf r11, cr6
// not r10, r11
// extrwi r3, r10, 1, 26
// Could recognize this and only load the appropriate CR bit.
assert_true(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;
}
}
Value* v;
if (count == 1) {
v = f.LoadCR(cri);
} else {
v = f.LoadZero(INT64_TYPE);
}
f.StoreGPR(i.XFX.RT, v);
return 0;
}
XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) {

View File

@ -253,8 +253,26 @@ void PPCHIRBuilder::StoreCTR(Value* value) {
}
Value* PPCHIRBuilder::LoadCR(uint32_t n) {
assert_always();
return 0;
// Construct the entire word of just the bits we care about.
// This makes it easier for the optimizer to exclude things, though
// we could be even more clever and watch sequences.
Value* v = Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 0,
INT8_TYPE),
INT64_TYPE),
4 * (7 - n) + 3);
v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 1,
INT8_TYPE),
INT64_TYPE),
4 * (7 - n) + 2));
v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 2,
INT8_TYPE),
INT64_TYPE),
4 * (7 - n) + 1));
v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 3,
INT8_TYPE),
INT64_TYPE),
4 * (7 - n) + 0));
return v;
}
Value* PPCHIRBuilder::LoadCRField(uint32_t n, uint32_t bit) {

Binary file not shown.

View File

@ -0,0 +1,20 @@
/vagrant/src/alloy/frontend/ppc/test/bin//instr_vcmpxxfp.o: file format elf64-powerpc
Disassembly of section .text:
0000000000100000 <test_vcmpxxfp_1>:
100000: 10 64 2c c6 .long 0x10642cc6
100004: 7c 70 20 26 mfocrf r3,2
100008: 4e 80 00 20 blr
000000000010000c <test_vcmpxxfp_2>:
10000c: 10 64 2c c6 .long 0x10642cc6
100010: 7c 70 20 26 mfocrf r3,2
100014: 4e 80 00 20 blr
0000000000100018 <test_vcmpxxfp_3>:
100018: 10 64 2c c6 .long 0x10642cc6
10001c: 7c 70 20 26 mfocrf r3,2
100020: 4e 80 00 20 blr

View File

@ -0,0 +1,3 @@
0000000000000000 t test_vcmpxxfp_1
000000000000000c t test_vcmpxxfp_2
0000000000000018 t test_vcmpxxfp_3

View File

@ -0,0 +1,32 @@
test_vcmpxxfp_1:
#_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000]
#_ REGISTER_IN v5 [3f800000, 3f800000, 3f800000, 3f800000]
vcmpeqfp. v3, v4, v5
mfocrf r3, 2 # cr6
blr
#_ REGISTER_OUT v3 [ffffffff, ffffffff, ffffffff, ffffffff]
#_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000]
#_ REGISTER_OUT v5 [3f800000, 3f800000, 3f800000, 3f800000]
#_ REGISTER_OUT r3 0x00000080
test_vcmpxxfp_2:
#_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000]
#_ REGISTER_IN v5 [3f800001, 3f800000, 3f800000, 3f800000]
vcmpeqfp. v3, v4, v5
mfocrf r3, 2 # cr6
blr
#_ REGISTER_OUT v3 [00000000, ffffffff, ffffffff, ffffffff]
#_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000]
#_ REGISTER_OUT v5 [3f800001, 3f800000, 3f800000, 3f800000]
#_ REGISTER_OUT r3 0x00000000
test_vcmpxxfp_3:
#_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000]
#_ REGISTER_IN v5 [3f800001, 3f800001, 3f800001, 3f800001]
vcmpeqfp. v3, v4, v5
mfocrf r3, 2 # cr6
blr
#_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000]
#_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000]
#_ REGISTER_OUT v5 [3f800001, 3f800001, 3f800001, 3f800001]
#_ REGISTER_OUT r3 0x00000020