ARM: Hook the external data processing instructions into the Thumb decoder.

This commit is contained in:
Gabe Black 2010-06-02 12:58:02 -05:00
parent beb759912b
commit b66e3aec43
2 changed files with 441 additions and 221 deletions

View file

@ -43,98 +43,18 @@
1: decode BIGTHUMB {
// 16 bit thumb instructions.
0: decode TOPCODE_15_13 {
0x0, 0x1: decode TOPCODE_13_11 {
0x0: WarnUnimpl::lsl(); //immediate
0x1: WarnUnimpl::lsr(); //immediate
0x2: WarnUnimpl::asr(); //immediate
0x3: decode TOPCODE_10_9 {
0x0: WarnUnimpl::add(); //register
0x1: WarnUnimpl::sub(); //register
0x2: WarnUnimpl::add(); //3 bit immediate
0x3: WarnUnimpl::sub(); //3 bit immediate
}
0x4: WarnUnimpl::mov(); //immediate
0x5: WarnUnimpl::cmp(); //immediate
0x6: WarnUnimpl::add(); //8 bit immediate, thumb
0x7: WarnUnimpl::sub(); //8 bit immediate, thumb
}
0x0, 0x1: Thumb16ShiftAddSubMoveCmp::thumb16ShiftAddMoveCmp();
0x2: decode TOPCODE_12_10 {
// Data processing
0x0: decode TOPCODE_9_6 {
0x0: WarnUnimpl::and(); //register
0x1: WarnUnimpl::eor(); //register
0x2: WarnUnimpl::lsl(); //register
0x3: WarnUnimpl::lsr(); //register
0x4: WarnUnimpl::asr(); //register
0x5: WarnUnimpl::adc(); //register
0x6: WarnUnimpl::sbc(); //register
0x7: WarnUnimpl::ror(); //register
0x8: WarnUnimpl::tst(); //register
0x9: WarnUnimpl::rsb(); //immediate
0xa: WarnUnimpl::cmp(); //register (high registers)
0xb: WarnUnimpl::cmn(); //register
0xc: WarnUnimpl::orr(); //register
0xd: WarnUnimpl::mul();
0xe: WarnUnimpl::bic(); //register
0xf: WarnUnimpl::mvn(); //register
}
// Special data instructions and branch and exchange
0x1: decode TOPCODE_9_6 {
0x0: WarnUnimpl::add(); //register (low registers)
0x1, 0x2, 0x3: WarnUnimpl::add(); //register (high registers)
0x4: WarnUnimpl::unpredictable(); //?
0x5, 0x6, 0x7: WarnUnimpl::cmp(); //register
0x8: WarnUnimpl::mov(); //register (low registers)
0x9, 0xa, 0xb: WarnUnimpl::mov(); //register (high registers)
0xc, 0xd: WarnUnimpl::bx();
0xe, 0xf: WarnUnimpl::blx(); //register
}
0x0: Thumb16DataProcessing::thumb16DataProcessing();
0x1: Thumb16SpecDataAndBx::thumb16SpecDataAndBx();
0x2, 0x3: Thumb16MemLit::thumb16MemLit();
default: Thumb16MemReg::thumb16MemReg();
}
0x3, 0x4: Thumb16MemImm::thumb16MemImm();
0x5: decode TOPCODE_12_11 {
0x0: WarnUnimpl::adr();
0x1: WarnUnimpl::add(); //sp, immediate
0x2: decode TOPCODE_10_8 {
0x0: decode TOPCODE_7 {
0x0: WarnUnimpl::add(); //sp, immediate
0x1: WarnUnimpl::sub(); //sp, immediate
}
0x1, 0x3: WarnUnimpl::cbz(); //cbnz too...
0x2: decode TOPCODE_7_6 {
0x0: WarnUnimpl::sxth();
0x1: WarnUnimpl::sxtb();
0x2: WarnUnimpl::uxth();
0x3: WarnUnimpl::uxtb();
}
0x4, 0x5: WarnUnimpl::pop();
0x6: decode TOPCODE_7_5 {
0x2: WarnUnimpl::setend();
0x3: WarnUnimpl::cps();
}
}
0x3: decode TOPCODE_10_8 {
0x1, 0x3: WarnUnimpl::cbz(); //cbnz too...
0x2: decode TOPCODE_7_6 {
0x0: WarnUnimpl::rev();
0x1: WarnUnimpl::rev16();
0x3: WarnUnimpl::revsh();
}
0x4, 0x5: WarnUnimpl::pop();
0x6: WarnUnimpl::bkpt();
0x7: decode TOPCODE_3_0 {
0x0: WarnUnimpl::it();
default: decode TOPCODE_7_4 {
0x0: WarnUnimpl::nop();
0x1: WarnUnimpl::yield();
0x2: WarnUnimpl::wfe();
0x3: WarnUnimpl::wfi();
0x4: WarnUnimpl::sev();
default: WarnUnimpl::unallocated_hint();
}
}
}
0x0: Thumb16Adr::thumb16Adr();
0x1: Thumb16AddSp::thumb16AddSp(); //sp, immediate
0x2, 0x3: Thumb16Misc::thumb16Misc();
}
0x6: decode TOPCODE_12_11 {
0x0, 0x1: Thumb16MacroMem::thumb16MacroMem();
@ -197,45 +117,7 @@
}
}
}
0x1: decode HTOPCODE_8_5 {
0x0: decode LTRD {
0xf: decode HTS {
0x1: WarnUnimpl::tst(); // register
}
default: WarnUnimpl::and(); // register
}
0x1: WarnUnimpl::bic(); // register
0x2: decode HTRN {
0xf: WarnUnimpl::mov(); // register
default: WarnUnimpl::orr(); // register
}
0x3: decode HTRN {
0xf: WarnUnimpl::mvn(); // register
default: WarnUnimpl::orn(); // register
}
0x4: decode LTRD {
0xf: decode HTS {
0x1: WarnUnimpl::teq(); // register
}
default: WarnUnimpl::eor(); // register
}
0x6: WarnUnimpl::pkh();
0x8: decode LTRD {
0xf: decode HTS {
0x1: WarnUnimpl::cmn(); // register
}
default: WarnUnimpl::add(); // register
}
0xa: WarnUnimpl::adc(); // register
0xb: WarnUnimpl::sbc(); // register
0xd: decode LTRD {
0xf: decode HTS {
0x1: WarnUnimpl::cmp(); // register
}
default: WarnUnimpl::sub(); // register
}
0xe: WarnUnimpl::rsb(); // register
}
0x1: Thumb32DataProcShiftReg::thumb32DataProcShiftReg();
default: decode HTOPCODE_9_8 {
0x2: decode LTOPCODE_4 {
0x0: decode LTCOPROC {
@ -280,76 +162,7 @@
}
0x2: decode LTOPCODE_15 {
0x0: decode HTOPCODE_9 {
0x0: decode HTOPCODE_8_5 {
0x0: decode LTRD {
0xf: decode HTS {
0x1: DataModImmOp::tst({{
resTemp = Rn & rotated_imm;
}});
}
default: DataModImmOp::and({{
Rs = resTemp = Rn & rotated_imm;
}});
}
0x1: DataModImmOp::bic({{
Rs = resTemp = Rn & ~rotated_imm;
}});
0x2: decode HTRN {
0xf: DataModImmOp::mov({{
Rs = resTemp = rotated_imm;
}});
default: DataModImmOp::orr({{
Rs = resTemp = Rn | rotated_imm;
}});
}
0x3: decode HTRN {
0xf: DataModImmOp::mvn({{
Rs = resTemp = ~rotated_imm;
}});
default: DataModImmOp::orn({{
Rs = resTemp = Rn | ~rotated_imm;
}});
}
0x4: decode LTRD {
0xf: decode HTS {
0x1: DataModImmOp::teq({{
resTemp = Rn ^ rotated_imm;
}});
}
default: DataModImmOp::eor({{
Rs = resTemp = Rn ^ rotated_imm;
}});
}
0x8: decode LTRD {
0xf: decode HTS {
0x1: DataModImmOp::cmn({{
resTemp = Rn + rotated_imm;
}}, add);
}
default: DataModImmOp::add({{
Rs = resTemp = Rn + rotated_imm;
}}, add);
}
0xa: DataModImmOp::adc({{
Rs = resTemp = Rn + rotated_imm + CondCodes<29:>;
}}, add);
0xb: DataModImmOp::sbc({{
Rs = resTemp = Rn - rotated_imm - !CondCodes<29:>;
}}, sub);
0xd: decode LTRD {
0xf: decode HTS {
0x1: DataModImmOp::cmp({{
resTemp = Rn - rotated_imm;
}}, sub);
}
default: DataModImmOp::sub({{
Rs = resTemp = Rn - rotated_imm;
}}, sub);
}
0xe: DataModImmOp::rsb({{
Rs = resTemp = rotated_imm - Rn;
}}, rsb);
}
0x0: Thumb32DataProcModImm::thumb32DataProcModImm();
0x1: WarnUnimpl::Data_processing_plain_binary_immediate();
}
0x1: WarnUnimpl::Branches_and_miscellaneous_control();

View file

@ -40,28 +40,30 @@ def format ArmDataProcReg() {{
case %(opcode)#x:
if (immShift) {
if (setCc) {
return new %(className)sDRegCc(machInst,
rd, rn, rm, imm5, type);
return new %(className)sDRegCc(machInst, %(dest)s, %(op1)s,
rm, imm5, type);
} else {
return new %(className)sDReg(machInst,
rd, rn, rm, imm5, type);
return new %(className)sDReg(machInst, %(dest)s, %(op1)s,
rm, imm5, type);
}
} else {
if (setCc) {
return new %(className)sDRegRegCc(machInst,
rd, rn, rm, rs, type);
return new %(className)sDRegRegCc(machInst, %(dest)s,
%(op1)s, rm, rs, type);
} else {
return new %(className)sDRegReg(machInst,
rd, rn, rm, rs, type);
return new %(className)sDRegReg(machInst, %(dest)s,
%(op1)s, rm, rs, type);
}
}
break;
'''
def instCode(opcode, mnem):
def instCode(opcode, mnem, dest="rd", op1="rn"):
global instDecode
return instDecode % { "className": mnem.capitalize(),
"opcode": opcode }
"opcode": opcode,
"dest": dest,
"op1": op1 }
decode_block = '''
{
@ -83,14 +85,14 @@ def format ArmDataProcReg() {{
decode_block += instCode(0x5, "adc")
decode_block += instCode(0x6, "sbc")
decode_block += instCode(0x7, "rsc")
decode_block += instCode(0x8, "tst")
decode_block += instCode(0x9, "teq")
decode_block += instCode(0xa, "cmp")
decode_block += instCode(0xb, "cmn")
decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
decode_block += instCode(0xc, "orr")
decode_block += instCode(0xd, "mov")
decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
decode_block += instCode(0xe, "bic")
decode_block += instCode(0xf, "mvn")
decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
decode_block += '''
default:
return new Unknown(machInst);
@ -103,17 +105,21 @@ def format ArmDataProcImm() {{
instDecode = '''
case %(opcode)#x:
if (setCc) {
return new %(className)sDImmCc(machInst, rd, rn, imm, rotC);
return new %(className)sDImmCc(machInst, %(dest)s, %(op1)s,
imm, rotC);
} else {
return new %(className)sDImm(machInst, rd, rn, imm, rotC);
return new %(className)sDImm(machInst, %(dest)s, %(op1)s,
imm, rotC);
}
break;
'''
def instCode(opcode, mnem):
def instCode(opcode, mnem, dest="rd", op1="rn"):
global instDecode
return instDecode % { "className": mnem.capitalize(),
"opcode": opcode }
"opcode": opcode,
"dest": dest,
"op1": op1 }
decode_block = '''
{
@ -134,14 +140,14 @@ def format ArmDataProcImm() {{
decode_block += instCode(0x5, "adc")
decode_block += instCode(0x6, "sbc")
decode_block += instCode(0x7, "rsc")
decode_block += instCode(0x8, "tst")
decode_block += instCode(0x9, "teq")
decode_block += instCode(0xa, "cmp")
decode_block += instCode(0xb, "cmn")
decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
decode_block += instCode(0xc, "orr")
decode_block += instCode(0xd, "mov")
decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
decode_block += instCode(0xe, "bic")
decode_block += instCode(0xf, "mvn")
decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
decode_block += '''
default:
return new Unknown(machInst);
@ -149,3 +155,404 @@ def format ArmDataProcImm() {{
}
'''
}};
def format Thumb16ShiftAddSubMoveCmp() {{
decode_block = '''
{
const uint32_t imm5 = bits(machInst, 10, 6);
const uint32_t imm3 = bits(machInst, 8, 6);
const uint32_t imm8 = bits(machInst, 7, 0);
const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
switch (bits(machInst, 13, 11)) {
case 0x0: // lsl
return new MovDReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
case 0x1: // lsr
return new MovDReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
case 0x2: // asr
return new MovDReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
case 0x3:
switch (bits(machInst, 10, 9)) {
case 0x0:
return new AddDReg(machInst, rd, rn, rm, 0, LSL);
case 0x1:
return new SubDReg(machInst, rd, rn, rm, 0, LSL);
case 0x2:
return new AddDImm(machInst, rd, rn, imm3, true);
case 0x3:
return new SubDImm(machInst, rd, rn, imm3, true);
}
case 0x4:
return new MovDImm(machInst, rd8, INTREG_ZERO, imm8, true);
case 0x5:
return new CmpDImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
case 0x6:
return new AddDImm(machInst, rd8, rd8, imm8, true);
case 0x7:
return new SubDImm(machInst, rd8, rd8, imm8, true);
}
}
'''
}};
def format Thumb16DataProcessing() {{
decode_block = '''
{
const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
switch (bits(machInst, 9, 6)) {
case 0x0:
return new AndDReg(machInst, rdn, rdn, rm, 0, LSL);
case 0x1:
return new EorDReg(machInst, rdn, rdn, rm, 0, LSL);
case 0x2: //lsl
return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
case 0x3: //lsr
return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
case 0x4: //asr
return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
case 0x5:
return new AdcDReg(machInst, rdn, rdn, rm, 0, LSL);
case 0x6:
return new SbcDReg(machInst, rdn, rdn, rm, 0, LSL);
case 0x7: // ror
return new MovDRegReg(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
case 0x8:
return new TstDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
case 0x9:
return new RsbDImm(machInst, rdn, rm, 0, true);
case 0xa:
return new CmpDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
case 0xb:
return new CmnDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
case 0xc:
return new OrrDReg(machInst, rdn, rdn, rm, 0, LSL);
case 0xd:
//XXX Implement me!
return new WarnUnimplemented("mul", machInst);
case 0xe:
return new BicDReg(machInst, rdn, rdn, rm, 0, LSL);
case 0xf:
return new MvnDReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
}
}
'''
}};
def format Thumb16SpecDataAndBx() {{
decode_block = '''
{
const IntRegIndex rdn =
(IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
(bits(machInst, 7) << 3));
const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
switch (bits(machInst, 9, 8)) {
case 0x0:
return new AddDReg(machInst, rdn, rdn, rm, 0, LSL);
case 0x1:
return new CmpDReg(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
case 0x2:
return new MovDReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
case 0x3:
if (bits(machInst, 7) == 0)
return new WarnUnimplemented("bx", machInst);
else
// The register version.
return new WarnUnimplemented("blx", machInst);
}
}
'''
}};
def format Thumb16Adr() {{
decode_block = '''
{
const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
const uint32_t imm8 = bits(machInst, 7, 0) << 2;
return new AddDImm(machInst, rd, INTREG_PC, imm8, true);
}
'''
}};
def format Thumb16AddSp() {{
decode_block = '''
{
const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
const uint32_t imm8 = bits(machInst, 7, 0) << 2;
return new AddDImm(machInst, rd, INTREG_SP, imm8, true);
}
'''
}};
def format Thumb16Misc() {{
decode_block = '''
{
switch (bits(machInst, 11, 8)) {
case 0x0:
if (bits(machInst, 7)) {
return new SubDImm(machInst, INTREG_SP, INTREG_SP,
bits(machInst, 6, 0) << 2, true);
} else {
return new AddDImm(machInst, INTREG_SP, INTREG_SP,
bits(machInst, 6, 0) << 2, true);
}
case 0x1:
return new WarnUnimplemented("cbz", machInst);
case 0x2:
switch (bits(machInst, 7, 6)) {
case 0x0:
return new WarnUnimplemented("sxth", machInst);
case 0x1:
return new WarnUnimplemented("sxtb", machInst);
case 0x2:
return new WarnUnimplemented("uxth", machInst);
case 0x3:
return new WarnUnimplemented("uxtb", machInst);
}
case 0x3:
return new WarnUnimplemented("cbnz", machInst);
case 0x4:
case 0x5:
return new WarnUnimplemented("push", machInst);
case 0x6:
{
const uint32_t opBits = bits(machInst, 7, 5);
if (opBits == 2) {
return new WarnUnimplemented("setend", machInst);
} else if (opBits == 3) {
return new WarnUnimplemented("cps", machInst);
}
}
case 0x9:
return new WarnUnimplemented("cbz", machInst);
case 0xa:
switch (bits(machInst, 7, 5)) {
case 0x0:
return new WarnUnimplemented("rev", machInst);
case 0x1:
return new WarnUnimplemented("rev16", machInst);
case 0x3:
return new WarnUnimplemented("revsh", machInst);
default:
break;
}
break;
case 0xb:
return new WarnUnimplemented("cbnz", machInst);
case 0xc:
case 0xd:
return new WarnUnimplemented("pop", machInst);
case 0xe:
return new WarnUnimplemented("bkpt", machInst);
case 0xf:
if (bits(machInst, 3, 0) != 0)
return new WarnUnimplemented("it", machInst);
switch (bits(machInst, 7, 4)) {
case 0x0:
return new WarnUnimplemented("nop", machInst);
case 0x1:
return new WarnUnimplemented("yield", machInst);
case 0x2:
return new WarnUnimplemented("wfe", machInst);
case 0x3:
return new WarnUnimplemented("wfi", machInst);
case 0x4:
return new WarnUnimplemented("sev", machInst);
default:
return new WarnUnimplemented("unallocated_hint", machInst);
}
default:
break;
}
return new Unknown(machInst);
}
'''
}};
def format Thumb32DataProcModImm() {{
def decInst(mnem, dest="rd", op1="rn"):
return '''
if (s) {
return new %(mnem)sDImmCc(machInst, %(dest)s,
%(op1)s, imm, true);
} else {
return new %(mnem)sDImm(machInst, %(dest)s,
%(op1)s, imm, true);
}
''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
decode_block = '''
{
const uint32_t op = bits(machInst, 24, 21);
const bool s = (bits(machInst, 20) == 1);
const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
bits(machInst, 14, 12);
const uint32_t dataImm = bits(machInst, 7, 0);
const uint32_t imm = modified_imm(ctrlImm, dataImm);
switch (op) {
case 0x0:
if (rd == INTREG_PC) {
%(tst)s
} else {
%(and)s
}
case 0x1:
%(bic)s
case 0x2:
if (rn == INTREG_PC) {
%(mov)s
} else {
%(orr)s
}
case 0x3:
if (rn == INTREG_PC) {
%(mvn)s
} else {
%(orn)s
}
case 0x4:
if (rd == INTREG_PC) {
%(teq)s
} else {
%(eor)s
}
case 0x8:
if (rd == INTREG_PC) {
%(cmn)s
} else {
%(add)s
}
case 0xa:
%(adc)s
case 0xb:
%(sbc)s
case 0xd:
if (rd == INTREG_PC) {
%(cmp)s
} else {
%(sub)s
}
case 0xe:
%(rsb)s
default:
return new Unknown(machInst);
}
}
''' % {
"tst" : decInst("Tst", "INTREG_ZERO"),
"and" : decInst("And"),
"bic" : decInst("Bic"),
"mov" : decInst("Mov", op1="INTREG_ZERO"),
"orr" : decInst("Orr"),
"mvn" : decInst("Mvn", op1="INTREG_ZERO"),
"orn" : decInst("Orn"),
"teq" : decInst("Teq", dest="INTREG_ZERO"),
"eor" : decInst("Eor"),
"cmn" : decInst("Cmn", dest="INTREG_ZERO"),
"add" : decInst("Add"),
"adc" : decInst("Adc"),
"sbc" : decInst("Sbc"),
"cmp" : decInst("Cmp", dest="INTREG_ZERO"),
"sub" : decInst("Sub"),
"rsb" : decInst("Rsb")
}
}};
def format Thumb32DataProcShiftReg() {{
def decInst(mnem, dest="rd", op1="rn"):
return '''
if (s) {
return new %(mnem)sDRegCc(machInst, %(dest)s,
%(op1)s, rm, amt, type);
} else {
return new %(mnem)sDReg(machInst, %(dest)s,
%(op1)s, rm, amt, type);
}
''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
decode_block = '''
{
const uint32_t op = bits(machInst, 24, 21);
const bool s = (bits(machInst, 20) == 1);
const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
const uint32_t amt = (bits(machInst, 14, 12) << 2) |
bits(machInst, 7, 6);
const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
switch (op) {
case 0x0:
if (rd == INTREG_PC) {
%(tst)s
} else {
%(and)s
}
case 0x1:
%(bic)s
case 0x2:
if (rn == INTREG_PC) {
%(mov)s
} else {
%(orr)s
}
case 0x3:
if (rn == INTREG_PC) {
%(mvn)s
} else {
%(orn)s
}
case 0x4:
if (rd == INTREG_PC) {
%(teq)s
} else {
%(eor)s
}
case 0x6:
return new WarnUnimplemented("pkh", machInst);
case 0x8:
if (rd == INTREG_PC) {
%(cmn)s
} else {
%(add)s
}
case 0xa:
%(adc)s
case 0xb:
%(sbc)s
case 0xd:
if (rd == INTREG_PC) {
%(cmp)s
} else {
%(sub)s
}
case 0xe:
%(rsb)s
default:
return new Unknown(machInst);
}
}
''' % {
"tst" : decInst("Tst", "INTREG_ZERO"),
"and" : decInst("And"),
"bic" : decInst("Bic"),
"mov" : decInst("Mov", op1="INTREG_ZERO"),
"orr" : decInst("Orr"),
"mvn" : decInst("Mvn", op1="INTREG_ZERO"),
"orn" : decInst("Orn"),
"teq" : decInst("Teq", "INTREG_ZERO"),
"eor" : decInst("Eor"),
"cmn" : decInst("Cmn", "INTREG_ZERO"),
"add" : decInst("Add"),
"adc" : decInst("Adc"),
"sbc" : decInst("Sbc"),
"cmp" : decInst("Cmp", "INTREG_ZERO"),
"sub" : decInst("Sub"),
"rsb" : decInst("Rsb")
}
}};