Commit e1d71380 by Karl Schimpf

Add vdlr{s,d} to the integrated ARM assembler.

parent b9a404d4
...@@ -744,7 +744,8 @@ void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, ...@@ -744,7 +744,8 @@ void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
Emit(encoding); Emit(encoding);
} }
#if 0
// Moved to ARM32::AssemblerARM32::vldrs()
void Assembler::vldrs(SRegister sd, Address ad, Condition cond) { void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported()); ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sd != kNoSRegister); ASSERT(sd != kNoSRegister);
...@@ -756,7 +757,7 @@ void Assembler::vldrs(SRegister sd, Address ad, Condition cond) { ...@@ -756,7 +757,7 @@ void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
B11 | B9 | ad.vencoding(); B11 | B9 | ad.vencoding();
Emit(encoding); Emit(encoding);
} }
#endif
void Assembler::vstrs(SRegister sd, Address ad, Condition cond) { void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported()); ASSERT(TargetCPUFeatures::vfp_supported());
...@@ -771,7 +772,8 @@ void Assembler::vstrs(SRegister sd, Address ad, Condition cond) { ...@@ -771,7 +772,8 @@ void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
Emit(encoding); Emit(encoding);
} }
#if 0
// Moved to ARM32::AssemblerARM32::vldrd()
void Assembler::vldrd(DRegister dd, Address ad, Condition cond) { void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported()); ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(dd != kNoDRegister); ASSERT(dd != kNoDRegister);
...@@ -783,7 +785,7 @@ void Assembler::vldrd(DRegister dd, Address ad, Condition cond) { ...@@ -783,7 +785,7 @@ void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
B11 | B9 | B8 | ad.vencoding(); B11 | B9 | B8 | ad.vencoding();
Emit(encoding); Emit(encoding);
} }
#endif
void Assembler::vstrd(DRegister dd, Address ad, Condition cond) { void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported()); ASSERT(TargetCPUFeatures::vfp_supported());
......
...@@ -632,9 +632,15 @@ class Assembler : public ValueObject { ...@@ -632,9 +632,15 @@ class Assembler : public ValueObject {
bool vmovs(SRegister sd, float s_imm, Condition cond = AL); bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
bool vmovd(DRegister dd, double d_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); void vldrs(SRegister sd, Address ad, Condition cond = AL);
#endif
void vstrs(SRegister sd, Address ad, Condition cond = AL); 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); void vldrd(DRegister dd, Address ad, Condition cond = AL);
#endif
void vstrd(DRegister dd, Address ad, Condition cond = AL); void vstrd(DRegister dd, Address ad, Condition cond = AL);
void vldms(BlockAddressMode am, Register base, void vldms(BlockAddressMode am, Register base,
......
...@@ -238,7 +238,8 @@ enum EncodedOperand { ...@@ -238,7 +238,8 @@ enum EncodedOperand {
// //
// ***** OpEncodingMemEx ***** // ***** OpEncodingMemEx *****
// //
// Value=000000000000nnnn0000000000000000 where nnnn=Rn. // Value=00000000U000nnnn00000000xxxxxxxx where nnnn=Rn, xxxxxxxx=abs(Offset),
// and U=1 Offset>=0.
EncodedAsImmRegOffset, EncodedAsImmRegOffset,
// Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
// mmmm is the index register Rm, iiiii is the shift amount, ss is the shift // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
...@@ -2187,6 +2188,50 @@ void AssemblerARM32::vdivd(const Operand *OpDd, const Operand *OpDn, ...@@ -2187,6 +2188,50 @@ void AssemblerARM32::vdivd(const Operand *OpDd, const Operand *OpDn,
emitVFPddd(Cond, VdivdOpcode, Dd, Dn, Dm); 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, void AssemblerARM32::vmuls(const Operand *OpSd, const Operand *OpSn,
const Operand *OpSm, CondARM32::Cond Cond) { const Operand *OpSm, CondARM32::Cond Cond) {
// VMUL (floating-point) - ARM section A8.8.351, encoding A2: // VMUL (floating-point) - ARM section A8.8.351, encoding A2:
......
...@@ -338,6 +338,24 @@ public: ...@@ -338,6 +338,24 @@ public:
void vdivs(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm, void vdivs(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
CondARM32::Cond Cond); 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, void vmuld(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
CondARM32::Cond Cond); CondARM32::Cond Cond);
......
...@@ -1366,7 +1366,12 @@ template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { ...@@ -1366,7 +1366,12 @@ template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const {
Variable *Dest = getDest(); Variable *Dest = getDest();
Type DestTy = Dest->getType(); Type DestTy = Dest->getType();
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 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. // TODO(kschimpf) Handle case.
Asm->setNeedsTextFixup(); Asm->setNeedsTextFixup();
else else
......
; 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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment