Emit(encoding);
}
-
+#if 0
+// Moved to ARM32::AssemblerARM32::vldrs()
void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sd != kNoSRegister);
B11 | B9 | ad.vencoding();
Emit(encoding);
}
-
+#endif
void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported());
Emit(encoding);
}
-
+#if 0
+// Moved to ARM32::AssemblerARM32::vldrd()
void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(dd != kNoDRegister);
B11 | B9 | B8 | ad.vencoding();
Emit(encoding);
}
-
+#endif
void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported());
bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
bool vmovd(DRegister dd, double d_imm, Condition cond = AL);
+#if 0
+ // Moved to ARM32::AssemblerARM32::vldrs()
void vldrs(SRegister sd, Address ad, Condition cond = AL);
+#endif
void vstrs(SRegister sd, Address ad, Condition cond = AL);
+#if 0
+ // Moved to ARM32::AssemblerARM32::vldrd()
void vldrd(DRegister dd, Address ad, Condition cond = AL);
+#endif
void vstrd(DRegister dd, Address ad, Condition cond = AL);
void vldms(BlockAddressMode am, Register base,
//
// ***** OpEncodingMemEx *****
//
- // Value=000000000000nnnn0000000000000000 where nnnn=Rn.
+ // Value=00000000U000nnnn00000000xxxxxxxx where nnnn=Rn, xxxxxxxx=abs(Offset),
+ // and U=1 Offset>=0.
EncodedAsImmRegOffset,
// Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
// mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
emitVFPddd(Cond, VdivdOpcode, Dd, Dn, Dm);
}
+void AssemblerARM32::vldrd(const Operand *OpDd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo) {
+ // VLDR - ARM section A8.8.333, encoding A1.
+ // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}]
+ //
+ // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
+ // iiiiiiii=abs(Opcode), and U=1 if Opcode>=0,
+ constexpr const char *Vldrd = "vldrd";
+ IValueT Dd = encodeDRegister(OpDd, "Dd", Vldrd);
+ assert(CondARM32::isDefined(Cond));
+ IValueT Address;
+ EncodedOperand AddressEncoding = encodeAddress(OpAddress, Address, TInfo);
+ (void)AddressEncoding;
+ assert(AddressEncoding == EncodedAsImmRegOffset);
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 |
+ (encodeCondition(Cond) << kConditionShift) |
+ (getYInRegYXXXX(Dd) << 22) |
+ (getXXXXInRegYXXXX(Dd) << 12) | Address;
+ emitInst(Encoding);
+}
+
+void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo) {
+ // VDLR - ARM section A8.8.333, encoding A2.
+ // vldr<c> <Sd>, [<Rn>{, #+/-<imm>]]
+ //
+ // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd,
+ // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0;
+ constexpr const char *Vldrs = "vldrs";
+ IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs);
+ assert(CondARM32::isDefined(Cond));
+ IValueT Address;
+ EncodedOperand AddressEncoding = encodeAddress(OpAddress, Address, TInfo);
+ (void)AddressEncoding;
+ assert(AddressEncoding == EncodedAsImmRegOffset);
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 |
+ (encodeCondition(Cond) << kConditionShift) |
+ (getYInRegXXXXY(Sd) << 22) |
+ (getXXXXInRegXXXXY(Sd) << 12) | Address;
+ emitInst(Encoding);
+}
+
void AssemblerARM32::vmuls(const Operand *OpSd, const Operand *OpSn,
const Operand *OpSm, CondARM32::Cond Cond) {
// VMUL (floating-point) - ARM section A8.8.351, encoding A2:
void vdivs(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
CondARM32::Cond Cond);
+ void vldrd(const Operand *OpDd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo);
+
+ void vldrd(const Operand *OpDd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetLowering *Lowering) {
+ const TargetInfo TInfo(Lowering);
+ vldrd(OpDd, OpAddress, Cond, TInfo);
+ }
+
+ void vldrs(const Operand *OpSd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo);
+
+ void vldrs(const Operand *OpSd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetLowering *Lowering) {
+ const TargetInfo TInfo(Lowering);
+ vldrs(OpSd, OpAddress, Cond, TInfo);
+ }
+
void vmuld(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
CondARM32::Cond Cond);
Variable *Dest = getDest();
Type DestTy = Dest->getType();
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
- if (isVectorType(DestTy) || isScalarFloatingType(DestTy))
+ if (isScalarFloatingType(DestTy)) {
+ if (DestTy == IceType_f32)
+ Asm->vldrs(Dest, getSrc(0), getPredicate(), Func->getTarget());
+ else
+ Asm->vldrd(Dest, getSrc(0), getPredicate(), Func->getTarget());
+ } else if (isVectorType(DestTy))
// TODO(kschimpf) Handle case.
Asm->setNeedsTextFixup();
else
--- /dev/null
+; Show that we know how to translate (floating point) vldr.
+
+; REQUIRES: allow_dump
+
+; Compile using standalone assembler.
+; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -O2 \
+; RUN: -reg-use r5,s20,d20 \
+; RUN: | FileCheck %s --check-prefix=ASM
+
+; Show bytes in assembled standalone code.
+; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \
+; RUN: --args -O2 \
+; RUN: -reg-use r5,s20,d20 \
+; RUN: | FileCheck %s --check-prefix=DIS
+
+; Compile using integrated assembler.
+; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
+; RUN: -reg-use r5,s20,d20 \
+; RUN: | FileCheck %s --check-prefix=IASM
+
+; Show bytes in assembled integrated code.
+; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
+; RUN: --args -O2 \
+; RUN: -reg-use r5,s20,d20 \
+; RUN: | FileCheck %s --check-prefix=DIS
+
+define internal float @testFloat() {
+; ASM-LABEL: testFloat:
+; DIS-LABEL: 00000000 <testFloat>:
+
+entry:
+; ASM: .LtestFloat$entry:
+
+ %vaddr = inttoptr i32 0 to float*
+ %v = load float, float* %vaddr, align 1
+
+; ASM: vldr s20, [r5]
+; DIS: c: ed95aa00
+; IASM-NOT: vldr
+
+ ret float %v
+}
+
+define internal double @testDouble() {
+; ASM-LABEL: testDouble:
+; DIS-LABEL: 00000020 <testDouble>:
+
+entry:
+; ASM: .LtestDouble$entry:
+
+; %vaddr = bitcast [8 x i8]* @doubleVal to double*
+ %vaddr = inttoptr i32 0 to double*
+ %v = load double, double* %vaddr, align 1
+
+; ASM: vldr d20, [r5]
+; DIS: 28: edd54b00
+; IASM-NOT: vldr
+
+ ret double %v
+}