ARM: Decode the load halfword, memory hints instructions for 32 bit Thumb.
This commit is contained in:
parent
a483d44d9f
commit
7a9dcdf99f
2 changed files with 175 additions and 1 deletions
|
@ -140,7 +140,7 @@
|
||||||
}
|
}
|
||||||
0x1: decode HTOPCODE_6_5 {
|
0x1: decode HTOPCODE_6_5 {
|
||||||
0x0: WarnUnimpl::Load_byte_memory_hints();
|
0x0: WarnUnimpl::Load_byte_memory_hints();
|
||||||
0x1: WarnUnimpl::Load_halfword_memory_hints();
|
0x1: LoadHalfwordMemoryHints::loadHalfwordMemoryHints();
|
||||||
0x2: Thumb32LoadWord::thumb32LoadWord();
|
0x2: Thumb32LoadWord::thumb32LoadWord();
|
||||||
0x3: WarnUnimpl::undefined();
|
0x3: WarnUnimpl::undefined();
|
||||||
}
|
}
|
||||||
|
|
|
@ -468,6 +468,180 @@ def format Thumb32StoreSingle() {{
|
||||||
decode_block = decode % classNames
|
decode_block = decode % classNames
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
def format LoadHalfwordMemoryHints() {{
|
||||||
|
decode = '''
|
||||||
|
{
|
||||||
|
const uint32_t op1 = bits(machInst, 24, 23);
|
||||||
|
const uint32_t op2 = bits(machInst, 11, 6);
|
||||||
|
const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
|
||||||
|
const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
|
||||||
|
const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
|
||||||
|
const uint32_t imm12 = bits(machInst, 11, 0);
|
||||||
|
const uint32_t imm8 = bits(machInst, 7, 0);
|
||||||
|
bool pldw = bits(machInst, 21);
|
||||||
|
const uint32_t imm2 = bits(machInst, 5, 4);
|
||||||
|
if (rn == 0xf) {
|
||||||
|
if (rt == 0xf) {
|
||||||
|
if (bits(op1, 1) == 1) {
|
||||||
|
// Unallocated memory hint
|
||||||
|
return new NopInst(machInst);
|
||||||
|
} else {
|
||||||
|
return new Unknown(machInst);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bits(op1, 1) == 1) {
|
||||||
|
if (bits(machInst, 23)) {
|
||||||
|
return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC,
|
||||||
|
true, imm12);
|
||||||
|
} else {
|
||||||
|
return new %(ldrsh_lit)s(machInst, rt, INTREG_PC,
|
||||||
|
false, imm12);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bits(machInst, 23)) {
|
||||||
|
return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC,
|
||||||
|
true, imm12);
|
||||||
|
} else {
|
||||||
|
return new %(ldrh_lit)s(machInst, rt, INTREG_PC,
|
||||||
|
false, imm12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (rt == 0xf) {
|
||||||
|
switch (op1) {
|
||||||
|
case 0x0:
|
||||||
|
if (op2 == 0x0) {
|
||||||
|
if (pldw) {
|
||||||
|
return new %(pldw_radd)s(machInst, INTREG_ZERO,
|
||||||
|
rn, true, imm2, LSL, rm);
|
||||||
|
} else {
|
||||||
|
return new %(pld_radd)s(machInst, INTREG_ZERO,
|
||||||
|
rn, true, imm2, LSL, rm);
|
||||||
|
}
|
||||||
|
} else if (bits(op2, 5, 2) == 0xc) {
|
||||||
|
if (pldw) {
|
||||||
|
return new %(pldw_isub)s(machInst, INTREG_ZERO,
|
||||||
|
rn, false, imm8);
|
||||||
|
} else {
|
||||||
|
return new %(pld_isub)s(machInst, INTREG_ZERO,
|
||||||
|
rn, false, imm8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1:
|
||||||
|
if (pldw) {
|
||||||
|
return new %(pldw_iadd)s(machInst, INTREG_ZERO,
|
||||||
|
rn, true, imm12);
|
||||||
|
} else {
|
||||||
|
return new %(pld_iadd)s(machInst, INTREG_ZERO,
|
||||||
|
rn, true, imm12);
|
||||||
|
}
|
||||||
|
case 0x2:
|
||||||
|
if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) {
|
||||||
|
// Unallocated memory hint
|
||||||
|
return new NopInst(machInst);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
return new NopInst(machInst);
|
||||||
|
}
|
||||||
|
return new Unknown(machInst);
|
||||||
|
} else {
|
||||||
|
switch (op1) {
|
||||||
|
case 0x0:
|
||||||
|
if (op2 == 0) {
|
||||||
|
return new %(ldrh_radd)s(machInst, rt, rn, true,
|
||||||
|
imm2, LSL, rm);
|
||||||
|
} else if (bits(op2, 5, 2) == 0xe) {
|
||||||
|
return new %(ldrht)s(machInst, rt, rn, true, imm8);
|
||||||
|
} else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) {
|
||||||
|
const uint32_t puw = bits(machInst, 10, 8);
|
||||||
|
switch (puw) {
|
||||||
|
case 0x1:
|
||||||
|
return new %(ldrh_iw)s(machInst, rt,
|
||||||
|
rn, false, imm8);
|
||||||
|
case 0x3:
|
||||||
|
return new %(ldrh_iuw)s(machInst, rt,
|
||||||
|
rn, true, imm8);
|
||||||
|
case 0x4:
|
||||||
|
return new %(ldrh_ip)s(machInst, rt,
|
||||||
|
rn, false, imm8);
|
||||||
|
case 0x5:
|
||||||
|
return new %(ldrh_ipw)s(machInst, rt,
|
||||||
|
rn, false, imm8);
|
||||||
|
case 0x7:
|
||||||
|
return new %(ldrh_ipuw)s(machInst, rt,
|
||||||
|
rn, true, imm8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1:
|
||||||
|
return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12);
|
||||||
|
case 0x2:
|
||||||
|
if (op2 == 0) {
|
||||||
|
return new %(ldrsh_radd)s(machInst, rt, rn, true,
|
||||||
|
imm2, LSL, rm);
|
||||||
|
} else if (bits(op2, 5, 2) == 0xe) {
|
||||||
|
return new %(ldrsht)s(machInst, rt, rn, true, imm8);
|
||||||
|
} else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) {
|
||||||
|
const uint32_t puw = bits(machInst, 10, 8);
|
||||||
|
switch (puw) {
|
||||||
|
case 0x1:
|
||||||
|
return new %(ldrsh_iw)s(machInst, rt,
|
||||||
|
rn, false, imm8);
|
||||||
|
case 0x3:
|
||||||
|
return new %(ldrsh_iuw)s(machInst, rt,
|
||||||
|
rn, true, imm8);
|
||||||
|
case 0x4:
|
||||||
|
return new %(ldrsh_ip)s(machInst, rt,
|
||||||
|
rn, false, imm8);
|
||||||
|
case 0x5:
|
||||||
|
return new %(ldrsh_ipw)s(machInst, rt,
|
||||||
|
rn, false, imm8);
|
||||||
|
case 0x7:
|
||||||
|
return new %(ldrsh_ipuw)s(machInst, rt,
|
||||||
|
rn, true, imm8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12);
|
||||||
|
}
|
||||||
|
return new Unknown(machInst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
substDict = {
|
||||||
|
"ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True),
|
||||||
|
"ldrsh_lit" : loadImmClassName(False, False, False, 2, True),
|
||||||
|
"ldrh_lit_u" : loadImmClassName(False, True, False, 2),
|
||||||
|
"ldrh_lit" : loadImmClassName(False, False, False, 2),
|
||||||
|
"ldrsh_radd" : loadRegClassName(False, True, False, 2, True),
|
||||||
|
"ldrh_radd" : loadRegClassName(False, True, False, 2),
|
||||||
|
"ldrsh_iw" : loadImmClassName(True, False, True, 2, True),
|
||||||
|
"ldrsh_iuw" : loadImmClassName(True, True, True, 2, True),
|
||||||
|
"ldrsh_ip" : loadImmClassName(False, False, False, 2, True),
|
||||||
|
"ldrsh_ipw" : loadImmClassName(False, False, True, 2, True),
|
||||||
|
"ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True),
|
||||||
|
"ldrsh_iadd" : loadImmClassName(False, True, False, 2, True),
|
||||||
|
"ldrh_iw" : loadImmClassName(True, False, True, 2),
|
||||||
|
"ldrh_iuw" : loadImmClassName(True, True, True, 2),
|
||||||
|
"ldrh_ip" : loadImmClassName(False, False, False, 2),
|
||||||
|
"ldrh_ipw" : loadImmClassName(False, False, True, 2),
|
||||||
|
"ldrh_ipuw" : loadImmClassName(False, True, True, 2),
|
||||||
|
"ldrh_iadd" : loadImmClassName(False, True, False, 2),
|
||||||
|
"ldrht" : loadImmClassName(False, True, False, 2, user=True),
|
||||||
|
"ldrsht" : loadImmClassName(False, True, False, 2, True, user=True),
|
||||||
|
"pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1),
|
||||||
|
"pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1),
|
||||||
|
"pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1),
|
||||||
|
"pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1),
|
||||||
|
"pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1),
|
||||||
|
"pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1)
|
||||||
|
}
|
||||||
|
decode_block = decode % substDict
|
||||||
|
}};
|
||||||
|
|
||||||
def format Thumb16MemReg() {{
|
def format Thumb16MemReg() {{
|
||||||
decode = '''
|
decode = '''
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue