bool
MachineRegisterInfo::recomputeRegClass(unsigned Reg, const TargetMachine &TM) {
  const TargetInstrInfo *TII = TM.getInstrInfo();
  const TargetRegisterClass *OldRC = getRegClass(Reg);
  const TargetRegisterClass *NewRC = TRI->getLargestLegalSuperClass(OldRC);

  // Stop early if there is no room to grow.
  if (NewRC == OldRC)
    return false;

  // Accumulate constraints from all uses.
  for (reg_nodbg_iterator I = reg_nodbg_begin(Reg), E = reg_nodbg_end(); I != E;
       ++I) {
    const TargetRegisterClass *OpRC =
      I->getRegClassConstraint(I.getOperandNo(), TII, TRI);
    if (unsigned SubIdx = I.getOperand().getSubReg()) {
      if (OpRC)
        NewRC = TRI->getMatchingSuperRegClass(NewRC, OpRC, SubIdx);
      else
        NewRC = TRI->getSubClassWithSubReg(NewRC, SubIdx);
    } else if (OpRC)
      NewRC = TRI->getCommonSubClass(NewRC, OpRC);
    if (!NewRC || NewRC == OldRC)
      return false;
  }
  setRegClass(Reg, NewRC);
  return true;
}
예제 #2
0
SITargetLowering::SITargetLowering(TargetMachine &TM) :
    AMDGPUTargetLowering(TM),
    TII(static_cast<const SIInstrInfo*>(TM.getInstrInfo()))
{
  addRegisterClass(MVT::v4f32, &AMDIL::VReg_128RegClass);
  addRegisterClass(MVT::f32, &AMDIL::VReg_32RegClass);

  setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
  setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal);
}
예제 #3
0
R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
    AMDGPUTargetLowering(TM),
    TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo()))
{
  setOperationAction(ISD::MUL, MVT::i64, Expand);
//  setSchedulingPreference(Sched::VLIW);
  addRegisterClass(MVT::v4f32, &AMDIL::R600_Reg128RegClass);
  addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass);

  setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
  setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal);
}
예제 #4
0
SITargetLowering::SITargetLowering(TargetMachine &TM) :
    AMDGPUTargetLowering(TM),
    TII(static_cast<const SIInstrInfo*>(TM.getInstrInfo()))
{
  addRegisterClass(MVT::v4f32, &AMDIL::VReg_128RegClass);
  addRegisterClass(MVT::f32, &AMDIL::VReg_32RegClass);
  addRegisterClass(MVT::i32, &AMDIL::VReg_32RegClass);
  addRegisterClass(MVT::i64, &AMDIL::VReg_64RegClass);

  addRegisterClass(MVT::v4i32, &AMDIL::SReg_128RegClass);
  addRegisterClass(MVT::v8i32, &AMDIL::SReg_256RegClass);

  computeRegisterProperties();

  setOperationAction(ISD::ADD, MVT::i64, Legal);
  setOperationAction(ISD::ADD, MVT::i32, Legal);

}
예제 #5
0
bool
MachineRegisterInfo::recomputeRegClass(unsigned Reg, const TargetMachine &TM) {
  const TargetInstrInfo *TII = TM.getInstrInfo();
  const TargetRegisterClass *OldRC = getRegClass(Reg);
  const TargetRegisterClass *NewRC =
    getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC);

  // Stop early if there is no room to grow.
  if (NewRC == OldRC)
    return false;

  // Accumulate constraints from all uses.
  for (reg_nodbg_iterator I = reg_nodbg_begin(Reg), E = reg_nodbg_end(); I != E;
       ++I) {
    // Apply the effect of the given operand to NewRC.
    NewRC = I->getRegClassConstraintEffect(I.getOperandNo(), NewRC, TII,
                                           getTargetRegisterInfo());
    if (!NewRC || NewRC == OldRC)
      return false;
  }
  setRegClass(Reg, NewRC);
  return true;
}
bool
MachineRegisterInfo::recomputeRegClass(unsigned Reg, const TargetMachine &TM) {
  const TargetInstrInfo *TII = TM.getInstrInfo();
  const TargetRegisterClass *OldRC = getRegClass(Reg);
  const TargetRegisterClass *NewRC =
    getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC);

  // Stop early if there is no room to grow.
  if (NewRC == OldRC)
    return false;

  // Accumulate constraints from all uses.
  for (MachineOperand &MO : reg_nodbg_operands(Reg)) {
    // Apply the effect of the given operand to NewRC.
    MachineInstr *MI = MO.getParent();
    unsigned OpNo = &MO - &MI->getOperand(0);
    NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII,
                                            getTargetRegisterInfo());
    if (!NewRC || NewRC == OldRC)
      return false;
  }
  setRegClass(Reg, NewRC);
  return true;
}
예제 #7
0
R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
    AMDGPUTargetLowering(TM),
    TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo()))
{
  setOperationAction(ISD::MUL, MVT::i64, Expand);
  addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass);
  addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass);
  addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass);
  addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass);
  computeRegisterProperties();

  setOperationAction(ISD::BR_CC, MVT::i32, Custom);

  setOperationAction(ISD::FSUB, MVT::f32, Expand);

  setOperationAction(ISD::ROTL, MVT::i32, Custom);

  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);

  setOperationAction(ISD::SETCC, MVT::i32, Custom);

  setSchedulingPreference(Sched::VLIW);
}
예제 #8
0
/*
 * Disassemble a function, using the LLVM MC disassembler.
 *
 * See also:
 * - http://blog.llvm.org/2010/01/x86-disassembler.html
 * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html
 */
extern "C" void
lp_disassemble(const void* func)
{
#if HAVE_LLVM >= 0x0207
   using namespace llvm;

   const uint8_t *bytes = (const uint8_t *)func;

   /*
    * Limit disassembly to this extent
    */
   const uint64_t extent = 0x10000;

   uint64_t max_pc = 0;

   /*
    * Initialize all used objects.
    */

#if HAVE_LLVM >= 0x0301
   std::string Triple = sys::getDefaultTargetTriple();
#else
   std::string Triple = sys::getHostTriple();
#endif

   std::string Error;
   const Target *T = TargetRegistry::lookupTarget(Triple, Error);

#if HAVE_LLVM >= 0x0208
   InitializeNativeTargetAsmPrinter();
#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
   LLVMInitializeX86AsmPrinter();
#elif defined(PIPE_ARCH_ARM)
   LLVMInitializeARMAsmPrinter();
#elif defined(PIPE_ARCH_PPC)
   LLVMInitializePowerPCAsmPrinter();
#endif

#if HAVE_LLVM >= 0x0301
   InitializeNativeTargetDisassembler();
#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
   LLVMInitializeX86Disassembler();
#elif defined(PIPE_ARCH_ARM)
   LLVMInitializeARMDisassembler();
#endif

#if HAVE_LLVM >= 0x0300
   OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(Triple));
#else
   OwningPtr<const MCAsmInfo> AsmInfo(T->createAsmInfo(Triple));
#endif

   if (!AsmInfo) {
      debug_printf("error: no assembly info for target %s\n", Triple.c_str());
      return;
   }

#if HAVE_LLVM >= 0x0300
   const MCSubtargetInfo *STI = T->createMCSubtargetInfo(Triple, sys::getHostCPUName(), "");
   OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler(*STI));
#else 
   OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler());
#endif 
   if (!DisAsm) {
      debug_printf("error: no disassembler for target %s\n", Triple.c_str());
      return;
   }

   raw_debug_ostream Out;

#if HAVE_LLVM >= 0x0300
   unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
#else
   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
#endif

#if HAVE_LLVM >= 0x0301
   OwningPtr<const MCRegisterInfo> MRI(T->createMCRegInfo(Triple));
   if (!MRI) {
      debug_printf("error: no register info for target %s\n", Triple.c_str());
      return;
   }

   OwningPtr<const MCInstrInfo> MII(T->createMCInstrInfo());
   if (!MII) {
      debug_printf("error: no instruction info for target %s\n", Triple.c_str());
      return;
   }
#endif

#if HAVE_LLVM >= 0x0301
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
#elif HAVE_LLVM == 0x0300
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *STI));
#elif HAVE_LLVM >= 0x0208
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo));
#else
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out));
#endif
   if (!Printer) {
      debug_printf("error: no instruction printer for target %s\n", Triple.c_str());
      return;
   }

#if HAVE_LLVM >= 0x0301
   TargetOptions options;
#if defined(DEBUG)
   options.JITEmitDebugInfo = true;
#endif
#if defined(PIPE_ARCH_X86)
   options.StackAlignmentOverride = 4;
#endif
#if defined(DEBUG) || defined(PROFILE)
   options.NoFramePointerElim = true;
#endif
   TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "", options);
#elif HAVE_LLVM == 0x0300
   TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "");
#else
   TargetMachine *TM = T->createTargetMachine(Triple, "");
#endif

   const TargetInstrInfo *TII = TM->getInstrInfo();

   /*
    * Wrap the data in a MemoryObject
    */
   BufferMemoryObject memoryObject((const uint8_t *)bytes, extent);

   uint64_t pc;
   pc = 0;
   while (true) {
      MCInst Inst;
      uint64_t Size;

      /*
       * Print address.  We use addresses relative to the start of the function,
       * so that between runs.
       */

      debug_printf("%6lu:\t", (unsigned long)pc);

      if (!DisAsm->getInstruction(Inst, Size, memoryObject,
                                 pc,
#if HAVE_LLVM >= 0x0300
				  nulls(), nulls())) {
#else
				  nulls())) {
#endif
         debug_printf("invalid\n");
         pc += 1;
      }

      /*
       * Output the bytes in hexidecimal format.
       */

      if (0) {
         unsigned i;
         for (i = 0; i < Size; ++i) {
            debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]);
         }
         for (; i < 16; ++i) {
            debug_printf("   ");
         }
      }

      /*
       * Print the instruction.
       */

#if HAVE_LLVM >= 0x0300
      Printer->printInst(&Inst, Out, "");
#elif HAVE_LLVM >= 0x208
      Printer->printInst(&Inst, Out);
#else
      Printer->printInst(&Inst);
#endif
      Out.flush();

      /*
       * Advance.
       */

      pc += Size;

#if HAVE_LLVM >= 0x0300
      const MCInstrDesc &TID = TII->get(Inst.getOpcode());
#else
      const TargetInstrDesc &TID = TII->get(Inst.getOpcode());
#endif

      /*
       * Keep track of forward jumps to a nearby address.
       */

      if (TID.isBranch()) {
         for (unsigned i = 0; i < Inst.getNumOperands(); ++i) {
            const MCOperand &operand = Inst.getOperand(i);
            if (operand.isImm()) {
               uint64_t jump;

               /*
                * FIXME: Handle both relative and absolute addresses correctly.
                * EDInstInfo actually has this info, but operandTypes and
                * operandFlags enums are not exposed in the public interface.
                */

               if (1) {
                  /*
                   * PC relative addr.
                   */

                  jump = pc + operand.getImm();
               } else {
                  /*
                   * Absolute addr.
                   */

                  jump = (uint64_t)operand.getImm();
               }

               /*
                * Output the address relative to the function start, given
                * that MC will print the addresses relative the current pc.
                */
               debug_printf("\t\t; %lu", (unsigned long)jump);

               /*
                * Ignore far jumps given it could be actually a tail return to
                * a random address.
                */

               if (jump > max_pc &&
                   jump < extent) {
                  max_pc = jump;
               }
            }
         }
      }

      debug_printf("\n");

      /*
       * Stop disassembling on return statements, if there is no record of a
       * jump to a successive address.
       */

      if (TID.isReturn()) {
         if (pc > max_pc) {
            break;
         }
      }
   }

   /*
    * Print GDB command, useful to verify output.
    */

   if (0) {
      debug_printf("disassemble %p %p\n", bytes, bytes + pc);
   }

   debug_printf("\n");
#else /* HAVE_LLVM < 0x0207 */
   (void)func;
#endif /* HAVE_LLVM < 0x0207 */
}