base.isa revision 2561
110448Snilay@cs.wisc.edu//////////////////////////////////////////////////////////////////// 210448Snilay@cs.wisc.edu// 310448Snilay@cs.wisc.edu// Base class for sparc instructions, and some support functions 410448Snilay@cs.wisc.edu// 510448Snilay@cs.wisc.edu 610448Snilay@cs.wisc.eduoutput header {{ 710448Snilay@cs.wisc.edu 810448Snilay@cs.wisc.edu union CondCodes 910448Snilay@cs.wisc.edu { 1010448Snilay@cs.wisc.edu struct 1110448Snilay@cs.wisc.edu { 1210448Snilay@cs.wisc.edu uint8_t c:1; 1310448Snilay@cs.wisc.edu uint8_t v:1; 1410448Snilay@cs.wisc.edu uint8_t z:1; 1510448Snilay@cs.wisc.edu uint8_t n:1; 1610448Snilay@cs.wisc.edu }; 1710448Snilay@cs.wisc.edu uint32_t bits; 1810448Snilay@cs.wisc.edu }; 1910448Snilay@cs.wisc.edu 2010448Snilay@cs.wisc.edu enum CondTest 2110448Snilay@cs.wisc.edu { 2210447Snilay@cs.wisc.edu Always=0x8, 2310447Snilay@cs.wisc.edu Never=0x0, 2410447Snilay@cs.wisc.edu NotEqual=0x9, 2510447Snilay@cs.wisc.edu Equal=0x1, 2610447Snilay@cs.wisc.edu Greater=0xA, 2710447Snilay@cs.wisc.edu LessOrEqual=0x2, 2810447Snilay@cs.wisc.edu GreaterOrEqual=0xB, 2910447Snilay@cs.wisc.edu Less=0x3, 3010447Snilay@cs.wisc.edu GreaterUnsigned=0xC, 3110447Snilay@cs.wisc.edu LessOrEqualUnsigned=0x4, 3210447Snilay@cs.wisc.edu CarryClear=0xD, 3310447Snilay@cs.wisc.edu CarrySet=0x5, 3410447Snilay@cs.wisc.edu Positive=0xE, 3510447Snilay@cs.wisc.edu Negative=0x6, 3610447Snilay@cs.wisc.edu OverflowClear=0xF, 3710447Snilay@cs.wisc.edu OverflowSet=0x7 3810447Snilay@cs.wisc.edu }; 3910447Snilay@cs.wisc.edu 4010447Snilay@cs.wisc.edu extern char * CondTestAbbrev[]; 4110447Snilay@cs.wisc.edu 4210447Snilay@cs.wisc.edu /** 4310447Snilay@cs.wisc.edu * Base class for all SPARC static instructions. 4410447Snilay@cs.wisc.edu */ 4510447Snilay@cs.wisc.edu class SparcStaticInst : public StaticInst 4610447Snilay@cs.wisc.edu { 4710447Snilay@cs.wisc.edu protected: 4810447Snilay@cs.wisc.edu // Constructor. 4910447Snilay@cs.wisc.edu SparcStaticInst(const char *mnem, 5010447Snilay@cs.wisc.edu MachInst _machInst, OpClass __opClass) 5110447Snilay@cs.wisc.edu : StaticInst(mnem, _machInst, __opClass) 5210447Snilay@cs.wisc.edu { 5310447Snilay@cs.wisc.edu } 5410447Snilay@cs.wisc.edu 5510447Snilay@cs.wisc.edu std::string generateDisassembly(Addr pc, 5610447Snilay@cs.wisc.edu const SymbolTable *symtab) const; 5710447Snilay@cs.wisc.edu 5810447Snilay@cs.wisc.edu void printReg(std::ostream &os, int reg) const; 5910447Snilay@cs.wisc.edu }; 6010447Snilay@cs.wisc.edu 6110447Snilay@cs.wisc.edu bool passesCondition(uint32_t codes, uint32_t condition); 6210447Snilay@cs.wisc.edu 6310447Snilay@cs.wisc.edu inline int64_t sign_ext(uint64_t data, int origWidth) 6410447Snilay@cs.wisc.edu { 6510447Snilay@cs.wisc.edu int shiftAmount = 64 - origWidth; 6610447Snilay@cs.wisc.edu return (((int64_t)data) << shiftAmount) >> shiftAmount; 6710447Snilay@cs.wisc.edu } 6810447Snilay@cs.wisc.edu}}; 6910447Snilay@cs.wisc.edu 7010447Snilay@cs.wisc.eduoutput decoder {{ 7110447Snilay@cs.wisc.edu 7210447Snilay@cs.wisc.edu char * CondTestAbbrev[] = 7310447Snilay@cs.wisc.edu { 7410447Snilay@cs.wisc.edu "nev", //Never 7510447Snilay@cs.wisc.edu "e", //Equal 7610447Snilay@cs.wisc.edu "le", //Less or Equal 7710447Snilay@cs.wisc.edu "l", //Less 7810447Snilay@cs.wisc.edu "leu", //Less or Equal Unsigned 7910447Snilay@cs.wisc.edu "c", //Carry set 8010447Snilay@cs.wisc.edu "n", //Negative 8110447Snilay@cs.wisc.edu "o", //Overflow set 8210447Snilay@cs.wisc.edu "a", //Always 8310447Snilay@cs.wisc.edu "ne", //Not Equal 8410447Snilay@cs.wisc.edu "g", //Greater 8510447Snilay@cs.wisc.edu "ge", //Greater or Equal 8610447Snilay@cs.wisc.edu "gu", //Greater Unsigned 8710447Snilay@cs.wisc.edu "cc", //Carry clear 8810447Snilay@cs.wisc.edu "p", //Positive 8910447Snilay@cs.wisc.edu "oc" //Overflow Clear 9010447Snilay@cs.wisc.edu }; 9110447Snilay@cs.wisc.edu}}; 9210447Snilay@cs.wisc.edu 9310447Snilay@cs.wisc.edudef template ROrImmDecode {{ 9410447Snilay@cs.wisc.edu { 9510447Snilay@cs.wisc.edu return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 9610447Snilay@cs.wisc.edu : (SparcStaticInst *)(new %(class_name)s(machInst))); 9710447Snilay@cs.wisc.edu } 9810447Snilay@cs.wisc.edu}}; 9910447Snilay@cs.wisc.edu 10010447Snilay@cs.wisc.edulet {{ 10110447Snilay@cs.wisc.edu def splitOutImm(code): 10210447Snilay@cs.wisc.edu matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)') 10310447Snilay@cs.wisc.edu rOrImmMatch = matcher.search(code) 10410447Snilay@cs.wisc.edu if (rOrImmMatch == None): 10510447Snilay@cs.wisc.edu return (False, code, '', '', '') 10610447Snilay@cs.wisc.edu rString = rOrImmMatch.group("rNum") 10710447Snilay@cs.wisc.edu iString = rOrImmMatch.group("iNum") 10810447Snilay@cs.wisc.edu orig_code = code 10910447Snilay@cs.wisc.edu code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code) 11010447Snilay@cs.wisc.edu imm_code = matcher.sub('imm', orig_code) 11110447Snilay@cs.wisc.edu return (True, code, imm_code, rString, iString) 11210447Snilay@cs.wisc.edu}}; 11310447Snilay@cs.wisc.edu 11410447Snilay@cs.wisc.eduoutput decoder {{ 11510447Snilay@cs.wisc.edu 11610447Snilay@cs.wisc.edu inline void printMnemonic(std::ostream &os, const char * mnemonic) 11710447Snilay@cs.wisc.edu { 11810447Snilay@cs.wisc.edu ccprintf(os, "\t%s ", mnemonic); 11910447Snilay@cs.wisc.edu } 12010447Snilay@cs.wisc.edu 12110447Snilay@cs.wisc.edu void 12210447Snilay@cs.wisc.edu SparcStaticInst::printReg(std::ostream &os, int reg) const 12310447Snilay@cs.wisc.edu { 12410447Snilay@cs.wisc.edu const int MaxGlobal = 8; 12510447Snilay@cs.wisc.edu const int MaxOutput = 16; 12610447Snilay@cs.wisc.edu const int MaxLocal = 24; 12710447Snilay@cs.wisc.edu const int MaxInput = 32; 12810447Snilay@cs.wisc.edu if (reg == FramePointerReg) 12910447Snilay@cs.wisc.edu ccprintf(os, "%%fp"); 13010447Snilay@cs.wisc.edu else if (reg == StackPointerReg) 13110447Snilay@cs.wisc.edu ccprintf(os, "%%sp"); 13210447Snilay@cs.wisc.edu else if(reg < MaxGlobal) 13310447Snilay@cs.wisc.edu ccprintf(os, "%%g%d", reg); 13410447Snilay@cs.wisc.edu else if(reg < MaxOutput) 13510447Snilay@cs.wisc.edu ccprintf(os, "%%o%d", reg - MaxGlobal); 13610447Snilay@cs.wisc.edu else if(reg < MaxLocal) 13710447Snilay@cs.wisc.edu ccprintf(os, "%%l%d", reg - MaxOutput); 13810447Snilay@cs.wisc.edu else if(reg < MaxInput) 13910447Snilay@cs.wisc.edu ccprintf(os, "%%i%d", reg - MaxLocal); 14010447Snilay@cs.wisc.edu else { 14110447Snilay@cs.wisc.edu ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 14210447Snilay@cs.wisc.edu } 14310447Snilay@cs.wisc.edu } 14410447Snilay@cs.wisc.edu 14510447Snilay@cs.wisc.edu std::string SparcStaticInst::generateDisassembly(Addr pc, 14610447Snilay@cs.wisc.edu const SymbolTable *symtab) const 14710447Snilay@cs.wisc.edu { 14810447Snilay@cs.wisc.edu std::stringstream ss; 14910447Snilay@cs.wisc.edu 15010447Snilay@cs.wisc.edu printMnemonic(ss, mnemonic); 15110447Snilay@cs.wisc.edu 15210447Snilay@cs.wisc.edu // just print the first two source regs... if there's 15310447Snilay@cs.wisc.edu // a third one, it's a read-modify-write dest (Rc), 15410447Snilay@cs.wisc.edu // e.g. for CMOVxx 15510447Snilay@cs.wisc.edu if(_numSrcRegs > 0) 15610447Snilay@cs.wisc.edu { 15710447Snilay@cs.wisc.edu printReg(ss, _srcRegIdx[0]); 15810447Snilay@cs.wisc.edu } 15910447Snilay@cs.wisc.edu if(_numSrcRegs > 1) 16010447Snilay@cs.wisc.edu { 16110447Snilay@cs.wisc.edu ss << ","; 16210447Snilay@cs.wisc.edu printReg(ss, _srcRegIdx[1]); 16310447Snilay@cs.wisc.edu } 16410447Snilay@cs.wisc.edu 16510447Snilay@cs.wisc.edu // just print the first dest... if there's a second one, 16610447Snilay@cs.wisc.edu // it's generally implicit 16710447Snilay@cs.wisc.edu if(_numDestRegs > 0) 16810447Snilay@cs.wisc.edu { 16910447Snilay@cs.wisc.edu if(_numSrcRegs > 0) 17010447Snilay@cs.wisc.edu ss << ","; 17110447Snilay@cs.wisc.edu printReg(ss, _destRegIdx[0]); 17210447Snilay@cs.wisc.edu } 17310447Snilay@cs.wisc.edu 17410447Snilay@cs.wisc.edu return ss.str(); 17510447Snilay@cs.wisc.edu } 17610447Snilay@cs.wisc.edu 17710447Snilay@cs.wisc.edu bool passesCondition(uint32_t codes, uint32_t condition) 17810447Snilay@cs.wisc.edu { 17910447Snilay@cs.wisc.edu CondCodes condCodes; 18010447Snilay@cs.wisc.edu condCodes.bits = codes; 18110447Snilay@cs.wisc.edu switch(condition) 18210447Snilay@cs.wisc.edu { 18310447Snilay@cs.wisc.edu case Always: 18410447Snilay@cs.wisc.edu return true; 18510447Snilay@cs.wisc.edu case Never: 18610447Snilay@cs.wisc.edu return false; 18710447Snilay@cs.wisc.edu case NotEqual: 18810447Snilay@cs.wisc.edu return !condCodes.z; 18910447Snilay@cs.wisc.edu case Equal: 19010447Snilay@cs.wisc.edu return condCodes.z; 19110447Snilay@cs.wisc.edu case Greater: 19210447Snilay@cs.wisc.edu return !(condCodes.z | (condCodes.n ^ condCodes.v)); 19310447Snilay@cs.wisc.edu case LessOrEqual: 19410447Snilay@cs.wisc.edu return condCodes.z | (condCodes.n ^ condCodes.v); 19510447Snilay@cs.wisc.edu case GreaterOrEqual: 19610447Snilay@cs.wisc.edu return !(condCodes.n ^ condCodes.v); 19710447Snilay@cs.wisc.edu case Less: 19810447Snilay@cs.wisc.edu return (condCodes.n ^ condCodes.v); 19910447Snilay@cs.wisc.edu case GreaterUnsigned: 20010447Snilay@cs.wisc.edu return !(condCodes.c | condCodes.z); 20110447Snilay@cs.wisc.edu case LessOrEqualUnsigned: 20210447Snilay@cs.wisc.edu return (condCodes.c | condCodes.z); 20310447Snilay@cs.wisc.edu case CarryClear: 20410447Snilay@cs.wisc.edu return !condCodes.c; 20510447Snilay@cs.wisc.edu case CarrySet: 20610447Snilay@cs.wisc.edu return condCodes.c; 20710447Snilay@cs.wisc.edu case Positive: 20810447Snilay@cs.wisc.edu return !condCodes.n; 20910447Snilay@cs.wisc.edu case Negative: 21010447Snilay@cs.wisc.edu return condCodes.n; 21110447Snilay@cs.wisc.edu case OverflowClear: 21210447Snilay@cs.wisc.edu return !condCodes.v; 21310447Snilay@cs.wisc.edu case OverflowSet: 21410447Snilay@cs.wisc.edu return condCodes.v; 21510447Snilay@cs.wisc.edu } 21610447Snilay@cs.wisc.edu panic("Tried testing condition nonexistant " 21710447Snilay@cs.wisc.edu "condition code %d", condition); 21810447Snilay@cs.wisc.edu } 21910447Snilay@cs.wisc.edu}}; 22010447Snilay@cs.wisc.edu 22110447Snilay@cs.wisc.edu