diff options
| -rw-r--r-- | compiler/utils/arm/assembler_thumb2.cc | 3 | ||||
| -rw-r--r-- | compiler/utils/arm/assembler_thumb2_test.cc | 19 |
2 files changed, 22 insertions, 0 deletions
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc index 8747dad5e5..353c729249 100644 --- a/compiler/utils/arm/assembler_thumb2.cc +++ b/compiler/utils/arm/assembler_thumb2.cc @@ -2456,6 +2456,9 @@ void Thumb2Assembler::EmitLoadStore(Condition cond, } else if (!byte) { encoding |= B22; } + if (load && is_signed && (byte || half)) { + encoding |= B24; + } Emit32(encoding); } else { // 16 bit register offset. diff --git a/compiler/utils/arm/assembler_thumb2_test.cc b/compiler/utils/arm/assembler_thumb2_test.cc index f3fa72ccc6..abb09f726f 100644 --- a/compiler/utils/arm/assembler_thumb2_test.cc +++ b/compiler/utils/arm/assembler_thumb2_test.cc @@ -1450,4 +1450,23 @@ TEST_F(AssemblerThumb2Test, vpaddl) { DriverStr(expected, "vpaddl"); } +TEST_F(AssemblerThumb2Test, LoadFromShiftedRegOffset) { + arm::Address mem_address(arm::R0, arm::R1, arm::Shift::LSL, 2); + + __ ldrsb(arm::R2, mem_address); + __ ldrb(arm::R2, mem_address); + __ ldrsh(arm::R2, mem_address); + __ ldrh(arm::R2, mem_address); + __ ldr(arm::R2, mem_address); + + std::string expected = + "ldrsb r2, [r0, r1, LSL #2]\n" + "ldrb r2, [r0, r1, LSL #2]\n" + "ldrsh r2, [r0, r1, LSL #2]\n" + "ldrh r2, [r0, r1, LSL #2]\n" + "ldr r2, [r0, r1, LSL #2]\n"; + + DriverStr(expected, "LoadFromShiftedRegOffset"); +} + } // namespace art |