mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-03 14:21:30 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134244 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			175 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//===-- TargetInstrInfo.cpp - Target Instruction Information --------------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// This file implements the TargetInstrInfo class.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "llvm/Target/TargetInstrInfo.h"
 | 
						|
#include "llvm/Target/TargetRegisterInfo.h"
 | 
						|
#include "llvm/CodeGen/SelectionDAGNodes.h"
 | 
						|
#include "llvm/MC/MCAsmInfo.h"
 | 
						|
#include "llvm/MC/MCInstrItineraries.h"
 | 
						|
#include "llvm/Support/ErrorHandling.h"
 | 
						|
#include <cctype>
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//  TargetInstrInfo
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
TargetInstrInfo::~TargetInstrInfo() {
 | 
						|
}
 | 
						|
 | 
						|
const TargetRegisterClass*
 | 
						|
TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum,
 | 
						|
                             const TargetRegisterInfo *TRI) const {
 | 
						|
  if (OpNum >= MCID.getNumOperands())
 | 
						|
    return 0;
 | 
						|
 | 
						|
  short RegClass = MCID.OpInfo[OpNum].RegClass;
 | 
						|
  if (MCID.OpInfo[OpNum].isLookupPtrRegClass())
 | 
						|
    return TRI->getPointerRegClass(RegClass);
 | 
						|
 | 
						|
  // Instructions like INSERT_SUBREG do not have fixed register classes.
 | 
						|
  if (RegClass < 0)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  // Otherwise just look it up normally.
 | 
						|
  return TRI->getRegClass(RegClass);
 | 
						|
}
 | 
						|
 | 
						|
unsigned
 | 
						|
TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
 | 
						|
                                const MachineInstr *MI) const {
 | 
						|
  if (!ItinData || ItinData->isEmpty())
 | 
						|
    return 1;
 | 
						|
 | 
						|
  unsigned Class = MI->getDesc().getSchedClass();
 | 
						|
  unsigned UOps = ItinData->Itineraries[Class].NumMicroOps;
 | 
						|
  if (UOps)
 | 
						|
    return UOps;
 | 
						|
 | 
						|
  // The # of u-ops is dynamically determined. The specific target should
 | 
						|
  // override this function to return the right number.
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
 | 
						|
                             const MachineInstr *DefMI, unsigned DefIdx,
 | 
						|
                             const MachineInstr *UseMI, unsigned UseIdx) const {
 | 
						|
  if (!ItinData || ItinData->isEmpty())
 | 
						|
    return -1;
 | 
						|
 | 
						|
  unsigned DefClass = DefMI->getDesc().getSchedClass();
 | 
						|
  unsigned UseClass = UseMI->getDesc().getSchedClass();
 | 
						|
  return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
 | 
						|
                                   SDNode *DefNode, unsigned DefIdx,
 | 
						|
                                   SDNode *UseNode, unsigned UseIdx) const {
 | 
						|
  if (!ItinData || ItinData->isEmpty())
 | 
						|
    return -1;
 | 
						|
 | 
						|
  if (!DefNode->isMachineOpcode())
 | 
						|
    return -1;
 | 
						|
 | 
						|
  unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass();
 | 
						|
  if (!UseNode->isMachineOpcode())
 | 
						|
    return ItinData->getOperandCycle(DefClass, DefIdx);
 | 
						|
  unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass();
 | 
						|
  return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
 | 
						|
}
 | 
						|
 | 
						|
int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
 | 
						|
                                     const MachineInstr *MI,
 | 
						|
                                     unsigned *PredCost) const {
 | 
						|
  if (!ItinData || ItinData->isEmpty())
 | 
						|
    return 1;
 | 
						|
 | 
						|
  return ItinData->getStageLatency(MI->getDesc().getSchedClass());
 | 
						|
}
 | 
						|
 | 
						|
int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
 | 
						|
                                     SDNode *N) const {
 | 
						|
  if (!ItinData || ItinData->isEmpty())
 | 
						|
    return 1;
 | 
						|
 | 
						|
  if (!N->isMachineOpcode())
 | 
						|
    return 1;
 | 
						|
 | 
						|
  return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass());
 | 
						|
}
 | 
						|
 | 
						|
bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
 | 
						|
                                       const MachineInstr *DefMI,
 | 
						|
                                       unsigned DefIdx) const {
 | 
						|
  if (!ItinData || ItinData->isEmpty())
 | 
						|
    return false;
 | 
						|
 | 
						|
  unsigned DefClass = DefMI->getDesc().getSchedClass();
 | 
						|
  int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
 | 
						|
  return (DefCycle != -1 && DefCycle <= 1);
 | 
						|
}
 | 
						|
 | 
						|
/// insertNoop - Insert a noop into the instruction stream at the specified
 | 
						|
/// point.
 | 
						|
void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
 | 
						|
                                 MachineBasicBlock::iterator MI) const {
 | 
						|
  llvm_unreachable("Target didn't implement insertNoop!");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
 | 
						|
  const MCInstrDesc &MCID = MI->getDesc();
 | 
						|
  if (!MCID.isTerminator()) return false;
 | 
						|
 | 
						|
  // Conditional branch is a special case.
 | 
						|
  if (MCID.isBranch() && !MCID.isBarrier())
 | 
						|
    return true;
 | 
						|
  if (!MCID.isPredicable())
 | 
						|
    return true;
 | 
						|
  return !isPredicated(MI);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/// Measure the specified inline asm to determine an approximation of its
 | 
						|
/// length.
 | 
						|
/// Comments (which run till the next SeparatorString or newline) do not
 | 
						|
/// count as an instruction.
 | 
						|
/// Any other non-whitespace text is considered an instruction, with
 | 
						|
/// multiple instructions separated by SeparatorString or newlines.
 | 
						|
/// Variable-length instructions are not handled here; this function
 | 
						|
/// may be overloaded in the target code to do that.
 | 
						|
unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
 | 
						|
                                             const MCAsmInfo &MAI) const {
 | 
						|
 | 
						|
 | 
						|
  // Count the number of instructions in the asm.
 | 
						|
  bool atInsnStart = true;
 | 
						|
  unsigned Length = 0;
 | 
						|
  for (; *Str; ++Str) {
 | 
						|
    if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
 | 
						|
                                strlen(MAI.getSeparatorString())) == 0)
 | 
						|
      atInsnStart = true;
 | 
						|
    if (atInsnStart && !std::isspace(*Str)) {
 | 
						|
      Length += MAI.getMaxInstLength();
 | 
						|
      atInsnStart = false;
 | 
						|
    }
 | 
						|
    if (atInsnStart && strncmp(Str, MAI.getCommentString(),
 | 
						|
                               strlen(MAI.getCommentString())) == 0)
 | 
						|
      atInsnStart = false;
 | 
						|
  }
 | 
						|
 | 
						|
  return Length;
 | 
						|
}
 |