Add unpredictable conditions for ADC_i, ADC_r, ADC_rr, ADD_ADR, ADD_i, ADD_r, ADD_rr, ADD_SP_i, ADD_SP_r, ADR and MOV_i.
Change-Id: I2d0255c352881d855b375db65794ee7f282b1cfe
diff --git a/src/aarch32/assembler-aarch32.cc b/src/aarch32/assembler-aarch32.cc
index 43945af..a1c2630 100644
--- a/src/aarch32/assembler-aarch32.cc
+++ b/src/aarch32/assembler-aarch32.cc
@@ -1806,7 +1806,8 @@
if (IsUsingT32()) {
ImmediateT32 immediate_t32(imm);
// ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
- if (!size.IsNarrow() && immediate_t32.IsValid()) {
+ if (!size.IsNarrow() && immediate_t32.IsValid() &&
+ ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
(immediate_t32.GetEncodingValue() & 0xff) |
((immediate_t32.GetEncodingValue() & 0x700) << 4) |
@@ -1842,7 +1843,8 @@
uint32_t amount = operand.GetShiftAmount();
if (IsUsingT32()) {
// ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
- if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
+ if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
+ ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
uint32_t amount_ = amount % 32;
EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
@@ -1866,7 +1868,9 @@
Shift shift = operand.GetShift();
if (IsUsingA32()) {
// ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
- if (cond.IsNotNever()) {
+ if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
+ !operand.GetShiftRegister().IsPC()) ||
+ AllowUnpredictable())) {
EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
(rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
(shift.GetType() << 5) |
@@ -1890,7 +1894,8 @@
if (IsUsingT32()) {
ImmediateT32 immediate_t32(imm);
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
- if (!size.IsNarrow() && immediate_t32.IsValid()) {
+ if (!size.IsNarrow() && immediate_t32.IsValid() &&
+ ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
(immediate_t32.GetEncodingValue() & 0xff) |
((immediate_t32.GetEncodingValue() & 0x700) << 4) |
@@ -1926,7 +1931,8 @@
uint32_t amount = operand.GetShiftAmount();
if (IsUsingT32()) {
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
- if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
+ if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
+ ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
uint32_t amount_ = amount % 32;
EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
@@ -1950,7 +1956,9 @@
Shift shift = operand.GetShift();
if (IsUsingA32()) {
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
- if (cond.IsNotNever()) {
+ if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
+ !operand.GetShiftRegister().IsPC()) ||
+ AllowUnpredictable())) {
EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
(rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
(shift.GetType() << 5) |
@@ -2012,14 +2020,16 @@
return;
}
// ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
- if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
+ if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
((imm & 0x700) << 4) | ((imm & 0x800) << 15));
AdvanceIT();
return;
}
// ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
- if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
+ if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
+ ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
(immediate_t32.GetEncodingValue() & 0xff) |
((immediate_t32.GetEncodingValue() & 0x700) << 4) |
@@ -2028,14 +2038,16 @@
return;
}
// ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
- if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
+ if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
(imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
AdvanceIT();
return;
}
// ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
- if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
+ if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
(immediate_t32.GetEncodingValue() & 0xff) |
((immediate_t32.GetEncodingValue() & 0x700) << 4) |
@@ -2044,7 +2056,8 @@
return;
}
// ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
- if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
+ if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
((imm & 0x700) << 4) | ((imm & 0x800) << 15));
AdvanceIT();
@@ -2087,14 +2100,19 @@
return;
}
// ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
- if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp)) {
+ if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
+ (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
+ (!rd.IsPC() || !rm.IsPC())) ||
+ AllowUnpredictable())) {
EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
AdvanceIT();
return;
}
// ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
- if (!size.IsWide() && rd.Is(rm) && rn.Is(sp)) {
+ if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
+ (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond))) ||
+ AllowUnpredictable())) {
EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
((rd.GetCode() & 0x8) << 4));
AdvanceIT();
@@ -2112,7 +2130,8 @@
uint32_t amount = operand.GetShiftAmount();
if (IsUsingT32()) {
// ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
- if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
+ if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
+ ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
uint32_t amount_ = amount % 32;
EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
@@ -2121,7 +2140,8 @@
return;
}
// ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
- if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
+ if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
+ ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
uint32_t amount_ = amount % 32;
EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
(operand.GetTypeEncodingValue() << 4) |
@@ -2153,7 +2173,9 @@
Shift shift = operand.GetShift();
if (IsUsingA32()) {
// ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
- if (cond.IsNotNever()) {
+ if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
+ !operand.GetShiftRegister().IsPC()) ||
+ AllowUnpredictable())) {
EmitA32(0x00800010U | (cond.GetCondition() << 28) |
(rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
(shift.GetType() << 5) |
@@ -2183,7 +2205,10 @@
Register rm = operand.GetBaseRegister();
if (IsUsingT32()) {
// ADD<c>{<q>} <Rdn>, <Rm> ; T2
- if (InITBlock() && !rm.Is(sp)) {
+ if (InITBlock() && !rm.Is(sp) &&
+ (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
+ (!rd.IsPC() || !rm.IsPC())) ||
+ AllowUnpredictable())) {
EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
(rm.GetCode() << 3));
AdvanceIT();
@@ -2221,7 +2246,7 @@
}
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
- !rd.Is(pc)) {
+ !rd.Is(pc) && ((!rn.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
(immediate_t32.GetEncodingValue() & 0xff) |
((immediate_t32.GetEncodingValue() & 0x700) << 4) |
@@ -2275,7 +2300,7 @@
if (IsUsingT32()) {
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
- !rd.Is(pc)) {
+ !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
uint32_t amount_ = amount % 32;
EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
@@ -2285,7 +2310,7 @@
}
// ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
- !rd.Is(pc)) {
+ !rd.Is(pc) && ((!rm.IsPC()) || AllowUnpredictable())) {
uint32_t amount_ = amount % 32;
EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
(operand.GetTypeEncodingValue() << 4) |
@@ -2317,7 +2342,9 @@
Shift shift = operand.GetShift();
if (IsUsingA32()) {
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
- if (cond.IsNotNever()) {
+ if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
+ !operand.GetShiftRegister().IsPC()) ||
+ AllowUnpredictable())) {
EmitA32(0x00900010U | (cond.GetCondition() << 28) |
(rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
(shift.GetType() << 5) |
@@ -2356,21 +2383,24 @@
uint32_t imm = operand.GetImmediate();
if (IsUsingT32()) {
// ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
- if (rn.Is(pc) && (imm <= 4095)) {
+ if (rn.Is(pc) && (imm <= 4095) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
((imm & 0x700) << 4) | ((imm & 0x800) << 15));
AdvanceIT();
return;
}
// ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
- if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
+ if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
(imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
AdvanceIT();
return;
}
// ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
- if (rn.Is(sp) && (imm <= 4095)) {
+ if (rn.Is(sp) && (imm <= 4095) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
((imm & 0x700) << 4) | ((imm & 0x800) << 15));
AdvanceIT();
@@ -2418,7 +2448,7 @@
}
// ADR{<c>}{<q>} <Rd>, <label> ; T2
if (!size.IsNarrow() && label->IsBound() && (neg_offset > 0) &&
- (neg_offset <= 4095)) {
+ (neg_offset <= 4095) && ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
AdvanceIT();
@@ -2426,7 +2456,8 @@
}
// ADR{<c>}{<q>} <Rd>, <label> ; T3
if (!size.IsNarrow() &&
- (!label->IsBound() || ((offset >= 0) && (offset <= 4095)))) {
+ (!label->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
static class EmitOp : public Label::LabelEmitOperator {
public:
EmitOp() : Label::LabelEmitOperator(0, 4095) {}
@@ -6479,7 +6510,8 @@
return;
}
// MOV{<c>}{<q>} <Rd>, #<const> ; T2
- if (!size.IsNarrow() && immediate_t32.IsValid()) {
+ if (!size.IsNarrow() && immediate_t32.IsValid() &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
(immediate_t32.GetEncodingValue() & 0xff) |
((immediate_t32.GetEncodingValue() & 0x700) << 4) |
@@ -6488,7 +6520,8 @@
return;
}
// MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
- if (!size.IsNarrow() && (imm <= 65535)) {
+ if (!size.IsNarrow() && (imm <= 65535) &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
((imm & 0xf000) << 4));
@@ -6504,7 +6537,8 @@
return;
}
// MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
- if ((imm <= 65535) && cond.IsNotNever()) {
+ if ((imm <= 65535) && cond.IsNotNever() &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitA32(0x03000000U | (cond.GetCondition() << 28) |
(rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
return;
@@ -6620,7 +6654,8 @@
return;
}
// MOVS{<c>}{<q>} <Rd>, #<const> ; T2
- if (!size.IsNarrow() && immediate_t32.IsValid()) {
+ if (!size.IsNarrow() && immediate_t32.IsValid() &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
(immediate_t32.GetEncodingValue() & 0xff) |
((immediate_t32.GetEncodingValue() & 0x700) << 4) |
@@ -6674,7 +6709,7 @@
uint32_t imm = operand.GetImmediate();
if (IsUsingT32()) {
// MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
- if ((imm <= 65535)) {
+ if ((imm <= 65535) && ((!rd.IsPC()) || AllowUnpredictable())) {
EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
((imm & 0xf000) << 4));
@@ -6683,7 +6718,8 @@
}
} else {
// MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
- if ((imm <= 65535) && cond.IsNotNever()) {
+ if ((imm <= 65535) && cond.IsNotNever() &&
+ ((!rd.IsPC()) || AllowUnpredictable())) {
EmitA32(0x03000000U | (cond.GetCondition() << 28) |
(rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
return;