mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146702 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			133 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.5 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/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::getInstrLatency(const InstrItineraryData *ItinData,
 | |
|                                      const MachineInstr *MI,
 | |
|                                      unsigned *PredCost) const {
 | |
|   if (!ItinData || ItinData->isEmpty())
 | |
|     return 1;
 | |
| 
 | |
|   return ItinData->getStageLatency(MI->getDesc().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!");
 | |
| }
 | |
| 
 | |
| 
 | |
| /// 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;
 | |
| }
 |