}
IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
- OperandARM32Mem::AddrMode Mode) {
+ OperandARM32Mem::AddrMode Mode,
+ IValueT OffsetShift = 0) {
IValueT Value = Mode | (Reg << kRnShift);
if (Offset < 0) {
- Value = (Value ^ U) | -Offset; // Flip U to adjust sign.
- } else {
- Value |= Offset;
+ Offset = -Offset;
+ Value ^= U; // Flip U to adjust sign.
}
- return Value;
+ return Value | (Offset >> OffsetShift);
}
// Encodes immediate register offset using encoding 3.
switch (AddressEncoding) {
case DefaultOpEncoding:
return encodeImmRegOffset(Reg, Offset, Mode);
- case ImmRegOffsetDiv4:
+ case ImmRegOffsetDiv4: {
assert((Offset & 0x3) == 0);
- return encodeImmRegOffset(Reg, Offset >> 2, Mode);
+ constexpr IValueT RightShift2 = 2;
+ return encodeImmRegOffset(Reg, Offset, Mode, RightShift2);
+ }
case OpEncoding3:
return encodeImmRegOffsetEnc3(Reg, Offset, Mode);
case OpEncodingMemEx:
bool IsGoodOffset = canEncodeBranchOffset(Offset);
assert(IsGoodOffset);
- // Note: Following cast is for MINIMAL build.
(void)IsGoodOffset;
// Properly preserve only the bits supported in the instruction.
IValueT Address;
EncodedOperand AddressEncoding =
encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
- if (AddressEncoding != EncodedAsImmRegOffset)
- // TODO(kschimpf) Fix this.
- return setNeedsTextFixup();
+ (void)AddressEncoding;
+ assert(AddressEncoding == EncodedAsImmRegOffset);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 |
(encodeCondition(Cond) << kConditionShift) |
IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs);
assert(CondARM32::isDefined(Cond));
IValueT Address;
- EncodedOperand AddressEncoding = encodeAddress(OpAddress, Address, TInfo);
+ EncodedOperand AddressEncoding =
+ encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
(void)AddressEncoding;
assert(AddressEncoding == EncodedAsImmRegOffset);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Address;
IValueT AddressEncoding =
encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
- if (AddressEncoding != EncodedAsImmRegOffset)
- // TODO(kschimpf) Fix this.
- return setNeedsTextFixup();
+ (void)AddressEncoding;
+ assert(AddressEncoding == EncodedAsImmRegOffset);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 |
(encodeCondition(Cond) << kConditionShift) |
IValueT Sd = encodeSRegister(OpSd, "Sd", Vstrs);
assert(CondARM32::isDefined(Cond));
IValueT Address;
- if (encodeAddress(OpAddress, Address, TInfo) != EncodedAsImmRegOffset)
- assert(false);
+ IValueT AddressEncoding =
+ encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
+ (void)AddressEncoding;
+ assert(AddressEncoding == EncodedAsImmRegOffset);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Encoding =
B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) |
-; Test vldrd and vstrd when address is offset with an immediate.
+; Test vldr{s,d} and vstr{s,d} when address is offset with an immediate.
; REQUIRES: allow_dump
; RUN: -reg-use d20 \
; RUN: | FileCheck %s --check-prefix=DIS
-define internal i64 @testVldrStrImm(double %d) {
-; ASM-LABEL: testVldrStrImm:
-; DIS-LABEL: 00000000 <testVldrStrImm>:
-; IASM-LABEL: testVldrStrImm:
+define internal i32 @testFloatImm(float %f) {
+; ASM-LABEL: testFloatImm:
+; DIS-LABEL: 00000000 <testFloatImm>:
+; IASM-LABEL: testFloatImm:
entry:
-; ASM-NEXT: .LtestVldrStrImm$entry:
-; IASM-NEXT: .LtestVldrStrImm$entry:
+; ASM: .LtestFloatImm$entry:
+; IASM: .LtestFloatImm$entry:
+
+; ASM: vstr s0, [sp, #4]
+; DIS: 4: ed8d0a01
+; IASM-NOT: vstr
+
+ %v = bitcast float %f to i32
+
+; ASM: vldr s0, [sp, #4]
+; DIS: 8: ed9d0a01
+; IASM-NOT: vldr
+
+ ret i32 %v
+}
+
+define internal i64 @testDoubleImm(double %d) {
+; ASM-LABEL: testDoubleImm:
+; DIS-LABEL: 00000020 <testDoubleImm>:
+; IASM-LABEL: testDoubleImm:
+
+entry:
+; ASM: .LtestDoubleImm$entry:
+; IASM: .LtestDoubleImm$entry:
; ASM: vstr d0, [sp, #8]
-; DIS: 4: ed8d0b02
+; DIS: 24: ed8d0b02
; IASM-NOT: vstr
%v = bitcast double %d to i64
; ASM: vldr d20, [sp, #8]
-; DIS: 8: eddd4b02
+; DIS: 28: eddd4b02
; IASM-NOT: vldr
ret i64 %v