base.isa revision 2632
12632Sstever@eecs.umich.edu// Copyright (c) 2006 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, 802224SN/A MachInst _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 882469SN/A void printReg(std::ostream &os, int reg) const; 892030SN/A }; 902030SN/A 912482SN/A bool passesCondition(uint32_t codes, uint32_t condition); 922516SN/A 932516SN/A inline int64_t sign_ext(uint64_t data, int origWidth) 942516SN/A { 952526SN/A int shiftAmount = 64 - origWidth; 962516SN/A return (((int64_t)data) << shiftAmount) >> shiftAmount; 972516SN/A } 982482SN/A}}; 992482SN/A 1002561SN/Aoutput decoder {{ 1012561SN/A 1022561SN/A char * CondTestAbbrev[] = 1032561SN/A { 1042561SN/A "nev", //Never 1052561SN/A "e", //Equal 1062561SN/A "le", //Less or Equal 1072561SN/A "l", //Less 1082561SN/A "leu", //Less or Equal Unsigned 1092561SN/A "c", //Carry set 1102561SN/A "n", //Negative 1112561SN/A "o", //Overflow set 1122561SN/A "a", //Always 1132561SN/A "ne", //Not Equal 1142561SN/A "g", //Greater 1152561SN/A "ge", //Greater or Equal 1162561SN/A "gu", //Greater Unsigned 1172561SN/A "cc", //Carry clear 1182561SN/A "p", //Positive 1192561SN/A "oc" //Overflow Clear 1202561SN/A }; 1212561SN/A}}; 1222561SN/A 1232482SN/Adef template ROrImmDecode {{ 1242482SN/A { 1252482SN/A return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 1262482SN/A : (SparcStaticInst *)(new %(class_name)s(machInst))); 1272482SN/A } 1282482SN/A}}; 1292482SN/A 1302482SN/Alet {{ 1312482SN/A def splitOutImm(code): 1322614SN/A matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') 1332482SN/A rOrImmMatch = matcher.search(code) 1342482SN/A if (rOrImmMatch == None): 1352516SN/A return (False, code, '', '', '') 1362516SN/A rString = rOrImmMatch.group("rNum") 1372614SN/A if (rOrImmMatch.group("typeQual") != None): 1382614SN/A rString += rOrImmMatch.group("typeQual") 1392516SN/A iString = rOrImmMatch.group("iNum") 1402482SN/A orig_code = code 1412614SN/A code = matcher.sub('Rs' + rString, orig_code) 1422482SN/A imm_code = matcher.sub('imm', orig_code) 1432516SN/A return (True, code, imm_code, rString, iString) 1442030SN/A}}; 1452030SN/A 1462030SN/Aoutput decoder {{ 1472030SN/A 1482516SN/A inline void printMnemonic(std::ostream &os, const char * mnemonic) 1492516SN/A { 1502516SN/A ccprintf(os, "\t%s ", mnemonic); 1512516SN/A } 1522516SN/A 1532469SN/A void 1542469SN/A SparcStaticInst::printReg(std::ostream &os, int reg) const 1552469SN/A { 1562516SN/A const int MaxGlobal = 8; 1572516SN/A const int MaxOutput = 16; 1582516SN/A const int MaxLocal = 24; 1592516SN/A const int MaxInput = 32; 1602516SN/A if (reg == FramePointerReg) 1612516SN/A ccprintf(os, "%%fp"); 1622516SN/A else if (reg == StackPointerReg) 1632516SN/A ccprintf(os, "%%sp"); 1642516SN/A else if(reg < MaxGlobal) 1652516SN/A ccprintf(os, "%%g%d", reg); 1662516SN/A else if(reg < MaxOutput) 1672516SN/A ccprintf(os, "%%o%d", reg - MaxGlobal); 1682516SN/A else if(reg < MaxLocal) 1692516SN/A ccprintf(os, "%%l%d", reg - MaxOutput); 1702516SN/A else if(reg < MaxInput) 1712516SN/A ccprintf(os, "%%i%d", reg - MaxLocal); 1722469SN/A else { 1732516SN/A ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 1742469SN/A } 1752469SN/A } 1762469SN/A 1772224SN/A std::string SparcStaticInst::generateDisassembly(Addr pc, 1782224SN/A const SymbolTable *symtab) const 1792030SN/A { 1802224SN/A std::stringstream ss; 1812030SN/A 1822516SN/A printMnemonic(ss, mnemonic); 1832030SN/A 1842224SN/A // just print the first two source regs... if there's 1852224SN/A // a third one, it's a read-modify-write dest (Rc), 1862224SN/A // e.g. for CMOVxx 1872224SN/A if(_numSrcRegs > 0) 1882224SN/A { 1892224SN/A printReg(ss, _srcRegIdx[0]); 1902224SN/A } 1912224SN/A if(_numSrcRegs > 1) 1922224SN/A { 1932224SN/A ss << ","; 1942224SN/A printReg(ss, _srcRegIdx[1]); 1952224SN/A } 1962224SN/A 1972224SN/A // just print the first dest... if there's a second one, 1982224SN/A // it's generally implicit 1992224SN/A if(_numDestRegs > 0) 2002224SN/A { 2012030SN/A if(_numSrcRegs > 0) 2022224SN/A ss << ","; 2032224SN/A printReg(ss, _destRegIdx[0]); 2042224SN/A } 2052030SN/A 2062224SN/A return ss.str(); 2072030SN/A } 2082030SN/A 2092482SN/A bool passesCondition(uint32_t codes, uint32_t condition) 2102030SN/A { 2112482SN/A CondCodes condCodes; 2122482SN/A condCodes.bits = codes; 2132224SN/A switch(condition) 2142224SN/A { 2152224SN/A case Always: 2162224SN/A return true; 2172224SN/A case Never: 2182224SN/A return false; 2192224SN/A case NotEqual: 2202482SN/A return !condCodes.z; 2212224SN/A case Equal: 2222482SN/A return condCodes.z; 2232224SN/A case Greater: 2242482SN/A return !(condCodes.z | (condCodes.n ^ condCodes.v)); 2252224SN/A case LessOrEqual: 2262482SN/A return condCodes.z | (condCodes.n ^ condCodes.v); 2272224SN/A case GreaterOrEqual: 2282482SN/A return !(condCodes.n ^ condCodes.v); 2292224SN/A case Less: 2302482SN/A return (condCodes.n ^ condCodes.v); 2312224SN/A case GreaterUnsigned: 2322482SN/A return !(condCodes.c | condCodes.z); 2332224SN/A case LessOrEqualUnsigned: 2342482SN/A return (condCodes.c | condCodes.z); 2352224SN/A case CarryClear: 2362482SN/A return !condCodes.c; 2372224SN/A case CarrySet: 2382482SN/A return condCodes.c; 2392224SN/A case Positive: 2402482SN/A return !condCodes.n; 2412224SN/A case Negative: 2422482SN/A return condCodes.n; 2432224SN/A case OverflowClear: 2442482SN/A return !condCodes.v; 2452224SN/A case OverflowSet: 2462482SN/A return condCodes.v; 2472224SN/A } 2482469SN/A panic("Tried testing condition nonexistant " 2492469SN/A "condition code %d", condition); 2502030SN/A } 2512030SN/A}}; 2522030SN/A 253