OSDN Git Service

Add vdlr{s,d} to the integrated ARM assembler.
authorKarl Schimpf <kschimpf@google.com>
Thu, 21 Jan 2016 17:47:14 +0000 (09:47 -0800)
committerKarl Schimpf <kschimpf@google.com>
Thu, 21 Jan 2016 17:47:14 +0000 (09:47 -0800)
BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4334
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/1601103010 .

src/DartARM32/assembler_arm.cc
src/DartARM32/assembler_arm.h
src/IceAssemblerARM32.cpp
src/IceAssemblerARM32.h
src/IceInstARM32.cpp
tests_lit/assembler/arm32/vldr.ll [new file with mode: 0644]

index 4dca55a..6b0bfde 100644 (file)
@@ -744,7 +744,8 @@ void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
   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);
@@ -756,7 +757,7 @@ void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
                      B11 | B9 | ad.vencoding();
   Emit(encoding);
 }
-
+#endif
 
 void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
   ASSERT(TargetCPUFeatures::vfp_supported());
@@ -771,7 +772,8 @@ void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
   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);
@@ -783,7 +785,7 @@ void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
                      B11 | B9 | B8 | ad.vencoding();
   Emit(encoding);
 }
-
+#endif
 
 void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
   ASSERT(TargetCPUFeatures::vfp_supported());
index de8d4da..4de9e66 100644 (file)
@@ -632,9 +632,15 @@ class Assembler : public ValueObject {
   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,
index 8586016..a055b92 100644 (file)
@@ -238,7 +238,8 @@ enum EncodedOperand {
   //
   // ***** 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
@@ -2187,6 +2188,50 @@ void AssemblerARM32::vdivd(const Operand *OpDd, const Operand *OpDn,
   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:
index 955bde7..4b59a02 100644 (file)
@@ -338,6 +338,24 @@ public:
   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);
 
index a160582..a06d71d 100644 (file)
@@ -1366,7 +1366,12 @@ template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const {
   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
diff --git a/tests_lit/assembler/arm32/vldr.ll b/tests_lit/assembler/arm32/vldr.ll
new file mode 100644 (file)
index 0000000..e04097e
--- /dev/null
@@ -0,0 +1,60 @@
+; 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
+}