ARM: Decode the neon instruction space.
This commit is contained in:
parent
e50e6a260f
commit
85ba2a3243
3 changed files with 714 additions and 7 deletions
|
@ -119,7 +119,7 @@ decode BIGTHUMB {
|
|||
0x0: decode HTOPCODE_4 {
|
||||
0x0: decode HTOPCODE_8 {
|
||||
0x0: Thumb32StoreSingle::thumb32StoreSingle();
|
||||
0x1: WarnUnimpl::Advanced_SIMD_or_structure_load_store();
|
||||
0x1: ThumbNeonMem::thumbNeonMem();
|
||||
}
|
||||
0x1: decode HTOPCODE_6_5 {
|
||||
0x0: LoadByteMemoryHints::loadByteMemoryHints();
|
||||
|
@ -144,7 +144,7 @@ decode BIGTHUMB {
|
|||
0xf: McrMrc15::mcrMrc15();
|
||||
}
|
||||
}
|
||||
0x3: WarnUnimpl::Advanced_SIMD();
|
||||
0x3: ThumbNeonData::thumbNeonData();
|
||||
default: decode LTCOPROC {
|
||||
0xa, 0xb: ExtensionRegLoadStore::extensionRegLoadStre();
|
||||
0xf: decode HTOPCODE_9_4 {
|
||||
|
|
|
@ -45,6 +45,716 @@
|
|||
// Floating Point operate instructions
|
||||
//
|
||||
|
||||
let {{
|
||||
header_output = '''
|
||||
StaticInstPtr
|
||||
decodeNeonMem(ExtMachInst machInst);
|
||||
|
||||
StaticInstPtr
|
||||
decodeNeonData(ExtMachInst machInst);
|
||||
'''
|
||||
|
||||
decoder_output = '''
|
||||
StaticInstPtr
|
||||
decodeNeonMem(ExtMachInst machInst)
|
||||
{
|
||||
const uint32_t b = bits(machInst, 11, 8);
|
||||
const bool a = bits(machInst, 23);
|
||||
const bool l = bits(machInst, 21);
|
||||
|
||||
if (l) {
|
||||
// Load instructions.
|
||||
if (a) {
|
||||
switch (b) {
|
||||
}
|
||||
// Single.
|
||||
} else {
|
||||
switch (b) {
|
||||
}
|
||||
// Multiple.
|
||||
}
|
||||
} else {
|
||||
// Store instructions.
|
||||
if (a) {
|
||||
switch (b) {
|
||||
}
|
||||
// Single.
|
||||
} else {
|
||||
switch (b) {
|
||||
}
|
||||
// Multiple.
|
||||
}
|
||||
}
|
||||
return new WarnUnimplemented("neon memory", machInst);
|
||||
}
|
||||
'''
|
||||
|
||||
decoder_output += '''
|
||||
static StaticInstPtr
|
||||
decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
|
||||
{
|
||||
const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
|
||||
const uint32_t a = bits(machInst, 11, 8);
|
||||
const bool b = bits(machInst, 4);
|
||||
const uint32_t c = bits(machInst, 21, 20);
|
||||
switch (a) {
|
||||
case 0x0:
|
||||
if (b) {
|
||||
if (bits(machInst, 9) == 0) {
|
||||
return new WarnUnimplemented("vhadd", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vhsub", machInst);
|
||||
}
|
||||
} else {
|
||||
return new WarnUnimplemented("vqadd", machInst);
|
||||
}
|
||||
case 0x1:
|
||||
if (!b) {
|
||||
return new WarnUnimplemented("vrhadd", machInst);
|
||||
} else {
|
||||
if (u) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
return new WarnUnimplemented("veor", machInst);
|
||||
case 1:
|
||||
return new WarnUnimplemented("vbsl", machInst);
|
||||
case 2:
|
||||
return new WarnUnimplemented("vbit", machInst);
|
||||
case 3:
|
||||
return new WarnUnimplemented("vbif", machInst);
|
||||
}
|
||||
} else {
|
||||
switch (c) {
|
||||
case 0:
|
||||
return new WarnUnimplemented("vand (reg)", machInst);
|
||||
case 1:
|
||||
return new WarnUnimplemented("vbic (reg)", machInst);
|
||||
case 2:
|
||||
{
|
||||
const IntRegIndex n = (IntRegIndex)(
|
||||
(uint32_t)bits(machInst, 19, 16) |
|
||||
(uint32_t)(bits(machInst, 7) << 4));
|
||||
const IntRegIndex m = (IntRegIndex)(
|
||||
(uint32_t)bits(machInst, 3, 0) |
|
||||
(uint32_t)(bits(machInst, 5) << 4));
|
||||
if (n == m) {
|
||||
return new WarnUnimplemented("vmov (reg)",
|
||||
machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vorr (reg)",
|
||||
machInst);
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
return new WarnUnimplemented("vorn (reg)", machInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
case 0x2:
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vqsub", machInst);
|
||||
} else {
|
||||
if (bits(machInst, 9) == 0) {
|
||||
return new WarnUnimplemented("vhadd", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vhsub", machInst);
|
||||
}
|
||||
}
|
||||
case 0x3:
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vcge (reg)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vcgt (reg)", machInst);
|
||||
}
|
||||
case 0x4:
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vqshl (reg)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vshl (reg)", machInst);
|
||||
}
|
||||
case 0x5:
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vqrshl", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vrshl", machInst);
|
||||
}
|
||||
case 0x6:
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vmin (int)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vmax (int)", machInst);
|
||||
}
|
||||
case 0x7:
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vaba", machInst);
|
||||
} else {
|
||||
if (bits(machInst, 23) == 1) {
|
||||
if (bits(machInst, 6) == 1) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vabdl (int)", machInst);
|
||||
}
|
||||
} else {
|
||||
return new WarnUnimplemented("vabd (int)", machInst);
|
||||
}
|
||||
}
|
||||
case 0x8:
|
||||
if (b) {
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vceq (reg)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vtst", machInst);
|
||||
}
|
||||
} else {
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vsub (int)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vadd (int)", machInst);
|
||||
}
|
||||
}
|
||||
case 0x9:
|
||||
if (b) {
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vmul (poly)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vmul (int)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vmls (int)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vmla (int)", machInst);
|
||||
}
|
||||
}
|
||||
case 0xa:
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vpmin (int)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vpmax (int)", machInst);
|
||||
}
|
||||
case 0xb:
|
||||
if (b) {
|
||||
if (u) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vpadd (int)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vqrdmulh", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqdmulh", machInst);
|
||||
}
|
||||
}
|
||||
case 0xc:
|
||||
return new Unknown(machInst);
|
||||
case 0xd:
|
||||
if (b) {
|
||||
if (u) {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vmul (fp)", machInst);
|
||||
} else {
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
} else {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vmla (fp)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vmls (fp)", machInst);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (u) {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vpadd (fp)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vabd (fp)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vadd (fp)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vsub (fp)", machInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
case 0xe:
|
||||
if (b) {
|
||||
if (u) {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vacge", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vacgt", machInst);
|
||||
}
|
||||
} else {
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
} else {
|
||||
if (u) {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vcge (reg)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vcgt (reg)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vceq (reg)", machInst);
|
||||
} else {
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
case 0xf:
|
||||
if (b) {
|
||||
if (u) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vrecps", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vrsqrts", machInst);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (u) {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vpmax (fp)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vpmin (fp)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (bits(c, 1) == 0) {
|
||||
return new WarnUnimplemented("vmax (fp)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vmin (fp)", machInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
|
||||
static StaticInstPtr
|
||||
decodeNeonOneRegModImm(ExtMachInst machInst)
|
||||
{
|
||||
const bool op = bits(machInst, 5);
|
||||
const uint32_t cmode = bits(machInst, 11, 8);
|
||||
if (op) {
|
||||
if (bits(cmode, 3) == 0) {
|
||||
if (bits(cmode, 0) == 0) {
|
||||
return new WarnUnimplemented("vmov (imm)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vorr (imm)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (bits(cmode, 2) == 1) {
|
||||
return new WarnUnimplemented("vmov (imm)", machInst);
|
||||
} else {
|
||||
if (bits(cmode, 0) == 0) {
|
||||
return new WarnUnimplemented("vmov (imm)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vorr (imm)", machInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bits(cmode, 3) == 0) {
|
||||
if (bits(cmode, 0) == 0) {
|
||||
return new WarnUnimplemented("vmvn (imm)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vbic (imm)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (bits(cmode, 2) == 1) {
|
||||
switch (bits(cmode, 1, 0)) {
|
||||
case 0:
|
||||
case 1:
|
||||
return new WarnUnimplemented("vmvn (imm)", machInst);
|
||||
case 2:
|
||||
return new WarnUnimplemented("vmov (imm)", machInst);
|
||||
case 3:
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
return new WarnUnimplemented("vmov (imm)", machInst);
|
||||
} else {
|
||||
if (bits(cmode, 0) == 0) {
|
||||
return new WarnUnimplemented("vmvn (imm)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vbic (imm)", machInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
|
||||
static StaticInstPtr
|
||||
decodeNeonTwoRegAndShift(ExtMachInst machInst)
|
||||
{
|
||||
const uint32_t a = bits(machInst, 11, 8);
|
||||
const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
|
||||
const bool b = bits(machInst, 6);
|
||||
const bool l = bits(machInst, 7);
|
||||
|
||||
switch (a) {
|
||||
case 0x0:
|
||||
return new WarnUnimplemented("vshr", machInst);
|
||||
case 0x1:
|
||||
return new WarnUnimplemented("vsra", machInst);
|
||||
case 0x2:
|
||||
return new WarnUnimplemented("vrshr", machInst);
|
||||
case 0x3:
|
||||
return new WarnUnimplemented("vrsra", machInst);
|
||||
case 0x4:
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vsri", machInst);
|
||||
} else {
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
case 0x5:
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vsli", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vshl (imm)", machInst);
|
||||
}
|
||||
case 0x6:
|
||||
case 0x7:
|
||||
return new WarnUnimplemented("vqshl, vqshlu (imm)", machInst);
|
||||
case 0x8:
|
||||
if (l) {
|
||||
return new Unknown(machInst);
|
||||
} else if (u) {
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqshrn, vqshrun", machInst);
|
||||
}
|
||||
} else {
|
||||
if (b) {
|
||||
return new WarnUnimplemented("vrshrn", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vshrn", machInst);
|
||||
}
|
||||
}
|
||||
case 0x9:
|
||||
if (l) {
|
||||
return new Unknown(machInst);
|
||||
} else if (b) {
|
||||
return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqshrn, vqshrun", machInst);
|
||||
}
|
||||
case 0xa:
|
||||
if (l || b) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
// If the shift amount is zero, it's vmovl.
|
||||
return new WarnUnimplemented("vshll, vmovl", machInst);
|
||||
}
|
||||
case 0xe:
|
||||
case 0xf:
|
||||
if (l) {
|
||||
return new Unknown(machInst);
|
||||
} else if (a == 0xe) {
|
||||
return new WarnUnimplemented("vcvt (fixed to fp)", machInst);
|
||||
} else if (a == 0xf) {
|
||||
return new WarnUnimplemented("vcvt (fp to fixed)", machInst);
|
||||
}
|
||||
}
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
|
||||
static StaticInstPtr
|
||||
decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
|
||||
{
|
||||
const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
|
||||
const uint32_t a = bits(machInst, 11, 8);
|
||||
|
||||
switch (a) {
|
||||
case 0x0:
|
||||
return new WarnUnimplemented("vaddl", machInst);
|
||||
case 0x1:
|
||||
return new WarnUnimplemented("vaddw", machInst);
|
||||
case 0x2:
|
||||
return new WarnUnimplemented("vsubl", machInst);
|
||||
case 0x3:
|
||||
return new WarnUnimplemented("vsubw", machInst);
|
||||
case 0x4:
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vraddhn", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vaddhn", machInst);
|
||||
}
|
||||
case 0x5:
|
||||
return new WarnUnimplemented("vabal", machInst);
|
||||
case 0x6:
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vrsubhn", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vsubhn", machInst);
|
||||
}
|
||||
case 0x7:
|
||||
if (bits(machInst, 23)) {
|
||||
return new WarnUnimplemented("vabdl (int)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vabd (int)", machInst);
|
||||
}
|
||||
case 0x8:
|
||||
return new WarnUnimplemented("vmlal (int)", machInst);
|
||||
case 0xa:
|
||||
return new WarnUnimplemented("vmlsl (int)", machInst);
|
||||
case 0x9:
|
||||
if (bits(machInst, 23) == 0) {
|
||||
if (bits(machInst, 4) == 0) {
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vmls (int)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vmla (int)", machInst);
|
||||
}
|
||||
} else {
|
||||
if (u) {
|
||||
return new WarnUnimplemented("vmul (poly)", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vmul (int)", machInst);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return new WarnUnimplemented("vqdmlal", machInst);
|
||||
}
|
||||
case 0xb:
|
||||
if (!u) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqdmlsl", machInst);
|
||||
}
|
||||
case 0xc:
|
||||
return new WarnUnimplemented("vmull (int)", machInst);
|
||||
case 0xd:
|
||||
if (!u) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqdmull", machInst);
|
||||
}
|
||||
case 0xe:
|
||||
return new WarnUnimplemented("vmull (poly)", machInst);
|
||||
}
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
|
||||
static StaticInstPtr
|
||||
decodeNeonTwoRegScalar(ExtMachInst machInst)
|
||||
{
|
||||
const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
|
||||
const uint32_t a = bits(machInst, 11, 8);
|
||||
|
||||
switch (a) {
|
||||
case 0x0:
|
||||
return new WarnUnimplemented("vmla (int scalar)", machInst);
|
||||
case 0x1:
|
||||
return new WarnUnimplemented("vmla (fp scalar)", machInst);
|
||||
case 0x4:
|
||||
return new WarnUnimplemented("vmls (int scalar)", machInst);
|
||||
case 0x5:
|
||||
return new WarnUnimplemented("vmls (fp scalar)", machInst);
|
||||
case 0x2:
|
||||
return new WarnUnimplemented("vmlal (scalar)", machInst);
|
||||
case 0x6:
|
||||
return new WarnUnimplemented("vmlsl (scalar)", machInst);
|
||||
case 0x3:
|
||||
if (u) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqdmlal", machInst);
|
||||
}
|
||||
case 0x7:
|
||||
if (u) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqdmlsl", machInst);
|
||||
}
|
||||
case 0x8:
|
||||
return new WarnUnimplemented("vmul (int scalar)", machInst);
|
||||
case 0x9:
|
||||
return new WarnUnimplemented("vmul (fp scalar)", machInst);
|
||||
case 0xa:
|
||||
return new WarnUnimplemented("vmull (scalar)", machInst);
|
||||
case 0xb:
|
||||
if (u) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqdmull", machInst);
|
||||
}
|
||||
case 0xc:
|
||||
return new WarnUnimplemented("vqdmulh", machInst);
|
||||
case 0xd:
|
||||
return new WarnUnimplemented("vqrdmulh", machInst);
|
||||
}
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
|
||||
static StaticInstPtr
|
||||
decodeNeonTwoRegMisc(ExtMachInst machInst)
|
||||
{
|
||||
const uint32_t a = bits(machInst, 17, 16);
|
||||
const uint32_t b = bits(machInst, 10, 6);
|
||||
switch (a) {
|
||||
case 0x0:
|
||||
switch (bits(b, 4, 1)) {
|
||||
case 0x0:
|
||||
return new WarnUnimplemented("vrev64", machInst);
|
||||
case 0x1:
|
||||
return new WarnUnimplemented("vrev32", machInst);
|
||||
case 0x2:
|
||||
return new WarnUnimplemented("vrev16", machInst);
|
||||
case 0x4:
|
||||
case 0x5:
|
||||
return new WarnUnimplemented("vpaddl", machInst);
|
||||
case 0x8:
|
||||
return new WarnUnimplemented("vcls", machInst);
|
||||
case 0x9:
|
||||
return new WarnUnimplemented("vclz", machInst);
|
||||
case 0xa:
|
||||
return new WarnUnimplemented("vcnt", machInst);
|
||||
case 0xb:
|
||||
return new WarnUnimplemented("vmvn (reg)", machInst);
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
return new WarnUnimplemented("vpadal", machInst);
|
||||
case 0xe:
|
||||
return new WarnUnimplemented("vqabs", machInst);
|
||||
case 0xf:
|
||||
return new WarnUnimplemented("vqneg", machInst);
|
||||
default:
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
case 0x1:
|
||||
switch (bits(b, 3, 1)) {
|
||||
case 0x0:
|
||||
return new WarnUnimplemented("vcgt (imm #0)", machInst);
|
||||
case 0x1:
|
||||
return new WarnUnimplemented("vcge (imm #0)", machInst);
|
||||
case 0x2:
|
||||
return new WarnUnimplemented("vceq (imm #0)", machInst);
|
||||
case 0x3:
|
||||
return new WarnUnimplemented("vcle (imm #0)", machInst);
|
||||
case 0x4:
|
||||
return new WarnUnimplemented("vclt (imm #0)", machInst);
|
||||
case 0x6:
|
||||
return new WarnUnimplemented("vabs (imm #0)", machInst);
|
||||
case 0x7:
|
||||
return new WarnUnimplemented("vneg (imm #0)", machInst);
|
||||
}
|
||||
case 0x2:
|
||||
switch (bits(b, 4, 1)) {
|
||||
case 0x0:
|
||||
return new WarnUnimplemented("vswp", machInst);
|
||||
case 0x1:
|
||||
return new WarnUnimplemented("vtrn", machInst);
|
||||
case 0x2:
|
||||
return new WarnUnimplemented("vuzp", machInst);
|
||||
case 0x3:
|
||||
return new WarnUnimplemented("vzip", machInst);
|
||||
case 0x4:
|
||||
if (b == 0x8) {
|
||||
return new WarnUnimplemented("vmovn", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vqmovun", machInst);
|
||||
}
|
||||
case 0x5:
|
||||
return new WarnUnimplemented("vqmovn", machInst);
|
||||
case 0x6:
|
||||
if (b == 0xc) {
|
||||
return new WarnUnimplemented("vshll", machInst);
|
||||
} else {
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
case 0xc:
|
||||
case 0xe:
|
||||
if (b == 0x18) {
|
||||
return new WarnUnimplemented("vcvt (single to half)",
|
||||
machInst);
|
||||
} else if (b == 0x1c) {
|
||||
return new WarnUnimplemented("vcvt (half to single)",
|
||||
machInst);
|
||||
} else {
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
default:
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
case 0x3:
|
||||
if (bits(b, 4, 3) == 0x3) {
|
||||
return new WarnUnimplemented("vcvt (fp and int)", machInst);
|
||||
} else if ((b & 0x1a) == 0x10) {
|
||||
return new WarnUnimplemented("vrecpe", machInst);
|
||||
} else if ((b & 0x1a) == 0x12) {
|
||||
return new WarnUnimplemented("vrsqrte", machInst);
|
||||
} else {
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
}
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
|
||||
StaticInstPtr
|
||||
decodeNeonData(ExtMachInst machInst)
|
||||
{
|
||||
const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
|
||||
const uint32_t a = bits(machInst, 23, 19);
|
||||
const uint32_t b = bits(machInst, 11, 8);
|
||||
const uint32_t c = bits(machInst, 7, 4);
|
||||
if (bits(a, 4) == 0) {
|
||||
return decodeNeonThreeRegistersSameLength(machInst);
|
||||
} else if ((c & 0x9) == 1) {
|
||||
if ((a & 0x7) == 0) {
|
||||
return decodeNeonOneRegModImm(machInst);
|
||||
} else {
|
||||
return decodeNeonTwoRegAndShift(machInst);
|
||||
}
|
||||
} else if ((c & 0x9) == 9) {
|
||||
return decodeNeonTwoRegAndShift(machInst);
|
||||
} else if ((c & 0x5) == 0) {
|
||||
if (bits(a, 3, 2) != 0x3) {
|
||||
return decodeNeonThreeRegDiffLengths(machInst);
|
||||
}
|
||||
} else if ((c & 0x5) == 4) {
|
||||
if (bits(a, 3, 2) != 0x3) {
|
||||
return decodeNeonTwoRegScalar(machInst);
|
||||
}
|
||||
} else if ((a & 0x16) == 0x16) {
|
||||
if (!u) {
|
||||
if (bits(c, 0) == 0) {
|
||||
return new WarnUnimplemented("vext", machInst);
|
||||
}
|
||||
} else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
|
||||
return decodeNeonTwoRegMisc(machInst);
|
||||
} else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
|
||||
if (bits(machInst, 6) == 0) {
|
||||
return new WarnUnimplemented("vtbl", machInst);
|
||||
} else {
|
||||
return new WarnUnimplemented("vtbx", machInst);
|
||||
}
|
||||
} else if (b == 0xc && (c & 0x9) == 0) {
|
||||
return new WarnUnimplemented("vdup (scalar)", machInst);
|
||||
}
|
||||
}
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
'''
|
||||
}};
|
||||
|
||||
def format ThumbNeonMem() {{
|
||||
decode_block = '''
|
||||
return decodeNeonMem(machInst);
|
||||
'''
|
||||
}};
|
||||
|
||||
def format ThumbNeonData() {{
|
||||
decode_block = '''
|
||||
return decodeNeonMem(machInst);
|
||||
'''
|
||||
}};
|
||||
|
||||
let {{
|
||||
header_output = '''
|
||||
StaticInstPtr
|
||||
|
|
|
@ -54,13 +54,10 @@ def format ArmUnconditional() {{
|
|||
return new Cps(machInst, mods);
|
||||
}
|
||||
} else if (bits(op1, 6, 5) == 0x1) {
|
||||
return new WarnUnimplemented(
|
||||
"Advanced SIMD data-processing", machInst);
|
||||
return decodeNeonData(machInst);
|
||||
} else if (bits(op1, 6, 4) == 0x4) {
|
||||
if (bits(op1, 0) == 0) {
|
||||
return new WarnUnimplemented(
|
||||
"Advanced SIMD element or structure load/store",
|
||||
machInst);
|
||||
return decodeNeonMem(machInst);
|
||||
} else if (bits(op1, 2, 0) == 1) {
|
||||
// Unallocated memory hint
|
||||
return new NopInst(machInst);
|
||||
|
|
Loading…
Reference in a new issue