diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arm/isa/decoder/thumb.isa | 10 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/branch.isa | 27 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/data.isa | 34 |
3 files changed, 55 insertions, 16 deletions
diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa index 9071649a2..349a4a87d 100644 --- a/src/arch/arm/isa/decoder/thumb.isa +++ b/src/arch/arm/isa/decoder/thumb.isa @@ -58,14 +58,10 @@ } 0x6: decode TOPCODE_12_11 { 0x0, 0x1: Thumb16MacroMem::thumb16MacroMem(); - default: decode TOPCODE_11_8 { - 0xe: WarnUnimpl::undefined(); // permanently undefined - 0xf: WarnUnimpl::svc(); // formerly swi - default: WarnUnimpl::b(); // conditional - } + 0x2, 0x3: Thumb16CondBranchAndSvc::thumb16CondBranchAndSvc(); } 0x7: decode TOPCODE_12_11 { - 0x0: WarnUnimpl::b(); // unconditional + 0x0: Thumb16UncondBranch::thumb16UncondBranch(); } } @@ -165,7 +161,7 @@ 0x0: Thumb32DataProcModImm::thumb32DataProcModImm(); 0x1: WarnUnimpl::Data_processing_plain_binary_immediate(); } - 0x1: WarnUnimpl::Branches_and_miscellaneous_control(); + 0x1: BranchesAndMiscCtrl::branchesAndMiscCtrl(); } 0x3: decode HTOPCODE_10_9 { 0x0: decode HTOPCODE_4 { diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa index 63bb11227..0be00c20c 100644 --- a/src/arch/arm/isa/formats/branch.isa +++ b/src/arch/arm/isa/formats/branch.isa @@ -84,3 +84,30 @@ def format ArmBlxReg() {{ (ConditionCode)(uint32_t)machInst.condCode); ''' }}; + +def format Thumb16CondBranchAndSvc() {{ + decode_block = ''' + if (bits(machInst, 11, 9) != 0x7) { + return new B(machInst, sext<9>(bits(machInst, 7, 0) << 1), + (ConditionCode)(uint32_t)bits(machInst, 11, 8)); + } else if (bits(machInst, 8)) { + return new WarnUnimplemented("svc", machInst); + } else { + // This space will not be allocated in the future. + return new WarnUnimplemented("unimplemented", machInst); + } + ''' +}}; + +def format Thumb16UncondBranch() {{ + decode_block = ''' + return new B(machInst, sext<12>(bits(machInst, 10, 0) << 1), COND_UC); + ''' +}}; + +def format Thumb32 BranchesAndMiscCtrl() {{ + decode_block = ''' + return new WarnUnimplemented("Branches_and_miscellaneous_control", + machInst); + ''' +}}; diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa index ad59d7081..cfe25e025 100644 --- a/src/arch/arm/isa/formats/data.isa +++ b/src/arch/arm/isa/formats/data.isa @@ -256,11 +256,15 @@ def format Thumb16SpecDataAndBx() {{ case 0x2: return new MovReg(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); + if (bits(machInst, 7) == 0) { + return new BxReg(machInst, + (IntRegIndex)(uint32_t)bits(machInst, 6, 3), + COND_UC); + } else { + return new BlxReg(machInst, + (IntRegIndex)(uint32_t)bits(machInst, 6, 3), + COND_UC); + } } } ''' @@ -299,7 +303,10 @@ def format Thumb16Misc() {{ bits(machInst, 6, 0) << 2, true); } case 0x1: - return new WarnUnimplemented("cbz", machInst); + return new Cbz(machInst, + (bits(machInst, 9) << 6) | + (bits(machInst, 7, 3) << 1), + (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); case 0x2: switch (bits(machInst, 7, 6)) { case 0x0: @@ -312,7 +319,10 @@ def format Thumb16Misc() {{ return new WarnUnimplemented("uxtb", machInst); } case 0x3: - return new WarnUnimplemented("cbnz", machInst); + return new Cbz(machInst, + (bits(machInst, 9) << 6) | + (bits(machInst, 7, 3) << 1), + (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); case 0x4: case 0x5: return new WarnUnimplemented("push", machInst); @@ -326,7 +336,10 @@ def format Thumb16Misc() {{ } } case 0x9: - return new WarnUnimplemented("cbz", machInst); + return new Cbnz(machInst, + (bits(machInst, 9) << 6) | + (bits(machInst, 7, 3) << 1), + (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); case 0xa: switch (bits(machInst, 7, 5)) { case 0x0: @@ -340,7 +353,10 @@ def format Thumb16Misc() {{ } break; case 0xb: - return new WarnUnimplemented("cbnz", machInst); + return new Cbnz(machInst, + (bits(machInst, 9) << 6) | + (bits(machInst, 7, 3) << 1), + (IntRegIndex)(uint32_t)bits(machInst, 2, 0)); case 0xc: case 0xd: return new WarnUnimplemented("pop", machInst); |