[llvm-commits] [llvm] r59104 - in /llvm/trunk/lib/Target/ARM: ARMCodeEmitter.cpp ARMInstrFormats.td ARMInstrInfo.h ARMInstrVFP.td

Evan Cheng evan.cheng at apple.com
Tue Nov 11 22:41:42 PST 2008


Author: evancheng
Date: Wed Nov 12 00:41:41 2008
New Revision: 59104

URL: http://llvm.org/viewvc/llvm-project?rev=59104&view=rev
Log:
Fix VFP conversion instruction encodings.

Modified:
    llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
    llvm/trunk/lib/Target/ARM/ARMInstrVFP.td

Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=59104&r1=59103&r2=59104&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Wed Nov 12 00:41:41 2008
@@ -347,6 +347,8 @@
   case ARMII::VFPConv1Frm:
   case ARMII::VFPConv2Frm:
   case ARMII::VFPConv3Frm:
+  case ARMII::VFPConv4Frm:
+  case ARMII::VFPConv5Frm:
     emitVFPConversionInstruction(MI);
     break;
   case ARMII::VFPLdStFrm:
@@ -1095,22 +1097,9 @@
   emitWordLE(Binary);
 }
 
-void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
-  const TargetInstrDesc &TID = MI.getDesc();
-
-  // Part of binary is determined by TableGn.
-  unsigned Binary = getBinaryCodeForInstr(MI);
-
-  // Set the conditional execution predicate
-  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
-
-  // FMDRR encodes registers in reverse order.
-  unsigned Form = TID.TSFlags & ARMII::FormMask;
-  unsigned OpIdx = (Form == ARMII::VFPConv2Frm)
-    ? MI.findFirstPredOperandIdx()-1 : 0;
-
-  // Encode Dd / Sd.
+static unsigned encodeVFPRd(const MachineInstr &MI, unsigned OpIdx) {
   unsigned RegD = MI.getOperand(OpIdx).getReg();
+  unsigned Binary = 0;
   bool isSPVFP = false;
   RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
   if (!isSPVFP)
@@ -1119,29 +1108,13 @@
     Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
     Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
   }
-  if (Form == ARMII::VFPConv2Frm)
-    --OpIdx;
-  else
-    ++OpIdx;
-
-  if (Form == ARMII::VFPConv3Frm) {
-    unsigned RegM = MI.getOperand(OpIdx).getReg();
-    isSPVFP = false;
-    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
-    if (!isSPVFP)
-      Binary |=   RegM;
-    else {
-      Binary |= ((RegM & 0x1E) >> 1);
-      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
-    }
-
-    emitWordLE(Binary);
-    return;
-  }
+  return Binary;
+}
 
-  // Encode Dn / Sn.
+static unsigned encodeVFPRn(const MachineInstr &MI, unsigned OpIdx) {
   unsigned RegN = MI.getOperand(OpIdx).getReg();
-  isSPVFP = false;
+  unsigned Binary = 0;
+  bool isSPVFP = false;
   RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
   if (!isSPVFP)
     Binary |=   RegN               << ARMII::RegRnShift;
@@ -1149,23 +1122,74 @@
     Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
     Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
   }
-  if (Form == ARMII::VFPConv2Frm)
-    --OpIdx;
-  else
-    ++OpIdx;
+  return Binary;
+}
 
-  // FMRS / FMSR do not have Rm.
-  if (TID.getNumOperands() > OpIdx && MI.getOperand(OpIdx).isReg()) {
-    unsigned RegM = MI.getOperand(OpIdx).getReg();
-    isSPVFP = false;
-    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
-    if (!isSPVFP)
-      Binary |=   RegM;
-    else {
-      Binary |= ((RegM & 0x1E) >> 1);
-      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
-    }
+static unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) {
+  unsigned RegM = MI.getOperand(OpIdx).getReg();
+  unsigned Binary = 0;
+  bool isSPVFP = false;
+  RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegM;
+  else {
+    Binary |= ((RegM & 0x1E) >> 1);
+    Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
   }
+  return Binary;
+}
+
+void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
+  const TargetInstrDesc &TID = MI.getDesc();
+  unsigned Form = TID.TSFlags & ARMII::FormMask;
+
+  // Part of binary is determined by TableGn.
+  unsigned Binary = getBinaryCodeForInstr(MI);
+
+  // Set the conditional execution predicate
+  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+  switch (Form) {
+  default: break;
+  case ARMII::VFPConv1Frm:
+  case ARMII::VFPConv2Frm:
+  case ARMII::VFPConv3Frm:
+    // Encode Dd / Sd.
+    Binary |= encodeVFPRd(MI, 0);
+    break;
+  case ARMII::VFPConv4Frm:
+    // Encode Dn / Sn.
+    Binary |= encodeVFPRn(MI, 0);
+    break;
+  case ARMII::VFPConv5Frm:
+    // Encode Dm / Sm.
+    Binary |= encodeVFPRm(MI, 0);
+    break;
+  }
+
+  switch (Form) {
+  default: break;
+  case ARMII::VFPConv1Frm:
+    // Encode Dm / Sm.
+    Binary |= encodeVFPRm(MI, 1);
+  case ARMII::VFPConv2Frm:
+  case ARMII::VFPConv3Frm:
+    // Encode Dn / Sn.
+    Binary |= encodeVFPRn(MI, 1);
+    break;
+  case ARMII::VFPConv4Frm:
+  case ARMII::VFPConv5Frm:
+    // Encode Dd / Sd.
+    Binary |= encodeVFPRd(MI, 1);
+    break;
+  }
+
+  if (Form == ARMII::VFPConv5Frm)
+    // Encode Dn / Sn.
+    Binary |= encodeVFPRn(MI, 2);
+  else if (Form == ARMII::VFPConv3Frm)
+    // Encode Dm / Sm.
+    Binary |= encodeVFPRm(MI, 2);
 
   emitWordLE(Binary);
 }

Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=59104&r1=59103&r2=59104&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Nov 12 00:41:41 2008
@@ -42,11 +42,13 @@
 def VFPConv1Frm   : Format<17>;
 def VFPConv2Frm   : Format<18>;
 def VFPConv3Frm   : Format<19>;
-def VFPLdStFrm    : Format<20>;
-def VFPLdStMulFrm : Format<21>;
-def VFPMiscFrm    : Format<22>;
+def VFPConv4Frm   : Format<20>;
+def VFPConv5Frm   : Format<21>;
+def VFPLdStFrm    : Format<22>;
+def VFPLdStMulFrm : Format<23>;
+def VFPMiscFrm    : Format<24>;
 
-def ThumbFrm      : Format<23>;
+def ThumbFrm      : Format<25>;
 
 // Misc flag for data processing instructions that indicates whether
 // the instruction has a Rn register operand.
@@ -820,30 +822,39 @@
   let Inst{11-8}  = 0b1010;
 }
 
-class AVConv1I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
-           string asm, list<dag> pattern>
+// VFP conversion instructions
+class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
+               dag oops, dag iops, string opc, string asm, list<dag> pattern>
   : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
   let Inst{27-20} = opcod1;
-  let Inst{11-8}  = opcod2;
-  let Inst{4}     = 1;
+  let Inst{19-16} = opcod2;
+  let Inst{11-8}  = opcod3;
+  let Inst{6}     = 1;
 }
 
-class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
-           string asm, list<dag> pattern>
-  : AI<oops, iops, VFPConv2Frm, opc, asm, pattern> {
+class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
+             string opc, string asm, list<dag> pattern>
+  : AI<oops, iops, f, opc, asm, pattern> {
   let Inst{27-20} = opcod1;
   let Inst{11-8}  = opcod2;
   let Inst{4}     = 1;
 }
 
-class AVConv3I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
-               dag oops, dag iops, string opc, string asm, list<dag> pattern>
-  : AI<oops, iops, VFPConv3Frm, opc, asm, pattern> {
-  let Inst{27-20} = opcod1;
-  let Inst{19-16} = opcod2;
-  let Inst{11-8}  = opcod3;
-  let Inst{6}     = 1;
-}
+class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
+              string asm, list<dag> pattern>
+  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, opc, asm, pattern>;
+
+class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
+              string asm, list<dag> pattern>
+  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, opc, asm, pattern>;
+
+class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
+              string asm, list<dag> pattern>
+  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, opc, asm, pattern>;
+
+class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
+              string asm, list<dag> pattern>
+  : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, opc, asm, pattern>;
 
 //===----------------------------------------------------------------------===//
 

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.h?rev=59104&r1=59103&r2=59104&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.h Wed Nov 12 00:41:41 2008
@@ -106,12 +106,14 @@
     VFPConv1Frm   = 17 << FormShift,
     VFPConv2Frm   = 18 << FormShift,
     VFPConv3Frm   = 19 << FormShift,
-    VFPLdStFrm    = 20 << FormShift,
-    VFPLdStMulFrm = 21 << FormShift,
-    VFPMiscFrm    = 22 << FormShift,
+    VFPConv4Frm   = 20 << FormShift,
+    VFPConv5Frm   = 21 << FormShift,
+    VFPLdStFrm    = 22 << FormShift,
+    VFPLdStMulFrm = 23 << FormShift,
+    VFPMiscFrm    = 24 << FormShift,
 
     // Thumb format
-    ThumbFrm      = 23 << FormShift,
+    ThumbFrm      = 25 << FormShift,
 
     //===------------------------------------------------------------------===//
     // Field shifts - such shifts are used to set field while generating

Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=59104&r1=59103&r2=59104&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Wed Nov 12 00:41:41 2008
@@ -219,15 +219,15 @@
 // FP <-> GPR Copies.  Int <-> FP Conversions.
 //
 
-def FMRS   : AVConv1I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src),
+def FMRS   : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src),
                  "fmrs", " $dst, $src",
                  [(set GPR:$dst, (bitconvert SPR:$src))]>;
 
-def FMSR   : AVConv2I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
+def FMSR   : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
                  "fmsr", " $dst, $src",
                  [(set SPR:$dst, (bitconvert GPR:$src))]>;
 
-def FMRRD  : AVConv1I<0b11000101, 0b1011,
+def FMRRD  : AVConv3I<0b11000101, 0b1011,
                       (outs GPR:$dst1, GPR:$dst2), (ins DPR:$src),
                  "fmrrd", " $dst1, $dst2, $src",
                  [/* FIXME: Can't write pattern for multiple result instr*/]>;
@@ -235,7 +235,7 @@
 // FMDHR: GPR -> SPR
 // FMDLR: GPR -> SPR
 
-def FMDRR : AVConv2I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
+def FMDRR : AVConv5I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
                 "fmdrr", " $dst, $src1, $src2",
                 [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>;
 
@@ -251,25 +251,25 @@
 
 // Int to FP:
 
-def FSITOD : AVConv3I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
+def FSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
                  "fsitod", " $dst, $a",
                  [(set DPR:$dst, (arm_sitof SPR:$a))]> {
   let Inst{7} = 1; // Z bit
 }
 
-def FSITOS : AVConv3I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
+def FSITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
                  "fsitos", " $dst, $a",
                  [(set SPR:$dst, (arm_sitof SPR:$a))]> {
   let Inst{7} = 1; // Z bit
 }
 
-def FUITOD : AVConv3I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
+def FUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
                  "fuitod", " $dst, $a",
                  [(set DPR:$dst, (arm_uitof SPR:$a))]> {
   let Inst{7} = 0; // Z bit
 }
 
-def FUITOS : AVConv3I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
+def FUITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
                  "fuitos", " $dst, $a",
                  [(set SPR:$dst, (arm_uitof SPR:$a))]> {
   let Inst{7} = 1; // Z bit
@@ -278,28 +278,28 @@
 // FP to Int:
 // Always set Z bit in the instruction, i.e. "round towards zero" variants.
 
-def FTOSIZD : AVConv3I<0b11101011, 0b1101, 0b1011,
+def FTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011,
                        (outs SPR:$dst), (ins DPR:$a),
                  "ftosizd", " $dst, $a",
                  [(set SPR:$dst, (arm_ftosi DPR:$a))]> {
   let Inst{7} = 1; // Z bit
 }
 
-def FTOSIZS : AVConv3I<0b11101011, 0b1101, 0b1010,
+def FTOSIZS : AVConv1I<0b11101011, 0b1101, 0b1010,
                        (outs SPR:$dst), (ins SPR:$a),
                  "ftosizs", " $dst, $a",
                  [(set SPR:$dst, (arm_ftosi SPR:$a))]> {
   let Inst{7} = 1; // Z bit
 }
 
-def FTOUIZD : AVConv3I<0b11101011, 0b1100, 0b1011,
+def FTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011,
                        (outs SPR:$dst), (ins DPR:$a),
                  "ftouizd", " $dst, $a",
                  [(set SPR:$dst, (arm_ftoui DPR:$a))]> {
   let Inst{7} = 1; // Z bit
 }
 
-def FTOUIZS : AVConv3I<0b11101011, 0b1100, 0b1010,
+def FTOUIZS : AVConv1I<0b11101011, 0b1100, 0b1010,
                        (outs SPR:$dst), (ins SPR:$a),
                  "ftouizs", " $dst, $a",
                  [(set SPR:$dst, (arm_ftoui SPR:$a))]> {





More information about the llvm-commits mailing list