Add unpredictable checks when the instruction has to be last in IT block
Some instructions may only be used inside an IT block when there are the last
one, add checks for this in the assembler.
- BL
- BLX
- BX
- BXJ
- SUBS
Change-Id: I2c6e76580cb8b25900ab7b336910ddaa72bef66f
diff --git a/src/aarch32/assembler-aarch32.cc b/src/aarch32/assembler-aarch32.cc
index 93b5c03..4a9960b 100644
--- a/src/aarch32/assembler-aarch32.cc
+++ b/src/aarch32/assembler-aarch32.cc
@@ -3236,7 +3236,8 @@
// BL{<c>}{<q>} <label> ; T1
if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
((offset & 0x1) == 0)) ||
- !label->IsBound())) {
+ !label->IsBound()) &&
+ (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
static class EmitOp : public Label::LabelEmitOperator {
public:
EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
@@ -3296,7 +3297,8 @@
// BLX{<c>}{<q>} <label> ; T2
if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777212) &&
((offset & 0x3) == 0)) ||
- !label->IsBound())) {
+ !label->IsBound()) &&
+ (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
static class EmitOp : public Label::LabelEmitOperator {
public:
EmitOp() : Label::LabelEmitOperator(-16777216, 16777212) {}
@@ -3350,7 +3352,8 @@
CheckIT(cond);
if (IsUsingT32()) {
// BLX{<c>}{<q>} <Rm> ; T1
- if ((!rm.IsPC() || AllowUnpredictable())) {
+ if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
+ AllowUnpredictable())) {
EmitT32_16(0x4780 | (rm.GetCode() << 3));
AdvanceIT();
return;
@@ -3370,9 +3373,11 @@
CheckIT(cond);
if (IsUsingT32()) {
// BX{<c>}{<q>} <Rm> ; T1
- EmitT32_16(0x4700 | (rm.GetCode() << 3));
- AdvanceIT();
- return;
+ if ((OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
+ EmitT32_16(0x4700 | (rm.GetCode() << 3));
+ AdvanceIT();
+ return;
+ }
} else {
// BX{<c>}{<q>} <Rm> ; A1
if (cond.IsNotNever()) {
@@ -3388,7 +3393,8 @@
CheckIT(cond);
if (IsUsingT32()) {
// BXJ{<c>}{<q>} <Rm> ; T1
- if ((!rm.IsPC() || AllowUnpredictable())) {
+ if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
+ AllowUnpredictable())) {
EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
AdvanceIT();
return;
@@ -11775,7 +11781,8 @@
return;
}
// SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
- if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255)) {
+ if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255) &&
+ (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
EmitT32_32(0xf3de8f00U | imm);
AdvanceIT();
return;