[llvm-commits] [llvm] r145113 - in /llvm/trunk/lib/Target/Mips: MCTargetDesc/MipsMCCodeEmitter.cpp MipsAsmPrinter.cpp MipsAsmPrinter.h MipsInstrInfo.td MipsMCInstLower.cpp MipsMCInstLower.h

Akira Hatanaka ahatanaka at mips.com
Wed Nov 23 14:19:28 PST 2011


Author: ahatanak
Date: Wed Nov 23 16:19:28 2011
New Revision: 145113

URL: http://llvm.org/viewvc/llvm-project?rev=145113&view=rev
Log:
This patch makes the following changes necessary for MIPS' direct code emission.

- lower unaligned loads/stores.
- encode the size operand of instructions INS and EXT.
- emit relocation information needed for JAL (jump-and-link).  

Modified:
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
    llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
    llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp
    llvm/trunk/lib/Target/Mips/MipsMCInstLower.h

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp?rev=145113&r1=145112&r2=145113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp Wed Nov 23 16:19:28 2011
@@ -173,11 +173,21 @@
   } else if (MO.isExpr()) {
     const MCExpr *Expr = MO.getExpr();
     MCExpr::ExprKind Kind = Expr->getKind();
+    unsigned Ret = 0;
+
+    if (Kind == MCExpr::Binary) {
+      const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Expr);
+      Expr = BE->getLHS();
+      Kind = Expr->getKind();
+      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(BE->getRHS());
+      assert((Kind == MCExpr::SymbolRef) && CE &&
+             "Binary expression must be sym+const.");
+      Ret = CE->getValue();
+    }
+
     if (Kind == MCExpr::SymbolRef) {
-      Mips::Fixups FixupKind = Mips::fixup_Mips_NONE;
-      MCSymbolRefExpr::VariantKind SymRefKind =
-          cast<MCSymbolRefExpr>(Expr)->getKind();
-      switch(SymRefKind) {
+      Mips::Fixups FixupKind;
+      switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
       case MCSymbolRefExpr::VK_Mips_GPREL:
         FixupKind = Mips::fixup_Mips_GPREL16;
         break;
@@ -206,12 +216,12 @@
         FixupKind = Mips::fixup_Mips_TPREL_LO;
         break;
       default:
-        return 0;
+        return Ret;
       } // switch
       Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
     } // if SymbolRef
     // All of the information is in the fixup.
-    return 0;
+    return Ret;
   }
   llvm_unreachable("Unable to encode MCOperand!");
   // Not reached
@@ -234,15 +244,22 @@
 unsigned
 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
                                       SmallVectorImpl<MCFixup> &Fixups) const {
-  // FIXME: implement
-  return 0;
+  assert(MI.getOperand(OpNo).isImm());
+  unsigned szEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
+  return szEncoding - 1;
 }
 
+// FIXME: should be called getMSBEncoding
+//
 unsigned
 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
                                       SmallVectorImpl<MCFixup> &Fixups) const {
-  // FIXME: implement
-  return 0;
+  assert(MI.getOperand(OpNo-1).isImm());
+  assert(MI.getOperand(OpNo).isImm());
+  unsigned pos = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups);
+  unsigned sz = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
+
+  return pos + sz - 1;
 }
 
 #include "MipsGenMCCodeEmitter.inc"

Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=145113&r1=145112&r2=145113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Wed Nov 23 16:19:28 2011
@@ -78,12 +78,19 @@
 
   // Enclose unaligned load or store with .macro & .nomacro directives.
   if (isUnalignedLoadStore(Opc)) {
-    MCInst Directive;
-    Directive.setOpcode(Mips::MACRO);
-    OutStreamer.EmitInstruction(Directive);
-    OutStreamer.EmitInstruction(TmpInst0);
-    Directive.setOpcode(Mips::NOMACRO);
-    OutStreamer.EmitInstruction(Directive);
+    if (OutStreamer.hasRawTextSupport()) {
+      MCInst Directive;
+      Directive.setOpcode(Mips::MACRO);
+      OutStreamer.EmitInstruction(Directive);
+      OutStreamer.EmitInstruction(TmpInst0);
+      Directive.setOpcode(Mips::NOMACRO);
+      OutStreamer.EmitInstruction(Directive);
+    } else {
+      MCInstLowering.LowerUnalignedLoadStore(MI, MCInsts);
+      for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin(); I
+          != MCInsts.end(); ++I)
+        OutStreamer.EmitInstruction(*I);
+    }
     return;
   }
 
@@ -91,8 +98,8 @@
     // Lower CPLOAD and CPRESTORE
     if (Opc == Mips::CPLOAD) {
       MCInstLowering.LowerCPLOAD(MI, MCInsts);
-      for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin();
-           I != MCInsts.end(); ++I)
+      for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin(); I
+          != MCInsts.end(); ++I)
         OutStreamer.EmitInstruction(*I);
       return;
     }
@@ -101,7 +108,7 @@
       MCInstLowering.LowerCPRESTORE(MI, TmpInst0);
       OutStreamer.EmitInstruction(TmpInst0);
       return;
-    } 
+    }
   }
 
   OutStreamer.EmitInstruction(TmpInst0);

Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h?rev=145113&r1=145112&r2=145113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h Wed Nov 23 16:19:28 2011
@@ -27,9 +27,11 @@
 class Module;
 
 class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
-  const MipsSubtarget *Subtarget;
-  
+
 public:
+
+  const MipsSubtarget *Subtarget;
+
   explicit MipsAsmPrinter(TargetMachine &TM,  MCStreamer &Streamer)
     : AsmPrinter(TM, Streamer) {
     Subtarget = &TM.getSubtarget<MipsSubtarget>();

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=145113&r1=145112&r2=145113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Wed Nov 23 16:19:28 2011
@@ -145,7 +145,9 @@
   let EncoderMethod = "getBranchTargetOpValue";
   let OperandType = "OPERAND_PCREL";
 }
-def calltarget  : Operand<i32>;
+def calltarget  : Operand<iPTR> {
+  let EncoderMethod = "getJumpTargetOpValue";
+}
 def calltarget64: Operand<i64>;
 def simm16      : Operand<i32>;
 def simm16_64   : Operand<i64>;
@@ -378,6 +380,22 @@
   let isPseudo = Pseudo;
 }
 
+// Memory Load/Store
+let canFoldAsLoad = 1 in
+class LoadX<bits<6> op, RegisterClass RC,
+            Operand MemOpnd>:
+  FMem<op, (outs RC:$rt), (ins MemOpnd:$addr),
+     "",
+     [], IILoad> {
+}
+
+class StoreX<bits<6> op, RegisterClass RC,
+             Operand MemOpnd>:
+  FMem<op, (outs), (ins RC:$rt, MemOpnd:$addr),
+     "",
+     [], IIStore> {
+}
+
 // 32-bit load.
 multiclass LoadM32<bits<6> op, string instr_asm, PatFrag OpNode,
                    bit Pseudo = 0> {
@@ -396,6 +414,13 @@
                Requires<[IsN64]>;
 } 
 
+// 32-bit load.
+multiclass LoadX32<bits<6> op> {
+  def #NAME# : LoadX<op, CPURegs, mem>,
+               Requires<[NotN64]>;
+  def _P8    : LoadX<op, CPURegs, mem64>,
+               Requires<[IsN64]>;
+}
 // 32-bit store.
 multiclass StoreM32<bits<6> op, string instr_asm, PatFrag OpNode,
                     bit Pseudo = 0> {
@@ -414,6 +439,14 @@
                Requires<[IsN64]>;
 }
 
+// 32-bit store.
+multiclass StoreX32<bits<6> op> {
+  def #NAME# : StoreX<op, CPURegs, mem>,
+               Requires<[NotN64]>;
+  def _P8    : StoreX<op, CPURegs, mem64>,
+               Requires<[IsN64]>;
+}
+
 // Conditional Branch
 class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
   CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$imm16),
@@ -761,6 +794,12 @@
 defm USH     : StoreM32<0x29, "ush", truncstorei16_u, 1>;
 defm USW     : StoreM32<0x2b, "usw", store_u, 1>;
 
+/// Primitives for unaligned
+defm LWL     : LoadX32<0x22>;
+defm LWR     : LoadX32<0x26>;
+defm SWL     : StoreX32<0x2A>;
+defm SWR     : StoreX32<0x2E>;
+
 let hasSideEffects = 1 in
 def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype",
                     [(MipsSync imm:$stype)], NoItinerary, FrmOther>

Modified: llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp?rev=145113&r1=145112&r2=145113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp Wed Nov 23 16:19:28 2011
@@ -23,6 +23,7 @@
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/Target/Mangler.h"
+
 using namespace llvm;
 
 MipsMCInstLower::MipsMCInstLower(Mangler *mang, const MachineFunction &mf,
@@ -55,34 +56,34 @@
   }
 
   switch (MOTy) {
-    case MachineOperand::MO_MachineBasicBlock:
-      Symbol = MO.getMBB()->getSymbol();
-      break;
-
-    case MachineOperand::MO_GlobalAddress:
-      Symbol = Mang->getSymbol(MO.getGlobal());
-      break;
-
-    case MachineOperand::MO_BlockAddress:
-      Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
-      break;
-
-    case MachineOperand::MO_ExternalSymbol:
-      Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
-      break;
-
-    case MachineOperand::MO_JumpTableIndex:
-      Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
-      break;
-
-    case MachineOperand::MO_ConstantPoolIndex:
-      Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
-      if (MO.getOffset())
-        Offset += MO.getOffset();  
-      break;
+  case MachineOperand::MO_MachineBasicBlock:
+    Symbol = MO.getMBB()->getSymbol();
+    break;
+
+  case MachineOperand::MO_GlobalAddress:
+    Symbol = Mang->getSymbol(MO.getGlobal());
+    break;
+
+  case MachineOperand::MO_BlockAddress:
+    Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
+    break;
+
+  case MachineOperand::MO_ExternalSymbol:
+    Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
+    break;
+
+  case MachineOperand::MO_JumpTableIndex:
+    Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
+    break;
+
+  case MachineOperand::MO_ConstantPoolIndex:
+    Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
+    if (MO.getOffset())
+      Offset += MO.getOffset();
+    break;
 
-    default:
-      llvm_unreachable("<unknown operand type>");
+  default:
+    llvm_unreachable("<unknown operand type>");
   }
   
   const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, Ctx);
@@ -145,8 +146,8 @@
   OutMI.addOperand(MCOperand::CreateImm(MO.getImm()));
 }
 
-
-MCOperand MipsMCInstLower::LowerOperand(const MachineOperand& MO) const {
+MCOperand MipsMCInstLower::LowerOperand(const MachineOperand& MO,
+		                                    unsigned offset) const {
   MachineOperandType MOTy = MO.getType();
   
   switch (MOTy) {
@@ -158,14 +159,14 @@
     if (MO.isImplicit()) break;
     return MCOperand::CreateReg(MO.getReg());
   case MachineOperand::MO_Immediate:
-    return MCOperand::CreateImm(MO.getImm());
+    return MCOperand::CreateImm(MO.getImm() + offset);
   case MachineOperand::MO_MachineBasicBlock:
   case MachineOperand::MO_GlobalAddress:
   case MachineOperand::MO_ExternalSymbol:
   case MachineOperand::MO_JumpTableIndex:
   case MachineOperand::MO_ConstantPoolIndex:
   case MachineOperand::MO_BlockAddress:
-    return LowerSymbolOperand(MO, MOTy, 0);
+    return LowerSymbolOperand(MO, MOTy, offset);
  }
 
   return MCOperand();
@@ -182,3 +183,116 @@
       OutMI.addOperand(MCOp);
   }
 }
+
+void MipsMCInstLower::LowerUnalignedLoadStore(const MachineInstr *MI,
+		                                          SmallVector<MCInst,
+		                                          4>& MCInsts) {
+  unsigned Opc = MI->getOpcode();
+  MCInst instr1, instr2, instr3, move;
+
+  bool two_instructions = false;
+
+  assert(MI->getNumOperands() == 3);
+  assert(MI->getOperand(0).isReg());
+  assert(MI->getOperand(1).isReg());
+
+  MCOperand target = LowerOperand(MI->getOperand(0));
+  MCOperand base = LowerOperand(MI->getOperand(1));
+  MCOperand atReg = MCOperand::CreateReg(Mips::AT);
+  MCOperand zeroReg = MCOperand::CreateReg(Mips::ZERO);
+
+  MachineOperand unloweredName = MI->getOperand(2);
+  MCOperand name = LowerOperand(unloweredName);
+
+  move.setOpcode(Mips::ADDu);
+  move.addOperand(target);
+  move.addOperand(atReg);
+  move.addOperand(zeroReg);
+
+  switch (Opc) {
+  case Mips::ULW: {
+    // FIXME: only works for little endian right now
+    MCOperand adj_name = LowerOperand(unloweredName, 3);
+    if (base.getReg() == (target.getReg())) {
+      instr1.setOpcode(Mips::LWL);
+      instr1.addOperand(atReg);
+      instr1.addOperand(base);
+      instr1.addOperand(adj_name);
+      instr2.setOpcode(Mips::LWR);
+      instr2.addOperand(atReg);
+      instr2.addOperand(base);
+      instr2.addOperand(name);
+      instr3 = move;
+    } else {
+      two_instructions = true;
+      instr1.setOpcode(Mips::LWL);
+      instr1.addOperand(target);
+      instr1.addOperand(base);
+      instr1.addOperand(adj_name);
+      instr2.setOpcode(Mips::LWR);
+      instr2.addOperand(target);
+      instr2.addOperand(base);
+      instr2.addOperand(name);
+    }
+    break;
+  }
+  case Mips::ULHu: {
+    // FIXME: only works for little endian right now
+    MCOperand adj_name = LowerOperand(unloweredName, 1);
+    instr1.setOpcode(Mips::LBu);
+    instr1.addOperand(atReg);
+    instr1.addOperand(base);
+    instr1.addOperand(adj_name);
+    instr2.setOpcode(Mips::LBu);
+    instr2.addOperand(target);
+    instr2.addOperand(base);
+    instr2.addOperand(name);
+    instr3.setOpcode(Mips::INS);
+    instr3.addOperand(target);
+    instr3.addOperand(atReg);
+    instr3.addOperand(MCOperand::CreateImm(0x8));
+    instr3.addOperand(MCOperand::CreateImm(0x18));
+    break;
+  }
+
+  case Mips::USW: {
+    // FIXME: only works for little endian right now
+    assert (base.getReg() != target.getReg());
+    two_instructions = true;
+    MCOperand adj_name = LowerOperand(unloweredName, 3);
+    instr1.setOpcode(Mips::SWL);
+    instr1.addOperand(target);
+    instr1.addOperand(base);
+    instr1.addOperand(adj_name);
+    instr2.setOpcode(Mips::SWR);
+    instr2.addOperand(target);
+    instr2.addOperand(base);
+    instr2.addOperand(name);
+    break;
+  }
+  case Mips::USH: {
+    MCOperand adj_name = LowerOperand(unloweredName, 1);
+    instr1.setOpcode(Mips::SB);
+    instr1.addOperand(target);
+    instr1.addOperand(base);
+    instr1.addOperand(name);
+    instr2.setOpcode(Mips::SRL);
+    instr2.addOperand(atReg);
+    instr2.addOperand(target);
+    instr2.addOperand(MCOperand::CreateImm(8));
+    instr3.setOpcode(Mips::SB);
+    instr3.addOperand(atReg);
+    instr3.addOperand(base);
+    instr3.addOperand(adj_name);
+    break;
+  }
+  default:
+    // FIXME: need to add others
+    assert(0 && "unaligned instruction not processed");
+  }
+
+  MCInsts.push_back(instr1);
+  MCInsts.push_back(instr2);
+  if (!two_instructions) MCInsts.push_back(instr3);
+}
+

Modified: llvm/trunk/lib/Target/Mips/MipsMCInstLower.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMCInstLower.h?rev=145113&r1=145112&r2=145113&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMCInstLower.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsMCInstLower.h Wed Nov 23 16:19:28 2011
@@ -37,10 +37,12 @@
   void Lower(const MachineInstr *MI, MCInst &OutMI) const;
   void LowerCPLOAD(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts);
   void LowerCPRESTORE(const MachineInstr *MI, MCInst &OutMI);
+  void LowerUnalignedLoadStore(const MachineInstr *MI,
+		                           SmallVector<MCInst, 4>& MCInsts);
 private:
   MCOperand LowerSymbolOperand(const MachineOperand &MO,
                                MachineOperandType MOTy, unsigned Offset) const;
-  MCOperand LowerOperand(const MachineOperand& MO) const;
+  MCOperand LowerOperand(const MachineOperand& MO, unsigned offset = 0) const;
 };
 }
 





More information about the llvm-commits mailing list