diff options
Diffstat (limited to 'decuda_to_ptxplus/decudaInst.cc')
| -rw-r--r-- | decuda_to_ptxplus/decudaInst.cc | 1473 |
1 files changed, 1473 insertions, 0 deletions
diff --git a/decuda_to_ptxplus/decudaInst.cc b/decuda_to_ptxplus/decudaInst.cc new file mode 100644 index 0000000..3e5a402 --- /dev/null +++ b/decuda_to_ptxplus/decudaInst.cc @@ -0,0 +1,1473 @@ +#include "decudaInst.h" +#include <iostream> +#include <string> +#include <cstring> +#include <stdlib.h> + +extern void output(const char * text); + +//Constructor +decudaInst::decudaInst() +{ + //initilize everything to empty + m_label = ""; + m_predicate = ""; + m_base = ""; + m_baseModifiers = new stringList(); + m_typeModifiers = new stringList(); + m_operands = new stringList(); + m_predicateModifiers = new stringList(); + + m_nextDecudaInst = NULL; + + // Set operations per cycle to 8 by default (no penalty) + m_opPerCycle = 8; +} + +//retreive instruction mnemonic +char* decudaInst::getBase() +{ + return m_base; +} + +stringList* decudaInst::getOperands() +{ + return m_operands; +} + +stringList* decudaInst::getBaseModifiers() +{ + return m_baseModifiers; +} + +stringList* decudaInst::getTypeModifiers() +{ + return m_typeModifiers; +} + +//get next instruction in linked list +//direction is m_listStart to m_listEnd +decudaInst* decudaInst::getNextDecudaInst() +{ + return m_nextDecudaInst; +} + +void decudaInst::setBase(char* setBaseValue) +{ + m_base = setBaseValue; +} + +void decudaInst::addBaseModifier(char* addBaseMod) +{ + stringListPiece* tempPiece = new stringListPiece; + tempPiece->stringText = addBaseMod; + + m_baseModifiers->add(tempPiece); +} + +void decudaInst::addTypeModifier(char* addTypeMod) +{ + stringListPiece* tempPiece = new stringListPiece; + tempPiece->stringText = addTypeMod; + + m_typeModifiers->add(tempPiece); +} + +void decudaInst::addOperand(char* addOp) +{ + stringListPiece* tempPiece = new stringListPiece; + tempPiece->stringText = addOp; + + m_operands->add(tempPiece); +} + +void decudaInst::setPredicate(char* setPredicateValue) +{ + m_predicate = setPredicateValue; +} + +void decudaInst::addPredicateModifier(char* addPredicateMod) +{ + stringListPiece* tempPiece = new stringListPiece; + tempPiece->stringText = addPredicateMod; + + m_predicateModifiers->add(tempPiece); +} + +void decudaInst::setLabel(char* setLabelValue) +{ + m_label = setLabelValue; +} + +//set next instruction in linked list +//direction is m_listStart to m_listEnd +void decudaInst::setNextDecudaInst(decudaInst* setDecudaInstValue) +{ + m_nextDecudaInst = setDecudaInstValue; +} + +// returns true if current instruction is start of an entry (i.e. '{') +bool decudaInst::isEntryStart() +{ + return (strcmp(m_base, "{")==0); +} + +//print out .version and .target header lines +bool decudaInst::printHeaderInst() +{ + if(strcmp(m_base, ".version")==0) + { + output(m_base); output(" "); + + stringListPiece* currentPiece = m_operands->getListStart(); + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + + if(currentPiece!=NULL) + { + output("."); output(currentPiece->stringText); + } + output("+"); + output("\n"); + } + else if(strcmp(m_base, ".target")==0) + { + output(m_base); output(" "); + + stringListPiece* currentPiece = m_operands->getListStart(); + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + + while(currentPiece!=NULL) + { + output(", "); output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + output("\n"); + } + else if(strcmp(m_base, ".tex")==0) + { + output(m_base); output(" "); + + stringListPiece* currentPiece; + + + currentPiece = m_baseModifiers->getListStart(); + output(currentPiece->stringText); output(" "); + currentPiece = currentPiece->nextString; + + while(currentPiece!=NULL) + { + output(" "); output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + + currentPiece = m_operands->getListStart(); + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + + while(currentPiece!=NULL) + { + output(" "); output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + output(";\n"); + } + else + { + return false; + } + return true; +} + +//print out parameters +bool decudaInst::printHeaderInst2() +{ + if(strcmp(m_base, ".param")==0) + { + output(m_base); + + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + + for(int i=0; (i<m_typeModifiers->getSize())&&(currentPiece!=NULL); i++) + { + output(" "); output(currentPiece->stringText); + + currentPiece = currentPiece->nextString; + } + + currentPiece = m_operands->getListStart(); + for(int i=0; (i<m_operands->getSize())&&(currentPiece!=NULL); i++) + { + output(" "); output(currentPiece->stringText); + + currentPiece = currentPiece->nextString; + } + } + else + { + return false; + } + return true; +} +//print out the Decuda instruction +void decudaInst::printDecudaInst() +{ + /*TODO: print label here*/ + /*TODO: print predicate here*/ + /*std::cout << "Instruction Base: " << m_base << "\n"; + + std::cout << "Instruction Modifiers: "; + m_baseModifiers->printStringList(); + std::cout << "\n"; + + std::cout << "Operand types: "; + m_typeModifiers->printStringList(); + std::cout << "\n"; + + std::cout << "Operands: "; + m_operands->printStringList(); + std::cout << "\n\n";*/ + + std::cout << m_base << " "; + m_baseModifiers->printStringList(); + std::cout << " "; + m_typeModifiers->printStringList(); + std::cout << " "; + m_operands->printStringList(); + std::cout << "\n"; + + +} + + +// Just prints the base and operands +void decudaInst::printHeaderPtx() +{ + output(m_base); output(" "); + + stringListPiece* currentPiece; + + currentPiece = m_baseModifiers->getListStart(); + for(int i=0; (i<m_baseModifiers->getSize())&&(currentPiece!=NULL); i++) + { + output(" "); output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + + currentPiece = m_operands->getListStart(); + for(int i=0; (i<m_operands->getSize())&&(currentPiece!=NULL); i++) + { + output(" "); output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } +} + + + +// Print unmodified instruction +void decudaInst::printDefaultPtx() +{ + printLabel(); + printPredicate(); + + output(m_base); + + printBaseModifiers(); + printTypeModifiers(); + printOperands(); + + output(";"); +} + + +// Print unmodified base modifiers, operands, labels and predicates +void decudaInst::printLabel() +{ + if(m_label != "") { + output(m_label); + output(": "); + } +} + +void decudaInst::printPredicate() +{ + if(m_predicate != "") { + output(m_predicate); + + stringListPiece* currentPiece = m_predicateModifiers->getListStart(); + for(int i=0; (i<m_predicateModifiers->getSize())&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + + currentPiece = currentPiece->nextString; + } + + output(" "); + } +} + +void decudaInst::printBaseModifiers() +{ + stringListPiece* currentPiece = m_baseModifiers->getListStart(); + for(int i=0; (i<m_baseModifiers->getSize())&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + + currentPiece = currentPiece->nextString; + } +} + +void decudaInst::printTypeModifiers() +{ + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + for(int i=0; (i<m_typeModifiers->getSize())&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + + currentPiece = currentPiece->nextString; + } +} + +void decudaInst::printOperands() +{ + stringListPiece* currentPiece = m_operands->getListStart(); + char* operandDelimiter = ""; + for(int i=0; (i<m_operands->getSize())&&(currentPiece!=NULL); i++) + { + output(operandDelimiter); output(" "); output(currentPiece->stringText); + operandDelimiter = ","; + + currentPiece = currentPiece->nextString; + } +} + +//This is where the conversion to new PTX takes place +void decudaInst::printNewPtx() +{ + // + // Common modifications that apply to all instructions + // + stringListPiece* currentPiece; + int vectorFlag = 0; //0=default, 1=bb64 type, 2=bb128 type + + // Replace '%clock' with '%halfclock' + currentPiece = m_operands->getListStart(); + for(int i=0; (i<m_operands->getSize())&&(currentPiece!=NULL); i++) + { + char* modString = currentPiece->stringText; + if( strcmp(modString, "%%clock")==0 ) { + char* newText = "%%halfclock"; + currentPiece->stringText = newText; + } + currentPiece = currentPiece->nextString; + } + + // Remove .join from base modifier list + currentPiece = m_baseModifiers->getListStart(); + for(int i=0; (i<m_baseModifiers->getSize())&&(currentPiece!=NULL); i++) + { + char* modString = currentPiece->stringText; + if( strcmp(modString, ".join")==0 ) { + m_baseModifiers->remove(i); + } + currentPiece = currentPiece->nextString; + } + + // Change .end to .exit from base modified list + currentPiece = m_baseModifiers->getListStart(); + for(int i=0; (i<m_baseModifiers->getSize())&&(currentPiece!=NULL); i++) + { + char* modString = currentPiece->stringText; + if( strcmp(modString, ".end")==0 ) { + char* newText = ".exit"; + currentPiece->stringText = newText; + } + currentPiece = currentPiece->nextString; + } + + // Change .b64 to .bb64 from type modifier list + // Change .b128 to .bb128 from type modifier list + currentPiece = m_typeModifiers->getListStart(); + for(int i=0; (i<m_typeModifiers->getSize())&&(currentPiece!=NULL); i++) + { + char* modString = currentPiece->stringText; + if( strcmp(modString, ".b64")==0 ) { + char* newText = ".bb64"; + currentPiece->stringText = newText; + vectorFlag = 1; + } + if( strcmp(modString, ".b128")==0 ) { + char* newText = ".bb128"; + currentPiece->stringText = newText; + vectorFlag = 2; + } + currentPiece = currentPiece->nextString; + } + + //TODO: add support for two vectors in one instruction. Currently not sure if it can actually occur or not + if(vectorFlag != 0) + { + currentPiece = m_operands->getListStart(); + for(int i=0; (i<m_operands->getSize())&&(currentPiece!=NULL); i++) + { + char newText[40] = ""; + char *regNumString; + int regNumInt; + + char* modString = currentPiece->stringText; + if( modString[0] == '$' && modString[1] == 'r' ) { + strcpy(newText, modString); + strtok (newText, "r"); + regNumString = strtok (NULL, "r"); + regNumInt = atoi(regNumString); + if(vectorFlag ==1) + snprintf(newText,40,"{$r%u,$r%u}", regNumInt+0, regNumInt+1); + if(vectorFlag ==2) + snprintf(newText,40,"{$r%u,$r%u,$r%u,$r%u}", regNumInt+0, regNumInt+1, regNumInt+2, regNumInt+3); + + currentPiece->stringText = newText; + break; + } else if( modString[0] == '$' && modString[1] == 'o'&& modString[2] == 'f' ) { + strcpy(newText, modString); + strtok (newText, "s"); + regNumString = strtok (NULL, "s"); + regNumInt = atoi(regNumString); + if(vectorFlag ==1) + snprintf(newText,40,"{$ofs%u,$ofs%u}", regNumInt+0, regNumInt+1); + if(vectorFlag ==2) + snprintf(newText,40,"{$ofs%u,$ofs%u,$ofs%u,$ofs%u}", regNumInt+0, regNumInt+1, regNumInt+2, regNumInt+3); + + currentPiece->stringText = newText; + break; + } else if( modString[0] == '$' && modString[1] == 'p' ) { + strcpy(newText, modString); + strtok (newText, "p"); + regNumString = strtok (NULL, "p"); + regNumInt = atoi(regNumString); + if(vectorFlag ==1) + snprintf(newText,40,"{$p%u,$p%u}", regNumInt+0, regNumInt+1); + if(vectorFlag ==2) + snprintf(newText,40,"{$p%u,$p%u,$p%u,$p%u}", regNumInt+0, regNumInt+1, regNumInt+2, regNumInt+3); + + currentPiece->stringText = newText; + break; + } else if( modString[0] == '$' && modString[1] == 'o' ) { + strcpy(newText, modString); + strtok (newText, "o"); + regNumString = strtok (NULL, "o"); + regNumInt = atoi(regNumString); + if(vectorFlag ==1) + snprintf(newText,40,"{$o%u,$o%u}", regNumInt+0, regNumInt+1); + if(vectorFlag ==2) + snprintf(newText,40,"{$o%u,$o%u,$o%u,$o%u}", regNumInt+0, regNumInt+1, regNumInt+2, regNumInt+3); + + currentPiece->stringText = newText; + break; + } else if( modString[0] == '$' && modString[1] == 't'&& modString[2] == 'e' ) { + strcpy(newText, modString); + strtok (newText, "x"); + regNumString = strtok (NULL, "x"); + regNumInt = atoi(regNumString); + if(vectorFlag ==1) + snprintf(newText,40,"{$tex%u,$tex%u}", regNumInt+0, regNumInt+1); + if(vectorFlag ==2) + snprintf(newText,40,"{$tex%u,$tex%u,$tex%u,$tex%u}", regNumInt+0, regNumInt+1, regNumInt+2, regNumInt+3); + + currentPiece->stringText = newText; + break; + } + currentPiece = currentPiece->nextString; + } + } + + // Predicate modifiers : + // @$p0.ne and @$p0.neu map to @$p0, + // $p0.eq, $p0.equ, $p0.ge map to @!$p0 + // Assuming only one modifier for now, only removes the first one + /*if(m_predicate != "") + { + currentPiece = m_predicateModifiers->getListStart(); + char* modString = currentPiece->stringText; + if( strcmp(modString, ".ne")==0 || + strcmp(modString, ".neu")==0 || + strcmp(modString, ".gtu")==0 || + strcmp(modString, ".ltu")==0 || + strcmp(modString, ".sf")==0 ) { + m_predicateModifiers->remove(0); + } else if( strcmp(modString, ".eq")==0 || + strcmp(modString, ".equ")==0 || + strcmp(modString, ".le")==0 || + strcmp(modString, ".ge")==0 || + strcmp(modString, ".nsf")==0 ) { + // Insert '!' into predicate + std::string temp = m_predicate; + temp.insert(1, "!"); + strcpy(m_predicate, temp.c_str()); + m_predicateModifiers->remove(0); + } + }*/ + + // + // Instruction specific modifications + // + if(strcmp(m_base, "")==0) + { + } + else if(strcmp(m_base, ".entry")==0) + { + /*do nothing here*/ + } + else if(strcmp(m_base, ".lmem")==0) + { + } + else if(strcmp(m_base, ".smem")==0) + { + } + else if(strcmp(m_base, ".reg")==0) + { + } + else if(strcmp(m_base, ".bar")==0) + { + } + + + else if(strcmp(m_base, "cvt")==0) + { + + int cvt_inst_type = 0; //0==cvt, 1==abs + int cvt_neg_mod_flag = 0; //0=off, 1=on + + // Check the actual base instruction + stringListPiece* currentPiece = m_baseModifiers->getListStart(); + for(int i=0; (i<m_baseModifiers->getSize())&&(currentPiece!=NULL); i++) + { + char* modString = currentPiece->stringText; + if( strcmp(modString, ".abs")==0 ) { + cvt_inst_type = 1; + } + if( strcmp(modString, ".neg")==0 ) { + cvt_neg_mod_flag = 1; + } + currentPiece = currentPiece->nextString; + } + + if( cvt_inst_type == 1) { + // abs instruction + printLabel(); + printPredicate(); + + output("abs"); + + char* type = m_typeModifiers->getListStart()->stringText; + output(type); + + printOperands(); + + output(";"); + + } else { + // cvt instruction + + // Remove .neg base modifier + /*currentPiece = m_baseModifiers->getListStart(); + for(int i=0; (i<m_baseModifiers->getSize())&&(currentPiece!=NULL); i++) + { + char* modString = currentPiece->stringText; + if( strcmp(modString, ".neg")==0 ) { + m_baseModifiers->remove(i); + } + currentPiece = currentPiece->nextString; + }*/ + + printLabel(); + printPredicate(); + + output("cvt"); + + int typeModifiers = m_typeModifiers->getSize(); + + if(typeModifiers == 2) { + if(cvt_neg_mod_flag == 0) + stringListPiece* currentPiece = m_baseModifiers->getListStart(); + else + stringListPiece* currentPiece = m_baseModifiers->getListStart()->nextString; + + char* dstType = m_typeModifiers->getListStart()->stringText; + char* srcType = m_typeModifiers->getListStart()->nextString->stringText; + + for(int i=0; (i<m_baseModifiers->getSize())&&(currentPiece!=NULL); i++) + { + char* modString = currentPiece->stringText; + if( + (strcmp(modString, ".rn")==0) || + (strcmp(modString, ".rm")==0) || + (strcmp(modString, ".rp")==0) || + (strcmp(modString, ".rz")==0) + ) + { + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".f64")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".f64")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".f32")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".u8")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".u16")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".u32")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".u64")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".s8")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".s16")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".s32")==0)) + output(modString); + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".s64")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".u8")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".u16")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".u32")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".u64")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".s8")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".s16")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".s32")==0)) + output(modString); + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".s64")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".u8")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".u16")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".u32")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".u64")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".s8")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".s16")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".s32")==0)) + output(modString); + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".s64")==0)) + output(modString); + if((strcmp(dstType, ".u8")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u16")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u32")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u64")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s8")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s16")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s32")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s64")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u8")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u16")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u32")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u64")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s8")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s16")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s32")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s64")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u8")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u16")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u32")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".u64")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s8")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s16")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s32")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".s64")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".f16")==0) && (strcmp(srcType, ".f16")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".f32")==0) && (strcmp(srcType, ".f32")==0)) + { output(modString); output("i"); } + if((strcmp(dstType, ".f64")==0) && (strcmp(srcType, ".f64")==0)) + { output(modString); output("i"); } + } + else if ( + (strcmp(modString, ".rzi")==0) + ) + { + output(modString); + } + else + { + output("\nUnknown mod:"); output(currentPiece->stringText); + assert(0); + } + + currentPiece = currentPiece->nextString; + } + } else { + printBaseModifiers(); + } + + // If one type modifier, duplicate to two; + int numModifiers = m_typeModifiers->getSize(); + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + if( numModifiers == 1 ) { + output(currentPiece->stringText); + output(currentPiece->stringText); + } else { + printTypeModifiers(); + } + + printOperands(); + + output(";"); + + } + + } + else if(strcmp(m_base, "shl")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "add")==0) + { + printLabel(); + printPredicate(); + + output(m_base); + + printBaseModifiers(); + + currentPiece = m_typeModifiers->getListStart(); + for(int i=0; (i<m_typeModifiers->getSize())&&(currentPiece!=NULL); i++) + { + if(strcmp(currentPiece->stringText, ".b8")==0) + { + output(".u8"); + } + else if(strcmp(currentPiece->stringText, ".b16")==0) + { + output(".u16"); + } + else if(strcmp(currentPiece->stringText, ".b32")==0) + { + output(".u32"); + } + else if(strcmp(currentPiece->stringText, ".b64")==0) + { + output(".u64"); + } + else + { + output(currentPiece->stringText); + } + + currentPiece = currentPiece->nextString; + } + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "movsh")==0) + { + printLabel(); + printPredicate(); + + output("shl"); + + printBaseModifiers(); + + printTypeModifiers(); + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "mov")==0) + { + printLabel(); + printPredicate(); + + output("mov"); + + printBaseModifiers(); + + // If mov has two type modifiers, pick the smaller one for proper + // bit truncation + if( m_typeModifiers->getSize() == 2 ) { + std::string type1, type2, type; + int type1Size, type2Size; + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + type1 = currentPiece->stringText; + type2 = currentPiece->nextString->stringText; + + type1Size = atoi(type1.substr(2, type1.size()-2).c_str()); + type2Size = atoi(type2.substr(2, type2.size()-2).c_str()); + type = (type1Size < type2Size) ? type1 : type2; + output(type.c_str()); + } else if( m_typeModifiers->getSize() == 1 ) { + printTypeModifiers(); + } else { + output("Error: unsupported number of type modifiers. "); + } + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "bar.sync")==0) + { + printLabel(); + printPredicate(); + + output(m_base); + + printBaseModifiers(); + + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + currentPiece = m_typeModifiers->getListStart(); + for(int i=0; (i<m_typeModifiers->getSize())&&(currentPiece!=NULL); i++) + { + //output(currentPiece->stringText); + + currentPiece = currentPiece->nextString; + } + + printOperands(); + + output(";"); + m_opPerCycle = -1; + } + else if(strcmp(m_base, "mul")==0) + { + printDefaultPtx(); + + // opPerCycle - lower if a 32-bit integer mul + char* dstType = m_typeModifiers->getListStart()->stringText; + if( strcmp(dstType, ".s32")==0 || strcmp(dstType, ".u32")==0 || strcmp(dstType, ".b32")==0 ) + m_opPerCycle = 2; + } + else if(strcmp(m_base, "mad24")==0) + { + printLabel(); + printPredicate(); + + output("mad24"); + + printBaseModifiers(); + + // Only output the destination operand type (first type modifier only) + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + output(currentPiece->stringText); + + printOperands(); + // If 3 operands, this is a mac24 instruction, so add destination operand as 4th operand + int numOperands = m_operands->getSize(); + if(numOperands == 3) { + stringListPiece* currentPiece = m_operands->getListStart(); + output(", "); output(currentPiece->stringText); + } + + output(";"); + } + else if(strcmp(m_base, "mad24c1")==0) + { + output("nop; //"); + + printLabel(); + printPredicate(); + + output("mad24c1"); + + printBaseModifiers(); + + // Only output the destination operand type (first type modifier only) + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + output(currentPiece->stringText); + + printOperands(); + // If 3 operands, this is a mac24 instruction, so add destination operand as 4th operand + int numOperands = m_operands->getSize(); + if(numOperands == 3) { + stringListPiece* currentPiece = m_operands->getListStart(); + output(", "); output(currentPiece->stringText); + } + + output(";"); + } + else if(strcmp(m_base, "set")==0) + { + printLabel(); + printPredicate(); + + output("set"); + + printBaseModifiers(); + + // If one type modifier, duplicate to two; + // if three type modifiers, remove third + int numModifiers = m_typeModifiers->getSize(); + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + if( numModifiers == 1 ) { + output(currentPiece->stringText); + output(currentPiece->stringText); + } else if( numModifiers == 3) { + for(int i=0; (i<numModifiers-1)&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + } + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "mad")==0) + { + printDefaultPtx(); + + // opPerCycle - lower if a 32-bit integer mad + char* dstType = m_typeModifiers->getListStart()->stringText; + if( strcmp(dstType, ".s32")==0 || strcmp(dstType, ".u32")==0 || strcmp(dstType, ".b32")==0 ) + m_opPerCycle = 2; + } + else if(strcmp(m_base, "mul24")==0) + { + printLabel(); + printPredicate(); + + output("mul24"); + + printBaseModifiers(); + + // Only output the destination operand type (first type modifier only) + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + output(currentPiece->stringText); + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "set?68?")==0) + { + // This actually takes absolute value of first source operand and is set.gt + printLabel(); + printPredicate(); + + output("set.gt.abs"); + + printBaseModifiers(); + + // If one type modifier, duplicate to two; + // if three type modifiers, remove third + int numModifiers = m_typeModifiers->getSize(); + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + if( numModifiers == 1 ) { + output(currentPiece->stringText); + output(currentPiece->stringText); + } else if( numModifiers == 3) { + for(int i=0; (i<numModifiers-1)&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + } + + printOperands(); + + output(";"); + + output(" //set?68?"); + } + else if(strcmp(m_base, "set?65?")==0) + { + // This actually takes absolute value of first source operand and is set.lt + printLabel(); + printPredicate(); + + output("set.lt.abs"); + + printBaseModifiers(); + + // If one type modifier, duplicate to two; + // if three type modifiers, remove third + int numModifiers = m_typeModifiers->getSize(); + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + if( numModifiers == 1 ) { + output(currentPiece->stringText); + output(currentPiece->stringText); + } else if( numModifiers == 3) { + for(int i=0; (i<numModifiers-1)&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + } + + printOperands(); + + output(";"); + + output(" //set?65?"); + } + else if(strcmp(m_base, "set?67?")==0) + { + // Change to set.gt + printLabel(); + printPredicate(); + + output("set.gt.abs"); + + printBaseModifiers(); + + // If one type modifier, duplicate to two; + // if three type modifiers, remove third + int numModifiers = m_typeModifiers->getSize(); + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + if( numModifiers == 1 ) { + output(currentPiece->stringText); + output(currentPiece->stringText); + } else if( numModifiers == 3) { + for(int i=0; (i<numModifiers-1)&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + } + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "set?13?")==0) + { + // Change to set.gt + printLabel(); + printPredicate(); + + output("set.neu"); + + printBaseModifiers(); + + // If one type modifier, duplicate to two; + // if three type modifiers, remove third + int numModifiers = m_typeModifiers->getSize(); + stringListPiece* currentPiece = m_typeModifiers->getListStart(); + if( numModifiers == 1 ) { + output(currentPiece->stringText); + output(currentPiece->stringText); + } else if( numModifiers == 3) { + for(int i=0; (i<numModifiers-1)&&(currentPiece!=NULL); i++) + { + output(currentPiece->stringText); + currentPiece = currentPiece->nextString; + } + } + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "rcp")==0) + { + printDefaultPtx(); + + m_opPerCycle = 2; + } + else if(strcmp(m_base, "pre.sin")==0) + { + printLabel(); + printPredicate(); + + output("nop;"); + output(" //"); + output("pre.sin"); + printBaseModifiers(); + printTypeModifiers(); + printOperands(); + + // m_opPerCycle - Ignore + m_opPerCycle = -1; + } + else if(strcmp(m_base, "sin")==0) + { + printDefaultPtx(); + + m_opPerCycle = 1; + } + else if(strcmp(m_base, "pre.ex2")==0) + { + printLabel(); + printPredicate(); + + output("ex2"); + printBaseModifiers(); + printTypeModifiers(); + printOperands(); + output(";"); + + output(" //"); + printDefaultPtx(); + + // m_opPerCycle - Ignore + m_opPerCycle = -1; + } + else if(strcmp(m_base, "ex2")==0) + { + printLabel(); + printPredicate(); + + output("nop;"); + output(" //"); + output("ex2"); + printBaseModifiers(); + printTypeModifiers(); + printOperands(); + + m_opPerCycle = 1; + } + else if(strcmp(m_base, "cos")==0) + { + printDefaultPtx(); + + m_opPerCycle = 1; + } + else if(strcmp(m_base, "lg2")==0) + { + printDefaultPtx(); + + m_opPerCycle = 2; + } + else if(strcmp(m_base, "rsqrt")==0) + { + printDefaultPtx(); + + m_opPerCycle = 2; + } + else if(strcmp(m_base, "mac")==0) + { + // Replace with mad by adding a 4th operand + printLabel(); + printPredicate(); + + output("mad"); + + printBaseModifiers(); + + printTypeModifiers(); + + // Print operands and then include destination (1st) operand as the 4th operand + printOperands(); + stringListPiece* currentPiece = m_operands->getListStart(); + output(","); output(" "); output(currentPiece->stringText); + + output(";"); + + // opPerCycle - lower if a 32-bit integer mac + char* dstType = m_typeModifiers->getListStart()->stringText; + if( strcmp(dstType, ".s32")==0 || strcmp(dstType, ".u32")==0 || strcmp(dstType, ".b32")==0 ) + m_opPerCycle = 2; + } + else if(strcmp(m_base, "bra.label")==0) + { + printLabel(); + printPredicate(); + + output("bra"); + + printBaseModifiers(); + + printTypeModifiers(); + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "join.label")==0) + { + printLabel(); + printPredicate(); + + output("nop;"); + output(" //join.label"); + + // Ignore + m_opPerCycle = -1; + } + else if(strcmp(m_base, "nop.end")==0) + { + printLabel(); + printPredicate(); + + output("nop.exit;"); + + // Ignore + m_opPerCycle = -1; + } + else if(strcmp(m_base, "nop.join")==0) + { + printLabel(); + printPredicate(); + + output("nop;"); + + // Ignore + m_opPerCycle = -1; + } + else if(strcmp(m_base, "nop")==0) + { + //printLabel(); + //printPredicate(); + + output("nop;"); + } + else if(strcmp(m_base, "return")==0) + { + // ret instruction causes a deadlock bug in the simulator + // Temporary fix: branch to a dummy exit instruction that is added to the end of each + // entry with the label 'l_exit' + printLabel(); + printPredicate(); + + output("retp"); + //output("bra l_exit"); + + printBaseModifiers(); + + printTypeModifiers(); + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "and")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "andn")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "tex")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "xor")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "or")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "shr")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "subr")==0) + { + + // Replace with sub instruction with destination operands switched + printLabel(); + printPredicate(); + + output("sub"); + + printBaseModifiers(); + + printTypeModifiers(); + + // Switch source operands before printing + // Must be 3 operands, switch the last two; + if( m_operands->getSize() != 3) { + output("Error: subr instruction with number of operands other than 3.\n"); + assert(0); + } + char* firstOperand = m_operands->getListStart()->stringText; + char* secondOperand = m_operands->getListStart()->nextString->stringText; + char* thirdOperand = m_operands->getListStart()->nextString->nextString->stringText; + output(" "); output(firstOperand); output(","); + output(" "); output(thirdOperand); output(","); + output(" "); output(secondOperand); + + + output(";"); + } + else if(strcmp(m_base, "sub")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "max")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "min")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "call.label")==0) + { + printLabel(); + printPredicate(); + + output("callp"); + + printBaseModifiers(); + + printTypeModifiers(); + + printOperands(); + + output(";"); + + // Ignore + m_opPerCycle = -1; + } + else if(strcmp(m_base, "not")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "delta")==0) + { + // This is a neg instruction + printLabel(); + printPredicate(); + + output("neg"); + + printBaseModifiers(); + + printTypeModifiers(); + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "break")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "breakaddr.label")==0) + { + printLabel(); + printPredicate(); + + output("breakaddr"); + + printBaseModifiers(); + + printTypeModifiers(); + + printOperands(); + + output(";"); + } + else if(strcmp(m_base, "inc")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "exch")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "cas")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "norn")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "addc")==0) + { + output("nop; //"); + printDefaultPtx(); + } + else if(strcmp(m_base, "orn")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "nandn")==0) + { + printDefaultPtx(); + } + else if(strcmp(m_base, "nxor")==0) + { + output("nop; //"); + printDefaultPtx(); + } + else if(strcmp(m_base, "sad")==0) + { + output("nop; //"); + printDefaultPtx(); + } + else if(strcmp(m_base, "op.13")==0) + { + output("nop; //"); + printDefaultPtx(); + } + else if(strcmp(m_base, "op.e5")==0) + { + output("nop; //"); + printDefaultPtx(); + } + else if(strcmp(m_base, "op.e6")==0) + { + output("nop; //"); + printDefaultPtx(); + } + else if(strcmp(m_base, "op.d0")==0) + { + output("nop; //"); + printDefaultPtx(); + } + + + else if(strcmp(m_base, "{")==0) + { + //output(m_base); + + // Ignore + m_opPerCycle = -1; + } + else if(strcmp(m_base, "}")==0) + { + //output(m_base); + + // Ignore + m_opPerCycle = -1; + } + else + { + output("Unknown Instruction: "); output(m_base); + assert(0); + } + +} |
