OpenASIP 2.2
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Private Attributes | List of all members
TTAProgram::CodeGenerator Class Reference

#include <CodeGenerator.hh>

Collaboration diagram for TTAProgram::CodeGenerator:
Collaboration graph

Public Types

typedef std::set< TCEStringRegisterSet
 

Public Member Functions

 CodeGenerator (const TTAMachine::Machine &mach)
 
virtual ~CodeGenerator ()
 
TTAProgram::InstructionaddMoveToProcedure (TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)
 
void addAnnotatedMoveToProcedure (TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal, const TTAProgram::ProgramAnnotation &annotation)
 
TTAProgram::TerminalcreateTerminalRegister (const TTAMachine::RegisterFile &rf, int regNum, bool readPort) const
 
TTAProgram::TerminalcreateTerminalRegister (const TCEString &name, bool readPort)
 
TTAProgram::TerminalFUPortcreateTerminalFUPort (const TCEString &opName, int operand)
 
void loadTerminal (TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)
 
void storeTerminal (TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *dstTerminal, TTAProgram::Terminal *srcTerminal)
 
void loadFromAddress (TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, const TCEString &dstReg)
 
void storeToAddress (TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *dstTerminal, const TCEString &srcReg)
 
void loadFromRegisterAddress (TTAProgram::CodeSnippet &dstProcedure, const TCEString &srcReg, const TCEString &dstReg)
 
void storeToRegisterAddress (TTAProgram::CodeSnippet &dstProcedure, const TCEString &dstReg, const TCEString &srcReg)
 
void incrementRegisterAddress (TTAProgram::CodeSnippet &dstProcedure, const TCEString &dstReg, int increment)
 
void decrementRegisterAddress (TTAProgram::CodeSnippet &dstProcedure, const TCEString &dstReg, int decrement)
 
void incrementStackPointer (TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)
 
void decrementStackPointer (TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)
 
void popFromStack (TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::Terminal *dstTerminal)
 
void popRegisterFromStack (TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &dstReg)
 
void pushToStack (TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::Terminal *srcTerminal)
 
void pushRegisterToStack (TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &srcReg)
 
void popFromBuffer (TTAProgram::CodeSnippet &dstProcedure, const TCEString &indexRegister, TTAProgram::Terminal *dstTerminal)
 
void popRegisterFromBuffer (TTAProgram::CodeSnippet &dstProcedure, const TCEString &indexRegister, const TCEString &dstReg)
 
void pushToBuffer (TTAProgram::CodeSnippet &dstProcedure, const TCEString &indexRegister, TTAProgram::Terminal *srcTerminal)
 
void pushRegisterToBuffer (TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &srcReg)
 
void pushInstructionReferenceToStack (TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::InstructionReference &srcAddr)
 
void pushInstructionReferenceToBuffer (TTAProgram::CodeSnippet &dstProcedure, const TCEString &indexRegister, TTAProgram::InstructionReference &srcAddr)
 
void registerJump (TTAProgram::CodeSnippet &dstProcedure, const TCEString &jumpAddrReg)
 
void registerJump (TTAProgram::CodeSnippet &dstProcedure, const TCEString &jumpAddrReg, const TTAProgram::ProgramAnnotation &annotation)
 
std::shared_ptr< TTAProgram::MovecreateJump (TTAProgram::InstructionReference &dst)
 
std::shared_ptr< TTAProgram::MovecreateCall (TTAProgram::InstructionReference &callDst)
 
void createExternalCall (TTAProgram::CodeSnippet &dstProcedure, const TCEString &procedureName)
 
void createCall (TTAProgram::CodeSnippet &dstProcedure, TTAProgram::InstructionReference &callDst)
 
void registerMove (TTAProgram::CodeSnippet &dstProcedure, const TCEString &srcReg, const TCEString &dstReg)
 
void immediateMove (TTAProgram::CodeSnippet &dstProcedure, int imm, const TCEString &dstReg)
 
TTAProgram::ProcedurecreateSchedYieldProcedure (TTAProgram::InstructionReferenceManager &refManager, const TCEString &name, const TCEString &schedProcedureName, const TCEString &stackReg, const TCEString &rvReg, const RegisterSet &saveRegs)
 
std::vector< ProgramOperationPtrcreateForLoopBufferInit (const MoveNode *dynamicLimitMove, int iterationCount, int divider, int loopSize)
 
ProgramOperationPtr createBreakOperation (const MoveNode *jump)
 
ProgramOperationPtr createWhileLoopBufferInit (int loopSize)
 
std::shared_ptr< TTAProgram::MovecreateMove (TTAProgram::Terminal *src, TTAProgram::Terminal *dst)
 

Static Public Member Functions

static TTAProgram::MoveGuardcreateInverseGuard (const TTAProgram::MoveGuard &mg, const TTAMachine::Bus *bus=NULL)
 

Private Attributes

const TTAMachine::Machinemach_
 Target machine.
 
const UniversalMachineuMach_
 Universal machine.
 
int stackAlignment_
 
MachineInfo::OperationSet opset_
 

Detailed Description

CodeGenerator generates code pieces for given Program.

Contains various helper functions for making hand writing of POM easier.

Todo:
Rename to POMGenerator.

Definition at line 53 of file CodeGenerator.hh.

Member Typedef Documentation

◆ RegisterSet

Definition at line 55 of file CodeGenerator.hh.

Constructor & Destructor Documentation

◆ CodeGenerator()

TTAProgram::CodeGenerator::CodeGenerator ( const TTAMachine::Machine mach)
Todo:
This should probably take only Program

Definition at line 45 of file CodeGenerator.cc.

49}
static int maxMemoryAlignment(const TTAMachine::Machine &mach)
static OperationSet getOpset(const TTAMachine::Machine &mach)
const TTAMachine::Machine * mach_
Target machine.
const UniversalMachine * uMach_
Universal machine.
MachineInfo::OperationSet opset_
static UniversalMachine & instance()

References MachineInfo::getOpset(), MachineInfo::maxMemoryAlignment(), opset_, and stackAlignment_.

Here is the call graph for this function:

◆ ~CodeGenerator()

TTAProgram::CodeGenerator::~CodeGenerator ( )
virtual

Definition at line 51 of file CodeGenerator.cc.

51{}

Member Function Documentation

◆ addAnnotatedMoveToProcedure()

void TTAProgram::CodeGenerator::addAnnotatedMoveToProcedure ( TTAProgram::CodeSnippet dstProcedure,
TTAProgram::Terminal srcTerminal,
TTAProgram::Terminal dstTerminal,
const TTAProgram::ProgramAnnotation annotation 
)

Definition at line 71 of file CodeGenerator.cc.

75 {
76
77 TTAProgram::Instruction* newInstr =
80
81 auto movePtr = std::make_shared<TTAProgram::Move>(
82 srcTerminal, dstTerminal, uMach_->universalBus());
83
84 movePtr->addAnnotation(annotation);
85 newInstr->addMove(movePtr);
86
87 dstProcedure.add(newInstr);
88}
static NullInstructionTemplate & instance()
virtual void add(Instruction *ins)
void addMove(std::shared_ptr< Move > move)
TTAMachine::Bus & universalBus() const

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), TTAMachine::NullInstructionTemplate::instance(), uMach_, and UniversalMachine::universalBus().

Referenced by registerJump().

Here is the call graph for this function:

◆ addMoveToProcedure()

TTAProgram::Instruction * TTAProgram::CodeGenerator::addMoveToProcedure ( TTAProgram::CodeSnippet dstProcedure,
TTAProgram::Terminal srcTerminal,
TTAProgram::Terminal dstTerminal 
)

◆ createBreakOperation()

ProgramOperationPtr TTAProgram::CodeGenerator::createBreakOperation ( const MoveNode jump)

Definition at line 1070 of file CodeGenerator.cc.

1070 {
1071 // 4ever loop or buggy input?
1072 if (jump->move().isUnconditional()) {
1073 return nullptr;
1074 }
1075
1076 const TTAMachine::Guard& guard = jump->move().guard().guard();
1077 auto rg = dynamic_cast<const TTAMachine::RegisterGuard*>(&guard);
1078 if (!rg) {
1079 return nullptr;
1080 }
1081
1082 // TODO: change eq->ne or add xor to support non-inverted without
1083 // both ops.
1084 const char* opName = rg->isInverted() ? "lbufc" : "lbufz";
1086 if (!cu.hasOperation(opName)) {
1087 return nullptr;
1088 }
1089
1092 *uMach_->universalFunctionUnit().operation(opName), 1);
1093
1094 // create terminal for reading register
1095 auto src = createTerminalRegister(
1096 *rg->registerFile(), rg->registerIndex(), true);
1097
1098 MoveNode* loopSizeMN = new MoveNode(createMove(src, dst));
1099
1101 const Operation& op = pool.operation(opName);
1103 po->addInputNode(*loopSizeMN);
1104 loopSizeMN->addDestinationOperationPtr(po);
1105 return po;
1106}
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition MoveNode.hh:53
TTAProgram::Move & move()
void addDestinationOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:533
virtual bool hasOperation(const std::string &name) const
virtual bool isInverted() const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
TTAProgram::Terminal * createTerminalRegister(const TTAMachine::RegisterFile &rf, int regNum, bool readPort) const
std::shared_ptr< TTAProgram::Move > createMove(TTAProgram::Terminal *src, TTAProgram::Terminal *dst)
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isUnconditional() const
Definition Move.cc:154
virtual TTAMachine::HWOperation * operation(const std::string &name) const
UniversalFunctionUnit & universalFunctionUnit() const
std::unique_ptr< OperationPool > pool

References MoveNode::addDestinationOperationPtr(), TTAMachine::Machine::controlUnit(), createMove(), createTerminalRegister(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::Guard::isInverted(), TTAProgram::Move::isUnconditional(), mach_, MoveNode::move(), UniversalFunctionUnit::operation(), uMach_, and UniversalMachine::universalFunctionUnit().

Here is the call graph for this function:

◆ createCall() [1/2]

void TTAProgram::CodeGenerator::createCall ( TTAProgram::CodeSnippet dstProcedure,
TTAProgram::InstructionReference callDst 
)

Creates a call move and adds it to the given procedure.

Definition at line 689 of file CodeGenerator.cc.

691 {
692
695
696 TTAProgram::TerminalFUPort* dstTerminal =
697 createTerminalFUPort("call", 1);
698
699 addMoveToProcedure(dstProcedure, srcTerminal, dstTerminal);
700}
TTAProgram::TerminalFUPort * createTerminalFUPort(const TCEString &opName, int operand)
TTAProgram::Instruction * addMoveToProcedure(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)

References addMoveToProcedure(), and createTerminalFUPort().

Here is the call graph for this function:

◆ createCall() [2/2]

std::shared_ptr< TTAProgram::Move > TTAProgram::CodeGenerator::createCall ( TTAProgram::InstructionReference callDst)

Creates a call move.

Definition at line 657 of file CodeGenerator.cc.

657 {
660
661 TTAProgram::TerminalFUPort* dstTerminal =
662 createTerminalFUPort("call", 1);
663 return std::make_shared<TTAProgram::Move>(
664 srcTerminal, dstTerminal, uMach_->universalBus());
665}

References createTerminalFUPort(), uMach_, and UniversalMachine::universalBus().

Here is the call graph for this function:

◆ createExternalCall()

void TTAProgram::CodeGenerator::createExternalCall ( TTAProgram::CodeSnippet dstProcedure,
const TCEString procedureName 
)

Creates an external call move.

Definition at line 671 of file CodeGenerator.cc.

673 {
674
676 new TTAProgram::TerminalSymbolReference(procedureName);
677
678 TTAProgram::TerminalFUPort* dstTerminal =
679 createTerminalFUPort("call", 1);
680
681 addMoveToProcedure(dstProcedure, srcTerminal, dstTerminal);
682}

References addMoveToProcedure(), and createTerminalFUPort().

Referenced by createSchedYieldProcedure().

Here is the call graph for this function:

◆ createForLoopBufferInit()

std::vector< ProgramOperationPtr > TTAProgram::CodeGenerator::createForLoopBufferInit ( const MoveNode dynamicLimitMove,
int  iterationCount,
int  divider,
int  loopSize 
)

Definition at line 898 of file CodeGenerator.cc.

899 {
900
901 std::vector<ProgramOperationPtr> res;
902 // is power-of-2?
903 if (divider & (divider-1)) {
904 return res;
905 }
906
907 const char* opName = "lbufs";
909 if (!cu.hasOperation(opName)) {
910 return res;
911 }
912
914 const Operation& lbufsOp = pool.operation(opName);
915 SimValue loopSizeSV(MathTools::requiredBitsSigned(loopSize));
916 loopSizeSV = loopSize;
917 TTAProgram::TerminalImmediate* loopSizeSrc =
918 new TTAProgram::TerminalImmediate(loopSizeSV);
919
920 MoveNode* iterCountMN = NULL;
921 ProgramOperationPtr shiftPO;
923
924 // TODO: universalmachine is buggy. these should be in control unit,
925 // not universalfunction unit
926 TTAProgram::TerminalFUPort* iterCountDst =
928 *uMach_->universalFunctionUnit().operation(opName), 1);
929
930 TTAProgram::TerminalFUPort* loopSizeDst =
932 *uMach_->universalFunctionUnit().operation(opName), 2);
933
934 // static iteration count
935 if (dynamicLimitMove == NULL) {
936 SimValue iterCountSV(MathTools::requiredBitsSigned(iterationCount));
937 iterCountSV = iterationCount;
938 TTAProgram::Terminal* iterCountSrc = new TTAProgram::TerminalImmediate(iterCountSV);
939 iterCountMN = new MoveNode(createMove(iterCountSrc, iterCountDst));
940 } else {
941 bool decrement = false;
942 bool increment = false;
943 switch (iterationCount) {
944 case -1:
945 decrement = true;
946 case 0:
947 break;
948 default:
949 if (iterationCount > 0)
950 increment = true;
951 else
952 return res;
953 }
954 TTAProgram::Terminal* counterValSrc = NULL;
955 if (dynamicLimitMove->isSourceOperation())
956 counterValSrc = dynamicLimitMove->move().destination().copy();
957 else
958 counterValSrc = dynamicLimitMove->move().source().copy();
959
960 // if divider not 1, need shift of to scale it down.
961 TCEString adjustName = decrement ? "sub" : "add";
962 if (mach_->is64bit()) {
963 adjustName << "64";
964 }
965 if (decrement || increment) {
966 const Operation& subOp = pool.operation(adjustName.c_str());
967 subPO = std::make_shared<ProgramOperation>(subOp);
968
969 // signed 1 is 2 bits.
970 TTAProgram::TerminalImmediate* subAmountSrc =
972 SimValue(abs(iterationCount),
973 MathTools::requiredBitsSigned(iterationCount)));
974
975 TTAProgram::TerminalFUPort* subAmntDst = createTerminalFUPort(adjustName, 2);
976 TTAProgram::TerminalFUPort* subRes = createTerminalFUPort(adjustName, 3);
977
978 MoveNode* subAmtMN = new MoveNode(createMove(subAmountSrc, subAmntDst));
979 subPO->addInputNode(*subAmtMN);
980 subAmtMN->addDestinationOperationPtr(subPO);
981
982 iterCountMN = new MoveNode(createMove(subRes, iterCountDst));
983 subPO->addOutputNode(*iterCountMN);
984 iterCountMN->setSourceOperationPtr(subPO);
985
986 res.push_back(subPO);
987 // first input not here but later
988 }
989
990 if (divider > 1) {
991 TCEString shiftName = "shr";
992 if (mach_->is64bit()) {
993 shiftName << "64";
994 }
995 const Operation& shiftOp = pool.operation(shiftName.c_str());
996
997 int shiftAmount = MathTools::ceil_log2(divider);
998
999 SimValue shiftAmountSV(MathTools::requiredBitsSigned(shiftAmount));
1000 shiftAmountSV = shiftAmount;
1001
1002 TTAProgram::TerminalImmediate* shiftAmountSrc =
1003 new TTAProgram::TerminalImmediate(shiftAmountSV);
1004
1005 // create terminal references
1006 TTAProgram::TerminalFUPort* shiftValDst =
1007 createTerminalFUPort(shiftName, 1);
1008 TTAProgram::TerminalFUPort* shiftAmntDst =
1009 createTerminalFUPort(shiftName, 2);
1010 TTAProgram::TerminalFUPort* shiftRes =
1011 createTerminalFUPort(shiftName, 3);
1012
1013 MoveNode* shiftValMN = new MoveNode(createMove(counterValSrc, shiftValDst));
1014 MoveNode* shiftAmtMN = new MoveNode(createMove(shiftAmountSrc, shiftAmntDst));
1015
1016 shiftPO = std::make_shared<ProgramOperation>(shiftOp);
1017 shiftPO->addInputNode(*shiftValMN);
1018 shiftPO->addInputNode(*shiftAmtMN);
1019 shiftValMN->addDestinationOperationPtr(shiftPO);
1020 shiftAmtMN->addDestinationOperationPtr(shiftPO);
1021
1022 // push before the possible sub
1023 res.insert(res.begin(),shiftPO);
1024 MoveNode* shift2dec = NULL;
1025 if (!(decrement||increment)) {
1026 iterCountMN = new MoveNode(createMove(shiftRes, iterCountDst));
1027 shiftPO->addOutputNode(*iterCountMN);
1028 iterCountMN->setSourceOperationPtr(shiftPO);
1029 } else {
1030 // use dsub operation
1031 TTAProgram::TerminalFUPort* subValDst =
1032 createTerminalFUPort(adjustName, 1);
1033 shift2dec = new MoveNode(createMove(shiftRes, subValDst));
1034 subPO->addInputNode(*shift2dec);
1035 shift2dec->addDestinationOperationPtr(subPO);
1036
1037 shiftPO->addOutputNode(*shift2dec);
1038 shift2dec->setSourceOperationPtr(shiftPO);
1039 }
1040 } else { // no shifting, maybe decrement
1041 if (decrement||increment) {
1042 // create terminal references
1043 TTAProgram::TerminalFUPort* subValDst =
1044 createTerminalFUPort(adjustName, 1);
1045 MoveNode* subValMN = new MoveNode(createMove(counterValSrc, subValDst));
1046 subPO->addInputNode(*subValMN);
1047 subValMN->addDestinationOperationPtr(subPO);
1048 } else {
1049 iterCountMN = new MoveNode(createMove(counterValSrc, iterCountDst));
1050 }
1051 }
1052 }
1053 MoveNode* loopSizeMN = new MoveNode(createMove(loopSizeSrc, loopSizeDst));
1054
1055 ProgramOperationPtr loopBusInitOp(new ProgramOperation(lbufsOp));
1056 loopBusInitOp->addInputNode(*iterCountMN);
1057 loopBusInitOp->addInputNode(*loopSizeMN);
1058 iterCountMN->addDestinationOperationPtr(loopBusInitOp);
1059 loopSizeMN->addDestinationOperationPtr(loopBusInitOp);
1060
1061 res.push_back(loopBusInitOp);
1062 return res;
1063}
static int requiredBitsSigned(SLongWord number)
static int ceil_log2(long unsigned int number)
void setSourceOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:541
bool isSourceOperation() const
Definition MoveNode.cc:168
bool is64bit() const
Definition Machine.hh:260
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
virtual Terminal * copy() const =0

References MoveNode::addDestinationOperationPtr(), MathTools::ceil_log2(), TTAMachine::Machine::controlUnit(), TTAProgram::Terminal::copy(), createMove(), createTerminalFUPort(), TTAProgram::Move::destination(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::Machine::is64bit(), MoveNode::isSourceOperation(), mach_, MoveNode::move(), UniversalFunctionUnit::operation(), MathTools::requiredBitsSigned(), MoveNode::setSourceOperationPtr(), TTAProgram::Move::source(), uMach_, and UniversalMachine::universalFunctionUnit().

Here is the call graph for this function:

◆ createInverseGuard()

TTAProgram::MoveGuard * TTAProgram::CodeGenerator::createInverseGuard ( const TTAProgram::MoveGuard mg,
const TTAMachine::Bus bus = NULL 
)
static

Creates a guard with same guard register etc but inverted. The guard must be found from the given bus if bus given.

@TODO: support for port guards

Parameters
mgguard to inverse
busbus where the guard must be. if null same as bug of mg.
Returns
new MoveGuard that is given guard inverted, NULL if cannot create.

Definition at line 837 of file CodeGenerator.cc.

838 {
839
840 const TTAMachine::Guard& g = mg.guard();
841 if (bus == NULL) {
842 bus = g.parentBus();
843 }
844
845 bool inv = g.isInverted();
846 const TTAMachine::RegisterGuard* rg =
847 dynamic_cast<const TTAMachine::RegisterGuard*>(&g);
848 if (rg != NULL) {
849 const TTAMachine::RegisterFile* rf = rg->registerFile();
850 int regIndex = rg->registerIndex();
851
852 // fake guard to be bypassed as port guard?
853 if (bus == nullptr) {
854 return new TTAProgram::MoveGuard(
856 !rg->isInverted(), *rg->registerFile(), rg->registerIndex(), nullptr));
857 }
858 // find guard
859 for (int i = 0 ; i < bus->guardCount(); i++) {
860 const TTAMachine::Guard *g2 = bus->guard(i);
861 const TTAMachine::RegisterGuard* rg2 =
862 dynamic_cast<const TTAMachine::RegisterGuard*>(g2);
863 if (rg2) {
864 if( rg2->registerFile() == rf &&
865 rg2->registerIndex() == regIndex &&
866 rg2->isInverted() == !inv ) {
867 return new TTAProgram::MoveGuard(*rg2);
868 }
869 }
870 }
871 }
872 const TTAMachine::PortGuard* pg =
873 dynamic_cast<const TTAMachine::PortGuard*>(&g);
874 if (pg) {
875 auto port = pg->port();
876
877 // find guard
878 for (int i = 0 ; i < bus->guardCount(); i++) {
879 const TTAMachine::Guard *g2 = bus->guard(i);
880 const TTAMachine::PortGuard* pg2 =
881 dynamic_cast<const TTAMachine::PortGuard*>(g2);
882 if (pg2 && pg2->port() == port &&
883 pg2->isInverted() == !inv) {
884 return new TTAProgram::MoveGuard(*pg2);
885 }
886 }
887 }
888
889 return NULL;
890}
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
virtual Bus * parentBus() const
FUPort * port() const
const RegisterFile * registerFile() const

References TTAProgram::MoveGuard::guard(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAMachine::Guard::isInverted(), TTAMachine::Guard::parentBus(), TTAMachine::PortGuard::port(), TTAMachine::RegisterGuard::registerFile(), and TTAMachine::RegisterGuard::registerIndex().

Referenced by Peel2BBLoops::appendBB(), SimpleIfConverter::canConvert(), CopyingDelaySlotFiller::collectMoves(), CopyingDelaySlotFiller::fillDelaySlots(), PreOptimizer::inverseGuardsOfHeads(), BasicBlockScheduler::tryToOptimizeWaw(), and BUBasicBlockScheduler::tryToOptimizeWaw().

Here is the call graph for this function:

◆ createJump()

std::shared_ptr< TTAProgram::Move > TTAProgram::CodeGenerator::createJump ( TTAProgram::InstructionReference dst)

Definition at line 640 of file CodeGenerator.cc.

640 {
641
642 TTAProgram::TerminalFUPort* jump1Terminal =
643 createTerminalFUPort("jump", 1);
644
645 TTAProgram::Terminal* jump0Terminal =
647
648 return std::make_shared<TTAProgram::Move>(jump0Terminal, jump1Terminal,
650}

References createTerminalFUPort(), uMach_, and UniversalMachine::universalBus().

Referenced by SimpleIfConverter::addJump().

Here is the call graph for this function:

◆ createMove()

std::shared_ptr< TTAProgram::Move > TTAProgram::CodeGenerator::createMove ( TTAProgram::Terminal src,
TTAProgram::Terminal dst 
)

Definition at line 1065 of file CodeGenerator.cc.

1066 {
1067 return std::make_shared<TTAProgram::Move>(src, dst, uMach_->universalBus());
1068}

References uMach_, and UniversalMachine::universalBus().

Referenced by createBreakOperation(), createForLoopBufferInit(), and createWhileLoopBufferInit().

Here is the call graph for this function:

◆ createSchedYieldProcedure()

TTAProgram::Procedure * TTAProgram::CodeGenerator::createSchedYieldProcedure ( TTAProgram::InstructionReferenceManager refManager,
const TCEString name,
const TCEString schedProcedureName,
const TCEString stackReg,
const TCEString rvReg,
const RegisterSet saveRegs 
)

Creates yield function which saves requested registers.

Parameters
refManagerReference manager of destination program.
nameName for the created procedure.
schedProcedureScheduler function to call sp = schedule(sp)
stackRegStack register name assigned for program.
rvRegReturn value register name.
saveRegsSet of registers, which should be saved.

Definition at line 743 of file CodeGenerator.cc.

749 {
750
751 TTAProgram::Procedure* retVal =
753 name, *mach_->controlUnit()->addressSpace());
754
755 // *** Push registers to stack
756 for(RegisterSet::const_iterator i = saveRegs.begin();
757 i != saveRegs.end(); i++) {
758 pushRegisterToStack(*retVal, stackReg, *i);
759 }
760
761 // *** Push return address to stack as well
762 pushRegisterToStack(*retVal, stackReg, "RA");
763
764 // *** Create empty instruction to be used as yield_return destination
765 TTAProgram::Instruction* yeldReturnInstruction =
768
769 TTAProgram::InstructionReference yeldReturnReference =
770 refManager.createReference(*yeldReturnInstruction);
771
772 // *** Push InstructionReference to sp reading instruction to stack
773 pushInstructionReferenceToStack(*retVal, stackReg, yeldReturnReference);
774
775 // *** Save sp, switch thread and update sp
776
777 // put stackpointer address to be parameter
778#ifdef ALL_STACK_PARAMETERS
779 pushRegisterToStack(*retVal, stackReg, stackReg);
780#else
781 registerMove(*retVal, stackReg, rvReg);
782#endif
783 createExternalCall(*retVal, schedProcedureName);
784
785 // read new sp value from rv register
786 registerMove(*retVal, rvReg, stackReg);
787
788#ifdef ALL_STACK_PARAMETERS
789 // need to pop the parameter from stack
790 incrementStackPointer(*retVal, stackReg);
791#endif
792
793 // read yeld address from stack
794 popRegisterFromStack(*retVal, stackReg, "RA");
795
796 // jump to yeld point
799
800 // add previously created "label" instruction
801 retVal->add(yeldReturnInstruction);
802
803 // restore return address
804 popRegisterFromStack(*retVal, stackReg, "RA");
805
806 // read registers from stack
807 for(RegisterSet::const_reverse_iterator i = saveRegs.rbegin();
808 i != saveRegs.rend(); i++) {
809 popRegisterFromStack(*retVal, stackReg, *i);
810 }
811
812 // jump to yeld point
813 registerJump(*retVal, "RA");
814
815 // remove the placeholder instr.
816 refManager.replace(
817 *yeldReturnInstruction,
818 retVal->nextInstruction(*yeldReturnInstruction));
819
820 retVal->remove(*yeldReturnInstruction);
821 // debug print created function
822
823 return retVal;
824}
virtual AddressSpace * addressSpace() const
void registerMove(TTAProgram::CodeSnippet &dstProcedure, const TCEString &srcReg, const TCEString &dstReg)
void createExternalCall(TTAProgram::CodeSnippet &dstProcedure, const TCEString &procedureName)
void pushRegisterToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &srcReg)
void registerJump(TTAProgram::CodeSnippet &dstProcedure, const TCEString &jumpAddrReg)
void incrementStackPointer(TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)
void pushInstructionReferenceToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::InstructionReference &srcAddr)
void popRegisterFromStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &dstReg)
virtual Instruction & nextInstruction(const Instruction &ins) const
void replace(Instruction &insA, Instruction &insB)
InstructionReference createReference(Instruction &ins)
void add(Instruction *ins)
Definition Procedure.cc:160
void remove(Instruction &ins)
Definition Procedure.cc:297

References TTAProgram::Procedure::add(), TTAMachine::FunctionUnit::addressSpace(), TTAProgram::ProgramAnnotation::ANN_JUMP_TO_NEXT, TTAMachine::Machine::controlUnit(), createExternalCall(), TTAProgram::InstructionReferenceManager::createReference(), incrementStackPointer(), TTAMachine::NullInstructionTemplate::instance(), mach_, TTAProgram::CodeSnippet::nextInstruction(), popRegisterFromStack(), pushInstructionReferenceToStack(), pushRegisterToStack(), registerJump(), registerMove(), TTAProgram::Procedure::remove(), and TTAProgram::InstructionReferenceManager::replace().

Here is the call graph for this function:

◆ createTerminalFUPort()

TTAProgram::TerminalFUPort * TTAProgram::CodeGenerator::createTerminalFUPort ( const TCEString opName,
int  operand = 0 
)

If operand is not given return return address terminal.

Definition at line 94 of file CodeGenerator.cc.

94 {
95 if (operand != 0) {
96
98 const Operation& op = pool.operation(opName.c_str());
99 if (op.isControlFlowOperation()) {
101 *uMach_->controlUnit()->operation(opName);
102 return new TTAProgram::TerminalFUPort(hwOp, operand);
103 } else {
106 return new TTAProgram::TerminalFUPort(hwOp, operand);
107 }
108 } else {
111 }
112}
virtual bool isControlFlowOperation() const
Definition Operation.cc:294
SpecialRegisterPort * returnAddressPort() const
virtual HWOperation * operation(const std::string &name) const

References TTAMachine::Machine::controlUnit(), Operation::isControlFlowOperation(), TTAMachine::FunctionUnit::operation(), UniversalFunctionUnit::operation(), TTAMachine::ControlUnit::returnAddressPort(), uMach_, and UniversalMachine::universalFunctionUnit().

Referenced by createCall(), createCall(), createExternalCall(), createForLoopBufferInit(), createJump(), createTerminalRegister(), decrementRegisterAddress(), llvm::LLVMTCEBuilder::emitGlobalXXtructorCalls(), CallsToJumps::handleControlFlowGraph(), incrementRegisterAddress(), loadTerminal(), registerJump(), registerJump(), BFCopyRegWithOp::splitMove(), and storeTerminal().

Here is the call graph for this function:

◆ createTerminalRegister() [1/2]

TTAProgram::Terminal * TTAProgram::CodeGenerator::createTerminalRegister ( const TCEString name,
bool  readPort 
)

Definition at line 135 of file CodeGenerator.cc.

135 {
136
137 if (name == "RA") {
138 return createTerminalFUPort("RA");
139 } else {
140 const TTAMachine::RegisterFile* rf = NULL;
141 size_t findResult = name.find(".");
142 int regNum;
143 if (findResult == std::string::npos) {
145 regNum = Conversion::toInt(name.substr(1));
146
147 } else {
148 TCEString rfName = name.substr(0, findResult);
151 rf = regNav.item(rfName);
152 regNum = Conversion::toInt(
153 name.substr(findResult + 1, name.length()-findResult+1));
154 }
155 return createTerminalRegister(*rf, regNum, readPort);
156 }
157
158 return NULL;
159}
static int toInt(const T &source)
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
UnboundedRegisterFile & integerRegisterFile() const

References createTerminalFUPort(), createTerminalRegister(), UniversalMachine::integerRegisterFile(), TTAMachine::Machine::Navigator< ComponentType >::item(), mach_, TTAMachine::Machine::registerFileNavigator(), Conversion::toInt(), and uMach_.

Here is the call graph for this function:

◆ createTerminalRegister() [2/2]

TTAProgram::Terminal * TTAProgram::CodeGenerator::createTerminalRegister ( const TTAMachine::RegisterFile rf,
int  regNum,
bool  readPort 
) const

Definition at line 115 of file CodeGenerator.cc.

116 {
117 for (int i = 0; i < rf.portCount(); i++) {
118 if (readPort) {
119 if (rf.port(i)->isOutput()) {
121 *rf.port(i), regNum);
122 }
123 } else {
124 if (rf.port(i)->isInput()) {
126 *rf.port(i), regNum);
127 }
128 }
129 }
130 return NULL;
131}
virtual RFPort * port(const std::string &name) const
virtual bool isInput() const
Definition Port.cc:298
virtual bool isOutput() const
Definition Port.cc:308
virtual int portCount() const
Definition Unit.cc:135

References TTAMachine::Port::isInput(), TTAMachine::Port::isOutput(), TTAMachine::BaseRegisterFile::port(), and TTAMachine::Unit::portCount().

Referenced by createBreakOperation(), createTerminalRegister(), decrementRegisterAddress(), llvm::LLVMTCEBuilder::emitLongjmp(), llvm::LLVMTCEBuilder::emitReadSP(), llvm::LLVMTCEBuilder::emitReturnTo(), llvm::LLVMTCEBuilder::emitSetjmp(), llvm::LLVMTCEBuilder::emitWriteSP(), immediateMove(), incrementRegisterAddress(), loadFromAddress(), loadFromRegisterAddress(), popFromBuffer(), popFromStack(), pushToBuffer(), pushToStack(), registerJump(), registerJump(), registerMove(), storeToAddress(), and storeToRegisterAddress().

Here is the call graph for this function:

◆ createWhileLoopBufferInit()

ProgramOperationPtr TTAProgram::CodeGenerator::createWhileLoopBufferInit ( int  loopSize)

Definition at line 1116 of file CodeGenerator.cc.

1116 {
1117 const char* opName = "infloop";
1119 if (!cu.hasOperation(opName)) {
1120 return nullptr;
1121 }
1122
1123 TTAProgram::TerminalFUPort* loopSizeDst =
1125 *uMach_->universalFunctionUnit().operation(opName), 1);
1126
1128 const Operation& lbufsOp = pool.operation(opName);
1129 SimValue loopSizeSV(MathTools::requiredBitsSigned(loopSize));
1130 loopSizeSV = loopSize;
1131 TTAProgram::TerminalImmediate* loopSizeSrc =
1132 new TTAProgram::TerminalImmediate(loopSizeSV);
1133
1134 MoveNode* loopSizeMN = new MoveNode(createMove(loopSizeSrc, loopSizeDst));
1135
1136 ProgramOperationPtr loopBufInitOp(new ProgramOperation(lbufsOp));
1137 loopBufInitOp->addInputNode(*loopSizeMN);
1138 loopSizeMN->addDestinationOperationPtr(loopBufInitOp);
1139 return loopBufInitOp;
1140}

References MoveNode::addDestinationOperationPtr(), TTAMachine::Machine::controlUnit(), createMove(), TTAMachine::FunctionUnit::hasOperation(), mach_, UniversalFunctionUnit::operation(), MathTools::requiredBitsSigned(), uMach_, and UniversalMachine::universalFunctionUnit().

Here is the call graph for this function:

◆ decrementRegisterAddress()

void TTAProgram::CodeGenerator::decrementRegisterAddress ( TTAProgram::CodeSnippet dstProcedure,
const TCEString dstReg,
int  decrement 
)

Decrement address in a register by value of decrement.

Parameters
dstProcedureProcedure to add the moves to.
dstRegRegister to decrement.
decrementHow much to decrement.

Definition at line 380 of file CodeGenerator.cc.

382 {
383
384 TCEString subOp = mach_->is64bit() ? "sub64" : "sub";
385
386 // create terminal references
387 TTAProgram::Terminal* regReadTerminal =
388 createTerminalRegister(dstReg, true);
389
390 TTAProgram::Terminal* regWriteTerminal =
391 createTerminalRegister(dstReg, false);
392
393 // TODO: immediate creator function which calculates immWidth
394 SimValue immVal(MathTools::requiredBitsSigned(decrement));
395 immVal = decrement;
396 TTAProgram::TerminalImmediate* imm4Terminal =
398
399 TTAProgram::TerminalFUPort* sub1Terminal =
400 createTerminalFUPort(subOp, 1);
401
402 TTAProgram::TerminalFUPort* sub2Terminal =
403 createTerminalFUPort(subOp, 2);
404
405 TTAProgram::TerminalFUPort* sub3Terminal =
406 createTerminalFUPort(subOp, 3);
407
408 // dstProcedure->add(
409 // new CodeSnippet("sp -> sub.1; 4 -> sub.2; sub.3 -> sp;"
410 // "sp -> stw.1; srcTerm -> stw.2;"));
411 addMoveToProcedure(dstProcedure, regReadTerminal, sub1Terminal);
412 addMoveToProcedure(dstProcedure, imm4Terminal, sub2Terminal);
413 addMoveToProcedure(dstProcedure, sub3Terminal, regWriteTerminal);
414}

References addMoveToProcedure(), createTerminalFUPort(), createTerminalRegister(), TTAMachine::Machine::is64bit(), mach_, and MathTools::requiredBitsSigned().

Referenced by decrementStackPointer(), popFromBuffer(), and popRegisterFromBuffer().

Here is the call graph for this function:

◆ decrementStackPointer()

void TTAProgram::CodeGenerator::decrementStackPointer ( TTAProgram::CodeSnippet dstProcedure,
const TCEString spReg 
)

Definition at line 423 of file CodeGenerator.cc.

424 {
425 decrementRegisterAddress(dstProcedure, spReg, stackAlignment_);
426}
void decrementRegisterAddress(TTAProgram::CodeSnippet &dstProcedure, const TCEString &dstReg, int decrement)

References decrementRegisterAddress(), and stackAlignment_.

Referenced by llvm::LLVMTCEBuilder::emitSetjmp(), pushRegisterToStack(), and pushToStack().

Here is the call graph for this function:

◆ immediateMove()

void TTAProgram::CodeGenerator::immediateMove ( TTAProgram::CodeSnippet dstProcedure,
int  imm,
const TCEString dstReg 
)

Definition at line 717 of file CodeGenerator.cc.

719 {
720
721 SimValue immVal(32);
722 immVal = imm;
723 TTAProgram::TerminalImmediate* srcTerminal =
725
726 TTAProgram::Terminal* dstTerminal =
727 createTerminalRegister(dstReg, false);
728
729 addMoveToProcedure(dstProcedure, srcTerminal, dstTerminal);
730}

References addMoveToProcedure(), and createTerminalRegister().

Here is the call graph for this function:

◆ incrementRegisterAddress()

void TTAProgram::CodeGenerator::incrementRegisterAddress ( TTAProgram::CodeSnippet dstProcedure,
const TCEString dstReg,
int  increment 
)

Increment address in a register by value of increment.

Parameters
dstProcedureProcedure to add the moves to.
dstRegRegister to increment.
incrementHow much to increment.

Definition at line 335 of file CodeGenerator.cc.

337 {
338
339 TCEString addOp = mach_->is64bit() ? "add64" : "add";
340
341 // create terminal references
342 TTAProgram::Terminal* regReadTerminal =
343 createTerminalRegister(dstReg, true);
344
345 TTAProgram::Terminal* regWriteTerminal =
346 createTerminalRegister(dstReg, false);
347
348 // TODO: immediate creator function which calculates immWidth
349 SimValue immVal(MathTools::requiredBitsSigned(increment));
350 immVal = increment;
351 TTAProgram::TerminalImmediate* imm4Terminal =
353
354 TTAProgram::TerminalFUPort* add1Terminal =
355 createTerminalFUPort(addOp, 1);
356
357 TTAProgram::TerminalFUPort* add2Terminal =
358 createTerminalFUPort(addOp, 2);
359
360 TTAProgram::TerminalFUPort* add3Terminal =
361 createTerminalFUPort(addOp, 3);
362
363 // dstProcedure->add(
364 // new CodeSnippet("sp -> ldw.1; ldw.2 -> dstReg; "
365 // "4 -> add.1; sp -> add.2; add.3 -> sp"));
366
367 addMoveToProcedure(dstProcedure, imm4Terminal, add1Terminal);
368 addMoveToProcedure(dstProcedure, regReadTerminal, add2Terminal);
369 addMoveToProcedure(dstProcedure, add3Terminal, regWriteTerminal);
370}

References addMoveToProcedure(), createTerminalFUPort(), createTerminalRegister(), TTAMachine::Machine::is64bit(), mach_, and MathTools::requiredBitsSigned().

Referenced by incrementStackPointer(), pushRegisterToBuffer(), and pushToBuffer().

Here is the call graph for this function:

◆ incrementStackPointer()

void TTAProgram::CodeGenerator::incrementStackPointer ( TTAProgram::CodeSnippet dstProcedure,
const TCEString spReg 
)

Definition at line 417 of file CodeGenerator.cc.

418 {
419 incrementRegisterAddress(dstProcedure, spReg, stackAlignment_);
420}
void incrementRegisterAddress(TTAProgram::CodeSnippet &dstProcedure, const TCEString &dstReg, int increment)

References incrementRegisterAddress(), and stackAlignment_.

Referenced by createSchedYieldProcedure(), llvm::LLVMTCEBuilder::emitLongjmp(), llvm::LLVMTCEBuilder::emitSetjmp(), popFromStack(), and popRegisterFromStack().

Here is the call graph for this function:

◆ loadFromAddress()

void TTAProgram::CodeGenerator::loadFromAddress ( TTAProgram::CodeSnippet dstProcedure,
TTAProgram::Terminal srcTerminal,
const TCEString dstReg 
)

Loads register from address in a terminal.

Parameters
dstProcedureProcedure to add the moves to.
srcTerminalAddress to load from.
dstRegRegister to store loaded value.

Definition at line 256 of file CodeGenerator.cc.

259 {
260
261 // create terminal references
262 TTAProgram::Terminal* dstRegTerminal =
263 createTerminalRegister(dstReg, false);
264
265 loadTerminal(dstProcedure, srcTerminal, dstRegTerminal);
266}
void loadTerminal(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)

References createTerminalRegister(), and loadTerminal().

Referenced by loadFromRegisterAddress().

Here is the call graph for this function:

◆ loadFromRegisterAddress()

void TTAProgram::CodeGenerator::loadFromRegisterAddress ( TTAProgram::CodeSnippet dstProcedure,
const TCEString srcReg,
const TCEString dstReg 
)

Loads register from address in another register.

Parameters
dstProcedureProcedure to add the moves to.
srcRegAddress to load from.
dstRegRegister to store loaded value.

Definition at line 295 of file CodeGenerator.cc.

298 {
299
300 // create terminal references
301 TTAProgram::Terminal* srcTerminal =
302 createTerminalRegister(srcReg, true);
303
304 loadFromAddress(dstProcedure, srcTerminal, dstReg);
305}
void loadFromAddress(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, const TCEString &dstReg)

References createTerminalRegister(), and loadFromAddress().

Referenced by llvm::LLVMTCEBuilder::emitLongjmp(), popRegisterFromBuffer(), and popRegisterFromStack().

Here is the call graph for this function:

◆ loadTerminal()

void TTAProgram::CodeGenerator::loadTerminal ( TTAProgram::CodeSnippet dstProcedure,
TTAProgram::Terminal srcTerminal,
TTAProgram::Terminal dstTerminal 
)

Loads terminal from address in a terminal.

Parameters
dstProcedureProcedure to add the moves to.
srcTerminalAddress to load from.
dstTerminalTerminal to store loaded value.

Definition at line 169 of file CodeGenerator.cc.

172 {
173 TCEString loadOp;
174 int width = 0;
175 if (dstTerminal->isGPR()) {
176 width = dstTerminal->registerFile().width();
177 }
178
179 int defaultWidth = mach_->is64bit() ? 64 : 32;
180 if (width < defaultWidth) {
181 width = defaultWidth;
182 }
183 if (mach_->isLittleEndian()) {
184 loadOp = (boost::format("ld%d") % width).str();
185 } else {
186 loadOp = "ldw";
187 }
188 if (opset_.count(loadOp) == 0) {
190 (boost::format("Operation %s not found in the machine") % loadOp)
191 .str());
192 }
193
194 // create terminal references
195 TTAProgram::TerminalFUPort* load1Terminal =
196 createTerminalFUPort(loadOp, 1);
197
198 TTAProgram::TerminalFUPort* load2Terminal =
199 createTerminalFUPort(loadOp, 2);
200
201 addMoveToProcedure(dstProcedure, srcTerminal, load1Terminal);
202 addMoveToProcedure(dstProcedure, load2Terminal, dstTerminal);
203}
#define abortWithError(message)
virtual int width() const
bool isLittleEndian() const
Definition Machine.hh:258
virtual bool isGPR() const
Definition Terminal.cc:107
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225

References abortWithError, addMoveToProcedure(), createTerminalFUPort(), TTAMachine::Machine::is64bit(), TTAProgram::Terminal::isGPR(), TTAMachine::Machine::isLittleEndian(), mach_, opset_, TTAProgram::Terminal::registerFile(), and TTAMachine::BaseRegisterFile::width().

Referenced by llvm::LLVMTCEBuilder::createSPInitLoad(), loadFromAddress(), popFromBuffer(), and popFromStack().

Here is the call graph for this function:

◆ popFromBuffer()

void TTAProgram::CodeGenerator::popFromBuffer ( TTAProgram::CodeSnippet dstProcedure,
const TCEString indexRegister,
TTAProgram::Terminal dstTerminal 
)

TODO Decide how much the register value should be incremented in the following buffer operations. Right now it's 4, but maybe it should be calculated based on the terminal size. These operations aren't currently used anywhere. For stack buffer operations you should use the above functions, since they take into account the stack alignment. Pops value from buffer and stores it in a given terminal.

Parameters
dstProcedureProcedure to add the moves to.
indexRegisterPointer to the buffer.
dstTerminalTerminal to put the value into.

Definition at line 529 of file CodeGenerator.cc.

532 {
533 decrementRegisterAddress(dstProcedure, indexRegister, 4);
534
535 TTAProgram::Terminal* indexTerminal =
536 createTerminalRegister(indexRegister, true);
537 loadTerminal(dstProcedure, indexTerminal, dstTerminal);
538}

References createTerminalRegister(), decrementRegisterAddress(), and loadTerminal().

Here is the call graph for this function:

◆ popFromStack()

void TTAProgram::CodeGenerator::popFromStack ( TTAProgram::CodeSnippet dstProcedure,
const TCEString stackRegister,
TTAProgram::Terminal dstTerminal 
)

Pops value from stack and stores it in a given terminal.

Parameters
dstProcedureProcedure to add the moves to.
stackRegisterStack pointer name.
dstTerminalTerminal to put the value into.

Definition at line 436 of file CodeGenerator.cc.

439 {
440
441 TTAProgram::Terminal* stackTerminal =
442 createTerminalRegister(stackRegister, true);
443 loadTerminal(dstProcedure, stackTerminal, dstTerminal);
444
445 incrementStackPointer(dstProcedure, stackRegister);
446}

References createTerminalRegister(), incrementStackPointer(), and loadTerminal().

Referenced by llvm::LLVMTCEBuilder::emitSetjmp().

Here is the call graph for this function:

◆ popRegisterFromBuffer()

void TTAProgram::CodeGenerator::popRegisterFromBuffer ( TTAProgram::CodeSnippet dstProcedure,
const TCEString indexRegister,
const TCEString dstReg 
)

Pops value from buffer and stores it in a register.

Parameters
dstProcedureProcedure to add the moves to.
indexRegisterPointer to the buffer.
dstRegRegister to put the value into.

Definition at line 548 of file CodeGenerator.cc.

551 {
552 decrementRegisterAddress(dstProcedure, indexRegister, 4);
553
554 loadFromRegisterAddress(dstProcedure, indexRegister, dstReg);
555}
void loadFromRegisterAddress(TTAProgram::CodeSnippet &dstProcedure, const TCEString &srcReg, const TCEString &dstReg)

References decrementRegisterAddress(), and loadFromRegisterAddress().

Here is the call graph for this function:

◆ popRegisterFromStack()

void TTAProgram::CodeGenerator::popRegisterFromStack ( TTAProgram::CodeSnippet dstProcedure,
const TCEString stackRegister,
const TCEString dstReg 
)

Pops value from stack and stores it in a register.

Parameters
dstProcedureProcedure to add the moves to.
stackRegisterStack pointer name.
dstRegRegister to put the value into.

Definition at line 456 of file CodeGenerator.cc.

459 {
460
461 loadFromRegisterAddress(dstProcedure, stackRegister, dstReg);
462
463 incrementStackPointer(dstProcedure, stackRegister);
464}

References incrementStackPointer(), and loadFromRegisterAddress().

Referenced by createSchedYieldProcedure(), llvm::LLVMTCEBuilder::emitLongjmp(), and llvm::LLVMTCEBuilder::emitSetjmp().

Here is the call graph for this function:

◆ pushInstructionReferenceToBuffer()

void TTAProgram::CodeGenerator::pushInstructionReferenceToBuffer ( TTAProgram::CodeSnippet dstProcedure,
const TCEString indexRegister,
TTAProgram::InstructionReference srcAddr 
)

Definition at line 596 of file CodeGenerator.cc.

599 {
600
601 // create terminal references
604
605 pushToBuffer(dstProcedure, indexRegister, srcTerminal);
606}
void pushToBuffer(TTAProgram::CodeSnippet &dstProcedure, const TCEString &indexRegister, TTAProgram::Terminal *srcTerminal)

References pushToBuffer().

Here is the call graph for this function:

◆ pushInstructionReferenceToStack()

void TTAProgram::CodeGenerator::pushInstructionReferenceToStack ( TTAProgram::CodeSnippet dstProcedure,
const TCEString stackRegister,
TTAProgram::InstructionReference srcAddr 
)

Definition at line 503 of file CodeGenerator.cc.

505 {
506 // create terminal references
509
510 pushToStack(dstProcedure, stackRegister, srcTerminal);
511}
void pushToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::Terminal *srcTerminal)

References pushToStack().

Referenced by createSchedYieldProcedure(), and llvm::LLVMTCEBuilder::emitSetjmp().

Here is the call graph for this function:

◆ pushRegisterToBuffer()

void TTAProgram::CodeGenerator::pushRegisterToBuffer ( TTAProgram::CodeSnippet dstProcedure,
const TCEString indexRegister,
const TCEString srcReg 
)

Push a value in a register to a buffer.

Parameters
dstProcedureProcedure to add the moves to.
indexRegisterPointer to the buffer.
srcTerminalValue to push.

Definition at line 585 of file CodeGenerator.cc.

588 {
589
590 storeToRegisterAddress(dstProcedure, indexRegister, srcReg);
591
592 incrementRegisterAddress(dstProcedure, indexRegister, 4);
593}
void storeToRegisterAddress(TTAProgram::CodeSnippet &dstProcedure, const TCEString &dstReg, const TCEString &srcReg)

References incrementRegisterAddress(), and storeToRegisterAddress().

Here is the call graph for this function:

◆ pushRegisterToStack()

void TTAProgram::CodeGenerator::pushRegisterToStack ( TTAProgram::CodeSnippet dstProcedure,
const TCEString stackRegister,
const TCEString srcReg 
)

Push a value in a register to the stack.

Parameters
dstProcedureProcedure to add the moves to.
stackRegisterStack pointer name.
srcTerminalValue to push.

Definition at line 493 of file CodeGenerator.cc.

496 {
497 decrementStackPointer(dstProcedure, stackRegister);
498
499 storeToRegisterAddress(dstProcedure, stackRegister, srcReg);
500}
void decrementStackPointer(TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)

References decrementStackPointer(), and storeToRegisterAddress().

Referenced by createSchedYieldProcedure(), and llvm::LLVMTCEBuilder::emitSetjmp().

Here is the call graph for this function:

◆ pushToBuffer()

void TTAProgram::CodeGenerator::pushToBuffer ( TTAProgram::CodeSnippet dstProcedure,
const TCEString indexRegister,
TTAProgram::Terminal srcTerminal 
)

Push a value in a terminal to a buffer.

Parameters
dstProcedureProcedure to add the moves to.
indexRegisterPointer to the buffer.
srcTerminalValue to push.

Definition at line 565 of file CodeGenerator.cc.

568 {
569
570 TTAProgram::Terminal* indexTerminal =
571 createTerminalRegister(indexRegister, true);
572 storeTerminal(dstProcedure, indexTerminal, srcTerminal);
573
574 incrementRegisterAddress(dstProcedure, indexRegister, 4);
575}
void storeTerminal(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *dstTerminal, TTAProgram::Terminal *srcTerminal)

References createTerminalRegister(), incrementRegisterAddress(), and storeTerminal().

Referenced by pushInstructionReferenceToBuffer().

Here is the call graph for this function:

◆ pushToStack()

void TTAProgram::CodeGenerator::pushToStack ( TTAProgram::CodeSnippet dstProcedure,
const TCEString stackRegister,
TTAProgram::Terminal srcTerminal 
)

Push a value in a terminal to the stack.

Parameters
dstProcedureProcedure to add the moves to.
stackRegisterStack pointer name.
srcTerminalValue to push.

Definition at line 474 of file CodeGenerator.cc.

477 {
478 decrementStackPointer(dstProcedure, stackRegister);
479
480 TTAProgram::Terminal* stackTerminal =
481 createTerminalRegister(stackRegister, true);
482 storeTerminal(dstProcedure, stackTerminal, srcTerminal);
483}

References createTerminalRegister(), decrementStackPointer(), and storeTerminal().

Referenced by llvm::LLVMTCEBuilder::emitLongjmp(), llvm::LLVMTCEBuilder::emitSetjmp(), and pushInstructionReferenceToStack().

Here is the call graph for this function:

◆ registerJump() [1/2]

void TTAProgram::CodeGenerator::registerJump ( TTAProgram::CodeSnippet dstProcedure,
const TCEString jumpAddrReg 
)

Definition at line 609 of file CodeGenerator.cc.

611 {
612
613 TTAProgram::Terminal* jumpDestTerminal =
614 createTerminalRegister(jumpAddrReg, true);
615
616 TTAProgram::TerminalFUPort* jump1Terminal =
617 createTerminalFUPort("jump", 1);
618
619 // dstProcedure->add(new CodeSnippet("jumpAddrReg -> jmp.1;"));
620 addMoveToProcedure(dstProcedure, jumpDestTerminal, jump1Terminal);
621}

References addMoveToProcedure(), createTerminalFUPort(), and createTerminalRegister().

Referenced by createSchedYieldProcedure(), llvm::LLVMTCEBuilder::emitLongjmp(), and llvm::LLVMTCEBuilder::emitReturnTo().

Here is the call graph for this function:

◆ registerJump() [2/2]

void TTAProgram::CodeGenerator::registerJump ( TTAProgram::CodeSnippet dstProcedure,
const TCEString jumpAddrReg,
const TTAProgram::ProgramAnnotation annotation 
)

Definition at line 624 of file CodeGenerator.cc.

627 {
628
629 TTAProgram::Terminal* jumpDestTerminal =
630 createTerminalRegister(jumpAddrReg, true);
631
632 TTAProgram::TerminalFUPort* jump1Terminal =
633 createTerminalFUPort("jump", 1);
634
636 dstProcedure, jumpDestTerminal, jump1Terminal, annotation);
637}
void addAnnotatedMoveToProcedure(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal, const TTAProgram::ProgramAnnotation &annotation)

References addAnnotatedMoveToProcedure(), createTerminalFUPort(), and createTerminalRegister().

Here is the call graph for this function:

◆ registerMove()

void TTAProgram::CodeGenerator::registerMove ( TTAProgram::CodeSnippet dstProcedure,
const TCEString srcReg,
const TCEString dstReg 
)

Definition at line 703 of file CodeGenerator.cc.

705 {
706
707 TTAProgram::Terminal* srcTerminal =
708 createTerminalRegister(srcReg, true);
709
710 TTAProgram::Terminal* dstTerminal =
711 createTerminalRegister(dstReg, false);
712
713 addMoveToProcedure(dstProcedure, srcTerminal, dstTerminal);
714}

References addMoveToProcedure(), and createTerminalRegister().

Referenced by createSchedYieldProcedure().

Here is the call graph for this function:

◆ storeTerminal()

void TTAProgram::CodeGenerator::storeTerminal ( TTAProgram::CodeSnippet dstProcedure,
TTAProgram::Terminal dstTerminal,
TTAProgram::Terminal srcTerminal 
)

Store terminal to address in a terminal.

Parameters
dstProcedureProcedure to add the moves to.
dstTerminalAddress to store to.
srcTerminalTerminal to store.

Definition at line 213 of file CodeGenerator.cc.

216 {
217 TCEString storeOp;
218 int width = 0;
219 if (srcTerminal->isGPR()) {
220 width = srcTerminal->registerFile().width();
221 }
222 int defaultWidth = mach_->is64bit() ? 64 : 32;
223 if (width < defaultWidth) {
224 width = defaultWidth;
225 }
226
227 if (mach_->isLittleEndian()) {
228 storeOp = (boost::format("st%d") % width).str();
229 } else {
230 storeOp = "stw";
231 }
232 if (opset_.count(storeOp) == 0) {
234 (boost::format("Operation %s not found in the machine") % storeOp)
235 .str());
236 }
237
238 TTAProgram::TerminalFUPort* stw1Terminal =
239 createTerminalFUPort(storeOp, 1);
240
241 TTAProgram::TerminalFUPort* stw2Terminal =
242 createTerminalFUPort(storeOp, 2);
243
244 addMoveToProcedure(dstProcedure, dstTerminal, stw1Terminal);
245 addMoveToProcedure(dstProcedure, srcTerminal, stw2Terminal);
246}

References abortWithError, addMoveToProcedure(), createTerminalFUPort(), TTAMachine::Machine::is64bit(), TTAProgram::Terminal::isGPR(), TTAMachine::Machine::isLittleEndian(), mach_, opset_, TTAProgram::Terminal::registerFile(), and TTAMachine::BaseRegisterFile::width().

Referenced by pushToBuffer(), pushToStack(), and storeToAddress().

Here is the call graph for this function:

◆ storeToAddress()

void TTAProgram::CodeGenerator::storeToAddress ( TTAProgram::CodeSnippet dstProcedure,
TTAProgram::Terminal dstTerminal,
const TCEString srcReg 
)

Store register to address in a terminal.

Parameters
dstProcedureProcedure to add the moves to.
dstTerminalAddress to store to.
srcRegRegister to store.

Definition at line 276 of file CodeGenerator.cc.

279 {
280
281 TTAProgram::Terminal* srcRegTerminal =
282 createTerminalRegister(srcReg, true);
283
284 storeTerminal(dstProcedure, dstTerminal, srcRegTerminal);
285}

References createTerminalRegister(), and storeTerminal().

Referenced by llvm::LLVMTCEBuilder::emitSetjmp(), and storeToRegisterAddress().

Here is the call graph for this function:

◆ storeToRegisterAddress()

void TTAProgram::CodeGenerator::storeToRegisterAddress ( TTAProgram::CodeSnippet dstProcedure,
const TCEString dstReg,
const TCEString srcReg 
)

Store register to address in another register.

Parameters
dstProcedureProcedure to add the moves to.
dstRegAddress to store to.
srcRegRegister to store.

Definition at line 315 of file CodeGenerator.cc.

318 {
319
320 // create terminal references
321 TTAProgram::Terminal* dstTerminal =
322 createTerminalRegister(dstReg, true);
323
324 storeToAddress(dstProcedure, dstTerminal, srcReg);
325}
void storeToAddress(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *dstTerminal, const TCEString &srcReg)

References createTerminalRegister(), and storeToAddress().

Referenced by pushRegisterToBuffer(), and pushRegisterToStack().

Here is the call graph for this function:

Member Data Documentation

◆ mach_

const TTAMachine::Machine* TTAProgram::CodeGenerator::mach_
private

◆ opset_

MachineInfo::OperationSet TTAProgram::CodeGenerator::opset_
private

Definition at line 225 of file CodeGenerator.hh.

Referenced by CodeGenerator(), loadTerminal(), and storeTerminal().

◆ stackAlignment_

int TTAProgram::CodeGenerator::stackAlignment_
private

Definition at line 224 of file CodeGenerator.hh.

Referenced by CodeGenerator(), decrementStackPointer(), and incrementStackPointer().

◆ uMach_

const UniversalMachine* TTAProgram::CodeGenerator::uMach_
private

The documentation for this class was generated from the following files: