diff options
Diffstat (limited to 'compiler/utils/arm/assembler_thumb2.cc')
-rw-r--r-- | compiler/utils/arm/assembler_thumb2.cc | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc index 479186c5d7..e262134e6e 100644 --- a/compiler/utils/arm/assembler_thumb2.cc +++ b/compiler/utils/arm/assembler_thumb2.cc @@ -698,48 +698,37 @@ bool Thumb2Assembler::Is32BitDataProcessing(Condition cond ATTRIBUTE_UNUSED, return true; } - bool can_contain_high_register = (opcode == MOV) - || ((opcode == ADD || opcode == SUB) && (rn == rd)); - - if (IsHighRegister(rd) || IsHighRegister(rn)) { - if (can_contain_high_register) { - // There are high register instructions available for this opcode. - // However, there is no RRX available. - if (so.IsShift() && so.GetShift() == RRX) { - return true; + // Check special case for SP relative ADD and SUB immediate. + if ((opcode == ADD || opcode == SUB) && rn == SP && so.IsImmediate()) { + // If the immediate is in range, use 16 bit. + if (rd == SP) { + if (so.GetImmediate() < (1 << 9)) { // 9 bit immediate. + return false; + } + } else if (!IsHighRegister(rd) && opcode == ADD) { + if (so.GetImmediate() < (1 << 10)) { // 10 bit immediate. + return false; } + } + } - // Check special case for SP relative ADD and SUB immediate. - if ((opcode == ADD || opcode == SUB) && so.IsImmediate()) { - // If rn is SP and rd is a high register we need to use a 32 bit encoding. - if (rn == SP && rd != SP && IsHighRegister(rd)) { - return true; - } + bool can_contain_high_register = (opcode == MOV) + || ((opcode == ADD) && (rn == rd)); - uint32_t imm = so.GetImmediate(); - // If the immediates are out of range use 32 bit. - if (rd == SP && rn == SP) { - if (imm > (1 << 9)) { // 9 bit immediate. - return true; - } - } else if (opcode == ADD && rd != SP && rn == SP) { // 10 bit immediate. - if (imm > (1 << 10)) { - return true; - } - } else if (opcode == SUB && rd != SP && rn == SP) { - // SUB rd, SP, #imm is always 32 bit. - return true; - } - } + if (IsHighRegister(rd) || IsHighRegister(rn)) { + if (!can_contain_high_register) { + return true; } - // The ADD,SUB and MOV instructions that work with high registers don't have - // immediate variants. - if (so.IsImmediate()) { + // There are high register instructions available for this opcode. + // However, there is no actual shift available, neither for ADD nor for MOV (ASR/LSR/LSL/ROR). + if (so.IsShift() && (so.GetShift() == RRX || so.GetImmediate() != 0u)) { return true; } - if (!can_contain_high_register) { + // The ADD and MOV instructions that work with high registers don't have 16-bit + // immediate variants. + if (so.IsImmediate()) { return true; } } |