diff options
| author | Jack Carter <jcarter@mips.com> | 2012-07-16 15:14:51 +0000 | 
|---|---|---|
| committer | Jack Carter <jcarter@mips.com> | 2012-07-16 15:14:51 +0000 | 
| commit | f649043aa533ef2b4aedaf7151018f331173ae4c (patch) | |
| tree | 9557411e14e072f4c1c23e29a6026a74e00db808 /llvm/lib/Target | |
| parent | bb42a5e2cf0eeed7a98f899557f7fac36671e279 (diff) | |
| download | bcm5719-llvm-f649043aa533ef2b4aedaf7151018f331173ae4c.tar.gz bcm5719-llvm-f649043aa533ef2b4aedaf7151018f331173ae4c.zip | |
Doubleword Shift Left Logical Plus 32
Mips shift instructions DSLL, DSRL and DSRA are transformed into
DSLL32, DSRL32 and DSRA32 respectively if the shift amount is between
32 and 63
Here is a description of DSLL:
Purpose: Doubleword Shift Left Logical Plus 32
To execute a left-shift of a doubleword by a fixed amount--32 to 63 bits
Description: GPR[rd] <- GPR[rt] << (sa+32)
The 64-bit doubleword contents of GPR rt are shifted left, inserting
 zeros into the emptied bits; the result is placed in
GPR rd. The bit-shift amount in the range 0 to 31 is specified by sa.
This patch implements the direct object output of these instructions.
llvm-svn: 160277
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Mips/Mips64InstrInfo.td | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 22 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsMCInstLower.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsMCInstLower.h | 2 | 
4 files changed, 57 insertions, 1 deletions
| diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 7a9d41bae8f..cceee24a748 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -109,6 +109,11 @@ def DSRA     : shift_rotate_imm64<0x3b, 0x00, "dsra", sra>;  def DSLLV    : shift_rotate_reg<0x14, 0x00, "dsllv", shl, CPU64Regs>;  def DSRLV    : shift_rotate_reg<0x16, 0x00, "dsrlv", srl, CPU64Regs>;  def DSRAV    : shift_rotate_reg<0x17, 0x00, "dsrav", sra, CPU64Regs>; +let Pattern = []<dag> in { +def DSLL32   : shift_rotate_imm64<0x3c, 0x00, "dsll32", shl>; +def DSRL32   : shift_rotate_imm64<0x3e, 0x00, "dsrl32", srl>; +def DSRA32   : shift_rotate_imm64<0x3f, 0x00, "dsra32", sra>; +}  }  // Rotate Instructions  let Predicates = [HasMips64r2, HasStandardEncoding], diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index 4dac59105de..914a204fe2e 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -13,9 +13,10 @@  //===----------------------------------------------------------------------===//  #define DEBUG_TYPE "mips-asm-printer" -#include "MipsAsmPrinter.h"  #include "Mips.h" +#include "MipsAsmPrinter.h"  #include "MipsInstrInfo.h" +#include "MipsMCInstLower.h"  #include "InstPrinter/MipsInstPrinter.h"  #include "MCTargetDesc/MipsBaseInfo.h"  #include "llvm/ADT/SmallString.h" @@ -57,6 +58,25 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {      return;    } +  // Direct object specific instruction lowering +  if (!OutStreamer.hasRawTextSupport()) +    switch (MI->getOpcode()) { +    case Mips::DSLL: +    case Mips::DSRL: +    case Mips::DSRA: +      assert(MI->getNumOperands() == 3 && +             "Invalid no. of machine operands for shift!"); +      assert(MI->getOperand(2).isImm()); +      int64_t Shift = MI->getOperand(2).getImm(); +      if (Shift > 31) { +        MCInst TmpInst0; +        MCInstLowering.LowerLargeShift(MI, TmpInst0, Shift - 32); +        OutStreamer.EmitInstruction(TmpInst0); +        return; +      } +      break; +    } +    MachineBasicBlock::const_instr_iterator I = MI;    MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.cpp b/llvm/lib/Target/Mips/MipsMCInstLower.cpp index b6042af619d..c49d5308a5b 100644 --- a/llvm/lib/Target/Mips/MipsMCInstLower.cpp +++ b/llvm/lib/Target/Mips/MipsMCInstLower.cpp @@ -158,3 +158,32 @@ void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {        OutMI.addOperand(MCOp);    }  } + +// If the D<shift> instruction has a shift amount that is greater +// than 31 (checked in calling routine), lower it to a D<shift>32 instruction +void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI, +                                      MCInst& Inst, +                                      int64_t Shift) { +  // rt +  Inst.addOperand(LowerOperand(MI->getOperand(0))); +  // rd +  Inst.addOperand(LowerOperand(MI->getOperand(1))); +  // saminus32 +  Inst.addOperand(MCOperand::CreateImm(Shift)); + +  switch (MI->getOpcode()) { +  default: +    // Calling function is not synchronized +    llvm_unreachable("Unexpected shift instruction"); +    break; +  case Mips::DSLL: +    Inst.setOpcode(Mips::DSLL32); +    break; +  case Mips::DSRL: +    Inst.setOpcode(Mips::DSRL32); +    break; +  case Mips::DSRA: +    Inst.setOpcode(Mips::DSRA32); +    break; +  } +} diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.h b/llvm/lib/Target/Mips/MipsMCInstLower.h index 314420a1704..0abb996a687 100644 --- a/llvm/lib/Target/Mips/MipsMCInstLower.h +++ b/llvm/lib/Target/Mips/MipsMCInstLower.h @@ -33,6 +33,8 @@ public:    MipsMCInstLower(MipsAsmPrinter &asmprinter);    void Initialize(Mangler *mang, MCContext *C);    void Lower(const MachineInstr *MI, MCInst &OutMI) const; +  void LowerLargeShift(const MachineInstr *MI, MCInst &Inst, int64_t Shift); +  private:    MCOperand LowerSymbolOperand(const MachineOperand &MO,                                 MachineOperandType MOTy, unsigned Offset) const; | 

