summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2014-12-18 15:53:02 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2014-12-18 15:53:03 +0000
commitca747ea9951188dbc6f5217d49aca34aeadcc2a6 (patch)
treedd1e534e7e065a98b59c0a13e31b16c08596688f /compiler
parentaa94a95d6174014f0ee89d4ff49bd769f44ac636 (diff)
parent5bc561c31d119a964e54cf73b475f8eac044d905 (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.cc57
-rw-r--r--compiler/utils/assembler_thumb_test_expected.cc.inc28
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[] = {