diff options
author | 2014-12-18 15:53:02 +0000 | |
---|---|---|
committer | 2014-12-18 15:53:03 +0000 | |
commit | ca747ea9951188dbc6f5217d49aca34aeadcc2a6 (patch) | |
tree | dd1e534e7e065a98b59c0a13e31b16c08596688f /compiler | |
parent | aa94a95d6174014f0ee89d4ff49bd769f44ac636 (diff) | |
parent | 5bc561c31d119a964e54cf73b475f8eac044d905 (diff) |
Merge "Fix Thumb2 assembler to emit 16-bit add/sub SP, #imm."
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/utils/arm/assembler_thumb2.cc | 57 | ||||
-rw-r--r-- | compiler/utils/assembler_thumb_test_expected.cc.inc | 28 |
2 files changed, 37 insertions, 48 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; } } diff --git a/compiler/utils/assembler_thumb_test_expected.cc.inc b/compiler/utils/assembler_thumb_test_expected.cc.inc index 3f2641c76f..3d03234e04 100644 --- a/compiler/utils/assembler_thumb_test_expected.cc.inc +++ b/compiler/utils/assembler_thumb_test_expected.cc.inc @@ -102,11 +102,11 @@ const char* DataProcessingShiftedRegisterResults[] = { " 4: 11a3 asrs r3, r4, #6\n", " 6: ea4f 13f4 mov.w r3, r4, ror #7\n", " a: 41e3 rors r3, r4\n", - " c: 0128 lsls r0, r5, #4\n", - " e: 0968 lsrs r0, r5, #5\n", - " 10: 11a8 asrs r0, r5, #6\n", - " 12: ea4f 18f4 mov.w r8, r4, ror #7\n", - " 16: ea4f 0834 mov.w r8, r4, rrx\n", + " c: ea4f 1804 mov.w r8, r4, lsl #4\n", + " 10: ea4f 1854 mov.w r8, r4, lsr #5\n", + " 14: ea4f 18a4 mov.w r8, r4, asr #6\n", + " 18: ea4f 18f4 mov.w r8, r4, ror #7\n", + " 1c: ea4f 0834 mov.w r8, r4, rrx\n", nullptr }; const char* BasicLoadResults[] = { @@ -340,15 +340,15 @@ const char* MovWMovTResults[] = { nullptr }; const char* SpecialAddSubResults[] = { - " 0: f20d 0250 addw r2, sp, #80 ; 0x50\n", - " 4: f20d 0d50 addw sp, sp, #80 ; 0x50\n", - " 8: f20d 0850 addw r8, sp, #80 ; 0x50\n", - " c: f60d 7200 addw r2, sp, #3840 ; 0xf00\n", - " 10: f60d 7d00 addw sp, sp, #3840 ; 0xf00\n", - " 14: f2ad 0d50 subw sp, sp, #80 ; 0x50\n", - " 18: f2ad 0050 subw r0, sp, #80 ; 0x50\n", - " 1c: f2ad 0850 subw r8, sp, #80 ; 0x50\n", - " 20: f6ad 7d00 subw sp, sp, #3840 ; 0xf00\n", + " 0: aa14 add r2, sp, #80 ; 0x50\n", + " 2: b014 add sp, #80 ; 0x50\n", + " 4: f20d 0850 addw r8, sp, #80 ; 0x50\n", + " 8: f60d 7200 addw r2, sp, #3840 ; 0xf00\n", + " c: f60d 7d00 addw sp, sp, #3840 ; 0xf00\n", + " 10: b094 sub sp, #80 ; 0x50\n", + " 12: f2ad 0050 subw r0, sp, #80 ; 0x50\n", + " 16: f2ad 0850 subw r8, sp, #80 ; 0x50\n", + " 1a: f6ad 7d00 subw sp, sp, #3840 ; 0xf00\n", nullptr }; const char* StoreToOffsetResults[] = { |