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.
This commit is contained in:
Gene Wu
2010-08-23 11:18:41 -05:00
parent ad2c3b008d
commit 66bcbec96e
4 changed files with 42 additions and 11 deletions

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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) {

View File

@@ -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'