diff options
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index bab626f5ae..5d62dcb4ff 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -5304,18 +5304,29 @@ bool LocationsBuilderARM::CanEncodeConstantAsImmediate(uint32_t value, return true; } Opcode neg_opcode = kNoOperand; + uint32_t neg_value = 0; switch (opcode) { - case AND: neg_opcode = BIC; value = ~value; break; - case ORR: neg_opcode = ORN; value = ~value; break; - case ADD: neg_opcode = SUB; value = -value; break; - case ADC: neg_opcode = SBC; value = ~value; break; - case SUB: neg_opcode = ADD; value = -value; break; - case SBC: neg_opcode = ADC; value = ~value; break; - case MOV: neg_opcode = MVN; value = ~value; break; + case AND: neg_opcode = BIC; neg_value = ~value; break; + case ORR: neg_opcode = ORN; neg_value = ~value; break; + case ADD: neg_opcode = SUB; neg_value = -value; break; + case ADC: neg_opcode = SBC; neg_value = ~value; break; + case SUB: neg_opcode = ADD; neg_value = -value; break; + case SBC: neg_opcode = ADC; neg_value = ~value; break; + case MOV: neg_opcode = MVN; neg_value = ~value; break; default: return false; } - return assembler->ShifterOperandCanHold(kNoRegister, kNoRegister, neg_opcode, value, set_cc, &so); + + if (assembler->ShifterOperandCanHold(kNoRegister, + kNoRegister, + neg_opcode, + neg_value, + set_cc, + &so)) { + return true; + } + + return opcode == AND && IsPowerOfTwo(value + 1); } void InstructionCodeGeneratorARM::HandleFieldGet(HInstruction* instruction, @@ -7571,9 +7582,11 @@ void InstructionCodeGeneratorARM::GenerateAndConst(Register out, Register first, ShifterOperand so; if (__ ShifterOperandCanHold(kNoRegister, kNoRegister, AND, value, &so)) { __ and_(out, first, so); - } else { - DCHECK(__ ShifterOperandCanHold(kNoRegister, kNoRegister, BIC, ~value, &so)); + } else if (__ ShifterOperandCanHold(kNoRegister, kNoRegister, BIC, ~value, &so)) { __ bic(out, first, ShifterOperand(~value)); + } else { + DCHECK(IsPowerOfTwo(value + 1)); + __ ubfx(out, first, 0, WhichPowerOf2(value + 1)); } } |