diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCCodeEmitter.cpp')
| -rw-r--r-- | lib/Target/PowerPC/PPCCodeEmitter.cpp | 253 | 
1 files changed, 131 insertions, 122 deletions
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index df9ab52389ba..42232a07535b 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -50,13 +50,24 @@ namespace {      /// getBinaryCodeForInstr - This function, generated by the      /// CodeEmitterGenerator using TableGen, produces the binary encoding for      /// machine instructions. +    unsigned getBinaryCodeForInstr(const MachineInstr &MI) const; -    unsigned getBinaryCodeForInstr(const MachineInstr &MI); - +     +    MachineRelocation GetRelocation(const MachineOperand &MO, +                                    unsigned RelocID) const; +          /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr -      unsigned getMachineOpValue(const MachineInstr &MI, -                               const MachineOperand &MO); +                               const MachineOperand &MO) const; + +    unsigned get_crbitm_encoding(const MachineInstr &MI, unsigned OpNo) const; +    unsigned getDirectBrEncoding(const MachineInstr &MI, unsigned OpNo) const; +    unsigned getCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const; + +    unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const; +    unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const; +    unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const; +    unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;      const char *getPassName() const { return "PowerPC Machine Code Emitter"; } @@ -67,10 +78,6 @@ namespace {      /// emitBasicBlock - emits the given MachineBasicBlock to memory      ///      void emitBasicBlock(MachineBasicBlock &MBB); - -    /// getValueBit - return the particular bit of Val -    /// -    unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }    };  } @@ -128,125 +135,127 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {    }  } -unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, -                                           const MachineOperand &MO) { +unsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI, +                                             unsigned OpNo) const { +  const MachineOperand &MO = MI.getOperand(OpNo); +  assert((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) && +         (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); +  return 0x80 >> PPCRegisterInfo::getRegisterNumbering(MO.getReg()); +} -  unsigned rv = 0; // Return value; defaults to 0 for unhandled cases -                   // or things that get fixed up later by the JIT. -  if (MO.isReg()) { -    rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg()); +MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO,  +                                                unsigned RelocID) const { +  // If in PIC mode, we need to encode the negated address of the +  // 'movepctolr' into the unrelocated field.  After relocation, we'll have +  // &gv-&movepctolr-4 in the imm field.  Once &movepctolr is added to the imm +  // field, we get &gv.  This doesn't happen for branch relocations, which are +  // always implicitly pc relative. +  intptr_t Cst = 0; +  if (TM.getRelocationModel() == Reloc::PIC_) { +    assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); +    Cst = -(intptr_t)MovePCtoLROffset - 4; +  } +   +  if (MO.isGlobal()) +    return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID, +                                    const_cast<GlobalValue *>(MO.getGlobal()), +                                    Cst, isa<Function>(MO.getGlobal())); +  if (MO.isSymbol()) +    return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), +                                        RelocID, MO.getSymbolName(), Cst); +  if (MO.isCPI()) +    return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), +                                           RelocID, MO.getIndex(), Cst); -    // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the -    // register, not the register number directly. -    if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) && -        (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) { -      rv = 0x80 >> rv; -    } -  } else if (MO.isImm()) { -    rv = MO.getImm(); -  } else if (MO.isGlobal() || MO.isSymbol() || -             MO.isCPI() || MO.isJTI()) { -    unsigned Reloc = 0; -    if (MI.getOpcode() == PPC::BL_Darwin || MI.getOpcode() == PPC::BL8_Darwin || -        MI.getOpcode() == PPC::BL_SVR4 || MI.getOpcode() == PPC::BL8_ELF || -        MI.getOpcode() == PPC::TAILB || MI.getOpcode() == PPC::TAILB8) -      Reloc = PPC::reloc_pcrel_bx; -    else { -      if (TM.getRelocationModel() == Reloc::PIC_) { -        assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); -      } -      switch (MI.getOpcode()) { -      default: MI.dump(); llvm_unreachable("Unknown instruction for relocation!"); -      case PPC::LIS: -      case PPC::LIS8: -      case PPC::ADDIS: -      case PPC::ADDIS8: -        Reloc = PPC::reloc_absolute_high;       // Pointer to symbol -        break; -      case PPC::LI: -      case PPC::LI8: -      case PPC::LA: -      // Loads. -      case PPC::LBZ: -      case PPC::LBZ8: -      case PPC::LHA: -      case PPC::LHA8: -      case PPC::LHZ: -      case PPC::LHZ8: -      case PPC::LWZ: -      case PPC::LWZ8: -      case PPC::LFS: -      case PPC::LFD: - -      // Stores. -      case PPC::STB: -      case PPC::STB8: -      case PPC::STH: -      case PPC::STH8: -      case PPC::STW: -      case PPC::STW8: -      case PPC::STFS: -      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; -      } -    } +  if (MO.isMBB()) +    return MachineRelocation::getBB(MCE.getCurrentPCOffset(), +                                    RelocID, MO.getMBB()); +   +  assert(MO.isJTI()); +  return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), +                                         RelocID, MO.getIndex(), Cst); +} -    MachineRelocation R; -    if (MO.isGlobal()) { -      R = MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, -                                   const_cast<GlobalValue *>(MO.getGlobal()), 0, -                                   isa<Function>(MO.getGlobal())); -    } else if (MO.isSymbol()) { -      R = MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), -                                       Reloc, MO.getSymbolName(), 0); -    } else if (MO.isCPI()) { -      R = MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), -                                          Reloc, MO.getIndex(), 0); -    } else { -      assert(MO.isJTI()); -      R = MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), -                                          Reloc, MO.getIndex(), 0); -    } +unsigned PPCCodeEmitter::getDirectBrEncoding(const MachineInstr &MI, +                                             unsigned OpNo) const { +  const MachineOperand &MO = MI.getOperand(OpNo); +  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO); +   +  MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bx)); +  return 0; +} -    // If in PIC mode, we need to encode the negated address of the -    // 'movepctolr' into the unrelocated field.  After relocation, we'll have -    // &gv-&movepctolr-4 in the imm field.  Once &movepctolr is added to the imm -    // field, we get &gv.  This doesn't happen for branch relocations, which are -    // always implicitly pc relative. -    if (TM.getRelocationModel() == Reloc::PIC_ && Reloc != PPC::reloc_pcrel_bx){ -      assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); -      R.setConstantVal(-(intptr_t)MovePCtoLROffset - 4); -    } -    MCE.addRelocation(R); - -  } else if (MO.isMBB()) { -    unsigned Reloc = 0; -    unsigned Opcode = MI.getOpcode(); -    if (Opcode == PPC::B || Opcode == PPC::BL_Darwin || -        Opcode == PPC::BLA_Darwin|| Opcode == PPC::BL_SVR4 || -        Opcode == PPC::BLA_SVR4) -      Reloc = PPC::reloc_pcrel_bx; -    else // BCC instruction -      Reloc = PPC::reloc_pcrel_bcx; - -    MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), -                                               Reloc, MO.getMBB())); -  } else { -#ifndef NDEBUG -    errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; -#endif -    llvm_unreachable(0); -  } +unsigned PPCCodeEmitter::getCondBrEncoding(const MachineInstr &MI, +                                           unsigned OpNo) const { +  const MachineOperand &MO = MI.getOperand(OpNo); +  MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bcx)); +  return 0; +} -  return rv; +unsigned PPCCodeEmitter::getHA16Encoding(const MachineInstr &MI, +                                         unsigned OpNo) const { +  const MachineOperand &MO = MI.getOperand(OpNo); +  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO); + +  MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_high)); +  return 0; +} + +unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI, +                                         unsigned OpNo) const { +  const MachineOperand &MO = MI.getOperand(OpNo); +  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO); +   +  MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low)); +  return 0; +} + +unsigned PPCCodeEmitter::getMemRIEncoding(const MachineInstr &MI, +                                          unsigned OpNo) const { +  // Encode (imm, reg) as a memri, which has the low 16-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)) << 16; +   +  const MachineOperand &MO = MI.getOperand(OpNo); +  if (MO.isImm()) +    return (getMachineOpValue(MI, MO) & 0xFFFF) | RegBits; +   +  // Add a fixup for the displacement field. +  MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low)); +  return RegBits; +} + +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.isImm()) +    return (getMachineOpValue(MI, MO) & 0x3FFF) | RegBits; +   +  MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low_ix)); +  return RegBits; +} + + +unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, +                                           const MachineOperand &MO) const { + +  if (MO.isReg()) { +    // MTCRF/MFOCRF should go through get_crbitm_encoding for the CR operand. +    // The GPR operand should come through here though. +    assert((MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MFOCRF) || +           MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); +    return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); +  } +   +  assert(MO.isImm() && +         "Relocation required in an instruction that we cannot encode!"); +  return MO.getImm();  }  #include "PPCGenCodeEmitter.inc"  | 
