summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/isa/decoder/thumb.isa10
-rw-r--r--src/arch/arm/isa/formats/branch.isa27
-rw-r--r--src/arch/arm/isa/formats/data.isa34
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);