OpenASIP  2.0
Classes | Public Member Functions | Static Public Attributes | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
TDGen Class Reference

#include <TDGen.hh>

Collaboration diagram for TDGen:
Collaboration graph

Classes

struct  RegInfo
 
struct  TerminalDef
 

Public Member Functions

 TDGen (const TTAMachine::Machine &mach)
 
virtual ~TDGen ()
 
void generateBackend (std::string &path)
 

Static Public Attributes

static const char OT_REG_BOOL = 'b'
 
static const char OT_REG_INT = 'r'
 
static const char OT_REG_LONG = 's'
 
static const char OT_REG_FP = 'f'
 
static const char OT_REG_HFP = 'h'
 
static const char OT_REG_DOUBLE = 'd'
 
static const char OT_IMM_BOOL = 'j'
 
static const char OT_IMM_INT = 'i'
 
static const char OT_IMM_FP = 'k'
 
static const char OT_IMM_HFP = 'l'
 
static const char OT_IMM_LONG = 'a'
 
static const char OT_VREG_BOOL = 'a'
 
static const char OT_VREG_INT8 = 'q'
 
static const char OT_VREG_INT16 = 't'
 
static const char OT_VREG_INT32 = 'u'
 
static const char OT_VREG_FP = 'e'
 
static const char OT_VREG_HFP = 'g'
 

Protected Types

enum  RegType { GPR = 0, RESERVED, ARGUMENT, RESULT }
 
enum  RegsToProcess { ALL_REGISTERS, ONLY_EXTRAS, ONLY_LANES, ONLY_NORMAL }
 
typedef std::map< std::string, std::vector< std::string > > RegClassMap
 

Protected Member Functions

bool writeRegisterInfo (std::ostream &o)
 
void writeStartOfRegisterInfo (std::ostream &o)
 
void writeOperandDefs (std::ostream &o)
 
void writeIntegerImmediateDefs (std::ostream &o, const ImmInfo &iivis)
 
void writeMoveImmediateDefs (std::ostream &o)
 
void writeInstrInfo (std::ostream &o)
 
void writeBackendCode (std::ostream &o)
 
void writeTopLevelTD (std::ostream &o)
 
void writeInstrFormats (std::ostream &o)
 
bool checkRequiredRegisters ()
 
void analyzeRegisters ()
 
void analyzeRegisterFileClasses ()
 
void analyzeRegisters (RegsToProcess regsToProcess)
 
void gatherAllMachineOperations ()
 
void analyzeMachineVectorRegisterClasses ()
 
void analyzeMachineRegisters ()
 
void associateRegistersWithVectorRegisterClasses ()
 
void orderEqualWidthRegistersToRoundRobin ()
 
void verbose (const TCEString &msg) const
 
bool isVectorLoadOperation (const Operation &op) const
 
bool isVectorStoreOperation (const Operation &op) const
 
bool isWrongEndianessVectorOp (const Operation &op) const
 
bool isVectorBitwiseOperation (const Operation &op) const
 
bool hasRawOperands (const Operation &op) const
 
int subwordWidthOfRawData (const Operation &op) const
 
bool hasRegisterClassSupport (const Operation &op) const
 
bool hasRegisterClassSupport (const TDGenerator::ValueType &vt) const
 
TCEString associatedVectorRegisterClass (const Operand &operand) const
 
void writePatternReplacement (std::ostream &o, const TCEString &origPat, const TCEString &replacerPat) const
 
void writeOperationDefUsingGivenOperandTypes (std::ostream &o, Operation &op, bool skipPattern, std::vector< TDGenerator::ValueType > inputs, std::vector< TDGenerator::ValueType > outputs, TCEString instrSuffix="")
 
void writeRegisterDef (std::ostream &o, const RegInfo &reg, const std::string regName, const std::string regTemplate, const std::string aliases, RegType type)
 
void write64bitRegisterInfo (std::ostream &o)
 
void write32bitRegisterInfo (std::ostream &o)
 
void write16bitRegisterInfo (std::ostream &o)
 
void write8bitRegisterInfo (std::ostream &o)
 
void write1bitRegisterInfo (std::ostream &o)
 
void writeRARegisterInfo (std::ostream &o)
 
void writeGuardRegisterClassInfo (std::ostream &o)
 
void writeVectorRegisterBaseClasses (std::ostream &o) const
 
void writeVectorRegisterNames (std::ostream &o)
 
void writeVectorRegisterClasses (std::ostream &o) const
 
void writeVectorOperationDefs (std::ostream &o, Operation &op, bool skipPattern)
 
void writeVectorOperationDef (std::ostream &o, Operation &op, TCEString valueTypes, const TCEString &attributes, bool skipPattern)
 
void saveAdditionalVectorOperationInfo (const Operation &op, const TCEString &valueTypes, bool isRegisterOp)
 
void writeVectorMemoryOperationDefs (std::ostream &o, Operation &op, bool skipPattern)
 
void writeVectorBitwiseOperationDefs (std::ostream &o, Operation &op, bool skipPattern)
 
void writeVectorRegisterMoveDefs (std::ostream &o)
 
void writeVectorTruncStoreDefs (std::ostream &o) const
 
void writeScalarToVectorDefs (std::ostream &o) const
 
void writeVectorBitConversions (std::ostream &o) const
 
void writeScalarOperationExploitations (std::ostream &o)
 
void writeVectorLoadStoreOperationExploitations (std::ostream &o)
 
void writeWiderVectorOperationExploitations (std::ostream &o)
 
void genGeneratedTCEPlugin_getStore (std::ostream &o) const
 
void genGeneratedTCEPlugin_getLoad (std::ostream &o) const
 
void genGeneratedTCEPlugin_isVectorRegisterMove (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorValueType (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorBroadcastOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorPackOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorSelectOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorShuffle1Opcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorShuffle2Opcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getConstantVectorShuffleOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getExtractElemOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorShlSameOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorShrSameOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorShruSameOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorAndSameOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorIorSameOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorXorSameOpcode (std::ostream &o) const
 
void genTCETargetLoweringSIMD_addVectorRegisterClasses (std::ostream &o) const
 
void genTCETargetLoweringSIMD_associatedVectorRegClass (std::ostream &o) const
 
void genTCETargetLoweringSIMD_getSetCCResultVT (std::ostream &o) const
 
void genTCEInstrInfoSIMD_copyPhysVectorReg (std::ostream &o) const
 
void genGeneratedTCEPlugin_getVectorImmediateOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getGatherOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getLoadOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getAddOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getShlOpcode (std::ostream &o) const
 
void genGeneratedTCEPlugin_getIorOpcode (std::ostream &o) const
 
void writeVectorImmediateWriteDefs (std::ostream &instrInfoTD)
 
void createMinMaxDef (const TCEString &opName, const TCEString &valueName, std::ostream &os)
 
void createVectorMinMaxDef (const TCEString &opName, int bits, char llvmTypeChar, const TCEString &postFix, std::ostream &os)
 
void writeOperationDefs (std::ostream &o, Operation &op, bool skipPattern)
 
void writeOperationDef (std::ostream &o, Operation &op, const std::string &operandTypes, const std::string &attrs, bool skipPattern, std::string backendPrefix="")
 
std::string emulatingOpNodeLLVMName (const Operation &op, const OperationDAG &dag, const OperationNode &node, const std::string &operandTypes)
 
void writeEmulationPattern (std::ostream &o, const Operation &op, const OperationDAG &dag)
 
void write64bitMoveDefs (std::ostream &o)
 
void writeControlFlowInstrDefs (std::ostream &os)
 
void writeCondBranchDefs (std::ostream &os)
 
void writeCallDef (std::ostream &o)
 
void writeHWLoopDef (std::ostream &o)
 
virtual void writeCallDefRegs (std::ostream &o)
 
void writeRegisterClasses (std::ostream &o)
 
virtual TCEString llvmOperationPattern (const Operation &op, char operandType=' ') const
 
virtual TCEString llvmOperationName (const TCEString &opName) const
 
bool operationCanBeMatched (const Operation &op, std::set< std::string > *recursionCycleCheck=NULL, bool recursionHasStore=false)
 
bool operationDAGCanBeMatched (const OperationDAG &op, std::set< std::string > *recursionCycleCheck=NULL, bool recursionHasStore=false)
 
const OperationDAGgetMatchableOperationDAG (const Operation &op)
 
std::string tceOperationPattern (const Operation &op)
 
std::string patOutputs (const Operation &op, const std::string &oprTypes)
 
std::string patInputs (const Operation &op, const std::string &oprTypes)
 
virtual std::string operandToString (const Operand &operand, bool match, char operandType, const std::string &immDefName="")
 
std::string operationNodeToString (const Operation &op, const OperationDAG &dag, const OperationNode &node, bool emulationPattern, const std::string &operandTypes)
 
std::string constantNodeString (const Operation &op, const OperationDAG &dag, const ConstantNode &node, const std::string &operandTypes, const OperationDAGNode *successor=nullptr)
 
std::string dagNodeToString (const Operation &op, const OperationDAG &dag, const OperationDAGNode &node, bool emulationPattern, const std::string &operandTypes, const Operation *emulatingOp=nullptr, const OperationDAGNode *successor=nullptr)
 
std::string operationPattern (const Operation &op, const OperationDAG &dag, const std::string &operandTypes)
 
virtual char operandChar (Operand &operand)
 
std::string createDefaultOperandTypeString (const Operation &op)
 
void writeVectorStoreDefs (std::ostream &o, const TCEString &opName, const TCEString &opNameSuffix, bool addrImm, const TCEString &dataType, bool writePredicatedVersions)
 
void genTCEInstrInfo_copyPhys64bitReg (std::ostream &o) const
 
void writeArgRegsArray (std::ostream &os)
 
virtual void createSelectPatterns (std::ostream &os)
 
void writeAddressingModeDefs (std::ostream &o)
 
void createByteExtLoadPatterns (std::ostream &os)
 
void createShortExtLoadPatterns (std::ostream &os)
 
void create32BitExtLoadPatterns (std::ostream &os)
 
void createEndiannesQuery (std::ostream &os)
 
void createConstantMaterializationQuery (std::ostream &os)
 
void createConstShiftPatterns (std::ostream &os)
 
void writeOperationDefs (std::ostream &o, Operation &op, const std::string &operandTypes, const std::string &attrs, bool skipPattern, std::string backendPrefix="")
 
void writeVectorStoreDefs (std::ostream &o, Operation &op, int vectorLen)
 
void writeVectorTruncStoreDefs (std::ostream &o, Operation &op, int bitsize, int vectorLen)
 
void createGetMaxMemoryAlignment (std::ostream &os) const
 
void writeVectorAnyextPattern (std::ostream &o, Operation &op, const TCEString &loadPatternName, int vectorLen)
 
void writeVectorLoadDefs (std::ostream &o, const TCEString &opName, const TCEString &opNameSuffix, bool addrImm, const TCEString &resultType, const TCEString &loadPatternName, bool writePredicatedVersions)
 
virtual void writeImmediateDef (std::ostream &o, const std::string &defName, const std::string &operandType, const std::string &predicate)
 
void writeInstrDef (std::ostream &o, const std::string &instrDefName, const std::string &outs, const std::string &ins, const std::string &asmString, const std::string &pattern)
 
void writeVectorLoadDefs (std::ostream &o, Operation &op, const TCEString &loadPatternName, int vectorLen)
 
void writeBooleanStorePatterns (std::ostream &os)
 
std::string immediatePredicate (int64_t lowerBoundInclusive, uint64_t upperBoundInclusive)
 
std::string immediateOperandNameForEmulatedOperation (const OperationDAG &, const Operand &operand)
 
bool areImmediateOperandsLegal (const Operation &operation, const std::string &operandTypes) const
 
void writeBroadcastDefs (std::ostream &o, Operation &op, int vectorLen)
 
bool writePortGuardedJumpDefPair (std::ostream &os, const TCEString &tceop1, const TCEString &tceop2, bool fp=false)
 
std::string subPattern (const Operation &op, const OperationDAG &dag)
 
OperationDAGcreateTrivialDAG (Operation &op)
 
bool canBeImmediate (const OperationDAG &dag, const TerminalNode &node)
 
virtual void createMinMaxGenerator (std::ostream &os)
 
void writeCallSeqStart (std::ostream &os)
 
void writeMiscPatterns (std::ostream &o)
 
void generateLoadStoreCopyGenerator (std::ostream &os)
 
void createParamDRegNums (std::ostream &os)
 
virtual void createVectorRVDRegNums (std::ostream &os)
 
void writeCallingConv (std::ostream &os)
 
void writeCallingConvLicenceText (std::ostream &os)
 
void writeConstShiftPat (std::ostream &os, const TCEString &nodeName, const TCEString &opNameBase, int i)
 
void createBoolAndHalfLoadPatterns (std::ostream &os)
 
virtual void createConstantMaterializationPatterns (std::ostream &os)
 
void createBranchAnalysis (std::ostream &os)
 
void genTCERegisterInfo_setReservedVectorRegs (std::ostream &os) const
 
void writeGetPointerAdjustmentQuery (std::ostream &os) const
 
bool canBePredicated (Operation &op, const std::string &operandTypes)
 
TCEString getLLVMPatternWithConstants (const Operation &op, const std::string &operandTypes, const std::string &operand0, const std::string &operand1) const
 
std::string operandTypesToRegisters (const std::string &opdTypes) const
 
char operandTypeToRegister (const char &opdType) const
 
TCEString getMovePattern (const char &opdType, const std::string &inputPattern) const
 

Static Protected Member Functions

static std::vector< std::string > supportedStackAccessOperations (const TTAMachine::Machine &mach)
 

Protected Attributes

ImmInfoimmInfo_ = nullptr
 
std::map< ImmInfoKey, std::string > immOperandDefs_
 Maps (operation, operand) pairs to i32 immediate operand definition names. More...
 
const TTAMachine::Machinemach_
 
unsigned dregNum_
 
OperationDAGSelector::OperationSet allOpNames_
 Contains all operation names in upper case. More...
 
std::map< TCEString, Operation * > scalarOps_
 Contains all scalar operations (<Name, Operation>). More...
 
std::map< TCEString, Operation * > vectorOps_
 Contains all vector operations (<Name, Operation>). More...
 
std::map< int, TCEStringbaseClasses_
 Contains vector base classes for register files (<Width, Name>). More...
 
std::map< int, std::vector< TDGenerator::RegisterInfo > > registers_
 Contains registers fit for being vector registers (<Width, Registers>). More...
 
std::map< TCEString, TDGenerator::RegisterClassvRegClasses_
 Contains required vector register classes (<ValueType, RegClass>). More...
 
std::map< TCEString, TDGenerator::InstructionInforegisterStores_
 All register store operations (<ValueType, InstrInfo>). More...
 
std::map< TCEString, TDGenerator::InstructionInforegisterLoads_
 All register load operations (<ValueType, InstrInfo>). More...
 
std::map< TCEString, TDGenerator::InstructionInfoimmediateStores_
 All immediate store operations (<ValueType, InstrInfo>). More...
 
std::map< TCEString, TDGenerator::InstructionInfoimmediateLoads_
 All immediate load operations (<ValueType, InstrInfo>). More...
 
std::map< TCEString, TCEStringpackOperations_
 Contains machine's PACK instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringvbcastOperations_
 Contains machine's VBCAST instructions (<ValueType, InstrName>). More...
 
std::vector< std::pair< const Operation *, TCEString > > truncOperations_
 Contains machine's TRUNCxx/CFH instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringvselectOperations_
 Contains machine's VSELECT instructions (<instrName, ValueType>). More...
 
std::map< TCEString, TCEStringvshuffle1Operations_
 Contains machine's VSHUFFLE1 instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringvshuffle2Operations_
 Contains machine's VSHUFFLE2 instructions (<ValueType, InstrName>). More...
 
std::map< std::pair< TCEString, std::vector< int > >, TCEStringvcshuffleOperations_
 Contains machine's VCSHUFFLE instructions (<<ValueType, ConstantSelects>, InstrName>). More...
 
std::map< TCEString, TCEStringextractElemOperations_
 Contains machine's EXTRACTELEM instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringshlSameOperations_
 Contains machine's SHLSAME instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringshrSameOperations_
 Contains machine's SHRSAME instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringshruSameOperations_
 Contains machine's SHRUSAME instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringandSameOperations_
 Contains machine's ANDSAME instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringiorSameOperations_
 Contains machine's IORSAME instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringxorSameOperations_
 Contains machine's XORSAME instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringgatherOperations_
 Contains machine's GATHER instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringaddOperations_
 Contains machine's add instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringshlOperations_
 Contains machine's shl instructions (<ValueType, InstrName>). More...
 
std::map< TCEString, TCEStringiorOperations_
 Contains machine's shl instructions (<ValueType, InstrName>). More...
 
std::set< TCEStringmovOperations_
 Contains all moves between register classes (<InstrName>). More...
 
std::vector< RegInforegs1bit_
 
std::vector< RegInforegs8bit_
 
std::vector< RegInforegs16bit_
 
std::vector< RegInforegs32bit_
 
std::vector< RegInforegs64bit_
 
std::vector< std::string > llvmGuardRegs_
 The LLVM register defs used as guards. More...
 
std::map< std::string, RegInforegs_
 Map of generated llvm register names to physical register in the machine. More...
 
std::vector< std::string > argRegNames_
 
std::vector< std::string > resRegNames_
 
std::vector< std::string > gprRegNames_
 
std::map< std::string, std::string > opNames_
 
std::map< std::string, std::string > truePredOps_
 
std::map< std::string, std::string > falsePredOps_
 
int maxVectorSize_
 
int highestLaneInt_
 
int highestLaneBool_
 
bool hasExBoolRegs_
 
bool hasExIntRegs_
 
bool hasSelect_
 
bool hasConditionalMoves_
 
int maxScalarWidth_
 
bool littleEndian_
 
unsigned int argRegCount_
 
unsigned int requiredI32Regs_
 Minimum number of 32 bit registers. More...
 
unsigned int requiredI64Regs_
 
bool prebypassStackIndeces_
 
bool use64bitForFP_
 
std::set< RegInfoguardedRegs_
 List of register that are associated with a guard on a bus. More...
 
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::ComparatortempRegFiles_
 Register files whose last reg reserved for temp reg copies. More...
 
RegClassMap regsInClasses_
 All registers in certain group. More...
 
RegClassMap regsInRFClasses_
 
std::vector< std::string > constantMaterializationPredicates_
 All predicates used in constant materialization patterns. More...
 

Static Protected Attributes

static const int FP_SUBW_WIDTH
 Float type subword width. More...
 
static const int HFP_SUBW_WIDTH
 Half float type subword width. More...
 
static const int BOOL_SUBW_WIDTH
 Bool type subword width. More...
 
static const int MAX_SCALAR_WIDTH = 64
 Distincts wide vs scalar registers. More...
 
static const int MAX_SUBW_COUNT = SIMD_WORD_WIDTH / BYTE_BITWIDTH
 Maximum number of subwords that any SIMD operation can have. More...
 
static const bool EXPLOIT_BIGGER_REGISTERS = true
 If set to true, smaller vector value types can be stored to larger register files, e.g. v4i8 vectors can be stored to registers that are over 32 bits in size. More...
 
static const std::map< TCEString, TCEStringOPERATION_PATTERNS_
 Contains <BaseOpName, OpPattern> key-value pairs. More...
 
static const std::string guardRegTemplateName = "Guard"
 

Detailed Description

TCE Backend plugin source code and .td definition generator.

Generates files for building target architecture plugin for LLVM-TCE backend. This version generates the backend files for the "RISC instruction set style" output and provides useful methods.

Definition at line 77 of file TDGen.hh.

Member Typedef Documentation

◆ RegClassMap

typedef std::map<std::string, std::vector<std::string> > TDGen::RegClassMap
protected

Definition at line 628 of file TDGen.hh.

Member Enumeration Documentation

◆ RegsToProcess

enum TDGen::RegsToProcess
protected
Enumerator
ALL_REGISTERS 
ONLY_EXTRAS 
ONLY_LANES 
ONLY_NORMAL 

Definition at line 126 of file TDGen.hh.

126  {
128  ONLY_EXTRAS,
129  ONLY_LANES,
131  };

◆ RegType

enum TDGen::RegType
protected
Enumerator
GPR 
RESERVED 
ARGUMENT 
RESULT 

Definition at line 96 of file TDGen.hh.

96  {
97  GPR = 0,
98  RESERVED,
99  ARGUMENT,
100  RESULT
101  };

Constructor & Destructor Documentation

◆ TDGen()

TDGen::TDGen ( const TTAMachine::Machine mach)

Constructor.

Parameters
machMachine to generate plugin for.

Definition at line 341 of file TDGen.cc.

341  :
342  mach_(mach), dregNum_(0),
344  hasExBoolRegs_(false), hasExIntRegs_(false), hasSelect_(false),
346  argRegCount_(1),
348  use64bitForFP_(false) {
350 
351  prebypassStackIndeces_ = false;
352 
353  if (mach.is64bit()) {
354  std::set<int> scalarWidths { 1, 32 };
357 
358  // TODO: this does not make sense! requires more!
359  requiredI64Regs_ = 0;
361 
362  } else {
363  std::set<int> scalarWidths { 1, 32 };
366 
367  // TODO: this does not make sense! requires more!
368  requiredI32Regs_ = 0;
370  }
371 
373  maxScalarWidth_ = mach.is64bit() ? 64 : 32;
374 }

References ImmediateAnalyzer::analyze(), argRegCount_, MachineConnectivityCheck::hasConditionalMoves(), hasConditionalMoves_, immInfo_, TTAMachine::Machine::is64bit(), mach_, maxScalarWidth_, prebypassStackIndeces_, requiredI32Regs_, requiredI64Regs_, tempRegFiles_, and MachineConnectivityCheck::tempRegisterFiles().

Here is the call graph for this function:

◆ ~TDGen()

TDGen::~TDGen ( )
virtual

Destructor.

Definition at line 379 of file TDGen.cc.

379  {
380  delete immInfo_;
381 }

References immInfo_.

Member Function Documentation

◆ analyzeMachineRegisters()

void TDGen::analyzeMachineRegisters ( )
protected

Groups all registers in the machine by register width.

Goes through register files and sorts all real machine registers into <Width, vector<Register>> groups. A base class for each Width is also created.

Todo:
Apparently TDGen does not write information of 8 bit registers -> can't add them.

Definition at line 1422 of file TDGen.cc.

1422  {
1425  std::map<int, std::vector<RegisterInfo>>::iterator it;
1426 
1427  // Go through every register file in the machine.
1428  for (int i = 0; i < nav.count(); i++) {
1429  const TTAMachine::RegisterFile* rf = nav.item(i);
1430  assert(rf != NULL);
1431 
1432  // Check that the registerfile has both input and output ports.
1433  bool hasInput = false;
1434  bool hasOutput = false;
1435  for (int p = 0; p < rf->portCount(); p++) {
1436  if (rf->port(p)->isInput()) hasInput = true;
1437  if (rf->port(p)->isOutput()) hasOutput = true;
1438  }
1439 
1440  if (!hasInput) {
1443 
1445  << "Warning: Skipping register file '"
1446  << rf->name()
1447  << "': no input ports."
1448  << std::endl;
1449  }
1450  continue;
1451  }
1452 
1453  if (!hasOutput) {
1457  << "Warning Skipping register file '"
1458  << rf->name()
1459  << "': no output ports."
1460  << std::endl;
1461  }
1462  continue;
1463  }
1464 
1465  int rfWidth = rf->width();
1466 
1467  // If there is no entry for the width of the registers, create one.
1468  if (registers_.find(rfWidth) == registers_.end()) {
1469  registers_.insert(
1470  std::make_pair(rfWidth, std::vector<RegisterInfo>()));
1471  }
1472 
1473  it = registers_.find(rfWidth);
1474  std::vector<RegisterInfo>& registers = it->second;
1475 
1476  // Skip scalar size registers, they have been listed in TDGen.
1477  if (rfWidth > MAX_SCALAR_WIDTH) {
1478  // Kludge fix: Machines with >32 bit regs but without any vector
1479  // operations generates register info td file with 64 bit register
1480  // definition which are not associated to any register class.
1481  // This triggers assertion in LLVM side.
1482  if (vRegClasses_.empty()) continue;
1483 
1484  int lastIdx = rf->size();
1485 
1486  bool isTempRegRf = AssocTools::containsKey(tempRegFiles_, rf);
1487  if (isTempRegRf) {
1488  // If the machine is not enough connected,
1489  // preserve last register
1490  // of all register files for routing values.
1491  lastIdx--;
1492  }
1493 
1494  // Associate register file's registers with the width.
1495  for (int index = 0; index < lastIdx; ++index) {
1496  TCEString regName(
1497  rf->name() + "_" + Conversion::toString(index));
1498  RegisterInfo reg(regName, rf->name(), index, rfWidth);
1499  registers.push_back(reg);
1500  }
1501  }
1502  }
1503 
1505 
1506  // TDGen has hardcoded register name definitions, some
1507  // inspection needs to be done to create correct register names.
1508 
1509  std::vector<RegisterInfo> regs1bit;
1510  for (size_t i = 0; i < regs1bit_.size(); ++i) {
1511  RegisterInfo reg(
1512  "B" + Conversion::toString(i),
1513  regs1bit_[i].rf,
1514  regs1bit_[i].idx,
1515  1);
1516  regs1bit.push_back(reg);
1517  }
1518  registers_[1] = regs1bit;
1519 
1520  /// @todo Apparently TDGen does not write information of 8 bit
1521  /// registers -> can't add them.
1522 
1523  std::vector<RegisterInfo> regs16bit;
1524  for (size_t i = 0; i < regs16bit_.size(); ++i) {
1525  RegisterInfo reg(
1526  "H" + Conversion::toString(i),
1527  regs16bit_[i].rf,
1528  regs16bit_[i].idx,
1529  16);
1530 
1531  if (i == 0) {
1532  reg.regName_ = "HIRES0";
1533  }
1534 
1535  regs16bit.push_back(reg);
1536  }
1537  registers_[16] = regs16bit;
1538 
1539  std::vector<RegisterInfo> regs32bit;
1540  for (size_t i = 0; i < regs32bit_.size(); ++i) {
1541  RegisterInfo reg(
1542  "I" + Conversion::toString(i),
1543  regs32bit_[i].rf,
1544  regs32bit_[i].idx,
1545  32);
1546 
1547 
1548  if (!mach_.is64bit()) {
1549  if (i == 0) {
1550  reg.regName_ = "SP";
1551  } else if (i == 1) {
1552  reg.regName_ = "IRES0";
1553  } else if (i == 2) {
1554  reg.regName_ = "FP";
1555  } else if (i == 3) {
1556  reg.regName_ = "KLUDGE_REGISTER";
1557  } else if (i < argRegCount_ + 3) {
1558  reg.regName_ = "A" + Conversion::toString(i);
1559  }
1560  }
1561  regs32bit.push_back(reg);
1562  }
1563  registers_[32] = regs32bit;
1564 
1565  std::vector<RegisterInfo> regs64bit;
1566  for (size_t i = 0; i < regs64bit_.size(); ++i) {
1567  RegisterInfo reg(
1568  "L" + Conversion::toString(i),
1569  regs64bit_[i].rf,
1570  regs64bit_[i].idx,
1571  64);
1572 
1573  if (mach_.is64bit()) {
1574  if (i == 0) {
1575  reg.regName_ = "SP";
1576  } else if (i == 1) {
1577  reg.regName_ = "IRES0";
1578  } else if (i == 2) {
1579  reg.regName_ = "FP";
1580  } else if (i == 3) {
1581  reg.regName_ = "KLUDGE_REGISTER";
1582  } else if (i < argRegCount_ + 3) {
1583  reg.regName_ = "A" + Conversion::toString(i);
1584  }
1585  }
1586  regs64bit.push_back(reg);
1587  }
1588  registers_[64] = regs64bit;
1589 
1590  // Create base classes for different register widths.
1591  for (it = registers_.begin(); it != registers_.end(); ++it) {
1592  int width = it->first;
1593  if (width > MAX_SCALAR_WIDTH) {
1594  baseClasses_.insert(
1595  std::make_pair(width, "VR" + Conversion::toString(width)));
1596  } else {
1597  baseClasses_.insert(
1598  std::make_pair(width, "R" + Conversion::toString(width)));
1599  }
1600  }
1601 }

References argRegCount_, assert, baseClasses_, AssocTools::containsKey(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::is64bit(), TTAMachine::Port::isInput(), TTAMachine::Port::isOutput(), TTAMachine::Machine::Navigator< ComponentType >::item(), Application::logStream(), mach_, MAX_SCALAR_WIDTH, TTAMachine::Component::name(), orderEqualWidthRegistersToRoundRobin(), TTAMachine::BaseRegisterFile::port(), TTAMachine::Unit::portCount(), TTAMachine::Machine::registerFileNavigator(), registers_, TDGenerator::RegisterInfo::regName_, regs16bit_, regs1bit_, regs32bit_, regs64bit_, TTAMachine::BaseRegisterFile::size(), tempRegFiles_, Conversion::toString(), Application::VERBOSE_LEVEL_DEFAULT, Application::verboseLevel(), vRegClasses_, and TTAMachine::BaseRegisterFile::width().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ analyzeMachineVectorRegisterClasses()

void TDGen::analyzeMachineVectorRegisterClasses ( )
protected

Creates vector register classes required by the machine.

The function goes through all operations and lists all different vector operand value types, after which a register class is created for each vector value type to support the vector value type.

Definition at line 1226 of file TDGen.cc.

1226  {
1227  OperationPool opPool;
1228 
1229  // Has all vector value types (e.g. "v4i32", "v16i8", "v2f16", "v8f32")
1230  // that can be found among all the operands present in the machine.
1231  // Register classes will be defined based on these vector value types.
1232  std::set<TCEString> reqRegClassTypes;
1233 
1234  // List all existing vector value types in the machine.
1235  OperationDAGSelector::OperationSet::iterator opnIt;
1236  for (opnIt = allOpNames_.begin(); opnIt != allOpNames_.end(); ++opnIt) {
1237  Operation& op = opPool.operation((*opnIt).c_str());
1238 
1239  if (&op == &NullOperation::instance()) {
1240  continue;
1241  }
1242 
1243  // Go through every operand of the operation.
1244  for (int i = 1; i <= op.operandCount(); ++i) {
1245  Operand& operand = op.operand(i);
1246 
1247  // We are only interested in vector operands, skip otherwise.
1248  if (!operand.isVector()) {
1249  continue;
1250  }
1251 
1252  TCEString vtStr = ValueType::valueTypeStr(operand);
1253  if (vRegClasses_.find(vtStr) == vRegClasses_.end()) {
1254  reqRegClassTypes.insert(vtStr);
1255  }
1256 
1257  // If operand type is "raw" and vector subword width matches
1258  // float or half float width, list it also.
1259  if (operand.type() == Operand::RAW_DATA &&
1260  (operand.elementWidth() == FP_SUBW_WIDTH ||
1261  operand.elementWidth() == HFP_SUBW_WIDTH)) {
1262 
1263  ValueType vt(operand);
1264  vt.isFloat_ = true;
1265  const TCEString floatVtStr = vt.valueTypeStr();
1266 
1267  if (vRegClasses_.find(floatVtStr) == vRegClasses_.end()) {
1268  reqRegClassTypes.insert(floatVtStr);
1269  }
1270  }
1271  }
1272  }
1273 
1274  // Now we have listed all differend vector value types from the machine.
1275  // Create a register class for every LLVM supported vector value type.
1276 
1277  std::set<TCEString>::iterator it;
1278  for (it = reqRegClassTypes.begin(); it != reqRegClassTypes.end(); ++it) {
1279  const TCEString& vtStr = *it;
1280  const ValueType vt(vtStr);
1281 
1282  if (vt.isSupportedByLLVM()) {
1283  TCEString name = "V" + Conversion::toString(vt.subwCount_);
1284 
1285  if ((vt.isFloat_ && vt.subwWidth_ == FP_SUBW_WIDTH) ||
1286  (vt.isFloat_ && vt.subwWidth_ == HFP_SUBW_WIDTH)) {
1287  name += "F";
1288  } else {
1289  name += "I";
1290  }
1291 
1292  name += Conversion::toString(vt.subwWidth_) + "Regs";
1293 
1294  RegisterClass newRegClass(vt, name);
1295  vRegClasses_.insert(std::make_pair(vtStr, newRegClass));
1296  } else {
1297  verbose("Warning: RegisterClass not created for type: " + vtStr);
1298  }
1299  }
1300 }

References allOpNames_, Operand::elementWidth(), FP_SUBW_WIDTH, HFP_SUBW_WIDTH, NullOperation::instance(), TDGenerator::ValueType::isFloat_, TDGenerator::ValueType::isSupportedByLLVM(), Operand::isVector(), Operation::operand(), Operation::operandCount(), OperationPool::operation(), Operand::RAW_DATA, TDGenerator::ValueType::subwCount_, TDGenerator::ValueType::subwWidth_, Conversion::toString(), Operand::type(), TDGenerator::ValueType::valueTypeStr(), verbose(), and vRegClasses_.

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ analyzeRegisterFileClasses()

void TDGen::analyzeRegisterFileClasses ( )
protected

◆ analyzeRegisters() [1/2]

void TDGen::analyzeRegisters ( )
protected

Iterates through all registers in the machine and adds register information to the register sets.

Definition at line 783 of file TDGen.cc.

783  {
784 
785  const TTAMachine::Machine::BusNavigator busNav =
787 
788  // Check which registers have guards and put their info in
789  // guardedRegs_ set.
790  for (int i = 0; i < busNav.count(); i++) {
791  const TTAMachine::Bus& bus = *busNav.item(i);
792  for (int g = 0; g < bus.guardCount(); g++) {
793  const TTAMachine::RegisterGuard* rg =
794  dynamic_cast<const TTAMachine::RegisterGuard*>(bus.guard(g));
795 
796  if (rg != NULL) {
797  RegInfo reg = {
798  rg->registerFile()->name(),
799  (unsigned)rg->registerIndex() };
800 
801  guardedRegs_.insert(reg);
802  }
803  }
804  }
805 
808 
809  bool regsFound = true;
810  int currentIdx = 0;
811  while (regsFound) {
812  regsFound = false;
813  for (int i = 0; i < nav.count(); i++) {
814  const TTAMachine::RegisterFile* rf = nav.item(i);
815 
816  // Skip definition for registers that are marked as 'reserved'
817  if (rf->isReserved()) continue;
818 
819  // Skip the 0th index of a register file with zero register flag
820  if (currentIdx == 0 && rf->zeroRegister()) {
821  continue;
822  }
823 
824  // Check that the registerfile has both input and output ports.
825  bool hasInput = false;
826  bool hasOutput = false;
827  for (int p = 0; p < rf->portCount(); p++) {
828  if (rf->port(p)->isInput()) hasInput = true;
829  if (rf->port(p)->isOutput()) hasOutput = true;
830  }
831 
832  if (!hasInput) {
835 
837  << "Warning: Skipping register file '"
838  << rf->name()
839  << "': no input ports."
840  << std::endl;
841  }
842  continue;
843  }
844 
845  if (!hasOutput) {
848 
850  << "Warning Skipping register file '"
851  << rf->name()
852  << "': no output ports."
853  << std::endl;
854  }
855  continue;
856  }
857 
858  unsigned width = rf->width();
859  std::vector<RegInfo>* ri = NULL;
860  if (width == 64) ri = &regs64bit_;
861  else if (width == 32) ri = &regs32bit_;
862  //else if (width == 16) ri = &regs16bit_;
863  else if (width == 8) ri = &regs8bit_;
864  else if (width == 1) ri = &regs1bit_;
865  else {
866  continue;
867  }
868 
869  int lastIdx = rf->size();
870  // todo: find a good solution to use just one big rf for this.
871 
872  bool isTempRegRf = AssocTools::containsKey(tempRegFiles_, rf);
873  if (isTempRegRf) {
874  // If the machine is not enough connected,
875  // preserve last register
876  // of all register files for routing values.
877  lastIdx--;
878  }
879 
880  // leave some 32bit regs unallocated for the post pass scheduler's
881  // register renamer
882  if (width == 32) {
883  int renamerRegs = rf->size() * REG_RENAMER_PART / 100;
884  lastIdx -= renamerRegs;
885  }
886 
887  if (currentIdx < lastIdx) {
888  RegInfo reg = {rf->name(), (unsigned)currentIdx};
889  if (!(width == 32 &&
890  guardedRegs_.find(reg) != guardedRegs_.end())) {
891  ri->push_back(reg);
892  }
893  regsFound = true;
894  }
895  }
896  currentIdx++;
897  }
898 }

References TTAMachine::Machine::busNavigator(), AssocTools::containsKey(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), guardedRegs_, TTAMachine::Port::isInput(), TTAMachine::Port::isOutput(), TTAMachine::RegisterFile::isReserved(), TTAMachine::Machine::Navigator< ComponentType >::item(), Application::logStream(), mach_, TTAMachine::Component::name(), TTAMachine::BaseRegisterFile::port(), TTAMachine::Unit::portCount(), REG_RENAMER_PART, TTAMachine::RegisterGuard::registerFile(), TTAMachine::Machine::registerFileNavigator(), TTAMachine::RegisterGuard::registerIndex(), regs1bit_, regs32bit_, regs64bit_, regs8bit_, TTAMachine::BaseRegisterFile::size(), tempRegFiles_, Application::VERBOSE_LEVEL_DEFAULT, Application::verboseLevel(), TTAMachine::BaseRegisterFile::width(), and TTAMachine::RegisterFile::zeroRegister().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ analyzeRegisters() [2/2]

void TDGen::analyzeRegisters ( RegsToProcess  regsToProcess)
protected

◆ areImmediateOperandsLegal()

bool TDGen::areImmediateOperandsLegal ( const Operation operation,
const std::string &  operandTypes 
) const
protected

Checks if the operation can have the specified immediate operands.

Definition at line 7543 of file TDGen.cc.

7545  {
7546 
7547  assert(static_cast<int>(operandTypes.size()) >= operation.operandCount());
7548 
7549  for (int i = 0 ; i < operation.numberOfInputs(); i++) {
7550  if (operandTypes.at(i + operation.numberOfOutputs()) != OT_IMM_INT) {
7551  continue;
7552  }
7553 
7554  const Operand& operand = operation.operand(i+1);
7555 
7556  // Kludge fix for ADDri/MEMri operands. LLVM wants some times to select
7557  // store/load instruction, where the address operand is immediate.
7558  // However, the machine may not have capability to directly transport
7559  // immediate to the address operand. Considering the case as illegal
7560  // will reject operation definitions using ADDri/MEMri operands and
7561  // breaks the instruction selection later on. Temporarily accept
7562  // ADDri/MEMri operands until the issue is fixed.
7563  if (operand.isAddress()) {
7564  continue;
7565  }
7566 
7567  if (immInfo_->count(operation, operand) == 0) {
7568  for (int swappableWith : operand.swap()) {
7569  const Operand& otherOperand = operation.operand(swappableWith);
7570  if (immInfo_->count(operation, otherOperand)
7571  && operation.name() != "EQ"
7572  && operation.name() != "NE") {
7573  // ^ EQ and NE are not commutative in LLVM
7574  return true;
7575  }
7576  }
7577  return false;
7578  }
7579  }
7580 
7581  return true;
7582 }

References assert, ImmInfo::count(), immInfo_, Operand::isAddress(), Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), Operation::operandCount(), OT_IMM_INT, and Operand::swap().

Referenced by writeOperationDef().

Here is the call graph for this function:

◆ associatedVectorRegisterClass()

TCEString TDGen::associatedVectorRegisterClass ( const Operand operand) const
protected

Returns the name of the vector class that supports given operand.

Parameters
operandChecked if any register class supports value type of this.
Returns
Name of the register class that supports operand's value type.

Definition at line 1786 of file TDGen.cc.

1786  {
1787  std::map<TCEString, RegisterClass>::const_iterator it =
1788  vRegClasses_.find(ValueType::valueTypeStr(operand));
1789 
1790  if (it == vRegClasses_.end()) {
1791  // Shouldn't get here because any operation whose operands are not
1792  // supported will not get created.
1793  assert(false);
1794  }
1795 
1796  const RegisterClass& regClass = it->second;
1797  return regClass.name();
1798 }

References assert, TDGenerator::RegisterClass::name(), and vRegClasses_.

Referenced by operandToString().

Here is the call graph for this function:

◆ associateRegistersWithVectorRegisterClasses()

void TDGen::associateRegistersWithVectorRegisterClasses ( )
protected

Attaches proper register groups to register files.

Definition at line 1653 of file TDGen.cc.

1653  {
1654  std::map<TCEString, RegisterClass>::iterator rcIt;
1655  for (rcIt = vRegClasses_.begin(); rcIt != vRegClasses_.end(); ++rcIt) {
1656  RegisterClass& regClass = rcIt->second;
1657 
1658  // Go through all register groups (they are in ascending order by
1659  // width -> starts from the smallest width always towards wider ones).
1660  std::map<int, std::vector<RegisterInfo>>::iterator regsIt =
1661  registers_.begin();
1662 
1663  bool found = false;
1664  while (!found && regsIt != registers_.end()) {
1665  int regsWidth = regsIt->first;
1666  size_t amountOfRegs = (regsIt->second).size();
1667 
1668  // If can find a group of registers which satisfies the
1669  // register class width requirement, choose those registers.
1670  if (regsWidth >= regClass.valueType().width() &&
1671  amountOfRegs > 0) {
1672  const std::vector<RegisterInfo>& regs = regsIt->second;
1673  regClass.addRegisters(regs);
1674  found = true;
1675  }
1676 
1677  ++regsIt;
1678  }
1679 
1680  // If bigger register exploitation is desired, append all the rest
1681  // of the registers, because there are only wider registers left.
1683  while (regsIt != registers_.end()) {
1684  const std::vector<RegisterInfo>& biggerRegs = regsIt->second;
1685  regClass.addRegisters(biggerRegs);
1686  ++regsIt;
1687  }
1688  }
1689  }
1690 }

References TDGenerator::RegisterClass::addRegisters(), EXPLOIT_BIGGER_REGISTERS, registers_, TDGenerator::RegisterClass::valueType(), vRegClasses_, and TDGenerator::ValueType::width().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ canBeImmediate()

bool TDGen::canBeImmediate ( const OperationDAG dag,
const TerminalNode node 
)
protected

Returns true if the operand corresponding to the given TerminalNode in an OperationDAG can be immediate in the llvm pattern.

Parameters
dagDAG of the whole operation.
nodeTerminalNode corresponding to the operand queried.

Definition at line 6049 of file TDGen.cc.

6050  {
6051 
6052  if (dag.inDegree(node) != 0) {
6053  return false;
6054  }
6055 
6056  for (int i = 0; i < dag.outDegree(node); i++) {
6057  const OperationDAGEdge& edge = dag.outEdge(node, i);
6058  const OperationDAGNode& dstNode = dag.headNode(edge);
6059  const OperationNode* opNode =
6060  dynamic_cast<const OperationNode*>(&dstNode);
6061 
6062  if (opNode == NULL) {
6063  return false;
6064  }
6065  }
6066  return true;
6067 }

References BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::outDegree(), and BoostGraph< GraphNode, GraphEdge >::outEdge().

Referenced by dagNodeToString().

Here is the call graph for this function:

◆ canBePredicated()

bool TDGen::canBePredicated ( Operation op,
const std::string &  operandTypes 
)
protected

Returns true if the instruction can be predicated.

TODO

Definition at line 7591 of file TDGen.cc.

7591  {
7592 
7593  // Predicating operands with immediates can currently lead to
7594  // unschedulable code in case there's no bus that has both the
7595  // predicate and the immediate transfer capability. Disable
7596  // generating the predicated versions for immediate operand
7597  // patterns for now.
7598  if (operandTypes.find(OT_IMM_INT) != std::string::npos) return false;
7599 
7600  if (hasConditionalMoves_) return true;
7601 
7602  return false;
7603 }

References hasConditionalMoves_, and OT_IMM_INT.

Referenced by writeOperationDef().

◆ checkRequiredRegisters()

bool TDGen::checkRequiredRegisters ( )
protected

Checks that the target machine has required registers to build a usable plugin.

Returns
True if required registers were found, false if not.

Definition at line 3280 of file TDGen.cc.

3280  {
3281  if (!mach_.is64bit() && regs32bit_.size() < requiredI32Regs_) {
3282  std::string msg =
3283  (boost::format(
3284  "Architecture doesn't meet the minimal requirements.\n"
3285  "Only %d 32-bit general purpose registers found. At least %d\n"
3286  "needed.")
3287  % regs32bit_.size() % requiredI32Regs_)
3288  .str();
3289 
3290  if (tempRegFiles_.size() > 0) {
3291  msg += "Your machine is not fully connected, thus one register\n"
3292  "from each register file are reserved for temp moves and\n"
3293  "not used as general purpose registers.";
3294  }
3295 
3296  throw InvalidData(__FILE__, __LINE__, __func__, msg);
3297  return false;
3298  }
3299 
3300  if (regs64bit_.size() < requiredI64Regs_) {
3301  std::string msg =
3302  (boost::format(
3303  "Architecture doesn't meet the minimal requirements.\n"
3304  "Only %d 64-bit general purpose registers found. At least %d\n"
3305  "needed. ")
3306  % regs64bit_.size() % requiredI64Regs_)
3307  .str();
3308 
3309  if (tempRegFiles_.size() > 0) {
3310  msg += "Your machine is not fully connected, thus one register\n"
3311  "from each register file is reserved for temp moves and\n"
3312  "not used as general purpose registers.";
3313  }
3314 
3315  throw InvalidData(__FILE__, __LINE__, __func__, msg);
3316  return false;
3317  }
3318 
3319  return true;
3320 }

References __func__, TTAMachine::Machine::is64bit(), mach_, regs32bit_, regs64bit_, requiredI32Regs_, requiredI64Regs_, and tempRegFiles_.

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ constantNodeString()

std::string TDGen::constantNodeString ( const Operation op,
const OperationDAG dag,
const ConstantNode node,
const std::string &  operandTypes,
const OperationDAGNode successor = nullptr 
)
protected

Definition at line 5541 of file TDGen.cc.

5546  {
5547 
5548  assert(dag.inDegree(node) == 0);
5549  assert(dag.outDegree(node) == 1 || successor);
5550  const OperationDAGNode& succ = successor ?
5551  *successor : dag.headNode(dag.outEdge(node,0));
5552  const OperationNode* opn = dynamic_cast<const OperationNode*>(&succ);
5553  OperationDAG::NodeSet siblings = dag.predecessors(*opn);
5554  for (OperationDAG::NodeSet::iterator i = siblings.begin();
5555  i!= siblings.end(); i++) {
5556  const TerminalNode* tNode = dynamic_cast<const TerminalNode*>(*i);
5557  if (tNode != NULL) {
5558  const Operand& operand = op.operand(tNode->operandIndex());
5559  assert(operand.isInput());
5560  char operandType =
5561  operandTypes[operand.index()-1 + op.numberOfOutputs()];
5562  // Retrieve largest short immediate for the operand.
5563  switch (operandType) {
5564  case OT_REG_BOOL:
5565  case OT_IMM_BOOL:
5566  return "(i1 " + Conversion::toString(node.value()) + ")";
5567  case OT_REG_DOUBLE:
5568  return "(f64 " + Conversion::toString(node.value()) +")";
5569  case OT_REG_HFP:
5570  return "(f16 " + Conversion::toString(node.value()) + ")";
5571  // TODO: f16 vectors not yet implemented
5572  case OT_REG_FP:
5573  case OT_IMM_FP:
5574  return "(f32 " + Conversion::toString(node.value()) + ")";
5575  case OT_REG_LONG:
5576  case OT_IMM_LONG:
5577  return "(i64 " + Conversion::toString(node.value()) + ")";
5578  case OT_REG_INT:
5579  case OT_IMM_INT:
5580  return mach_.is64bit() ?
5581  "(i64 " + Conversion::toString(node.value()) + ")":
5582  "(i32 " + Conversion::toString(node.value()) + ")";
5583  default:
5584  break;
5585  }
5586  }
5587  }
5588  return Conversion::toString(node.value());
5589 }

References assert, BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), Operand::index(), TTAMachine::Machine::is64bit(), Operand::isInput(), mach_, Operation::numberOfOutputs(), Operation::operand(), TerminalNode::operandIndex(), OT_IMM_BOOL, OT_IMM_FP, OT_IMM_INT, OT_IMM_LONG, OT_REG_BOOL, OT_REG_DOUBLE, OT_REG_FP, OT_REG_HFP, OT_REG_INT, OT_REG_LONG, BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), BoostGraph< GraphNode, GraphEdge >::predecessors(), Conversion::toString(), and ConstantNode::value().

Referenced by dagNodeToString().

Here is the call graph for this function:

◆ create32BitExtLoadPatterns()

void TDGen::create32BitExtLoadPatterns ( std::ostream &  os)
protected

Definition at line 6734 of file TDGen.cc.

6734  {
6735  TCEString load = "LD32";
6736  const TCEString uload = "LDU32";
6737  TCEString ZXOP = "ZXW64";
6738  TCEString ZXOPC = "ZXW64ss";
6739 
6740  if (mach_.hasOperation(load)) {
6741  if (!mach_.hasOperation(uload)) {
6742  if (!mach_.hasOperation(ZXOP)) {
6743  // emulate zero ext with sing-ext and and
6744  os << "def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), "
6745  << "(AND64ssa (LD32ss ADDRrr:$addr),"
6746  << "0xffffffff)>;" << std::endl;
6747 
6748  os << "def : Pat<(i64 (zextloadi32 ADDRri:$addr)), "
6749  << "(AND64ssa (LD32sa ADDRri:$addr),"
6750  << "0xffffffff)>;" << std::endl;
6751  } else {
6752  // use zxw64 instr for zext
6753  os << "def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), "
6754  << "(" << ZXOPC << " (LD32ss ADDRrr:$addr))>;" <<std::endl;
6755 
6756  os << "def : Pat<(i64 (zextloadi32 ADDRri:$addr)), "
6757  << "(" << ZXOPC << " (LD32sa ADDRri:$addr))>;" <<std::endl;
6758  }
6759  }
6760  } else {
6761  if (!mach_.hasOperation(uload)) {
6762  std::cerr << "Warning: The architecture is missing any 16-bit loads."
6763  << std::endl;
6764  return;
6765  }
6766  load = uload;
6767 
6768  if (mach_.hasOperation("SXW64")) {
6769  // use zextload + sext for sextload
6770  os << "def : Pat<(i64 (sextloadi32 ADDRrr:$addr)), "
6771  << "(SXW64ss (LDU32ss ADDRrr:$addr))>;" << std::endl;
6772 
6773  os << "def : Pat<(i64 (sextloadi32 ADDRri:$addr)), "
6774  << "(SXW64ss (LDU32sa ADDRri:$addr))>;" << std::endl;
6775  } else {
6776  std::cerr << "Warning: no sign-extending 32-bit loads or"
6777  << " 32-bit sign extension instruction!"
6778  << " in the processor. All code may not compile!"
6779  << std::endl;
6780  }
6781  }
6782  // anyext.
6783  os << "def : Pat<(i64 (extloadi32 ADDRrr:$src)), "
6784  << "(" << load << "ss ADDRrr:$src)>;" << std::endl
6785 
6786  << "def : Pat<(i64 (extloadi32 ADDRri:$src)), "
6787  << "(" << load << "sa ADDRrr:$src)>;" << std::endl;
6788 }

References TTAMachine::Machine::hasOperation(), and mach_.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ createBoolAndHalfLoadPatterns()

void TDGen::createBoolAndHalfLoadPatterns ( std::ostream &  os)
protected

Definition at line 8534 of file TDGen.cc.

8534  {
8535 
8536  // TODO: what about true/false versions of these ops?
8537 
8538  TCEString load = littleEndian_ ? "LD8" : "LDQ";
8539  TCEString uload = littleEndian_ ? "LDU8" : "LDQU";
8540  TCEString wload = littleEndian_ ?
8541  (mach_.is64bit() ? "LD64" : "LD32") : "LDW";
8542  if (mach_.hasOperation(load)) {
8543  os << "def " << load
8544  << "Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8545  << "[(set R1Regs:$op2, (sextloadi1 ADDRrr:$op1))]>;" << std::endl
8546  << "def " << load
8547  << "Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8548  << "[(set R1Regs:$op2, (sextloadi1 ADDRri:$op1))]>; " << std::endl;
8549 
8550  opNames_[load + "Br"] = load;
8551  opNames_[load + "Bi"] = load;
8552 
8553  }
8554  if (mach_.hasOperation(uload)) {
8555  os << "def " << uload
8556  << "Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8557  << "[(set R1Regs:$op2, (zextloadi1 ADDRrr:$op1))]>;" << std::endl
8558  << "def " << uload
8559  << "Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8560  << "[(set R1Regs:$op2, (zextloadi1 ADDRri:$op1))]>;" << std::endl;
8561  opNames_[uload + "Br"] = uload;
8562  opNames_[uload + "Bi"] = uload;
8563 
8564  os << "def : Pat<(i1 (load ADDRrr:$addr)), ("
8565  << uload << "Br ADDRrr:$addr)>;" << std::endl;
8566  os << "def : Pat<(i1 (load ADDRri:$addr)), ("
8567  << uload << "Bi ADDRri:$addr)>;" << std::endl;
8568  } else {
8569  if (mach_.hasOperation(load)) {
8570  os << "def : Pat<(i1 (load ADDRrr:$addr)), ("
8571  << load << "Br ADDRrr:$addr)>;" << std::endl;
8572  os << "def : Pat<(i1 (load ADDRri:$addr)), ("
8573  << load << "Bi ADDRri:$addr)>;" << std::endl;
8574  }
8575  }
8576 
8577  // if no 8-bit loads, create 32/64-bit loads for stack access but
8578  // no patterns for isel as only the stack is 32/64-bit aligned.
8579  // 1- and 8-bit loads on isel will be handled by lowering.
8580  if (!mach_.hasOperation(load) &&
8581  !mach_.hasOperation(uload) &&
8582  mach_.hasOperation(wload)) {
8583  os << "def " << wload
8584  << "Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8585  << "[]>;" << std::endl
8586  << "def " << wload
8587  << "Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8588  << "[]>;" << std::endl;
8589 
8590  opNames_[wload + "Br"] = wload;
8591  opNames_[wload + "Bi"] = wload;
8592  }
8593 
8594  TCEString halfLoad = littleEndian_ ? "LD16" : "LDH";
8595  if (!mach_.hasOperation(halfLoad)) {
8596  TCEString halfULoad = littleEndian_ ? "LDU16" : "LDHU";
8597  if (mach_.hasOperation(halfULoad)) {
8598  halfLoad = halfULoad;
8599  } else {
8600  return;
8601  }
8602  }
8603 
8604  os << "def " << halfLoad << "hr : InstTCE<(outs HFPRegs:$op2), "
8605  << "(ins MEMrr:$op1), \"\", [(set HFPRegs:$op2, "
8606  << "(load ADDRrr:$op1))]>;" << std::endl;
8607 
8608  os << "def " << halfLoad << "hi : InstTCE<(outs HFPRegs:$op2), "
8609  << "(ins MEMri:$op1), \"\", [(set HFPRegs:$op2, "
8610  << "(load ADDRri:$op1))]>;" << std::endl;
8611 
8612  opNames_[halfLoad + "hr"] = halfLoad;
8613  opNames_[halfLoad + "hi"] = halfLoad;
8614 
8615  // TODO: what about 32-bit?
8616 }

References TTAMachine::Machine::hasOperation(), TTAMachine::Machine::is64bit(), littleEndian_, mach_, and opNames_.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ createBranchAnalysis()

void TDGen::createBranchAnalysis ( std::ostream &  os)
protected

Definition at line 7896 of file TDGen.cc.

7896  {
7897  os << "bool GeneratedTCEPlugin::analyzeCCBranch(" << std::endl
7898  << "\tllvm::MachineInstr& i," << std::endl
7899  << "\tllvm::SmallVectorImpl<llvm::MachineOperand>& cond) const {"
7900  << std::endl
7901  << std::endl;
7902 
7905 
7906  os << "\tif (i.getOpcode() == TCE::EQ_JUMP) {" << std::endl
7907  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7908  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7909  << "\t\tcond.push_back(MachineOperand::CreateImm(2));"
7910  << std::endl
7911  << "\t\treturn false; }" << std::endl;
7912 
7913  os << "\tif (i.getOpcode() == TCE::NE_JUMP) {" << std::endl
7914  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7915  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7916  << "\t\tcond.push_back(MachineOperand::CreateImm(3));"
7917  << std::endl
7918  << "\t\treturn false; }" << std::endl;
7919 
7920  os << "\tif (i.getOpcode() == TCE::GT_JUMP) {" << std::endl
7921  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7922  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7923  << "\t\tcond.push_back(MachineOperand::CreateImm(4));"
7924  << std::endl
7925  << "\t\treturn false; }" << std::endl;
7926 
7927  os << "\tif (i.getOpcode() == TCE::LE_JUMP) {" << std::endl
7928  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7929  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7930  << "\t\tcond.push_back(MachineOperand::CreateImm(5));"
7931  << std::endl
7932  << "\t\treturn false; }" << std::endl;
7933 
7934  os << "\tif (i.getOpcode() == TCE::GTU_JUMP) {" << std::endl
7935  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7936  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7937  << "\t\tcond.push_back(MachineOperand::CreateImm(6));"
7938  << std::endl
7939  << "\t\treturn false; }" << std::endl;
7940 
7941  os << "\tif (i.getOpcode() == TCE::LEU_JUMP) {" << std::endl
7942  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7943  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7944  << "\t\tcond.push_back(MachineOperand::CreateImm(7));"
7945  << std::endl
7946  << "\t\treturn false; }" << std::endl;
7947 
7948  if (opNames_.find("EQF_JUMP") != opNames_.end()) {
7949  os << "\tif (i.getOpcode() == TCE::EQF_JUMP) {" << std::endl
7950  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7951  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7952  << "\t\tcond.push_back(MachineOperand::CreateImm(8));"
7953  << std::endl
7954  << "\t\treturn false; }" << std::endl;
7955  }
7956 
7957  if (opNames_.find("NEF_JUMP") != opNames_.end()) {
7958  os << "\tif (i.getOpcode() == TCE::NEF_JUMP) {" << std::endl
7959  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7960  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7961  << "\t\tcond.push_back(MachineOperand::CreateImm(9));"
7962  << std::endl
7963  << "\t\treturn false; }" << std::endl;
7964  }
7965 
7966  if (opNames_.find("LEF_JUMP") != opNames_.end()) {
7967  os << "\tif (i.getOpcode() == TCE::LEF_JUMP) {" << std::endl
7968  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7969  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7970  << "\t\tcond.push_back(MachineOperand::CreateImm(10));"
7971  << std::endl
7972  << "\t\treturn false; }" << std::endl;
7973  }
7974 
7975  if (opNames_.find("GEF_JUMP") != opNames_.end()) {
7976  os << "\tif (i.getOpcode() == TCE::GEF_JUMP) {" << std::endl
7977  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7978  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7979  << "\t\tcond.push_back(MachineOperand::CreateImm(10));"
7980  << std::endl
7981  << "\t\treturn false; }" << std::endl;
7982  }
7983 
7984  if (opNames_.find("LTF_JUMP") != opNames_.end()) {
7985  os << "\tif (i.getOpcode() == TCE::LTF_JUMP) {" << std::endl
7986  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7987  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7988  << "\t\tcond.push_back(MachineOperand::CreateImm(12));"
7989  << std::endl
7990  << "\t\treturn false; }" << std::endl;
7991  }
7992 
7993  if (opNames_.find("GTF_JUMP") != opNames_.end()) {
7994  os << "\tif (i.getOpcode() == TCE::GTF_JUMP) {" << std::endl
7995  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
7996  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
7997  << "\t\tcond.push_back(MachineOperand::CreateImm(13));"
7998  << std::endl
7999  << "\t\treturn false; }" << std::endl;
8000  }
8001  }
8002 
8005  if (opNames_.count("TCEBREQrr")) {
8006  os << "\tif (i.getOpcode() == TCE::TCEBREQrr) {" << std::endl
8007  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8008  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8009  << "\t\tcond.push_back(MachineOperand::CreateImm(2));"
8010  << std::endl
8011  << "\t\treturn false;" << std::endl
8012  << "\t}" << std::endl;
8013 
8014  os << "\tif (i.getOpcode() == TCE::TCEBREQri) {" << std::endl
8015  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8016  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8017  << "\t\tcond.push_back(MachineOperand::CreateImm(102));"
8018  << std::endl
8019  << "\t\treturn false;" << std::endl
8020  << "\t}" << std::endl;
8021  }
8022 
8023  if (opNames_.count("TCEBRNErr")) {
8024  os << "\tif (i.getOpcode() == TCE::TCEBRNErr) {" << std::endl
8025  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8026  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8027  << "\t\tcond.push_back(MachineOperand::CreateImm(3));"
8028  << std::endl
8029  << "\t\treturn false;" << std::endl
8030  << "\t}" << std::endl;
8031 
8032  os << "\tif (i.getOpcode() == TCE::TCEBRNEri) {" << std::endl
8033  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8034  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8035  << "\t\tcond.push_back(MachineOperand::CreateImm(103));"
8036  << std::endl
8037  << "\t\treturn false;" << std::endl
8038  << "\t}" << std::endl;
8039  }
8040 
8041  if (opNames_.count("TCEBRGTrr")) {
8042  os << "\tif (i.getOpcode() == TCE::TCEBRGTrr) {" << std::endl
8043  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8044  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8045  << "\t\tcond.push_back(MachineOperand::CreateImm(4));"
8046  << std::endl
8047  << "\t\treturn false;" << std::endl
8048  << "\t}" << std::endl;
8049 
8050  os << "\tif (i.getOpcode() == TCE::TCEBRGTri) {" << std::endl
8051  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8052  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8053  << "\t\tcond.push_back(MachineOperand::CreateImm(104));"
8054  << std::endl
8055  << "\t\treturn false;" << std::endl
8056  << "\t}" << std::endl;
8057  }
8058 
8059  if (opNames_.count("TCEBRGTUrr")) {
8060  os << "\tif (i.getOpcode() == TCE::TCEBRGTUrr) {" << std::endl
8061  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8062  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8063  << "\t\tcond.push_back(MachineOperand::CreateImm(6));"
8064  << std::endl
8065  << "\t\treturn false;" << std::endl
8066  << "\t}" << std::endl;
8067 
8068  os << "\tif (i.getOpcode() == TCE::TCEBRGTUri) {" << std::endl
8069  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8070  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8071  << "\t\tcond.push_back(MachineOperand::CreateImm(106));"
8072  << std::endl
8073  << "\t\treturn false;" << std::endl
8074  << "\t}" << std::endl;
8075  }
8076 
8077  if (opNames_.count("TCEBRLTrr")) {
8078  os << "\tif (i.getOpcode() == TCE::TCEBRLTrr) {" << std::endl
8079  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8080  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8081  << "\t\tcond.push_back(MachineOperand::CreateImm(14));"
8082  << std::endl
8083  << "\t\treturn false;" << std::endl
8084  << "\t}" << std::endl;
8085 
8086  os << "\tif (i.getOpcode() == TCE::TCEBRLTri) {" << std::endl
8087  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8088  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8089  << "\t\tcond.push_back(MachineOperand::CreateImm(114));"
8090  << std::endl
8091  << "\t\treturn false;" << std::endl
8092  << "\t}" << std::endl;
8093  }
8094 
8095  if (opNames_.count("TCEBRLTUrr")) {
8096  os << "\tif (i.getOpcode() == TCE::TCEBRLTUrr) {" << std::endl
8097  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8098  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8099  << "\t\tcond.push_back(MachineOperand::CreateImm(15));"
8100  << std::endl
8101  << "\t\treturn false;" << std::endl
8102  << "\t}" << std::endl;
8103 
8104  os << "\tif (i.getOpcode() == TCE::TCEBRLTUri) {" << std::endl
8105  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8106  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8107  << "\t\tcond.push_back(MachineOperand::CreateImm(115));"
8108  << std::endl
8109  << "\t\treturn false;" << std::endl
8110  << "\t}" << std::endl;
8111  }
8112 
8113  if (opNames_.count("TCEBRLErr")) {
8114  os << "\tif (i.getOpcode() == TCE::TCEBRLErr) {" << std::endl
8115  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8116  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8117  << "\t\tcond.push_back(MachineOperand::CreateImm(5));"
8118  << std::endl
8119  << "\t\treturn false;" << std::endl
8120  << "\t}" << std::endl;
8121 
8122  os << "\tif (i.getOpcode() == TCE::TCEBRLEri) {" << std::endl
8123  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8124  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8125  << "\t\tcond.push_back(MachineOperand::CreateImm(105));"
8126  << std::endl
8127  << "\t\treturn false;" << std::endl
8128  << "\t}" << std::endl;
8129  }
8130 
8131  if (opNames_.count("TCEBRLEUrr")) {
8132  os << "\tif (i.getOpcode() == TCE::TCEBRLEUrr) {" << std::endl
8133  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8134  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8135  << "\t\tcond.push_back(MachineOperand::CreateImm(7));"
8136  << std::endl
8137  << "\t\treturn false;" << std::endl
8138  << "\t}" << std::endl;
8139 
8140  os << "\tif (i.getOpcode() == TCE::TCEBRLEUri) {" << std::endl
8141  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8142  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8143  << "\t\tcond.push_back(MachineOperand::CreateImm(107));"
8144  << std::endl
8145  << "\t\treturn false;" << std::endl
8146  << "\t}" << std::endl;
8147  }
8148 
8149  if (opNames_.count("TCEBRGErr")) {
8150  os << "\tif (i.getOpcode() == TCE::TCEBRGErr) {" << std::endl
8151  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8152  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8153  << "\t\tcond.push_back(MachineOperand::CreateImm(16));"
8154  << std::endl
8155  << "\t\treturn false;" << std::endl
8156  << "\t}" << std::endl;
8157 
8158  os << "\tif (i.getOpcode() == TCE::TCEBRGEri) {" << std::endl
8159  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8160  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8161  << "\t\tcond.push_back(MachineOperand::CreateImm(116));"
8162  << std::endl
8163  << "\t\treturn false;" << std::endl
8164  << "\t}" << std::endl;
8165  }
8166 
8167  if (opNames_.count("TCEBRGEUrr")) {
8168  os << "\tif (i.getOpcode() == TCE::TCEBRGEUrr) {" << std::endl
8169  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8170  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8171  << "\t\tcond.push_back(MachineOperand::CreateImm(17));"
8172  << std::endl
8173  << "\t\treturn false;" << std::endl
8174  << "\t}" << std::endl;
8175 
8176  os << "\tif (i.getOpcode() == TCE::TCEBRGEUri) {" << std::endl
8177  << "\t\tcond.push_back(i.getOperand(0));" << std::endl
8178  << "\t\tcond.push_back(i.getOperand(1));" << std::endl
8179  << "\t\tcond.push_back(MachineOperand::CreateImm(117));"
8180  << std::endl
8181  << "\t\treturn false;" << std::endl
8182  << "\t}" << std::endl;
8183  }
8184  }
8185  os << "\treturn true;"
8186  << "}" << std::endl << std::endl;
8187 
8188  // insert branch
8189 
8190  os << "#include <llvm/CodeGen/MachineInstrBuilder.h>" << std::endl
8191  << std::endl;
8192 
8193  os << "void TCEInstrInfo::insertCCBranch( " << std::endl
8194  << "\tMachineBasicBlock& mbb," << std::endl
8195  << "\tMachineBasicBlock& tbb," << std::endl
8196  << "\tArrayRef<MachineOperand> cond," << std::endl
8197  << "const DebugLoc& dl) const {" << std::endl
8198  << "\tassert(cond.size() == 3);" << std::endl;
8199 
8200  os << "\tint opcode;" << std::endl;
8201 
8204  os << "\tswitch (cond[2].getImm()) {" << std::endl
8205  << "\t\tcase 2: opcode = TCE::EQ_JUMP;break;" << std::endl
8206  << "\t\tcase 3: opcode = TCE::NE_JUMP;break;" << std::endl
8207  << "\t\tcase 4: opcode = TCE::GT_JUMP;break;" << std::endl
8208  << "\t\tcase 5: opcode = TCE::LE_JUMP;break;" << std::endl
8209  << "\t\tcase 6: opcode = TCE::GTU_JUMP;break;" << std::endl
8210  << "\t\tcase 7: opcode = TCE::LEU_JUMP;break;" << std::endl;
8211 
8212  if (opNames_.find("EQF_JUMP") != opNames_.end()) {
8213  os << "\t\tcase 8: opcode = TCE::EQF_JUMP;break;" << std::endl;
8214  }
8215  if (opNames_.find("NEF_JUMP") != opNames_.end()) {
8216  os << "\t\tcase 9: opcode = TCE::NEF_JUMP;break;" << std::endl;
8217  }
8218  if (opNames_.find("LEF_JUMP") != opNames_.end()) {
8219  os << "\t\tcase 10: opcode = TCE::LEF_JUMP;break;" << std::endl;
8220  }
8221  if (opNames_.find("GEF_JUMP") != opNames_.end()) {
8222  os << "\t\tcase 11: opcode = TCE::GEF_JUMP;break;" << std::endl;
8223  }
8224  if (opNames_.find("LTF_JUMP") != opNames_.end()) {
8225  os << "\t\tcase 12: opcode = TCE::LTF_JUMP;break;" << std::endl;
8226  }
8227  if (opNames_.find("GEF_JUMP") != opNames_.end()) {
8228  os << "\t\tcase 13: opcode = TCE::GTF_JUMP;break;" << std::endl;
8229  }
8230 
8231  os << "\t\tdefault: assert(false && \"Unknown condition code\");}"
8232  << std::endl;
8235  os << "\tswitch (cond[2].getImm()) {" << std::endl;
8236  if (opNames_.count("TCEBREQrr")) {
8237  os << "\t\tcase 2: opcode = TCE::TCEBREQrr; break;" << std::endl
8238  << "\t\tcase 102: opcode = TCE::TCEBREQri; break;"
8239  << std::endl;
8240  }
8241  if (opNames_.count("TCEBRNErr")) {
8242  os << "\t\tcase 3: opcode = TCE::TCEBRNErr; break;" << std::endl
8243  << "\t\tcase 103: opcode = TCE::TCEBRNEri; break;"
8244  << std::endl;
8245  }
8246  if (opNames_.count("TCEBRGTrr")) {
8247  os << "\t\tcase 4: opcode = TCE::TCEBRGTrr; break;" << std::endl
8248  << "\t\tcase 104: opcode = TCE::TCEBRGTri; break;"
8249  << std::endl;
8250  }
8251  if (opNames_.count("TCEBRGTUrr")) {
8252  os << "\t\tcase 6: opcode = TCE::TCEBRGTUrr; break;" << std::endl
8253  << "\t\tcase 106: opcode = TCE::TCEBRGTUri; break;"
8254  << std::endl;
8255  }
8256  if (opNames_.count("TCEBRLTrr")) {
8257  os << "\t\tcase 14: opcode = TCE::TCEBRLTrr; break;" << std::endl
8258  << "\t\tcase 114: opcode = TCE::TCEBRLTri; break;"
8259  << std::endl;
8260  }
8261  if (opNames_.count("TCEBRLTUrr")) {
8262  os << "\t\tcase 15: opcode = TCE::TCEBRLTUrr; break;" << std::endl
8263  << "\t\tcase 115: opcode = TCE::TCEBRLTUri; break;"
8264  << std::endl;
8265  }
8266  if (opNames_.count("TCEBRLErr")) {
8267  os << "\t\tcase 5: opcode = TCE::TCEBRLErr; break;" << std::endl
8268  << "\t\tcase 105: opcode = TCE::TCEBRLEri; break;"
8269  << std::endl;
8270  }
8271  if (opNames_.count("TCEBRLEUrr")) {
8272  os << "\t\tcase 7: opcode = TCE::TCEBRLEUrr; break;" << std::endl
8273  << "\t\tcase 107: opcode = TCE::TCEBRLEUri; break;"
8274  << std::endl;
8275  }
8276  if (opNames_.count("TCEBRGErr")) {
8277  os << "\t\tcase 16: opcode = TCE::TCEBRGErr; break;" << std::endl
8278  << "\t\tcase 116: opcode = TCE::TCEBRGEri; break;"
8279  << std::endl;
8280  }
8281  if (opNames_.count("TCEBRGEUrr")) {
8282  os << "\t\tcase 17: opcode = TCE::TCEBRGEUrr; break;" << std::endl
8283  << "\t\tcase 117: opcode = TCE::TCEBRGEUri; break;"
8284  << std::endl;
8285  }
8286  os << "\t\tdefault: assert(false && \"Unknown condition code\");}"
8287  << std::endl;
8288  } else {
8289  os << "\tassert(false && \"Unknown condition code\");" << std::endl;
8290  }
8291 
8292  os << "\tif (cond[1].isReg()) {" << std::endl
8293  << "\t\tBuildMI(&mbb, dl, get(opcode)).addReg(cond[0].getReg())"
8294  << std::endl
8295  << "\t\t .addReg(cond[1].getReg()).addMBB(&tbb);" << std::endl
8296  << "\t} else {" << std::endl
8297  << "\t\tBuildMI(&mbb, dl, get(opcode)).addReg(cond[0].getReg())"
8298  << std::endl
8299  << "\t\t .addImm(cond[1].getImm()).addMBB(&tbb);" << std::endl
8300  << "\t}" << std::endl;
8301  os << "}";
8302 }

References mach_, opNames_, MachineInfo::supportsBoolRegisterGuardedJumps(), and MachineInfo::supportsPortGuardedJumps().

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ createByteExtLoadPatterns()

void TDGen::createByteExtLoadPatterns ( std::ostream &  os)
protected

Definition at line 6457 of file TDGen.cc.

6457  {
6458  TCEString load = littleEndian_ ? "LD8" : "LDQ";
6459  TCEString uload = littleEndian_ ? "LDU8" : "LDQU";
6460  TCEString destSize = mach_.is64bit() ? "64" : "32";
6461  int bits = mach_.is64bit() ? 64 : 32;
6462  TCEString ANDIMM = mach_.is64bit() ? "AND64ssa" : "ANDrri";
6463  TCEString ANDREG = mach_.is64bit() ? "AND64sss" : "ANDrrr";
6464  TCEString SUBIMM = mach_.is64bit() ? "SUB64sas" : "SUBrir";
6465  TCEString EXTOP = mach_.is64bit() ? "SXQ64" : "SXQW";
6466  TCEString EXTOPC = mach_.is64bit() ? "SXQ64sr" : "SXQWrr";
6467  TCEString SHL = mach_.is64bit() ? "SHL" : "SHL64";
6468  TCEString SHR = mach_.is64bit() ? "SHR" : "SHR64";
6469  TCEString SHRU = mach_.is64bit() ? "SHRU" : "SHRU64ssa";
6470  TCEString SHLOPC = mach_.is64bit() ? "SHLrri" : "SHL64ssa";
6471  TCEString SHROPC = mach_.is64bit() ? "SHRrri" : "SHR64ssa";
6472  TCEString SHRUOPC = mach_.is64bit() ? "SHRUrri" : "SHRU64ssa";
6473  TCEString SHL4 = mach_.is64bit() ? "SHL4_32" : "SHL4_64";
6474  TCEString SHR4 = mach_.is64bit() ? "SHR4_32" : "SHR4_64";
6475  TCEString SHRU4 = mach_.is64bit() ? "SHRU4_32" : "SHRU4_64ssa";
6476  TCEString regSrcChar = mach_.is64bit() ? OT_REG_LONG : OT_REG_INT;
6477  TCEString dstTypeChar = OT_REG_INT;
6478  TCEString immSrcChar = mach_.is64bit() ? OT_IMM_LONG : OT_IMM_INT;
6479  TCEString loadOpcReg = load + dstTypeChar + regSrcChar;
6480  TCEString loadOpcImm = load + dstTypeChar + immSrcChar;
6481 
6482  if (mach_.hasOperation(load)) {
6483  if (!mach_.hasOperation(uload)) {
6484 
6485  // emulate zero ext with sing-ext and and
6486  os << "def : Pat<(i" << destSize << " (zextloadi8 ADDRrr:$addr)), "
6487  << "(" << ANDIMM << " ("
6488  << loadOpcReg << " ADDRrr:$addr), 255)>;"
6489  << std::endl;
6490  os << "def : Pat<(i" << destSize << " (zextloadi8 ADDRri:$addr)), "
6491  << "(" << ANDIMM << " ("
6492  << loadOpcImm << " ADDRri:$addr), 255)>;"
6493  << std::endl;
6494  }
6495  } else {
6496  // if no sign ext load, try zero ext load
6497  if (!mach_.hasOperation(uload)) {
6498  std::cerr << "Warning: The architecture is missing any 8-bit loads."
6499  << " All code may not compile!"
6500  << std::endl;
6501  return;
6502  }
6503  loadOpcReg = uload + dstTypeChar + regSrcChar;
6504  loadOpcImm = uload + dstTypeChar + immSrcChar;
6505 
6506  if (mach_.hasOperation(EXTOP)) {
6507  // use zextload + sext for sextload
6508  os << "def : Pat<(i" << destSize
6509  << " (sextloadi8 ADDRrr:$addr)), "
6510  << "(" << EXTOPC << " ("
6511  << loadOpcReg << " ADDRrr:$addr))>;" << std::endl;
6512  os << "def : Pat<(i" << destSize
6513  << " (sextloadi8 ADDRri:$addr)), "
6514  << "(" << EXTOPC << " ("
6515  << loadOpcImm << " ADDRri:$addr))>;" << std::endl;
6516 
6517  } else {
6518  if (mach_.hasOperation(SHL) && mach_.hasOperation(SHR)) {
6519 
6520  int sb = bits -8;
6521  os << "def : Pat<(i" << destSize
6522  << " (sextloadi16 ADDRrr:$addr)), "
6523  << "(" << SHROPC << " (" << SHLOPC << " ("
6524  << load << "rr ADDRrr:$addr), "
6525  << sb << "), " << sb << ")>;" << std::endl;
6526 
6527  os << "def : Pat<(i" << destSize
6528  << " (sextloadi16 ADDRri:$addr)), "
6529  << "(" << SHROPC << " (" << SHLOPC << " ("
6530  << load << "ri ADDRri:$addr), "
6531  << sb << "), " << sb << ")>;" << std::endl;
6532  } else if (mach_.hasOperation(SHL4) &&
6533  mach_.hasOperation(SHR4)) {
6534  if (!mach_.is64bit()) {
6535  os << "def : Pat<(i32 (sextloadi8 ADDRrr:$addr)), "
6536  << "(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6537  << "(SHR4_32rr (SHR4_32rr "
6538  << "(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr "
6539  << "(SHL4_32rr (SHL4_32rr ("
6540  << load << "rr ADDRrr:$addr)))))))))))))>;"
6541  << std::endl;
6542 
6543  os << "def : Pat<(i32 (sextloadi8 ADDRri:$addr)), "
6544  << "(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6545  << "(SHR4_32rr (SHR4_32rr "
6546  << "(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr "
6547  << "(SHL4_32rr (SHL4_32rr ("
6548  << load << "ri ADDRri:$addr)))))))))))))>;"
6549  << std::endl;
6550  } else {
6551  os << "def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), "
6552  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6553  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6554  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6555  << "(SHR4_64ss (SHR4_64ss "
6556  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6557  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6558  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6559  << "(SHL4_64ss (SHL4_64ss ("
6560  << load << "rr ADDRrr:$addr)))))))))))))>;"
6561  << std::endl;
6562 
6563  os << "def : Pat<(i64 (sextloadi8 ADDRri:$addr)), "
6564  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6565  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6566  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6567  << "(SHR4_64ss (SHR4_64ss "
6568  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6569  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6570  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6571  << "(SHL4_64ss (SHL4_64ss ("
6572  << load << "ri ADDRri:$addr)))))))))))))>;"
6573  << std::endl;
6574  }
6575  } else {
6576  std::cerr << "Warning: no sign-extending 8-bit loads,"
6577  << " 8-bit sign extension instruction or suitable"
6578  << " shifts for sext-emulation in the processor."
6579  << " All code may not compile!" << std::endl;
6580  }
6581  }
6582  }
6583 
6584  // TODO: is there a more capable version of this code
6585  // commented out above???
6586 
6587  os << "def : Pat<(i" << destSize << " (zextloadi1 ADDRrr:$addr)), ("
6588  << loadOpcReg << " ADDRrr:$addr)>;"
6589  << std::endl
6590  << "def : Pat<(i" << destSize << " (zextloadi1 ADDRri:$addr)), ("
6591  << loadOpcImm << " ADDRri:$addr)>;"
6592  << std::endl;
6593 
6594  os << "def : Pat<(i" << destSize << " (sextloadi1 ADDRrr:$addr)), "
6595  << "(" << SUBIMM << " 0, "
6596  << "(" << ANDREG << " ("
6597  << loadOpcReg << " ADDRrr:$addr), 1))>;"
6598  << std::endl
6599  << "def : Pat<(i" << destSize << " (sextloadi1 ADDRri:$addr)), "
6600  << "(" << SUBIMM << " 0, "
6601  << "(" << ANDREG << " ("
6602  << loadOpcImm << " ADDRri:$addr), 1))>;"
6603  << std::endl
6604  << "// anyextloads" << std::endl;
6605 
6606  os << "def : Pat<(i" << destSize << " (extloadi1 ADDRrr:$src)), ("
6607  << loadOpcReg << " ADDRrr:$src)>;" << std::endl
6608  << "def : Pat<(i" << destSize << " (extloadi1 ADDRri:$src)), ("
6609  << loadOpcImm << " ADDRri:$src)>;" << std::endl
6610  << "def : Pat<(i" << destSize << " (extloadi8 ADDRrr:$src)), ("
6611  << loadOpcReg << " ADDRrr:$src)>;" << std::endl
6612  << "def : Pat<(i" << destSize << " (extloadi8 ADDRri:$src)), ("
6613  << loadOpcImm << " ADDRri:$src)>;" << std::endl
6614  << std::endl;
6615 }

References TTAMachine::Machine::hasOperation(), TTAMachine::Machine::is64bit(), littleEndian_, mach_, OT_IMM_INT, OT_IMM_LONG, OT_REG_INT, OT_REG_LONG, and SUBIMM.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ createConstantMaterializationPatterns()

void TDGen::createConstantMaterializationPatterns ( std::ostream &  os)
protectedvirtual

Generates llvm patterns for constants which are not supported directly as immediates by the target machine.

For example, if a target does not sign extending immediates, a pattern is generated that transforms negative constants C to (SUB 0, -C).

Definition at line 7384 of file TDGen.cc.

7384  {
7385 
7386  // TODO: this is used when when not needed!
7387  // creating unnecessary NEG operations!
7388 
7389  // LLVM XForm fragments //
7390 
7391  // Transformation functions definitions that creates new constants
7392  // from unsupported constants.
7393  os << std::endl << "// Arithmetic negation XForm fragment."
7394  << std::endl << "def aneg_xform : SDNodeXForm<imm, [{"
7395  << std::endl << " return CurDAG->getTargetConstant("
7396  << std::endl << " -(N->getZExtValue()), SDLoc(N), MVT::i32);"
7397  << std::endl << "}]>;"
7398  << std::endl << std::endl;
7399 
7400  // Constant select operand definitions //
7401 
7402  // Used in Constant materialization patterns to select the constant values
7403  // that are valid for the pattern transformation. The predicate must
7404  // test that the original constant can be accepted by the materialization
7405  // pattern itself and test that the resulted constants by XForms are
7406  // supported too by the target machine.
7407 
7408  // Negative constant materialization: C -> NEG(-C) or C -> SUB(0, -C)
7409  // selecting the cheapest.
7410  std::vector<std::string> ops;
7411  if (opNames_.count("NEGri")) ops.push_back("NEG");
7412  if (opNames_.count("SUBrri")) ops.push_back("SUB");
7413  for (auto op : ops) {
7414  // Predicate that accepts the negative constants
7415  std::string predicate = "Imm < 0";
7416  std::pair<int64_t, int64_t> tmp = immInfo_->immediateValueBounds(
7417  ImmInfoKey{op , 1} , 32);
7418  if (tmp.second < 2) continue;
7419 
7420  predicate += " && Imm >= -" + Conversion::toString(tmp.second-1);
7421 
7422  writeImmediateDef(os, "minus_i32imm", "i32", predicate);
7423  // store predicates for the materialization queries by ISelLowering,
7424  // where decisions to bail unsupported constants to constant pool are
7425  // made. The stored predicates are written to Backend.inc later on.
7426  constantMaterializationPredicates_.push_back(predicate);
7427 
7428  os << std::endl << "def : Pat<(i32 minus_i32imm:$imm)," << std::endl;
7429  if (op == "NEG") {
7430  os << " (NEGri (aneg_xform imm:$imm))>;";
7431  } else if (op == "SUB") {
7432  os << " (SUBrri (MOVI32ri 0), (aneg_xform imm:$imm))>;";
7433  }
7434  os << std::endl;
7435  break; // We need only the cheapest materialization pattern.
7436  }
7437 }

References constantMaterializationPredicates_, ImmInfo::immediateValueBounds(), immInfo_, opNames_, Conversion::toString(), and writeImmediateDef().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ createConstantMaterializationQuery()

void TDGen::createConstantMaterializationQuery ( std::ostream &  os)
protected

Creates query function for TCEISelLowering for testing if otherwise unsupported constant as immediate can be materialized instead of converting it to constant pool load.

Definition at line 6427 of file TDGen.cc.

6427  {
6428 
6429  if (constantMaterializationPredicates_.empty()) {
6430  os << "bool GeneratedTCEPlugin::canMaterializeConstant("
6431  << "const ConstantInt&) const { " << std::endl
6432  << " return false;" << std::endl
6433  << "};" << std::endl;
6434  return;
6435  }
6436 
6437  os << "bool GeneratedTCEPlugin::canMaterializeConstant("
6438  << "const ConstantInt& ci) const {"
6439  << std::endl
6440  << " int64_t Imm = ci.getSExtValue();" << std::endl
6441  << " if (";
6442  bool first = true;
6443  for (auto& predicate : constantMaterializationPredicates_) {
6444  if (!first) {
6445  os << std::endl << " || ";
6446  }
6447  os << "(" << predicate << ")";
6448  first = false;
6449  }
6450  os << ") {"
6451  << " return true;" << std::endl
6452  << " }" << std::endl
6453  << " return false;" << std::endl
6454  << "}" << std::endl;
6455 }

References constantMaterializationPredicates_.

Referenced by writeBackendCode().

◆ createConstShiftPatterns()

void TDGen::createConstShiftPatterns ( std::ostream &  os)
protected

Definition at line 8525 of file TDGen.cc.

8525  {
8526  int bits = mach_.is64bit() ? 64: 32;
8527  for (int i = 1; i < bits; i++) {
8528  writeConstShiftPat(os, "TCESRAConst", "SHR", i);
8529  writeConstShiftPat(os, "TCESRLConst", "SHRU", i);
8530  writeConstShiftPat(os, "TCESHLConst", "SHL", i);
8531  }
8532 }

References TTAMachine::Machine::is64bit(), mach_, and writeConstShiftPat().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ createDefaultOperandTypeString()

std::string TDGen::createDefaultOperandTypeString ( const Operation op)
protected

Definition at line 5369 of file TDGen.cc.

5369  {
5370  std::string operandTypes;
5371 
5372  int inputs = op.numberOfInputs();
5373  int outputs = op.numberOfOutputs();
5374 
5375  for (int i = 0; i < outputs; i++) {
5376  Operand& operand = op.operand(i + inputs +1);
5377  operandTypes += operandChar(operand);
5378  }
5379 
5380  for (int i = 0; i < inputs ; i++) {
5381  Operand& operand = op.operand(i +1);
5382  operandTypes += operandChar(operand);
5383  }
5384  return operandTypes;
5385 }

References Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), and operandChar().

Referenced by subPattern(), writeOperationDefs(), and writeOperationDefUsingGivenOperandTypes().

Here is the call graph for this function:

◆ createEndiannesQuery()

void TDGen::createEndiannesQuery ( std::ostream &  os)
protected

Definition at line 6413 of file TDGen.cc.

6413  {
6414  bool is64bit = mach_.is64bit();
6415  os << "bool GeneratedTCEPlugin::isLittleEndian() const {" << std::endl;
6416  os << "return " << littleEndian_ << "; }" << std::endl;
6417  os << "bool GeneratedTCEPlugin::is64bit() const {" << std::endl;
6418  os << "return " << is64bit << "; }" << std::endl;
6419 }

References TTAMachine::Machine::is64bit(), littleEndian_, and mach_.

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ createGetMaxMemoryAlignment()

void TDGen::createGetMaxMemoryAlignment ( std::ostream &  os) const
protected

Definition at line 6974 of file TDGen.cc.

6974  {
6975  if (mach_.is64bit()) {
6976  os << std::endl
6977  << "unsigned GeneratedTCEPlugin::getMaxMemoryAlignment() const {"
6978  << std::endl
6979  << "\treturn 8;"
6980  << std::endl << "}" << std::endl;
6981  } else {
6982  os << std::endl
6983  << "unsigned GeneratedTCEPlugin::getMaxMemoryAlignment() const {"
6984  << std::endl
6985  << "\treturn 4;"
6986  << std::endl << "}" << std::endl;
6987  }
6988 }

References TTAMachine::Machine::is64bit(), and mach_.

Here is the call graph for this function:

◆ createMinMaxDef()

void TDGen::createMinMaxDef ( const TCEString opName,
const TCEString valueName,
std::ostream &  os 
)
protected

Definition at line 6296 of file TDGen.cc.

6297  {
6298  if (opNames_.find(opName) != opNames_.end()) {
6299  os << "\tif (vt == MVT::" << valueName << ") return TCE::"
6300  << opName << ";" << std::endl;
6301  }
6302 }

References opNames_.

Referenced by createVectorMinMaxDef().

◆ createMinMaxGenerator()

void TDGen::createMinMaxGenerator ( std::ostream &  os)
protectedvirtual

Definition at line 6324 of file TDGen.cc.

6324  {
6325 
6326  bool is64bit = mach_.is64bit();
6327  // MIN
6328  os << "int GeneratedTCEPlugin::getMinOpcode(SDNode* n) const {" << std::endl
6329  << "\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6330  if (!is64bit) {
6331  if (opNames_.find("MINrrr") != opNames_.end()) {
6332  os << "if (vt == MVT::i32) return TCE::MINrrr;" << std::endl;
6333  }
6334  } else {
6335  if (opNames_.find("MIN64sss") != opNames_.end()) {
6336  os << "if (vt == MVT::i64) return TCE::MIN64sss;" << std::endl;
6337  }
6338  }
6339  if (opNames_.find("MINFfff") != opNames_.end()) {
6340  os << "if (vt == MVT::f32) return TCE::MINFfff;" << std::endl;
6341  }
6342 
6343  createVectorMinMaxDef("MINH", 16, 'f', "ggg", os);
6344  createVectorMinMaxDef("MINF", 32, 'f', "eee", os);
6345  createVectorMinMaxDef("MIN", 32, 'i', "uuu", os);
6346  createVectorMinMaxDef("MIN", 16, 'i', "ttt", os);
6347 
6348  os << "\treturn -1; " << std::endl << "}" << std::endl;
6349 
6350  // MAX
6351  os << "int GeneratedTCEPlugin::getMaxOpcode(SDNode* n) const {" << std::endl
6352  << "\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6353 
6354  if (!is64bit) {
6355  if (opNames_.find("MAXrrr") != opNames_.end()) {
6356  os << "if (vt == MVT::i32) return TCE::MAXrrr;" << std::endl;
6357  }
6358  } else {
6359  if (opNames_.find("MAX64sss") != opNames_.end()) {
6360  os << "if (vt == MVT::i64) return TCE::MAX64sss;" << std::endl;
6361  }
6362 
6363  }
6364  if (opNames_.find("MAXFfff") != opNames_.end()) {
6365  os << "if (vt == MVT::f32) return TCE::MAXFfff;" << std::endl;
6366  }
6367 
6368  createVectorMinMaxDef("MAXH", 16, 'f', "ggg", os);
6369  createVectorMinMaxDef("MAXF", 32, 'f', "eee", os);
6370  createVectorMinMaxDef("MAX", 32, 'i', "uuu", os);
6371  createVectorMinMaxDef("MAX", 16, 'i', "ttt", os);
6372 
6373  os << "\treturn -1; " << std::endl << "}" << std::endl;
6374 
6375  // MINU
6376  os << "int GeneratedTCEPlugin::getMinuOpcode(SDNode* n) const {" << std::endl;
6377  os << "\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6378 
6379  if (!is64bit) {
6380  if (opNames_.find("MINUrrr") != opNames_.end()) {
6381  os << "if (vt == MVT::i32) return TCE::MINUrrr;" << std::endl;
6382  }
6383  } else {
6384  if (opNames_.find("MINU64sss") != opNames_.end()) {
6385  os << "if (vt == MVT::i64) return TCE::MINU64sss;" << std::endl;
6386  }
6387  }
6388  createVectorMinMaxDef("MINU", 32, 'i', "uuu", os);
6389  createVectorMinMaxDef("MINU", 16, 'i', "ttt", os);
6390 
6391  os << "\treturn -1; " << std::endl << "}" << std::endl;
6392 
6393  // MAXU
6394  os << "int GeneratedTCEPlugin::getMaxuOpcode(SDNode* n) const {" << std::endl;
6395  os << "\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6396 
6397 
6398  if (!is64bit) {
6399  if (opNames_.find("MAXUrrr") != opNames_.end()) {
6400  os << "if (vt == MVT::i32) return TCE::MAXUrrr;" << std::endl;
6401  }
6402  } else {
6403  if (opNames_.find("MAXU64sss") != opNames_.end()) {
6404  os << "if (vt == MVT::i64) return TCE::MAXU64sss;" << std::endl;
6405  }
6406  }
6407 
6408  createVectorMinMaxDef("MAXU", 32, 'i', "uuu", os);
6409  createVectorMinMaxDef("MAXU", 16, 'i', "ttt", os);
6410  os << "\treturn -1; " << std::endl << "}" << std::endl;
6411 }

References createVectorMinMaxDef(), TTAMachine::Machine::is64bit(), mach_, and opNames_.

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ createParamDRegNums()

void TDGen::createParamDRegNums ( std::ostream &  os)
protected

Definition at line 6936 of file TDGen.cc.

6936  {
6937  os <<
6938  "std::vector<unsigned>" << std::endl <<
6939  "GeneratedTCEPlugin::getParamDRegNums() const {" << std::endl <<
6940  "std::vector<unsigned> res;" << std::endl;
6941  for (unsigned int i = 4; i < argRegCount_ + 3; i++) {
6942  os << "res.push_back(TCE::A" << i << ");" << std::endl;
6943  }
6944  os << "return res;}" << std::endl;
6945 }

References argRegCount_.

Referenced by writeBackendCode().

◆ createSelectPatterns()

void TDGen::createSelectPatterns ( std::ostream &  os)
protectedvirtual

Definition at line 6991 of file TDGen.cc.

6991  {
6992  os << "// Creating select patterns. " << std::endl;
6993  if (!hasSelect_) {
6994  os << "// Does not have select instr. " << std::endl;
6995  if (!hasConditionalMoves_) {
6996  std::string NEG = mach_.is64bit() ? "NEG64" : "NEG";
6997  std::string NEGOPC = mach_.is64bit() ? "NEG64ss" : "NEGrr";
6998  std::string gprRegs = mach_.is64bit() ? "R64IRegs" : "R32IRegs";
6999  std::string typeStr = mach_.is64bit() ? "ssa" : "rri";
7000  std::string typeStrInv = mach_.is64bit() ? "sas" : "rir";
7001 
7002  const char* sub = mach_.is64bit() ? "SUB64" : "SUB";
7003  const char* iand = mach_.is64bit() ? "AND64" : "AND";
7004  std::string ior = mach_.is64bit() ? "IOR64" : "IOR";
7005  std::string defType = mach_.is64bit() ? "i64" : "i32";
7006  std::string andReg = mach_.is64bit() ? "AND64sss" : "ANDrrr";
7007  std::string iorReg = mach_.is64bit() ? "IOR64sss" : "IORrrr";
7008 
7009  std::string iorBool = mach_.is64bit() ? "IOR64bbb" : "IORbbb";
7010  std::string andBool = mach_.is64bit() ? "AND64bbb" : "ANDbbb";
7011  std::string xorBooli = mach_.is64bit() ? "XOR64bbj" : "XORbbj";
7012 
7013  bool hasNeg = opNames_.count("NEGrr");
7014 
7015  std::string condRC = regs1bit_.empty() ? gprRegs : "R1Regs";
7016  std::string truncOp = regs1bit_.empty() ? std::string(iand) + typeStr : "ANDext";
7017  OperationPool opPool;
7018  std::string truncPattern = regs1bit_.empty()
7019  ? std::string("$c")
7020  : std::string("(") + truncOp + " " + condRC + ":$c" + ", 1)";
7021  std::string falseMask = getLLVMPatternWithConstants(
7022  opPool.operation(sub), typeStr, truncPattern, "1");
7023 
7024  std::string trueMask = hasNeg ?
7025  std::string("(" + NEGOPC + " ") + truncPattern +
7026  std::string(")")
7028  opPool.operation(sub), typeStrInv, "0", truncPattern);
7029 
7030  std::string applyTrueMaskOnImm = getLLVMPatternWithConstants(
7031  opPool.operation(iand), typeStr, trueMask, "imm:$t");
7032  std::string applyFalseMaskOnImm = getLLVMPatternWithConstants(
7033  opPool.operation(iand), typeStr, falseMask, "imm:$f");
7034 
7035 #if 0 // TODO: why is this commented out???
7036  if (mach_.is64bit()) {
7037  os << std::endl
7038  << "def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, R64Regs:$f)), "
7039  << "(IOR64sss (AND64sss R32Regs:$t, (SUB64sas 0, (ANDext R1Regs:$c, 1))),"
7040  << "(AND64sss R32Regs:$f, (SUB64ssa (ANDext R1Regs:$c, 1), 1)))>;"
7041  << std::endl << std::endl
7042 
7043  << "def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t),(i64 imm:$f))),"
7044  << "(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7045  << "(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7046  << std::endl << std::endl
7047 
7048  << "def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, (i64 imm:$f))),"
7049  << "(IOR64sss (AND64sss (SUB64sas 0, (ANDext R1Regs:$c, 1)), R32Regs:$t),"
7050  << "(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7051  << std::endl << std::endl
7052 
7053  << "def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t), R64Regs:$f)),"
7054  << "(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7055  << "(AND64sss (SUB64ssa (ANDext R1Regs:$c, 1), 1), R32Regs:$f))>;"
7056  << std::endl << std::endl;
7057 
7058  os << std::endl
7059  << "def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, R64Regs:$f)), "
7060  << "(IOR64sss (AND64sss R64Regs:$t, (SUB64sas 0, (ANDext R1Regs:$c, 1))),"
7061  << "(AND64sss R64Regs:$f, (SUB64ssa (ANDext R1Regs:$c, 1), 1)))>;"
7062  << std::endl << std::endl
7063 
7064  << "def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t),(i64 imm:$f))),"
7065  << "(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7066  << "(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7067  << std::endl << std::endl
7068 
7069  << "def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, (i64 imm:$f))),"
7070  << "(IOR64sss (AND64sss (SUB64sas 0, (ANDext R1Regs:$c, 1)), R64Regs:$t),"
7071  << "(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7072  << std::endl << std::endl
7073 
7074  << "def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t), R64Regs:$f)),"
7075  << "(IOR64sss (ANDssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7076  << "(ANDsss (SUBssa (ANDext R1Regs:$c, 1), 1), R64Regs:$f))>;"
7077  << std::endl << std::endl
7078 
7079  << "def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, R1Regs:$f)),"
7080  << "(IOR64bbb (AND64bbb R1Regs:$c, R1Regs:$t), "
7081  << "(AND64bbb (XOR64bbj R1Regs:$c, 1), R1Regs:$f))>;"
7082  << std::endl << std::endl
7083 
7084  << "def : Pat<(i1 (select R1Regs:$c, (i1 0), R1Regs:$f)),"
7085  << "(AND64bbb (XOR64bbj R1Regs:$c, 1), R1Regs:$f)>;"
7086  << std::endl << std::endl
7087 
7088  << "def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, (i1 -1))),"
7089  << "(IOR64bbb (AND64bbb R1Regs:$c, R1Regs:$t),"
7090  << "(XOR64bbj R1Regs:$c, 1))>;"
7091  << std::endl << std::endl;
7092  } //else {
7093 #endif
7094 
7095  if (mach_.is64bit()) {
7096  // optimize select with zero.
7097  os << "def : Pat<(i64 (select "
7098  << condRC << ":$c, R64Regs:$t, (i64 0)))," << std::endl
7099  << " (AND64sss "
7100  << trueMask << ", R64Regs:$t)>;"
7101  << std::endl << std::endl
7102 
7103  << "def : Pat<(i64 (select "
7104  << condRC << ":$c, (i64 0), R64Regs:$f))," << std::endl
7105  << "(AND64sss " << falseMask << ", R64Regs:$f)>;"
7106  << std::endl << std::endl;
7107 
7108  // also select with zero and some other imm
7109  os << "def : Pat<(i64 (select "
7110  << condRC << ":$c, (i64 imm:$t),(i64 0)))," << std::endl
7111  << " " << applyTrueMaskOnImm << ">;"
7112  << std::endl << std::endl;
7113 
7114  os << "def : Pat<(i64 (select "
7115  << condRC << ":$c, (i64 0),(i64 imm:$f)))," << std::endl
7116  << " " << applyFalseMaskOnImm << ">;"
7117  << std::endl << std::endl;
7118  } else {
7119  // optimize select with zero.
7120  os << "def : Pat<(i32 (select "
7121  << condRC << ":$c, R32Regs:$t, (i32 0)))," << std::endl
7122  << " (ANDrrr "
7123  << trueMask << ", R32Regs:$t)>;"
7124  << std::endl << std::endl
7125 
7126  << "def : Pat<(i32 (select "
7127  << condRC << ":$c, (i32 0), R32Regs:$f))," << std::endl
7128  << "(ANDrrr " << falseMask << ", R32Regs:$f)>;"
7129  << std::endl << std::endl;
7130 
7131  // also select with zero and some other imm
7132  os << "def : Pat<(i32 (select "
7133  << condRC << ":$c, (i32 imm:$t),(i32 0)))," << std::endl
7134  << " " << applyTrueMaskOnImm << ">;"
7135  << std::endl << std::endl;
7136 
7137  os << "def : Pat<(i32 (select "
7138  << condRC << ":$c, (i32 0),(i32 imm:$f)))," << std::endl
7139  << " " << applyFalseMaskOnImm << ">;"
7140  << std::endl << std::endl;
7141  }
7142 
7143 
7144  // TODO: similar patterns could be made with -1, avoiding one AND?
7145 
7146  // then the more generic ones
7147  os << std::endl
7148  << "def : Pat<(" << defType << " (select "
7149  << condRC << ":$c, " << gprRegs << ":$t, " << gprRegs << ":$f)), " << std::endl
7150  << " (" << iorReg << " (" << andReg << " " << gprRegs << ":$t, "
7151  << trueMask << "),"
7152  << "(" << andReg << " " << gprRegs << ":$f, " << falseMask << "))>;"
7153  << std::endl << std::endl
7154 
7155  << "def : Pat<(" << defType << " (select "
7156  << condRC << ":$c, (" << defType << " imm:$t),(" << defType << " imm:$f)))," << std::endl
7157  << " (" << iorReg << " " << applyTrueMaskOnImm << ","
7158  << applyFalseMaskOnImm << ")>;"
7159  << std::endl << std::endl
7160 
7161  << "def : Pat<(" << defType << " (select "
7162  << condRC << ":$c, " << gprRegs << ":$t, (" << defType << " imm:$f)))," << std::endl
7163  << " (" << iorReg << " (" << andReg << " "
7164  << trueMask << ", " << gprRegs << ":$t)," << applyFalseMaskOnImm << ")>;"
7165  << std::endl << std::endl
7166 
7167  << "def : Pat<(" << defType << " (select "
7168  << condRC << ":$c, (" << defType << " imm:$t), " << gprRegs << ":$f))," << std::endl
7169  << " (" << iorReg << " " << applyTrueMaskOnImm << ","
7170  << "(" << andReg << " " << falseMask << ", " << gprRegs << ":$f))>;"
7171  << std::endl << std::endl;
7172 
7173  if (!regs1bit_.empty()) {
7174  os << "def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, R1Regs:$f)),"
7175  << std::endl
7176  << " (" << iorBool << " (" << andBool << " R1Regs:$c, R1Regs:$t), "
7177  << "(" << andBool << " (" << xorBooli << " R1Regs:$c, 1), R1Regs:$f))>;"
7178  << std::endl << std::endl
7179 
7180  << "def : Pat<(i1 (select R1Regs:$c, (i1 0), R1Regs:$f)),"
7181  << std::endl
7182  << " (" << andBool << " (" << xorBooli << " R1Regs:$c, 1), R1Regs:$f)>;"
7183  << std::endl << std::endl
7184 
7185  << "def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, (i1 -1))),"
7186  << std::endl
7187  << " (" << iorBool << " (" << andBool << " R1Regs:$c, R1Regs:$t),"
7188  << "(" << xorBooli << " R1Regs:$c, 1))>;"
7189  << std::endl << std::endl;
7190  }
7191 
7192  os << "def : Pat<(f32 (select " << condRC << ":$c, "
7193  "FPRegs:$t,FPRegs:$f))," << std::endl
7194  << " (IORfff (ANDfff FPRegs:$t, (SUBfir 0, "
7195  << truncPattern << ")),"
7196  << "(ANDfff FPRegs:$f, (SUBfri "
7197  << truncPattern << ",1)))>;"
7198  << std::endl << std::endl
7199 
7200  << "def : Pat<(f16 (select " << condRC << ":$c, "
7201  "R32HFPRegs:$t, R32HFPRegs:$f))," << std::endl
7202  << " (IORhhh (ANDhhh R32HFPRegs:$t, (SUBhir 0, "
7203  << truncPattern << ")),"
7204  << "(ANDhhh R32HFPRegs:$f, (SUBhri "
7205  << truncPattern << ",1)))>;"
7206  << std::endl << std::endl;
7207 // }
7208  } else { // has conditional moves.
7209  opNames_["SELECT_I1bb"] = "CMOV_SELECT";
7210  opNames_["SELECT_I1bj"] = "CMOV_SELECT";
7211  opNames_["SELECT_I1jb"] = "CMOV_SELECT";
7212  opNames_["SELECT_I1jj"] = "CMOV_SELECT";
7213  opNames_["SELECT_I32rr"] = "CMOV_SELECT";
7214  opNames_["SELECT_I32ir"] = "CMOV_SELECT";
7215  opNames_["SELECT_I32ri"] = "CMOV_SELECT";
7216  opNames_["SELECT_I32ii"] = "CMOV_SELECT";
7217  opNames_["SELECT_F32"] = "CMOV_SELECT";
7218  opNames_["SELECT_F16"] = "CMOV_SELECT";
7219 
7220  // TODO: why does this break??
7221  os << " let isSelect = 1 in {" << std::endl;
7222 
7223  if (mach_.is64bit()) {
7224  opNames_["SELECT_I64rr"] = "CMOV_SELECT";
7225  opNames_["SELECT_I64ir"] = "CMOV_SELECT";
7226  opNames_["SELECT_I64ri"] = "CMOV_SELECT";
7227  opNames_["SELECT_I64ii"] = "CMOV_SELECT";
7228  opNames_["SELECT_F64"] = "CMOV_SELECT";
7229 
7230 
7231 
7232  os << "def SELECT_I64rr : InstTCE<(outs R64IRegs:$dst),"
7233  << "(ins R1Regs:$c, R64IRegs:$T, R64IRegs:$F),"
7234  << "\"# SELECT_I64 PSEUDO!\","
7235  << "[(set R64IRegs:$dst,"
7236  << "(select R1Regs:$c, R64IRegs:$T, R64IRegs:$F))]>;"
7237  << std::endl << std::endl
7238 
7239  << "def SELECT_I64ri : InstTCE<(outs R64IRegs:$dst),"
7240  << "(ins R64IRegs:$c, R64IRegs:$T, i64imm:$F),"
7241  << "\"# SELECT_I64 PSEUDO!\","
7242  << "[(set R64IRegs:$dst,"
7243  << "(select R64IRegs:$c, R64IRegs:$T, (i64 imm:$F)))]>;"
7244  << std::endl << std::endl
7245 
7246  << "def SELECT_I64ir : InstTCE<(outs R64IRegs:$dst),"
7247  << "(ins R64IRegs:$c, i64imm:$T, R64IRegs:$F),"
7248  << "\"# SELECT_I64 PSEUDO!\","
7249  << "[(set R64IRegs:$dst,"
7250  << "(select R64IRegs:$c, (i64 imm:$T), R64IRegs:$F))]>;"
7251  << std::endl << std::endl
7252 
7253  << "def SELECT_I64ii : InstTCE<(outs R64IRegs:$dst),"
7254  << "(ins R64IRegs:$c, i64imm:$T, i64imm:$F),"
7255  << "\"# SELECT_I64 PSEUDO!\","
7256  << "[(set R64IRegs:$dst,"
7257  << "(select R64IRegs:$c, (i64 imm:$T), (i64 imm:$F)))]>;"
7258  << std::endl << std::endl
7259 
7260  << "def SELECT_F64 : InstTCE<(outs R64DFPRegs:$dst),"
7261  << "(ins R1Regs:$c, R64DFPRegs:$T, R64DFPRegs:$F),"
7262  << "\"# SELECT_F64 PSEUDO!\","
7263  << "[(set R64DFPRegs:$dst,"
7264  << "(select R1Regs:$c, R64DFPRegs:$T, R64DFPRegs:$F))]>;"
7265  << std::endl << std::endl;
7266  }
7267 
7268  os << "def SELECT_I1bb : InstTCE<(outs R1Regs:$dst),"
7269  << "(ins GuardRegs:$c, R1Regs:$T, R1Regs:$F),"
7270  << "\"# SELECT_I1 PSEUDO!\","
7271  << " [(set R1Regs:$dst,"
7272  << "(select GuardRegs:$c, R1Regs:$T, R1Regs:$F))]>;"
7273  << std::endl << std::endl
7274 
7275  << "def SELECT_I1bj : InstTCE<(outs R1Regs:$dst),"
7276  << " (ins GuardRegs:$c, R1Regs:$T, i1imm:$F),"
7277  << "\"# SELECT_I1 PSEUDO!\","
7278  << "[(set R1Regs:$dst,"
7279  << "(select GuardRegs:$c, R1Regs:$T, (i1 imm:$F)))]>;"
7280  << std::endl << std::endl
7281 
7282  << "def SELECT_I1jb : InstTCE<(outs R1Regs:$dst),"
7283  << "(ins GuardRegs:$c, i1imm:$T, R1Regs:$F),"
7284  << "\"# SELECT_I1 PSEUDO!\","
7285  << "[(set R1Regs:$dst,"
7286  << "(select GuardRegs:$c, (i1 imm:$T), R1Regs:$F))]>;"
7287  << std::endl << std::endl
7288 
7289  << "def SELECT_I1jj : InstTCE<(outs R1Regs:$dst),"
7290  << "(ins GuardRegs:$c, i1imm:$T, i1imm:$F),"
7291  << "\"# SELECT_I1 PSEUDO!\","
7292  << "[(set R1Regs:$dst,"
7293  << "(select GuardRegs:$c, (i1 imm:$T), (i1 imm:$F)))]>;"
7294  << std::endl << std::endl
7295 
7296  << "def SELECT_I32rr : InstTCE<(outs R32IRegs:$dst),"
7297  << "(ins GuardRegs:$c, R32IRegs:$T, R32IRegs:$F),"
7298  << "\"# SELECT_I32 PSEUDO!\","
7299  << "[(set R32IRegs:$dst,"
7300  << "(select GuardRegs:$c, R32IRegs:$T, R32IRegs:$F))]>;"
7301  << std::endl << std::endl
7302 // select with the cond in an i32 (produced by expanded vselects with i32 cond vectors)
7303 
7304  << "def SELECT_I32ri : InstTCE<(outs R32IRegs:$dst),"
7305  << "(ins R32IRegs:$c, R32IRegs:$T, i32imm:$F),"
7306  << "\"# SELECT_I32 PSEUDO!\","
7307  << "[(set R32IRegs:$dst,"
7308  << "(select R32IRegs:$c, R32IRegs:$T, i32MoveImm:$F))]>;"
7309  << std::endl << std::endl
7310 
7311  << "def SELECT_I32ir : InstTCE<(outs R32IRegs:$dst),"
7312  << "(ins R32IRegs:$c, i32imm:$T, R32IRegs:$F),"
7313  << "\"# SELECT_I32 PSEUDO!\","
7314  << "[(set R32IRegs:$dst,"
7315  << "(select R32IRegs:$c, i32MoveImm:$T, R32IRegs:$F))]>;"
7316  << std::endl << std::endl
7317 
7318  << "def SELECT_I32ii : InstTCE<(outs R32IRegs:$dst),"
7319  << "(ins R32IRegs:$c, i32imm:$T, i32imm:$F),"
7320  << "\"# SELECT_I32 PSEUDO!\","
7321  << "[(set R32IRegs:$dst,"
7322  << "(select R32IRegs:$c, i32MoveImm:$T, i32MoveImm:$F))]>;"
7323  << std::endl << std::endl
7324 
7325  << "def SELECT_F32 : InstTCE<(outs FPRegs:$dst),"
7326  << "(ins GuardRegs:$c, FPRegs:$T, FPRegs:$F),"
7327  << "\"# SELECT_F32 PSEUDO!\","
7328  << "[(set FPRegs:$dst,"
7329  << "(select GuardRegs:$c, FPRegs:$T, FPRegs:$F))]>;"
7330  << std::endl << std::endl
7331 
7332  << "def SELECT_F16 : InstTCE<(outs HFPRegs:$dst),"
7333  << "(ins GuardRegs:$c, HFPRegs:$T, HFPRegs:$F),"
7334  << "\"# SELECT_F16 PSEUDO!\","
7335  << "[(set HFPRegs:$dst, "
7336  << "(select GuardRegs:$c, HFPRegs:$T, HFPRegs:$F))]>;"
7337  << std::endl << std::endl;
7338 
7339  os << "}" << std::endl << std::endl;
7340 
7341  if (mach_.is64bit()) {
7342  os << "def : Pat<(i64 (select R64IRegs:$c, R64IRegs:$T, R64IRegs:$F)),"
7343  << "(SELECT_I64rr (MOVI64I1ss R64Regs:$c),"
7344  << "R64IRegs:$T, R64IRegs:$F)>;"
7345  << std::endl << std::endl;
7346  }
7347 
7348  os << "def : Pat<(i32 (select R32IRegs:$c, R32IRegs:$T, R32IRegs:$F)),"
7349  << "(SELECT_I32rr (MOVI32I1rr R32Regs:$c),"
7350  << "R32IRegs:$T, R32IRegs:$F)>;"
7351  << std::endl << std::endl;
7352 
7353  }
7354  } else {
7355  os << "// Has select instr!. " << std::endl;
7356  }
7357  std::map<TCEString, RegisterClass>::const_iterator it;
7358  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
7359  const RegisterClass& regClass = it->second;
7360  TCEString regClassName = regClass.name();
7361  ValueType valType = regClass.valueType();
7362  TCEString valTypeName = valType.valueTypeStr();
7363 
7364  os << "def SELECT_" << valTypeName << " : InstTCE<(outs "
7365  << regClassName << ":$dst), (ins R1Regs:$c, " << regClassName
7366  << ":$T, " << regClassName << ":$F), \"\","
7367  << "[(set " << regClassName << ":$dst,"
7368  << "(select R1Regs:$c, " << regClassName << ":$T, " << regClassName
7369  << ":$F))]>;" << std::endl
7370  << std::endl;
7371 
7372  opNames_["SELECT_" + valTypeName] = "CMOV_SELECT";
7373  }
7374 }

References getLLVMPatternWithConstants(), hasConditionalMoves_, hasSelect_, TTAMachine::Machine::is64bit(), mach_, TDGenerator::RegisterClass::name(), OperationPool::operation(), opNames_, regs1bit_, sub, TDGenerator::RegisterClass::valueType(), TDGenerator::ValueType::valueTypeStr(), and vRegClasses_.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ createShortExtLoadPatterns()

void TDGen::createShortExtLoadPatterns ( std::ostream &  os)
protected

Definition at line 6617 of file TDGen.cc.

6617  {
6618  TCEString load = littleEndian_ ? "LD16" : "LDH";
6619  TCEString destSize = mach_.is64bit() ? "64" : "32";
6620  int bits = mach_.is64bit() ? 64 : 32;
6621  TCEString ANDOPC = mach_.is64bit() ? "AND64ssa" : "ANDrri";
6622  TCEString uload = littleEndian_ ? "LDU16" : "LDHU";
6623  TCEString EXTOP = mach_.is64bit() ? "SXH64" : "SXHW";
6624  TCEString EXTOPC = mach_.is64bit() ? "SXH64sr" : "SXHWrr";
6625  TCEString regSrcChar = mach_.is64bit() ? OT_REG_LONG : OT_REG_INT;
6626  TCEString dstTypeChar = OT_REG_INT;
6627  TCEString immSrcChar = mach_.is64bit() ? OT_IMM_LONG : OT_IMM_INT;
6628  TCEString loadOpcReg = load + dstTypeChar + regSrcChar;
6629  TCEString loadOpcImm = load + dstTypeChar + immSrcChar;
6630 
6631  TCEString SHL = mach_.is64bit() ? "SHL" : "SHL64";
6632  TCEString SHR = mach_.is64bit() ? "SHR" : "SHR64";
6633  TCEString SHRU = mach_.is64bit() ? "SHRU" : "SHRU64ssa";
6634  TCEString SHLOPC = mach_.is64bit() ? "SHLrri" : "SHL64ssa";
6635  TCEString SHROPC = mach_.is64bit() ? "SHRrri" : "SHR64ssa";
6636  TCEString SHRUOPC = mach_.is64bit() ? "SHRUrri" : "SHRU64ssa";
6637  TCEString SHL4 = mach_.is64bit() ? "SHL4_32" : "SHL4_64";
6638  TCEString SHR4 = mach_.is64bit() ? "SHR4_32" : "SHR4_64";
6639  TCEString SHRU4 = mach_.is64bit() ? "SHRU4_32" : "SHRU4_64ssa";
6640 
6641  if (mach_.hasOperation(load)) {
6642  if (!mach_.hasOperation(uload)) {
6643  // emulate zero ext with sing-ext and and
6644  os << "def : Pat<(i" << destSize
6645  << " (zextloadi16 ADDRrr:$addr)), "
6646  << "(" << ANDOPC << " (" << loadOpcReg
6647  << " ADDRrr:$addr), 65535)>;" << std::endl;
6648  os << "def : Pat<(i" << destSize
6649  << " (zextloadi16 ADDRri:$addr)), "
6650  << "(" << ANDOPC << " ("
6651  << loadOpcImm << " ADDRri:$addr), 65535)>;" << std::endl;
6652  }
6653  } else {
6654  if (!mach_.hasOperation(uload)) {
6655  std::cerr << "Warning: The architecture is missing any 16-bit loads."
6656  << std::endl;
6657  return;
6658  }
6659  loadOpcReg = uload + dstTypeChar + regSrcChar;
6660  loadOpcImm = uload + dstTypeChar + immSrcChar;
6661 
6662  if (mach_.hasOperation(EXTOP)) {
6663  // use zextload + sext for sextload
6664  os << "def : Pat<(i" << destSize
6665  << " (sextloadi16 ADDRrr:$addr)), "
6666  << "(" << EXTOPC
6667  << " (" << loadOpcReg << " ADDRrr:$addr))>;" << std::endl;
6668  os << "def : Pat<(i" << destSize
6669  << " (sextloadi16 ADDRri:$addr)), "
6670  << "(" << EXTOPC
6671  << " (" << loadOpcImm << " ADDRri:$addr))>;" << std::endl;
6672  } else {
6673  if (mach_.hasOperation(SHL) && mach_.hasOperation(SHR)) {
6674  int sb = bits -16;
6675  os << "def : Pat<(i" << destSize
6676  << " (sextloadi16 ADDRrr:$addr)), "
6677  << "(" << SHROPC << " (" << SHLOPC << " ("
6678  << load << "rr ADDRrr:$addr), "
6679  << sb << "), " << sb << ")>;" << std::endl;
6680 
6681  os << "def : Pat<(i" << destSize
6682  << " (sextloadi16 ADDRri:$addr)), "
6683  << "(" << SHROPC << " (" << SHLOPC << " ("
6684  << load << "ri ADDRri:$addr), "
6685  << sb << "), " << sb << ")>;" << std::endl;
6686  } else if (mach_.hasOperation(SHL4) &&
6687  mach_.hasOperation(SHR4)) {
6688  if (!mach_.is64bit()) {
6689  os << "def : Pat<(i32 (sextloadi16 ADDRrr:$addr)), "
6690  << "(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6691  << "(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr ("
6692  << load << "rr ADDRrr:$addr)))))))))>;" << std::endl;
6693 
6694  os << "def : Pat<(i32 (sextloadi16 ADDRri:$addr)), "
6695  << "(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6696  << "(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr ("
6697  << load << "ri ADDRri:$addr)))))))))>;" << std::endl;
6698  } else {
6699  os << "def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), "
6700  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6701  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6702  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6703  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6704  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6705  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss ("
6706  << load << "rr ADDRrr:$addr)))))))))))))>;"
6707  << std::endl;
6708 
6709  os << "def : Pat<(i64 (sextloadi8 ADDRri:$addr)), "
6710  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6711  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6712  << "(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6713  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6714  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6715  << "(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss ("
6716  << load << "ri ADDRri:$addr)))))))))))))>;"
6717  << std::endl;
6718  }
6719  } else {
6720  std::cerr << "Warning: no sign-extending 16-bit loads,"
6721  << " 16-bit sign extension instruction or suitable"
6722  << " shifts for sext-emulation in the processor."
6723  << " All code may not compile!" << std::endl;
6724  }
6725  }
6726  }
6727  // anyext
6728  os << "def : Pat<(i" << destSize << " (extloadi16 ADDRrr:$src)), ("
6729  << loadOpcReg << " ADDRrr:$src)>;" << std::endl
6730  << "def : Pat<(i" << destSize << " (extloadi16 ADDRri:$src)), ("
6731  << loadOpcImm << " ADDRri:$src)>;" << std::endl;
6732 }

References TTAMachine::Machine::hasOperation(), TTAMachine::Machine::is64bit(), littleEndian_, mach_, OT_IMM_INT, OT_IMM_LONG, OT_REG_INT, and OT_REG_LONG.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ createTrivialDAG()

OperationDAG * TDGen::createTrivialDAG ( Operation op)
protected

Creates a dummy dag for an OSAL operation.

Parameters
opOperation to create OperationDAG for.
Returns
OperationDAG consisting of only one operation node referencing the given operation.

Definition at line 6019 of file TDGen.cc.

6019  {
6020 
6021  OperationDAG* dag = new OperationDAG(op.impl());
6022  OperationNode* opNode = new OperationNode(op);
6023  dag->addNode(*opNode);
6024 
6025  for (int i = 0; i < op.numberOfInputs() + op.numberOfOutputs(); i++) {
6026  const Operand& operand = op.operand(i + 1);
6027  TerminalNode* t = new TerminalNode(operand.index());
6028  dag->addNode(*t);
6029  if (operand.isInput()) {
6030  OperationDAGEdge* e = new OperationDAGEdge(1, operand.index());
6031  dag->connectNodes(*t, *opNode, *e);
6032  } else {
6033  OperationDAGEdge* e = new OperationDAGEdge(operand.index(), 1);
6034  dag->connectNodes(*opNode, *t, *e);
6035  }
6036  }
6037  return dag;
6038 }

References BoostGraph< GraphNode, GraphEdge >::addNode(), BoostGraph< GraphNode, GraphEdge >::connectNodes(), Operation::impl(), Operand::index(), Operand::isInput(), Operation::numberOfInputs(), Operation::numberOfOutputs(), and Operation::operand().

Referenced by writeOperationDef().

Here is the call graph for this function:

◆ createVectorMinMaxDef()

void TDGen::createVectorMinMaxDef ( const TCEString opName,
int  bits,
char  llvmTypeChar,
const TCEString postFix,
std::ostream &  os 
)
protected

Definition at line 6306 of file TDGen.cc.

6311  {
6312 
6313  for (int elemCount=2; elemCount <= 1024; elemCount<<=1) {
6314  TCEString opName = baseOpName;
6315  opName << bits << "X" << elemCount << postFix;
6316  TCEString vecType = "v";
6317  vecType << elemCount << (TCEString)(llvmTypeChar) << bits;
6318  createMinMaxDef(opName, vecType, os);
6319  }
6320 }

References createMinMaxDef().

Referenced by createMinMaxGenerator().

Here is the call graph for this function:

◆ createVectorRVDRegNums()

void TDGen::createVectorRVDRegNums ( std::ostream &  os)
protectedvirtual

Definition at line 6948 of file TDGen.cc.

6948  {
6949  os <<
6950  "std::vector<unsigned>" << std::endl <<
6951  "GeneratedTCEPlugin::getVectorRVDRegNums() const {" << std::endl <<
6952  "std::vector<unsigned> res;" << std::endl;
6953 
6954  std::set<TCEString> processedRegs;
6955  for (auto rcIt : vRegClasses_) {
6956  const RegisterClass& regClass = rcIt.second;
6957 
6958  int width = regClass.valueType().width();
6959  if (regClass.numberOfRegisters() > 0) {
6960  const TCEString& name = regClass.registerInfo(0).regName_;
6961  if (processedRegs.find(name) == processedRegs.end() &&
6962  width > maxScalarWidth_) {
6963  processedRegs.insert(name);
6964 
6965  os << "res.push_back(TCE::" << name << ");" << std::endl;
6966  }
6967  }
6968  }
6969  os << "return res;}" << std::endl;
6970 }

References maxScalarWidth_, TDGenerator::RegisterClass::numberOfRegisters(), TDGenerator::RegisterClass::registerInfo(), TDGenerator::RegisterInfo::regName_, TDGenerator::RegisterClass::valueType(), vRegClasses_, and TDGenerator::ValueType::width().

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ dagNodeToString()

std::string TDGen::dagNodeToString ( const Operation op,
const OperationDAG dag,
const OperationDAGNode node,
bool  emulationPattern,
const std::string &  operandTypes,
const Operation emulatingOp = nullptr,
const OperationDAGNode successor = nullptr 
)
protected

Converts single OperationDAG node to llvm pattern fragment string.

Parameters
opOperation that the whole DAG is for.
dagWhole operation DAG.
nodeDAG node to return string for.
immOpIndex of an operand to define as an immediate or 0 if none.
emulationPatternTrue, if the returned string should be in emulation pattern format.
Returns
DAG node as a llvm .td string.

Definition at line 5436 of file TDGen.cc.

5439  {
5440  const OperationNode* oNode = dynamic_cast<const OperationNode*>(&node);
5441  if (oNode != NULL) {
5442  assert(
5443  dag.inDegree(*oNode) ==
5444  oNode->referencedOperation().numberOfInputs());
5445 
5446  return operationNodeToString(
5447  op, dag, *oNode, emulationPattern, operandTypes);
5448  }
5449 
5450  const TerminalNode* tNode = dynamic_cast<const TerminalNode*>(&node);
5451  if (tNode != NULL) {
5452  const Operand& operand = op.operand(tNode->operandIndex());
5453  if (dag.inDegree(*tNode) == 0) {
5454  // Input operand for the whole operation.
5455  assert(operand.isInput());
5456 
5457  char operandType =
5458  operandTypes[operand.index()-1 + op.numberOfOutputs()];
5459  bool imm = (operandType == OT_IMM_INT ||
5460  operandType == OT_IMM_BOOL);
5461 
5462  if (imm && !canBeImmediate(dag, *tNode)) {
5463  std::string msg =
5464  "Invalid immediate operand for " + op.name() +
5465  " operand #" + Conversion::toString(tNode->operandIndex());
5466  throw InvalidData(__FILE__, __LINE__, __func__, msg);
5467  }
5468 
5469  if (emulationPattern) {
5470  assert(emulatingOp != nullptr);
5471  return operandToString(operand, false, operandType,
5473  *emulatingOp, operand)]);
5474  } else {
5475  return operandToString(operand, false, operandType,
5476  immOperandDefs_[ImmInfo::key(op, operand)]);
5477  }
5478  } else {
5479  // Output operand for the whole operation.
5480  assert(dag.inDegree(*tNode) == 1);
5481  assert(op.operand(tNode->operandIndex()).isOutput());
5482  assert(operand.isOutput());
5483  int globalOperandIndex =
5484  tNode->operandIndex() - op.numberOfInputs();
5485  assert(globalOperandIndex == 1);
5486 
5487  const OperationDAGEdge& edge = dag.inEdge(node, 0);
5488  const OperationDAGNode& srcNode = dag.tailNode(edge);
5489 
5490  // Multiple-output operation nodes not supported in the middle
5491  // of dag:
5492  assert(dag.outDegree(srcNode) == 1);
5493 
5494  std::string dnString =
5496  op, dag, srcNode, emulationPattern, operandTypes,
5497  emulatingOp, successor);
5498 
5499  bool needTrunc = (operandTypes[globalOperandIndex-1] ==
5500  OT_REG_BOOL &&
5501  operandTypes[1] != OT_REG_BOOL &&
5502  operandTypes[1] != OT_IMM_BOOL);
5503 
5504  // handle setcc's without trunc
5505  // also loads and extends.
5506  if (needTrunc) {
5507  if (dnString.substr(0,4) == "(set" ||
5508  dnString.substr(0,5) == "(zext" ||
5509  dnString.substr(0,5) == "(load") {
5510  needTrunc = false;
5511  }
5512  }
5513 
5514  if (needTrunc) {
5515  std::string pattern =
5516  "(set " + operandToString(
5517  operand, emulationPattern, operandTypes[0])
5518  + ", (trunc " + dnString + "))";
5519  return pattern;
5520  } else {
5521  std::string pattern =
5522  "(set " + operandToString(
5523  operand, emulationPattern, operandTypes[0])
5524  + ", " + dnString + ")";
5525  return pattern;
5526  }
5527  }
5528  }
5529 
5530  // Constant values.
5531  const ConstantNode* cNode = dynamic_cast<const ConstantNode*>(&node);
5532  if (cNode != NULL) {
5533  return constantNodeString(op, dag, *cNode, operandTypes, successor);
5534  }
5535 
5536  abortWithError("Unknown OperationDAG node type.");
5537  return "";
5538 }

References __func__, abortWithError, assert, canBeImmediate(), constantNodeString(), immOperandDefs_, BoostGraph< GraphNode, GraphEdge >::inDegree(), Operand::index(), BoostGraph< GraphNode, GraphEdge >::inEdge(), Operand::isInput(), Operand::isOutput(), ImmInfo::key(), Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), TerminalNode::operandIndex(), operandToString(), operationNodeToString(), OT_IMM_BOOL, OT_IMM_INT, OT_REG_BOOL, BoostGraph< GraphNode, GraphEdge >::outDegree(), OperationNode::referencedOperation(), BoostGraph< GraphNode, GraphEdge >::tailNode(), and Conversion::toString().

Referenced by operationNodeToString(), operationPattern(), subPattern(), and writeEmulationPattern().

Here is the call graph for this function:

◆ emulatingOpNodeLLVMName()

std::string TDGen::emulatingOpNodeLLVMName ( const Operation op,
const OperationDAG dag,
const OperationNode node,
const std::string &  operandTypes 
)
protected

Returns an llvm name for an operation node in an emulation dag.

Parameters
opthe operation being emulated.
dagdag of the emulated operation
nodenode whose name is being asked
operandTypesstring containing oeprand types for the emulated op.

Definition at line 5600 of file TDGen.cc.

5602  {
5603  const Operation& operation = node.referencedOperation();
5604  std::string operationName = StringTools::stringToUpper(operation.name());
5605 
5606 
5607  int inputs = operation.numberOfInputs();
5608 
5609  // Look at outgoing nodes. If operand goes to another op,
5610  // the value is in register.
5611  // if it's terminal, get the type from the paramete string.
5612  for (int i = 1 ; i < operation.numberOfOutputs() + 1; i++) {
5613  char c = 0;
5614  for (int e = 0; e < dag.outDegree(node); e++) {
5615  const OperationDAGEdge& edge = dag.outEdge(node, e);
5616  int dst = edge.srcOperand();
5617  if (dst == i + operation.numberOfInputs()) {
5618  TerminalNode* t =
5619  dynamic_cast<TerminalNode*>(
5620  &(dag.headNode(edge)));
5621  if (t != NULL) {
5622  int strIndex = t->operandIndex() -1 -
5623  op.numberOfInputs();
5624  assert((int)operandTypes.length() > strIndex &&
5625  strIndex >= 0);
5626  if (c != 0 && c != operandTypes[strIndex]) {
5627  throw InvalidData(__FILE__,__LINE__,__func__,
5628  "conflicting output types!");
5629  }
5630  c = operandTypes[strIndex];
5631  } else {
5632  Operand &operand =
5633  operation.operand(i+operation.numberOfInputs());
5634  char type = operandChar(operand);
5635  if (c != 0 && c!= type) {
5636  throw InvalidData(__FILE__,__LINE__,__func__,
5637  "conflicting output types!");
5638  }
5639  c = type;
5640  }
5641  }
5642  }
5643  if (c == 0) {
5644  throw InvalidData(__FILE__,__LINE__,__func__,"output not found.");
5645  }
5646  operationName += c;
5647  }
5648 
5649  // Look at incoming nodes. If operand comes from another op,
5650  // the value is in register. If operand comes from constant,
5651  // it's immediate.
5652  // if it's terminal, get the type from the parm string.
5653  for (int i = 1; i < inputs + 1; i++) {
5654  Operand &operand = operation.operand(i);
5655  for (int e = 0; e < dag.inDegree(node); e++) {
5656  const OperationDAGEdge& edge = dag.inEdge(node, e);
5657  int dst = edge.dstOperand();
5658  if (dst == i) {
5659  if (dynamic_cast<OperationNode*>(&(dag.tailNode(edge)))) {
5660  operationName += operandChar(operand);
5661  } else {
5662  if (dynamic_cast<ConstantNode*>(
5663  &(dag.tailNode(edge)))) {
5664  if (operand.type() == Operand::SINT_WORD ||
5665  operand.type() == Operand::UINT_WORD) {
5666  operationName += OT_IMM_INT;
5667  } else if (operand.type() == Operand::RAW_DATA ||
5668  operand.type() == Operand::SLONG_WORD ||
5669  operand.type() == Operand::ULONG_WORD) {
5670  operationName += mach_.is64bit() ?
5672  }
5673  } else {
5674  TerminalNode* t =
5675  dynamic_cast<TerminalNode*>(
5676  &(dag.tailNode(edge)));
5677  assert (t != NULL);
5678  int strIndex = t->operandIndex() -1 +
5679  op.numberOfOutputs();
5680  if ((int)operandTypes.length() <= strIndex ||
5681  strIndex <= 0) {
5682  std::cerr << "Invalid operand types length or"
5683  << "strIndex in operation:"
5684  << operation.name()
5685  << " OperandTypes string is: "
5686  << operandTypes
5687  << " strIndex is: " << strIndex
5688  << std::endl;
5689  assert(false);
5690  }
5691  operationName += operandTypes[strIndex];
5692  }
5693  }
5694  }
5695  }
5696  }
5697  return operationName;
5698 }

References __func__, assert, OperationDAGEdge::dstOperand(), BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::inEdge(), TTAMachine::Machine::is64bit(), mach_, Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), operandChar(), TerminalNode::operandIndex(), OT_IMM_INT, OT_IMM_LONG, BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), Operand::RAW_DATA, OperationNode::referencedOperation(), Operand::SINT_WORD, Operand::SLONG_WORD, OperationDAGEdge::srcOperand(), StringTools::stringToUpper(), BoostGraph< GraphNode, GraphEdge >::tailNode(), Operand::type(), Operand::UINT_WORD, and Operand::ULONG_WORD.

Referenced by operationNodeToString().

Here is the call graph for this function:

◆ gatherAllMachineOperations()

void TDGen::gatherAllMachineOperations ( )
protected

Gathers all machine op names and sorts them to vector and scalar operations.

Definition at line 941 of file TDGen.cc.

941  {
942  // Get all operation names to one container.
944 
945  OperationPool opPool;
946  OperationDAGSelector::OperationSet::const_iterator it;
947  for (it = allOpNames_.begin(); it != allOpNames_.end(); ++it) {
948  TCEString opName = *it;
949  Operation* op = &opPool.operation(opName.c_str());
950 
951  if (op != &NullOperation::instance()) {
952  if (op->isVectorOperation()) {
953  vectorOps_.insert(std::make_pair(opName, op));
954  } else {
955  scalarOps_.insert(std::make_pair(opName, op));
956  }
957  }
958  }
959 }

References allOpNames_, MachineInfo::getOpset(), NullOperation::instance(), Operation::isVectorOperation(), mach_, OperationPool::operation(), scalarOps_, and vectorOps_.

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ generateBackend()

void TDGen::generateBackend ( std::string &  path)

Generates all files required to build a tce backend plugin (excluding static plugin code included from include/llvm/TCE/).

Definition at line 388 of file TDGen.cc.

388  {
389  std::ofstream regTD;
390  regTD.open((path + "/GenRegisterInfo.td").c_str());
391  writeRegisterInfo(regTD);
392  regTD.close();
393 
394  std::ofstream instrTD0;
395  instrTD0.open((path + "/GenInstrInfo0.td").c_str());
396  writeAddressingModeDefs(instrTD0);
397  instrTD0.close();
398 
399  std::ofstream operandTD;
400  operandTD.open((path + "/GenOperandInfo.td").c_str());
401  writeOperandDefs(operandTD);
402  operandTD.close();
403 
404  std::ofstream instrTD;
405  instrTD.open((path + "/GenInstrInfo.td").c_str());
406  writeInstrInfo(instrTD);
407 #ifdef DEBUG_TDGEN
408  writeInstrInfo(std::cerr);
409 #endif
410  instrTD.close();
411 
412  std::ofstream formatTD;
413  formatTD.open((path + "/GenTCEInstrFormats.td").c_str());
414  writeInstrFormats(formatTD);
415  formatTD.close();
416 
417  std::ofstream ccTD;
418  ccTD.open((path + "/GenCallingConv.td").c_str());
419  writeCallingConv(ccTD);
420  ccTD.close();
421 
422  std::ofstream argArr;
423  argArr.open((path + "/ArgRegs.hh").c_str());
424  writeArgRegsArray(argArr);
425  argArr.close();
426 
427  std::ofstream pluginInc;
428  pluginInc.open((path + "/Backend.inc").c_str());
429  writeBackendCode(pluginInc);
430  pluginInc.close();
431 
432  std::ofstream topLevelTD;
433  topLevelTD.open((path + "/TCE.td").c_str());
434  writeTopLevelTD(topLevelTD);
435  topLevelTD.close();
436 }

References writeAddressingModeDefs(), writeArgRegsArray(), writeBackendCode(), writeCallingConv(), writeInstrFormats(), writeInstrInfo(), writeOperandDefs(), writeRegisterInfo(), and writeTopLevelTD().

Referenced by LLVMBackend::createPlugin().

Here is the call graph for this function:

◆ generateLoadStoreCopyGenerator()

void TDGen::generateLoadStoreCopyGenerator ( std::ostream &  os)
protected

Generates implementations of getLoad() and getStore() to Backend.inc file.

Parameters
osOutput stream to the file.

Definition at line 6291 of file TDGen.cc.

6291  {
6294 }

References genGeneratedTCEPlugin_getLoad(), and genGeneratedTCEPlugin_getStore().

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ genGeneratedTCEPlugin_getAddOpcode()

void TDGen::genGeneratedTCEPlugin_getAddOpcode ( std::ostream &  o) const
protected

Definition at line 3229 of file TDGen.cc.

3229  {
3230  o << endl
3231  << "// Returns correct vector ADD opcode" << endl
3232  << "int GeneratedTCEPlugin::getAddOpcode("
3233  << "const EVT& vt) const {" << endl;
3234 
3235  for (auto it = addOperations_.begin(); it != addOperations_.end(); ++it) {
3236  o << "\tif (vt == MVT::" << it->first
3237  << ") return TCE::" << it->second << ";" << endl;
3238  }
3239 
3240  o << "\treturn -1;" << endl << "}" << endl;
3241 }

References addOperations_.

Referenced by writeBackendCode().

◆ genGeneratedTCEPlugin_getConstantVectorShuffleOpcode()

void TDGen::genGeneratedTCEPlugin_getConstantVectorShuffleOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getExtractElemOpcode()

void TDGen::genGeneratedTCEPlugin_getExtractElemOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getGatherOpcode()

void TDGen::genGeneratedTCEPlugin_getGatherOpcode ( std::ostream &  o) const
protected

Definition at line 3199 of file TDGen.cc.

3199  {
3200  o << endl
3201  << "// Returns correct vector GATHER opcode" << endl
3202  << "int GeneratedTCEPlugin::getGatherOpcode("
3203  << "const EVT& vt) const {" << endl;
3204 
3205  for (auto it = gatherOperations_.begin(); it != gatherOperations_.end();
3206  ++it) {
3207  o << "\tif (vt == MVT::" << it->first
3208  << ") return TCE::" << it->second << ";" << endl;
3209  }
3210 
3211  o << "\treturn -1;" << endl << "}" << endl;
3212 }

References gatherOperations_.

◆ genGeneratedTCEPlugin_getIorOpcode()

void TDGen::genGeneratedTCEPlugin_getIorOpcode ( std::ostream &  o) const
protected

Definition at line 3259 of file TDGen.cc.

3259  {
3260  o << endl
3261  << "// Returns correct vector SHL opcode" << endl
3262  << "int GeneratedTCEPlugin::getIorOpcode("
3263  << "const EVT& vt) const {" << endl;
3264 
3265  for (auto it = iorOperations_.begin(); it != iorOperations_.end(); ++it) {
3266  o << "\tif (vt == MVT::" << it->first
3267  << ") return TCE::" << it->second << ";" << endl;
3268  }
3269 
3270  o << "\treturn -1;" << endl << "}" << endl;
3271 }

References iorOperations_.

Referenced by writeBackendCode().

◆ genGeneratedTCEPlugin_getLoad()

void TDGen::genGeneratedTCEPlugin_getLoad ( std::ostream &  o) const
protected

Generates implementation of getLoad() function.

Definition at line 2883 of file TDGen.cc.

2883  {
2884  TCEString prefix = "&"; // Address of -operator.
2885  TCEString rcpf = "RegsRegClass";
2886  TCEString rapf = "TCE::RARegRegClass";
2887 
2888  TCEString loadB = littleEndian_ ? "LD8" : "LDQ";
2889  if (!mach_.hasOperation(loadB)) {
2890  loadB = littleEndian_ ? "LDU8" : "LDQU";
2891  if (!mach_.hasOperation(loadB)) {
2892  loadB="";
2893  }
2894  }
2895 
2896  TCEString loadW = littleEndian_ ? "LD32" : "LDW";
2897  TCEString loadH = littleEndian_ ? "LD16" : "LDH";
2898  TCEString loadL = "LD64";
2899  if (!mach_.hasOperation(loadH)) {
2900  loadH = littleEndian_ ? "LDU16;" : "LDHU";
2901  if (!mach_.hasOperation(loadH)) {
2902  loadH="";
2903  }
2904  }
2905 
2906  o << "int GeneratedTCEPlugin::getLoad(const TargetRegisterClass *rc)"
2907  << " const {" << endl;
2908 
2909  o << "\tif (rc == " << prefix << rapf << ") return TCE::"
2910  << loadW << "RAr;" << endl;
2911 
2912  if (!mach_.hasOperation(loadW) && mach_.hasOperation("LDU32")) {
2913  loadW = "LDU32";
2914  }
2915 
2916  for (RegClassMap::const_iterator ri = regsInClasses_.begin();
2917  ri != regsInClasses_.end(); ri++) {
2918  if ((ri->first.find("R1") == 0 ||
2919  ri->first.find(TDGen::guardRegTemplateName) == 0) &&
2920  ri->first.find("R16") != 0 && loadB != "") {
2921  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2922  << rcpf <<") return TCE::" << loadB << "Br;" << endl;
2923  }
2924  if (ri->first.find("R32") == 0) {
2925  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2926  << rcpf << ") return TCE::" << loadW << "rr;" << endl;
2927 
2928  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2929  << "I" << rcpf << ") return TCE::" << loadW << "rr;" << endl;
2930 
2931  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2932  << "FP" << rcpf << ") return TCE::" << loadW << "fr;" << endl;
2933  if (loadH != "") {
2934  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2935  << "HFP" << rcpf << ") return TCE::" << loadH << "hr;" << endl;
2936  }
2937  }
2938  if (mach_.is64bit()) {
2939  if (ri->first.find("R64") == 0) {
2940  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2941  << rcpf << ") return TCE::" << loadL << "ss;" << endl;
2942 
2943  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2944  << "I" << rcpf << ") return TCE::" << loadL << "ss;" << endl;
2945 
2946  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2947  << "DFP" << rcpf << ") return TCE::" << loadL << "ds;" << endl;
2948 
2949  }
2950  }
2951  }
2952 
2953  if (use64bitForFP_) {
2954  o << "\tif (rc == &TCE::FPRegsRegClass) return TCE::LD64fs;"
2955  << std::endl;
2956 
2957  o << "\tif (rc == &TCE::HFPRegsRegClass) return TCE::LD64hs;"
2958  << std::endl;
2959  } else {
2960  o << "\tif (rc == &TCE::FPRegsRegClass) return TCE::"
2961  << loadW << "fr;" << std::endl;
2962 
2963  o << "\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
2964  << loadW << "hr;" << std::endl;
2965  }
2966 
2967  std::map<TCEString, RegisterClass>::const_iterator it;
2968  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
2969  const TCEString& vtStr = it->first;
2970  const RegisterClass& regClass = it->second;
2971 
2972  std::map<TCEString, InstructionInfo>::const_iterator loadIt =
2973  registerLoads_.find(vtStr);
2974 
2975  if (loadIt != registerLoads_.end()) {
2976  o << "\tif (rc == &TCE::" << regClass.name() << "RegClass) "
2977  << "return TCE::" << (loadIt->second).instrName_ << ";" << endl;
2978  } else {
2979  verbose("Warning: no load generated for RegisterClass " +
2980  regClass.name() + " to GeneratedTCEPlugin::getLoad");
2981  }
2982  }
2983 
2984  o << "\tprintf(\"regclass of size %d \\n\", rc->MC->RegsSize);" << std::endl
2985  << "\tassert(0&&\"loading from stack to given regclass not supported."
2986  << " Bug in backend?\");"
2987  << endl
2988  << "} " << endl
2989  << endl;
2990 }

References guardRegTemplateName, TTAMachine::Machine::hasOperation(), TTAMachine::Machine::is64bit(), littleEndian_, mach_, TDGenerator::RegisterClass::name(), registerLoads_, regsInClasses_, use64bitForFP_, verbose(), and vRegClasses_.

Referenced by generateLoadStoreCopyGenerator().

Here is the call graph for this function:

◆ genGeneratedTCEPlugin_getLoadOpcode()

void TDGen::genGeneratedTCEPlugin_getLoadOpcode ( std::ostream &  o) const
protected

Definition at line 3215 of file TDGen.cc.

3215  {
3216  o << endl
3217  << "// Returns correct load opcode" << endl
3218  << "int GeneratedTCEPlugin::getLoadOpcode("
3219  << "const EVT& vt) const {" << endl;
3220 
3221  for (auto it = registerLoads_.begin(); it != registerLoads_.end(); ++it) {
3222  o << "\tif (vt == MVT::" << it->first
3223  << ") return TCE::" << it->second.instrName_ << ";" << endl;
3224  }
3225  o << "\treturn -1;" << endl << "}" << endl;
3226 }

References registerLoads_.

Referenced by writeBackendCode().

◆ genGeneratedTCEPlugin_getShlOpcode()

void TDGen::genGeneratedTCEPlugin_getShlOpcode ( std::ostream &  o) const
protected

Definition at line 3244 of file TDGen.cc.

3244  {
3245  o << endl
3246  << "// Returns correct vector SHL opcode" << endl
3247  << "int GeneratedTCEPlugin::getShlOpcode("
3248  << "const EVT& vt) const {" << endl;
3249 
3250  for (auto it = shlOperations_.begin(); it != shlOperations_.end(); ++it) {
3251  o << "\tif (vt == MVT::" << it->first
3252  << ") return TCE::" << it->second << ";" << endl;
3253  }
3254 
3255  o << "\treturn -1;" << endl << "}" << endl;
3256 }

References shlOperations_.

Referenced by writeBackendCode().

◆ genGeneratedTCEPlugin_getStore()

void TDGen::genGeneratedTCEPlugin_getStore ( std::ostream &  o) const
protected

Generates implementation of getStore() function.

Definition at line 2783 of file TDGen.cc.

2783  {
2784  TCEString prefix = "&"; // Address of -operator.
2785  TCEString rcpf = "RegsRegClass";
2786  TCEString rapf = "TCE::RARegRegClass";
2787  TCEString storeB = littleEndian_ ? "ST8Brb;" : "STQBrb;";
2788  TCEString storeW = littleEndian_ ? "ST32" : "STW";
2789  TCEString storeH = littleEndian_ ? "ST16" : "STH";
2790  TCEString storeL = "ST64";
2791 
2792  o << "#include <stdio.h>" << endl
2793  << "int GeneratedTCEPlugin::getStore(const TargetRegisterClass *rc)"
2794  << " const {" << endl;
2795 
2796  o << "\tif (rc == " << prefix << rapf
2797  << ") return TCE::STWRArr;"
2798  << endl;
2799 
2800  for (RegClassMap::const_iterator ri = regsInClasses_.begin();
2801  ri != regsInClasses_.end(); ri++) {
2802 
2803  if ((ri->first.find("R1") == 0 ||
2804  ri->first.find(TDGen::guardRegTemplateName) == 0) &&
2805  ri->first.find("R16") != 0) {
2806  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2807  << rcpf << ") return TCE::" << storeB << endl;
2808  }
2809  if (ri->first.find("R32") == 0) {
2810  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2811  << rcpf << ") return TCE::" << storeW << "rr;" << endl;
2812 
2813  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2814  << "I" << rcpf << ") return TCE::" << storeW << "rr;" << endl;
2815 
2816  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2817  << "FP" << rcpf << ") return TCE::" << storeW << "fr;" << endl;
2818 
2819  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2820  << "HFP" << rcpf << ") return TCE::" << storeH << "hr;" << endl;
2821  }
2822  if (mach_.is64bit()) {
2823  if (ri->first.find("R64") == 0) {
2824  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2825  << rcpf << ") return TCE::" << storeL << "ss;" << endl;
2826 
2827  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2828  << "I" << rcpf << ") return TCE::" << storeL << "ss;"
2829  << endl;
2830 
2831  o << "\tif (rc == " << prefix << "TCE::" << ri->first
2832  << "DFP" << rcpf << ") return TCE::" << storeL << "ds;"
2833  << endl;
2834  }
2835  // TODO: double support here?
2836  }
2837  }
2838 
2839  if (use64bitForFP_) {
2840  o << "\tif (rc == &TCE::FPRegsRegClass) return TCE::ST64fs;"
2841  << std::endl;
2842 
2843  o << "\tif (rc == &TCE::HFPRegsRegClass) return TCE::ST64hs;"
2844  << std::endl;
2845  } else {
2846  o << "\tif (rc == &TCE::FPRegsRegClass) return TCE::"
2847  << storeW << "fr;" << std::endl;
2848 
2849  o << "\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
2850  << storeW << "hr;" << std::endl;
2851  }
2852 
2853  std::map<TCEString, RegisterClass>::const_iterator it;
2854  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
2855  const TCEString& vtStr = it->first;
2856  const RegisterClass& regClass = it->second;
2857 
2858  std::map<TCEString, InstructionInfo>::const_iterator storeIt =
2859  registerStores_.find(vtStr);
2860 
2861  if (storeIt != registerStores_.end()) {
2862  o << "\tif (rc == &TCE::" << regClass.name() << "RegClass) "
2863  << "return TCE::" << (storeIt->second).instrName_ << ";" << endl;
2864  } else {
2865  verbose("Warning: no store generated for RegisterClass " +
2866  regClass.name() + " to GeneratedTCEPlugin::getStore");
2867  }
2868  }
2869 
2870  o << "\tstd::cerr << \"regclass id:\" <<rc->getID() << \"of size \" "
2871  << "<<rc->MC->RegsSize<< std::endl;" << std::endl;
2872  o << "\tassert(0&&\"Storing given regclass to stack not supported. "
2873  << "Bug in backend?\");"
2874  << endl
2875  << "} " << endl
2876  << endl;
2877 }

References guardRegTemplateName, TTAMachine::Machine::is64bit(), littleEndian_, mach_, TDGenerator::RegisterClass::name(), registerStores_, regsInClasses_, use64bitForFP_, verbose(), and vRegClasses_.

Referenced by generateLoadStoreCopyGenerator().

Here is the call graph for this function:

◆ genGeneratedTCEPlugin_getVectorAndSameOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorAndSameOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorBroadcastOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorBroadcastOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorImmediateOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorImmediateOpcode ( std::ostream &  o) const
protected

Definition at line 3179 of file TDGen.cc.

3180  {
3181  backendCode << "int GeneratedTCEPlugin::getVectorImmediateOpcode(const "
3182  "EVT& vt) const {"
3183  << std::endl;
3184  for (auto it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
3185  const RegisterClass& regClass = it->second;
3186  TCEString regClassName = regClass.name();
3187  ValueType valType = regClass.valueType();
3188  TCEString valTypeName = valType.valueTypeStr();
3189  if (valType.width() <= 32) {
3190  TCEString opName = "MOVI" + valTypeName;
3191  backendCode << "\tif (vt == MVT::" << valTypeName
3192  << ") return TCE::" << opName << ";" << std::endl;
3193  }
3194  }
3195  backendCode << "\treturn -1;\n}" << endl;
3196 }

References TDGenerator::RegisterClass::name(), TDGenerator::RegisterClass::valueType(), TDGenerator::ValueType::valueTypeStr(), vRegClasses_, and TDGenerator::ValueType::width().

Here is the call graph for this function:

◆ genGeneratedTCEPlugin_getVectorIorSameOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorIorSameOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorPackOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorPackOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorSelectOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorSelectOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorShlSameOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorShlSameOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorShrSameOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorShrSameOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorShruSameOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorShruSameOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorShuffle1Opcode()

void TDGen::genGeneratedTCEPlugin_getVectorShuffle1Opcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorShuffle2Opcode()

void TDGen::genGeneratedTCEPlugin_getVectorShuffle2Opcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorValueType()

void TDGen::genGeneratedTCEPlugin_getVectorValueType ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_getVectorXorSameOpcode()

void TDGen::genGeneratedTCEPlugin_getVectorXorSameOpcode ( std::ostream &  o) const
protected

◆ genGeneratedTCEPlugin_isVectorRegisterMove()

void TDGen::genGeneratedTCEPlugin_isVectorRegisterMove ( std::ostream &  o) const
protected

◆ genTCEInstrInfo_copyPhys64bitReg()

void TDGen::genTCEInstrInfo_copyPhys64bitReg ( std::ostream &  o) const
protected

Definition at line 8322 of file TDGen.cc.

8322  {
8323  o << std::endl
8324  << "#include <llvm/CodeGen/MachineInstrBuilder.h>" << std::endl
8325  << "// copies 64-bit reg to a another" << std::endl
8326  << "bool TCEInstrInfo::copyPhys64bitReg(" << std::endl
8327  << "\tMachineBasicBlock& mbb," << std::endl
8328  << "\tMachineBasicBlock::iterator mbbi," << std::endl
8329  << "const DebugLoc& dl," << std::endl
8330  << "\tunsigned destReg, unsigned srcReg," << std::endl
8331  << "\tbool killSrc) const {" << std::endl
8332  << std::endl;
8333 
8334  if (mach_.is64bit()) {
8335  o << "\tif (TCE::R64RegsRegClass.contains(destReg, srcReg)) {\n"
8336  << "\t\tBuildMI(mbb, mbbi, dl, get(TCE::MOV64rr), destReg)\n"
8337  << "\t\t\t.addReg(srcReg, getKillRegState(killSrc));" << std::endl
8338  << "\t\treturn true;" << std::endl
8339  << "}" << std::endl;
8340  }
8341  o << "\treturn false;" << std::endl
8342  << "}";
8343 }

References TTAMachine::Machine::is64bit(), and mach_.

Here is the call graph for this function:

◆ genTCEInstrInfoSIMD_copyPhysVectorReg()

void TDGen::genTCEInstrInfoSIMD_copyPhysVectorReg ( std::ostream &  o) const
protected

Generates implementation of copyPhysVectorReg().

Only the previously created vector register classes are added to the implementation to make LLVM compilation flow work.

Definition at line 3131 of file TDGen.cc.

3131  {
3132  o << endl
3133  << "#include <llvm/CodeGen/MachineInstrBuilder.h>" << endl
3134  << "// Copies a vector register to another" << endl
3135 
3136  << "bool TCEInstrInfo::copyPhysVectorReg(" << endl
3137  << "\tMachineBasicBlock& mbb," << endl
3138  << "\tMachineBasicBlock::iterator mbbi," << endl
3139  << "const DebugLoc& dl," << endl
3140  << "\tMCRegister destReg, MCRegister srcReg," << endl
3141  << "\tbool killSrc) const {" << endl
3142  << endl;
3143 
3144  std::map<TCEString, RegisterClass>::const_iterator it;
3145  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
3146  const RegisterClass& regClass = it->second;
3147 
3148  o << "\tif (TCE::" << regClass.name()
3149  << "RegClass.contains(destReg, srcReg)) {" << endl
3150  << "\t\tBuildMI(mbb, mbbi, dl, get(TCE::"
3151  << "MOV" << regClass.name() << "), destReg)" << endl
3152  << "\t\t.addReg(srcReg, getKillRegState(killSrc));" << endl
3153  << "\t\treturn true;" << endl
3154  << "\t}" << endl;
3155  }
3156  o << "\treturn false;" << endl << "}" << endl;
3157 }

References TDGenerator::RegisterClass::name(), and vRegClasses_.

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ genTCERegisterInfo_setReservedVectorRegs()

void TDGen::genTCERegisterInfo_setReservedVectorRegs ( std::ostream &  os) const
protected

Definition at line 4162 of file TDGen.cc.

4163  {
4164  os << "void TCERegisterInfo::setReservedVectorRegs("
4165  << "llvm::BitVector& reserved) const {" << std::endl;
4166 
4167  std::set<TCEString> processedRegs;
4168  for (auto rcIt : vRegClasses_) {
4169  const RegisterClass& regClass = rcIt.second;
4170 
4171  int width = regClass.valueType().width();
4172  if (regClass.numberOfRegisters() > 0) {
4173  const TCEString& name = regClass.registerInfo(0).regName_;
4174  if (processedRegs.find(name) == processedRegs.end() &&
4175  width > maxScalarWidth_) {
4176  processedRegs.insert(name);
4177  os << "reserved.set(TCE::" << name << ");" << std::endl;
4178  }
4179  }
4180  }
4181  os << "}" << std::endl;
4182 }

References maxScalarWidth_, TDGenerator::RegisterClass::numberOfRegisters(), TDGenerator::RegisterClass::registerInfo(), TDGenerator::RegisterInfo::regName_, TDGenerator::RegisterClass::valueType(), vRegClasses_, and TDGenerator::ValueType::width().

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ genTCETargetLoweringSIMD_addVectorRegisterClasses()

void TDGen::genTCETargetLoweringSIMD_addVectorRegisterClasses ( std::ostream &  o) const
protected

Generates a function that adds existing register classes in lowering phase.

Definition at line 2997 of file TDGen.cc.

2998  {
2999  o << endl << "// Adds all vector classes to backend" << endl
3000  << "void TCETargetLowering::addVectorRegisterClasses() {" << endl;
3001  std::map<TCEString, RegisterClass>::const_iterator it;
3002  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
3003  const RegisterClass& regClass = it->second;
3004 
3005  o << "\taddRegisterClass("
3006  << "MVT::" << regClass.valueType().valueTypeStr() << ", "
3007  << "&TCE::" << regClass.name() << "RegClass);"
3008  << endl;
3009  }
3010 
3011  o << "}" << endl;
3012 
3013  o << endl << "// Sets build and extract lowering" << endl
3014  << "void TCETargetLowering::addVectorLowerings() {" << endl;
3015 
3016  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
3017  const RegisterClass& regClass = it->second;
3018 
3019  o << "\tsetOperationAction(ISD::BUILD_VECTOR,"
3020  << "MVT::" << regClass.valueType().valueTypeStr() << ", "
3021  << "Custom);" << endl;
3022 
3023  o << "\tsetOperationAction(ISD::EXTRACT_SUBVECTOR,"
3024  << "MVT::" << regClass.valueType().valueTypeStr() << ", "
3025  << "Expand);" << endl;
3026 
3027  for (auto vt : ValueType::SUPPORTED_LLVM_VALUE_TYPES) {
3028  if (vRegClasses_.find(vt) == vRegClasses_.end()) {
3029  o << "\tsetTruncStoreAction(MVT::"
3030  << regClass.valueType().valueTypeStr()
3031  << ", MVT::" << vt << ", Expand);" << endl;
3032  }
3033  }
3034  }
3035  o << "}" << endl;
3036 }

References TDGenerator::RegisterClass::name(), TDGenerator::RegisterClass::valueType(), TDGenerator::ValueType::valueTypeStr(), and vRegClasses_.

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ genTCETargetLoweringSIMD_associatedVectorRegClass()

void TDGen::genTCETargetLoweringSIMD_associatedVectorRegClass ( std::ostream &  o) const
protected

Generates a function that returns correct reg class for a value type.

Definition at line 3042 of file TDGen.cc.

3043  {
3044  o << endl << "// Returns vector register class for given value type"
3045  << endl
3046  << "std::pair<unsigned, const TargetRegisterClass*> "
3047  << "TCETargetLowering::associatedVectorRegClass(const EVT& vt) "
3048  << "const {"
3049  << endl;
3050 
3051  std::map<TCEString, RegisterClass>::const_iterator it;
3052  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
3053  const TCEString& vtStr = it->first;
3054  const RegisterClass& regClass = it->second;
3055 
3056  o << "\tif (vt == MVT::" << vtStr << ") "
3057  << "return std::make_pair(0U, &TCE::"
3058  << regClass.name() << "RegClass);" << endl;
3059  }
3060 
3061  o << "\treturn std::make_pair(0U, (TargetRegisterClass*)0);" << endl
3062  << "}" << endl;
3063 }

References TDGenerator::RegisterClass::name(), and vRegClasses_.

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ genTCETargetLoweringSIMD_getSetCCResultVT()

void TDGen::genTCETargetLoweringSIMD_getSetCCResultVT ( std::ostream &  o) const
protected

Generates a function that returns correct return value type for comparisons.

In LLVM vector comparison operations result into boolean vectors, which have the same subword count as input vectors.

Definition at line 3072 of file TDGen.cc.

3072  {
3073  o << endl
3074  << "llvm::EVT TCETargetLowering::getSetCCResultVT(const EVT& vt) "
3075  << "const {"
3076  << endl;
3077 
3078  int subwCount = 2;
3079  while (subwCount <= MAX_SUBW_COUNT) {
3080  TCEString boolVecVtStr = "v" + Conversion::toString(subwCount) + "i1";
3081  ValueType boolVecVt(boolVecVtStr);
3082 
3083  if (!boolVecVt.isSupportedByLLVM()) {
3084  break;
3085  }
3086 
3087  o << "\tif (vt.getVectorElementCount().getKnownMinValue() == "
3088  << Conversion::toString(subwCount) << ") return llvm::MVT::"
3089  << boolVecVtStr << ";" << endl;
3090  subwCount *= 2;
3091  }
3092 
3093  o << "\treturn llvm::MVT::INVALID_SIMPLE_VALUE_TYPE;" << endl
3094  << "}" << endl;
3095 }

References TDGenerator::ValueType::isSupportedByLLVM(), MAX_SUBW_COUNT, and Conversion::toString().

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ getLLVMPatternWithConstants()

TCEString TDGen::getLLVMPatternWithConstants ( const Operation op,
const std::string &  operandTypes,
const std::string &  operand0,
const std::string &  operand1 
) const
protected

Returns LLVM pattern for the expression with constant value(s) supported by target machine.

For example, for pattern (SUBrri (foo ...), 123) the method returns (SUBrrr (foo ...), (MOVI32ri 123)) if the target machine can not supply the constant "123" as an immediate.

The method should be called after all operation definitions have been created (after all calls to writeOperationDef()).

Return empty string if the given pattern can not be handled because:

  • Operation is not supported by target machine.
Parameters
opThe operation.
operandTypesThe preferred operand types.
operand0The pattern for the first operand or constant indicated by operandTypes.
operand1The pattern for the second operand or constant indicated by operandTypes.

Definition at line 7682 of file TDGen.cc.

7685  {
7686 
7687  //TODO If operation is not supported, try to replace it with an emulation
7688  // pattern first and then deal with the new patterns with constant
7689  // operands (and take account possible infinite recursion).
7690  //TODO Cache the calculated results?
7691 
7692  assert(op.numberOfInputs() == 2);
7693 
7694  auto makePattern = [](
7695  const std::string& opc,
7696  const std::string& opdTypes,
7697  const std::string& operand0,
7698  const std::string& operand1) -> TCEString {
7699  return std::string("(") + opc + opdTypes + " " + operand0
7700  + ", " + operand1 + ")";
7701  };
7702 
7703  std::string opc = StringTools::stringToUpper(op.name());
7704  const std::string outputOpdTypes = operandTypes.substr(
7705  0, op.numberOfOutputs());
7706  const std::string inputOpdTypes = operandTypes.substr(
7707  op.numberOfOutputs());
7708  assert(inputOpdTypes.size() == 2);
7709  const auto regOperandsOnly = operandTypesToRegisters(operandTypes);
7710  if (!opNames_.count(opc + regOperandsOnly)) {
7711  // Operation is not supported at all by the target machine.
7712  return "";
7713  }
7714 
7715  if (opNames_.count(opc + operandTypes)) {
7716  // Supported as is.
7717  return makePattern(opc, operandTypes, operand0, operand1);
7718  }
7719 
7720  std::vector<std::string> supportedOperandTypes;
7721  for (auto i = 0u; i < inputOpdTypes.size(); i++) {
7722  std::string oneInputChanged = inputOpdTypes;
7723  oneInputChanged[i] = operandTypeToRegister(oneInputChanged[i]);
7724  if (oneInputChanged == inputOpdTypes) continue;
7725  if (opNames_.count(opc + outputOpdTypes + oneInputChanged)) {
7726  supportedOperandTypes.push_back(oneInputChanged);
7727  }
7728  }
7729 
7730  supportedOperandTypes.push_back(regOperandsOnly);
7731 
7732  std::vector<const std::string*> inputOpdValues{&operand0, &operand1};
7733 
7734  // Now legalize pattern by changing unsupported immediate operands with
7735  // immediate moves.
7736  for (const auto& supportedOpdType : supportedOperandTypes) {
7737 
7738  // Loop throught immediate opd types. Check if constant is encodable
7739  // for the operation.
7740  bool isSupported = true;
7741  for (auto i = 0u; i < supportedOpdType.size(); i++) {
7742  auto& opdType = supportedOpdType.at(i);
7743  auto osalOpdIdx = i - op.numberOfInputs() + 1;
7744 
7745  bool ok = false;
7746  switch (opdType) {
7747  default:
7748  ok = true; // Ok. Not immediate type.
7749  break;
7750  case OT_IMM_INT: {
7751  bool isOperandReference =
7752  inputOpdValues.at(i)->find(":$") != std::string::npos;
7753  if (isOperandReference) {
7754  // Size of the constant is not known, must expect the
7755  // worst.
7756  ok = false;
7757  break;
7758  }
7759  int64_t value = Conversion::toInt(
7760  *inputOpdValues.at(i));
7761  ok = immInfo_->canTakeImmediate(op, osalOpdIdx, value,
7762  32);
7763  }
7764  break;
7765  case OT_IMM_FP:
7767  op, osalOpdIdx, 32);
7768  break;
7769  case OT_IMM_HFP:
7771  op, osalOpdIdx, 16);
7772  break;
7773  case OT_IMM_BOOL:
7775  op, osalOpdIdx, 1);
7776  break;
7777  }
7778  if (!ok) {
7779  isSupported = false;
7780  break;
7781  }
7782  }
7783 
7784  if (!isSupported) continue;
7785 
7786  std::string result = std::string("(") + opc + outputOpdTypes
7787  + supportedOpdType + " ";
7788  if (supportedOpdType.at(0) == inputOpdTypes.at(0)) {
7789  result += *inputOpdValues.at(0);
7790  } else {
7791  result += getMovePattern(
7792  inputOpdTypes.at(0), *inputOpdValues.at(0));
7793  }
7794  for (auto i = 1u; i < supportedOpdType.size(); i++) {
7795  result += ", ";
7796  if (supportedOpdType.at(i) == inputOpdTypes.at(i)) {
7797  result += *inputOpdValues.at(i);
7798  } else {
7799  result += getMovePattern(
7800  inputOpdTypes.at(i), *inputOpdValues.at(i));
7801  }
7802  }
7803  result += ")";
7804  return result;
7805  }
7806 
7807  return "";
7808 }

References assert, ImmInfo::canTakeImmediate(), ImmInfo::canTakeImmediateByWidth(), getMovePattern(), immInfo_, Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), operandTypesToRegisters(), operandTypeToRegister(), opNames_, OT_IMM_BOOL, OT_IMM_FP, OT_IMM_HFP, OT_IMM_INT, StringTools::stringToUpper(), and Conversion::toInt().

Referenced by createSelectPatterns().

Here is the call graph for this function:

◆ getMatchableOperationDAG()

const OperationDAG * TDGen::getMatchableOperationDAG ( const Operation op)
protected

Returns first operation DAG that can be used in LLVM pattern.

Operation DAGs are traversed in the order of trigger-semantics in the first .opp file found in path that defines the Operation.

This method does not transfer ownership.

Returns
The matchable operation DAG. Nullptr if could not find.

Definition at line 5320 of file TDGen.cc.

5321  {
5322 
5323  // check if one of dags of operation is ok
5324  for (int i = 0; i < op.dagCount(); i++) {
5325  OperationDAG& dag = op.dag(i);
5326  if (op.dagError(i) != "") {
5327  std::cerr << "Broken dag in operation " << op.name()
5328  << op.dagCode(i) << std::endl;
5329  assert(0);
5330  }
5331 
5332  if (operationDAGCanBeMatched(dag)) {
5333  return &dag;
5334  }
5335  }
5336  return nullptr;
5337 }

References assert, Operation::dag(), Operation::dagCode(), Operation::dagCount(), Operation::dagError(), Operation::name(), and operationDAGCanBeMatched().

Referenced by operationNodeToString(), and writeOperationDef().

Here is the call graph for this function:

◆ getMovePattern()

TCEString TDGen::getMovePattern ( const char &  opdType,
const std::string &  inputPattern 
) const
protected

Definition at line 7835 of file TDGen.cc.

7836  {
7837 
7838  TCEString pat = "(MOV";
7839  // Note: This listing is incomplete.
7840  switch (opdType) {
7841  case OT_IMM_INT: // Integer immediate.
7842  pat += std::string("I32") + operandTypeToRegister(opdType) + opdType;
7843  break;
7844  case OT_REG_INT: // Integer register.
7845  pat += std::string("I32") + operandTypeToRegister(opdType) + opdType;
7846  break;
7847  case OT_IMM_BOOL: // Boolean immediate.
7848  pat += "I1ri"; //TODO: this is inconsistent
7849  break;
7850  case OT_REG_BOOL: // Boolean register.
7851  pat += "I1rr"; //TODO: this is inconsistent
7852  break;
7853  case OT_IMM_FP: // Single precision floating point immediate.
7854  case OT_REG_FP: // -||- register.
7855  pat += std::string("F32") + operandTypeToRegister(opdType) + opdType;
7856  break;
7857  case OT_IMM_HFP: // Half precision floating point immediate.
7858  case OT_REG_HFP: // -||- register.
7859  pat += std::string("F16") + operandTypeToRegister(opdType) + opdType;
7860  break;
7861  // TODO: vector register and immediate types.
7862  default:
7863  assert(false && "Handling for a type not implemented");
7864  break;
7865  }
7866  pat += " " + inputPattern + ")";
7867  return pat;
7868 }

References assert, operandTypeToRegister(), OT_IMM_BOOL, OT_IMM_FP, OT_IMM_HFP, OT_IMM_INT, OT_REG_BOOL, OT_REG_FP, OT_REG_HFP, and OT_REG_INT.

Referenced by getLLVMPatternWithConstants().

Here is the call graph for this function:

◆ hasRawOperands()

bool TDGen::hasRawOperands ( const Operation op) const
protected

Checks if operation has operands of raw type.

Parameters
opOperation to be checked.
Returns
True, if operation has at least one operand of raw type.

Definition at line 1699 of file TDGen.cc.

1699  {
1700  for (int i = 1; i <= op.operandCount(); ++i) {
1701  const Operand& operand = op.operand(i);
1702  if (operand.type() == Operand::RAW_DATA && operand.isVector()) {
1703  return true;
1704  }
1705  }
1706  return false;
1707 }

References Operand::isVector(), Operation::operand(), Operation::operandCount(), Operand::RAW_DATA, and Operand::type().

Here is the call graph for this function:

◆ hasRegisterClassSupport() [1/2]

bool TDGen::hasRegisterClassSupport ( const Operation op) const
protected

Checks if all operands of the operation have a supporting register class.

Parameters
opOperation whose operands will be checked.
Returns
True, if all operands are supported by register classes.

Definition at line 1749 of file TDGen.cc.

1749  {
1750  for (int i = 1; i <= op.operandCount(); ++i) {
1751  const Operand& operand = op.operand(i);
1752 
1753  if (operand.isVector()) {
1754  TCEString vtStr = ValueType::valueTypeStr(operand);
1755  if (vRegClasses_.find(vtStr) == vRegClasses_.end()) {
1756  return false;
1757  }
1758  }
1759  }
1760 
1761  return true;
1762 }

References Operand::isVector(), Operation::operand(), Operation::operandCount(), and vRegClasses_.

Referenced by writeScalarOperationExploitations(), writeVectorBitwiseOperationDefs(), and writeVectorOperationDef().

Here is the call graph for this function:

◆ hasRegisterClassSupport() [2/2]

bool TDGen::hasRegisterClassSupport ( const TDGenerator::ValueType vt) const
protected

Checks if the ValueType has a supporting register class.

Parameters
vtValueType to be checked.
Returns
True, if the value type is supported by a register class.

Definition at line 1771 of file TDGen.cc.

1771  {
1772  if (vRegClasses_.find(vt.valueTypeStr()) == vRegClasses_.end()) {
1773  return false;
1774  }
1775 
1776  return true;
1777 }

References TDGenerator::ValueType::valueTypeStr(), and vRegClasses_.

Here is the call graph for this function:

◆ immediateOperandNameForEmulatedOperation()

std::string TDGen::immediateOperandNameForEmulatedOperation ( const OperationDAG dag,
const Operand operand 
)
protected

Returns corresponding immediate operand name for the emulated operation.

Parameters
dagThe emulation code of the emulated operation.
operandThe operand.
Returns
The operand immediate name if found. Otherwise return empty string.

Definition at line 7510 of file TDGen.cc.

7512  {
7513 
7514  for (const auto& sourceNode : dag.rootNodes()) {
7515  const TerminalNode* sourceTerminal =
7516  dynamic_cast<TerminalNode*>(sourceNode);
7517 
7518  if (sourceTerminal == nullptr) continue;
7519 
7520  for (const auto& destEdge : dag.outEdges(*sourceTerminal)) {
7521  const OperationNode* opNode =
7522  dynamic_cast<OperationNode*>(&dag.headNode(*destEdge));
7523 
7524  assert(opNode != nullptr &&
7525  "TerminalNode points to other than OperandNode.");
7526  const Operation& operation = opNode->referencedOperation();
7527  ImmInfoKey key = ImmInfo::key(operation, operand);
7528  if (immOperandDefs_.count(key)) {
7529  return immOperandDefs_.at(key);
7530  } else {
7531  return "";
7532  }
7533  }
7534  }
7535  return "";
7536 }

References assert, BoostGraph< GraphNode, GraphEdge >::headNode(), immOperandDefs_, ImmInfo::key(), BoostGraph< GraphNode, GraphEdge >::outEdges(), OperationNode::referencedOperation(), and BoostGraph< GraphNode, GraphEdge >::rootNodes().

Referenced by writeEmulationPattern().

Here is the call graph for this function:

◆ immediatePredicate()

std::string TDGen::immediatePredicate ( int64_t  lowerBoundInclusive,
uint64_t  upperBoundInclusive 
)
protected

Returns llvm predicate expression for short immediate constraint.

Definition at line 7486 of file TDGen.cc.

7488  {
7489 
7490  // If can transport any 64-bit imm, no need for any checks.
7491  if (upperBoundInclusive == UINT64_MAX ||
7492  lowerBoundInclusive == INT64_MIN) {
7493  return std::string("(true)");
7494  }
7495 
7496  return std::string("(")
7497  + Conversion::toString(lowerBoundInclusive) + "ll"
7498  + " <= Imm && Imm <= "
7499  + Conversion::toString(upperBoundInclusive) + "ll)";
7500 }

References Conversion::toString().

Referenced by writeIntegerImmediateDefs(), and writeMoveImmediateDefs().

Here is the call graph for this function:

◆ isVectorBitwiseOperation()

bool TDGen::isVectorBitwiseOperation ( const Operation op) const
protected

Checks if the given operation is a bitwise operation.

Parameters
opOperation which is checked.
Returns
True, if operation is a bitwise operation.

Definition at line 1939 of file TDGen.cc.

1939  {
1940  abortWithError("WiP");
1941  return false;
1942 }

References abortWithError.

Referenced by writeInstrInfo().

◆ isVectorLoadOperation()

bool TDGen::isVectorLoadOperation ( const Operation op) const
protected

Checks if the given operation is a vector load memory operation.

Parameters
opOperation which is checked.
Returns
True, if operation is a vector load memory operation.

Definition at line 1909 of file TDGen.cc.

1909  {
1910  abortWithError("WiP");
1911  return false;
1912 }

References abortWithError.

Referenced by writeInstrInfo().

◆ isVectorStoreOperation()

bool TDGen::isVectorStoreOperation ( const Operation op) const
protected

Checks if the given operation is a vector store memory operation.

Parameters
opOperation which is checked.
Returns
True, if operation is a vector store memory operation.

Definition at line 1921 of file TDGen.cc.

1921  {
1922  abortWithError("WiP");
1923  return false;
1924 }

References abortWithError.

Referenced by writeInstrInfo().

◆ isWrongEndianessVectorOp()

bool TDGen::isWrongEndianessVectorOp ( const Operation op) const
protected

Definition at line 1927 of file TDGen.cc.

1927  {
1928  abortWithError("WiP");
1929  return false;
1930 }

References abortWithError.

◆ llvmOperationName()

TCEString TDGen::llvmOperationName ( const TCEString operationName) const
protectedvirtual

Returns llvm operation name for the given OSAL operation name, if any.

Definition at line 5068 of file TDGen.cc.

5068  {
5069 
5070  TCEString opName = StringTools::stringToLower(operationName);
5071 
5072  if (opName == "add") return "add";
5073  if (opName == "sub") return "sub";
5074  if (opName == "mul") return "mul";
5075  if (opName == "div") return "sdiv";
5076  if (opName == "divu") return "udiv";
5077  if (opName == "mod") return "srem";
5078  if (opName == "modu") return "urem";
5079 
5080  if (opName == "add64") return "add";
5081  if (opName == "sub64") return "sub";
5082  if (opName == "mul64") return "mul";
5083  if (opName == "div64") return "sdiv";
5084  if (opName == "divu64") return "udiv";
5085  if (opName == "mod64") return "srem";
5086  if (opName == "modu64") return "urem";
5087 
5088  if (opName == "shl") return "shl";
5089  if (opName == "shr") return "sra";
5090  if (opName == "shru") return "srl";
5091  if (opName == "rotl") return "rotl";
5092  if (opName == "rotr") return "rotr";
5093 
5094  if (opName == "shl64") return "shl";
5095  if (opName == "shr64") return "sra";
5096  if (opName == "shru64") return "srl";
5097  if (opName == "rotl64") return "rotl";
5098  if (opName == "rotr64") return "rotr";
5099 
5100  if (opName == "and") return "and";
5101  if (opName == "ior") return "or";
5102  if (opName == "xor") return "xor";
5103 
5104  if (opName == "and64") return "and";
5105  if (opName == "ior64") return "or";
5106  if (opName == "xor64") return "xor";
5107 
5108  if (opName == "eq") return "seteq";
5109  if (opName == "eq64") return "seteq";
5110  if (opName == "ne") return "setne";
5111  if (opName == "ne64") return "setne";
5112  if (opName == "lt") return "setlt";
5113  if (opName == "lt64") return "setlt";
5114  if (opName == "le") return "setle";
5115  if (opName == "le64") return "setle";
5116  if (opName == "gt") return "setgt";
5117  if (opName == "gt64") return "setgt";
5118  if (opName == "ge") return "setge";
5119  if (opName == "ltu") return "setult";
5120  if (opName == "ltu64") return "setult";
5121  if (opName == "leu") return "setule";
5122  if (opName == "leu64") return "setule";
5123  if (opName == "gtu") return "setugt";
5124  if (opName == "gtu64") return "setugt";
5125  if (opName == "geu") return "setuge";
5126  if (opName == "geu64") return "setuge";
5127 
5128  if (opName == "eqf" || opName == "eqd") return "setoeq";
5129  if (opName == "nef" || opName == "ned") return "setone";
5130  if (opName == "ltf" || opName == "ltd") return "setolt";
5131  if (opName == "lef" || opName == "led") return "setole";
5132  if (opName == "gtf" || opName == "gtd") return "setogt";
5133  if (opName == "gef" || opName == "ged") return "setoge";
5134 
5135  if (opName == "equf" || opName == "equd") return "setueq";
5136  if (opName == "neuf" || opName == "neud") return "setune";
5137  if (opName == "ltuf" || opName == "ltud") return "setult";
5138  if (opName == "leuf" || opName == "leud") return "setule";
5139  if (opName == "gtuf" || opName == "gtud") return "setugt";
5140  if (opName == "geuf" || opName == "geud") return "setuge";
5141 
5142  if (opName == "ordf" || opName =="ordd") return "seto";
5143  if (opName == "uordf" || opName == "uordd") return "setuo";
5144 
5145  if (opName == "addf") return "fadd";
5146  if (opName == "subf") return "fsub";
5147  if (opName == "mulf") return "fmul";
5148  if (opName == "divf") return "fdiv";
5149  if (opName == "absf") return "fabs";
5150  if (opName == "negf") return "fneg";
5151  if (opName == "sqrtf") return "fsqrt";
5152 
5153  if (opName == "cif") return "sint_to_fp";
5154  if (opName == "cfi") return "fp_to_sint";
5155  if (opName == "cifu") return "uint_to_fp";
5156  if (opName == "cfiu") return "fp_to_uint";
5157 
5158  if (opName == "cfh") return "fpround";
5159  if (opName == "chf") return "fpextend";
5160 
5161  if (littleEndian_) {
5162  if (opName == "ld8") return "sextloadi8";
5163  if (opName == "ldu8") return "zextloadi8";
5164  if (opName == "ld16") return "sextloadi16";
5165  if (opName == "ldu16") return "zextloadi16";
5166  if (mach_.is64bit()) {
5167  if (opName == "ld32") return "sextloadi32";
5168  if (opName == "ldu32") return "zextloadi32";
5169  } else {
5170  if (opName == "ld32" || opName =="ldu32") return "load";
5171  }
5172  if (opName == "ld64") return "load";
5173 
5174  //if (opName == "ldd") return "load";
5175 
5176  if (opName == "st8") return "truncstorei8";
5177  if (opName == "st16") return "truncstorei16";
5178  if (opName == "st32") {
5179  if (mach_.is64bit()) {
5180  return "truncstorei32";
5181  } else {
5182  return "store";
5183  }
5184  }
5185 
5186  if (opName == "st32") return "store";
5187  if (opName == "st64") return "store";
5188  //if (opName == "std") return "load";
5189  } else { // big-endian
5190  if (opName == "ldq") return "sextloadi8";
5191  if (opName == "ldqu") return "zextloadi8";
5192  if (opName == "ldh") return "sextloadi16";
5193  if (opName == "ldhu") return "zextloadi16";
5194  if (opName == "ldw") return "load";
5195  //if (opName == "ldd") return "load";
5196 
5197  if (opName == "stq") return "truncstorei8";
5198  if (opName == "sth") return "truncstorei16";
5199  if (opName == "stw") return "store";
5200  //if (opName == "std") return "load";
5201  }
5202 
5203  if (opName.length() >2 && opName.substr(0,2) == "sx") {
5204  return "sext_inreg";
5205  }
5206 
5207  if (opName == "truncwh" || opName == "truncwb" || opName == "trunchb")
5208  return "trunc";
5209 
5210  if (opName == "neg") return "ineg";
5211  if (opName == "not") return "not";
5212  if (opName == "cas") return "atomic_cmp_swap_32";
5213 
5214  if (opName == "select") return "select";
5215 
5216  // Unknown operation name.
5217  return "";
5218 }

References TTAMachine::Machine::is64bit(), littleEndian_, mach_, and StringTools::stringToLower().

Referenced by writePortGuardedJumpDefPair().

Here is the call graph for this function:

◆ llvmOperationPattern()

TCEString TDGen::llvmOperationPattern ( const Operation op,
char  operandType = ' ' 
) const
protectedvirtual

Returns LLVM operation pattern for given OSAL operation.

Parameters
opOperation for which the LLVM pattern should be returned.
Returns
Operation pattern in llvm.

Definition at line 4854 of file TDGen.cc.

4854  {
4855  TCEString opName = StringTools::stringToLower(op.name());
4856 
4857  if (opName == "add") return "add %1%, %2%";
4858  if (opName == "add64") return "add %1%, %2%";
4859  if (opName == "sub") return "sub %1%, %2%";
4860  if (opName == "sub64") return "sub %1%, %2%";
4861  if (opName == "mul") return "mul %1%, %2%";
4862  if (opName == "mul64") return "mul %1%, %2%";
4863  if (opName == "div") return "sdiv %1%, %2%";
4864  if (opName == "divu") return "udiv %1%, %2%";
4865  if (opName == "div64") return "sdiv %1%, %2%";
4866  if (opName == "divu64") return "udiv %1%, %2%";
4867  if (opName == "mod") return "srem %1%, %2%";
4868  if (opName == "modu") return "urem %1%, %2%";
4869  if (opName == "mod64") return "srem %1%, %2%";
4870  if (opName == "modu64") return "urem %1%, %2%";
4871 
4872  if (opName == "shl") return "shl %1%, %2%";
4873  if (opName == "shr") return "sra %1%, %2%";
4874  if (opName == "shru") return "srl %1%, %2%";
4875  if (opName == "rotl") return "rotl %1%, %2%";
4876  if (opName == "rotr") return "rotr %1%, %2%";
4877 
4878 
4879  if (opName == "shl64") return "shl %1%, %2%";
4880  if (opName == "shr64") return "sra %1%, %2%";
4881  if (opName == "shru64") return "srl %1%, %2%";
4882  if (opName == "rotl64") return "rotl %1%, %2%";
4883  if (opName == "rotr64") return "rotr %1%, %2%";
4884 
4885  if (opName == "and") return "and %1%, %2%";
4886  if (opName == "ior") return "or %1%, %2%";
4887  if (opName == "xor") return "xor %1%, %2%";
4888 
4889  if (opName == "and64") return "and %1%, %2%";
4890  if (opName == "ior64") return "or %1%, %2%";
4891  if (opName == "xor64") return "xor %1%, %2%";
4892 
4893  if (opName == "eq") return "seteq %1%, %2%";
4894  if (opName == "eq64") return "seteq %1%, %2%";
4895  if (opName == "ne") return "setne %1%, %2%";
4896  if (opName == "ne64") return "setne %1%, %2%";
4897  if (opName == "lt") return "setlt %1%, %2%";
4898  if (opName == "lt64") return "setlt %1%, %2%";
4899  if (opName == "le") return "setle %1%, %2%";
4900  if (opName == "le64") return "setle %1%, %2%";
4901  if (opName == "gt") return "setgt %1%, %2%";
4902  if (opName == "gt64") return "setgt %1%, %2%";
4903  if (opName == "ge") return "setge %1%, %2%";
4904  if (opName == "ge64") return "setge %1%, %2%";
4905  if (opName == "ltu") return "setult %1%, %2%";
4906  if (opName == "ltu64") return "setult %1%, %2%";
4907  if (opName == "leu") return "setule %1%, %2%";
4908  if (opName == "leu64") return "setule %1%, %2%";
4909  if (opName == "gtu") return "setugt %1%, %2%";
4910  if (opName == "gtu64") return "setugt %1%, %2%";
4911  if (opName == "geu") return "setuge %1%, %2%";
4912  if (opName == "geu64") return "setuge %1%, %2%";
4913 
4914  if (opName == "eqf" || opName == "eqd") return "setoeq %1%, %2%";
4915  if (opName == "nef" || opName == "ned") return "setone %1%, %2%";
4916  if (opName == "ltf" || opName == "ltd") return "setolt %1%, %2%";
4917  if (opName == "lef" || opName == "led") return "setole %1%, %2%";
4918  if (opName == "gtf" || opName == "gtd") return "setogt %1%, %2%";
4919  if (opName == "gef" || opName == "ged") return "setoge %1%, %2%";
4920 
4921  if (opName == "equf" || opName == "equd") return "setueq %1%, %2%";
4922  if (opName == "neuf" || opName == "neud") return "setune %1%, %2%";
4923  if (opName == "ltuf" || opName == "ltud") return "setult %1%, %2%";
4924  if (opName == "leuf" || opName == "leud") return "setule %1%, %2%";
4925  if (opName == "gtuf" || opName == "gtud") return "setugt %1%, %2%";
4926  if (opName == "geuf" || opName == "geud") return "setuge %1%, %2%";
4927 
4928  if (opName == "ordf" || opName == "ordd") return "seto %1%, %2%";
4929  if (opName == "uordf"|| opName == "uordd")return "setuo %1%, %2%";
4930 
4931  if (opName == "addf" || opName == "addd") return "fadd %1%, %2%";
4932  if (opName == "subf" || opName == "subd") return "fsub %1%, %2%";
4933  if (opName == "mulf" || opName == "muld") return "fmul %1%, %2%";
4934  if (opName == "divf" || opName == "divd") return "fdiv %1%, %2%";
4935  if (opName == "absf" || opName == "absd") return "fabs %1%";
4936  if (opName == "negf" || opName == "negd") return "fneg %1%";
4937  if (opName == "sqrtf"|| opName == "sqrtd")return "fsqrt %1%";
4938 
4939  if (opName == "cif") return "sint_to_fp %1%";
4940  if (opName == "cfi") return "fp_to_sint %1%";
4941  if (opName == "cifu") return "uint_to_fp %1%";
4942  if (opName == "cfiu") return "fp_to_uint %1%";
4943 
4944  if (opName == "cld") return "sint_to_fp %1%";
4945  if (opName == "cdl") return "fp_to_sint %1%";
4946  if (opName == "cldu") return "uint_to_fp %1%";
4947  if (opName == "cdlu") return "fp_to_uint %1%";
4948 
4949  if (opName == "cfh" || opName == "cdf") return "fpround %1%";
4950  if (opName == "chf") return "f32 (fpextend %1%)";
4951  if (opName == "cfd") return "f64 (fpextend %1%)";
4952 
4953  if (opName == "cih") return "sint_to_fp %1%";
4954  if (opName == "chi") return "i32 (fp_to_sint %1%)";
4955  if (opName == "cihu") return "uint_to_fp %1%";
4956  if (opName == "chiu") return "i32 (fp_to_uint %1%)";
4957 
4958  if (opName == "neuh") return "setune %1%, %2%";
4959  if (opName == "eqh") return "setoeq %1%, %2%";
4960  if (opName == "neh") return "setone %1%, %2%";
4961  if (opName == "lth") return "setolt %1%, %2%";
4962  if (opName == "leh") return "setole %1%, %2%";
4963  if (opName == "gth") return "setogt %1%, %2%";
4964  if (opName == "geh") return "setoge %1%, %2%";
4965 
4966  if (opName == "ordh") return "seto %1%, %2%";
4967  if (opName == "uordh") return "setuo %1%, %2%";
4968 
4969  if (opName == "addh") return "fadd %1%, %2%";
4970  if (opName == "subh") return "fsub %1%, %2%";
4971  if (opName == "mulh") return "fmul %1%, %2%";
4972  if (opName == "divh") return "fdiv %1%, %2%";
4973  if (opName == "absh") return "fabs %1%";
4974  if (opName == "negh") return "fneg %1%";
4975  if (opName == "sqrth") return "fsqrt %1%";
4976 
4977  if (opName == "cih") return "sint_to_fp %1%";
4978  if (opName == "chi") return "fp_to_sint %1%";
4979  if (opName == "cihu") return "uint_to_fp %1%";
4980  if (opName == "chiu") return "fp_to_uint %1%";
4981 
4982  if (opName == "csh") return "sint_to_fp %1%";
4983  if (opName == "cshu") return "uint_to_fp %1%";
4984  if (opName == "chs") return "fp_to_sint %1%";
4985  if (opName == "chsu") return "fp_to_uint %1%";
4986 
4987  if (littleEndian_) {
4988  if (opName == "ld8") return "sextloadi8 %1%";
4989  if (opName == "ldu8") return "zextloadi8 %1%";
4990  if (opName == "ld16") return "sextloadi16 %1%";
4991  if (opName == "ldu16") return "zextloadi16 %1%";
4992  if (mach_.is64bit()) {
4993  if (opName == "ld32") return "sextloadi32 %1%";
4994  if (opName == "ldu32") return "zextloadi32 %1%";
4995  } else {
4996  if (opName == "ld32" || opName == "ldu32") return "load %1%";
4997  }
4998  if (opName == "ld64") return "load %1%";
4999  //if (opName == "ldd") return "load";
5000 
5001  if (opName == "st8") return "truncstorei8 %2%, %1%";
5002  if (opName == "st16") return "truncstorei16 %2%, %1%";
5003  if (mach_.is64bit()) {
5004  if (opName == "st32") return "truncstorei32 %2%, %1%";
5005  } else {
5006  if (opName == "st32") return "store %2%, %1%";
5007  }
5008  if (opName == "st64") return "store %2%, %1%";
5009  } else {
5010  if (opName == "ldq") return "sextloadi8 %1%";
5011  if (opName == "ldqu") return "zextloadi8 %1%";
5012  if (opName == "ldh") return "sextloadi16 %1%";
5013  if (opName == "ldhu") return "zextloadi16 %1%";
5014  if (opName == "ldw") return "load %1%";
5015  //if (opName == "ldd") return "load";
5016 
5017  if (opName == "stq") return "truncstorei8 %2%, %1%";
5018  if (opName == "sth") return "truncstorei16 %2%, %1%";
5019  if (opName == "stw") return "store %2%, %1%";
5020  //if (opName == "std") return "load";
5021  }
5022 
5023  if (opName == "sxw64") {
5024  return "sext_inreg %1%, i32";
5025  }
5026 
5027  if (opName == "sxb64") {
5028  return "sext_inreg %1%, i1";
5029  }
5030 
5031  if (opName == "sxq64") {
5032  return "sext_inreg %1%, i8";
5033  }
5034  if (opName == "sxh64") {
5035  return "sext_inreg %1%, i16";
5036  }
5037 
5038  if (opName == "sxhw") {
5039  return "sext_inreg %1%, i16";
5040  }
5041  if (opName == "sxqw") {
5042  return "sext_inreg %1%, i8";
5043  }
5044 
5045  if (opName == "sxw")
5046  return mach_.is64bit() ? "sext_inreg %1%, i64": "sext_inreg %1%, i32";
5047 
5048  if (opName == "sxbw") return "sext_inreg %1%, i1";
5049 
5050  if (opName == "truncwh" || opName == "truncwb" || opName == "trunchb")
5051  return "trunc %1%";
5052 
5053  if (opName == "neg") return "ineg %1%";
5054  if (opName == "not") return "not %1%";
5055 
5056  if (opName == "cas") return "atomic_cmp_swap_32 %1%, %2%, %3%";
5057  if (opName == "select") return "select %3%, %1%, %2%";
5058 
5059  // Unknown operation name.
5060  return "";
5061 }

References TTAMachine::Machine::is64bit(), littleEndian_, mach_, Operation::name(), and StringTools::stringToLower().

Referenced by operationCanBeMatched(), operationNodeToString(), writeEmulationPattern(), and writeOperationDef().

Here is the call graph for this function:

◆ operandChar()

char TDGen::operandChar ( Operand operand)
protectedvirtual

Returns corresponding character for given operand type.

Parameters
operandOperand under inspection.
Returns
Corresponding character of operand type.

Definition at line 4714 of file TDGen.cc.

4714  {
4715  if (operand.isVector()) {
4716  if (operand.type() == Operand::BOOL) {
4717  return OT_VREG_BOOL;
4718  } else if (operand.type() == Operand::HALF_FLOAT_WORD) {
4719  return OT_VREG_HFP;
4720  } else if (operand.type() == Operand::FLOAT_WORD) {
4721  return OT_VREG_FP;
4722  } else {
4723  if (operand.elementWidth() == 1) {
4724  return OT_VREG_BOOL;
4725  } else if (operand.elementWidth() == 8) {
4726  return OT_VREG_INT8;
4727  } else if (operand.elementWidth() == 16) {
4728  return OT_VREG_INT16;
4729  } else {
4730  return OT_VREG_INT32;
4731  }
4732  }
4733  }
4734 
4735  if (operand.type() == Operand::BOOL) {
4736  return OT_REG_BOOL;
4737  } else if (operand.type() == Operand::HALF_FLOAT_WORD) {
4738  return OT_REG_HFP;
4739  } else if (operand.type() == Operand::ULONG_WORD ||
4740  operand.type() == Operand::SLONG_WORD ||
4741  operand.type() == Operand::RAW_DATA) {
4742  return mach_.is64bit() ? OT_REG_LONG : OT_REG_INT;
4743  } else if (operand.type() != Operand::UINT_WORD &&
4744  operand.type() != Operand::SINT_WORD) {
4745  return OT_REG_FP;
4746  } else {
4747  return OT_REG_INT;
4748  }
4749 }

References Operand::BOOL, Operand::elementWidth(), Operand::FLOAT_WORD, Operand::HALF_FLOAT_WORD, TTAMachine::Machine::is64bit(), Operand::isVector(), mach_, OT_REG_BOOL, OT_REG_FP, OT_REG_HFP, OT_REG_INT, OT_REG_LONG, OT_VREG_BOOL, OT_VREG_FP, OT_VREG_HFP, OT_VREG_INT16, OT_VREG_INT32, OT_VREG_INT8, Operand::RAW_DATA, Operand::SINT_WORD, Operand::SLONG_WORD, Operand::type(), Operand::UINT_WORD, and Operand::ULONG_WORD.

Referenced by createDefaultOperandTypeString(), emulatingOpNodeLLVMName(), operationCanBeMatched(), writeEmulationPattern(), and writeOperationDef().

Here is the call graph for this function:

◆ operandToString()

std::string TDGen::operandToString ( const Operand operand,
bool  match,
char  operandType,
const std::string &  immDefName = "" 
)
protectedvirtual

Returns LLVM .td format string for an operand.

Parameters
operandOperand to return string for.
matchTrue, if the string should be in the matching pattern format.
operandTypeCharacter that identifies the type of the operand.
Returns
Operand string to be used in a llvm .td pattern.
Todo:
Vector of pointers once supported. Change operand types for GATHER and SCATTER to be mem-data and mem-address, because that will direct the address operand into this if-clause.

Definition at line 5796 of file TDGen.cc.

5800  {
5801  int idx = operand.index();
5802 
5803  if (operand.isVector() && !operand.isAddress()) {
5804  switch (operandType) {
5805  case OT_VREG_BOOL:
5806  case OT_VREG_INT8:
5807  case OT_VREG_INT16:
5808  case OT_VREG_INT32:
5809  case OT_VREG_FP:
5810  case OT_VREG_HFP: {
5811  TCEString regClass = associatedVectorRegisterClass(operand);
5812  return regClass + ":$op" + Conversion::toString(idx);
5813  }
5814  }
5815  }
5816 
5817  // from TDGenSIMD: if (operand.isVector && operand.isAddress()
5818  /// @todo Vector of pointers once supported. Change operand types
5819  /// for GATHER and SCATTER to be mem-data and mem-address, because
5820  /// that will direct the address operand into this if-clause.
5821 
5822  if (operand.isAddress()) {
5823  switch (operandType) {
5824  case OT_IMM_INT:
5825  case OT_IMM_LONG:
5826  if (match) {
5827  return "MEMri:$op" + Conversion::toString(idx);
5828  } else {
5829  return "ADDRri:$op" + Conversion::toString(idx);
5830  }
5831  case OT_REG_INT:
5832  case OT_REG_LONG:
5833  if (match) {
5834  return "MEMrr:$op" + Conversion::toString(idx);
5835  } else {
5836  return "ADDRrr:$op" + Conversion::toString(idx);
5837  }
5838  default:
5839  std::string msg =
5840  "invalid operation type for mem operand:";
5841  msg += operandType;
5842  throw InvalidData(__FILE__, __LINE__, __func__, msg);
5843  }
5844  } else if (operand.type() == Operand::SINT_WORD ||
5845  operand.type() == Operand::UINT_WORD ||
5846  operand.type() == Operand::RAW_DATA ||
5847  operand.type() == Operand::BOOL) {
5848 
5849  // imm
5850  switch (operandType) {
5851  case OT_IMM_LONG:
5852  if (match) {
5853  return "i64imm:$op" + Conversion::toString(idx);
5854  } else {
5855  return "(i64 imm:$op" + Conversion::toString(idx) + ")";
5856  }
5857  case OT_IMM_INT:
5858  assert(!immDefName.empty() &&
5859  "No immediate operand defined for the operand.");
5860  return immDefName + ":$op" + Conversion::toString(idx);
5861  case OT_IMM_BOOL:
5862  if (match) {
5863  return "i1imm:$op" + Conversion::toString(idx);
5864  } else {
5865  return "(i1 imm:$op" + Conversion::toString(idx) + ")";
5866  }
5867  case OT_REG_INT:
5868  return mach_.is64bit() ?
5869  "R64IRegs:$op" + Conversion::toString(idx):
5870  "R32IRegs:$op" + Conversion::toString(idx);
5871  case OT_REG_LONG:
5872  return "R64IRegs:$op" + Conversion::toString(idx);
5873  case OT_REG_BOOL:
5874  return "R1Regs:$op" + Conversion::toString(idx);
5875  case OT_REG_FP:
5876  if (operand.type() == Operand::RAW_DATA) {
5877  return "FPRegs:$op" + Conversion::toString(idx);
5878  }
5879  /* fall through */
5880  case OT_REG_HFP:
5881  if (operand.type() == Operand::RAW_DATA) {
5882  return "HFPRegs:$op" + Conversion::toString(idx);
5883  }
5884  /* fall through */
5885  default:
5886  std::string msg =
5887  "invalid operation type for integer operand:";
5888  msg += operandType;
5889  throw InvalidData(__FILE__, __LINE__, __func__, msg);
5890  }
5891  } else if (operand.type() == Operand::FLOAT_WORD ) {
5892 
5893  switch (operandType) {
5894  case OT_IMM_INT:
5895  case OT_IMM_FP:
5896  if (match) {
5897  return "f32imm:$op" + Conversion::toString(idx);
5898  } else {
5899  return "(f32 fpimm:$op" + Conversion::toString(idx) + ")";
5900  }
5901  case OT_REG_INT:
5902  case OT_REG_FP:
5903  return "FPRegs:$op" + Conversion::toString(idx);
5904 
5905  default:
5906  std::string msg =
5907  "invalid operation type for float operand:";
5908  msg += operandType;
5909  throw InvalidData(__FILE__, __LINE__, __func__, msg);
5910  }
5911  } else if (operand.type() == Operand::HALF_FLOAT_WORD) {
5912 
5913  switch (operandType) {
5914  case OT_IMM_INT:
5915  case OT_IMM_FP:
5916  case OT_IMM_HFP:
5917  if (match) {
5918  return "f16imm:$op" + Conversion::toString(idx);
5919  } else {
5920  return "(f16 fpimm:$op" + Conversion::toString(idx) + ")";
5921  }
5922  case OT_REG_INT:
5923  case OT_REG_HFP:
5924  return "HFPRegs:$op" + Conversion::toString(idx);
5925  default:
5926  std::string msg =
5927  "invalid operation type for half operand:";
5928  msg += operandType;
5929  throw InvalidData(__FILE__, __LINE__, __func__, msg);
5930  }
5931  } else if (operand.type() == Operand::DOUBLE_WORD) {
5932  // TODO: immediate check??
5933  return "R64DFPRegs:$op" + Conversion::toString(idx);
5934  } else if (operand.type() == Operand::SLONG_WORD ||
5935  operand.type() == Operand::ULONG_WORD) {
5936  if (operandType == OT_REG_BOOL) {
5937  return "R1Regs:$op" + Conversion::toString(idx);
5938  }
5939  if (operandType == OT_IMM_BOOL) {
5940  if (match) {
5941  return "i1imm:$op" + Conversion::toString(idx);
5942  } else {
5943  return "(i1 imm:$op" + Conversion::toString(idx) + ")";
5944  }
5945  }
5946  if (operandType == OT_IMM_LONG) {
5947  return match ?
5948  "i64imm:$op" + Conversion::toString(idx) :
5949  "(i64 imm:$op" + Conversion::toString(idx) + ")";
5950  }
5951  return mach_.is64bit() ?
5952  "R64IRegs:$op" + Conversion::toString(idx):
5953  "R32IRegs:$op" + Conversion::toString(idx);
5954  } else {
5955  std::cerr << "Unknown operand type: " << operandType << std::endl;
5956  assert(false && "Unknown operand type.");
5957  }
5958  abortWithError("Unknown operand type on osal? Should not get here.");
5959  return "";
5960 }

References __func__, abortWithError, assert, associatedVectorRegisterClass(), Operand::BOOL, Operand::DOUBLE_WORD, Operand::FLOAT_WORD, Operand::HALF_FLOAT_WORD, Operand::index(), TTAMachine::Machine::is64bit(), Operand::isAddress(), Operand::isVector(), mach_, OT_IMM_BOOL, OT_IMM_FP, OT_IMM_HFP, OT_IMM_INT, OT_IMM_LONG, OT_REG_BOOL, OT_REG_FP, OT_REG_HFP, OT_REG_INT, OT_REG_LONG, OT_VREG_BOOL, OT_VREG_FP, OT_VREG_HFP, OT_VREG_INT16, OT_VREG_INT32, OT_VREG_INT8, Operand::RAW_DATA, Operand::SINT_WORD, Operand::SLONG_WORD, Conversion::toString(), Operand::type(), Operand::UINT_WORD, and Operand::ULONG_WORD.

Referenced by dagNodeToString(), patInputs(), patOutputs(), and writeEmulationPattern().

Here is the call graph for this function:

◆ operandTypesToRegisters()

std::string TDGen::operandTypesToRegisters ( const std::string &  opdTypes) const
protected

Definition at line 7811 of file TDGen.cc.

7811  {
7812  std::string result(opdTypes);
7813  for (char& type : result) {
7814  type = operandTypeToRegister(type);
7815  }
7816  return result;
7817 }

References operandTypeToRegister().

Referenced by getLLVMPatternWithConstants().

Here is the call graph for this function:

◆ operandTypeToRegister()

char TDGen::operandTypeToRegister ( const char &  opdType) const
protected

Definition at line 7820 of file TDGen.cc.

7820  {
7821  switch (opdType) {
7822  case OT_IMM_INT: return OT_REG_INT; // Integer immediate.
7823  case OT_IMM_BOOL: return OT_REG_BOOL; // Boolean immediate.
7824  case OT_IMM_FP: return OT_REG_FP; // 32-bit floating point immediate.
7825  case OT_IMM_HFP: return OT_REG_HFP; // 15-bi floating point immediate.
7826  // TODO: vector immediate types.
7827  default:
7828  break;
7829  }
7830  return opdType; // Return as is (should be register type).
7831 }

References OT_IMM_BOOL, OT_IMM_FP, OT_IMM_HFP, OT_IMM_INT, OT_REG_BOOL, OT_REG_FP, OT_REG_HFP, and OT_REG_INT.

Referenced by getLLVMPatternWithConstants(), getMovePattern(), and operandTypesToRegisters().

◆ operationCanBeMatched()

bool TDGen::operationCanBeMatched ( const Operation op,
std::set< std::string > *  recursionCycleCheck = NULL,
bool  recursionHasStore = false 
)
protected

Check if operation can be matched with llvm pattern.

Check if operation has llvmOperationPatters or one of it's DAGs contain only operations, which can be matched.

Definition at line 5240 of file TDGen.cc.

5242  {
5243 
5244  // LLVM does not support operations with >255 inputs.
5245  if (op.numberOfInputs() > 255) {
5246  return false;
5247  }
5248  // TODO: this should have been changed?
5250  // if operation has llvm pattern
5251  if (llvmOperationPattern(op,operandChar) != "") {
5252  return true;
5253  }
5254 
5255  std::set<std::string> useSet;
5256  if (recursionCycleCheck != NULL) {
5257  useSet = *recursionCycleCheck;
5258  }
5259  useSet.insert(op.name());
5260 
5261  // check if one of dags of operation is ok
5262  for (int i = 0; i < op.dagCount(); i++) {
5263  OperationDAG& dag = op.dag(i);
5264  if (operationDAGCanBeMatched(dag, &useSet, recursionHasStore)) {
5265  return true;
5266  }
5267  }
5268 
5269  return false;
5270 }

References Operation::dag(), Operation::dagCount(), TTAMachine::Machine::is64bit(), llvmOperationPattern(), mach_, Operation::name(), Operation::numberOfInputs(), operandChar(), operationDAGCanBeMatched(), OT_REG_INT, and OT_REG_LONG.

Referenced by operationDAGCanBeMatched(), and writeInstrInfo().

Here is the call graph for this function:

◆ operationDAGCanBeMatched()

bool TDGen::operationDAGCanBeMatched ( const OperationDAG op,
std::set< std::string > *  recursionCycleCheck = NULL,
bool  recursionHasStore = false 
)
protected

Definition at line 5274 of file TDGen.cc.

5277  {
5278 
5279  bool hasStore = false;
5280 
5281  for (int j = 0; j < opDag.nodeCount(); j++) {
5282  OperationNode* opNode = dynamic_cast<OperationNode*>(&opDag.node(j));
5283  if (opNode) {
5284  Operation& refOp = opNode->referencedOperation();
5285  if (refOp.writesMemory()) {
5286  if (recursionHasStore || hasStore) {
5287  return false;
5288  } else {
5289  hasStore = true;
5290  }
5291  }
5292 
5293  // check that the same operation is not used recursively
5294  if (recursionCycleCheck &&
5295  recursionCycleCheck->count(refOp.name()) != 0) {
5296  return false;
5297  }
5298 
5299  // check if referenced op can be matched
5300  if (!operationCanBeMatched(refOp, recursionCycleCheck,
5301  hasStore)) {
5302  return false;
5303  }
5304  }
5305  }
5306  return true;
5307 }

References Operation::name(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), operationCanBeMatched(), OperationNode::referencedOperation(), and Operation::writesMemory().

Referenced by getMatchableOperationDAG(), and operationCanBeMatched().

Here is the call graph for this function:

◆ operationNodeToString()

std::string TDGen::operationNodeToString ( const Operation op,
const OperationDAG dag,
const OperationNode node,
bool  emulationPattern,
const std::string &  operandTypes 
)
protected

Converts OSAL dag operation node to llvm .td pattern fragment string.

Parameters
opOperation which this operation node is part of.
dagParent DAG of the operation node.
nodeNode to convert to string.
immOpIndex of an operand to define as immediate or 0 if none.
emulationPatternTrue, if the string should be in emulation pattern format.

Definition at line 5711 of file TDGen.cc.

5713  {
5714  const Operation& operation = node.referencedOperation();
5715 
5716  std::string operationPat;
5717 
5718  if (emulationPattern) {
5719  operationPat = emulatingOpNodeLLVMName(
5720  op, dag, node, operandTypes);
5721 
5722  for (int i = 0; i < operation.numberOfInputs(); i++) {
5723  if (i > 0) {
5724  operationPat += ", ";
5725  } else {
5726  operationPat += " ";
5727  }
5728  operationPat =
5729  operationPat + "%" + Conversion::toString(i + 1) + "%";
5730  }
5731  } else {
5732  operationPat = llvmOperationPattern(operation, operandTypes[0]);
5733 
5734  // generate pattern for operation if not llvmOperation (can match
5735  // custom op patterns)
5736  if (operationPat == "") {
5737  auto* dagToUse = getMatchableOperationDAG(operation);
5738  if (dagToUse) {
5739  return subPattern(operation, *dagToUse);
5740  } else {
5741  operationPat = tceOperationPattern(operation);
5742  }
5743  }
5744  }
5745 
5746  if (operationPat == "") {
5747  std::string msg("Unknown operation node in dag: " +
5748  std::string(operation.name()));
5749 
5750  throw InvalidData(__FILE__, __LINE__, __func__, msg);
5751  }
5752 
5753  boost::format pattern(operationPat);
5754 
5755  int inputs = operation.numberOfInputs();
5756 #ifndef NDEBUG
5757  int outputs =
5758 #endif
5759  operation.numberOfOutputs();
5760 
5761  assert(outputs == 0 || outputs == 1);
5762 
5763  for (int i = 1; i < inputs + 1; i++) {
5764  for (int e = 0; e < dag.inDegree(node); e++) {
5765  const OperationDAGEdge& edge = dag.inEdge(node, e);
5766  int dst = edge.dstOperand();
5767  if (dst == i) {
5768  const OperationDAGNode& in = dag.tailNode(edge);
5769  std::string dagNodeString = dagNodeToString(
5770  op, dag, in, emulationPattern, operandTypes,
5771  &operation, &node);
5772  try {
5773  pattern % dagNodeString;
5774  } catch(...) {
5775  TCEString msg = "Boost format threw exception! ";
5776  msg << "Input format: " << operationPat;
5777  throw InvalidData(__FILE__, __LINE__, __func__, msg);
5778  }
5779  }
5780  }
5781  }
5782 
5783  return std::string("(") + pattern.str() + ")";
5784 }

References __func__, assert, dagNodeToString(), OperationDAGEdge::dstOperand(), emulatingOpNodeLLVMName(), getMatchableOperationDAG(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::inEdge(), llvmOperationPattern(), Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), OperationNode::referencedOperation(), subPattern(), BoostGraph< GraphNode, GraphEdge >::tailNode(), tceOperationPattern(), and Conversion::toString().

Referenced by dagNodeToString().

Here is the call graph for this function:

◆ operationPattern()

std::string TDGen::operationPattern ( const Operation op,
const OperationDAG dag,
const std::string &  operandTypes 
)
protected

Returns operation pattern in llvm .td format.

Parameters
opOperation to return pattern for.
dagOperation pattern's DAG.
immOpIndex of an operand to define as an immediate operand, or 0, if all operands should be in registers.
Returns
Pattern string.

Definition at line 5351 of file TDGen.cc.

5354  {
5355 
5356  std::string retVal;
5357  for (OperationDAG::NodeSet::iterator i = dag.endNodes().begin();
5358  i != dag.endNodes().end(); ++i) {
5359  if (i != dag.endNodes().begin()) {
5360  retVal += ",";
5361  }
5362  const OperationDAGNode& res = **(i);
5363  retVal += dagNodeToString(op, dag, res, false, operandTypes);
5364  }
5365  return retVal;
5366 }

References dagNodeToString(), and OperationDAG::endNodes().

Referenced by writeOperationDef().

Here is the call graph for this function:

◆ orderEqualWidthRegistersToRoundRobin()

void TDGen::orderEqualWidthRegistersToRoundRobin ( )
protected

Sets registers to use round robin order in register allocation.

Starting from register index number 0, all same width registers having the same index number are pushed to a vector. Then, index is increased by one and same action is performed, index increased etc., until all registers of same width are pushed to the vector. Then, the vector is used to replace old register order.

For example, two register files R64_1 (register indices 0, 1, 2 and 3) and R64_2 (register indices 0, 1) are ordered as: R64_1(0), R64_2(0), R64_1(1), R64_2(1), R64_1(2), R64_1(3), and LLVM register allocator will use this order to allocate the registers.

Definition at line 1618 of file TDGen.cc.

1618  {
1619  std::vector<RegisterInfo> roundRobinOrder;
1620 
1621  // Loop through every different group of register widths.
1622  std::map<int, std::vector<RegisterInfo>>::iterator it;
1623  for (it = registers_.begin(); it != registers_.end(); ++it) {
1624  roundRobinOrder.clear();
1625  std::vector<RegisterInfo>& registers = it->second;
1626 
1627  unsigned i = 0;
1628  unsigned idx = 0;
1629 
1630  // Loop until all registers of same width are reordered.
1631  while (roundRobinOrder.size() != registers.size()) {
1632  RegisterInfo& info = registers[i];
1633  if (info.regIndex_ == idx) {
1634  roundRobinOrder.push_back(info);
1635  }
1636 
1637  if (i == registers.size() - 1) {
1638  i = 0;
1639  ++idx;
1640  } else {
1641  ++i;
1642  }
1643  }
1644 
1645  registers = roundRobinOrder;
1646  }
1647 }

References TDGenerator::RegisterInfo::regIndex_, and registers_.

Referenced by analyzeMachineRegisters().

◆ patInputs()

std::string TDGen::patInputs ( const Operation op,
const std::string &  inputTypes 
)
protected

Returns llvm input definition list for an operation.

Parameters
opOperation to define inputs for.
Returns
String defining operation inputs in llvm .td format.

Definition at line 5969 of file TDGen.cc.

5969  {
5970 
5971  std::string ins;
5972  for (int i = 0; i < op.numberOfInputs(); i++) {
5973  if (i > 0) {
5974  ins += ", ";
5975  }
5976 
5977  char inputType = inputTypes[i + op.numberOfOutputs()];
5978  std::string immDef("");
5979  // NOTE: !op.operand(i+1).isAddress() is kludge fix for MEMri/ADDri
5980  // operands. They do not have immediate operand definitions (yet).
5981  if (inputType == OT_IMM_INT && !op.operand(i+1).isAddress()) {
5982  assert(immOperandDefs_.count(
5983  ImmInfo::key(op, op.operand(i+1)))
5984  && "Missing immediate operand definition for the operand.");
5985  immDef = immOperandDefs_[ImmInfo::key(op, op.operand(i+1))];
5986  }
5987  ins += operandToString(op.operand(i + 1), true, inputType, immDef);
5988  }
5989  return ins;
5990 }

References assert, immOperandDefs_, Operand::isAddress(), ImmInfo::key(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), operandToString(), and OT_IMM_INT.

Referenced by writeOperationDef().

Here is the call graph for this function:

◆ patOutputs()

std::string TDGen::patOutputs ( const Operation op,
const std::string &  operandTypes 
)
protected

Returns llvm output definition list for an operation.

Parameters
opOperation to define outputs for.
Returns
String defining operation outputs in llvm .td format.

Definition at line 6000 of file TDGen.cc.

6000  {
6001  std::string outs;
6002  for (int i = 0; i < op.numberOfOutputs(); i++) {
6003  assert(op.operand(op.numberOfInputs() + 1 + i).isOutput());
6004  outs += (i > 0) ? (",") : (" ");
6005  outs += operandToString(
6006  op.operand(op.numberOfInputs() + 1 + i), true, operandTypes[i]);
6007  }
6008  return outs;
6009 }

References assert, Operand::isOutput(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), and operandToString().

Referenced by writeOperationDef().

Here is the call graph for this function:

◆ saveAdditionalVectorOperationInfo()

void TDGen::saveAdditionalVectorOperationInfo ( const Operation op,
const TCEString valueTypes,
bool  isRegisterOp 
)
protected

Saves information of some operations.

Additional information of some operations is needed later, and thus, they need to be saved for later reference.

Parameters
opVector operation.
valueTypesOperand value type identifier characters.
isRegisterOpIf false, operation has immediate operands.

Definition at line 2190 of file TDGen.cc.

2191  {
2192  abortWithError("WiP");
2193 }

References abortWithError.

Referenced by writeVectorOperationDef().

◆ subPattern()

std::string TDGen::subPattern ( const Operation op,
const OperationDAG dag 
)
protected

Return operation pattern is llvm .td format without outputs.

This pattern can be used as sub-pattern of bigger pattern. The operation must have only one output.

Parameters
opOperation to return pattern for.
dagOperation pattern's DAG.
Returns
Pattern string.

Definition at line 5398 of file TDGen.cc.

5400  {
5401 
5402  if (dag.endNodes().size() != 1) {
5403  throw InvalidData(
5404  __FILE__,__LINE__,__func__,
5405  "Cannot create subpattern: not exactly 1 end node!");
5406  }
5407 
5408  OperationDAG::NodeSet::iterator i = dag.endNodes().begin();
5409  const OperationDAGNode& res = **(i);
5410  OperationDAG::NodeSet preds = dag.predecessors(res);
5411  if (preds.size() != 1) {
5412  throw InvalidData(
5413  __FILE__,__LINE__,__func__,
5414  "Cannot create subpattern: not single data source for end node.");
5415  }
5416 
5417  std::string operandTypes = createDefaultOperandTypeString(op);
5418  // TODO: what about immediate operands?
5419 
5420  // TODO: size of the operand string?
5421  return dagNodeToString(
5422  op, dag, **(preds.begin()), false, operandTypes);
5423 }

References __func__, createDefaultOperandTypeString(), dagNodeToString(), OperationDAG::endNodes(), and BoostGraph< GraphNode, GraphEdge >::predecessors().

Referenced by operationNodeToString().

Here is the call graph for this function:

◆ subwordWidthOfRawData()

int TDGen::subwordWidthOfRawData ( const Operation op) const
protected

Returns subword width of vector operands of "raw" type.

Note
This function chooses the subword width based on subword width of the WIDEST "raw" data operand that can be found from the operation, since that approach works for current SIMD operation definitions. If this approach doesn't work for your operation, modify the function properly to fulfil your needs.
Parameters
opOperation that has raw operands.
Returns
Subword width of the raw vector operands.

Definition at line 1722 of file TDGen.cc.

1722  {
1723  int widestWidth = -1;
1724  int widestRawOperandIndex = -1;
1725  for (int i = 1; i <= op.operandCount(); ++i) {
1726  const Operand& operand = op.operand(i);
1727  if (operand.type() == Operand::RAW_DATA && operand.isVector()) {
1728  if (operand.width() > widestWidth) {
1729  widestWidth = operand.width();
1730  widestRawOperandIndex = i;
1731  }
1732  }
1733  }
1734 
1735  if (widestRawOperandIndex >= 0) {
1736  return op.operand(widestRawOperandIndex).elementWidth();
1737  }
1738 
1739  assert(false && "Invalid input operation.");
1740 }

References assert, Operand::elementWidth(), Operand::isVector(), Operation::operand(), Operation::operandCount(), Operand::RAW_DATA, Operand::type(), and Operand::width().

Here is the call graph for this function:

◆ supportedStackAccessOperations()

std::vector< std::string > TDGen::supportedStackAccessOperations ( const TTAMachine::Machine mach)
staticprotected

Returns OSAL operation names valid for stack accesses.

Parameters
machThe target machine.

Definition at line 7611 of file TDGen.cc.

7611  {
7612 
7613  using namespace TTAMachine;
7614 
7615  std::vector<std::string> opcodes;
7616 
7617  auto collectMemoryOps = [](
7618  std::vector<std::string>& newOpcodes,
7619  const FunctionUnit& fu) -> void {
7620 
7621  for (int i = 0; i < fu.operationCount(); i++) {
7622  const Operation& op = MachineInfo::osalOperation(*fu.operation(i));
7623  if (!op.readsMemory() && !op.writesMemory()) {
7624  continue;
7625  }
7626  newOpcodes.push_back(StringTools::stringToUpper(op.name()));
7627  }
7628  };
7629 
7630  std::map<const AddressSpace*, std::set<const FunctionUnit*>>
7631  addrSpaceLsuMap;
7632  for (const FunctionUnit* fu : mach.functionUnitNavigator()) {
7633  if (fu->hasAddressSpace()) {
7634  addrSpaceLsuMap[fu->addressSpace()].insert(fu);
7635  }
7636  }
7637 
7638  const int stackAddressSpaceId = 0;
7639  if (addrSpaceLsuMap.size() == 1) {
7640  // Only one data address space. Stack resides there.
7641  for (auto lsu : addrSpaceLsuMap.begin()->second) {
7642  collectMemoryOps(opcodes, *lsu);
7643  }
7644  } else {
7645  // Multiple data address spaces. Find LSUs having the stack address
7646  // space ID.
7647  for (auto asLsusPair : addrSpaceLsuMap) {
7648  if (asLsusPair.first->hasNumericalId(stackAddressSpaceId)) {
7649  for (auto lsu : asLsusPair.second) {
7650  collectMemoryOps(opcodes, *lsu);
7651  }
7652  break;
7653  }
7654  }
7655  }
7656 
7657  return opcodes;
7658 }

References TTAMachine::Machine::functionUnitNavigator(), Operation::name(), MachineInfo::osalOperation(), Operation::readsMemory(), StringTools::stringToUpper(), and Operation::writesMemory().

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ tceOperationPattern()

std::string TDGen::tceOperationPattern ( const Operation op)
protected

Pattern for tce generated custom op patterns.

Definition at line 5225 of file TDGen.cc.

5225  {
5226  std::string opList = "";
5227  for (int i = 0; i < op.numberOfInputs(); i++) {
5228  opList += " %" + Conversion::toString(i+1) + "%";
5229  }
5230  return op.name() + opList;
5231 }

References Operation::name(), Operation::numberOfInputs(), and Conversion::toString().

Referenced by operationNodeToString().

Here is the call graph for this function:

◆ verbose()

void TDGen::verbose ( const TCEString msg) const
protected

Prints debugging information if verbose switch is used.

Parameters
msgDebug message.

Definition at line 1806 of file TDGen.cc.

1806  {
1808  Application::logStream() << msg << endl;
1809  }
1810 }

References Application::logStream(), Application::VERBOSE_LEVEL_DEFAULT, and Application::verboseLevel().

Referenced by analyzeMachineVectorRegisterClasses(), genGeneratedTCEPlugin_getLoad(), genGeneratedTCEPlugin_getStore(), writeCallingConv(), and writeVectorOperationDef().

Here is the call graph for this function:

◆ write16bitRegisterInfo()

void TDGen::write16bitRegisterInfo ( std::ostream &  o)
protected

Writes 16-bit register definitions to the output stream.

Definition at line 1155 of file TDGen.cc.

1155  {
1156  // --- Hardcoded reserved registers. ---
1157  writeRegisterDef(o, regs16bit_[0], "HIRES0", "R16", "", RESULT);
1158 
1159  // -------------------------------------
1160 
1161  for (unsigned i = 1; i < regs16bit_.size(); i++) {
1162  std::string regName = "H" + Conversion::toString(i);
1163  writeRegisterDef(o, regs16bit_[i], regName, "R16", "", GPR);
1164  }
1165 
1166  o << std::endl;
1167 
1168  // All 16-bit regs.
1169  for (RegClassMap::iterator ri = regsInClasses_.begin();
1170  ri != regsInClasses_.end(); ri++) {
1171  // go through all 1-bit RF classes
1172  if (ri->first.find("R16") == 0) {
1173  o << "def " << ri->first
1174  << "Regs : RegisterClass<\"TCE\", [i16], 32, (add ";
1175  o << ri->second[0];
1176  for (unsigned i = 1; i < ri->second.size(); i++) {
1177  o << " , " << ri->second[i];
1178  }
1179  o << ")>;" << std::endl;
1180  }
1181  }
1182  o << std::endl;
1183 
1184  for (RegClassMap::iterator ri = regsInClasses_.begin();
1185  ri != regsInClasses_.end(); ri++) {
1186  // go through all 1-bit RF classes
1187  if (ri->first.find("R16") == 0) {
1188  o << "def " << ri->first
1189  << "IRegs : RegisterClass<\"TCE\", [i16], 32, (add ";
1190  o << ri->second[0];
1191  for (unsigned i = 1; i < ri->second.size(); i++) {
1192  o << " , " << ri->second[i];
1193  }
1194  o << ")>;" << std::endl;
1195  }
1196  }
1197  o << std::endl;
1198 
1199  // floating-point-versions of these
1200 
1201  for (RegClassMap::iterator ri = regsInClasses_.begin();
1202  ri != regsInClasses_.end(); ri++) {
1203  // go through all 1-bit RF classes
1204  if (ri->first.find("R16") == 0) {
1205  o << "def " << ri->first
1206  << "FPRegs : RegisterClass<\"TCE\", [f16], 32, (add ";
1207  o << ri->second[0];
1208  for (unsigned i = 1; i < ri->second.size(); i++) {
1209  o << " , " << ri->second[i];
1210  }
1211  o << ")>;" << std::endl;
1212  }
1213  }
1214 
1215  o << std::endl;
1216 }

References GPR, regs16bit_, regsInClasses_, RESULT, Conversion::toString(), and writeRegisterDef().

Here is the call graph for this function:

◆ write1bitRegisterInfo()

void TDGen::write1bitRegisterInfo ( std::ostream &  o)
protected

Writes 1-bit register definitions to the output stream.

Definition at line 905 of file TDGen.cc.

905  {
906  if (regs1bit_.size() < 1) {
907  RegInfo reg = {"dummy1", 0};
908  std::string name = "I1DUMMY";
909  writeRegisterDef(o, reg, name, "R1", "", RESERVED);
910  } else {
911  for (unsigned i = 0; i < regs1bit_.size(); i++) {
912  std::string regName = "B" + Conversion::toString(i);
913  writeRegisterDef(o, regs1bit_[i], regName, "R1", "", GPR);
914  }
915  }
916 
917  int stackSize = mach_.is64bit() ? 64 : 32;
918  for (RegClassMap::iterator ri = regsInClasses_.begin();
919  ri != regsInClasses_.end(); ri++) {
920  // go through all 1-bit RF classes
921  if (ri->first.find("R1") == 0) {
922  o << std::endl
923  << "def " << ri->first << "Regs : RegisterClass<\"TCE\", [i1]"
924  << ", " << stackSize << ", (add ";
925  o << ri->second[0];
926  for (unsigned i = 1; i < ri->second.size(); i++) {
927  o << " , " << ri->second[i];
928  }
929  o << ")> {" << std::endl
930  << " let Size=" << stackSize << ";" << std::endl
931  << "}" << std::endl;
932  }
933  }
934 }

References GPR, TTAMachine::Machine::is64bit(), mach_, regs1bit_, regsInClasses_, RESERVED, Conversion::toString(), and writeRegisterDef().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ write32bitRegisterInfo()

void TDGen::write32bitRegisterInfo ( std::ostream &  o)
protected

Definition at line 965 of file TDGen.cc.

965  {
966 
967  std::string i32regs;
968  size_t i = 0;
969 
970  if (!mach_.is64bit()) {
971  // --- Hardcoded reserved registers. ---
972  writeRegisterDef(o, regs32bit_[0], "SP", "R32", "", RESERVED);
973  writeRegisterDef(o, regs32bit_[1], "IRES0", "R32", "", RESULT);
974  writeRegisterDef(o, regs32bit_[2], "FP", "R32", "", RESERVED);
975 
978  o, regs32bit_[3], "KLUDGE_REGISTER", "R32", "", GPR);
979  } else {
981  o, regs32bit_[3], "KLUDGE_REGISTER", "R32", "", RESERVED);
982  }
983 
984  i32regs = "SP, IRES0, FP, KLUDGE_REGISTER";
985 
986  //after the loop, i will have the index of first non-special reg.
987  for (i = 4;
988  i < std::min((size_t)argRegCount_ + 3, regs32bit_.size());
989  i++) {
990  std::string regName = "A" + Conversion::toString(i);
991  writeRegisterDef(o, regs32bit_[i], regName, "R32", "", ARGUMENT);
992  i32regs += ", ";
993  i32regs += regName;
994  }
995  }
996 
997  if (regs32bit_.size() < 1) {
998  RegInfo reg = { "dummy32", 0 };
999  writeRegisterDef(o, reg, "dummy32", "R64", "", RESERVED);
1000  o << "def R32Regs : RegisterClass<\"TCE\", [i32,f32,f16,i1], 32, (add dummy32)>;"
1001  << std::endl;
1002  o << "def R32IRegs : RegisterClass<\"TCE\", [i32], 32, (add dummy32)>;"
1003  << std::endl;
1004  o << "def R32FPRegs : RegisterClass<\"TCE\", [f32], 32, (add dummy32)>;"
1005  << std::endl;
1006  o << "def R32HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add dummy32)>;"
1007  << std::endl;
1008  }
1009 
1010  // Generate data structure that contain registers grouped by their
1011  // physical RFs
1012  for (; i < regs32bit_.size(); i++) {
1013  std::string regName = "I" + Conversion::toString(i);
1014  writeRegisterDef(o, regs32bit_[i], regName, "R32", "", GPR);
1015 
1016  if (!regsInRFClasses_.count(regs32bit_[i].rf)) {
1017  regsInRFClasses_[regs32bit_[i].rf] = std::vector<std::string>();
1018  }
1019  i32regs += ", ";
1020  i32regs += regName;
1021  regsInRFClasses_[regs32bit_[i].rf].push_back(regName);
1022  }
1023 
1024  o << std::endl;
1025 
1026  if (!mach_.is64bit()) {
1027  // Bypass registers
1028  for (size_t j = 0; j < 256; ++j) {
1029  std::string regName = "BP" + Conversion::toString(j);
1030 
1031  o << "def " << regName << " : "
1032  << "R32<\"ByPass_Regs"
1033  << "\", []>, DwarfRegNum<"
1034  << "[" << dregNum_++ << "]>;"
1035  << std::endl;
1036  }
1037 
1038  // Bypass register class
1039  o << "def R32_ByPass_Regs : RegisterClass<\"TCE\", [i32,f32,f16], 32, (add ";
1040  for (size_t j = 0; j < 256; ++j) {
1041  std::string regName = "BP" + Conversion::toString(j);
1042 
1043  if (j != 0) {
1044  o << ", ";
1045  }
1046 
1047  o << regName;
1048  }
1049 
1050  o << ")>;" << std::endl;
1051  }
1052 
1053 
1054  for (RegClassMap::iterator
1055  it = regsInRFClasses_.begin(); it != regsInRFClasses_.end(); ++it) {
1056  o << "def R32_"
1057  << it->first
1058  << "_Regs : RegisterClass<\"TCE\", [i32,f32,f16], 32, (add ";
1059 
1060  for (std::vector<std::string>::iterator r = it->second.begin();
1061  r != it->second.end(); ++r) {
1062  if (r != it->second.begin()) {
1063  o << ", ";
1064  }
1065 
1066  o << *r;
1067  }
1068 
1069  o << ")>;" << std::endl;
1070  }
1071 
1072  o << std::endl;
1073 
1074  // Register classes for all 32-bit registers.
1075  // TODO: why are these needed? same as integer classes below?
1076  for (RegClassMap::iterator ri = regsInClasses_.begin();
1077  ri != regsInClasses_.end(); ri++) {
1078  // go through all 1-bit RF classes
1079  if (ri->first.find("R32") == 0) {
1080 
1081  o << "def " << ri->first << "Regs : RegisterClass<\"TCE\", [i32,f32,f16,i1], 32, (add ";
1082  o << ri->second[0];
1083  for (unsigned i = 1; i < ri->second.size(); i++) {
1084  o << " , " << ri->second[i];
1085  }
1086  o << ")>;" << std::endl;
1087  }
1088  }
1089  o << std::endl;
1090 
1091  // Integer register classes for 32-bit registers
1092  for (RegClassMap::iterator ri = regsInClasses_.begin();
1093  ri != regsInClasses_.end(); ri++) {
1094  // go through all 32-bit RF classes
1095  if (ri->first.find("R32") == 0) {
1096  o << "def " << ri->first << "IRegs : RegisterClass<\"TCE\", [i32], 32, (add ";
1097  o << ri->second[0];
1098  for (unsigned i = 1; i < ri->second.size(); i++) {
1099  o << " , " << ri->second[i];
1100  }
1101  o << ")>;" << std::endl;
1102  }
1103  }
1104  o << std::endl;
1105 
1106  // Floating point register classes for 32-bit registers
1107  for (RegClassMap::iterator ri = regsInClasses_.begin();
1108  ri != regsInClasses_.end(); ri++) {
1109  // go through all 32-bit RF classes
1110  if (ri->first.find("R32") == 0) {
1111 
1112  o << "def " << ri->first << "FPRegs : RegisterClass<\"TCE\", [f32], 32, (add ";
1113  o << ri->second[0];
1114  for (unsigned i = 1; i < ri->second.size(); i++) {
1115  o << " , " << ri->second[i];
1116  }
1117  o << ")>;" << std::endl;
1118  }
1119  }
1120 
1121  // Half-float register classes for 32-bit registers (TODO: 16-bit registers also?)
1122  for (RegClassMap::iterator ri = regsInClasses_.begin();
1123  ri != regsInClasses_.end(); ri++) {
1124  // go through all 32-bit RF classes
1125  if (ri->first.find("R32") == 0) {
1126  o << "def " << ri->first << "HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add ";
1127  o << ri->second[0];
1128  for (unsigned i = 1; i < ri->second.size(); i++) {
1129  o << " , " << ri->second[i];
1130  }
1131  o << ")>;" << std::endl;
1132  }
1133  }
1134 
1135 // if (regs32bit_.size() <3) {
1136  if (mach_.is64bit()) { // for now. later try to use 32-b it regs for float.
1137  use64bitForFP_ = true;
1138  }
1139 
1140  if (!use64bitForFP_) {
1141 
1142  o << "def FPRegs : RegisterClass<\"TCE\", [f32], 32, (add "
1143  << i32regs << ")>;" << std::endl;
1144 
1145  o << "def HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add "
1146  << i32regs << ")>;" << std::endl;
1147  }
1148  o << std::endl;
1149 }

References argRegCount_, ARGUMENT, dregNum_, GPR, TTAMachine::Machine::is64bit(), mach_, prebypassStackIndeces_, regs32bit_, regsInClasses_, regsInRFClasses_, RESERVED, RESULT, Conversion::toString(), use64bitForFP_, and writeRegisterDef().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ write64bitMoveDefs()

void TDGen::write64bitMoveDefs ( std::ostream &  o)
protected

Definition at line 8304 of file TDGen.cc.

8304  {
8305  o << std::endl << "// 64-bit register->register move definitions."
8306  << std::endl << "let isAsCheapAsAMove = 1 in {" << std::endl;
8307 
8308  o << "def MOV64rr : InstTCE<(outs R64Regs:$dst), (ins R64Regs:$src),"
8309  << " \"$src -> $dst;\", []>;" << std::endl;
8310 
8311  o << "def PRED_TRUE_MOV64rr : InstTCE<(outs R64Regs:$dst), "
8312  << "(ins R1Regs:$pred, R64Regs:$src), \"$src -> $dst;\", []>;"
8313  << std::endl;
8314 
8315  o << "def PRED_FALSE_MOV64rr : InstTCE<(outs R64Regs:$dst), "
8316  << "(ins R1Regs:$pred, R64Regs:$src), \"$src -> $dst;\", []>;"
8317  << std::endl;
8318 
8319  o << "} // end of is as cheap as move" << std::endl;
8320 }

◆ write64bitRegisterInfo()

void TDGen::write64bitRegisterInfo ( std::ostream &  o)
protected

Writes 64-bit register definitions to the output stream.

Definition at line 1307 of file TDGen.cc.

1307  {
1308 
1309  // --- Hardcoded reserved registers. ---
1310  std::string i64regs;
1311  std::string f64regs;
1312  size_t i = 0;
1313 
1314  if (mach_.is64bit()) {
1315  // --- Hardcoded reserved registers. ---
1316  writeRegisterDef(o, regs64bit_[0], "SP", "R64", "", RESERVED);
1317  writeRegisterDef(o, regs64bit_[1], "IRES0", "R64", "", RESULT);
1318  writeRegisterDef(o, regs64bit_[2], "FP", "R64", "", RESERVED);
1320  o, regs64bit_[3], "KLUDGE_REGISTER", "R64", "", RESERVED);
1321  i64regs = "SP, IRES0, FP, KLUDGE_REGISTER";
1322 
1323  //after the loop, i will have the index of first non-special reg.
1324  for (i = 4;
1325  i < std::min(argRegCount_ + 3, (unsigned int)regs64bit_.size());
1326  i++) {
1327  std::string regName = "A" + Conversion::toString(i);
1328  writeRegisterDef(o, regs64bit_[i], regName, "R64", "", ARGUMENT);
1329  i64regs += ", ";
1330  i64regs += regName;
1331  }
1332  } else {
1333 
1334  if (regs64bit_.size() < 1) {
1335  RegInfo reg = { "DUMMY64", 0 };
1336  writeRegisterDef(o, reg, "DUMMY64", "R64", "", RESERVED);
1337  i64regs = "DUMMY64";
1338  }
1339 
1340  }
1341 
1342  // i already contains the correct starting index.
1343  for (; i < regs64bit_.size(); i++) {
1344  std::string intRegName = "L" + Conversion::toString(i);
1345  if (i != 0)
1346  i64regs += ", ";
1347  i64regs += intRegName;
1348  writeRegisterDef(o, regs64bit_[i], intRegName, "R64", "", GPR);
1349  }
1350 
1351  if (mach_.is64bit()) {
1352  // Bypass registers
1353  for (size_t j = 0; j < 256; ++j) {
1354  std::string regName = "BP" + Conversion::toString(j);
1355 
1356  o << "def " << regName << " : "
1357  << "R64<\"ByPass_Regs"
1358  << "\", []>, DwarfRegNum<"
1359  << "[" << dregNum_++ << "]>;"
1360  << std::endl;
1361  }
1362 
1363  // Bypass register class
1364  o << "def R64_ByPass_Regs : RegisterClass<\"TCE\", [i64,i32,f64,f32,f16], 64, (add ";
1365  for (size_t j = 0; j < 256; ++j) {
1366  std::string regName = "BP" + Conversion::toString(j);
1367 
1368  if (j != 0) {
1369  o << ", ";
1370  }
1371 
1372  o << regName;
1373  }
1374 
1375  o << ")>;" << std::endl;
1376  }
1377 
1378  TCEString dataTypes64 = use64bitForFP_ ?
1379  "[i64,f64,f32,f16]" :
1380  "[i64,f64]";
1381 
1382  o << std::endl
1383  << "def R64Regs : RegisterClass<\"TCE\", " << dataTypes64
1384  << ", 64, (add " << i64regs << ")> ;"
1385  << std::endl;
1386 
1387  o << std::endl
1388  << "def R64IRegs : RegisterClass<\"TCE\", [i64], 64, (add "
1389  << i64regs << ")> ;"
1390  << std::endl;
1391 
1392  o << std::endl
1393  << "def R64FPRegs : RegisterClass<\"TCE\", [f32], 64, (add "
1394  << i64regs << ")>;" << std::endl;
1395 
1396  o << std::endl
1397  << "def R64HFPRegs : RegisterClass<\"TCE\", [f16], 64, (add "
1398  << i64regs << ")>;" << std::endl;
1399 
1400  o << std::endl
1401  << "def R64DFPRegs : RegisterClass<\"TCE\", [f64], 64, (add "
1402  << i64regs << ")>;" << std::endl << std::endl;
1403 
1404  if (use64bitForFP_) {
1405  o << "def FPRegs : RegisterClass<\"TCE\", [f32], 64, (add "
1406  << i64regs << ")>;" << std::endl << std::endl;
1407 
1408  o << "def HFPRegs : RegisterClass<\"TCE\", [f16], 64, (add "
1409  << i64regs << ")>;" << std::endl << std::endl;
1410  }
1411 }

References argRegCount_, ARGUMENT, dregNum_, GPR, TTAMachine::Machine::is64bit(), mach_, regs64bit_, RESERVED, RESULT, Conversion::toString(), use64bitForFP_, and writeRegisterDef().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ write8bitRegisterInfo()

void TDGen::write8bitRegisterInfo ( std::ostream &  o)
protected

◆ writeAddressingModeDefs()

void TDGen::writeAddressingModeDefs ( std::ostream &  o)
protected

Definition at line 8345 of file TDGen.cc.

8345  {
8346  if (!mach_.is64bit()) {
8347  o << std::endl
8348  << "// Addressing modes." << std::endl
8349  << "def ADDRrr : ComplexPattern<i32, 2, \"SelectADDRrr\", [], []>;" << std::endl
8350  << "def ADDRri : ComplexPattern<i32, 2, \"SelectADDRri\", [frameindex], []>;" << std::endl
8351  << std::endl
8352  << "// Address operands" << std::endl
8353  << "def MEMrr : Operand<i32> {" << std::endl
8354  << "let PrintMethod = \"printMemOperand\";" << std::endl
8355  << "let MIOperandInfo = (ops R32IRegs, R32IRegs);" << std::endl
8356  << "}" << std::endl
8357  << "def MEMri : Operand<i32> {" << std::endl
8358  << "let PrintMethod = \"printMemOperand\";" << std::endl
8359  << "let MIOperandInfo = (ops R32IRegs, i32imm);" << std::endl
8360  << "}" << std::endl
8361  << std::endl
8362  << "// Branch targets have OtherVT type." << std::endl
8363  << "def brtarget : Operand<OtherVT>; " << std::endl
8364  << "def calltarget : Operand<i32>;" << std::endl;
8365 
8366  o << "def SDT_TCECall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;" << std::endl;
8367  } else {
8368  o << std::endl
8369  << "// Addressing modes." << std::endl
8370  << "def ADDRrr : ComplexPattern<i64, 2, \"SelectADDRrr\", [], []>;" << std::endl
8371  << "def ADDRri : ComplexPattern<i64, 2, \"SelectADDRri\", [frameindex], []>;" << std::endl
8372  << std::endl
8373  << "// Address operands" << std::endl
8374  << "def MEMrr : Operand<i64> {" << std::endl
8375  << "let PrintMethod = \"printMemOperand\";" << std::endl
8376  << "let MIOperandInfo = (ops R64IRegs, R64IRegs);" << std::endl
8377  << "}" << std::endl
8378  << "def MEMri : Operand<i64> {" << std::endl
8379  << "let PrintMethod = \"printMemOperand\";" << std::endl
8380  << "let MIOperandInfo = (ops R64IRegs, i64imm);" << std::endl
8381  << "}" << std::endl
8382  << std::endl
8383  << "// Branch targets have OtherVT type." << std::endl
8384  << "def brtarget : Operand<OtherVT>; " << std::endl
8385  << "def calltarget : Operand<i64>;" << std::endl;
8386 
8387  o << "def SDT_TCECall : SDTypeProfile<0, 1, [SDTCisVT<0, i64>]>;" << std::endl;
8388  }
8389 }

References TTAMachine::Machine::is64bit(), and mach_.

Referenced by generateBackend().

Here is the call graph for this function:

◆ writeArgRegsArray()

void TDGen::writeArgRegsArray ( std::ostream &  os)
protected

Definition at line 6922 of file TDGen.cc.

6922  {
6923  os << "#ifndef ARGREGS_HH" << std::endl
6924  << "#define ARGREGS_HH" << std::endl << std::endl
6925  << "static const unsigned ArgRegs[] = { TCE::IRES0" << std::endl;
6926  for (unsigned int i = 4; i < (3 + argRegCount_); i++) {
6927  os << ",TCE::A" << i;
6928  }
6929  os << "};" << std::endl;
6930 
6931  os << "static const int argRegCount = " << argRegCount_ <<";" << std::endl
6932  << "#endif" << std::endl;
6933 }

References argRegCount_.

Referenced by generateBackend().

◆ writeBackendCode()

void TDGen::writeBackendCode ( std::ostream &  o)
protected

Generates required function definitions for the backend plugin.

Parameters
oOutput stream to write the c++ code to.

Definition at line 3941 of file TDGen.cc.

3941  {
3942  // Register & operation info table initialization
3943 
3944  o << "void" << std::endl
3945  << "GeneratedTCEPlugin::initialize() {" << std::endl;
3946 
3947  // operation names
3948  std::map<std::string, std::string>::const_iterator iter =
3949  opNames_.begin();
3950 
3951  for (; iter != opNames_.end(); iter++) {
3952  o << " opNames_[TCE::" << (*iter).first
3953  << "] = \"" << (*iter).second
3954  << "\";" << std::endl;
3955  }
3956 
3957  for (iter = truePredOps_.begin(); iter != truePredOps_.end(); iter++) {
3958  o << " truePredOps_[TCE::" << (*iter).first
3959  << "] = TCE::" << (*iter).second
3960  << ";" << std::endl;
3961  }
3962 
3963  for (iter = falsePredOps_.begin(); iter != falsePredOps_.end(); iter++) {
3964  o << " falsePredOps_[TCE::" << (*iter).first
3965  << "] = TCE::" << (*iter).second
3966  << ";" << std::endl;
3967  }
3968 
3969  // Register names & indices
3970  std::map<std::string, RegInfo>::const_iterator rIter = regs_.begin();
3971  rIter = regs_.begin();
3972  for (; rIter != regs_.end(); rIter++) {
3973  const RegInfo& regInfo = rIter->second;
3974  o << " regNames_[TCE::" << (*rIter).first
3975  << "] = \"" << regInfo.rf
3976  << "\";" << std::endl;
3977 
3978  o << " regIndices_[TCE::" << (*rIter).first
3979  << "] = " << regInfo.idx
3980  << ";" << std::endl;
3981 
3982  TCEString ttaRegName = regInfo.rf + "." + std::to_string(regInfo.idx);
3983  o << " ttallvmRegMap_[\"" << ttaRegName << "\"] = "
3984  << "TCE::" << (*rIter).first << ";" << std::endl;
3985  }
3986 
3987  // Supported stack access opcodes
3988  o << std::endl;
3989  for (std::string opName : supportedStackAccessOperations(mach_)) {
3990  o << " validStackAccessOperations_.insert(\"" << opName << "\");"
3991  << std::endl;
3992  }
3993 
3994  // Target machine .adf XML string.
3995  o << std::endl;
3996  std::string adfXML;
3997  ADFSerializer serializer;
3998  serializer.setDestinationString(adfXML);
3999  serializer.writeMachine(mach_);
4000  o << " adfXML_ = \"";
4001  for (unsigned int i = 0; i < adfXML.length(); i++) {
4002  if (adfXML[i] == '"') o << "\\\"";
4003  else if (adfXML[i] == '\n') o << "\"\n\"";
4004  else o << adfXML[i];
4005  }
4006  o << "\";" << std::endl;
4007 
4008 
4009  // data address space
4012  std::string asName = "";
4013  for (int i = 0; i < nav.count(); i++) {
4014  if (nav.item(i) != mach_.controlUnit() &&
4015  nav.item(i)->addressSpace() != NULL) {
4016  asName = nav.item(i)->addressSpace()->name();
4017  }
4018  }
4019 
4020  if (asName == "") {
4021  std::string msg = "Couldn't determine data address space.";
4022  throw InvalidData(__FILE__, __LINE__, __func__, msg);
4023  }
4024  o << " dataASName_ = \"" << asName << "\";" << std::endl;
4025 
4026  o << "}" << std::endl;
4027 
4028 
4029  bool hasSDIV = false;
4030  bool hasUDIV = false;
4031  bool hasSREM = false;
4032  bool hasUREM = false;
4033  bool hasMUL = false;
4034  bool hasROTL = false;
4035  bool hasROTR = false;
4036  bool hasSXHW = false;
4037  bool hasSXQW = false;
4038  bool hasSQRTF = false;
4039  bool hasSHR = false;
4040  bool hasSHRU = false;
4041  bool hasSHL = false;
4042  bool has8bitLoads = false;
4043  bool has16bitLoads = false;
4044 // bool has32bitLoads = false; // used only for 64-bit system
4045 
4048 
4049  for (int i = 0; i < fuNav.count(); i++) {
4050  const TTAMachine::FunctionUnit* fu = fuNav.item(i);
4051  for (int o = 0; o < fu->operationCount(); o++) {
4052  const std::string opName =
4054 
4055  if (mach_.is64bit()) {
4056  if (opName == "div64") hasSDIV = true;
4057  if (opName == "divu64") hasUDIV = true;
4058  if (opName == "mod64") hasSREM = true;
4059  if (opName == "modu64") hasUREM = true;
4060  if (opName == "mul64") hasMUL = true;
4061  if (opName == "rotl64") hasROTL = true;
4062  if (opName == "rotr64") hasROTR = true;
4063  if (opName == "sxh64") hasSXHW = true;
4064  if (opName == "sxq64") hasSXQW = true;
4065  if (opName == "shr64") hasSHR = true;
4066  if (opName == "shru64") hasSHRU = true;
4067  if (opName == "shl64") hasSHL = true;
4068  } else {
4069  if (opName == "div") hasSDIV = true;
4070  if (opName == "divu") hasUDIV = true;
4071  if (opName == "mod") hasSREM = true;
4072  if (opName == "modu") hasUREM = true;
4073  if (opName == "mul") hasMUL = true;
4074  if (opName == "rotl") hasROTL = true;
4075  if (opName == "rotr") hasROTR = true;
4076  if (opName == "sxhw") hasSXHW = true;
4077  if (opName == "sxqw") hasSXQW = true;
4078  if (opName == "shr") hasSHR = true;
4079  if (opName == "shru") hasSHRU = true;
4080  if (opName == "shl") hasSHL = true;
4081  }
4082  if (opName == "sqrtf") hasSQRTF = true;
4083 
4084  if (littleEndian_) {
4085  if (opName == "ld16" || opName == "ldu16") {
4086  has16bitLoads = true;
4087  } else if(opName == "ld8" || opName == "ldu8") {
4088  has8bitLoads = true;
4089 // } else if (opName == "ld32" || opName == "ldu32") {
4090 // has32bitLoads = true;
4091  }
4092  } else {
4093  if (opName == "ldh" || opName == "ldhu") {
4094  has16bitLoads = true;
4095  } else if (opName == "ldq" || opName == "ldqu") {
4096  has8bitLoads = true;
4097 // } else if (opName == "ldw") {
4098 // has32bitLoads = true;
4099  }
4100  }
4101  }
4102  }
4103 
4104  o << "bool GeneratedTCEPlugin::hasSDIV() const { return "
4105  << hasSDIV << "; }" << std::endl
4106  << "bool GeneratedTCEPlugin::hasUDIV() const { return "
4107  << hasUDIV << "; }" << std::endl
4108  << "bool GeneratedTCEPlugin::hasSREM() const { return "
4109  << hasSREM << "; }" << std::endl
4110  << "bool GeneratedTCEPlugin::hasUREM() const { return "
4111  << hasUREM << "; }" << std::endl
4112  << "bool GeneratedTCEPlugin::hasMUL() const { return "
4113  << hasMUL << "; }" << std::endl
4114  << "bool GeneratedTCEPlugin::hasROTL() const { return "
4115  << hasROTL << "; }" << std::endl
4116  << "bool GeneratedTCEPlugin::hasROTR() const { return "
4117  << hasROTR << "; }" << std::endl
4118  << "bool GeneratedTCEPlugin::hasSXHW() const { return "
4119  << hasSXHW << "; }" << std::endl
4120  << "bool GeneratedTCEPlugin::hasSXQW() const { return "
4121  << hasSXQW << "; }" << std::endl
4122  << "bool GeneratedTCEPlugin::hasSQRTF() const { return "
4123  << hasSQRTF << "; }" << std::endl
4124  << "bool GeneratedTCEPlugin::hasSHR() const { return "
4125  << hasSHR << "; }" << std::endl
4126  << "bool GeneratedTCEPlugin::hasSHL() const { return "
4127  << hasSHL << "; }" << std::endl
4128  << "bool GeneratedTCEPlugin::hasSHRU() const { return "
4129  << hasSHRU << ";}" << std::endl
4130  << "bool GeneratedTCEPlugin::has8bitLoads() const { return "
4131  << has8bitLoads << ";}" << std::endl
4132  << "bool GeneratedTCEPlugin::has16bitLoads() const { return "
4133  << has16bitLoads << ";}" << std::endl;
4134 // << "bool GeneratedTCEPlugin::has32bitLoads() const { return "
4135 // << has32bitLoads << ";}" << std::endl
4136 
4137  o << "int GeneratedTCEPlugin::maxVectorSize() const { return "
4138  << maxVectorSize_ << "; }" << std::endl;
4139 
4140  // create dummy version here
4142 
4151 
4160 }

References __func__, TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), createBranchAnalysis(), createConstantMaterializationQuery(), createEndiannesQuery(), createMinMaxGenerator(), createParamDRegNums(), createVectorRVDRegNums(), falsePredOps_, TTAMachine::Machine::functionUnitNavigator(), generateLoadStoreCopyGenerator(), genGeneratedTCEPlugin_getAddOpcode(), genGeneratedTCEPlugin_getIorOpcode(), genGeneratedTCEPlugin_getLoadOpcode(), genGeneratedTCEPlugin_getShlOpcode(), genTCEInstrInfoSIMD_copyPhysVectorReg(), genTCERegisterInfo_setReservedVectorRegs(), genTCETargetLoweringSIMD_addVectorRegisterClasses(), genTCETargetLoweringSIMD_associatedVectorRegClass(), genTCETargetLoweringSIMD_getSetCCResultVT(), TDGen::RegInfo::idx, TTAMachine::Machine::is64bit(), TTAMachine::Machine::Navigator< ComponentType >::item(), littleEndian_, mach_, maxVectorSize_, TTAMachine::HWOperation::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), opNames_, regs_, TDGen::RegInfo::rf, XMLSerializer::setDestinationString(), StringTools::stringToLower(), supportedStackAccessOperations(), truePredOps_, writeGetPointerAdjustmentQuery(), and ADFSerializer::writeMachine().

Referenced by generateBackend().

Here is the call graph for this function:

◆ writeBooleanStorePatterns()

void TDGen::writeBooleanStorePatterns ( std::ostream &  os)
protected

Writes special store patterns for i1 types.

Definition at line 4527 of file TDGen.cc.

4527  {
4528  std::string storeOp("");
4529  auto storeOps = littleEndian_
4530  ? std::vector<std::string>{"ST8ri", "ST8rr"}
4531  : std::vector<std::string>{"STQri", "STQrr"};
4532  for (auto op : storeOps) {
4533  if (opNames_.count(op)) {
4534  storeOp = op;
4535  break;
4536  }
4537  }
4538  if (storeOp.empty()) return;
4539 
4540  // TODO: is this 32 correct for 64-bit ADFs?
4541  auto storeConstBit = [=](const std::string& bitVal) -> std::string {
4542  return std::string("(") + storeOp + " ADDRrr:$addr, " +
4543  (storeOp.back() == 'i' ? "(i32 " : "(MOVI32ri ") + bitVal +
4544  "))";
4545  };
4546 
4547  // Patterns to avoid i1 "true" values to be emitted as -1, which breaks
4548  // on, for example, BZ and BNZ if the condition is loaded later, inverted
4549  // using XOR and finally the result is bypassed: this results the -1 to be
4550  // converted to -2, which is interpreted still as true.
4551  os << "def : Pat<(store (i1 -1), ADDRrr:$addr), " << std::endl
4552  << " " << storeConstBit("1") << ">;" << std::endl;
4553  os << "def : Pat<(store (i1 1), ADDRrr:$addr), " << std::endl
4554  << " " << storeConstBit("1") << ">;" << std::endl;
4555  os << "def : Pat<(store (i1 0), ADDRrr:$addr), " << std::endl
4556  << " " << storeConstBit("0") << ">;" << std::endl;
4557 }

References littleEndian_, and opNames_.

Referenced by writeInstrInfo().

◆ writeBroadcastDefs()

void TDGen::writeBroadcastDefs ( std::ostream &  o,
Operation op,
int  vectorLen 
)
protected

◆ writeCallDef()

void TDGen::writeCallDef ( std::ostream &  o)
protected

Writes .td pattern for the call instruction(s) to the output stream.

Definition at line 3899 of file TDGen.cc.

3899  {
3900  o << "let ";
3901 
3902  if (!argRegNames_.empty()) {
3903  o << "Uses = [";
3904  for (unsigned i = 0; i < argRegNames_.size(); i++) {
3905  if (i > 0) o << ", ";
3906  o << argRegNames_[i];
3907  }
3908  o << "],";
3909  }
3910 
3911  o << "hasDelaySlot = 1, isCall = 1,";
3912  o << "Defs = [";
3913 
3914  writeCallDefRegs(o);
3915 
3916  o << "] in {" << std::endl;
3917  o << "def CALL : InstTCE<(outs), (ins calltarget:$dst),";
3918  o << "\"$dst -> call.1;\", []>;" << std::endl;
3919 
3920  o << "def CALL_MEMrr : InstTCE<(outs), (ins MEMrr:$ptr),";
3921  o << "\"$ptr -> call.1;\", [(call ADDRrr:$ptr)]>;" << std::endl;
3922 
3923  o << "def CALL_MEMri : InstTCE<(outs), (ins MEMri:$ptr),";
3924  o << "\"$ptr -> call.1;\", [(call ADDRri:$ptr)]>;" << std::endl;
3925  o << "}" << std::endl;
3926 
3927  o << "def : Pat<(call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;"
3928  << std::endl;
3929 
3930  o << "def : Pat<(call texternalsym:$dst), (CALL texternalsym:$dst)>;"
3931  << std::endl;
3932 
3933 }

References argRegNames_, and writeCallDefRegs().

Referenced by writeControlFlowInstrDefs().

Here is the call graph for this function:

◆ writeCallDefRegs()

void TDGen::writeCallDefRegs ( std::ostream &  o)
protectedvirtual

Definition at line 3524 of file TDGen.cc.

3524  {
3525  for (unsigned i = 0; i < resRegNames_.size(); i++) {
3526  if (i > 0) o << ", ";
3527  o << resRegNames_[i];
3528  }
3529  for (unsigned i = 0; i < gprRegNames_.size(); i++) {
3530  o << ", " << gprRegNames_[i];
3531  }
3532 
3533  // call dest may call others which may mess up these
3534  for (unsigned i = 0; i < argRegNames_.size(); i++) {
3535  o << ", " << argRegNames_[i];
3536  }
3537 
3538  std::map<int, std::vector<RegisterInfo>>::const_iterator it;
3539  for (it = registers_.begin(); it != registers_.end(); ++it) {
3540  int regsWidth = it->first;
3541 
3542  const std::vector<RegisterInfo>& regs = it->second;
3543  TCEString baseClass = baseClasses_.find(regsWidth)->second;
3544 
3545  for (size_t i = 0; i < regs.size(); ++i) {
3546  // Don't declare <=32b registers again, it has been done in TDGen.
3547  if (regsWidth > maxScalarWidth_) {
3548  RegisterInfo reg = regs[i];
3549  o << ", " << reg.regName_;
3550  }
3551  }
3552  }
3553 }

References argRegNames_, baseClasses_, gprRegNames_, maxScalarWidth_, registers_, TDGenerator::RegisterInfo::regName_, and resRegNames_.

Referenced by writeCallDef().

◆ writeCallingConv()

void TDGen::writeCallingConv ( std::ostream &  os)
protected

Writes details about function arguments and returns values.

Parameters
oOutput stream to the file.

Definition at line 6796 of file TDGen.cc.

6796  {
6798 
6799  int bits = mach_.is64bit() ? 64 : 32;
6800  int bytes = mach_.is64bit() ? 8 : 4;
6801  // Function return value types.
6802  os << "// Function return value types." << endl;
6803  os << "def RetCC_TCE : CallingConv<[" << endl;
6804  if (mach_.is64bit()) {
6805  os << " CCIfType<[i1], CCPromoteToType<i64>>," << endl
6806  << " CCIfType<[i32], CCPromoteToType<i64>>," << endl
6807  << " CCIfType<[i64], CCAssignToReg<[IRES0]>>," << endl
6808  << " CCIfType<[f64], CCAssignToReg<[IRES0]>>," << endl << endl;
6809  } else {
6810  os << " CCIfType<[i1], CCPromoteToType<i32>>," << endl;
6811  os << " CCIfType<[i32], CCAssignToReg<[IRES0]>>," << endl;
6812  }
6813 
6814  os << " CCIfType<[f16], CCAssignToReg<[IRES0]>>," << endl
6815  << " CCIfType<[f32], CCAssignToReg<[IRES0]>>," << endl << endl;
6816 
6817  os << " // Vector value types." << endl;
6818  std::map<TCEString, RegisterClass>::const_iterator rcIt;
6819  for (rcIt = vRegClasses_.begin(); rcIt != vRegClasses_.end(); ++rcIt) {
6820  const TCEString& vtStr = rcIt->first;
6821  const RegisterClass& regClass = rcIt->second;
6822 
6823  if (regClass.numberOfRegisters() > 0) {
6824  os << " CCIfType<[" << vtStr << "], CCAssignToReg<[";
6825  if (regClass.valueType().width() <= bits) {
6826  os << "IRES0";
6827  } else {
6828  os << regClass.registerInfo(0).regName_;
6829  }
6830  os << "]>>," << endl;
6831  } else {
6832  verbose("ValueType " + vtStr + " can not be a return value");
6833  }
6834  }
6835 
6836  os << " CCAssignToStack<" << bytes << ", " << bytes << ">" << endl
6837  << "]>;" << endl << endl;
6838 
6839  // Function argument value types.
6840  os << "// Function argument value types." << endl;
6841  os << "def CC_TCE : CallingConv<[" << endl;
6842  if (mach_.is64bit()) {
6843  os << " CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>," << endl
6844  << " CCIfType<[i64], CCAssignToReg<[IRES0]>>," << endl << endl;
6845 
6846  for (unsigned int i = 4; i < (3 + argRegCount_); i++) {
6847  os << " CCIfType<[i64], CCAssignToReg<[A" << i << "]>>," << endl;
6848  }
6849 
6850  } else {
6851  os << " CCIfType<[i1, i8, i16], CCPromoteToType<i32>>," << endl
6852  << " CCIfType<[i32], CCAssignToReg<[IRES0]>>," << endl << endl;
6853 
6854  for (unsigned int i = 4; i < (3 + argRegCount_); i++) {
6855  os << " CCIfType<[i32], CCAssignToReg<[A" << i << "]>>," << endl;
6856  }
6857  }
6858 
6859  if (mach_.is64bit()) {
6860  os << " // 64-bit integer values get stored in stack slots that are"
6861  << endl
6862  << " // 8 bytes insize and 8-byte aligned." << endl
6863  << " CCIfType<[i64, f64, f32], CCAssignToStack<8, 8>>,"
6864  << endl << endl;
6865  } else {
6866  os << " // Integer values get stored in stack slots that are" << endl
6867  << " // 4 bytes insize and 4-byte aligned." << endl
6868  << " CCIfType<[i32, f32], CCAssignToStack<4, 4>>," << endl << endl;
6869  }
6870  os << " // Double values get stored in stack slots that are" << endl
6871  << " // 8 bytes in size and 8-byte aligned." << endl
6872  << " CCIfType<[f64], CCAssignToStack<8, 8>>";
6873 
6874  if (vRegClasses_.size() > 0) {
6875  os << ",";
6876  }
6877  os << endl << endl;
6878 
6879  os << " // Vector value types." << endl;
6880  for (rcIt = vRegClasses_.begin(); rcIt != vRegClasses_.end(); ++rcIt) {
6881  const TCEString& vtStr = rcIt->first;
6882  const RegisterClass& regClass = rcIt->second;
6883 
6884  int byteAlignment = regClass.alignment() / 8;
6885  if (byteAlignment < bytes) {
6886  byteAlignment = bytes;
6887  }
6888 
6889  os << " CCIfType<[" << vtStr << "], CCAssignToStack<"
6890  << byteAlignment << ", " << byteAlignment << ">>";
6891  if (rcIt != --vRegClasses_.end()) {
6892  os << ",";
6893  }
6894  os << endl;
6895  }
6896 
6897  os << "]>;" << endl;
6898 }

References TDGenerator::RegisterClass::alignment(), argRegCount_, TTAMachine::Machine::is64bit(), mach_, TDGenerator::RegisterClass::numberOfRegisters(), TDGenerator::RegisterClass::registerInfo(), TDGenerator::RegisterInfo::regName_, TDGenerator::RegisterClass::valueType(), verbose(), vRegClasses_, TDGenerator::ValueType::width(), and writeCallingConvLicenceText().

Referenced by generateBackend().

Here is the call graph for this function:

◆ writeCallingConvLicenceText()

void TDGen::writeCallingConvLicenceText ( std::ostream &  os)
protected

Definition at line 6901 of file TDGen.cc.

6901  {
6902  os << "//===- GenCallingConv.td - Calling Conventions TCE ---------*- "
6903  << "tablegen -*-===//" << std::endl
6904  << "// " << std::endl
6905  << "// The LLVM Compiler Infrastructure" << std::endl
6906  << "//" << std::endl
6907  << "// This file is distributed under the University of "
6908  << "Illinois Open Source" << std::endl
6909  << "// License. See LICENSE.TXT for details." << std::endl
6910  << "// " << std::endl
6911  << "//===--------------------------------------------------------"
6912  << "--------------===//" << std::endl
6913  << "//" << std::endl
6914  << "// This describes the calling conventions for the TCE "
6915  << "architectures." << std::endl
6916  << "//" << std::endl
6917  << "//===--------------------------------------------------------"
6918  << "--------------===//" << std::endl << std::endl;
6919 }

Referenced by writeCallingConv().

◆ writeCallSeqStart()

void TDGen::writeCallSeqStart ( std::ostream &  os)
protected

Definition at line 7870 of file TDGen.cc.

7870  {
7871 
7872  bool is64bit = mach_.is64bit();
7873 
7874  if (!is64bit) {
7875  os << "def SDT_TCECallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,"
7876  << "SDTCisVT<1, i32> ]>;" << std::endl << std::endl;
7877  } else {
7878  os << "def SDT_TCECallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,"
7879  << "SDTCisVT<1, i64> ]>;" << std::endl << std::endl;
7880  }
7881  os << "def callseq_start : SDNode<\"ISD::CALLSEQ_START\", "
7882  << "SDT_TCECallSeqStart, [SDNPHasChain, SDNPOutGlue]>;" << std::endl
7883  << std::endl
7884  << "let Defs = [SP], Uses = [SP] in {" << std::endl
7885  << "def ADJCALLSTACKDOWN : Pseudo<(outs),";
7886  if (!is64bit) {
7887  os << "(ins i32imm:$amt1, i32imm:$amt2),";
7888  } else {
7889  os << "(ins i64imm:$amt1, i64imm:$amt2),";
7890  }
7891  os << "\"# ADJCALLSTACKDOWN $amt1, $amt2\","
7892  << "[(callseq_start timm:$amt1, timm:$amt2)]>;}"
7893  << std::endl << std::endl;
7894 }

References TTAMachine::Machine::is64bit(), and mach_.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeCondBranchDefs()

void TDGen::writeCondBranchDefs ( std::ostream &  os)
protected

Writes instructions definitions and patterns for conditional branches.

Definition at line 3605 of file TDGen.cc.

3605  {
3606 
3607  auto cuOpset = MachineInfo::getOpset(*mach_.controlUnit());
3608 
3610 
3611  os << std::endl << "let isTerminator = 1, isBranch = 1 in {" << std::endl;
3612 
3613  if (cuOpset.count("JUMP") && opNames_.count("TCEBRCOND") == 0) {
3614  writeInstrDef(os, "TCEBRCOND", "",
3615  "GuardRegs:$gr, brtarget:$dst",
3616  "? $gr $dst -> jump.1;",
3617  "(brcond GuardRegs:$gr, bb:$dst)");
3618  os << std::endl;
3619  opNames_["TCEBRCOND"] = "?jump";
3620  }
3621 
3622  if (cuOpset.count("JUMP") && opNames_.count("TCEBRICOND") == 0) {
3623  writeInstrDef(os, "TCEBRICOND", "",
3624  "GuardRegs:$gr, brtarget:$dst",
3625  "! $gr $dst -> jump.1;",
3626  "(brcond (not GuardRegs:$gr), bb:$dst)");
3627  opNames_["TCEBRICOND"] = "!jump";
3628  }
3629  os << "}" << std::endl;
3630 
3631  // generate brcc pseudo jumps. these are split in llvmtcebuilder into
3632  // separate comparison and jump.
3634 
3635  if (!writePortGuardedJumpDefPair(os, "EQ", "NE")) {
3636  abortWithError("Required eq/ne op not found. please add to adf.");
3637  }
3638  if (!writePortGuardedJumpDefPair(os, "GT", "LE")) {
3639  abortWithError("Required gt/le op not found. please add to adf.");
3640  }
3641  if (!writePortGuardedJumpDefPair(os, "GTU", "LEU")) {
3642  abortWithError("Required gtu/leu op not found. please add to adf.");
3643  }
3644 
3645  // floating point ops are optional.
3646  writePortGuardedJumpDefPair(os, "EQF", "NEF", true);
3647  writePortGuardedJumpDefPair(os, "LEF", "GTF", true);
3648  writePortGuardedJumpDefPair(os, "LTF", "GEF", true);
3649 
3650  if (MachineInfo::supportsPortGuardedJump(mach_, false, "AND")) {
3651  writeInstrDef(os, "AND_JUMP", "",
3652  "R32IRegs:$cmp1, R32IRegs:$cmp2, brtarget:$dst", "",
3653  "(brcond (and R32IRegs:$cmp1, R32IRegs:$cmp2), bb:$dst)");
3654  } else {
3655  std::cerr << "Missing AND operation as true-guard source to jump." << std::endl;
3656  assert(false);
3657  }
3658 
3659  if (MachineInfo::supportsPortGuardedJump(mach_, false, "IOR")) {
3660  writeInstrDef(os, "IOR_JUMP", "",
3661  "R32IRegs:$cmp1, R32IRegs:$cmp2, brtarget:$dst", "",
3662  "(brcond (or R32IRegs:$cmp1, R32IRegs:$cmp2), bb:$dst)");
3663  } else {
3664  std::cerr << "Missing IOR operation as true-guard source to jump." << std::endl;
3665  assert(false);
3666  }
3667 
3668  os << std::endl << "let isTerminator = 1, isBranch = 1 in {" << std::endl;
3669 
3670  // dummy br(i)cond ops
3671  writeInstrDef(os, "TCEBRCOND", "",
3672  "GuardRegs:$gr, brtarget:$dst",
3673  "? $gr $dst -> jump.1;",
3674  "");
3675  os << std::endl;
3676 
3677  writeInstrDef(os, "TCEBRICOND", "",
3678  "GuardRegs:$gr, brtarget:$dst",
3679  "? $gr $dst -> jump.1;",
3680  "");
3681  os << std::endl;
3682 
3683 
3684  os << "}" << std::endl;
3685 
3686  os << "def: Pat<(brcc SETLT, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3687  << " (GT_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3688 
3689 
3690  os << "def: Pat<(brcc SETGE, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3691  << " (LE_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3692 
3693  os << "def: Pat<(brcc SETULT, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3694  << " (GTU_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3695 
3696 
3697  os << "def: Pat<(brcc SETUGE, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3698  << " (LEU_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3699 
3700 
3701  opNames_["AND_JUMP"] = "and+?jump";
3702  opNames_["IOR_JUMP"] = "ior+?jump";
3703 
3704  // conditional jumps without guard.
3705  } else {
3706 
3707  os << std::endl << "let isTerminator = 1, isBranch = 1 in {" << std::endl;
3708 
3709  if (cuOpset.count("BNZ1")) {
3710  // TODO: Check if has R1 regs or not!
3711 
3712  writeInstrDef(os, "TCEBRCOND", "", "R32IRegs:$gr, brtarget:$dst",
3713  "", "(brcond R32IRegs:$gr, bb:$dst)");
3714  os << std::endl;
3715  opNames_["TCEBRCOND"] = "BNZ1";
3716  } else {
3717  if (cuOpset.count("BNZ")) {
3718  writeInstrDef(os, "TCEBRCOND", "", "R32IRegs:$gr, brtarget:$dst",
3719  "", "(brcond R32IRegs:$gr, bb:$dst)");
3720  os << std::endl;
3721  opNames_["TCEBRCOND"] = "BNZ";
3722  } else {
3723  std::cerr << "Does not have guarded jumps or neither bnz or bnz1" << std::endl;
3724  }
3725  }
3726 
3727  if (cuOpset.count("BZ1")) {
3728  // TODO: Check if has R1 regs or not!
3729 
3730  writeInstrDef(os, "TCEBRICOND", "", "R32IRegs:$gr, brtarget:$dst",
3731  "", "(brcond (not R32IRegs:$gr), bb:$dst)");
3732  os << std::endl;
3733  opNames_["TCEBRICOND"] = "BZ1";
3734  } else {
3735  if (cuOpset.count("BZ")) {
3736  writeInstrDef(os, "TCEBRICOND", "", "R32IRegs:$gr, brtarget:$dst",
3737  "", "(brcond (not R32IRegs:$gr), bb:$dst)");
3738  os << std::endl;
3739  opNames_["TCEBRICOND"] = "BZ";
3740  } else {
3741  std::cerr << "Does not have guarded jumps or neither bz or bz1" << std::endl;
3742  }
3743  }
3744 
3745  if (cuOpset.count("BEQ")) {
3746  writeInstrDef(os, "TCEBREQrr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3747  "", "(brcond (i32 (seteq R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3748  opNames_["TCEBREQrr"] = "BEQ";
3749  writeInstrDef(os, "TCEBREQri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3750  "", "(brcond (i32 (seteq R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3751  opNames_["TCEBREQri"] = "BEQ";
3752  }
3753 
3754  if (cuOpset.count("BNE")) {
3755  writeInstrDef(os, "TCEBRNErr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3756  "", "(brcond (i32 (setne R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3757  opNames_["TCEBRNErr"] = "BNE";
3758  writeInstrDef(os, "TCEBRNEri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3759  "", "(brcond (i32 (setne R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3760  opNames_["TCEBRNEri"] = "BNE";
3761  }
3762 
3763  if (cuOpset.count("BGT")) {
3764  writeInstrDef(os, "TCEBRGTrr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3765  "", "(brcond (i32 (setgt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3766  opNames_["TCEBRGTrr"] = "BGT";
3767  writeInstrDef(os, "TCEBRGTri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3768  "", "(brcond (i32 (setgt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3769  opNames_["TCEBRGTri"] = "BGT";
3770  }
3771 
3772  if (cuOpset.count("BGTU")) {
3773  writeInstrDef(os, "TCEBRGTUrr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3774  "", "(brcond (i32 (setugt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3775  opNames_["TCEBRGTUrr"] = "BGTU";
3776  writeInstrDef(os, "TCEBRGTUri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3777  "", "(brcond (i32 (setugt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3778  opNames_["TCEBRGTUri"] = "BGTU";
3779  }
3780 
3781  if (cuOpset.count("BLT")) {
3782  writeInstrDef(os, "TCEBRLTrr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3783  "", "(brcond (i32 (setlt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3784  opNames_["TCEBRLTrr"] = "BLT";
3785  writeInstrDef(os, "TCEBRLTri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3786  "", "(brcond (i32 (setlt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3787  opNames_["TCEBRLTri"] = "BLT";
3788  }
3789 
3790  if (cuOpset.count("BLTU")) {
3791  writeInstrDef(os, "TCEBRLTUrr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3792  "", "(brcond (i32 (setult R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3793  opNames_["TCEBRLTUrr"] = "BLTU";
3794  writeInstrDef(os, "TCEBRLTUri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3795  "", "(brcond (i32 (setult R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3796  opNames_["TCEBRLTUri"] = "BLTU";
3797  }
3798 
3799  if (cuOpset.count("BLE")) {
3800  writeInstrDef(os, "TCEBRLErr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3801  "", "(brcond (i32 (setle R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3802  opNames_["TCEBRLErr"] = "BLE";
3803  writeInstrDef(os, "TCEBRLEri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3804  "", "(brcond (i32 (setle R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3805  opNames_["TCEBRLEri"] = "BLE";
3806  }
3807 
3808  if (cuOpset.count("BLEU")) {
3809  writeInstrDef(os, "TCEBRLEUrr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3810  "", "(brcond (i32 (setule R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3811  opNames_["TCEBRLEUrr"] = "BLEU";
3812  writeInstrDef(os, "TCEBRLEUri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3813  "", "(brcond (i32 (setule R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3814  opNames_["TCEBRLEUri"] = "BLEU";
3815  }
3816 
3817  if (cuOpset.count("BGE")) {
3818  writeInstrDef(os, "TCEBRGErr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3819  "", "(brcond (i32 (setge R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3820  opNames_["TCEBRGErr"] = "BGE";
3821  writeInstrDef(os, "TCEBRGEri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3822  "", "(brcond (i32 (setge R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3823  opNames_["TCEBRGEri"] = "BGE";
3824  }
3825 
3826  if (cuOpset.count("BGEU")) {
3827  writeInstrDef(os, "TCEBRGEUrr", "", "R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3828  "", "(brcond (i32 (setuge R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3829  opNames_["TCEBRGEUrr"] = "BGEU";
3830  writeInstrDef(os, "TCEBRGEUri", "", "R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3831  "", "(brcond (i32 (setuge R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3832  opNames_["TCEBRGEUri"] = "BGEU";
3833  }
3834 
3835  os << "}" << std::endl;
3836  }
3837 }

References abortWithError, assert, TTAMachine::Machine::controlUnit(), MachineInfo::getOpset(), mach_, opNames_, MachineInfo::supportsBoolRegisterGuardedJumps(), MachineInfo::supportsPortGuardedJump(), MachineInfo::supportsPortGuardedJumps(), writeInstrDef(), and writePortGuardedJumpDefPair().

Referenced by writeControlFlowInstrDefs().

Here is the call graph for this function:

◆ writeConstShiftPat()

void TDGen::writeConstShiftPat ( std::ostream &  os,
const TCEString nodeName,
const TCEString opNameBase,
int  i 
)
protected

Definition at line 8503 of file TDGen.cc.

8505  {
8506 
8507  if (!mach_.is64bit()) {
8508  TCEString opName = opNameBase; opName << i << "_32rr";
8509  if (opNames_.find(opName) != opNames_.end()) {
8510  os << "def : Pat<(i32 (" << nodeName
8511  << " R32IRegs:$val, (i32 " << i << "))), ("
8512  << opName << " R32IRegs:$val)>;" << std::endl;
8513  }
8514  } else {
8515  TCEString opName = opNameBase; opName << i << "_64rr";
8516  if (opNames_.find(opName) != opNames_.end()) {
8517  os << "def : Pat<(i64 (" << nodeName
8518  << " R64IRegs:$val, (i64 " << i << "))), ("
8519  << opName << " R64IRegs:$val)>;" << std::endl;
8520  }
8521  }
8522 }

References TTAMachine::Machine::is64bit(), mach_, and opNames_.

Referenced by createConstShiftPatterns().

Here is the call graph for this function:

◆ writeControlFlowInstrDefs()

void TDGen::writeControlFlowInstrDefs ( std::ostream &  os)
protected

Writes control flow instructions definitions and patterns

Definition at line 3560 of file TDGen.cc.

3560  {
3561 
3562  writeCondBranchDefs(os);
3563 
3564  writeCallDef(os);
3565 }

References writeCallDef(), and writeCondBranchDefs().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeEmulationPattern()

void TDGen::writeEmulationPattern ( std::ostream &  o,
const Operation op,
const OperationDAG dag 
)
protected

Writes operation emulation pattern in .td format to an output stream.

Parameters
oOutput stream to write the definition to.
opEmulated operation.
dagEmulation pattern.

Definition at line 4759 of file TDGen.cc.

4762  {
4763 
4764  char operandCh = mach_.is64bit() ? OT_REG_LONG : OT_REG_INT;
4765 
4766  const OperationDAGNode* res = *(dag.endNodes().begin());
4767  if (dag.endNodes().empty()) {
4768  std::cerr << "end nodes of dag for operation: " << op.name()
4769  << " is empty!" << std::endl;
4770  assert(false);
4771  }
4772 
4773  const OperationNode* opNode = dynamic_cast<const OperationNode*>(res);
4774  if (opNode == NULL) {
4775  assert(dag.inDegree(*res) == 1);
4776  const OperationDAGEdge& edge = dag.inEdge(*res, 0);
4777  res = dynamic_cast<OperationNode*>(&dag.tailNode(edge));
4778  assert(res != NULL);
4779  }
4780 
4781  int inputCount = op.numberOfInputs();
4782 
4783  bool ok = true;
4784  std::string llvmPat = llvmOperationPattern(op, operandCh);
4785  if (llvmPat == "") {
4786  std::cerr << "unknown op: " << op.name() << std::endl;
4787  }
4788  assert(llvmPat != "" && "Unknown operation to emulate.");
4789 
4790  boost::format match1(llvmPat);
4791 
4792  int outputs = op.numberOfOutputs();
4793 
4794  std::string operandTypes;
4795  for (int i = 0; i < outputs; i++) {
4796  operandTypes += operandChar(op.operand(i+inputCount + 1));
4797  }
4798 
4799  for (int i = 0; i < op.numberOfInputs(); i++) {
4800  char inputType = operandChar(op.operand(i+1));
4801 
4802  std::string immDef = immediateOperandNameForEmulatedOperation(
4803  dag, op.operand(i + 1));
4804 
4805  operandTypes += inputType;
4806  match1 % operandToString(op.operand(i + 1), false, inputType, immDef);
4807  }
4808  if (ok) {
4809  o << "def : Pat<(" << match1.str() << "), "
4810  << dagNodeToString(op, dag, *res, true, operandTypes)
4811  << ">;" << std::endl;
4812 
4813  // need to generate emulation patterns for boolean out
4814  // for these comparison operations.
4815  if (op.name() == "LTF" || op.name() == "LTUF" ||
4816  op.name() == "EQF" || op.name() == "EQUF" ||
4817  op.name() == "GEF" || op.name() == "GEUF" ||
4818  op.name() == "LEF" || op.name() == "LEUF" ||
4819  op.name() == "GTF" || op.name() == "GTUF" ||
4820  op.name() == "NEF" || op.name() == "NEUF" ||
4821  op.name() == "EQ" || op.name() == "NE" ||
4822  op.name() == "EQ64" || op.name() == "NE64" ||
4823  op.name() == "GE" ||op.name() == "GEU" ||
4824  op.name() == "GE64" ||op.name() == "GEU64" ||
4825  op.name() == "GT" || op.name() == "GTU" ||
4826  op.name() == "GT64" || op.name() == "GTU64" ||
4827  op.name() == "LE" || op.name() == "LEU" ||
4828  op.name() == "LE64" || op.name() == "LEU64" ||
4829  op.name() == "LT" || op.name() == "LTU" ||
4830  op.name() == "LT64" || op.name() == "LTU64" ||
4831  op.name() == "LTD" || op.name() == "LTUD" ||
4832  op.name() == "EQD" || op.name() == "EQUD" ||
4833  op.name() == "GED" || op.name() == "GEUD" ||
4834  op.name() == "LED" || op.name() == "LEUD" ||
4835  op.name() == "GTD" || op.name() == "GTUD" ||
4836  op.name() == "NED" || op.name() == "NEUD" ||
4837  op.name() == "ORDD" || op.name() == "UORDD" ||
4838  op.name() == "ORDF" || op.name() == "UORDF") {
4839  std::string boolOperandTypes = operandTypes;
4840  boolOperandTypes[0] = 'b';
4841  o << "def : Pat<(" << match1.str() << "), "
4842  << dagNodeToString(op, dag, *res, true, boolOperandTypes)
4843  << ">;" << std::endl;
4844  }
4845  }
4846 }

References assert, dagNodeToString(), OperationDAG::endNodes(), immediateOperandNameForEmulatedOperation(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::inEdge(), TTAMachine::Machine::is64bit(), llvmOperationPattern(), mach_, Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), operandChar(), operandToString(), OT_REG_INT, OT_REG_LONG, and BoostGraph< GraphNode, GraphEdge >::tailNode().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeGetPointerAdjustmentQuery()

void TDGen::writeGetPointerAdjustmentQuery ( std::ostream &  os) const
protected

Writes query method for retrieving LLVM instruction for pointer adjustment and suitable offset value.

Some machines may not SUBrri definition (second operand can not take an immediate) and, therefore, pointer adjustments must use other operation for it.

Definition at line 7448 of file TDGen.cc.

7448  {
7449 
7450  TCEString ADDIMM = mach_.is64bit() ? "ADD64ssa" : "ADDrri";
7451  TCEString SUBIMM = mach_.is64bit() ? "SUB64ssa" : "SUBrri";
7452 
7453 
7454 
7455  boost::format queryTmpl(
7456  "// <MI opcode, adjusted offset>\n"
7457  "std::tuple<int, int> GeneratedTCEPlugin::getPointerAdjustment(\n"
7458  " int offset) const {\n"
7459  " if (offset > 0) // Adjust pointer up.\n"
7460  " return std::make_tuple(TCE::%1%, offset);\n"
7461  " else\n"
7462  " return std::make_tuple(TCE::%2%, %3%);\n"
7463  "}\n");
7464 
7465  // Prefer non-negative offset
7466  if (opNames_.count(SUBIMM)) {
7467  os << queryTmpl % ADDIMM % SUBIMM % "-offset" << std::endl;
7468  return;
7469  } else if (opNames_.count("ADDrri")) {
7470  os << queryTmpl % ADDIMM % ADDIMM % "offset" << std::endl;
7471  return;
7472  }
7473 
7475  InvalidData,
7476  "The machine is missing ADD or SUB operation with direct\n"
7477  "immediate source for pointer adjustment operations.");
7478  return;
7479 }

References ADDIMM, TTAMachine::Machine::is64bit(), mach_, opNames_, SUBIMM, and THROW_EXCEPTION.

Referenced by writeBackendCode().

Here is the call graph for this function:

◆ writeGuardRegisterClassInfo()

void TDGen::writeGuardRegisterClassInfo ( std::ostream &  o)
protected

Writes register class for registers usable as guard.

Call this after all regular register definitions are written (after all calls to writeRegisterDef());

Definition at line 1952 of file TDGen.cc.

1952  {
1953 
1954  int bits = mach_.is64bit() ? 64 : 32;
1955  o << std::endl
1956  << "// #################################" << std::endl
1957  << "// Register class definitions for guards" << std::endl;
1958 
1959  if (llvmGuardRegs_.empty()) {
1960  o << "// No guard registers in this machine" << std::endl;
1961  RegInfo reg = {"noGuardReg", 0};
1962  std::string name = "NOGUARD";
1963  writeRegisterDef(o, reg, name, "R1", "", RESERVED);
1964  o << "def " << guardRegTemplateName
1965  << "Regs : RegisterClass<\"TCE\", [i1], " << bits << ", (add "
1966  << name << ")>;" << std::endl;
1967  return;
1968  }
1969 
1970  o << "def " << guardRegTemplateName
1971  << "Regs : RegisterClass<\"TCE\", [i1], " << bits << ", (add ";
1972  bool firstItem = true;
1973  for (auto& regDef : llvmGuardRegs_) {
1974  if (firstItem) {
1975  o << regDef;
1976  firstItem = false;
1977  continue;
1978  }
1979  o << ", " << regDef;
1980  }
1981  o << ")> {" << std::endl;
1982  o << " let Size=" << bits << ";" << std::endl;
1983  o << "}" << std::endl;
1984  o << "// #################################" << std::endl << std::endl;
1985 }

References guardRegTemplateName, TTAMachine::Machine::is64bit(), llvmGuardRegs_, mach_, RESERVED, and writeRegisterDef().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ writeHWLoopDef()

void TDGen::writeHWLoopDef ( std::ostream &  os)
protected

Writes hwloop instructions and patterns.

Definition at line 3571 of file TDGen.cc.

3571  {
3572  os << std::endl << "// Hardware loop instructions" << std::endl;
3573  if (mach_.controlUnit()->hasOperation("hwloop")) {
3574  os << "let isTerminator=1 in {" << std::endl
3575  << " def HWLOOPii : InstTCE<(outs), (ins i32imm0:$rIter, "
3576  "i32imm0:$rInstr), \"\", []>;"
3577  << std::endl
3578  << " def HWLOOPri : InstTCE<(outs), (ins i32imm0:$rIter, "
3579  "i32imm0:$rInstr), \"\", []>;"
3580  << std::endl
3581  << "}" << std::endl
3582  << "def : Pat<(int_set_loop_iterations i32imm0:$rIter), "
3583  "(HWLOOPii i32imm0:$rIter, 0)>;"
3584  << std::endl
3585  << "def : Pat<(int_set_loop_iterations R32IRegs:$rIter), "
3586  "(HWLOOPri R32IRegs:$rIter, 0)>;"
3587  << std::endl;
3588  opNames_["HWLOOPii"] = "hwloop";
3589  opNames_["HWLOOPri"] = "hwloop";
3590  }
3591 
3592  // Write loop jump pseudo
3593  os << "let isTerminator = 1 in {" << std::endl
3594  << " def LJUMP : InstTCE<(outs), (ins brtarget:$dst), \"\", []>;"
3595  << std::endl
3596  << "}" << std::endl
3597  << std::endl;
3598  opNames_["LJUMP"] = "PSEUDO";
3599 }

References TTAMachine::Machine::controlUnit(), TTAMachine::FunctionUnit::hasOperation(), mach_, and opNames_.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeImmediateDef()

void TDGen::writeImmediateDef ( std::ostream &  o,
const std::string &  defName,
const std::string &  operandType,
const std::string &  predicate 
)
protectedvirtual

Writes single immediate operand definitions to the stream.

Parameters
oThe output stream.
defNameThe name of the immediate operand definition.
operandTypeThe target type (i.e "i32").
predicateThe predicate expression without return statement or ';' at the end.

Definition at line 4569 of file TDGen.cc.

4573  {
4574 
4575  o << "def " << defName << " : Operand<" << operandType
4576  << "> , ImmLeaf<" << operandType << ", [{" << std::endl
4577  << " return " << predicate << ";}]>;" << std::endl;
4578 }

Referenced by createConstantMaterializationPatterns(), writeIntegerImmediateDefs(), and writeMoveImmediateDefs().

◆ writeInstrDef()

void TDGen::writeInstrDef ( std::ostream &  o,
const std::string &  instrDefName,
const std::string &  outs,
const std::string &  ins,
const std::string &  asmString,
const std::string &  pattern 
)
protected

Writes LLVM instruction definition in TCE format to the stream.

Definition at line 4585 of file TDGen.cc.

4591  {
4592 
4593  o << "def " << instrDefName << " : InstTCE<" << std::endl
4594  << " (outs " << outs << ")," << std::endl
4595  << " (ins " << ins << ")," << std::endl
4596  << " \"" << asmString << "\", " << std::endl
4597  << " [" << pattern << "]>;" << std::endl;
4598 }

Referenced by writeCondBranchDefs(), and writePortGuardedJumpDefPair().

◆ writeInstrFormats()

void TDGen::writeInstrFormats ( std::ostream &  o)
protected

Writes details about instruction formatting

Parameters
oOutput stream to the file.

Definition at line 4214 of file TDGen.cc.

4214  {
4215  o << "//" << endl;
4216  o << "// TCE Instruction formats." << endl;
4217  o << "//" << endl;
4218  o << "// Only one simple format is currently available" << endl;
4219  o << "//" << endl;
4220  o << "// Automatically generated file, do not edit!" << endl;
4221  o << "//" << endl;
4222  o << "" << endl;
4223  o << "class InstTCE<dag outOps, dag inOps, string asmstr," << endl;
4224  o << " list<dag> pattern = []," << endl;
4225  o << " InstrItinClass itin = IT_FU>" << endl;
4226  o << " : Instruction {" << endl;
4227  o << " let Namespace = \"TCE\";" << endl;
4228  o << " dag InOperandList = inOps;" << endl;
4229  o << " dag OutOperandList = outOps;" << endl;
4230  o << " let AsmString = asmstr;" << endl;
4231  o << " let Pattern = pattern;" << endl;
4232  o << " let Itinerary = itin;" << endl;
4233  o << "}" << endl;
4234  o << "" << endl;
4235  o << "class Pseudo<dag outOps, dag inOps," << endl;
4236  o << " string asmstr, list<dag> pattern>" << endl;
4237  o << " : InstTCE<outOps, inOps, asmstr, pattern>;" << endl;
4238 }

Referenced by generateBackend().

◆ writeInstrInfo()

void TDGen::writeInstrInfo ( std::ostream &  os)
protected

Writes all machine instructions to instruction info .td file.

Parameters
osOutput stream to the file.
Note
This todo marking is from TDGenSIMD

Definition at line 3328 of file TDGen.cc.

3328  {
3329 
3330  writeCallSeqStart(os);
3331 
3335 
3338 
3339  OperationPool opPool;
3340 
3341  for (int i = 0; i < fuNav.count(); i++) {
3342  const TTAMachine::FunctionUnit* fu = fuNav.item(i);
3343  for (int o = 0; o < fu->operationCount(); o++) {
3344  const std::string opName = fu->operation(o)->name();
3345  opNames.insert(StringTools::stringToUpper(opName));
3346  }
3347  }
3348 
3349  if (littleEndian_) {
3350  if (mach_.is64bit()) {
3351  opNames_["ST64fa"] = "ST64";
3352  opNames_["ST64fs"] = "ST64";
3353  opNames_["ST64ha"] = "ST64";
3354  opNames_["ST64hs"] = "ST64";
3355  opNames_["ST64da"] = "ST64";
3356  opNames_["ST64ds"] = "ST64";
3357 
3358  opNames_["LD64fa"] = "LD64";
3359  opNames_["LD64fs"] = "LD64";
3360  opNames_["LD64ha"] = "LD64";
3361  opNames_["LD64hs"] = "LD64";
3362  opNames_["LD64da"] = "LD64";
3363  opNames_["LD64ds"] = "LD64";
3364  }
3365 
3366  if (mach_.hasOperation("LD32")) {
3367  opNames_["LD32fr"] = "LD32";
3368  opNames_["LD32fi"] = "LD32";
3369 
3370  opNames_["LD32hr"] = "LD32";
3371  opNames_["LD32hi"] = "LD32";
3372 
3373  } else if (mach_.hasOperation("LDU32")) {
3374  opNames_["LD32fr"] = "LDU32";
3375  opNames_["LD32fi"] = "LDU32";
3376 
3377  opNames_["LD32hr"] = "LDU32";
3378  opNames_["LD32hi"] = "LDU32";
3379  }
3380  opNames_["ST32fr"] = "ST32";
3381  opNames_["ST32fi"] = "ST32";
3382 
3383  opNames_["ST32hr"] = "ST32";
3384  opNames_["ST32hi"] = "ST32";
3385 
3386  opNames_["ST16hr"] = "ST16";
3387  opNames_["ST16hi"] = "ST16";
3388  } else {
3389  opNames_["LDWfr"] = "LDW";
3390  opNames_["LDWfi"] = "LDW";
3391  opNames_["LDWhr"] = "LDW";
3392  opNames_["LDWhi"] = "LDW";
3393 
3394  opNames_["STWfr"] = "STW";
3395  opNames_["STWfi"] = "STW";
3396 
3397  opNames_["STWhr"] = "STW";
3398  opNames_["STWhi"] = "STW";
3399  opNames_["STHhr"] = "STH";
3400  opNames_["STHhi"] = "STH";
3401  }
3402 
3403  // Some global/address immediate if conversion fails
3404  // so commented out.
3405  // TODO: ^ up-to-date comment? ^
3406  if (hasConditionalMoves_) {
3407 
3408  if (mach_.is64bit()) {
3409  truePredOps_["MOV64ss"] = "PRED_TRUE_MOV64ss";
3410  falsePredOps_["MOV64ss"] = "PRED_FALSE_MOV64ss";
3411  }
3412 
3413  truePredOps_["MOVI32rr"] = "PRED_TRUE_MOVI32rr";
3414  falsePredOps_["MOVI32rr"] = "PRED_FALSE_MOVI32rr";
3415  truePredOps_["MOVI1rr"] = "PRED_TRUE_MOVI1rr";
3416  falsePredOps_["MOVI1rr"] = "PRED_FALSE_MOVI1rr";
3417  }
3418 
3419  OperationDAGSelector::OperationSet::const_iterator iter = opNames.begin();
3420  for (; iter != opNames.end(); iter++) {
3421  OperationDAGSelector::OperationSet::iterator r =
3422  requiredOps.find(*iter);
3423  if (r != requiredOps.end()) {
3424  requiredOps.erase(r);
3425  }
3426  Operation& op = opPool.operation((*iter).c_str());
3427  bool skipPattern = false;
3428 
3429  if (&op == &NullOperation::instance()) {
3430  continue;
3431  }
3432 
3433  // TODO: Allow multioutput (remove last or)
3434  if (!operationCanBeMatched(op)) {
3435  // TODO: write opeation def without graphs
3436  if (&op != &NullOperation::instance()) {
3437  skipPattern = true;
3438  if (Application::verboseLevel() > 0) {
3440  << "Skipped writing operation pattern for "
3441  << op.name() << endl;
3442  }
3443  } else {
3444  // NULL op - ignore
3445  continue;
3446  }
3447  }
3448 
3449  // TODO: remove this. For now MIMO operation patterns are not
3450  // supported by tablegen.
3451  if (op.numberOfOutputs() > 1) {
3452  skipPattern = true;
3453  continue;
3454  }
3455 
3456  if (op.isVectorOperation()) {
3458  writeVectorMemoryOperationDefs(os, op, skipPattern);
3459  } else if (isVectorBitwiseOperation(op)) {
3460  writeVectorBitwiseOperationDefs(os, op, skipPattern);
3461  } else {
3462  writeVectorOperationDefs(os, op, skipPattern);
3463  }
3464  } else {
3465  writeOperationDefs(os, op, skipPattern);
3466  }
3467  }
3468 
3476 
3477  // Call operations.
3479 
3480  // Hardware loop instructions
3481  writeHWLoopDef(os);
3482 
3483  // Emulated operations.
3484  for (iter = requiredOps.begin(); iter != requiredOps.end(); iter++) {
3485  const Operation& op = opPool.operation((*iter).c_str());
3486 
3487  if (&op == &NullOperation::instance()) {
3488  std::string msg = "Required OP '" + *iter + "' not found.";
3489  throw InvalidData(__FILE__, __LINE__, __func__, msg);
3490  }
3491 
3492  const OperationDAGSelector::OperationDAGList emulationDAGs =
3494 
3495  if (emulationDAGs.empty()) {
3498  Application::logStream() << "Warning: Operation '" << *iter
3499  << "' not supported." << endl;
3500  }
3501  } else {
3502  /// @note This todo marking is from TDGenSIMD
3503  // TODO: write all dags of operation (first as normal, the rest
3504  // as pattern)
3505  writeEmulationPattern(os, op, emulationDAGs.smallestNodeCount());
3506  }
3507  }
3508 
3511  if (mach_.is64bit()) {
3513  }
3514 
3516 
3517  writeMiscPatterns(os);
3522 }

References __func__, allOpNames_, TTAMachine::Machine::Navigator< ComponentType >::count(), create32BitExtLoadPatterns(), createBoolAndHalfLoadPatterns(), createByteExtLoadPatterns(), createConstantMaterializationPatterns(), createConstShiftPatterns(), createSelectPatterns(), createShortExtLoadPatterns(), falsePredOps_, OperationDAGSelector::findDags(), TTAMachine::Machine::functionUnitNavigator(), hasConditionalMoves_, TTAMachine::Machine::hasOperation(), immInfo_, NullOperation::instance(), TTAMachine::Machine::is64bit(), isVectorBitwiseOperation(), isVectorLoadOperation(), Operation::isVectorOperation(), isVectorStoreOperation(), TTAMachine::Machine::Navigator< ComponentType >::item(), littleEndian_, LLVMBackend::llvmRequiredOpset(), Application::logStream(), mach_, TTAMachine::HWOperation::name(), Operation::name(), Operation::numberOfOutputs(), OperationPool::operation(), TTAMachine::FunctionUnit::operation(), operationCanBeMatched(), TTAMachine::FunctionUnit::operationCount(), opNames_, OperationDAGSelector::OperationDAGList::smallestNodeCount(), StringTools::stringToUpper(), truePredOps_, Application::VERBOSE_LEVEL_DEFAULT, Application::verboseLevel(), writeBooleanStorePatterns(), writeCallSeqStart(), writeControlFlowInstrDefs(), writeEmulationPattern(), writeHWLoopDef(), writeMiscPatterns(), writeOperationDefs(), writeScalarOperationExploitations(), writeScalarToVectorDefs(), writeVectorBitConversions(), writeVectorBitwiseOperationDefs(), writeVectorImmediateWriteDefs(), writeVectorLoadStoreOperationExploitations(), writeVectorMemoryOperationDefs(), writeVectorOperationDefs(), writeVectorRegisterMoveDefs(), and writeVectorTruncStoreDefs().

Referenced by generateBackend().

Here is the call graph for this function:

◆ writeIntegerImmediateDefs()

void TDGen::writeIntegerImmediateDefs ( std::ostream &  o,
const ImmInfo iivs 
)
protected

Writes unique immediate operands (ImmLeafs) for all operations that can have short immediates to transported to theirs operands.

The names of the immediate operands are stored in i32immOperandDefs_ map. Note: operations, that can not have short immediates to be trasported at all, do not entry in the map.

Parameters
oThe output stream.
iivsThe immediate info.

Definition at line 594 of file TDGen.cc.

596  {
597 
598  TCEString immDefBaseName = mach_.is64bit() ? "i64imm" : "i32imm";
599  TCEString immDefType = mach_.is64bit() ? "i64" : "i32";
600  int bits = mach_.is64bit() ? 64 : 32;
601  using ImmBounds = std::pair<int64_t, int64_t>;
602 
603  OperationPool opPool;
604  std::set<const Operation*> opset;
605  for (auto& iiv : iivs) {
606  const Operation& op = opPool.operation(iiv.first.first.c_str());
607  if (&op == &NullOperation::instance())
608  continue;
609  opset.insert(&op);
610  }
611 
612  std::map<ImmBounds, std::string> immediateClasses;
613  int immId = 0;
614  for (auto op : opset) {
615  // Divide input operands into groups that can be swapped together.
616  // Commutative instructions with immediate operands in the patterns
617  // are defined having the immediate operands as last operands
618  // (e.g. ADDrri). For these a combined ImmLeaf is created (union of
619  // each of ImmLeaf of the inputs).
620  std::vector<std::set<int>> inputGroups;
621  for (int opdIdx = 1; opdIdx < op->numberOfInputs() + 1; opdIdx++) {
622  const Operand& opd = op->operand(opdIdx);
623 
624  bool alreadyGrouped = false;
625  for (auto& group : inputGroups) {
626  if (group.count(opdIdx)) {
627  alreadyGrouped = true;
628  break;
629  }
630  }
631  if (alreadyGrouped) continue;
632 
633  inputGroups.push_back(std::set<int>());
634  inputGroups.back().insert(opdIdx);
635  for (int otherOpdIdx : opd.swap()) {
636  inputGroups.back().insert(otherOpdIdx);
637  }
638  }
639 
640  // For each input operand group assign an ImmLeaf operand definition.
641  // The names of ImmLeaf definitions are stored in immOperandDefs_,
642  // which is accessed using operation and operand as the key.
643  for (auto group : inputGroups) {
644  ImmBounds widestImmBound;
645  for (auto idx : group) {
646  // Determine max transportable immediate value range.
647  if (iivs.count(*op, idx)) {
648  // perform union
649  ImmBounds immBound = iivs.immediateValueBounds(
650  *op, idx, bits);
651  widestImmBound.first = std::min(
652  widestImmBound.first, immBound.first);
653  widestImmBound.second = std::max(
654  widestImmBound.second, immBound.second);
655  }
656  // Can not transport immediates at all.
657  if (widestImmBound == ImmBounds()) continue;
658 
659  // immediateClasses stores unique encountered immediate value
660  // ranges.
661  if (immediateClasses.count(widestImmBound) == 0) {
662  std::string immDefName = std::string("i32imm")
663  + Conversion::toString(immId);
664  if (!mach_.is64bit()) {
665  immediateClasses[widestImmBound] = immDefName;
666  }
668  o, immDefName, "i32", immediatePredicate(
669  widestImmBound.first, widestImmBound.second));
670 
671  immDefName = std::string("i64imm")
672  + Conversion::toString(immId);
673 
674  if (mach_.is64bit()) {
675  immediateClasses[widestImmBound] = immDefName;
676  }
677 
679  o, immDefName, "i64", immediatePredicate(
680  widestImmBound.first, widestImmBound.second));
681 
682  immId++;
683 
684  }
685  immOperandDefs_[ImmInfo::key(*op, idx)] =
686  immediateClasses.at(widestImmBound);
687  }
688  }
689  }
690 }

References immediatePredicate(), immOperandDefs_, NullOperation::instance(), TTAMachine::Machine::is64bit(), ImmInfo::key(), mach_, OperationPool::operation(), Operand::swap(), Conversion::toString(), and writeImmediateDef().

Referenced by writeOperandDefs().

Here is the call graph for this function:

◆ writeMiscPatterns()

void TDGen::writeMiscPatterns ( std::ostream &  o)
protected

Definition at line 8391 of file TDGen.cc.

8391  {
8392  if (!mach_.is64bit()) {
8393  o << "// zero extending moves used in some patterns" << std::endl
8394  << "def ANDext : InstTCE<(outs R32IRegs:$dst), (ins R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8395  << "def PRED_TRUE_ANDext : InstTCE<(outs R32IRegs:$dst),"
8396  << " (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8397  << "def PRED_FALSE_ANDext : InstTCE<(outs R32IRegs:$dst),"
8398  << " (ins R1Regs:$pred, R1Regs:$src, i32imm:$val),\"\", []>;" << std::endl
8399  << "def XORbicmp: InstTCE<(outs R1Regs:$dst),"
8400  << " (ins R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8401  << "def PRED_TRUE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8402  << " (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8403  << "def PRED_FALSE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8404  << " (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl;
8405 
8406  o << "def: Pat <(i32 (anyext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl
8407  << "def: Pat <(i32 (zext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl;
8408 
8409  o << "// select of 1 or 0." << std::endl
8410  << "def : Pat<(i32 (select R1Regs:$c, (i32 1), (i32 0))),"
8411  << " (ANDext R1Regs:$c, 1)>;" << std::endl;
8412 
8413  o << std::endl
8414  << "def: Pat <(i32 (sext R1Regs:$src)), (SUBrir 0,(ANDext R1Regs:$src, 1))>;"
8415  << std::endl;
8416 
8417  o << "// ------ Shift (emulation) patterns. " << std::endl
8418  << "def: Pat <(i32 (shl R32IRegs:$val, (i32 1))),"
8419  << " (ADDrrr R32Regs:$val, R32Regs:$val)>;" << std::endl
8420  << "def: Pat <(i32 (TCESHLConst R32IRegs:$val, (i32 1))),"
8421  << " (ADDrrr R32IRegs:$val, R32IRegs:$val)>;" << std::endl;
8422 
8423  o << "// ----- Global addresses, constant pool entries ------" << std::endl
8424  << "def TCEGlobalAddr : SDNode<\"TCEISD::GLOBAL_ADDR\", SDTIntUnaryOp>;" << std::endl
8425  << "def TCEConstPool : SDNode<\"TCEISD::CONST_POOL\", SDTIntUnaryOp>;" << std::endl
8426  << "def : Pat<(TCEGlobalAddr tglobaladdr:$in), (MOVI32ri tglobaladdr:$in)>;" << std::endl
8427  << "def : Pat<(TCEGlobalAddr tconstpool:$in), (MOVI32ri tconstpool:$in)>;" << std::endl
8428  << "def : Pat<(TCEConstPool tglobaladdr:$in), (MOVI32ri tglobaladdr:$in)>;" << std::endl
8429  << "def : Pat<(TCEConstPool tconstpool:$in), (MOVI32ri tconstpool:$in)>;" << std::endl;
8430 
8431 
8432  o << "// some peephole patterns." << std::endl
8433  << "// 1-bit select with imm values - xor or mov." << std::endl
8434  << "def : Pat<(i1 (select R1Regs:$c, (i1 0), (i1 -1))), (XORbbj R1Regs:$c, 1)>;" << std::endl
8435  << "def : Pat<(i1 (select R1Regs:$c, (i1 -1), (i1 0))), (MOVI1rr R1Regs:$c)>;" << std::endl
8436  << "def : Pat<(i1 (select R1Regs:$c, (i1 -1), R1Regs:$F)), (IORbbb R1Regs:$c, R1Regs:$F)>;" << std::endl
8437  << "def : Pat<(i1 (select R1Regs:$c, R1Regs:$T, (i1 0))), (ANDbbb R1Regs:$c, R1Regs:$T)>;" << std::endl;
8438 
8439  o << "// 1-bit comparison between booleans - xor or xnor(implemented with 2 xors)" << std::endl
8440  << "def : Pat<(i1 (setne R1Regs:$op1, R1Regs:$op2)), (XORbbb R1Regs:$op1, R1Regs:$op2)>;" << std::endl
8441  << "// TODO: should the temp values be converted to i32? usually more i32 regs." << std::endl
8442  << "def : Pat<(i1 (seteq R1Regs:$op1, R1Regs:$op2)), (XORbbj (XORbbb R1Regs:$op1, R1Regs:$op2), 1)>;" << std::endl;
8443 
8444  o << "def TCEBlockAddress : SDNode<\"TCEISD::BLOCK_ADDR\", SDTIntUnaryOp>;" << std::endl
8445  << "def : Pat<(TCEBlockAddress tblockaddress:$src1), (MOVI32ri tblockaddress:$src1)>;" << std::endl;
8446 
8447  } else {
8448  o << "// zero extending moves used in some patterns" << std::endl
8449  << "def ANDext : InstTCE<(outs R64IRegs:$dst),"
8450  << " (ins R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8451  << "def PRED_TRUE_ANDext : InstTCE<(outs R64IRegs:$dst),"
8452  << " (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8453  << "def PRED_FALSE_ANDext : InstTCE<(outs R64IRegs:$dst),"
8454  << " (ins R1Regs:$pred, R1Regs:$src, i64imm:$val),\"\", []>;" << std::endl
8455  << "def XORbicmp: InstTCE<(outs R1Regs:$dst),"
8456  << " (ins R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8457  << "def PRED_TRUE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8458  << " (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8459  << "def PRED_FALSE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8460  << " (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl;
8461 
8462  o << "def: Pat <(i64 (anyext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl
8463  << "def: Pat <(i64 (zext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl;
8464 
8465  o << "// select of 1 or 0." << std::endl
8466  << "def : Pat<(i64 (select R1Regs:$c, (i64 1), (i64 0))), (ANDext R1Regs:$c, 1)>;" << std::endl;
8467 
8468  o << std::endl
8469  << "def: Pat <(i64 (sext R1Regs:$src)), (SUB64sas 0,(ANDext R1Regs:$src, 1))>;"
8470  << std::endl;
8471 
8472  o << "// ------ Shift (emulation) patterns. " << std::endl
8473  << "def: Pat <(i64 (shl R64IRegs:$val, (i64 1))),"
8474  << " (ADD64sss R64Regs:$val, R64Regs:$val)>;" << std::endl
8475  << "def: Pat <(i64 (TCESHLConst R64IRegs:$val, (i64 1))),"
8476  << " (ADD64sss R64IRegs:$val, R64IRegs:$val)>;" << std::endl;
8477 
8478  o << "// ----- Global addresses, constant pool entries ------" << std::endl
8479  << "def TCEGlobalAddr : SDNode<\"TCEISD::GLOBAL_ADDR\", SDTIntUnaryOp>;" << std::endl
8480  << "def TCEConstPool : SDNode<\"TCEISD::CONST_POOL\", SDTIntUnaryOp>;" << std::endl
8481  << "def : Pat<(TCEGlobalAddr tglobaladdr:$in), (MOVI64sa tglobaladdr:$in)>;" << std::endl
8482  << "def : Pat<(TCEGlobalAddr tconstpool:$in), (MOVI64sa tconstpool:$in)>;" << std::endl
8483  << "def : Pat<(TCEConstPool tglobaladdr:$in), (MOVI64sa tglobaladdr:$in)>;" << std::endl
8484  << "def : Pat<(TCEConstPool tconstpool:$in), (MOVI64sa tconstpool:$in)>;" << std::endl;
8485 
8486  o << "// some peephole patterns." << std::endl
8487  << "// 1-bit select with imm values - xor or mov." << std::endl
8488  << "def : Pat<(i1 (select R1Regs:$c, (i1 0), (i1 -1))), (XOR64bbj R1Regs:$c, 1)>;" << std::endl
8489  << "def : Pat<(i1 (select R1Regs:$c, (i1 -1), (i1 0))), (MOVI1rr R1Regs:$c)>;" << std::endl
8490  << "def : Pat<(i1 (select R1Regs:$c, (i1 -1), R1Regs:$F)), (IOR64bbb R1Regs:$c, R1Regs:$F)>;" << std::endl
8491  << "def : Pat<(i1 (select R1Regs:$c, R1Regs:$T, (i1 0))), (AND64bbb R1Regs:$c, R1Regs:$T)>;" << std::endl;
8492 
8493  o << "// 1-bit comparison between booleans - xor or xnor(implemented with 2 xors)" << std::endl
8494  << "def : Pat<(i1 (setne R1Regs:$op1, R1Regs:$op2)), (XOR64bbb R1Regs:$op1, R1Regs:$op2)>;" << std::endl
8495  << "// TODO: should the temp values be converted to i64? usually more i64 regs." << std::endl
8496  << "def : Pat<(i1 (seteq R1Regs:$op1, R1Regs:$op2)), (XOR64bbj (XOR64bbb R1Regs:$op1, R1Regs:$op2), 1)>;" << std::endl;
8497 
8498  o << "def TCEBlockAddress : SDNode<\"TCEISD::BLOCK_ADDR\", SDTIntUnaryOp>;" << std::endl
8499  << "def : Pat<(TCEBlockAddress tblockaddress:$src1), (MOVI64sa tblockaddress:$src1)>;" << std::endl;
8500  }
8501 }

References TTAMachine::Machine::is64bit(), and mach_.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeMoveImmediateDefs()

void TDGen::writeMoveImmediateDefs ( std::ostream &  o)
protected

Writes immediate operand definitions that are used for MOV instructions.

Creates immediate operand definitions for immediate to register instructions (MOVI), that only accept supported immediate values.

Note
Implemented currently only for i32 registers.

Definition at line 701 of file TDGen.cc.

701  {
702  using MCC = MachineConnectivityCheck;
703 
704  TCEString immDefBaseName = mach_.is64bit() ? "i64imm" : "i32imm";
705  TCEString immDefType = mach_.is64bit() ? "i64" : "i32";
706  int bits = mach_.is64bit() ? 64 : 32;
707 
708  std::pair<int64_t, uint64_t> moveImm{ 0, 0 };
709  for (auto& rf : mach_.registerFileNavigator()) {
710  if (rf->width() != bits) continue;
711 
712  for (auto& bus : mach_.busNavigator()) {
713  if (!MCC::busConnectedToRF(*bus, *rf)
714  || bus->immediateWidth() == 0) {
715  continue;
716  }
717 
718  if (bus->immediateWidth() >= bits) {
719  moveImm.first = -(1ll << (bits-1));
720  moveImm.second = (1ll << bits)-1;
721  break;
722  } else {
723  std::pair<int64_t, uint64_t> imm =
724  MathTools::bitsToIntegerRange<int64_t, uint64_t>(
725  bus->immediateWidth(),
726  bus->signExtends());
727 
728  moveImm.first = std::min(moveImm.first, imm.first);
729  moveImm.second = std::max(moveImm.second, imm.second);
730  }
731  }
732  }
733 
734  for (auto& iu : mach_.immediateUnitNavigator()) {
735  for (auto& it : mach_.instructionTemplateNavigator()) {
736  int supportedWidth = it->supportedWidth(*iu);
737  if (supportedWidth >= bits) {
738  moveImm.first = -(1ll << (bits-1));
739  moveImm.second = (1ll << bits)-1;
740  break;
741  } else {
742  std::pair<int64_t, uint64_t> imm =
743  MathTools::bitsToIntegerRange<int64_t, uint64_t>(
744  supportedWidth, iu->signExtends());
745 
746  moveImm.first = std::min(moveImm.first, imm.first);
747  moveImm.second = std::max(moveImm.second, imm.second);
748  }
749  }
750  }
751 
752  writeImmediateDef(o, "i32MoveImm", "i32", immediatePredicate(
753  moveImm.first, moveImm.second));
754 
755  writeImmediateDef(o, "i64MoveImm", "i64", immediatePredicate(
756  moveImm.first, moveImm.second));
757 
758 }

References TTAMachine::Machine::busNavigator(), immediatePredicate(), TTAMachine::Machine::immediateUnitNavigator(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::Machine::is64bit(), mach_, TTAMachine::Machine::registerFileNavigator(), and writeImmediateDef().

Referenced by writeOperandDefs().

Here is the call graph for this function:

◆ writeOperandDefs()

void TDGen::writeOperandDefs ( std::ostream &  o)
protected

Writes all short immediate definitions to the stream.

Parameters
oThe output stream.

Definition at line 566 of file TDGen.cc.

566  {
567  assert(immInfo_ != nullptr
568  && "Short immediate analysis results are not available!");
569 
570  o << "// Immediate definitions for TCE instructions." << std::endl;
571 
573 
574  o << std::endl;
575  o << "// Immediate definitions for immediate to register moves."
576  << std::endl;
578 
579  o << std::endl;
580 }

References assert, immInfo_, writeIntegerImmediateDefs(), and writeMoveImmediateDefs().

Referenced by generateBackend().

Here is the call graph for this function:

◆ writeOperationDef()

void TDGen::writeOperationDef ( std::ostream &  o,
Operation op,
const std::string &  operandTypes,
const std::string &  attrs,
bool  skipPattern,
std::string  backendPrefix = "" 
)
protected

Writes a single operation def for single operation.

Parameters
oOutput stream to write the definition to.
opOperation to write definition for.
operandTypesvalue types of operands.

Definition at line 4608 of file TDGen.cc.

4611  {
4612  assert (operandTypes.size() > 0);
4613 
4614  // Skip definition if the operation has immediate to operand which the
4615  // machine can not transport short immediates to.
4616  if (!areImmediateOperandsLegal(op, operandTypes)) {
4620  << "Skipped writing operation pattern for: "
4621  << op.name() + operandTypes
4622  << ": Can not have immediate operand."
4623  << std::endl;
4624  }
4625  return;
4626  }
4627 
4629 
4630  std::string outputs, inputs, asmstr, pattern;
4631  outputs = "(outs" + patOutputs(op, operandTypes) + ")";
4632  inputs = "(ins " + patInputs(op, operandTypes) + ")";
4633  std::string predicatedInputs =
4634  "(ins GuardRegs:$pred, " +patInputs(op, operandTypes)+ ")";
4635 
4636  asmstr = "\"\"";
4637 
4638  if (!skipPattern) {
4639  if (llvmOperationPattern(op, operandChar) != "" ||
4640  op.dagCount() == 0) {
4641  OperationDAG* trivial = createTrivialDAG(op);
4642  pattern = operationPattern(op, *trivial, operandTypes);
4643  delete trivial;
4644  } else {
4645  auto* dagToUse = getMatchableOperationDAG(op);
4646  if (dagToUse)
4647  pattern = operationPattern(op, *dagToUse, operandTypes);
4648  }
4649  }
4650 
4651  if (attrs != "") {
4652  o << "let" << attrs << " in { " << std::endl;
4653  }
4654 
4655  std::string opcEnum =
4656  StringTools::stringToUpper(op.name()) + operandTypes;
4657 
4658  o << "def " << opcEnum << " : "
4659  << "InstTCE<"
4660  << outputs << ", "
4661  << inputs << ", "
4662  << asmstr << ", " ;
4663  if(operandTypes[0] == 'b') { //instruction can be used for comparison
4664  o << "[" << pattern << "]>"
4665  << std::endl
4666  << "{ let isCompare = 1;}" << std::endl;
4667  } else {
4668  o << "[" << pattern << "]>;"
4669  << std::endl;
4670  }
4671 
4672  bool opCanBePredicated = canBePredicated(op, operandTypes);
4673 
4674  if (opCanBePredicated) {
4675  // write predicated versions
4676  o << "def PRED_TRUE_" << opcEnum << " : "
4677  << "InstTCE<"
4678  << outputs << ", "
4679  << predicatedInputs << ", "
4680  << asmstr << ", "
4681  << "[]>;"
4682  << std::endl;
4683  // write predicated versions
4684  o << "def PRED_FALSE_" << opcEnum << " : "
4685  << "InstTCE<"
4686  << outputs << ", "
4687  << predicatedInputs << ", "
4688  << asmstr << ", "
4689  << "[]>;"
4690  << std::endl;
4691  }
4692 
4693  if (attrs != "") {
4694  o << "}" << std::endl;
4695  }
4696  opNames_[opcEnum] = backendPrefix + op.name();
4697 
4698  if (opCanBePredicated) {
4699  opNames_["PRED_TRUE_" + opcEnum] = "?" + backendPrefix + op.name();
4700  opNames_["PRED_FALSE_" + opcEnum] = "!" + backendPrefix + op.name();
4701  truePredOps_[opcEnum] = "PRED_TRUE_" + opcEnum;
4702  falsePredOps_[opcEnum] = "PRED_FALSE_" + opcEnum;
4703  }
4704 }

References areImmediateOperandsLegal(), assert, canBePredicated(), createTrivialDAG(), Operation::dagCount(), falsePredOps_, getMatchableOperationDAG(), TTAMachine::Machine::is64bit(), llvmOperationPattern(), Application::logStream(), mach_, Operation::name(), operandChar(), operationPattern(), opNames_, OT_REG_INT, OT_REG_LONG, patInputs(), patOutputs(), StringTools::stringToUpper(), truePredOps_, Application::VERBOSE_LEVEL_DEFAULT, and Application::verboseLevel().

Referenced by writeOperationDefs(), and writeVectorOperationDef().

Here is the call graph for this function:

◆ writeOperationDefs() [1/2]

void TDGen::writeOperationDefs ( std::ostream &  o,
Operation op,
bool  skipPattern 
)
protected

Writes scalar operation definition(s).

Parameters
oOutput stream to write the definition to.
opOperation to write definition for.
skipPatternTrue, if skip pattern generation.
Note
This todo marking is from TDGen.
This todo marking is from TDGen.

Definition at line 4271 of file TDGen.cc.

4274  {
4275 
4276  std::string attrs;
4277 
4278  // These white listed operations have mayLoad/mayStore flag
4279  // inferred from the llvm pattern and declaring it
4280  // explicitly will display warning in tablegen.
4281  if (op.name() != "LDQ" && op.name() != "LDQU" &&
4282  op.name() != "LDH" && op.name() != "LDHU" &&
4283  op.name() != "LDW" && op.name() != "LDD" &&
4284  op.name() != "STQ" && op.name() != "STH" &&
4285  op.name() != "STW" && op.name() != "STD" &&
4286  op.name() != "ALDQ" && op.name() != "ALDQU" &&
4287  op.name() != "ALDH" && op.name() != "ALDHU" &&
4288  op.name() != "ALDW" && op.name() != "ALDD" &&
4289  op.name() != "ASTQ" && op.name() != "ASTH" &&
4290  op.name() != "ASTW" && op.name() != "ASTD" &&
4291 
4292  op.name() != "LD8" && op.name() != "LDU8" &&
4293  op.name() != "LD16" && op.name() != "LDU16" &&
4294  op.name() != "LD32" && op.name() != "LDU32" &&
4295  op.name() != "LD64" &&
4296  op.name() != "ST8" && op.name() != "ST16" &&
4297  op.name() != "ST32" && op.name() != "ST64" &&
4298  op.name() != "ALD8" && op.name() != "ALDU8" &&
4299  op.name() != "ALD16" && op.name() != "ALDU16" &&
4300  op.name() != "ALD32" && op.name() != "ALDU32" &&
4301  op.name() != "ALD64" &&
4302  op.name() != "AST8" && op.name() != "AST16" &&
4303  op.name() != "AST32" && op.name() != "AST64" &&
4304  op.name() != "CAS") {
4305 
4306  if (op.readsMemory()) attrs += " mayLoad = 1";
4307  if (op.readsMemory() && op.writesMemory()) attrs += ", ";
4308  if (op.writesMemory()) attrs += " mayStore = 1";
4309  }
4310 
4311  // no bool outs for some operatios
4312  if (op.name() == "CFI" || op.name() == "CFIU") {
4313  writeOperationDef(o, op, "rf", attrs, skipPattern);
4314  return;
4315  }
4316 
4317  if (op.name() == "CDL" || op.name() == "CDLU") {
4318  writeOperationDef(o, op, "sd", attrs, skipPattern);
4319  return;
4320  }
4321 
4322  if (op.name() == "CLD" || op.name() == "CLDU") {
4323  writeOperationDef(o, op, "ds", attrs, skipPattern);
4324  return;
4325  }
4326 
4327  // no bool outs for some operatios
4328  if (op.name() == "CFD") {
4329  writeOperationDef(o, op, "df", attrs, skipPattern);
4330  return;
4331  }
4332 
4333  // no bool outs for some operatios
4334  if (op.name() == "CDF") {
4335  writeOperationDef(o, op, "fd", attrs, skipPattern);
4336  return;
4337  }
4338 
4339  // rotations are allways n x n -> n bits.
4340  if (op.name() == "ROTL" || op.name() == "ROTR" ||
4341  op.name() == "SHL" || op.name() == "SHR" || op.name() == "SHRU") {
4342  writeOperationDefs(o, op, "rrr", attrs, skipPattern);
4343  return;
4344  }
4345 
4346  if (op.name() == "SXHW" || op.name() == "SXQW") {
4347  writeOperationDef(o, op, "rr", attrs, skipPattern);
4348  return;
4349  }
4350 
4351  if (op.name() == "SXW64" || op.name() == "ZXW64") {
4352  writeOperationDef(o, op, "ss", attrs, skipPattern);
4353  return;
4354  }
4355 
4356  // these can have 1-bit inputs
4357  // TODO: this is lacking some 64-bit ops??
4358  if (op.name() == "XOR" || op.name() == "IOR" || op.name() == "AND" ||
4359  op.name() == "ANDN" || op.name() == "ADD" || op.name() == "SUB" ||
4360  op.name() == "XOR64" || op.name() == "IOR64" || op.name() == "AND64") {
4361  writeOperationDefs(o, op, "bbb", attrs, skipPattern);
4362  }
4363 
4364  if (op.name() == "SELECT") {
4365  if (!hasConditionalMoves_) {
4366  writeOperationDef(o, op, "rrrb", attrs, skipPattern);
4367  writeOperationDef(o, op, "riib", attrs, skipPattern);
4368  writeOperationDef(o, op, "rrib", attrs, skipPattern);
4369  writeOperationDef(o, op, "rirb", attrs, skipPattern);
4370  writeOperationDef(o, op, "bbbb", attrs, skipPattern);
4371  writeOperationDef(o, op, "bjjb", attrs, skipPattern);
4372  writeOperationDef(o, op, "bjbb", attrs, skipPattern);
4373  writeOperationDef(o, op, "bbjb", attrs, skipPattern);
4374  // TODO: what about floating-point values?
4375  writeOperationDef(o, op, "fffb", attrs, skipPattern);
4376  writeOperationDef(o, op, "hhhb", attrs, skipPattern);
4377 
4378  // ADFs with boolan values in GPRs
4379  writeOperationDef(o, op, "rrrr", attrs, skipPattern);
4380  writeOperationDef(o, op, "riir", attrs, skipPattern);
4381  writeOperationDef(o, op, "rrir", attrs, skipPattern);
4382  writeOperationDef(o, op, "rirr", attrs, skipPattern);
4383  writeOperationDef(o, op, "bbbr", attrs, skipPattern);
4384  writeOperationDef(o, op, "bjjr", attrs, skipPattern);
4385  writeOperationDef(o, op, "bjbr", attrs, skipPattern);
4386  writeOperationDef(o, op, "bbjr", attrs, skipPattern);
4387  // TODO: what about floating-point values?
4388  writeOperationDef(o, op, "fffr", attrs, skipPattern);
4389  writeOperationDef(o, op, "hhhr", attrs, skipPattern);
4390 
4391  hasSelect_ = true;
4392  return;
4393  } else {
4394  std::cerr << "The target architecture has both"
4395  << "conditional moves and select instruction."
4396  << "Ignoring select and using conditional moves instead"
4397  << std::endl;
4398  return;
4399  }
4400  }
4401 
4402  // store likes this. store immediate to immediate address
4403  if (op.numberOfInputs() == 2 && op.numberOfOutputs() == 0) {
4404  Operand& operand1 = op.operand(1);
4405  Operand& operand2 = op.operand(2);
4406  /// @note This todo marking is from TDGen.
4407  // TODO: add an else branch here for float immediates
4408  if ((operand1.type() == Operand::UINT_WORD ||
4409  operand1.type() == Operand::SINT_WORD ||
4410  operand1.type() == Operand::RAW_DATA) &&
4411  (operand2.type() == Operand::UINT_WORD ||
4412  operand2.type() == Operand::SINT_WORD ||
4413  operand2.type() == Operand::RAW_DATA)) {
4414 
4415  if (mach_.is64bit()) {
4416  writeOperationDef(o, op, "aa", attrs, skipPattern);
4417  } else {
4418  writeOperationDef(o, op, "ii", attrs, skipPattern);
4419  }
4420  }
4421  }
4422 
4423  std::string operandTypes = createDefaultOperandTypeString(op);
4424  // this the ordinary def
4425 
4426  // then try with immediates.
4427  /// @note This todo marking is from TDGen.
4428  // TODO: this should be 2^n loop instead of n loop, to get
4429  // all permutations.
4430 
4431  writeOperationDefs(o, op, operandTypes, attrs, skipPattern);
4432 
4433  // then with boolean outs, and vector versions.
4434  if (op.numberOfOutputs() == 1 && !op.readsMemory()) {
4435  Operand& outOperand = op.operand(op.numberOfInputs()+1);
4436  if (outOperand.type() == Operand::UINT_WORD ||
4437  outOperand.type() == Operand::SINT_WORD ||
4438  outOperand.type() == Operand::ULONG_WORD ||
4439  outOperand.type() == Operand::SLONG_WORD) {
4440 
4441  // 32/64 to 1-bit operations
4442  operandTypes[0] = OT_REG_BOOL;
4443  writeOperationDefs(o, op, operandTypes, attrs, skipPattern);
4444  }
4445 
4446  // create vector versions.
4447  }
4448 }

References createDefaultOperandTypeString(), hasConditionalMoves_, hasSelect_, TTAMachine::Machine::is64bit(), mach_, Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), OT_REG_BOOL, Operand::RAW_DATA, Operation::readsMemory(), Operand::SINT_WORD, Operand::SLONG_WORD, Operand::type(), Operand::UINT_WORD, Operand::ULONG_WORD, writeOperationDef(), and Operation::writesMemory().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeOperationDefs() [2/2]

void TDGen::writeOperationDefs ( std::ostream &  o,
Operation op,
const std::string &  operandTypes,
const std::string &  attrs,
bool  skipPattern,
std::string  backendPrefix = "" 
)
protected

Writes operation defs for single operation, with different immediate params.

Parameters
oOutput stream to write the definition to.
opOperation to write definition for.
operandTypesvalue types of operands.

Definition at line 4475 of file TDGen.cc.

4477  {
4478 
4479  // first without imms.
4480  writeOperationDef(o, op, operandTypes, attrs, skipPattern, backendPrefix);
4481 
4482  for (int i = 0; i < op.numberOfInputs(); i++) {
4483  bool canSwap = false;
4484 
4485  // those ops SHOULD be can-swap but are not. kludge-fix.
4486  // consider making them can-swap.
4487  if (op.name() == "ALDQ" || op.name() == "ALDQU" ||
4488  op.name() == "ALDH" || op.name() == "ALDHU" ||
4489  op.name() == "ALDW" || op.name() == "ALDD" ||
4490  op.name() == "ASTQ" || op.name() == "ASTH" ||
4491  op.name() == "ASTW" || op.name() == "ASTD" ||
4492 
4493  op.name() == "ALD8" || op.name() == "ALDU8" ||
4494  op.name() == "ALD16"|| op.name() == "ALDU16" ||
4495  op.name() == "ALD32"|| op.name() == "ALD64" ||
4496  op.name() == "AST8" || op.name() == "AST16" ||
4497  op.name() == "AST32"|| op.name() == "AST64") {
4498  canSwap = true;
4499  }
4500 
4501  for (int j = i+1 ; j < op.numberOfInputs(); j++) {
4502  if (op.canSwap(i+1, j+1)) {
4503  canSwap = true;
4504  break;
4505  }
4506  }
4507  // setcc of LLVM is not commutative and get confused if we don't generate
4508  // a pattern with immediate elsewhere than the last operand
4509  canSwap = canSwap && !(op.name().upper() == "EQ" || op.name().upper() == "NE");
4510 
4511  if (!canSwap) {
4512  std::string opTypes = operandTypes;
4513  char& c = opTypes[i + op.numberOfOutputs()];
4515  if (c) {
4516  writeOperationDef(o, op, opTypes, attrs, skipPattern, backendPrefix);
4517  }
4518  }
4519  }
4520 }

References Operation::canSwap(), Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), regOperandCharToImmOperandChar(), TCEString::upper(), and writeOperationDef().

Here is the call graph for this function:

◆ writeOperationDefUsingGivenOperandTypes()

void TDGen::writeOperationDefUsingGivenOperandTypes ( std::ostream &  o,
Operation op,
bool  skipPattern,
std::vector< TDGenerator::ValueType inputs,
std::vector< TDGenerator::ValueType outputs,
TCEString  instrSuffix = "" 
)
protected

Writes operation definition using given operand types.

Changes the operands to match the provided ones, after which a definition is written. Finally, original operands are restored.

Parameters
oOutput stream.
opOperation used to create new operation definitions.
skipPatternIf true, operation pattern writing is skipped.
inputsInput operand types for the new operation.
outputsOutput operand types for the new operation.
instrSuffixOptional suffix that will be added to instruction name.

Definition at line 1840 of file TDGen.cc.

1846  {
1847  assert(
1848  inputs.size() == static_cast<size_t>(op.numberOfInputs()) &&
1849  "Given input operand count doesn't match operation's count.");
1850  assert(
1851  outputs.size() == static_cast<size_t>(op.numberOfOutputs()) &&
1852  "Given output operand count doesn't match operation's count.");
1853 
1854  std::vector<ValueType> oldInputs;
1855  std::vector<ValueType> oldOutputs;
1856 
1857  // Change operands to match the provided ones.
1858  for (int i = 0; i < op.numberOfInputs(); ++i) {
1859  Operand& input = op.input(i);
1860  oldInputs.push_back(ValueType(input));
1861 
1862  ValueType vt = inputs[i];
1863  input.setType(vt.operandType());
1864  input.setElementWidth(vt.subwWidth_);
1865  input.setElementCount(vt.subwCount_);
1866  }
1867 
1868  for (int i = 0; i < op.numberOfOutputs(); ++i) {
1869  Operand& output = op.output(i);
1870  oldOutputs.push_back(ValueType(output));
1871 
1872  ValueType vt = outputs[i];
1873  output.setType(vt.operandType());
1874  output.setElementWidth(vt.subwWidth_);
1875  output.setElementCount(vt.subwCount_);
1876  }
1877 
1878  // Write new operation definition.
1879  TCEString types = createDefaultOperandTypeString(op) + instrSuffix;
1880  writeVectorOperationDef(o, op, types, "", skipPattern);
1881 
1882  // Restore old operands.
1883  for (int i = 0; i < op.numberOfInputs(); ++i) {
1884  Operand& input = op.input(i);
1885 
1886  ValueType vt = oldInputs[i];
1887  input.setType(vt.operandType());
1888  input.setElementWidth(vt.subwWidth_);
1889  input.setElementCount(vt.subwCount_);
1890  }
1891 
1892  for (int i = 0; i < op.numberOfOutputs(); ++i) {
1893  Operand& output = op.output(i);
1894 
1895  ValueType vt = oldOutputs[i];
1896  output.setType(vt.operandType());
1897  output.setElementWidth(vt.subwWidth_);
1898  output.setElementCount(vt.subwCount_);
1899  }
1900 }

References assert, createDefaultOperandTypeString(), Operation::input(), Operation::numberOfInputs(), Operation::numberOfOutputs(), TDGenerator::ValueType::operandType(), Operation::output(), Operand::setElementCount(), Operand::setElementWidth(), Operand::setType(), TDGenerator::ValueType::subwCount_, TDGenerator::ValueType::subwWidth_, and writeVectorOperationDef().

Referenced by writeScalarOperationExploitations(), writeVectorBitwiseOperationDefs(), and writeVectorLoadStoreOperationExploitations().

Here is the call graph for this function:

◆ writePatternReplacement()

void TDGen::writePatternReplacement ( std::ostream &  o,
const TCEString origPat,
const TCEString replacerPat 
) const
protected

Writes a pattern fragment definition.

Parameters
origPatPattern that instruction selector should replace.
replacerPatPattern that will replace the original pattern.

Definition at line 1819 of file TDGen.cc.

1822  {
1823  o << "def : Pat<(" << origPat << "), (" << replacerPat << ")>;" << endl;
1824 }

Referenced by writeScalarToVectorDefs(), writeVectorBitConversions(), and writeVectorTruncStoreDefs().

◆ writePortGuardedJumpDefPair()

bool TDGen::writePortGuardedJumpDefPair ( std::ostream &  os,
const TCEString tceop1,
const TCEString tceop2,
bool  fp = false 
)
protected

Definition at line 3841 of file TDGen.cc.

3842  {
3843 
3844  TCEString llvmop1 = TDGen::llvmOperationName(tceop1).upper();
3845  TCEString llvmop2 = TDGen::llvmOperationName(tceop2).upper();
3846 
3847  TCEString regclass = fp ? "R32FPRegs" : "R32IRegs";
3848  if (MachineInfo::supportsPortGuardedJump(mach_, false, tceop1) ||
3850 
3851  os << std::endl << "let isTerminator = 1, isBranch = 1 in {" << std::endl;
3852 
3853  writeInstrDef(os, tceop1+"_JUMP", "",
3854  regclass + ":$cmp1, "+ regclass + ":$cmp2, brtarget:$dst", "",
3855  "(brcc "+ llvmop1 +", "+ regclass + ":$cmp1, " + regclass + ":$cmp2, bb:$dst)");
3856 
3857  os << "}" << std::endl;
3858  if (MachineInfo::supportsPortGuardedJump(mach_, false, tceop1)) {
3859  opNames_[tceop1 + "_JUMP"] = tceop1 + "+?jump";
3860  } else {
3861  opNames_[tceop1 + "_JUMP"] = tceop2 + "+!jump";
3862  }
3863  } else {
3864  std::cerr << "Missing "<< tceop1 << " operation as true-guard source"
3865  << " or " << tceop2 << " operation as invarted guard source to jump." << std::endl;
3866  return false;
3867  }
3868 
3869  if (MachineInfo::supportsPortGuardedJump(mach_, true, tceop1) ||
3870  MachineInfo::supportsPortGuardedJump(mach_, false, tceop2)) {
3871 
3872  os << std::endl << "let isTerminator = 1, isBranch = 1 in {" << std::endl;
3873 
3874 
3875  writeInstrDef(os, tceop2+"_JUMP", "",
3876  regclass + ":$cmp1, "+ regclass + ":$cmp2, brtarget:$dst", "",
3877  "(brcc "+ llvmop2 +", "+ regclass + ":$cmp1, " + regclass + ":$cmp2, bb:$dst)");
3878 
3879  os << "}" << std::endl;
3880 
3881  if (MachineInfo::supportsPortGuardedJump(mach_, false, tceop2)) {
3882  opNames_[tceop2 + "_JUMP"] = tceop2 + "+?jump";
3883  } else {
3884  opNames_[tceop2 + "_JUMP"] = tceop1 + "+!jump";
3885  }
3886  } else {
3887  std::cerr << "Missing " << tceop2 << " operation as true-guard source"
3888  << " or " << tceop1 << " operation as inverted guard source to jump."
3889  << std::endl;
3890  return false;
3891  }
3892  return true;
3893 }

References llvmOperationName(), mach_, opNames_, MachineInfo::supportsPortGuardedJump(), TCEString::upper(), and writeInstrDef().

Referenced by writeCondBranchDefs().

Here is the call graph for this function:

◆ writeRARegisterInfo()

void TDGen::writeRARegisterInfo ( std::ostream &  o)
protected

Writes return address register definition to the output stream.

Definition at line 3101 of file TDGen.cc.

3101  {
3102  o << "class Rra<string n> : TCEReg<n, []>;" << std::endl;
3103  o << "def RA : Rra<\"return-address\">, ";
3104  o << "DwarfRegNum<[" << dregNum_++ << "]>;";
3105  o << std::endl;
3106  if (mach_.is64bit()) {
3107  o << "def RAReg : RegisterClass<\"TCE\", [i64], 64, (add RA)>;" <<
3108  std::endl;
3109  } else {
3110  o << "def RAReg : RegisterClass<\"TCE\", [i32], 32, (add RA)>;" <<
3111  std::endl;
3112  }
3113 }

References dregNum_, TTAMachine::Machine::is64bit(), and mach_.

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ writeRegisterClasses()

void TDGen::writeRegisterClasses ( std::ostream &  o)
protected

Definition at line 761 of file TDGen.cc.

761  {
762 
763  o << "class R1<string n, list<Register> aliases> : TCEReg<n, aliases> {"
764  << "}" << std::endl;
765 
766  o << "class R32<string n, list<Register> aliases> : TCEReg<n, aliases> {"
767  << "}" << std::endl;
768 
769  o << "class R64<string n, list<Register> aliases> : TCEReg<n, aliases> {"
770  << "}" << std::endl;
771 
772 
773  o << "class R16<string n, list<Register> aliases> : TCEReg<n, aliases> {"
774  << "}" << std::endl;
775 }

Referenced by writeRegisterInfo().

◆ writeRegisterDef()

void TDGen::writeRegisterDef ( std::ostream &  o,
const RegInfo reg,
const std::string  regName,
const std::string  regTemplate,
const std::string  aliases,
RegType  type 
)
protected

Writes .td definition of a single register to the output stream.

Parameters
oOutput stream to write the definition to.
regInformation about the physical register.
regNameName for the register in the llvm framework.
regTemplateBase class for the register.
aliasesComma-separated list of aliases for this register.

Definition at line 448 of file TDGen.cc.

454  {
455 
456  std::string templ = regTemplate;
457 
458  o << "def " << regName << " : " << templ
459  << "<\"" << reg.rf << "." << reg.idx
460  << "\", [" << aliases << "]>, DwarfRegNum<"
461  << "[" << dregNum_ << "]>;"
462  << std::endl;
463 
464 
465  if (type == GPR) {
466  gprRegNames_.push_back(regName);
467  } else if (type == ARGUMENT) {
468  argRegNames_.push_back(regName);
469  } else if (type == RESULT) {
470  argRegNames_.push_back(regName);
471  resRegNames_.push_back(regName);
472  } else {
473  assert(type == RESERVED);
474  }
475 
476  regs_[regName] = reg;
477 
478  regsInClasses_[regTemplate].push_back(regName);
479 
480  if (guardedRegs_.find(reg) != guardedRegs_.end()) {
481  llvmGuardRegs_.push_back(regName);
482  regsInClasses_[guardRegTemplateName].push_back(regName);
483  }
484 
485  dregNum_++;
486 }

References argRegNames_, ARGUMENT, assert, dregNum_, GPR, gprRegNames_, guardedRegs_, guardRegTemplateName, TDGen::RegInfo::idx, llvmGuardRegs_, regs_, regsInClasses_, RESERVED, resRegNames_, RESULT, and TDGen::RegInfo::rf.

Referenced by write16bitRegisterInfo(), write1bitRegisterInfo(), write32bitRegisterInfo(), write64bitRegisterInfo(), writeGuardRegisterClassInfo(), and writeVectorRegisterNames().

◆ writeRegisterInfo()

bool TDGen::writeRegisterInfo ( std::ostream &  o)
protected

Writes .td definitions of all registers in the machine to an output stream.

Parameters
oOutput stream for the .td definitions.
Returns
True, if the definitions were succesfully generated.

Definition at line 496 of file TDGen.cc.

496  {
498 
499  if (!checkRequiredRegisters()) {
500  return false;
501  }
502 
504 
505  // Write scalar register information without old vector backend registers.
510 // write16bitRegisterInfo(o); // currently not supported properly
513 
514  // Gather and separate all operations to vector and scalar containers.
516 
517  // Create register classes for vector operands.
519  // Group registers by width.
521  // Associate register groups properly with register classes.
523 
524  // Write register related information to the .td file.
529 
530  return true;
531 }

References analyzeMachineRegisters(), analyzeMachineVectorRegisterClasses(), analyzeRegisters(), assert, associateRegistersWithVectorRegisterClasses(), checkRequiredRegisters(), gatherAllMachineOperations(), regs32bit_, requiredI32Regs_, write1bitRegisterInfo(), write32bitRegisterInfo(), write64bitRegisterInfo(), writeGuardRegisterClassInfo(), writeRARegisterInfo(), writeRegisterClasses(), writeStartOfRegisterInfo(), writeVectorRegisterBaseClasses(), writeVectorRegisterClasses(), and writeVectorRegisterNames().

Referenced by generateBackend().

Here is the call graph for this function:

◆ writeScalarOperationExploitations()

void TDGen::writeScalarOperationExploitations ( std::ostream &  o)
protected

This function writes scalar operation exploitations.

Some scalar operations can be exploited to execute vector operations. For instance, bitwise logical operations are same for any operand width. A 32-bit scalar XOR operation can execute bitwise exclusive OR operation for v32i1, v4i8 and v2i16 vector operands similarly as it does for i32 type.

Definition at line 2419 of file TDGen.cc.

2419  {
2420  o << endl
2421  << endl
2422  << "// Scalar operations exploited to execute small vector operations."
2423  << endl;
2424 
2425  // Use minimal architecture NOT/AND/IOR/XOR 32-bit operations to execute
2426  // bitwise vector operations with operands of 32 bits or lower width.
2427  OperationPool opPool;
2428 
2429  std::vector<Operation*> scalarBitwiseOps;
2430  scalarBitwiseOps.push_back(&opPool.operation("NOT"));
2431  scalarBitwiseOps.push_back(&opPool.operation("AND"));
2432  scalarBitwiseOps.push_back(&opPool.operation("IOR"));
2433  scalarBitwiseOps.push_back(&opPool.operation("XOR"));
2434  scalarBitwiseOps.push_back(&opPool.operation("NOT64"));
2435  scalarBitwiseOps.push_back(&opPool.operation("AND64"));
2436  scalarBitwiseOps.push_back(&opPool.operation("IOR64"));
2437  scalarBitwiseOps.push_back(&opPool.operation("XOR64"));
2438 
2439 
2440  for (size_t opI = 0; opI < scalarBitwiseOps.size(); ++opI) {
2441  Operation& op = *scalarBitwiseOps[opI];
2442  if (&op == &NullOperation::instance() ||
2443  !mach_.hasOperation(op.name())) {
2444  continue;
2445  }
2446 
2447  int width = 2;
2448 
2449  while (width <= op.output(0).width()) {
2450  // Get vector value types for the current width, e.g v4i8, v2i16
2451  // and v32i1 value types for width 32.
2452  std::vector<ValueType> intVecVts =
2453  ValueType::vectorTypesOfWidth(width, true);
2454 
2455  for (size_t i = 0; i < intVecVts.size(); ++i) {
2456  ValueType& vecVt = intVecVts[i];
2457  const TCEString vecVtStr = vecVt.valueTypeStr();
2458 
2459  if (hasRegisterClassSupport(vecVt)) {
2460  std::vector<ValueType> inputs;
2461  std::vector<ValueType> outputs;
2462 
2463  for (int i = 0; i < op.numberOfInputs(); ++i) {
2464  inputs.push_back(vecVt);
2465  }
2466  for (int i = 0; i < op.numberOfOutputs(); ++i) {
2467  outputs.push_back(vecVt);
2468  }
2469 
2471  o, op, false, inputs, outputs, vecVtStr);
2472  }
2473  }
2474 
2475  width *= 2;
2476  }
2477  }
2478 
2479  // Use LDQ/LDH/LDW and STQ/STH/STW operations to create memory access
2480  // operations for vector operands of 32-bit or lower width.
2481  int memDataOpndWidth = 2;
2482 
2483  const char* defaultType = mach_.is64bit() ? "i64" : "i32";
2484 
2485  while (memDataOpndWidth <= MAX_SCALAR_WIDTH) {
2486  std::vector<ValueType> vecVts =
2487  ValueType::vectorTypesOfWidth(memDataOpndWidth);
2488 
2489  for (size_t i = 0; i < vecVts.size(); ++i) {
2490  const ValueType& dataOpndVt = vecVts[i];
2491  const TCEString dataOpndVtStr = dataOpndVt.valueTypeStr();
2492 
2493  if (hasRegisterClassSupport(dataOpndVt)) {
2494  Operation* op = NULL;
2495  if (memDataOpndWidth <= 8) {
2496  if (littleEndian_) {
2497  op = &opPool.operation("LD8");
2498  } else {
2499  op = &opPool.operation("LDQ");
2500  }
2501  } else if (memDataOpndWidth <= 16) {
2502  if (littleEndian_) {
2503  op = &opPool.operation("LD16");
2504  } else {
2505  op = &opPool.operation("LDH");
2506  }
2507  } else if (memDataOpndWidth <= 32){
2508  if (littleEndian_) {
2509  op = &opPool.operation("LD32");
2510  } else {
2511  op = &opPool.operation("LDW");
2512  }
2513  } else {
2514  if (littleEndian_) {
2515  op = &opPool.operation("LD64");
2516  } else {
2517  op = &opPool.operation("LDD");
2518  std::cerr << "Warning: SIMD support with "
2519  << "big-endian adf is deprecated" << std::endl;
2520  }
2521  }
2522 
2523  std::vector<ValueType> inputs;
2524  std::vector<ValueType> outputs;
2525 
2526  // Address operand 32 or 64 bits
2527  inputs.push_back(ValueType(defaultType));
2528  // Data operand.
2529  outputs.push_back(dataOpndVt);
2530 
2532  o, *op, false, inputs, outputs, dataOpndVtStr);
2533  }
2534  }
2535 
2536  for (size_t i = 0; i< vecVts.size(); ++i) {
2537  const ValueType& dataOpndVt = vecVts[i];
2538  const TCEString dataOpndVtStr = dataOpndVt.valueTypeStr();
2539 
2540  if (hasRegisterClassSupport(dataOpndVt)) {
2541  Operation* op = NULL;
2542  if (memDataOpndWidth <= 8) {
2543  if (littleEndian_) {
2544  op = &opPool.operation("ST8");
2545  } else {
2546  op = &opPool.operation("STQ");
2547  }
2548  } else if (memDataOpndWidth <= 16) {
2549  if (littleEndian_) {
2550  op = &opPool.operation("ST16");
2551  } else {
2552  op = &opPool.operation("STH");
2553  }
2554  } else if (memDataOpndWidth <= 32) {
2555  if (littleEndian_) {
2556  op = &opPool.operation("ST32");
2557  } else {
2558  op = &opPool.operation("STW");
2559  }
2560  } else {
2561  if (littleEndian_) {
2562  op = &opPool.operation("ST64");
2563  } else {
2564  op = &opPool.operation("STD");
2565  std::cerr << "Warning: SIMD support with "
2566  << "big-endian adf is deprecated" << std::endl;
2567  }
2568  }
2569 
2570  std::vector<ValueType> inputs;
2571  std::vector<ValueType> outputs;
2572 
2573  // Address operand 32 or 64 bits.
2574  inputs.push_back(ValueType(defaultType));
2575  inputs.push_back(dataOpndVt);
2576  // There is no output operands for store.
2577 
2579  o, *op, false, inputs, outputs, dataOpndVtStr);
2580 
2581  }
2582  }
2583 
2584  memDataOpndWidth *= 2;
2585  }
2586 }

References TTAMachine::Machine::hasOperation(), hasRegisterClassSupport(), NullOperation::instance(), TTAMachine::Machine::is64bit(), littleEndian_, mach_, MAX_SCALAR_WIDTH, Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), OperationPool::operation(), Operation::output(), TDGenerator::ValueType::valueTypeStr(), Operand::width(), and writeOperationDefUsingGivenOperandTypes().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeScalarToVectorDefs()

void TDGen::writeScalarToVectorDefs ( std::ostream &  o) const
protected

Writes scalar_to_vector patterns for vector value types.

Todo:
Add i8 and i16 subword support once those types have RegisterClass support. For now, just skip generation for them.

Definition at line 2332 of file TDGen.cc.

2332  {
2333  o << endl << "// Scalar to vector definitions." << endl;
2334  std::map<TCEString, TCEString>::const_iterator it;
2335  for (it = vbcastOperations_.begin(); it != vbcastOperations_.end();
2336  ++it) {
2337  const TCEString& vtStr = it->first;
2338  const TCEString& vbcastInstr = it->second;
2339 
2340  ValueType scalarVt(vtStr);
2341  scalarVt.subwCount_ = 1; // Change vector type to scalar.
2342  TCEString scalarVtStr = scalarVt.valueTypeStr();
2343 
2344  /// @todo Add i8 and i16 subword support once those types have
2345  /// RegisterClass support. For now, just skip generation for them.
2346  if (scalarVtStr == "f16" || scalarVtStr == "f32" ||
2347  scalarVtStr == "i32") {
2348  TCEString originalPattern =
2349  vtStr + " (scalar_to_vector " + scalarVtStr + ":$in)";
2350  TCEString replacerPattern =
2351  vbcastInstr + " " + scalarVtStr + ":$in";
2352 
2353  writePatternReplacement(o, originalPattern, replacerPattern);
2354  }
2355  }
2356 }

References TDGenerator::ValueType::subwCount_, TDGenerator::ValueType::valueTypeStr(), vbcastOperations_, and writePatternReplacement().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeStartOfRegisterInfo()

void TDGen::writeStartOfRegisterInfo ( std::ostream &  o)
protected

Writes static register info to the beginning of register info .td file.

Parameters
oOutput stream to the file.

Definition at line 539 of file TDGen.cc.

539  {
540  o << "//" << endl;
541  o << "// This file is generated automatically!" << endl;
542  o << "// Do not edit." << endl;
543  o << "//" << endl;
544  o << endl;
545 
546  o << "class TCEReg<string n, list<Register> aliases> : "
547  << "Register<n> {"
548  << endl;
549 
550  o << " let Namespace = \"TCE\";" << endl;
551  o << " let Aliases = aliases;" << endl;
552  o << "}" << endl;
553  o << "class TCEVectorReg<string n, list<Register> subregs> : "
554  << "RegisterWithSubRegs<n, subregs> {"
555  << endl
556  << " let Namespace = \"TCE\";" << endl
557  << "}\n" << endl;
558 }

Referenced by writeRegisterInfo().

◆ writeTopLevelTD()

void TDGen::writeTopLevelTD ( std::ostream &  o)
protected

Writes a top level TCE.td file which includes generated .td definitions.

Parameters
oOutput stream to the file.

Definition at line 4190 of file TDGen.cc.

4190  {
4191  o << "include \"Target.td\"" << std::endl;
4192  o << "include \"TCEItinerary.td\"" << std::endl;
4193  o << "include \"GenRegisterInfo.td\"" << std::endl;
4194  o << "include \"GenTCEInstrFormats.td\"" << std::endl;
4195  o << "include \"TCEInstrInfo.td\"" << std::endl;
4196  o << "include \"GenCallingConv.td\"" << std::endl;
4197  o << "def TCEInstrInfo : InstrInfo { }" << std::endl;
4198  o << "class Proc<string Name, SchedMachineModel Model,";
4199  o << " list<SubtargetFeature> Features>";
4200  o << " : ProcessorModel<Name, Model, Features>;";
4201  o << std::endl;
4202  o << "def : Proc<\"generic\", TCEModelV0,[]>;";
4203  o << std::endl;
4204  o << "def TCE : Target { let InstructionSet = TCEInstrInfo; }"
4205  << std::endl;
4206 }

Referenced by generateBackend().

◆ writeVectorAnyextPattern()

void TDGen::writeVectorAnyextPattern ( std::ostream &  o,
Operation op,
const TCEString loadPatternName,
int  vectorLen 
)
protected

◆ writeVectorBitConversions()

void TDGen::writeVectorBitConversions ( std::ostream &  o) const
protected

Writes bit conversion patterns.

Definition at line 2362 of file TDGen.cc.

2362  {
2363  o << endl << "// Bit conversions between vector types." << endl;
2364 
2365  std::map<TCEString, RegisterClass>::const_iterator it1;
2366  for (it1 = vRegClasses_.begin(); it1 != vRegClasses_.end(); ++it1) {
2367  const TCEString& vtStr1 = it1->first;
2368  const RegisterClass& regClass1 = it1->second;
2369 
2370  std::map<TCEString, RegisterClass>::const_iterator it2;
2371  for (it2 = vRegClasses_.begin(); it2 != vRegClasses_.end(); ++it2) {
2372  const TCEString& vtStr2 = it2->first;
2373  const RegisterClass& regClass2 = it2->second;
2374  if (regClass1.valueType().width() !=
2375  regClass2.valueType().width() ||
2376  vtStr1 == vtStr2) {
2377  continue;
2378  }
2379  const TCEString originalPattern = vtStr2 + " (bitconvert (" +
2380  vtStr1 + " " +
2381  regClass1.name() + ":$src))";
2382  const TCEString replacerPattern =
2383  vtStr2 + " " + regClass2.name() + ":$src";
2384  writePatternReplacement(o, originalPattern, replacerPattern);
2385  }
2386  }
2387 
2388  o << endl << "// Bit conversions to/from i32." << endl;
2389 
2390  // Write i32 -> same size vector type bit conversions.
2391  std::map<TCEString, RegisterClass>::const_iterator it;
2392  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
2393  const TCEString& vtStr = it->first;
2394  const RegisterClass& regClass = it->second;
2395 
2396  if (regClass.valueType().width() == 32 && vtStr != "i32") {
2397  TCEString originalPattern = "i32 (bitconvert (" + vtStr + " " +
2398  regClass.name() + ":$src))";
2399  TCEString replacerPattern = "i32 R32IRegs:$src";
2400  writePatternReplacement(o, originalPattern, replacerPattern);
2401 
2402  originalPattern = vtStr + " (bitconvert (i32 R32IRegs:$src))";
2403  replacerPattern = vtStr + " " + regClass.name() + ":$src";
2404  writePatternReplacement(o, originalPattern, replacerPattern);
2405  }
2406  }
2407 }

References TDGenerator::RegisterClass::name(), TDGenerator::RegisterClass::valueType(), vRegClasses_, TDGenerator::ValueType::width(), and writePatternReplacement().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeVectorBitwiseOperationDefs()

void TDGen::writeVectorBitwiseOperationDefs ( std::ostream &  o,
Operation op,
bool  skipPattern 
)
protected

Writes bitwise NOT/AND/IOR/XOR operation definitions for vector operations.

For 32-bit or less vector widths, 32-bit base operation is used. For bitwise bool vector operations wider than 32 bits, corresponding bitwise operation is searched from the machine, and used to create operation definitions if it exists.

Parameters
oOutput stream.
opOperation used to create bitwise operations.
skipPatternIf true, operation pattern writing is skipped.

Definition at line 2601 of file TDGen.cc.

2602  {
2603  o << endl;
2604 
2605  if (op.numberOfOutputs() == 0) {
2606  assert(false && "Bitwise operation has 0 outputs.");
2607  }
2608 
2609  int opWidth = op.output(0).width();
2610  std::vector<ValueType> vts = ValueType::vectorTypesOfWidth(opWidth);
2611 
2612  for (size_t i = 0; i < vts.size(); ++i) {
2613  const ValueType& vecVt = vts[i];
2614  const TCEString vecVtStr = vecVt.valueTypeStr();
2615 
2616  // Only integer value types are used in bitwise operations.
2617  if (!vecVt.isFloat_ && hasRegisterClassSupport(vecVt)) {
2618  std::vector<ValueType> inputs;
2619  std::vector<ValueType> outputs;
2620 
2621  for (int i = 0; i < op.numberOfInputs(); ++i) {
2622  inputs.push_back(vecVt);
2623  }
2624  for (int i = 0; i < op.numberOfOutputs(); ++i) {
2625  outputs.push_back(vecVt);
2626  }
2627 
2629  o, op, skipPattern, inputs, outputs, vecVtStr);
2630  }
2631  }
2632 
2633  o << endl;
2634 }

References assert, hasRegisterClassSupport(), TDGenerator::ValueType::isFloat_, Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::output(), TDGenerator::ValueType::valueTypeStr(), Operand::width(), and writeOperationDefUsingGivenOperandTypes().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeVectorImmediateWriteDefs()

void TDGen::writeVectorImmediateWriteDefs ( std::ostream &  instrInfoTD)
protected

Definition at line 3160 of file TDGen.cc.

3160  {
3161  for (auto it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
3162  const RegisterClass& regClass = it->second;
3163  TCEString regClassName = regClass.name();
3164  ValueType valType = regClass.valueType();
3165  TCEString valTypeName = valType.valueTypeStr();
3166  if (valType.width() <= 32) {
3167  TCEString opName = "MOVI" + valTypeName;
3168  instrInfoTD << "def " << opName << " : InstTCE<(outs "
3169  << regClassName
3170  << ":$dst), (ins i32imm:$val), \"\",[]>;"
3171  << std::endl;
3172 
3173  opNames_[opName] = "MOVE";
3174  }
3175  }
3176 }

References TDGenerator::RegisterClass::name(), opNames_, TDGenerator::RegisterClass::valueType(), TDGenerator::ValueType::valueTypeStr(), vRegClasses_, and TDGenerator::ValueType::width().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeVectorLoadDefs() [1/2]

void TDGen::writeVectorLoadDefs ( std::ostream &  o,
const TCEString opName,
const TCEString opNameSuffix,
bool  addrImm,
const TCEString resultType,
const TCEString loadPatternName,
bool  writePredicatedVersions 
)
protected

◆ writeVectorLoadDefs() [2/2]

void TDGen::writeVectorLoadDefs ( std::ostream &  o,
Operation op,
const TCEString loadPatternName,
int  vectorLen 
)
protected

◆ writeVectorLoadStoreOperationExploitations()

void TDGen::writeVectorLoadStoreOperationExploitations ( std::ostream &  o)
protected

Attaches load and store operations to vector types that don't have them.

Checks first which vector value types don't have load and store operations for memory accessing. After collecting the value types without load/store, the function tries to search existing load/store instructions whose data operand width matches the vector value type that doesn't have a load/store operation. If the function can find matching memory instructions, it creates new memory instructions for the vector value types by exploiting existing matching memory instructions.

Definition at line 2648 of file TDGen.cc.

2649  {
2650 
2651  const char* defaultTypeStr = mach_.is64bit() ? "i64" : "i32";
2652 
2653  // Value type string of the register class.
2654  std::set<TCEString> withoutLoadOperation;
2655  std::set<TCEString> withoutStoreOperation;
2656 
2657  // Collect all vector value types that are without load or store
2658  // operation support for memory accessing.
2659  std::map<TCEString, RegisterClass>::iterator it;
2660  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
2661  const TCEString vtStr = it->first;
2662  const ValueType vt(vtStr);
2663 
2664  // 32-bit and smaller vectors are covered by LDQ/LDH/LDW/STQ/STH/STW.
2665  // TODO: shoudl this have 64 also for 32-bit ADFs?
2666  if (vt.width() > maxScalarWidth_) {
2667  if (registerLoads_.find(vtStr) == registerLoads_.end()) {
2668  withoutLoadOperation.insert(vtStr);
2669  }
2670 
2671  if (registerStores_.find(vtStr) == registerStores_.end()) {
2672  withoutStoreOperation.insert(vtStr);
2673  }
2674  }
2675  }
2676 
2677  o << endl << "// Define memory operations for vector operands without"
2678  << endl << "// load or store operation definition by exploiting"
2679  << endl << "// existing memory operations of proper width." << endl;
2680 
2681  OperationPool opPool;
2682 
2683  std::set<TCEString>::const_iterator wLoadIt;
2684  for (wLoadIt = withoutLoadOperation.begin();
2685  wLoadIt != withoutLoadOperation.end(); ++wLoadIt) {
2686  const TCEString& dataOpndVtStr = *wLoadIt;
2687  const ValueType vt(dataOpndVtStr);
2688 
2689  bool foundExploitable = false;
2690  std::map<TCEString, InstructionInfo>::const_iterator loadIt =
2691  registerLoads_.begin();
2692 
2693  // Try to find any machine load instruction that is able to load
2694  // equal amount of bytes from memory as the ValueType is wide.
2695  while (!foundExploitable && loadIt != registerLoads_.end()) {
2696  const ValueType loadInstrVt(loadIt->first);
2697 
2698  // If found a match, remove the last two characters of the
2699  // load instruction name to get the OSAL operation name.
2700  if (vt.width() == loadInstrVt.width()) {
2701  foundExploitable = true;
2702  const TCEString opName = (loadIt->second).osalOpName_;
2703  Operation& op = opPool.operation(opName.c_str());
2704 
2705  std::vector<ValueType> inputs;
2706  std::vector<ValueType> outputs;
2707 
2708  // Address operand always 32 or 64 bits.
2709  inputs.push_back(ValueType(defaultTypeStr));
2710  // Data operand.
2711  outputs.push_back(dataOpndVtStr);
2712 
2714  o, op, false, inputs, outputs, dataOpndVtStr);
2715  }
2716 
2717  ++loadIt;
2718  }
2719  }
2720 
2721  std::set<TCEString>::const_iterator wStoreIt;
2722  for (wStoreIt = withoutStoreOperation.begin();
2723  wStoreIt != withoutStoreOperation.end(); ++wStoreIt) {
2724  const TCEString& dataOpndVtStr = *wStoreIt;
2725  const ValueType vt(dataOpndVtStr);
2726 
2727  bool foundExploitable = false;
2728  std::map<TCEString, InstructionInfo>::const_iterator storeIt =
2729  registerStores_.begin();
2730 
2731  // Try to find any machine store instruction that is able to store
2732  // equal amount of bytes to memory as the ValueType is wide.
2733  while (!foundExploitable && storeIt != registerStores_.end()) {
2734  const ValueType storeInstrVt(storeIt->first);
2735 
2736  // If found a match, remove the last two characters of the
2737  // store instruction name to get the OSAL operation name.
2738  if (vt.width() == storeInstrVt.width()) {
2739  foundExploitable = true;
2740  const TCEString opName = (storeIt->second).osalOpName_;
2741  Operation& op = opPool.operation(opName.c_str());
2742 
2743  std::vector<ValueType> inputs;
2744  std::vector<ValueType> outputs;
2745 
2746  // Address operand always i32 or 64 bits.
2747  inputs.push_back(ValueType(defaultTypeStr));
2748  inputs.push_back(dataOpndVtStr);
2749  // There is no output operands for store.
2750 
2752  o, op, false, inputs, outputs, dataOpndVtStr);
2753  }
2754 
2755  ++storeIt;
2756  }
2757  }
2758 
2759  o << endl;
2760 }

References TTAMachine::Machine::is64bit(), mach_, maxScalarWidth_, OperationPool::operation(), registerLoads_, registerStores_, vRegClasses_, TDGenerator::ValueType::width(), and writeOperationDefUsingGivenOperandTypes().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeVectorMemoryOperationDefs()

void TDGen::writeVectorMemoryOperationDefs ( std::ostream &  o,
Operation op,
bool  skipPattern 
)
protected

Writes instruction definitions for memory vector operations.

Subword aligned LDQ/LDH/LDW/STQ/STH/STQ vector operations can be passed directly to writing vector operation definitions, but vector aligned LOAD and STORE operations can be used for several different vector types of the same width, thus, all the different vector types need to be covered and separate memory instruction have to be made for them.

Definition at line 2205 of file TDGen.cc.

2206  {
2207  abortWithError("WiP");
2208 }

References abortWithError.

Referenced by writeInstrInfo().

◆ writeVectorOperationDef()

void TDGen::writeVectorOperationDef ( std::ostream &  o,
Operation op,
TCEString  valueTypes,
const TCEString attributes,
bool  skipPattern 
)
protected

Writes instruction of the vector operation to the .td file.

Creates register version and possibly an immediate version of the vector operation in case there are any scalar operands.

Parameters
oOutput stream to the file.
opOperation to be written as an instruction to the .td file.
valueTypesOperand value type identifier characters.
attributesOperation attributes.
skipPatternTrue, if skip pattern creation.

Definition at line 2125 of file TDGen.cc.

2127  {
2128  // Make sure operation's operands are fully supported by
2129  // vector register classes.
2130  if (!hasRegisterClassSupport(op)) {
2131  verbose(
2132  "Warning: " + op.name() + valueTypes +
2133  " was not created due to unsupported operands.");
2134  return;
2135  }
2136 
2137  // Write register version of the operation.
2138  TDGen::writeOperationDef(o, op, valueTypes, attributes, skipPattern);
2139 
2140  // Information of some operations is needed later, save it if needed.
2141  saveAdditionalVectorOperationInfo(op, valueTypes, true);
2142 
2143  // Create the same instruction with immediate inputs if there are
2144  // any input operands that are scalars.
2145  bool scalarsFound = false;
2146  for (int i = op.numberOfOutputs(); i < op.operandCount(); ++i) {
2147  char& c = valueTypes[i];
2148  switch (c) {
2149  case OT_REG_BOOL:
2150  c = OT_IMM_BOOL;
2151  scalarsFound = true;
2152  break;
2153  case OT_REG_INT:
2154  c = OT_IMM_INT;
2155  scalarsFound = true;
2156  break;
2157  case OT_REG_FP:
2158  c = OT_IMM_FP;
2159  scalarsFound = true;
2160  break;
2161  case OT_REG_HFP:
2162  c = OT_IMM_HFP;
2163  scalarsFound = true;
2164  break;
2165  default:
2166  continue;
2167  }
2168  }
2169 
2170  if (scalarsFound) {
2171  // Write immediate version of the operation.
2172  TDGen::writeOperationDef(o, op, valueTypes, attributes, skipPattern);
2173 
2174  // Information of some immediate versions are needed also.
2175  saveAdditionalVectorOperationInfo(op, valueTypes, false);
2176  }
2177 }

References hasRegisterClassSupport(), Operation::name(), Operation::numberOfOutputs(), Operation::operandCount(), OT_IMM_BOOL, OT_IMM_FP, OT_IMM_HFP, OT_IMM_INT, OT_REG_BOOL, OT_REG_FP, OT_REG_HFP, OT_REG_INT, saveAdditionalVectorOperationInfo(), verbose(), and writeOperationDef().

Referenced by writeOperationDefUsingGivenOperandTypes().

Here is the call graph for this function:

◆ writeVectorOperationDefs()

void TDGen::writeVectorOperationDefs ( std::ostream &  o,
Operation op,
bool  skipPattern 
)
protected

Writes needed defitinion(s) of the vector operation to the .td file.

Creates 4 differend instructions of the operation at most:

  • Integer version (register)
  • Integer version (immediate)
  • Float/half float version (register)
  • Float/half float version (immediate)
Parameters
oOutput stream to the .td file.
opVector operation of which the definitions will be created.
skipPatternTrue, if skip pattern creation.

Definition at line 2108 of file TDGen.cc.

2108  {
2109  abortWithError("WiP");
2110 }

References abortWithError.

Referenced by writeInstrInfo().

◆ writeVectorRegisterBaseClasses()

void TDGen::writeVectorRegisterBaseClasses ( std::ostream &  o) const
protected

Writes base class definitions to the .td file.

Definition at line 1991 of file TDGen.cc.

1991  {
1992  o << endl
1993  << "// #################################" << endl
1994  << "// Vector register base class definitions" << endl;
1995 
1996  std::map<int, TCEString>::const_iterator bcIt;
1997  for (bcIt = baseClasses_.begin(); bcIt != baseClasses_.end(); ++bcIt) {
1998  int width = bcIt->first;
1999 
2000  if (width > MAX_SCALAR_WIDTH) {
2001  TCEString baseClassName = bcIt->second;
2002  o << "class " << baseClassName
2003  << "<string n, list<Register> aliases> : "
2004  << "TCEVectorReg<n, aliases> {}" << endl;
2005  }
2006  }
2007  o << "// #################################" << endl;
2008 }

References baseClasses_, and MAX_SCALAR_WIDTH.

Referenced by writeRegisterInfo().

◆ writeVectorRegisterClasses()

void TDGen::writeVectorRegisterClasses ( std::ostream &  o) const
protected

Writes register class definitions to the .td file.

Definition at line 2046 of file TDGen.cc.

2046  {
2047  o << endl
2048  << "// #################################" << endl
2049  << "// Register class definitions for vector registers" << endl;
2050 
2051  std::map<TCEString, RegisterClass>::const_iterator it;
2052  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
2053  const TCEString& vtStr = it->first;
2054  const RegisterClass& regClass = it->second;
2055 
2056  if (regClass.numberOfRegisters() == 0) {
2057  std::string msg =
2058  std::string("The machine is missing registers for ") +
2059  regClass.valueType().valueTypeStr() + " operands" +
2060  " required by some operation(s).";
2061 
2062  std::cerr << "Error: Illegal machine: " << msg << std::endl;
2064  }
2065 
2066  o << "def " << regClass.name() << " : "
2067  << "RegisterClass<\"TCE\", "
2068  << "[" << vtStr << "], " << regClass.alignment() << ", (add ";
2069 
2070  // Add registers to the register class.
2071  for (size_t i = 0; i < regClass.numberOfRegisters(); ++i) {
2072  const RegisterInfo& reg = regClass.registerInfo(i);
2073  o << reg.regName_;
2074 
2075  if (i != regClass.numberOfRegisters() - 1) {
2076  o << ", ";
2077  }
2078  }
2079  o << ")> ";
2080 
2081  // Register classes below 8 bit of total width need to be set as
2082  // "8 bit of size" so that when they are spilled to stack, the
2083  // byte size of the register class is at least 1.
2084  if (regClass.valueType().width() < 8) {
2085  o << "{" << endl << " let Size=8;" << endl << "}" << endl;
2086  } else {
2087  o << ";" << endl;
2088  }
2089  }
2090 
2091  o << "// #################################" << endl;
2092 }

References TDGenerator::RegisterClass::alignment(), TDGenerator::RegisterClass::name(), TDGenerator::RegisterClass::numberOfRegisters(), TDGenerator::RegisterClass::registerInfo(), TDGenerator::RegisterInfo::regName_, THROW_EXCEPTION, TDGenerator::RegisterClass::valueType(), TDGenerator::ValueType::valueTypeStr(), vRegClasses_, and TDGenerator::ValueType::width().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ writeVectorRegisterMoveDefs()

void TDGen::writeVectorRegisterMoveDefs ( std::ostream &  o)
protected

Writes MOV instructions between vector register classes.

Definition at line 2214 of file TDGen.cc.

2214  {
2215  o << endl
2216  << "// Vector register->register move definitions." << endl
2217  << "let isAsCheapAsAMove = 1 in {" << endl;
2218 
2219  std::map<TCEString, RegisterClass>::const_iterator it;
2220  for (it = vRegClasses_.begin(); it != vRegClasses_.end(); ++it) {
2221  const RegisterClass& regClass = it->second;
2222 
2223  const TCEString opcode = "MOV" + regClass.name();
2224  const TCEString vtStr = regClass.valueType().valueTypeStr();
2225 
2226  const TCEString outs = "(outs " + regClass.name() + ":$dst), ";
2227  const TCEString ins = "(ins " + regClass.name() + ":$src), ";
2228  const TCEString insPred =
2229  "(ins GuardRegs:$pred, " + regClass.name() + ":$src), ";
2230  const TCEString asmOp = "\"$src -> $dst;\", []";
2231 
2232  o << "def " << opcode << " : "
2233  << "InstTCE<" << outs << ins << asmOp << ">;" << endl;
2234 
2235  opNames_[opcode] = opcode;
2236  movOperations_.insert(opcode);
2237 
2238  if (hasConditionalMoves_) {
2239  o << "def PRED_TRUE_" << opcode << " : "
2240  << "InstTCE<" << outs << insPred << asmOp << ">;" << endl;
2241 
2242  o << "def PRED_FALSE_" << opcode << " : "
2243  << "InstTCE<" << outs << insPred << asmOp << ">;" << endl;
2244 
2245  opNames_["PRED_TRUE_" + opcode] = "?" + opcode;
2246  opNames_["PRED_FALSE_" + opcode] = "!" + opcode;
2247  truePredOps_[opcode] = "PRED_TRUE_" + opcode;
2248  falsePredOps_[opcode] = "PRED_TRUE_" + opcode;
2249 
2250  movOperations_.insert("PRED_TRUE_" + opcode);
2251  movOperations_.insert("PRED_FALSE_" + opcode);
2252  }
2253  }
2254 
2255  o << "}" << endl;
2256 }

References falsePredOps_, hasConditionalMoves_, movOperations_, TDGenerator::RegisterClass::name(), opNames_, truePredOps_, TDGenerator::RegisterClass::valueType(), TDGenerator::ValueType::valueTypeStr(), and vRegClasses_.

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeVectorRegisterNames()

void TDGen::writeVectorRegisterNames ( std::ostream &  o)
protected

Writes register definitions to the .td file.

Definition at line 2014 of file TDGen.cc.

2014  {
2015  o << endl
2016  << "// #################################" << endl
2017  << "// Register name definitions for vector registers" << endl;
2018 
2019  std::set<TCEString> declaredRegNames;
2020 
2021  std::map<int, std::vector<RegisterInfo>>::const_iterator it;
2022  for (it = registers_.begin(); it != registers_.end(); ++it) {
2023  int regsWidth = it->first;
2024 
2025  const std::vector<RegisterInfo>& regs = it->second;
2026  TCEString baseClass = baseClasses_.find(regsWidth)->second;
2027 
2028  for (size_t i = 0; i < regs.size(); ++i) {
2029  // Don't declare <=32b registers again, it has been done in TDGen.
2030  if (regsWidth > MAX_SCALAR_WIDTH) {
2031  RegisterInfo reg = regs[i];
2032  RegInfo oldRegInfo = {reg.regFileName_, reg.regIndex_};
2034  o, oldRegInfo, reg.regName_, baseClass, "", RESERVED);
2035  declaredRegNames.insert(reg.regName_);
2036  }
2037  }
2038  }
2039  o << "// #################################" << endl;
2040 }

References baseClasses_, MAX_SCALAR_WIDTH, TDGenerator::RegisterInfo::regFileName_, TDGenerator::RegisterInfo::regIndex_, registers_, TDGenerator::RegisterInfo::regName_, RESERVED, and writeRegisterDef().

Referenced by writeRegisterInfo().

Here is the call graph for this function:

◆ writeVectorStoreDefs() [1/2]

void TDGen::writeVectorStoreDefs ( std::ostream &  o,
const TCEString opName,
const TCEString opNameSuffix,
bool  addrImm,
const TCEString dataType,
bool  writePredicatedVersions 
)
protected

◆ writeVectorStoreDefs() [2/2]

void TDGen::writeVectorStoreDefs ( std::ostream &  o,
Operation op,
int  vectorLen 
)
protected

◆ writeVectorTruncStoreDefs() [1/2]

void TDGen::writeVectorTruncStoreDefs ( std::ostream &  o) const
protected

Writes truncstore patterns for vector value types.

Definition at line 2262 of file TDGen.cc.

2262  {
2263  o << endl << "// Vector truncstore definitions, needed below." << endl;
2264 
2265  // Create truncstore definitions for vector value types, there has to
2266  // exist store operations for the same value type that the TRUNC
2267  // operation has. For example, in order to create truncstore using
2268  // TRUNCWH16X4, there has to be store operations in the machine that
2269  // supports storing v4i16 value type.
2270 
2271  std::map<TCEString, RegisterClass>::const_iterator rcIt;
2272  for (rcIt = vRegClasses_.begin(); rcIt != vRegClasses_.end(); ++rcIt) {
2273  o << "def truncstore" << rcIt->first << " : "
2274  << "PatFrag<(ops node:$val, node:$ptr),"
2275  << "(truncstore node:$val, node:$ptr), "
2276  << "[{return cast<StoreSDNode>(N)->getMemoryVT() == "
2277  << "MVT::" << rcIt->first << ";}]>;" << endl;
2278  }
2279  // Create patterns which will replace "truncstore" pattern with separate
2280  // TRUNC and then STORE operations.
2281 
2282  o << endl << "// Pattern definitions for truncstores." << endl;
2283  std::vector<std::pair<const Operation*, TCEString>>::const_iterator it;
2284  for (it = truncOperations_.begin(); it != truncOperations_.end(); ++it) {
2285  const TCEString& truncInstr = it->second;
2286  const TCEString& vtFromStr =
2287  ValueType::valueTypeStr(it->first->input(0));
2288  const TCEString targetVtStr =
2289  ValueType::valueTypeStr(it->first->output(0));
2290 
2291  std::map<TCEString, InstructionInfo>::const_iterator regStoreIt =
2292  registerStores_.find(targetVtStr);
2293 
2294  // Use register version of store operations.
2295  if (regStoreIt != registerStores_.end()) {
2296  const TCEString& regStoreInstr = (regStoreIt->second).instrName_;
2297  const TCEString originalPattern = "truncstore" + targetVtStr +
2298  " " + vtFromStr +
2299  ":$op2, ADDRrr:$op1";
2300  const RegisterClass& regClass =
2301  vRegClasses_.find(vtFromStr)->second;
2302  const TCEString replacerPattern =
2303  regStoreInstr + " ADDRrr:$op1, (" + truncInstr + " " +
2304  regClass.name() + ":$op2)";
2305 
2306  writePatternReplacement(o, originalPattern, replacerPattern);
2307  }
2308 
2309  std::map<TCEString, InstructionInfo>::const_iterator immStoreIt =
2310  immediateStores_.find(targetVtStr);
2311 
2312  // Use immediate version of store operations.
2313  if (immStoreIt != immediateStores_.end()) {
2314  const TCEString& immStoreInstr = (immStoreIt->second).instrName_;
2315  const TCEString originalPattern = "truncstore" + targetVtStr +
2316  " " + vtFromStr +
2317  ":$op2, ADDRri:$op1";
2318  const RegisterClass& regClass =
2319  vRegClasses_.find(vtFromStr)->second;
2320  const TCEString replacerPattern =
2321  immStoreInstr + " ADDRri:$op1, (" + truncInstr + " " +
2322  regClass.name() + ":$op2)";
2323  writePatternReplacement(o, originalPattern, replacerPattern);
2324  }
2325  }
2326 }

References immediateStores_, TDGenerator::RegisterClass::name(), registerStores_, truncOperations_, vRegClasses_, and writePatternReplacement().

Referenced by writeInstrInfo().

Here is the call graph for this function:

◆ writeVectorTruncStoreDefs() [2/2]

void TDGen::writeVectorTruncStoreDefs ( std::ostream &  o,
Operation op,
int  bitsize,
int  vectorLen 
)
protected

◆ writeWiderVectorOperationExploitations()

void TDGen::writeWiderVectorOperationExploitations ( std::ostream &  o)
protected

Writes vector operation definitions that exploit bigger vector operations.

Exploited vector operands are written in ascending order by their subword count, meaning that e.g. ADD32X16, ADD32X32, and ADD32X4 operation exploitations are listed so that ADD32X4 are written first, then ADD32X16, and then ADD32X32. This way the instruction selection will first use ADD32X4 to execute vector addition for v2i32 vector operand types, and thus, is more optimal solution than executing the same v2i32 addition with ADD32X16 (though ADD32X4 would be also available in the machine).

Definition at line 2775 of file TDGen.cc.

2775  {
2776  abortWithError("WiP");
2777 }

References abortWithError.

Member Data Documentation

◆ addOperations_

std::map<TCEString, TCEString> TDGen::addOperations_
protected

Contains machine's add instructions (<ValueType, InstrName>).

Definition at line 564 of file TDGen.hh.

Referenced by genGeneratedTCEPlugin_getAddOpcode().

◆ allOpNames_

OperationDAGSelector::OperationSet TDGen::allOpNames_
protected

Contains all operation names in upper case.

Definition at line 505 of file TDGen.hh.

Referenced by analyzeMachineVectorRegisterClasses(), gatherAllMachineOperations(), and writeInstrInfo().

◆ andSameOperations_

std::map<TCEString, TCEString> TDGen::andSameOperations_
protected

Contains machine's ANDSAME instructions (<ValueType, InstrName>).

Definition at line 556 of file TDGen.hh.

◆ argRegCount_

unsigned int TDGen::argRegCount_
protected

◆ argRegNames_

std::vector<std::string> TDGen::argRegNames_
protected

Definition at line 590 of file TDGen.hh.

Referenced by writeCallDef(), writeCallDefRegs(), and writeRegisterDef().

◆ baseClasses_

std::map<int, TCEString> TDGen::baseClasses_
protected

Contains vector base classes for register files (<Width, Name>).

Definition at line 514 of file TDGen.hh.

Referenced by analyzeMachineRegisters(), writeCallDefRegs(), writeVectorRegisterBaseClasses(), and writeVectorRegisterNames().

◆ BOOL_SUBW_WIDTH

const int TDGen::BOOL_SUBW_WIDTH
staticprotected
Initial value:

Bool type subword width.

Definition at line 469 of file TDGen.hh.

◆ constantMaterializationPredicates_

std::vector<std::string> TDGen::constantMaterializationPredicates_
protected

All predicates used in constant materialization patterns.

Definition at line 634 of file TDGen.hh.

Referenced by createConstantMaterializationPatterns(), and createConstantMaterializationQuery().

◆ dregNum_

unsigned TDGen::dregNum_
protected

◆ EXPLOIT_BIGGER_REGISTERS

const bool TDGen::EXPLOIT_BIGGER_REGISTERS = true
staticprotected

If set to true, smaller vector value types can be stored to larger register files, e.g. v4i8 vectors can be stored to registers that are over 32 bits in size.

Definition at line 478 of file TDGen.hh.

Referenced by associateRegistersWithVectorRegisterClasses().

◆ extractElemOperations_

std::map<TCEString, TCEString> TDGen::extractElemOperations_
protected

Contains machine's EXTRACTELEM instructions (<ValueType, InstrName>).

Definition at line 548 of file TDGen.hh.

◆ falsePredOps_

std::map<std::string, std::string> TDGen::falsePredOps_
protected

◆ FP_SUBW_WIDTH

const int TDGen::FP_SUBW_WIDTH
staticprotected
Initial value:

Float type subword width.

Definition at line 465 of file TDGen.hh.

Referenced by analyzeMachineVectorRegisterClasses().

◆ gatherOperations_

std::map<TCEString, TCEString> TDGen::gatherOperations_
protected

Contains machine's GATHER instructions (<ValueType, InstrName>).

Definition at line 562 of file TDGen.hh.

Referenced by genGeneratedTCEPlugin_getGatherOpcode().

◆ gprRegNames_

std::vector<std::string> TDGen::gprRegNames_
protected

Definition at line 592 of file TDGen.hh.

Referenced by writeCallDefRegs(), and writeRegisterDef().

◆ guardedRegs_

std::set<RegInfo> TDGen::guardedRegs_
protected

List of register that are associated with a guard on a bus.

Definition at line 621 of file TDGen.hh.

Referenced by analyzeRegisters(), and writeRegisterDef().

◆ guardRegTemplateName

const std::string TDGen::guardRegTemplateName = "Guard"
staticprotected

◆ hasConditionalMoves_

bool TDGen::hasConditionalMoves_
protected

◆ hasExBoolRegs_

bool TDGen::hasExBoolRegs_
protected

Definition at line 604 of file TDGen.hh.

◆ hasExIntRegs_

bool TDGen::hasExIntRegs_
protected

Definition at line 605 of file TDGen.hh.

◆ hasSelect_

bool TDGen::hasSelect_
protected

Definition at line 606 of file TDGen.hh.

Referenced by createSelectPatterns(), and writeOperationDefs().

◆ HFP_SUBW_WIDTH

const int TDGen::HFP_SUBW_WIDTH
staticprotected
Initial value:

Half float type subword width.

Definition at line 467 of file TDGen.hh.

Referenced by analyzeMachineVectorRegisterClasses().

◆ highestLaneBool_

int TDGen::highestLaneBool_
protected

Definition at line 602 of file TDGen.hh.

◆ highestLaneInt_

int TDGen::highestLaneInt_
protected

Definition at line 601 of file TDGen.hh.

◆ immediateLoads_

std::map<TCEString, TDGenerator::InstructionInfo> TDGen::immediateLoads_
protected

All immediate load operations (<ValueType, InstrInfo>).

Definition at line 529 of file TDGen.hh.

◆ immediateStores_

std::map<TCEString, TDGenerator::InstructionInfo> TDGen::immediateStores_
protected

All immediate store operations (<ValueType, InstrInfo>).

Definition at line 527 of file TDGen.hh.

Referenced by writeVectorTruncStoreDefs().

◆ immInfo_

ImmInfo* TDGen::immInfo_ = nullptr
protected

◆ immOperandDefs_

std::map<ImmInfoKey, std::string> TDGen::immOperandDefs_
protected

Maps (operation, operand) pairs to i32 immediate operand definition names.

Definition at line 433 of file TDGen.hh.

Referenced by dagNodeToString(), immediateOperandNameForEmulatedOperation(), patInputs(), and writeIntegerImmediateDefs().

◆ iorOperations_

std::map<TCEString, TCEString> TDGen::iorOperations_
protected

Contains machine's shl instructions (<ValueType, InstrName>).

Definition at line 568 of file TDGen.hh.

Referenced by genGeneratedTCEPlugin_getIorOpcode().

◆ iorSameOperations_

std::map<TCEString, TCEString> TDGen::iorSameOperations_
protected

Contains machine's IORSAME instructions (<ValueType, InstrName>).

Definition at line 558 of file TDGen.hh.

◆ littleEndian_

bool TDGen::littleEndian_
protected

◆ llvmGuardRegs_

std::vector<std::string> TDGen::llvmGuardRegs_
protected

The LLVM register defs used as guards.

Definition at line 584 of file TDGen.hh.

Referenced by writeGuardRegisterClassInfo(), and writeRegisterDef().

◆ mach_

const TTAMachine::Machine& TDGen::mach_
protected

◆ MAX_SCALAR_WIDTH

const int TDGen::MAX_SCALAR_WIDTH = 64
staticprotected

Distincts wide vs scalar registers.

Definition at line 471 of file TDGen.hh.

Referenced by analyzeMachineRegisters(), writeScalarOperationExploitations(), writeVectorRegisterBaseClasses(), and writeVectorRegisterNames().

◆ MAX_SUBW_COUNT

const int TDGen::MAX_SUBW_COUNT = SIMD_WORD_WIDTH / BYTE_BITWIDTH
staticprotected

Maximum number of subwords that any SIMD operation can have.

Definition at line 473 of file TDGen.hh.

Referenced by genTCETargetLoweringSIMD_getSetCCResultVT().

◆ maxScalarWidth_

int TDGen::maxScalarWidth_
protected

◆ maxVectorSize_

int TDGen::maxVectorSize_
protected

Definition at line 599 of file TDGen.hh.

Referenced by writeBackendCode().

◆ movOperations_

std::set<TCEString> TDGen::movOperations_
protected

Contains all moves between register classes (<InstrName>).

Definition at line 571 of file TDGen.hh.

Referenced by writeVectorRegisterMoveDefs().

◆ OPERATION_PATTERNS_

const std::map< TCEString, TCEString > TDGen::OPERATION_PATTERNS_
staticprotected

Contains <BaseOpName, OpPattern> key-value pairs.

Definition at line 502 of file TDGen.hh.

◆ opNames_

std::map<std::string, std::string> TDGen::opNames_
protected

◆ OT_IMM_BOOL

const char TDGen::OT_IMM_BOOL = 'j'
static

◆ OT_IMM_FP

const char TDGen::OT_IMM_FP = 'k'
static

◆ OT_IMM_HFP

const char TDGen::OT_IMM_HFP = 'l'
static

◆ OT_IMM_INT

const char TDGen::OT_IMM_INT = 'i'
static

◆ OT_IMM_LONG

const char TDGen::OT_IMM_LONG = 'a'
static

◆ OT_REG_BOOL

const char TDGen::OT_REG_BOOL = 'b'
static

◆ OT_REG_DOUBLE

const char TDGen::OT_REG_DOUBLE = 'd'
static

Definition at line 487 of file TDGen.hh.

Referenced by constantNodeString().

◆ OT_REG_FP

const char TDGen::OT_REG_FP = 'f'
static

◆ OT_REG_HFP

const char TDGen::OT_REG_HFP = 'h'
static

◆ OT_REG_INT

const char TDGen::OT_REG_INT = 'r'
static

◆ OT_REG_LONG

const char TDGen::OT_REG_LONG = 's'
static

◆ OT_VREG_BOOL

const char TDGen::OT_VREG_BOOL = 'a'
static

Definition at line 493 of file TDGen.hh.

Referenced by operandChar(), and operandToString().

◆ OT_VREG_FP

const char TDGen::OT_VREG_FP = 'e'
static

Definition at line 497 of file TDGen.hh.

Referenced by operandChar(), and operandToString().

◆ OT_VREG_HFP

const char TDGen::OT_VREG_HFP = 'g'
static

Definition at line 498 of file TDGen.hh.

Referenced by operandChar(), and operandToString().

◆ OT_VREG_INT16

const char TDGen::OT_VREG_INT16 = 't'
static

Definition at line 495 of file TDGen.hh.

Referenced by operandChar(), and operandToString().

◆ OT_VREG_INT32

const char TDGen::OT_VREG_INT32 = 'u'
static

Definition at line 496 of file TDGen.hh.

Referenced by operandChar(), and operandToString().

◆ OT_VREG_INT8

const char TDGen::OT_VREG_INT8 = 'q'
static

Definition at line 494 of file TDGen.hh.

Referenced by operandChar(), and operandToString().

◆ packOperations_

std::map<TCEString, TCEString> TDGen::packOperations_
protected

Contains machine's PACK instructions (<ValueType, InstrName>).

Definition at line 532 of file TDGen.hh.

◆ prebypassStackIndeces_

bool TDGen::prebypassStackIndeces_
protected

Definition at line 617 of file TDGen.hh.

Referenced by TDGen(), and write32bitRegisterInfo().

◆ registerLoads_

std::map<TCEString, TDGenerator::InstructionInfo> TDGen::registerLoads_
protected

All register load operations (<ValueType, InstrInfo>).

Definition at line 525 of file TDGen.hh.

Referenced by genGeneratedTCEPlugin_getLoad(), genGeneratedTCEPlugin_getLoadOpcode(), and writeVectorLoadStoreOperationExploitations().

◆ registers_

std::map<int, std::vector<TDGenerator::RegisterInfo> > TDGen::registers_
protected

Contains registers fit for being vector registers (<Width, Registers>).

Definition at line 517 of file TDGen.hh.

Referenced by analyzeMachineRegisters(), associateRegistersWithVectorRegisterClasses(), orderEqualWidthRegistersToRoundRobin(), writeCallDefRegs(), and writeVectorRegisterNames().

◆ registerStores_

std::map<TCEString, TDGenerator::InstructionInfo> TDGen::registerStores_
protected

All register store operations (<ValueType, InstrInfo>).

Definition at line 523 of file TDGen.hh.

Referenced by genGeneratedTCEPlugin_getStore(), writeVectorLoadStoreOperationExploitations(), and writeVectorTruncStoreDefs().

◆ regs16bit_

std::vector<RegInfo> TDGen::regs16bit_
protected

Definition at line 578 of file TDGen.hh.

Referenced by analyzeMachineRegisters(), and write16bitRegisterInfo().

◆ regs1bit_

std::vector<RegInfo> TDGen::regs1bit_
protected

◆ regs32bit_

std::vector<RegInfo> TDGen::regs32bit_
protected

◆ regs64bit_

std::vector<RegInfo> TDGen::regs64bit_
protected

◆ regs8bit_

std::vector<RegInfo> TDGen::regs8bit_
protected

Definition at line 576 of file TDGen.hh.

Referenced by analyzeRegisters().

◆ regs_

std::map<std::string, RegInfo> TDGen::regs_
protected

Map of generated llvm register names to physical register in the machine.

Definition at line 588 of file TDGen.hh.

Referenced by writeBackendCode(), and writeRegisterDef().

◆ regsInClasses_

RegClassMap TDGen::regsInClasses_
protected

◆ regsInRFClasses_

RegClassMap TDGen::regsInRFClasses_
protected

Definition at line 632 of file TDGen.hh.

Referenced by write32bitRegisterInfo().

◆ requiredI32Regs_

unsigned int TDGen::requiredI32Regs_
protected

Minimum number of 32 bit registers.

Definition at line 615 of file TDGen.hh.

Referenced by checkRequiredRegisters(), TDGen(), and writeRegisterInfo().

◆ requiredI64Regs_

unsigned int TDGen::requiredI64Regs_
protected

Definition at line 616 of file TDGen.hh.

Referenced by checkRequiredRegisters(), and TDGen().

◆ resRegNames_

std::vector<std::string> TDGen::resRegNames_
protected

Definition at line 591 of file TDGen.hh.

Referenced by writeCallDefRegs(), and writeRegisterDef().

◆ scalarOps_

std::map<TCEString, Operation*> TDGen::scalarOps_
protected

Contains all scalar operations (<Name, Operation>).

Definition at line 508 of file TDGen.hh.

Referenced by gatherAllMachineOperations().

◆ shlOperations_

std::map<TCEString, TCEString> TDGen::shlOperations_
protected

Contains machine's shl instructions (<ValueType, InstrName>).

Definition at line 566 of file TDGen.hh.

Referenced by genGeneratedTCEPlugin_getShlOpcode().

◆ shlSameOperations_

std::map<TCEString, TCEString> TDGen::shlSameOperations_
protected

Contains machine's SHLSAME instructions (<ValueType, InstrName>).

Definition at line 550 of file TDGen.hh.

◆ shrSameOperations_

std::map<TCEString, TCEString> TDGen::shrSameOperations_
protected

Contains machine's SHRSAME instructions (<ValueType, InstrName>).

Definition at line 552 of file TDGen.hh.

◆ shruSameOperations_

std::map<TCEString, TCEString> TDGen::shruSameOperations_
protected

Contains machine's SHRUSAME instructions (<ValueType, InstrName>).

Definition at line 554 of file TDGen.hh.

◆ tempRegFiles_

std::set< const TTAMachine::RegisterFile*, TTAMachine::MachinePart::Comparator> TDGen::tempRegFiles_
protected

Register files whose last reg reserved for temp reg copies.

Definition at line 626 of file TDGen.hh.

Referenced by analyzeMachineRegisters(), analyzeRegisters(), checkRequiredRegisters(), and TDGen().

◆ truePredOps_

std::map<std::string, std::string> TDGen::truePredOps_
protected

◆ truncOperations_

std::vector<std::pair<const Operation*, TCEString> > TDGen::truncOperations_
protected

Contains machine's TRUNCxx/CFH instructions (<ValueType, InstrName>).

Definition at line 536 of file TDGen.hh.

Referenced by writeVectorTruncStoreDefs().

◆ use64bitForFP_

bool TDGen::use64bitForFP_
protected

◆ vbcastOperations_

std::map<TCEString, TCEString> TDGen::vbcastOperations_
protected

Contains machine's VBCAST instructions (<ValueType, InstrName>).

Definition at line 534 of file TDGen.hh.

Referenced by writeScalarToVectorDefs().

◆ vcshuffleOperations_

std::map<std::pair<TCEString, std::vector<int> >, TCEString> TDGen::vcshuffleOperations_
protected

Contains machine's VCSHUFFLE instructions (<<ValueType, ConstantSelects>, InstrName>).

Definition at line 546 of file TDGen.hh.

◆ vectorOps_

std::map<TCEString, Operation*> TDGen::vectorOps_
protected

Contains all vector operations (<Name, Operation>).

Definition at line 511 of file TDGen.hh.

Referenced by gatherAllMachineOperations().

◆ vRegClasses_

std::map<TCEString, TDGenerator::RegisterClass> TDGen::vRegClasses_
protected

◆ vselectOperations_

std::map<TCEString, TCEString> TDGen::vselectOperations_
protected

Contains machine's VSELECT instructions (<instrName, ValueType>).

Definition at line 538 of file TDGen.hh.

◆ vshuffle1Operations_

std::map<TCEString, TCEString> TDGen::vshuffle1Operations_
protected

Contains machine's VSHUFFLE1 instructions (<ValueType, InstrName>).

Definition at line 540 of file TDGen.hh.

◆ vshuffle2Operations_

std::map<TCEString, TCEString> TDGen::vshuffle2Operations_
protected

Contains machine's VSHUFFLE2 instructions (<ValueType, InstrName>).

Definition at line 542 of file TDGen.hh.

◆ xorSameOperations_

std::map<TCEString, TCEString> TDGen::xorSameOperations_
protected

Contains machine's XORSAME instructions (<ValueType, InstrName>).

Definition at line 560 of file TDGen.hh.


The documentation for this class was generated from the following files:
Operand
Definition: Operand.hh:52
TDGen::requiredI64Regs_
unsigned int requiredI64Regs_
Definition: TDGen.hh:616
OperationDAGEdge::dstOperand
int dstOperand() const
Definition: OperationDAGEdge.cc:54
TDGen::gprRegNames_
std::vector< std::string > gprRegNames_
Definition: TDGen.hh:592
ADDIMM
#define ADDIMM
Definition: TCEFrameInfo.cc:62
TDGen::createEndiannesQuery
void createEndiannesQuery(std::ostream &os)
Definition: TDGen.cc:6413
TDGenerator::RegisterInfo::regFileName_
TCEString regFileName_
Name of the register file the register belongs to, e.g. "RF".
Definition: TDGen.hh:656
TDGen::writePortGuardedJumpDefPair
bool writePortGuardedJumpDefPair(std::ostream &os, const TCEString &tceop1, const TCEString &tceop2, bool fp=false)
Definition: TDGen.cc:3841
TDGenerator::RegisterClass
Definition: TDGen.hh:721
BoostGraph::predecessors
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
TDGen::OT_REG_FP
static const char OT_REG_FP
Definition: TDGen.hh:485
TDGen::RESULT
@ RESULT
Definition: TDGen.hh:100
TDGen::genTCETargetLoweringSIMD_associatedVectorRegClass
void genTCETargetLoweringSIMD_associatedVectorRegClass(std::ostream &o) const
Definition: TDGen.cc:3042
ImmInfo::immediateValueBounds
std::pair< int64_t, int64_t > immediateValueBounds(const ImmInfoKey &key, int destWidth) const
Definition: ImmInfo.cc:219
BoostGraph::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
BoostGraph::outEdge
virtual Edge & outEdge(const Node &node, const int index) const
Operation::writesMemory
virtual bool writesMemory() const
Definition: Operation.cc:252
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
TDGen::OT_REG_INT
static const char OT_REG_INT
Definition: TDGen.hh:483
TDGen::getMatchableOperationDAG
const OperationDAG * getMatchableOperationDAG(const Operation &op)
Definition: TDGen.cc:5320
TDGen::maxScalarWidth_
int maxScalarWidth_
Definition: TDGen.hh:610
TDGen::writeHWLoopDef
void writeHWLoopDef(std::ostream &o)
Definition: TDGen.cc:3571
TDGen::writeBooleanStorePatterns
void writeBooleanStorePatterns(std::ostream &os)
Definition: TDGen.cc:4527
TDGenerator::RegisterInfo::regIndex_
unsigned regIndex_
Register index in the register file.
Definition: TDGen.hh:658
TTAMachine::Machine::hasOperation
bool hasOperation(const TCEString &opName) const
Definition: Machine.cc:1048
TDGen::checkRequiredRegisters
bool checkRequiredRegisters()
Definition: TDGen.cc:3280
TDGen::resRegNames_
std::vector< std::string > resRegNames_
Definition: TDGen.hh:591
TDGen::createConstantMaterializationQuery
void createConstantMaterializationQuery(std::ostream &os)
Definition: TDGen.cc:6427
TDGen::writeConstShiftPat
void writeConstShiftPat(std::ostream &os, const TCEString &nodeName, const TCEString &opNameBase, int i)
Definition: TDGen.cc:8503
TDGen::writeVectorRegisterClasses
void writeVectorRegisterClasses(std::ostream &o) const
Definition: TDGen.cc:2046
Operand::setElementCount
virtual void setElementCount(int elementCount)
Definition: Operand.cc:308
Operand::BOOL
@ BOOL
Definition: Operand.hh:64
MachineConnectivityCheck
Definition: MachineConnectivityCheck.hh:69
TDGen::OT_IMM_HFP
static const char OT_IMM_HFP
Definition: TDGen.hh:491
TDGen::OT_VREG_INT32
static const char OT_VREG_INT32
Definition: TDGen.hh:496
BoostGraph::tailNode
virtual Node & tailNode(const Edge &edge) const
ImmInfo::canTakeImmediateByWidth
bool canTakeImmediateByWidth(const Operation &operation, int inputOperandId, int bitWidth)
Definition: ImmInfo.cc:275
TDGen::canBeImmediate
bool canBeImmediate(const OperationDAG &dag, const TerminalNode &node)
Definition: TDGen.cc:6049
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
TDGen::immediateStores_
std::map< TCEString, TDGenerator::InstructionInfo > immediateStores_
All immediate store operations (<ValueType, InstrInfo>).
Definition: TDGen.hh:527
TTAMachine::RegisterFile::isReserved
virtual bool isReserved() const
Definition: RegisterFile.cc:184
TDGen::write64bitRegisterInfo
void write64bitRegisterInfo(std::ostream &o)
Definition: TDGen.cc:1307
BoostGraph::headNode
virtual Node & headNode(const Edge &edge) const
Operation::output
virtual Operand & output(int index) const
Definition: Operation.cc:526
Operand::HALF_FLOAT_WORD
@ HALF_FLOAT_WORD
Definition: Operand.hh:63
TDGenerator::RegisterClass::registerInfo
RegisterInfo registerInfo(int index) const
Definition: TDGen.cc:9010
TDGenerator::RegisterClass::valueType
ValueType valueType() const
Definition: TDGen.cc:8990
TDGen::requiredI32Regs_
unsigned int requiredI32Regs_
Minimum number of 32 bit registers.
Definition: TDGen.hh:615
ImmInfo::count
size_t count(const ImmInfoKey &key) const
Definition: ImmInfo.hh:87
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
TDGen::immInfo_
ImmInfo * immInfo_
Definition: TDGen.hh:430
TDGen::OT_VREG_BOOL
static const char OT_VREG_BOOL
Definition: TDGen.hh:493
TDGen::writeVectorBitConversions
void writeVectorBitConversions(std::ostream &o) const
Definition: TDGen.cc:2362
TDGen::OT_IMM_INT
static const char OT_IMM_INT
Definition: TDGen.hh:489
Operation::dagError
virtual TCEString dagError(int index) const
Definition: Operation.cc:182
TDGen::tceOperationPattern
std::string tceOperationPattern(const Operation &op)
Definition: TDGen.cc:5225
TDGen::operationPattern
std::string operationPattern(const Operation &op, const OperationDAG &dag, const std::string &operandTypes)
Definition: TDGen.cc:5351
TDGen::createDefaultOperandTypeString
std::string createDefaultOperandTypeString(const Operation &op)
Definition: TDGen.cc:5369
TDGen::createByteExtLoadPatterns
void createByteExtLoadPatterns(std::ostream &os)
Definition: TDGen.cc:6457
TDGen::writeVectorRegisterNames
void writeVectorRegisterNames(std::ostream &o)
Definition: TDGen.cc:2014
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
BoostGraph< OperationDAGNode, OperationDAGEdge >::NodeSet
std::set< OperationDAGNode *, typename OperationDAGNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TDGen::writeCallDef
void writeCallDef(std::ostream &o)
Definition: TDGen.cc:3899
TDGen::genGeneratedTCEPlugin_getIorOpcode
void genGeneratedTCEPlugin_getIorOpcode(std::ostream &o) const
Definition: TDGen.cc:3259
TDGenerator::ValueType::subwCount_
int subwCount_
Subword count of the value type.
Definition: TDGen.hh:710
TDGen::regs16bit_
std::vector< RegInfo > regs16bit_
Definition: TDGen.hh:578
REG_RENAMER_PART
static const unsigned REG_RENAMER_PART
Definition: TDGen.cc:332
TDGen::highestLaneInt_
int highestLaneInt_
Definition: TDGen.hh:601
TTAMachine::Bus
Definition: Bus.hh:53
TDGen::associatedVectorRegisterClass
TCEString associatedVectorRegisterClass(const Operand &operand) const
Definition: TDGen.cc:1786
TDGenerator::RegisterClass::addRegisters
void addRegisters(const std::vector< RegisterInfo > &registers)
Definition: TDGen.cc:9033
TDGen::truePredOps_
std::map< std::string, std::string > truePredOps_
Definition: TDGen.hh:596
ImmInfoKey
std::pair< std::string, int > ImmInfoKey
Definition: ImmInfo.hh:53
Operand::UINT_WORD
@ UINT_WORD
Definition: Operand.hh:60
SUBIMM
#define SUBIMM
Definition: TCEFrameInfo.cc:63
TTAMachine::Machine::is64bit
bool is64bit() const
Definition: Machine.hh:260
TDGen::writeOperationDefs
void writeOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
Definition: TDGen.cc:4271
Operand::width
virtual int width() const
Definition: Operand.cc:318
Operand::setType
virtual void setType(OperandType type)
Definition: Operand.cc:175
TDGen::writeCallSeqStart
void writeCallSeqStart(std::ostream &os)
Definition: TDGen.cc:7870
Application::VERBOSE_LEVEL_DEFAULT
static const int VERBOSE_LEVEL_DEFAULT
Default verbose level - do not print anything unnecessary.
Definition: Application.hh:222
MachineInfo::osalOperation
static Operation & osalOperation(const TTAMachine::HWOperation &hwOp)
Definition: MachineInfo.cc:794
TDGen::writeInstrInfo
void writeInstrInfo(std::ostream &o)
Definition: TDGen.cc:3328
TerminalNode
Definition: TerminalNode.hh:47
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
TDGen::writeVectorImmediateWriteDefs
void writeVectorImmediateWriteDefs(std::ostream &instrInfoTD)
Definition: TDGen.cc:3160
Operand::setElementWidth
virtual void setElementWidth(int elementWidth)
Definition: Operand.cc:288
Conversion
Definition: Conversion.hh:52
TDGen::analyzeMachineRegisters
void analyzeMachineRegisters()
Definition: TDGen.cc:1422
TDGen::falsePredOps_
std::map< std::string, std::string > falsePredOps_
Definition: TDGen.hh:597
TDGenerator::RegisterClass::name
TCEString name() const
Definition: TDGen.cc:8980
TDGen::argRegCount_
unsigned int argRegCount_
Definition: TDGen.hh:613
TDGen::createVectorRVDRegNums
virtual void createVectorRVDRegNums(std::ostream &os)
Definition: TDGen.cc:6948
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
OperationNode::referencedOperation
Operation & referencedOperation() const
Definition: OperationNode.cc:70
TDGen::scalarOps_
std::map< TCEString, Operation * > scalarOps_
Contains all scalar operations (<Name, Operation>).
Definition: TDGen.hh:508
TDGenerator::RegisterInfo
Definition: TDGen.hh:644
TDGen::llvmOperationPattern
virtual TCEString llvmOperationPattern(const Operation &op, char operandType=' ') const
Definition: TDGen.cc:4854
TDGen::OT_REG_BOOL
static const char OT_REG_BOOL
Definition: TDGen.hh:482
TDGen::supportedStackAccessOperations
static std::vector< std::string > supportedStackAccessOperations(const TTAMachine::Machine &mach)
Definition: TDGen.cc:7611
TDGen::OT_VREG_HFP
static const char OT_VREG_HFP
Definition: TDGen.hh:498
Operand::elementWidth
virtual int elementWidth() const
Definition: Operand.cc:278
TDGen::write32bitRegisterInfo
void write32bitRegisterInfo(std::ostream &o)
Definition: TDGen.cc:965
TDGen::ONLY_EXTRAS
@ ONLY_EXTRAS
Definition: TDGen.hh:128
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
BoostGraph::addNode
virtual void addNode(Node &node)
OperationNode
Definition: OperationNode.hh:47
TDGen::orderEqualWidthRegistersToRoundRobin
void orderEqualWidthRegistersToRoundRobin()
Definition: TDGen.cc:1618
TTAMachine::Machine::Navigator::count
int count() const
TDGen::guardedRegs_
std::set< RegInfo > guardedRegs_
List of register that are associated with a guard on a bus.
Definition: TDGen.hh:621
TDGen::OT_REG_LONG
static const char OT_REG_LONG
Definition: TDGen.hh:484
TCEString::upper
TCEString upper() const
Definition: TCEString.cc:86
Operand::isOutput
virtual bool isOutput() const
Definition: Operand.cc:155
NullOperation::instance
static NullOperation & instance()
TDGen::writeScalarToVectorDefs
void writeScalarToVectorDefs(std::ostream &o) const
Definition: TDGen.cc:2332
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
TDGen::writeVectorRegisterMoveDefs
void writeVectorRegisterMoveDefs(std::ostream &o)
Definition: TDGen.cc:2214
TDGen::writeVectorOperationDefs
void writeVectorOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
Definition: TDGen.cc:2108
OperationDAGEdge
Definition: OperationDAGEdge.hh:38
MachineConnectivityCheck::hasConditionalMoves
static bool hasConditionalMoves(const TTAMachine::Machine &mach, const std::set< int > &rfWidths)
Definition: MachineConnectivityCheck.cc:1876
TDGen::OT_VREG_INT8
static const char OT_VREG_INT8
Definition: TDGen.hh:494
TDGen::genGeneratedTCEPlugin_getLoad
void genGeneratedTCEPlugin_getLoad(std::ostream &o) const
Definition: TDGen.cc:2883
Conversion::toString
static std::string toString(const T &source)
TDGen::writeInstrDef
void writeInstrDef(std::ostream &o, const std::string &instrDefName, const std::string &outs, const std::string &ins, const std::string &asmString, const std::string &pattern)
Definition: TDGen.cc:4585
TDGen::writeVectorMemoryOperationDefs
void writeVectorMemoryOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
Definition: TDGen.cc:2205
TDGen::regs8bit_
std::vector< RegInfo > regs8bit_
Definition: TDGen.hh:576
TDGen::vbcastOperations_
std::map< TCEString, TCEString > vbcastOperations_
Contains machine's VBCAST instructions (<ValueType, InstrName>).
Definition: TDGen.hh:534
TDGen::isVectorStoreOperation
bool isVectorStoreOperation(const Operation &op) const
Definition: TDGen.cc:1921
TDGen::shlOperations_
std::map< TCEString, TCEString > shlOperations_
Contains machine's shl instructions (<ValueType, InstrName>).
Definition: TDGen.hh:566
TDGen::areImmediateOperandsLegal
bool areImmediateOperandsLegal(const Operation &operation, const std::string &operandTypes) const
Definition: TDGen.cc:7543
Operation::dagCode
virtual TCEString dagCode(int index) const
Definition: Operation.cc:159
TDGen::isVectorLoadOperation
bool isVectorLoadOperation(const Operation &op) const
Definition: TDGen.cc:1909
TDGen::writeGetPointerAdjustmentQuery
void writeGetPointerAdjustmentQuery(std::ostream &os) const
Definition: TDGen.cc:7448
OperationDAG::endNodes
const OperationDAG::NodeSet & endNodes() const
Definition: OperationDAG.cc:137
ImmInfo::key
static ImmInfoKey key(const Operation &operation, int inputOperandId)
Definition: ImmInfo.cc:57
TDGenerator::ValueType
Definition: TDGen.hh:679
BoostGraph::outDegree
virtual int outDegree(const Node &node) const
TDGen::allOpNames_
OperationDAGSelector::OperationSet allOpNames_
Contains all operation names in upper case.
Definition: TDGen.hh:505
TTAMachine::Machine::isLittleEndian
bool isLittleEndian() const
Definition: Machine.hh:258
Operation::canSwap
virtual bool canSwap(int id1, int id2) const
Definition: Operation.cc:470
TDGen::OT_VREG_INT16
static const char OT_VREG_INT16
Definition: TDGen.hh:495
StringTools::stringToUpper
static std::string stringToUpper(const std::string &source)
Definition: StringTools.cc:143
TDGen::writeOperandDefs
void writeOperandDefs(std::ostream &o)
Definition: TDGen.cc:566
TDGen::hasRegisterClassSupport
bool hasRegisterClassSupport(const Operation &op) const
Definition: TDGen.cc:1749
TDGen::ONLY_NORMAL
@ ONLY_NORMAL
Definition: TDGen.hh:130
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TDGen::ARGUMENT
@ ARGUMENT
Definition: TDGen.hh:99
Operand::isVector
virtual bool isVector() const
Definition: Operand.cc:268
TDGen::hasConditionalMoves_
bool hasConditionalMoves_
Definition: TDGen.hh:608
TDGen::genTCETargetLoweringSIMD_addVectorRegisterClasses
void genTCETargetLoweringSIMD_addVectorRegisterClasses(std::ostream &o) const
Definition: TDGen.cc:2997
TDGen::createTrivialDAG
OperationDAG * createTrivialDAG(Operation &op)
Definition: TDGen.cc:6019
TDGen::vRegClasses_
std::map< TCEString, TDGenerator::RegisterClass > vRegClasses_
Contains required vector register classes (<ValueType, RegClass>).
Definition: TDGen.hh:520
TDGen::writeStartOfRegisterInfo
void writeStartOfRegisterInfo(std::ostream &o)
Definition: TDGen.cc:539
TDGen::writeTopLevelTD
void writeTopLevelTD(std::ostream &o)
Definition: TDGen.cc:4190
TDGen::registerStores_
std::map< TCEString, TDGenerator::InstructionInfo > registerStores_
All register store operations (<ValueType, InstrInfo>).
Definition: TDGen.hh:523
TDGen::dregNum_
unsigned dregNum_
Definition: TDGen.hh:462
OperationDAGSelector::findDags
static OperationDAGList findDags(const std::string &opName, OperationSet opSet, const ImmInfo *immInfo=nullptr)
Definition: OperationDAGSelector.cc:57
TDGen::writeCallingConvLicenceText
void writeCallingConvLicenceText(std::ostream &os)
Definition: TDGen.cc:6901
TDGen::createMinMaxGenerator
virtual void createMinMaxGenerator(std::ostream &os)
Definition: TDGen.cc:6324
TDGen::tempRegFiles_
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegFiles_
Register files whose last reg reserved for temp reg copies.
Definition: TDGen.hh:626
TDGenerator::RegisterClass::alignment
int alignment() const
Definition: TDGen.cc:9000
TDGen::immediatePredicate
std::string immediatePredicate(int64_t lowerBoundInclusive, uint64_t upperBoundInclusive)
Definition: TDGen.cc:7486
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
TDGen::writeIntegerImmediateDefs
void writeIntegerImmediateDefs(std::ostream &o, const ImmInfo &iivis)
Definition: TDGen.cc:594
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
TDGen::regsInRFClasses_
RegClassMap regsInRFClasses_
Definition: TDGen.hh:632
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
TDGen::getLLVMPatternWithConstants
TCEString getLLVMPatternWithConstants(const Operation &op, const std::string &operandTypes, const std::string &operand0, const std::string &operand1) const
Definition: TDGen.cc:7682
InvalidData
Definition: Exception.hh:149
TDGen::hasExBoolRegs_
bool hasExBoolRegs_
Definition: TDGen.hh:604
MachineInfo::supportsPortGuardedJump
static bool supportsPortGuardedJump(const TTAMachine::Machine &machine, bool inverted, const TCEString &opName)
Definition: MachineInfo.cc:703
OperationDAGEdge::srcOperand
int srcOperand() const
Definition: OperationDAGEdge.cc:49
TDGen::addOperations_
std::map< TCEString, TCEString > addOperations_
Contains machine's add instructions (<ValueType, InstrName>).
Definition: TDGen.hh:564
TDGen::hasSelect_
bool hasSelect_
Definition: TDGen.hh:606
TDGen::writeAddressingModeDefs
void writeAddressingModeDefs(std::ostream &o)
Definition: TDGen.cc:8345
regOperandCharToImmOperandChar
char regOperandCharToImmOperandChar(char c)
Definition: TDGen.cc:4450
OperationDAGNode
Definition: OperationDAGNode.hh:45
TDGen::operationNodeToString
std::string operationNodeToString(const Operation &op, const OperationDAG &dag, const OperationNode &node, bool emulationPattern, const std::string &operandTypes)
Definition: TDGen.cc:5711
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
THROW_EXCEPTION
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition: Exception.hh:39
Operand::SLONG_WORD
@ SLONG_WORD
Definition: Operand.hh:66
TDGen::saveAdditionalVectorOperationInfo
void saveAdditionalVectorOperationInfo(const Operation &op, const TCEString &valueTypes, bool isRegisterOp)
Definition: TDGen.cc:2190
TDGenerator::ValueType::subwWidth_
int subwWidth_
Subword width of the value type.
Definition: TDGen.hh:708
TDGen::writeGuardRegisterClassInfo
void writeGuardRegisterClassInfo(std::ostream &o)
Definition: TDGen.cc:1952
TTAMachine::RegisterGuard
Definition: Guard.hh:137
BoostGraph::inEdge
virtual Edge & inEdge(const Node &node, const int index) const
TDGen::highestLaneBool_
int highestLaneBool_
Definition: TDGen.hh:602
TDGen::canBePredicated
bool canBePredicated(Operation &op, const std::string &operandTypes)
Definition: TDGen.cc:7591
TDGen::writeVectorLoadStoreOperationExploitations
void writeVectorLoadStoreOperationExploitations(std::ostream &o)
Definition: TDGen.cc:2648
ADFSerializer
Definition: ADFSerializer.hh:49
TDGen::writeOperationDef
void writeOperationDef(std::ostream &o, Operation &op, const std::string &operandTypes, const std::string &attrs, bool skipPattern, std::string backendPrefix="")
Definition: TDGen.cc:4608
TDGen::operandToString
virtual std::string operandToString(const Operand &operand, bool match, char operandType, const std::string &immDefName="")
Definition: TDGen.cc:5796
TDGen::hasExIntRegs_
bool hasExIntRegs_
Definition: TDGen.hh:605
TDGen::FP_SUBW_WIDTH
static const int FP_SUBW_WIDTH
Float type subword width.
Definition: TDGen.hh:465
TDGen::baseClasses_
std::map< int, TCEString > baseClasses_
Contains vector base classes for register files (<Width, Name>).
Definition: TDGen.hh:514
TDGen::genTCERegisterInfo_setReservedVectorRegs
void genTCERegisterInfo_setReservedVectorRegs(std::ostream &os) const
Definition: TDGen.cc:4162
OperationDAG
Definition: OperationDAG.hh:43
ImmediateAnalyzer::analyze
static ImmInfo * analyze(const TTAMachine::Machine &mach)
Definition: ImmediateAnalyzer.cc:60
TDGenerator::ValueType::width
int width() const
Definition: TDGen.cc:8702
ImmInfo::canTakeImmediate
bool canTakeImmediate(const Operation &operation, int inputOperandId, int64_t value, int destWidth)
Definition: ImmInfo.cc:252
TDGen::writeArgRegsArray
void writeArgRegsArray(std::ostream &os)
Definition: TDGen.cc:6922
__func__
#define __func__
Definition: Application.hh:67
TDGen::subPattern
std::string subPattern(const Operation &op, const OperationDAG &dag)
Definition: TDGen.cc:5398
Operand::FLOAT_WORD
@ FLOAT_WORD
Definition: Operand.hh:61
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
TDGen::gatherOperations_
std::map< TCEString, TCEString > gatherOperations_
Contains machine's GATHER instructions (<ValueType, InstrName>).
Definition: TDGen.hh:562
TDGen::genGeneratedTCEPlugin_getLoadOpcode
void genGeneratedTCEPlugin_getLoadOpcode(std::ostream &o) const
Definition: TDGen.cc:3215
TDGen::registers_
std::map< int, std::vector< TDGenerator::RegisterInfo > > registers_
Contains registers fit for being vector registers (<Width, Registers>).
Definition: TDGen.hh:517
ConstantNode
Definition: ConstantNode.hh:43
Operand::index
virtual int index() const
Definition: Operand.cc:135
TDGen::genGeneratedTCEPlugin_getStore
void genGeneratedTCEPlugin_getStore(std::ostream &o) const
Definition: TDGen.cc:2783
OperationDAGSelector::OperationDAGList
Definition: OperationDAGSelector.hh:56
TDGen::mach_
const TTAMachine::Machine & mach_
Definition: TDGen.hh:459
MachineInfo::getOpset
static OperationSet getOpset(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:65
TDGenerator::RegisterInfo::regName_
TCEString regName_
Register name in GenRegisterInfo.td, e.g. "KLUDGE_REGISTER".
Definition: TDGen.hh:654
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
TDGen::writeOperationDefUsingGivenOperandTypes
void writeOperationDefUsingGivenOperandTypes(std::ostream &o, Operation &op, bool skipPattern, std::vector< TDGenerator::ValueType > inputs, std::vector< TDGenerator::ValueType > outputs, TCEString instrSuffix="")
Definition: TDGen.cc:1840
Operation::readsMemory
virtual bool readsMemory() const
Definition: Operation.cc:242
TDGen::opNames_
std::map< std::string, std::string > opNames_
Definition: TDGen.hh:594
TDGen::createBranchAnalysis
void createBranchAnalysis(std::ostream &os)
Definition: TDGen.cc:7896
TDGenerator::ValueType::isFloat_
bool isFloat_
If true, the value type is a floating point type.
Definition: TDGen.hh:712
TDGen::MAX_SCALAR_WIDTH
static const int MAX_SCALAR_WIDTH
Distincts wide vs scalar registers.
Definition: TDGen.hh:471
Operand::SINT_WORD
@ SINT_WORD
Definition: Operand.hh:59
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
TDGen::EXPLOIT_BIGGER_REGISTERS
static const bool EXPLOIT_BIGGER_REGISTERS
If set to true, smaller vector value types can be stored to larger register files,...
Definition: TDGen.hh:478
TDGen::guardRegTemplateName
static const std::string guardRegTemplateName
Definition: TDGen.hh:636
OperationDAGSelector::OperationSet
TCETools::CIStringSet OperationSet
Definition: OperationDAGSelector.hh:88
TDGen::writeRegisterDef
void writeRegisterDef(std::ostream &o, const RegInfo &reg, const std::string regName, const std::string regTemplate, const std::string aliases, RegType type)
Definition: TDGen.cc:448
Operation::isVectorOperation
virtual bool isVectorOperation() const
Definition: Operation.cc:222
Operand::ULONG_WORD
@ ULONG_WORD
Definition: Operand.hh:67
Operation::impl
OperationPimpl & impl()
Definition: Operation.hh:170
TDGen::prebypassStackIndeces_
bool prebypassStackIndeces_
Definition: TDGen.hh:617
TDGen::operandChar
virtual char operandChar(Operand &operand)
Definition: TDGen.cc:4714
BoostGraph::inDegree
virtual int inDegree(const Node &node) const
Operand::RAW_DATA
@ RAW_DATA
Definition: Operand.hh:65
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Port::isOutput
virtual bool isOutput() const
Definition: Port.cc:308
TDGen::writeImmediateDef
virtual void writeImmediateDef(std::ostream &o, const std::string &defName, const std::string &operandType, const std::string &predicate)
Definition: TDGen.cc:4569
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Operation
Definition: Operation.hh:59
TDGen::regsInClasses_
RegClassMap regsInClasses_
All registers in certain group.
Definition: TDGen.hh:630
Operation::operandCount
virtual int operandCount() const
Definition: Operation.cc:212
TDGen::regs32bit_
std::vector< RegInfo > regs32bit_
Definition: TDGen.hh:580
TDGen::HFP_SUBW_WIDTH
static const int HFP_SUBW_WIDTH
Half float type subword width.
Definition: TDGen.hh:467
TDGen::getMovePattern
TCEString getMovePattern(const char &opdType, const std::string &inputPattern) const
Definition: TDGen.cc:7835
TDGen::create32BitExtLoadPatterns
void create32BitExtLoadPatterns(std::ostream &os)
Definition: TDGen.cc:6734
TDGen::writeControlFlowInstrDefs
void writeControlFlowInstrDefs(std::ostream &os)
Definition: TDGen.cc:3560
MachineConnectivityCheck::tempRegisterFiles
static std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegisterFiles(const TTAMachine::Machine &machine)
Definition: MachineConnectivityCheck.cc:1038
TDGen::writeRARegisterInfo
void writeRARegisterInfo(std::ostream &o)
Definition: TDGen.cc:3101
TDGen::writeRegisterInfo
bool writeRegisterInfo(std::ostream &o)
Definition: TDGen.cc:496
TDGen::writePatternReplacement
void writePatternReplacement(std::ostream &o, const TCEString &origPat, const TCEString &replacerPat) const
Definition: TDGen.cc:1819
TDGen::createMinMaxDef
void createMinMaxDef(const TCEString &opName, const TCEString &valueName, std::ostream &os)
Definition: TDGen.cc:6296
TDGen::vectorOps_
std::map< TCEString, Operation * > vectorOps_
Contains all vector operations (<Name, Operation>).
Definition: TDGen.hh:511
OperationDAGSelector::OperationDAGList::smallestNodeCount
OperationDAG & smallestNodeCount() const
Definition: OperationDAGSelector.hh:64
TDGen::analyzeRegisters
void analyzeRegisters()
Definition: TDGen.cc:783
TDGen::OT_IMM_LONG
static const char OT_IMM_LONG
Definition: TDGen.hh:492
Operation::input
virtual Operand & input(int index) const
Definition: Operation.cc:503
TDGen::writeVectorRegisterBaseClasses
void writeVectorRegisterBaseClasses(std::ostream &o) const
Definition: TDGen.cc:1991
TDGen::writeCallingConv
void writeCallingConv(std::ostream &os)
Definition: TDGen.cc:6796
BoostGraph::outEdges
virtual EdgeSet outEdges(const Node &node) const
TDGen::writeVectorTruncStoreDefs
void writeVectorTruncStoreDefs(std::ostream &o) const
Definition: TDGen.cc:2262
Operand::DOUBLE_WORD
@ DOUBLE_WORD
Definition: Operand.hh:62
Operation::operand
virtual Operand & operand(int id) const
Definition: Operation.cc:541
TDGen::analyzeMachineVectorRegisterClasses
void analyzeMachineVectorRegisterClasses()
Definition: TDGen.cc:1226
TDGen::verbose
void verbose(const TCEString &msg) const
Definition: TDGen.cc:1806
XMLSerializer::setDestinationString
void setDestinationString(std::string &destination)
Definition: XMLSerializer.cc:156
TTAMachine::BaseRegisterFile::port
virtual RFPort * port(const std::string &name) const
Definition: BaseRegisterFile.cc:129
Operation::dagCount
virtual int dagCount() const
Definition: Operation.cc:134
TDGen::OT_REG_DOUBLE
static const char OT_REG_DOUBLE
Definition: TDGen.hh:487
TDGen::writeBackendCode
void writeBackendCode(std::ostream &o)
Definition: TDGen.cc:3941
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
TDGen::ONLY_LANES
@ ONLY_LANES
Definition: TDGen.hh:129
TDGen::writeCondBranchDefs
void writeCondBranchDefs(std::ostream &os)
Definition: TDGen.cc:3605
TDGen::writeMoveImmediateDefs
void writeMoveImmediateDefs(std::ostream &o)
Definition: TDGen.cc:701
TDGen::immediateOperandNameForEmulatedOperation
std::string immediateOperandNameForEmulatedOperation(const OperationDAG &, const Operand &operand)
Definition: TDGen.cc:7510
IllegalMachine
Definition: Exception.hh:878
TDGen::writeVectorOperationDef
void writeVectorOperationDef(std::ostream &o, Operation &op, TCEString valueTypes, const TCEString &attributes, bool skipPattern)
Definition: TDGen.cc:2125
TDGen::OT_VREG_FP
static const char OT_VREG_FP
Definition: TDGen.hh:497
TDGen::writeRegisterClasses
void writeRegisterClasses(std::ostream &o)
Definition: TDGen.cc:761
ConstantNode::value
virtual long value() const
Definition: ConstantNode.cc:60
TDGen::createConstantMaterializationPatterns
virtual void createConstantMaterializationPatterns(std::ostream &os)
Definition: TDGen.cc:7384
Operand::type
virtual OperandType type() const
Definition: Operand.cc:165
TDGen::regs1bit_
std::vector< RegInfo > regs1bit_
Definition: TDGen.hh:574
TDGen::regs_
std::map< std::string, RegInfo > regs_
Map of generated llvm register names to physical register in the machine.
Definition: TDGen.hh:588
TDGen::dagNodeToString
std::string dagNodeToString(const Operation &op, const OperationDAG &dag, const OperationDAGNode &node, bool emulationPattern, const std::string &operandTypes, const Operation *emulatingOp=nullptr, const OperationDAGNode *successor=nullptr)
Definition: TDGen.cc:5436
TDGen::maxVectorSize_
int maxVectorSize_
Definition: TDGen.hh:599
TDGenerator::RegisterClass::numberOfRegisters
size_t numberOfRegisters() const
Definition: TDGen.cc:9023
TCEString
Definition: TCEString.hh:53
sub
#define sub
Definition: ConstantTransformer.cc:63
TDGen::isVectorBitwiseOperation
bool isVectorBitwiseOperation(const Operation &op) const
Definition: TDGen.cc:1939
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
TDGen::genGeneratedTCEPlugin_getShlOpcode
void genGeneratedTCEPlugin_getShlOpcode(std::ostream &o) const
Definition: TDGen.cc:3244
TDGen::patOutputs
std::string patOutputs(const Operation &op, const std::string &oprTypes)
Definition: TDGen.cc:6000
TDGen::writeInstrFormats
void writeInstrFormats(std::ostream &o)
Definition: TDGen.cc:4214
TDGen::createVectorMinMaxDef
void createVectorMinMaxDef(const TCEString &opName, int bits, char llvmTypeChar, const TCEString &postFix, std::ostream &os)
Definition: TDGen.cc:6306
TDGen::writeCallDefRegs
virtual void writeCallDefRegs(std::ostream &o)
Definition: TDGen.cc:3524
ADFSerializer::writeMachine
void writeMachine(const TTAMachine::Machine &machine)
Definition: ADFSerializer.cc:259
MachineInfo::supportsPortGuardedJumps
static bool supportsPortGuardedJumps(const TTAMachine::Machine &machine)
Definition: MachineInfo.cc:663
TDGen::RESERVED
@ RESERVED
Definition: TDGen.hh:98
TDGen::gatherAllMachineOperations
void gatherAllMachineOperations()
Definition: TDGen.cc:941
TDGen::createShortExtLoadPatterns
void createShortExtLoadPatterns(std::ostream &os)
Definition: TDGen.cc:6617
TTAMachine::Port::isInput
virtual bool isInput() const
Definition: Port.cc:298
TDGen::constantNodeString
std::string constantNodeString(const Operation &op, const OperationDAG &dag, const ConstantNode &node, const std::string &operandTypes, const OperationDAGNode *successor=nullptr)
Definition: TDGen.cc:5541
TDGen::constantMaterializationPredicates_
std::vector< std::string > constantMaterializationPredicates_
All predicates used in constant materialization patterns.
Definition: TDGen.hh:634
TDGen::writeScalarOperationExploitations
void writeScalarOperationExploitations(std::ostream &o)
Definition: TDGen.cc:2419
TDGen::registerLoads_
std::map< TCEString, TDGenerator::InstructionInfo > registerLoads_
All register load operations (<ValueType, InstrInfo>).
Definition: TDGen.hh:525
TDGen::argRegNames_
std::vector< std::string > argRegNames_
Definition: TDGen.hh:590
TDGen::patInputs
std::string patInputs(const Operation &op, const std::string &oprTypes)
Definition: TDGen.cc:5969
TDGen::operationDAGCanBeMatched
bool operationDAGCanBeMatched(const OperationDAG &op, std::set< std::string > *recursionCycleCheck=NULL, bool recursionHasStore=false)
Definition: TDGen.cc:5274
TDGen::iorOperations_
std::map< TCEString, TCEString > iorOperations_
Contains machine's shl instructions (<ValueType, InstrName>).
Definition: TDGen.hh:568
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
Operand::isAddress
virtual bool isAddress() const
Definition: Operand.cc:328
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
TDGen::createParamDRegNums
void createParamDRegNums(std::ostream &os)
Definition: TDGen.cc:6936
Conversion::toInt
static int toInt(const T &source)
TDGenerator::ValueType::valueTypeStr
TCEString valueTypeStr() const
Definition: TDGen.cc:8772
TDGen::writeVectorBitwiseOperationDefs
void writeVectorBitwiseOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
Definition: TDGen.cc:2601
TDGen::truncOperations_
std::vector< std::pair< const Operation *, TCEString > > truncOperations_
Contains machine's TRUNCxx/CFH instructions (<ValueType, InstrName>).
Definition: TDGen.hh:536
TDGen::llvmGuardRegs_
std::vector< std::string > llvmGuardRegs_
The LLVM register defs used as guards.
Definition: TDGen.hh:584
TDGen::createBoolAndHalfLoadPatterns
void createBoolAndHalfLoadPatterns(std::ostream &os)
Definition: TDGen.cc:8534
TDGen::emulatingOpNodeLLVMName
std::string emulatingOpNodeLLVMName(const Operation &op, const OperationDAG &dag, const OperationNode &node, const std::string &operandTypes)
Definition: TDGen.cc:5600
OperationPool
Definition: OperationPool.hh:52
TDGen::operandTypeToRegister
char operandTypeToRegister(const char &opdType) const
Definition: TDGen.cc:7820
TDGen::immOperandDefs_
std::map< ImmInfoKey, std::string > immOperandDefs_
Maps (operation, operand) pairs to i32 immediate operand definition names.
Definition: TDGen.hh:433
TDGen::associateRegistersWithVectorRegisterClasses
void associateRegistersWithVectorRegisterClasses()
Definition: TDGen.cc:1653
TDGenerator::ValueType::operandType
Operand::OperandType operandType() const
Definition: TDGen.cc:8752
TTAMachine
Definition: Assembler.hh:48
TDGen::writeMiscPatterns
void writeMiscPatterns(std::ostream &o)
Definition: TDGen.cc:8391
TDGen::operationCanBeMatched
bool operationCanBeMatched(const Operation &op, std::set< std::string > *recursionCycleCheck=NULL, bool recursionHasStore=false)
Definition: TDGen.cc:5240
TTAMachine::BaseRegisterFile::size
virtual int size() const
TDGen::createConstShiftPatterns
void createConstShiftPatterns(std::ostream &os)
Definition: TDGen.cc:8525
BoostGraph::rootNodes
virtual NodeSet rootNodes() const
useful utility functions
Operand::isInput
virtual bool isInput() const
Definition: Operand.cc:145
TDGen::genTCEInstrInfoSIMD_copyPhysVectorReg
void genTCEInstrInfoSIMD_copyPhysVectorReg(std::ostream &o) const
Definition: TDGen.cc:3131
TDGen::llvmOperationName
virtual TCEString llvmOperationName(const TCEString &opName) const
Definition: TDGen.cc:5068
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
TTAMachine::BaseRegisterFile::width
virtual int width() const
LLVMBackend::llvmRequiredOpset
static OperationDAGSelector::OperationSet llvmRequiredOpset(bool includeFloatOps, bool isLittleEndian, bool bits64)
Definition: LLVMBackend.cc:150
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
TDGen::GPR
@ GPR
Definition: TDGen.hh:97
MachineInfo::supportsBoolRegisterGuardedJumps
static bool supportsBoolRegisterGuardedJumps(const TTAMachine::Machine &machine)
Definition: MachineInfo.cc:616
TDGen::writeEmulationPattern
void writeEmulationPattern(std::ostream &o, const Operation &op, const OperationDAG &dag)
Definition: TDGen.cc:4759
Operation::numberOfOutputs
virtual int numberOfOutputs() const
Definition: Operation.cc:202
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TDGen::write1bitRegisterInfo
void write1bitRegisterInfo(std::ostream &o)
Definition: TDGen.cc:905
Operand::defaultElementWidth
static int defaultElementWidth(OperandType type)
Definition: Operand.cc:557
TDGen::ALL_REGISTERS
@ ALL_REGISTERS
Definition: TDGen.hh:127
Operation::dag
virtual OperationDAG & dag(int index) const
Definition: Operation.cc:148
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
TDGen::movOperations_
std::set< TCEString > movOperations_
Contains all moves between register classes (<InstrName>).
Definition: TDGen.hh:571
TerminalNode::operandIndex
virtual int operandIndex() const
Definition: TerminalNode.cc:60
TDGen::genGeneratedTCEPlugin_getAddOpcode
void genGeneratedTCEPlugin_getAddOpcode(std::ostream &o) const
Definition: TDGen.cc:3229
TDGen::regs64bit_
std::vector< RegInfo > regs64bit_
Definition: TDGen.hh:582
TDGen::generateLoadStoreCopyGenerator
void generateLoadStoreCopyGenerator(std::ostream &os)
Definition: TDGen.cc:6291
TDGen::createSelectPatterns
virtual void createSelectPatterns(std::ostream &os)
Definition: TDGen.cc:6991
TTAMachine::RegisterFile::zeroRegister
virtual bool zeroRegister() const
Definition: RegisterFile.cc:629
TDGen::operandTypesToRegisters
std::string operandTypesToRegisters(const std::string &opdTypes) const
Definition: TDGen.cc:7811
TDGen::OT_IMM_BOOL
static const char OT_IMM_BOOL
Definition: TDGen.hh:488
TDGen::littleEndian_
bool littleEndian_
Definition: TDGen.hh:612
TDGen::use64bitForFP_
bool use64bitForFP_
Definition: TDGen.hh:618
TDGen::OT_IMM_FP
static const char OT_IMM_FP
Definition: TDGen.hh:490
TDGen::MAX_SUBW_COUNT
static const int MAX_SUBW_COUNT
Maximum number of subwords that any SIMD operation can have.
Definition: TDGen.hh:473
Operand::swap
virtual const std::set< int > & swap() const
Definition: Operand.cc:361
TDGen::OT_REG_HFP
static const char OT_REG_HFP
Definition: TDGen.hh:486
TDGen::genTCETargetLoweringSIMD_getSetCCResultVT
void genTCETargetLoweringSIMD_getSetCCResultVT(std::ostream &o) const
Definition: TDGen.cc:3072