base.isa revision 3978
13978Sgblack@eecs.umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan 22632Sstever@eecs.umich.edu// All rights reserved. 32632Sstever@eecs.umich.edu// 42632Sstever@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 52632Sstever@eecs.umich.edu// modification, are permitted provided that the following conditions are 62632Sstever@eecs.umich.edu// met: redistributions of source code must retain the above copyright 72632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 82632Sstever@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 92632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 102632Sstever@eecs.umich.edu// documentation and/or other materials provided with the distribution; 112632Sstever@eecs.umich.edu// neither the name of the copyright holders nor the names of its 122632Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from 132632Sstever@eecs.umich.edu// this software without specific prior written permission. 142632Sstever@eecs.umich.edu// 152632Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162632Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172632Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182632Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192632Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202632Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212632Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222632Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232632Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242632Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252632Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262632Sstever@eecs.umich.edu// 272632Sstever@eecs.umich.edu// Authors: Ali Saidi 282632Sstever@eecs.umich.edu// Gabe Black 292632Sstever@eecs.umich.edu// Steve Reinhardt 302632Sstever@eecs.umich.edu 312030SN/A//////////////////////////////////////////////////////////////////// 322030SN/A// 332030SN/A// Base class for sparc instructions, and some support functions 342030SN/A// 352030SN/A 362030SN/Aoutput header {{ 372224SN/A 382482SN/A union CondCodes 392224SN/A { 402482SN/A struct 412482SN/A { 422482SN/A uint8_t c:1; 432482SN/A uint8_t v:1; 442482SN/A uint8_t z:1; 452482SN/A uint8_t n:1; 462482SN/A }; 472482SN/A uint32_t bits; 482458SN/A }; 492224SN/A 502482SN/A enum CondTest 512224SN/A { 522224SN/A Always=0x8, 532224SN/A Never=0x0, 542224SN/A NotEqual=0x9, 552224SN/A Equal=0x1, 562224SN/A Greater=0xA, 572224SN/A LessOrEqual=0x2, 582224SN/A GreaterOrEqual=0xB, 592224SN/A Less=0x3, 602224SN/A GreaterUnsigned=0xC, 612224SN/A LessOrEqualUnsigned=0x4, 622224SN/A CarryClear=0xD, 632224SN/A CarrySet=0x5, 642224SN/A Positive=0xE, 652224SN/A Negative=0x6, 662224SN/A OverflowClear=0xF, 672224SN/A OverflowSet=0x7 682458SN/A }; 692224SN/A 702561SN/A extern char * CondTestAbbrev[]; 712561SN/A 722030SN/A /** 732030SN/A * Base class for all SPARC static instructions. 742030SN/A */ 752224SN/A class SparcStaticInst : public StaticInst 762030SN/A { 772224SN/A protected: 782224SN/A // Constructor. 792224SN/A SparcStaticInst(const char *mnem, 803278Sgblack@eecs.umich.edu ExtMachInst _machInst, OpClass __opClass) 812224SN/A : StaticInst(mnem, _machInst, __opClass) 822030SN/A { 832030SN/A } 842030SN/A 852224SN/A std::string generateDisassembly(Addr pc, 862224SN/A const SymbolTable *symtab) const; 872469SN/A 882951Sgblack@eecs.umich.edu void printReg(std::ostream &os, int reg) const; 892944Sgblack@eecs.umich.edu void printSrcReg(std::ostream &os, int reg) const; 902944Sgblack@eecs.umich.edu void printDestReg(std::ostream &os, int reg) const; 912944Sgblack@eecs.umich.edu 922944Sgblack@eecs.umich.edu void printRegArray(std::ostream &os, 932944Sgblack@eecs.umich.edu const RegIndex indexArray[], int num) const; 942030SN/A }; 952030SN/A 962482SN/A bool passesCondition(uint32_t codes, uint32_t condition); 972516SN/A 982516SN/A inline int64_t sign_ext(uint64_t data, int origWidth) 992516SN/A { 1002526SN/A int shiftAmount = 64 - origWidth; 1012516SN/A return (((int64_t)data) << shiftAmount) >> shiftAmount; 1022516SN/A } 1032482SN/A}}; 1042482SN/A 1052561SN/Aoutput decoder {{ 1062561SN/A 1072561SN/A char * CondTestAbbrev[] = 1082561SN/A { 1092561SN/A "nev", //Never 1102561SN/A "e", //Equal 1112561SN/A "le", //Less or Equal 1122561SN/A "l", //Less 1132561SN/A "leu", //Less or Equal Unsigned 1142561SN/A "c", //Carry set 1152561SN/A "n", //Negative 1162561SN/A "o", //Overflow set 1172561SN/A "a", //Always 1182561SN/A "ne", //Not Equal 1192561SN/A "g", //Greater 1202561SN/A "ge", //Greater or Equal 1212561SN/A "gu", //Greater Unsigned 1222561SN/A "cc", //Carry clear 1232561SN/A "p", //Positive 1242561SN/A "oc" //Overflow Clear 1252561SN/A }; 1262561SN/A}}; 1272561SN/A 1282482SN/Adef template ROrImmDecode {{ 1292482SN/A { 1302482SN/A return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 1312482SN/A : (SparcStaticInst *)(new %(class_name)s(machInst))); 1322482SN/A } 1332482SN/A}}; 1342482SN/A 1352482SN/Alet {{ 1362482SN/A def splitOutImm(code): 1372614SN/A matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') 1382482SN/A rOrImmMatch = matcher.search(code) 1392482SN/A if (rOrImmMatch == None): 1402516SN/A return (False, code, '', '', '') 1412516SN/A rString = rOrImmMatch.group("rNum") 1422614SN/A if (rOrImmMatch.group("typeQual") != None): 1432614SN/A rString += rOrImmMatch.group("typeQual") 1442516SN/A iString = rOrImmMatch.group("iNum") 1452482SN/A orig_code = code 1462614SN/A code = matcher.sub('Rs' + rString, orig_code) 1472482SN/A imm_code = matcher.sub('imm', orig_code) 1482516SN/A return (True, code, imm_code, rString, iString) 1492030SN/A}}; 1502030SN/A 1512030SN/Aoutput decoder {{ 1522030SN/A 1532516SN/A inline void printMnemonic(std::ostream &os, const char * mnemonic) 1542516SN/A { 1552516SN/A ccprintf(os, "\t%s ", mnemonic); 1562516SN/A } 1572516SN/A 1582944Sgblack@eecs.umich.edu void SparcStaticInst::printRegArray(std::ostream &os, 1592944Sgblack@eecs.umich.edu const RegIndex indexArray[], int num) const 1602944Sgblack@eecs.umich.edu { 1612944Sgblack@eecs.umich.edu if(num <= 0) 1622944Sgblack@eecs.umich.edu return; 1632944Sgblack@eecs.umich.edu printReg(os, indexArray[0]); 1642944Sgblack@eecs.umich.edu for(int x = 1; x < num; x++) 1652944Sgblack@eecs.umich.edu { 1662944Sgblack@eecs.umich.edu os << ", "; 1672944Sgblack@eecs.umich.edu printReg(os, indexArray[x]); 1682944Sgblack@eecs.umich.edu } 1692944Sgblack@eecs.umich.edu } 1702944Sgblack@eecs.umich.edu 1712469SN/A void 1722944Sgblack@eecs.umich.edu SparcStaticInst::printSrcReg(std::ostream &os, int reg) const 1732944Sgblack@eecs.umich.edu { 1742944Sgblack@eecs.umich.edu if(_numSrcRegs > reg) 1752944Sgblack@eecs.umich.edu printReg(os, _srcRegIdx[reg]); 1762944Sgblack@eecs.umich.edu } 1772944Sgblack@eecs.umich.edu 1782944Sgblack@eecs.umich.edu void 1792944Sgblack@eecs.umich.edu SparcStaticInst::printDestReg(std::ostream &os, int reg) const 1802944Sgblack@eecs.umich.edu { 1812944Sgblack@eecs.umich.edu if(_numDestRegs > reg) 1822944Sgblack@eecs.umich.edu printReg(os, _destRegIdx[reg]); 1832944Sgblack@eecs.umich.edu } 1842944Sgblack@eecs.umich.edu 1852944Sgblack@eecs.umich.edu void 1862951Sgblack@eecs.umich.edu SparcStaticInst::printReg(std::ostream &os, int reg) const 1872469SN/A { 1882516SN/A const int MaxGlobal = 8; 1892516SN/A const int MaxOutput = 16; 1902516SN/A const int MaxLocal = 24; 1912516SN/A const int MaxInput = 32; 1923978Sgblack@eecs.umich.edu const int MaxMicroReg = 40; 1933978Sgblack@eecs.umich.edu if (reg < FP_Base_DepTag) { 1943978Sgblack@eecs.umich.edu //If we used a register from the next or previous window, 1953978Sgblack@eecs.umich.edu //take out the offset. 1963978Sgblack@eecs.umich.edu while (reg >= MaxMicroReg) 1973978Sgblack@eecs.umich.edu reg -= MaxMicroReg; 1983978Sgblack@eecs.umich.edu if (reg == FramePointerReg) 1993978Sgblack@eecs.umich.edu ccprintf(os, "%%fp"); 2003978Sgblack@eecs.umich.edu else if (reg == StackPointerReg) 2013978Sgblack@eecs.umich.edu ccprintf(os, "%%sp"); 2023978Sgblack@eecs.umich.edu else if(reg < MaxGlobal) 2033978Sgblack@eecs.umich.edu ccprintf(os, "%%g%d", reg); 2043978Sgblack@eecs.umich.edu else if(reg < MaxOutput) 2053978Sgblack@eecs.umich.edu ccprintf(os, "%%o%d", reg - MaxGlobal); 2063978Sgblack@eecs.umich.edu else if(reg < MaxLocal) 2073978Sgblack@eecs.umich.edu ccprintf(os, "%%l%d", reg - MaxOutput); 2083978Sgblack@eecs.umich.edu else if(reg < MaxInput) 2093978Sgblack@eecs.umich.edu ccprintf(os, "%%i%d", reg - MaxLocal); 2103978Sgblack@eecs.umich.edu else if(reg < MaxMicroReg) 2113978Sgblack@eecs.umich.edu ccprintf(os, "%%u%d", reg - MaxInput); 2123978Sgblack@eecs.umich.edu //The fake int regs that are really control regs 2133978Sgblack@eecs.umich.edu else { 2143978Sgblack@eecs.umich.edu switch (reg - MaxMicroReg) { 2153978Sgblack@eecs.umich.edu case 1: 2163978Sgblack@eecs.umich.edu ccprintf(os, "%%y"); 2173978Sgblack@eecs.umich.edu break; 2183978Sgblack@eecs.umich.edu case 2: 2193978Sgblack@eecs.umich.edu ccprintf(os, "%%ccr"); 2203978Sgblack@eecs.umich.edu break; 2213978Sgblack@eecs.umich.edu case 3: 2223978Sgblack@eecs.umich.edu ccprintf(os, "%%cansave"); 2233978Sgblack@eecs.umich.edu break; 2243978Sgblack@eecs.umich.edu case 4: 2253978Sgblack@eecs.umich.edu ccprintf(os, "%%canrestore"); 2263978Sgblack@eecs.umich.edu break; 2273978Sgblack@eecs.umich.edu case 5: 2283978Sgblack@eecs.umich.edu ccprintf(os, "%%cleanwin"); 2293978Sgblack@eecs.umich.edu break; 2303978Sgblack@eecs.umich.edu case 6: 2313978Sgblack@eecs.umich.edu ccprintf(os, "%%otherwin"); 2323978Sgblack@eecs.umich.edu break; 2333978Sgblack@eecs.umich.edu case 7: 2343978Sgblack@eecs.umich.edu ccprintf(os, "%%wstate"); 2353978Sgblack@eecs.umich.edu break; 2363978Sgblack@eecs.umich.edu } 2373978Sgblack@eecs.umich.edu } 2383978Sgblack@eecs.umich.edu } else if (reg < Ctrl_Base_DepTag) { 2393978Sgblack@eecs.umich.edu ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 2403978Sgblack@eecs.umich.edu } else { 2413978Sgblack@eecs.umich.edu switch (reg - Ctrl_Base_DepTag) { 2423978Sgblack@eecs.umich.edu case MISCREG_ASI: 2433978Sgblack@eecs.umich.edu ccprintf(os, "%%asi"); 2443978Sgblack@eecs.umich.edu break; 2453978Sgblack@eecs.umich.edu case MISCREG_FPRS: 2463978Sgblack@eecs.umich.edu ccprintf(os, "%%fprs"); 2473978Sgblack@eecs.umich.edu break; 2483978Sgblack@eecs.umich.edu case MISCREG_PCR: 2493978Sgblack@eecs.umich.edu ccprintf(os, "%%pcr"); 2503978Sgblack@eecs.umich.edu break; 2513978Sgblack@eecs.umich.edu case MISCREG_PIC: 2523978Sgblack@eecs.umich.edu ccprintf(os, "%%pic"); 2533978Sgblack@eecs.umich.edu break; 2543978Sgblack@eecs.umich.edu case MISCREG_GSR: 2553978Sgblack@eecs.umich.edu ccprintf(os, "%%gsr"); 2563978Sgblack@eecs.umich.edu break; 2573978Sgblack@eecs.umich.edu case MISCREG_SOFTINT: 2583978Sgblack@eecs.umich.edu ccprintf(os, "%%softint"); 2593978Sgblack@eecs.umich.edu break; 2603978Sgblack@eecs.umich.edu case MISCREG_SOFTINT_SET: 2613978Sgblack@eecs.umich.edu ccprintf(os, "%%softint_set"); 2623978Sgblack@eecs.umich.edu break; 2633978Sgblack@eecs.umich.edu case MISCREG_SOFTINT_CLR: 2643978Sgblack@eecs.umich.edu ccprintf(os, "%%softint_clr"); 2653978Sgblack@eecs.umich.edu break; 2663978Sgblack@eecs.umich.edu case MISCREG_TICK_CMPR: 2673978Sgblack@eecs.umich.edu ccprintf(os, "%%tick_cmpr"); 2683978Sgblack@eecs.umich.edu break; 2693978Sgblack@eecs.umich.edu case MISCREG_STICK: 2703978Sgblack@eecs.umich.edu ccprintf(os, "%%stick"); 2713978Sgblack@eecs.umich.edu break; 2723978Sgblack@eecs.umich.edu case MISCREG_STICK_CMPR: 2733978Sgblack@eecs.umich.edu ccprintf(os, "%%stick_cmpr"); 2743978Sgblack@eecs.umich.edu break; 2753978Sgblack@eecs.umich.edu case MISCREG_TPC: 2763978Sgblack@eecs.umich.edu ccprintf(os, "%%tpc"); 2773978Sgblack@eecs.umich.edu break; 2783978Sgblack@eecs.umich.edu case MISCREG_TNPC: 2793978Sgblack@eecs.umich.edu ccprintf(os, "%%tnpc"); 2803978Sgblack@eecs.umich.edu break; 2813978Sgblack@eecs.umich.edu case MISCREG_TSTATE: 2823978Sgblack@eecs.umich.edu ccprintf(os, "%%tstate"); 2833978Sgblack@eecs.umich.edu break; 2843978Sgblack@eecs.umich.edu case MISCREG_TT: 2853978Sgblack@eecs.umich.edu ccprintf(os, "%%tt"); 2863978Sgblack@eecs.umich.edu break; 2873978Sgblack@eecs.umich.edu case MISCREG_TICK: 2883978Sgblack@eecs.umich.edu ccprintf(os, "%%tick"); 2893978Sgblack@eecs.umich.edu break; 2903978Sgblack@eecs.umich.edu case MISCREG_TBA: 2913978Sgblack@eecs.umich.edu ccprintf(os, "%%tba"); 2923978Sgblack@eecs.umich.edu break; 2933978Sgblack@eecs.umich.edu case MISCREG_PSTATE: 2943978Sgblack@eecs.umich.edu ccprintf(os, "%%pstate"); 2953978Sgblack@eecs.umich.edu break; 2963978Sgblack@eecs.umich.edu case MISCREG_TL: 2973978Sgblack@eecs.umich.edu ccprintf(os, "%%tl"); 2983978Sgblack@eecs.umich.edu break; 2993978Sgblack@eecs.umich.edu case MISCREG_PIL: 3003978Sgblack@eecs.umich.edu ccprintf(os, "%%pil"); 3013978Sgblack@eecs.umich.edu break; 3023978Sgblack@eecs.umich.edu case MISCREG_CWP: 3033978Sgblack@eecs.umich.edu ccprintf(os, "%%cwp"); 3043978Sgblack@eecs.umich.edu break; 3053978Sgblack@eecs.umich.edu case MISCREG_GL: 3063978Sgblack@eecs.umich.edu ccprintf(os, "%%gl"); 3073978Sgblack@eecs.umich.edu break; 3083978Sgblack@eecs.umich.edu case MISCREG_HPSTATE: 3093978Sgblack@eecs.umich.edu ccprintf(os, "%%hpstate"); 3103978Sgblack@eecs.umich.edu break; 3113978Sgblack@eecs.umich.edu case MISCREG_HTSTATE: 3123978Sgblack@eecs.umich.edu ccprintf(os, "%%htstate"); 3133978Sgblack@eecs.umich.edu break; 3143978Sgblack@eecs.umich.edu case MISCREG_HINTP: 3153978Sgblack@eecs.umich.edu ccprintf(os, "%%hintp"); 3163978Sgblack@eecs.umich.edu break; 3173978Sgblack@eecs.umich.edu case MISCREG_HTBA: 3183978Sgblack@eecs.umich.edu ccprintf(os, "%%htba"); 3193978Sgblack@eecs.umich.edu break; 3203978Sgblack@eecs.umich.edu case MISCREG_HSTICK_CMPR: 3213978Sgblack@eecs.umich.edu ccprintf(os, "%%hstick_cmpr"); 3223978Sgblack@eecs.umich.edu break; 3233978Sgblack@eecs.umich.edu case MISCREG_HVER: 3243978Sgblack@eecs.umich.edu ccprintf(os, "%%hver"); 3253978Sgblack@eecs.umich.edu break; 3263978Sgblack@eecs.umich.edu case MISCREG_STRAND_STS_REG: 3273978Sgblack@eecs.umich.edu ccprintf(os, "%%strand_sts_reg"); 3283978Sgblack@eecs.umich.edu break; 3293978Sgblack@eecs.umich.edu case MISCREG_FSR: 3303978Sgblack@eecs.umich.edu ccprintf(os, "%%fsr"); 3313978Sgblack@eecs.umich.edu break; 3323978Sgblack@eecs.umich.edu default: 3333978Sgblack@eecs.umich.edu ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag); 3343978Sgblack@eecs.umich.edu } 3352469SN/A } 3362469SN/A } 3372469SN/A 3382224SN/A std::string SparcStaticInst::generateDisassembly(Addr pc, 3392224SN/A const SymbolTable *symtab) const 3402030SN/A { 3412224SN/A std::stringstream ss; 3422030SN/A 3432516SN/A printMnemonic(ss, mnemonic); 3442030SN/A 3452224SN/A // just print the first two source regs... if there's 3462224SN/A // a third one, it's a read-modify-write dest (Rc), 3472224SN/A // e.g. for CMOVxx 3482224SN/A if(_numSrcRegs > 0) 3492224SN/A { 3502224SN/A printReg(ss, _srcRegIdx[0]); 3512224SN/A } 3522224SN/A if(_numSrcRegs > 1) 3532224SN/A { 3542224SN/A ss << ","; 3552224SN/A printReg(ss, _srcRegIdx[1]); 3562224SN/A } 3572224SN/A 3582224SN/A // just print the first dest... if there's a second one, 3592224SN/A // it's generally implicit 3602224SN/A if(_numDestRegs > 0) 3612224SN/A { 3622030SN/A if(_numSrcRegs > 0) 3632224SN/A ss << ","; 3642224SN/A printReg(ss, _destRegIdx[0]); 3652224SN/A } 3662030SN/A 3672224SN/A return ss.str(); 3682030SN/A } 3692030SN/A 3702482SN/A bool passesCondition(uint32_t codes, uint32_t condition) 3712030SN/A { 3722482SN/A CondCodes condCodes; 3733603Ssaidi@eecs.umich.edu condCodes.bits = 0; 3743603Ssaidi@eecs.umich.edu condCodes.c = codes & 0x1 ? 1 : 0; 3753603Ssaidi@eecs.umich.edu condCodes.v = codes & 0x2 ? 1 : 0; 3763603Ssaidi@eecs.umich.edu condCodes.z = codes & 0x4 ? 1 : 0; 3773603Ssaidi@eecs.umich.edu condCodes.n = codes & 0x8 ? 1 : 0; 3783603Ssaidi@eecs.umich.edu 3792224SN/A switch(condition) 3802224SN/A { 3812224SN/A case Always: 3822224SN/A return true; 3832224SN/A case Never: 3842224SN/A return false; 3852224SN/A case NotEqual: 3862482SN/A return !condCodes.z; 3872224SN/A case Equal: 3882482SN/A return condCodes.z; 3892224SN/A case Greater: 3902482SN/A return !(condCodes.z | (condCodes.n ^ condCodes.v)); 3912224SN/A case LessOrEqual: 3922482SN/A return condCodes.z | (condCodes.n ^ condCodes.v); 3932224SN/A case GreaterOrEqual: 3942482SN/A return !(condCodes.n ^ condCodes.v); 3952224SN/A case Less: 3962482SN/A return (condCodes.n ^ condCodes.v); 3972224SN/A case GreaterUnsigned: 3982482SN/A return !(condCodes.c | condCodes.z); 3992224SN/A case LessOrEqualUnsigned: 4002482SN/A return (condCodes.c | condCodes.z); 4012224SN/A case CarryClear: 4022482SN/A return !condCodes.c; 4032224SN/A case CarrySet: 4042482SN/A return condCodes.c; 4052224SN/A case Positive: 4062482SN/A return !condCodes.n; 4072224SN/A case Negative: 4082482SN/A return condCodes.n; 4092224SN/A case OverflowClear: 4102482SN/A return !condCodes.v; 4112224SN/A case OverflowSet: 4122482SN/A return condCodes.v; 4132224SN/A } 4142469SN/A panic("Tried testing condition nonexistant " 4152469SN/A "condition code %d", condition); 4162030SN/A } 4172030SN/A}}; 4182030SN/A 419