Sqrt intrinsic
Perform math intrinsics on StrictMath when appropriate following Dalvik
change: https://android-review.googlesource.com/42932
Filter package name of intrinsic methods to reduce number of
comparisons.
Change-Id: Iff97c501d4386f76d3f2297406417fa3b76d0a8a
diff --git a/src/disassembler_arm.cc b/src/disassembler_arm.cc
index f987367..509755c 100644
--- a/src/disassembler_arm.cc
+++ b/src/disassembler_arm.cc
@@ -459,8 +459,7 @@
args << Rn << ", " << d << " .. " << (d + imm8);
}
}
- }
- if ((op3 & 0x30) == 0x20 && op4 == 0) { // 10 xxxx ... 0
+ } else if ((op3 & 0x30) == 0x20 && op4 == 0) { // 10 xxxx ... 0
if ((coproc & 0xE) == 0xA) {
// VFP data-processing instructions
// |111|1|1100|0000|0000|1111|110|0|00 |0|0|0000|
@@ -473,21 +472,28 @@
// 111 0 1110|1111 0100 1110 101 0 01 1 0 1001 - eef4ea69
uint32_t opc1 = (instr >> 20) & 0xF;
uint32_t opc2 = (instr >> 16) & 0xF;
- //uint32_t opc3 = (instr >> 6) & 0x3;
+ uint32_t opc3 = (instr >> 6) & 0x3;
if ((opc1 & 0xB) == 0xB) { // 1x11
// Other VFP data-processing instructions.
+ uint32_t D = (instr >> 22) & 0x1;
+ uint32_t Vd = (instr >> 12) & 0xF;
+ uint32_t sz = (instr >> 8) & 1;
+ uint32_t M = (instr >> 5) & 1;
+ uint32_t Vm = instr & 0xF;
+ bool dp_operation = sz == 1;
switch (opc2) {
+ case 0x1: // Vneg/Vsqrt
+ // 1110 11101 D 11 0001 dddd 101s o1M0 mmmm
+ opcode << (opc3 == 1 ? "vneg" : "vsqrt") << (dp_operation ? ".f64" : ".f32");
+ if (dp_operation) {
+ args << "f" << ((D << 4) | Vd) << ", " << "f" << ((M << 4) | Vm);
+ } else {
+ args << "f" << ((Vd << 1) | D) << ", " << "f" << ((Vm << 1) | M);
+ }
+ break;
case 0x4: case 0x5: { // Vector compare
// 1110 11101 D 11 0100 dddd 101 sE1M0 mmmm
- uint32_t D = (instr >> 22) & 0x1;
- uint32_t Vd = (instr >> 12) & 0xF;
- uint32_t sz = (instr >> 8) & 1;
- uint32_t E = (instr >> 7) & 1;
- uint32_t M = (instr >> 5) & 1;
- uint32_t Vm = instr & 0xF;
- bool dp_operation = sz == 1;
- opcode << (E == 0 ? "vcmp" : "vcmpe");
- opcode << (dp_operation ? ".f64" : ".f32");
+ opcode << (opc3 == 1 ? "vcmp" : "vcmpe") << (dp_operation ? ".f64" : ".f32");
if (dp_operation) {
args << "f" << ((D << 4) | Vd) << ", " << "f" << ((M << 4) | Vm);
} else {
@@ -498,6 +504,24 @@
}
}
}
+ } else if ((op3 & 0x30) == 0x30) { // 11 xxxx
+ // Advanced SIMD
+ if ((instr & 0xFFBF0ED0) == 0xeeb10ac0) { // Vsqrt
+ // 1110 11101 D 11 0001 dddd 101S 11M0 mmmm
+ // 1110 11101 0 11 0001 1101 1011 1100 1000 - eeb1dbc8
+ uint32_t D = (instr >> 22) & 1;
+ uint32_t Vd = (instr >> 12) & 0xF;
+ uint32_t sz = (instr >> 8) & 1;
+ uint32_t M = (instr >> 5) & 1;
+ uint32_t Vm = instr & 0xF;
+ bool dp_operation = sz == 1;
+ opcode << "vsqrt" << (dp_operation ? ".f64" : ".f32");
+ if (dp_operation) {
+ args << "f" << ((D << 4) | Vd) << ", " << "f" << ((M << 4) | Vm);
+ } else {
+ args << "f" << ((Vd << 1) | D) << ", " << "f" << ((Vm << 1) | M);
+ }
+ }
}
}
break;