add support for encoding the lo14 forms used for a few PPC64 addressing
authorChris Lattner <sabre@nondot.org>
Mon, 15 Nov 2010 08:02:41 +0000 (08:02 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 15 Nov 2010 08:02:41 +0000 (08:02 +0000)
modes.  For example, we now get:

ld r3, lo16(_G)(r3)             ; encoding: [0xe8,0x63,A,0bAAAAAA00]
                                        ;   fixup A - offset: 0, value: lo16(_G), kind: fixup_ppc_lo14

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119133 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCCodeEmitter.cpp
lib/Target/PowerPC/PPCInstr64Bit.td
lib/Target/PowerPC/PPCInstrFormats.td
lib/Target/PowerPC/PPCInstrInfo.td
lib/Target/PowerPC/PPCMCCodeEmitter.cpp

index 9335b183dbda7f3179899b6315c5a06eac7928ee..48848e3713a92324bfbe90253e6566a5310d0542 100644 (file)
@@ -66,7 +66,7 @@ namespace {
 
     unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const;
     unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const;
-    unsigned getLO14Encoding(const MachineInstr &MI, unsigned OpNo) const;
+    unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
 
     const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
 
@@ -209,13 +209,19 @@ unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI,
   return 0;
 }
 
-unsigned PPCCodeEmitter::getLO14Encoding(const MachineInstr &MI,
-                                         unsigned OpNo) const {
+unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI,
+                                           unsigned OpNo) const {
+  // Encode (imm, reg) as a memrix, which has the low 14-bits as the
+  // displacement and the next 5 bits as the register #.
+  assert(MI.getOperand(OpNo+1).isReg());
+  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 14;
+  
   const MachineOperand &MO = MI.getOperand(OpNo);
-  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
+  if (MO.isImm())
+    return (getMachineOpValue(MI, MO) & 0x3FFF) | RegBits;
   
   MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low_ix));
-  return 0;
+  return RegBits;
 }
 
 
@@ -259,13 +265,6 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
     case PPC::STFD:
       Reloc = PPC::reloc_absolute_low;
       break;
-
-    case PPC::LWA:
-    case PPC::LD:
-    case PPC::STD:
-    case PPC::STD_32:
-      Reloc = PPC::reloc_absolute_low_ix;
-      break;
     }
 
     MCE.addRelocation(GetRelocation(MO, Reloc));
index 0b96bcd6357d82be485b0bbfed30edc758a4de72..fada63dd8ce1a7ebfef1c5b3e71ffd6396113270 100644 (file)
@@ -552,12 +552,13 @@ def LDtoc: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
                   "",
                   [(set G8RC:$rD,
                      (PPCtoc_entry tglobaladdr:$disp, G8RC:$reg))]>, isPPC64;
-let RST = 2, DS = 8 in
+                     
+let RST = 2, DS_RA = 0 in // FIXME: Should be a pseudo.
 def LDinto_toc: DSForm_1<58, 0, (outs), (ins G8RC:$reg),
                     "ld 2, 8($reg)", LdStLD,
                     [(PPCload_toc G8RC:$reg)]>, isPPC64;
                     
-let RST = 2, DS = 40, RA = 1 in
+let RST = 2, DS_RA = 0 in // FIXME: Should be a pseudo.
 def LDtoc_restore : DSForm_1<58, 0, (outs), (ins),
                     "ld 2, 40(1)", LdStLD,
                     [(PPCtoc_restore)]>, isPPC64;
@@ -628,8 +629,8 @@ def STHU8 : DForm_1<45, (outs ptr_rc:$ea_res), (ins G8RC:$rS,
                                         iaddroff:$ptroff))]>,
                     RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
 
-def STDU : DSForm_1<62, 1, (outs ptr_rc:$ea_res), (ins G8RC:$rS,
-                                s16immX4:$ptroff, ptr_rc:$ptrreg),
+def STDU : DSForm_1a<62, 1, (outs ptr_rc:$ea_res), (ins G8RC:$rS,
+                                        s16immX4:$ptroff, ptr_rc:$ptrreg),
                     "stdu $rS, $ptroff($ptrreg)", LdStSTD,
                     [(set ptr_rc:$ea_res, (pre_store G8RC:$rS, ptr_rc:$ptrreg, 
                                                      iaddroff:$ptroff))]>,
index 4357bdccec7bde7f633bb82296e5a0f683a2ed74..3949bd3d21c39f67c63068c762e818bc15ed5bbd 100644 (file)
@@ -188,17 +188,31 @@ class DSForm_1<bits<6> opcode, bits<2> xo, dag OOL, dag IOL, string asmstr,
                InstrItinClass itin, list<dag> pattern>
          : I<opcode, OOL, IOL, asmstr, itin> {
   bits<5>  RST;
-  bits<14> DS;
-  bits<5>  RA;
+  bits<19> DS_RA;
 
   let Pattern = pattern;
   
   let Inst{6-10}  = RST;
-  let Inst{11-15} = RA;
-  let Inst{16-29} = DS;
+  let Inst{11-15} = DS_RA{18-14};  // Register #
+  let Inst{16-29} = DS_RA{13-0};   // Displacement.
   let Inst{30-31} = xo;
 }
 
+class DSForm_1a<bits<6> opcode, bits<2> xo, dag OOL, dag IOL, string asmstr,
+                InstrItinClass itin, list<dag> pattern>
+         : I<opcode, OOL, IOL, asmstr, itin> {
+   bits<5>  RST;
+   bits<14> DS;
+   bits<5>  RA;
+   let Pattern = pattern;
+   
+   let Inst{6-10}  = RST;
+   let Inst{11-15} = RA;
+   let Inst{16-29} = DS;
+   let Inst{30-31} = xo;
+}
+
 // 1.7.6 X-Form
 class XForm_base_r3xo<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, 
                       InstrItinClass itin, list<dag> pattern>
index 11f84d0d84c0119c8fc8c0be3e109cefc45281a7..a9b1d87f3f6f3244babd27acb71d85b61d22ddb6 100644 (file)
@@ -324,6 +324,7 @@ def memrr : Operand<iPTR> {
 def memrix : Operand<iPTR> {   // memri where the imm is shifted 2 bits.
   let PrintMethod = "printMemRegImmShifted";
   let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg);
+  let EncoderMethod = "getMemRIXEncoding";
 }
 def tocentry : Operand<iPTR> {
   let MIOperandInfo = (ops i32imm:$imm);
index 644f46f21d8a8680347cefabcf1e6f9e0ed2f460..66c0bb72a9c2f6009c3fbdd067394a453f4930c5 100644 (file)
@@ -66,8 +66,8 @@ public:
                            SmallVectorImpl<MCFixup> &Fixups) const;
   unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo,
                            SmallVectorImpl<MCFixup> &Fixups) const;
-  unsigned getLO14Encoding(const MCInst &MI, unsigned OpNo,
-                           SmallVectorImpl<MCFixup> &Fixups) const;
+  unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
+                             SmallVectorImpl<MCFixup> &Fixups) const;
   unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
                                SmallVectorImpl<MCFixup> &Fixups) const;
 
@@ -147,15 +147,20 @@ unsigned PPCMCCodeEmitter::getLO16Encoding(const MCInst &MI, unsigned OpNo,
   return 0;
 }
 
-unsigned PPCMCCodeEmitter::getLO14Encoding(const MCInst &MI, unsigned OpNo,
+unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
                                        SmallVectorImpl<MCFixup> &Fixups) const {
+  // Encode (imm, reg) as a memrix, which has the low 14-bits as the
+  // displacement and the next 5 bits as the register #.
+  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 14;
+  
   const MCOperand &MO = MI.getOperand(OpNo);
-  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
+  if (MO.isImm())
+    return (getMachineOpValue(MI, MO, Fixups) & 0x3FFF) | RegBits;
   
   // Add a fixup for the branch target.
   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
                                    (MCFixupKind)PPC::fixup_ppc_lo14));
-  return 0;
+  return RegBits;
 }