mfocrf + test
This commit is contained in:
parent
cfcd6118c2
commit
f60677f359
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
0000000000000000 t test_vcmpxxfp_1
|
||||
000000000000000c t test_vcmpxxfp_2
|
||||
0000000000000018 t test_vcmpxxfp_3
|
|
@ -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
|
Loading…
Reference in New Issue