summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGene Wu <Gene.Wu@arm.com>2010-08-23 11:18:41 -0500
committerGene Wu <Gene.Wu@arm.com>2010-08-23 11:18:41 -0500
commit66bcbec96e9bb9619b306a281cb18e2b4cea91c5 (patch)
tree7cd3bdd69fb3fd19c59bcb1879491334be421d41 /src
parentad2c3b008dbc0496bdf4d80c93275e0bbebbb4fb (diff)
downloadgem5-66bcbec96e9bb9619b306a281cb18e2b4cea91c5.tar.xz
ARM: BX instruction can be contitional if last instruction in a IT block
Branches are allowed to be the last instuction in an IT block. Before it was assumed that they could not. So Branches in thumb2 were Uncond.
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/isa/formats/branch.isa29
-rw-r--r--src/arch/arm/isa/formats/data.isa16
-rw-r--r--src/arch/arm/isa/formats/uncond.isa2
-rw-r--r--src/arch/arm/isa/insts/branch.isa6
4 files changed, 42 insertions, 11 deletions
diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
index e47665266..f203d5257 100644
--- a/src/arch/arm/isa/formats/branch.isa
+++ b/src/arch/arm/isa/formats/branch.isa
@@ -50,7 +50,7 @@ def format ArmBBlxImm() {{
if (machInst.condCode == 0xF) {
int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
(bits(machInst, 24) << 1);
- return new BlxImm(machInst, imm);
+ return new BlxImm(machInst, imm, COND_UC);
} else {
return new B(machInst, sext<26>(bits(machInst, 23, 0) << 2),
(ConditionCode)(uint32_t)machInst.condCode);
@@ -63,7 +63,7 @@ def format ArmBlBlxImm() {{
if (machInst.condCode == 0xF) {
int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
(bits(machInst, 24) << 1);
- return new BlxImm(machInst, imm);
+ return new BlxImm(machInst, imm, COND_UC);
} else {
return new Bl(machInst, sext<26>(bits(machInst, 23, 0) << 2),
(ConditionCode)(uint32_t)machInst.condCode);
@@ -236,6 +236,13 @@ def format Thumb32BranchesAndMiscCtrl() {{
}
case 0x1:
{
+ ConditionCode condCode;
+ if(machInst.itstateMask) {
+ condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
+ } else {
+ condCode = COND_UC;
+ }
+
const uint32_t s = bits(machInst, 26);
const uint32_t i1 = !(bits(machInst, 13) ^ s);
const uint32_t i2 = !(bits(machInst, 11) ^ s);
@@ -244,13 +251,19 @@ def format Thumb32BranchesAndMiscCtrl() {{
const int32_t imm = sext<25>((s << 24) |
(i1 << 23) | (i2 << 22) |
(imm10 << 12) | (imm11 << 1));
- return new B(machInst, imm, COND_UC);
+ return new B(machInst, imm, condCode);
}
case 0x4:
{
if (bits(machInst, 0) == 1) {
return new Unknown(machInst);
}
+ ConditionCode condCode;
+ if(machInst.itstateMask) {
+ condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
+ } else {
+ condCode = COND_UC;
+ }
const uint32_t s = bits(machInst, 26);
const uint32_t i1 = !(bits(machInst, 13) ^ s);
const uint32_t i2 = !(bits(machInst, 11) ^ s);
@@ -259,10 +272,16 @@ def format Thumb32BranchesAndMiscCtrl() {{
const int32_t imm = sext<25>((s << 24) |
(i1 << 23) | (i2 << 22) |
(imm10h << 12) | (imm10l << 2));
- return new BlxImm(machInst, imm);
+ return new BlxImm(machInst, imm, condCode);
}
case 0x5:
{
+ ConditionCode condCode;
+ if(machInst.itstateMask) {
+ condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
+ } else {
+ condCode = COND_UC;
+ }
const uint32_t s = bits(machInst, 26);
const uint32_t i1 = !(bits(machInst, 13) ^ s);
const uint32_t i2 = !(bits(machInst, 11) ^ s);
@@ -271,7 +290,7 @@ def format Thumb32BranchesAndMiscCtrl() {{
const int32_t imm = sext<25>((s << 24) |
(i1 << 23) | (i2 << 22) |
(imm10 << 12) | (imm11 << 1));
- return new Bl(machInst, imm, COND_UC);
+ return new Bl(machInst, imm, condCode);
}
default:
break;
diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa
index a2e748bcb..03a585001 100644
--- a/src/arch/arm/isa/formats/data.isa
+++ b/src/arch/arm/isa/formats/data.isa
@@ -1040,13 +1040,25 @@ def format Thumb16SpecDataAndBx() {{
return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
case 0x3:
if (bits(machInst, 7) == 0) {
+ ConditionCode condCode;
+ if(machInst.itstateMask) {
+ condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
+ } else {
+ condCode = COND_UC;
+ }
return new BxReg(machInst,
(IntRegIndex)(uint32_t)bits(machInst, 6, 3),
- COND_UC);
+ condCode);
} else {
+ ConditionCode condCode;
+ if(machInst.itstateMask) {
+ condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
+ } else {
+ condCode = COND_UC;
+ }
return new BlxReg(machInst,
(IntRegIndex)(uint32_t)bits(machInst, 6, 3),
- COND_UC);
+ condCode);
}
}
}
diff --git a/src/arch/arm/isa/formats/uncond.isa b/src/arch/arm/isa/formats/uncond.isa
index 4fa707b2b..079b472f3 100644
--- a/src/arch/arm/isa/formats/uncond.isa
+++ b/src/arch/arm/isa/formats/uncond.isa
@@ -231,7 +231,7 @@ def format ArmUnconditional() {{
const uint32_t imm =
(sext<26>(bits(machInst, 23, 0) << 2)) |
(bits(machInst, 24) << 1);
- return new BlxImm(machInst, imm);
+ return new BlxImm(machInst, imm, COND_UC);
}
case 0x2:
if (bits(op1, 4, 0) != 0) {
diff --git a/src/arch/arm/isa/insts/branch.isa b/src/arch/arm/isa/insts/branch.isa
index 089a2e7d9..98e751e1a 100644
--- a/src/arch/arm/isa/insts/branch.isa
+++ b/src/arch/arm/isa/insts/branch.isa
@@ -87,9 +87,9 @@ let {{
# Since we're switching ISAs, the target ISA will be the opposite
# of the current ISA. !arm is whether the target is ARM.
newPC = '(!arm ? (roundDown(curPc, 4) + imm) : (curPc + imm))'
- base = "BranchImm"
- declare = BranchImmDeclare
- constructor = BranchImmConstructor
+ base = "BranchImmCond"
+ declare = BranchImmCondDeclare
+ constructor = BranchImmCondConstructor
else:
Name += "Reg"
newPC = 'Op1'