[llvm-commits] [llvm] r116471 - in /llvm/trunk: lib/Target/ARM/ARMInstrVFP.td lib/Target/ARM/ARMMCCodeEmitter.cpp test/MC/ARM/simple-fp-encoding.ll

Bill Wendling isanbard at gmail.com
Wed Oct 13 19:33:27 PDT 2010


Author: void
Date: Wed Oct 13 21:33:26 2010
New Revision: 116471

URL: http://llvm.org/viewvc/llvm-project?rev=116471&view=rev
Log:
Add support for vmov.f64/.f32 encoding. There's a bit of a hack going on
here. The f32 in FCONSTS is handled as a double instead of a float in the
code. So the encoding of the immediate into the instruction isn't exactly in
line with the documentation in that regard. But given that we know it's handled
as a double, it doesn't cause any harm.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
    llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
    llvm/trunk/test/MC/ARM/simple-fp-encoding.ll

Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=116471&r1=116470&r2=116471&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Wed Oct 13 21:33:26 2010
@@ -921,7 +921,7 @@
 let Defs = [CPSR], Uses = [FPSCR] in
 def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
                    "\tapsr_nzcv, fpscr",
-             [(arm_fmstat)]> {
+                   [(arm_fmstat)]> {
   let Inst{27-20} = 0b11101111;
   let Inst{19-16} = 0b0001;
   let Inst{15-12} = 0b1111;
@@ -932,7 +932,7 @@
   let Inst{3-0}   = 0b0000;
 }
 
-// FPSCR <-> GPR (for disassembly only)
+// FPSCR <-> GPR
 let hasSideEffects = 1, Uses = [FPSCR] in
 def VMRS : VFPAI<(outs GPR:$Rt), (ins), VFPMiscFrm, IIC_fpSTAT,
                  "vmrs", "\t$Rt, fpscr",
@@ -971,25 +971,49 @@
 
 // Materialize FP immediates. VFP3 only.
 let isReMaterializable = 1 in {
-def FCONSTD : VFPAI<(outs DPR:$dst), (ins vfp_f64imm:$imm),
+def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm),
                     VFPMiscFrm, IIC_fpUNA64,
-                    "vmov", ".f64\t$dst, $imm",
-                    [(set DPR:$dst, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
+                    "vmov", ".f64\t$Dd, $imm",
+                    [(set DPR:$Dd, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
+  // Instruction operands.
+  bits<5>  Dd;
+  bits<32> imm;
+
+  // Encode instruction operands.
+  let Inst{15-12} = Dd{3-0};
+  let Inst{22}    = Dd{4};
+  let Inst{19}    = imm{31};
+  let Inst{18-16} = imm{22-20};
+  let Inst{3-0}   = imm{19-16};
+
+  // Encode remaining instruction bits.
   let Inst{27-23} = 0b11101;
   let Inst{21-20} = 0b11;
   let Inst{11-9}  = 0b101;
-  let Inst{8}     = 1;
+  let Inst{8}     = 1;          // Double precision.
   let Inst{7-4}   = 0b0000;
 }
 
-def FCONSTS : VFPAI<(outs SPR:$dst), (ins vfp_f32imm:$imm),
-                    VFPMiscFrm, IIC_fpUNA32,
-                    "vmov", ".f32\t$dst, $imm",
-                    [(set SPR:$dst, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
+def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
+                     VFPMiscFrm, IIC_fpUNA32,
+                     "vmov", ".f32\t$Sd, $imm",
+                     [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
+  // Instruction operands.
+  bits<5>  Sd;
+  bits<32> imm;
+
+  // Encode instruction operands.
+  let Inst{15-12} = Sd{4-1};
+  let Inst{22}    = Sd{0};
+  let Inst{19}    = imm{31};    // The immediate is handled as a double.
+  let Inst{18-16} = imm{22-20};
+  let Inst{3-0}   = imm{19-16};
+
+  // Encode remaining instruction bits.
   let Inst{27-23} = 0b11101;
   let Inst{21-20} = 0b11;
   let Inst{11-9}  = 0b101;
-  let Inst{8}     = 0;
+  let Inst{8}     = 0;          // Single precision.
   let Inst{7-4}   = 0b0000;
 }
 }

Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=116471&r1=116470&r2=116471&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Wed Oct 13 21:33:26 2010
@@ -138,10 +138,13 @@
 /// operand requires relocation, record the relocation and return zero.
 unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
                                              const MCOperand &MO) const {
-  if (MO.isReg())
+  if (MO.isReg()) {
     return getARMRegisterNumbering(MO.getReg());
-  else if (MO.isImm()) {
+  } else if (MO.isImm()) {
     return static_cast<unsigned>(MO.getImm());
+  } else if (MO.isFPImm()) {
+    return static_cast<unsigned>(APFloat(MO.getFPImm())
+                     .bitcastToAPInt().getHiBits(32).getLimitedValue());
   } else {
 #ifndef NDEBUG
     errs() << MO;
@@ -151,7 +154,6 @@
   return 0;
 }
 
-
 unsigned ARMMCCodeEmitter::getSORegOpValue(const MCInst &MI,
                                            unsigned OpIdx) const {
   // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg

Modified: llvm/trunk/test/MC/ARM/simple-fp-encoding.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/simple-fp-encoding.ll?rev=116471&r1=116470&r2=116471&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/simple-fp-encoding.ll (original)
+++ llvm/trunk/test/MC/ARM/simple-fp-encoding.ll Wed Oct 13 21:33:26 2010
@@ -352,3 +352,19 @@
 }
 
 declare void @llvm.arm.set.fpscr(i32) nounwind
+
+
+define double @f102() nounwind readnone {
+entry:
+; CHECK: f102
+; CHECK: vmov.f64 d16, #3.000000e+00 @ encoding: [0x08,0x0b,0xf0,0xee]
+  ret double 3.000000e+00
+}
+
+define float @f103(float %a) nounwind readnone {
+entry:
+; CHECK: f103
+; CHECK: vmov.f32 s0, #3.000000e+00  @ encoding: [0x08,0x0a,0xb0,0xee]
+  %add = fadd float %a, 3.000000e+00
+  ret float %add
+}





More information about the llvm-commits mailing list