base.isa revision 12110
13931Ssaidi@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 704004Sgblack@eecs.umich.edu enum FpCondTest 714004Sgblack@eecs.umich.edu { 724004Sgblack@eecs.umich.edu FAlways=0x8, 734004Sgblack@eecs.umich.edu FNever=0x0, 744004Sgblack@eecs.umich.edu FUnordered=0x7, 754004Sgblack@eecs.umich.edu FGreater=0x6, 764004Sgblack@eecs.umich.edu FUnorderedOrGreater=0x5, 774004Sgblack@eecs.umich.edu FLess=0x4, 784004Sgblack@eecs.umich.edu FUnorderedOrLess=0x3, 794004Sgblack@eecs.umich.edu FLessOrGreater=0x2, 804004Sgblack@eecs.umich.edu FNotEqual=0x1, 814004Sgblack@eecs.umich.edu FEqual=0x9, 824004Sgblack@eecs.umich.edu FUnorderedOrEqual=0xA, 834004Sgblack@eecs.umich.edu FGreaterOrEqual=0xB, 844004Sgblack@eecs.umich.edu FUnorderedOrGreaterOrEqual=0xC, 854004Sgblack@eecs.umich.edu FLessOrEqual=0xD, 864004Sgblack@eecs.umich.edu FUnorderedOrLessOrEqual=0xE, 874004Sgblack@eecs.umich.edu FOrdered=0xF 884004Sgblack@eecs.umich.edu }; 894004Sgblack@eecs.umich.edu 905202Sstever@gmail.com extern const char *CondTestAbbrev[]; 912561SN/A 922030SN/A /** 932030SN/A * Base class for all SPARC static instructions. 942030SN/A */ 952224SN/A class SparcStaticInst : public StaticInst 962030SN/A { 972224SN/A protected: 982224SN/A // Constructor. 992224SN/A SparcStaticInst(const char *mnem, 1003278Sgblack@eecs.umich.edu ExtMachInst _machInst, OpClass __opClass) 1012224SN/A : StaticInst(mnem, _machInst, __opClass) 1022030SN/A { 1032030SN/A } 1042030SN/A 1052224SN/A std::string generateDisassembly(Addr pc, 1062224SN/A const SymbolTable *symtab) const; 1072469SN/A 10812104Snathanael.premillieu@arm.com void printReg(std::ostream &os, RegId reg) const; 1092944Sgblack@eecs.umich.edu void printSrcReg(std::ostream &os, int reg) const; 1102944Sgblack@eecs.umich.edu void printDestReg(std::ostream &os, int reg) const; 1112944Sgblack@eecs.umich.edu 1122944Sgblack@eecs.umich.edu void printRegArray(std::ostream &os, 11312104Snathanael.premillieu@arm.com const RegId indexArray[], int num) const; 1147720Sgblack@eecs.umich.edu 1157720Sgblack@eecs.umich.edu void advancePC(SparcISA::PCState &pcState) const; 1162030SN/A }; 1172030SN/A 1184004Sgblack@eecs.umich.edu bool passesFpCondition(uint32_t fcc, uint32_t condition); 1194004Sgblack@eecs.umich.edu 1202482SN/A bool passesCondition(uint32_t codes, uint32_t condition); 1212516SN/A 1227741Sgblack@eecs.umich.edu inline int64_t 1237741Sgblack@eecs.umich.edu sign_ext(uint64_t data, int origWidth) 1242516SN/A { 1252526SN/A int shiftAmount = 64 - origWidth; 1262516SN/A return (((int64_t)data) << shiftAmount) >> shiftAmount; 1272516SN/A } 1282482SN/A}}; 1292482SN/A 1302561SN/Aoutput decoder {{ 1312561SN/A 1325202Sstever@gmail.com const char *CondTestAbbrev[] = 1332561SN/A { 1347741Sgblack@eecs.umich.edu "nev", // Never 1357741Sgblack@eecs.umich.edu "e", // Equal 1367741Sgblack@eecs.umich.edu "le", // Less or Equal 1377741Sgblack@eecs.umich.edu "l", // Less 1387741Sgblack@eecs.umich.edu "leu", // Less or Equal Unsigned 1397741Sgblack@eecs.umich.edu "c", // Carry set 1407741Sgblack@eecs.umich.edu "n", // Negative 1417741Sgblack@eecs.umich.edu "o", // Overflow set 1427741Sgblack@eecs.umich.edu "a", // Always 1437741Sgblack@eecs.umich.edu "ne", // Not Equal 1447741Sgblack@eecs.umich.edu "g", // Greater 1457741Sgblack@eecs.umich.edu "ge", // Greater or Equal 1467741Sgblack@eecs.umich.edu "gu", // Greater Unsigned 1477741Sgblack@eecs.umich.edu "cc", // Carry clear 1487741Sgblack@eecs.umich.edu "p", // Positive 1497741Sgblack@eecs.umich.edu "oc" // Overflow Clear 1502561SN/A }; 1512561SN/A}}; 1522561SN/A 1532482SN/Adef template ROrImmDecode {{ 1542482SN/A { 1552482SN/A return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 1562482SN/A : (SparcStaticInst *)(new %(class_name)s(machInst))); 1572482SN/A } 1582482SN/A}}; 1592482SN/A 1604362Sgblack@eecs.umich.eduoutput header {{ 1614362Sgblack@eecs.umich.edu union DoubleSingle 1624362Sgblack@eecs.umich.edu { 1634362Sgblack@eecs.umich.edu double d; 1644362Sgblack@eecs.umich.edu uint64_t ui; 1654362Sgblack@eecs.umich.edu uint32_t s[2]; 1664362Sgblack@eecs.umich.edu DoubleSingle(double _d) : d(_d) 1674362Sgblack@eecs.umich.edu {} 1684362Sgblack@eecs.umich.edu DoubleSingle(uint64_t _ui) : ui(_ui) 1694362Sgblack@eecs.umich.edu {} 1704362Sgblack@eecs.umich.edu DoubleSingle(uint32_t _s0, uint32_t _s1) 1714362Sgblack@eecs.umich.edu { 1724362Sgblack@eecs.umich.edu s[0] = _s0; 1734362Sgblack@eecs.umich.edu s[1] = _s1; 1744362Sgblack@eecs.umich.edu } 1754362Sgblack@eecs.umich.edu }; 1764362Sgblack@eecs.umich.edu}}; 1774362Sgblack@eecs.umich.edu 1784362Sgblack@eecs.umich.edulet {{ 1794362Sgblack@eecs.umich.edu def filterDoubles(code): 1804362Sgblack@eecs.umich.edu assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE) 1814362Sgblack@eecs.umich.edu for opName in ("Frd", "Frs1", "Frs2", "Frd_N"): 1824362Sgblack@eecs.umich.edu next_pos = 0 1834362Sgblack@eecs.umich.edu operandsREString = (r''' 1848588Sgblack@eecs.umich.edu (?<!\w) # neg. lookbehind assertion: prevent partial matches 1858588Sgblack@eecs.umich.edu ((%s)(?:_([^\W_]+))?) # match: operand with optional '.' then suffix 1868588Sgblack@eecs.umich.edu (?!\w) # neg. lookahead assertion: prevent partial matches 1874362Sgblack@eecs.umich.edu ''' % opName) 1884362Sgblack@eecs.umich.edu operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE) 1894362Sgblack@eecs.umich.edu is_src = False 1904362Sgblack@eecs.umich.edu is_dest = False 1914362Sgblack@eecs.umich.edu extension = None 1924362Sgblack@eecs.umich.edu foundOne = False 1934362Sgblack@eecs.umich.edu while 1: 1944362Sgblack@eecs.umich.edu match = operandsRE.search(code, next_pos) 1954362Sgblack@eecs.umich.edu if not match: 1964362Sgblack@eecs.umich.edu break 1974362Sgblack@eecs.umich.edu foundOne = True 1984362Sgblack@eecs.umich.edu op = match.groups() 1994362Sgblack@eecs.umich.edu (op_full, op_base, op_ext) = op 2004362Sgblack@eecs.umich.edu is_dest_local = (assignRE.match(code, match.end()) != None) 2014362Sgblack@eecs.umich.edu is_dest = is_dest or is_dest_local 2024362Sgblack@eecs.umich.edu is_src = is_src or not is_dest_local 2034362Sgblack@eecs.umich.edu if extension and extension != op_ext: 2044362Sgblack@eecs.umich.edu raise Exception, "Inconsistent extensions in double filter." 2054362Sgblack@eecs.umich.edu extension = op_ext 2064362Sgblack@eecs.umich.edu next_pos = match.end() 2074362Sgblack@eecs.umich.edu if foundOne: 2084362Sgblack@eecs.umich.edu # Get rid of any unwanted extension 2094362Sgblack@eecs.umich.edu code = operandsRE.sub(op_base, code) 2104362Sgblack@eecs.umich.edu is_int = False 2114362Sgblack@eecs.umich.edu member = "d" 2124362Sgblack@eecs.umich.edu if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"): 2134362Sgblack@eecs.umich.edu is_int = True 2144362Sgblack@eecs.umich.edu member = "ui" 2154362Sgblack@eecs.umich.edu if is_src: 2164362Sgblack@eecs.umich.edu code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \ 2174362Sgblack@eecs.umich.edu (opName, opName, opName, member)) + code 2184362Sgblack@eecs.umich.edu if is_dest: 2194362Sgblack@eecs.umich.edu code += ''' 2204362Sgblack@eecs.umich.edu %s_low = DoubleSingle(%s).s[1]; 2214362Sgblack@eecs.umich.edu %s_high = DoubleSingle(%s).s[0];''' % \ 2224362Sgblack@eecs.umich.edu (opName, opName, opName, opName) 2234362Sgblack@eecs.umich.edu if is_int: 2244362Sgblack@eecs.umich.edu code = ("uint64_t %s;" % opName) + code 2254362Sgblack@eecs.umich.edu else: 2264362Sgblack@eecs.umich.edu code = ("double %s;" % opName) + code 2274362Sgblack@eecs.umich.edu return code 2284362Sgblack@eecs.umich.edu}}; 2294362Sgblack@eecs.umich.edu 2302482SN/Alet {{ 2312482SN/A def splitOutImm(code): 2328588Sgblack@eecs.umich.edu matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?') 2332482SN/A rOrImmMatch = matcher.search(code) 2342482SN/A if (rOrImmMatch == None): 2352516SN/A return (False, code, '', '', '') 2362516SN/A rString = rOrImmMatch.group("rNum") 2372614SN/A if (rOrImmMatch.group("typeQual") != None): 2382614SN/A rString += rOrImmMatch.group("typeQual") 2392516SN/A iString = rOrImmMatch.group("iNum") 2402482SN/A orig_code = code 2412614SN/A code = matcher.sub('Rs' + rString, orig_code) 2422482SN/A imm_code = matcher.sub('imm', orig_code) 2432516SN/A return (True, code, imm_code, rString, iString) 2442030SN/A}}; 2452030SN/A 2462030SN/Aoutput decoder {{ 2472030SN/A 2482516SN/A inline void printMnemonic(std::ostream &os, const char * mnemonic) 2492516SN/A { 2502516SN/A ccprintf(os, "\t%s ", mnemonic); 2512516SN/A } 2522516SN/A 2532944Sgblack@eecs.umich.edu void SparcStaticInst::printRegArray(std::ostream &os, 25412104Snathanael.premillieu@arm.com const RegId indexArray[], int num) const 2552944Sgblack@eecs.umich.edu { 2567741Sgblack@eecs.umich.edu if (num <= 0) 2572944Sgblack@eecs.umich.edu return; 2582944Sgblack@eecs.umich.edu printReg(os, indexArray[0]); 2597741Sgblack@eecs.umich.edu for (int x = 1; x < num; x++) { 2602944Sgblack@eecs.umich.edu os << ", "; 2612944Sgblack@eecs.umich.edu printReg(os, indexArray[x]); 2622944Sgblack@eecs.umich.edu } 2632944Sgblack@eecs.umich.edu } 2642944Sgblack@eecs.umich.edu 2652469SN/A void 2667720Sgblack@eecs.umich.edu SparcStaticInst::advancePC(SparcISA::PCState &pcState) const 2677720Sgblack@eecs.umich.edu { 2687720Sgblack@eecs.umich.edu pcState.advance(); 2697720Sgblack@eecs.umich.edu } 2707720Sgblack@eecs.umich.edu 2717720Sgblack@eecs.umich.edu void 2722944Sgblack@eecs.umich.edu SparcStaticInst::printSrcReg(std::ostream &os, int reg) const 2732944Sgblack@eecs.umich.edu { 2747741Sgblack@eecs.umich.edu if (_numSrcRegs > reg) 2752944Sgblack@eecs.umich.edu printReg(os, _srcRegIdx[reg]); 2762944Sgblack@eecs.umich.edu } 2772944Sgblack@eecs.umich.edu 2782944Sgblack@eecs.umich.edu void 2792944Sgblack@eecs.umich.edu SparcStaticInst::printDestReg(std::ostream &os, int reg) const 2802944Sgblack@eecs.umich.edu { 2817741Sgblack@eecs.umich.edu if (_numDestRegs > reg) 2822944Sgblack@eecs.umich.edu printReg(os, _destRegIdx[reg]); 2832944Sgblack@eecs.umich.edu } 2842944Sgblack@eecs.umich.edu 2852944Sgblack@eecs.umich.edu void 28612104Snathanael.premillieu@arm.com SparcStaticInst::printReg(std::ostream &os, RegId reg) const 2872469SN/A { 2882516SN/A const int MaxGlobal = 8; 2892516SN/A const int MaxOutput = 16; 2902516SN/A const int MaxLocal = 24; 2912516SN/A const int MaxInput = 32; 2923978Sgblack@eecs.umich.edu const int MaxMicroReg = 40; 29312106SRekai.GonzalezAlberquilla@arm.com RegIndex reg_idx = reg.index(); 29412106SRekai.GonzalezAlberquilla@arm.com if (reg.isIntReg()) { 2957741Sgblack@eecs.umich.edu // If we used a register from the next or previous window, 2967741Sgblack@eecs.umich.edu // take out the offset. 29712104Snathanael.premillieu@arm.com while (reg_idx >= MaxMicroReg) 29812104Snathanael.premillieu@arm.com reg_idx -= MaxMicroReg; 29912104Snathanael.premillieu@arm.com if (reg_idx == FramePointerReg) 3003978Sgblack@eecs.umich.edu ccprintf(os, "%%fp"); 30112104Snathanael.premillieu@arm.com else if (reg_idx == StackPointerReg) 3023978Sgblack@eecs.umich.edu ccprintf(os, "%%sp"); 30312104Snathanael.premillieu@arm.com else if (reg_idx < MaxGlobal) 30412104Snathanael.premillieu@arm.com ccprintf(os, "%%g%d", reg_idx); 30512104Snathanael.premillieu@arm.com else if (reg_idx < MaxOutput) 30612104Snathanael.premillieu@arm.com ccprintf(os, "%%o%d", reg_idx - MaxGlobal); 30712104Snathanael.premillieu@arm.com else if (reg_idx < MaxLocal) 30812104Snathanael.premillieu@arm.com ccprintf(os, "%%l%d", reg_idx - MaxOutput); 30912104Snathanael.premillieu@arm.com else if (reg_idx < MaxInput) 31012104Snathanael.premillieu@arm.com ccprintf(os, "%%i%d", reg_idx - MaxLocal); 31112104Snathanael.premillieu@arm.com else if (reg_idx < MaxMicroReg) 31212104Snathanael.premillieu@arm.com ccprintf(os, "%%u%d", reg_idx - MaxInput); 3137741Sgblack@eecs.umich.edu // The fake int regs that are really control regs 3143978Sgblack@eecs.umich.edu else { 31512104Snathanael.premillieu@arm.com switch (reg_idx - MaxMicroReg) { 3163978Sgblack@eecs.umich.edu case 1: 3173978Sgblack@eecs.umich.edu ccprintf(os, "%%y"); 3183978Sgblack@eecs.umich.edu break; 3193978Sgblack@eecs.umich.edu case 2: 3203978Sgblack@eecs.umich.edu ccprintf(os, "%%ccr"); 3213978Sgblack@eecs.umich.edu break; 3223978Sgblack@eecs.umich.edu case 3: 3233978Sgblack@eecs.umich.edu ccprintf(os, "%%cansave"); 3243978Sgblack@eecs.umich.edu break; 3253978Sgblack@eecs.umich.edu case 4: 3263978Sgblack@eecs.umich.edu ccprintf(os, "%%canrestore"); 3273978Sgblack@eecs.umich.edu break; 3283978Sgblack@eecs.umich.edu case 5: 3293978Sgblack@eecs.umich.edu ccprintf(os, "%%cleanwin"); 3303978Sgblack@eecs.umich.edu break; 3313978Sgblack@eecs.umich.edu case 6: 3323978Sgblack@eecs.umich.edu ccprintf(os, "%%otherwin"); 3333978Sgblack@eecs.umich.edu break; 3343978Sgblack@eecs.umich.edu case 7: 3353978Sgblack@eecs.umich.edu ccprintf(os, "%%wstate"); 3363978Sgblack@eecs.umich.edu break; 3373978Sgblack@eecs.umich.edu } 3383978Sgblack@eecs.umich.edu } 33912106SRekai.GonzalezAlberquilla@arm.com } else if (reg.isFloatReg()) { 34012104Snathanael.premillieu@arm.com ccprintf(os, "%%f%d", reg_idx); 3413978Sgblack@eecs.umich.edu } else { 34212104Snathanael.premillieu@arm.com switch (reg_idx) { 3433978Sgblack@eecs.umich.edu case MISCREG_ASI: 3443978Sgblack@eecs.umich.edu ccprintf(os, "%%asi"); 3453978Sgblack@eecs.umich.edu break; 3463978Sgblack@eecs.umich.edu case MISCREG_FPRS: 3473978Sgblack@eecs.umich.edu ccprintf(os, "%%fprs"); 3483978Sgblack@eecs.umich.edu break; 3493978Sgblack@eecs.umich.edu case MISCREG_PCR: 3503978Sgblack@eecs.umich.edu ccprintf(os, "%%pcr"); 3513978Sgblack@eecs.umich.edu break; 3523978Sgblack@eecs.umich.edu case MISCREG_PIC: 3533978Sgblack@eecs.umich.edu ccprintf(os, "%%pic"); 3543978Sgblack@eecs.umich.edu break; 3553978Sgblack@eecs.umich.edu case MISCREG_GSR: 3563978Sgblack@eecs.umich.edu ccprintf(os, "%%gsr"); 3573978Sgblack@eecs.umich.edu break; 3583978Sgblack@eecs.umich.edu case MISCREG_SOFTINT: 3593978Sgblack@eecs.umich.edu ccprintf(os, "%%softint"); 3603978Sgblack@eecs.umich.edu break; 3613978Sgblack@eecs.umich.edu case MISCREG_SOFTINT_SET: 3623978Sgblack@eecs.umich.edu ccprintf(os, "%%softint_set"); 3633978Sgblack@eecs.umich.edu break; 3643978Sgblack@eecs.umich.edu case MISCREG_SOFTINT_CLR: 3653978Sgblack@eecs.umich.edu ccprintf(os, "%%softint_clr"); 3663978Sgblack@eecs.umich.edu break; 3673978Sgblack@eecs.umich.edu case MISCREG_TICK_CMPR: 3683978Sgblack@eecs.umich.edu ccprintf(os, "%%tick_cmpr"); 3693978Sgblack@eecs.umich.edu break; 3703978Sgblack@eecs.umich.edu case MISCREG_STICK: 3713978Sgblack@eecs.umich.edu ccprintf(os, "%%stick"); 3723978Sgblack@eecs.umich.edu break; 3733978Sgblack@eecs.umich.edu case MISCREG_STICK_CMPR: 3743978Sgblack@eecs.umich.edu ccprintf(os, "%%stick_cmpr"); 3753978Sgblack@eecs.umich.edu break; 3763978Sgblack@eecs.umich.edu case MISCREG_TPC: 3773978Sgblack@eecs.umich.edu ccprintf(os, "%%tpc"); 3783978Sgblack@eecs.umich.edu break; 3793978Sgblack@eecs.umich.edu case MISCREG_TNPC: 3803978Sgblack@eecs.umich.edu ccprintf(os, "%%tnpc"); 3813978Sgblack@eecs.umich.edu break; 3823978Sgblack@eecs.umich.edu case MISCREG_TSTATE: 3833978Sgblack@eecs.umich.edu ccprintf(os, "%%tstate"); 3843978Sgblack@eecs.umich.edu break; 3853978Sgblack@eecs.umich.edu case MISCREG_TT: 3863978Sgblack@eecs.umich.edu ccprintf(os, "%%tt"); 3873978Sgblack@eecs.umich.edu break; 3883978Sgblack@eecs.umich.edu case MISCREG_TICK: 3893978Sgblack@eecs.umich.edu ccprintf(os, "%%tick"); 3903978Sgblack@eecs.umich.edu break; 3913978Sgblack@eecs.umich.edu case MISCREG_TBA: 3923978Sgblack@eecs.umich.edu ccprintf(os, "%%tba"); 3933978Sgblack@eecs.umich.edu break; 3943978Sgblack@eecs.umich.edu case MISCREG_PSTATE: 3953978Sgblack@eecs.umich.edu ccprintf(os, "%%pstate"); 3963978Sgblack@eecs.umich.edu break; 3973978Sgblack@eecs.umich.edu case MISCREG_TL: 3983978Sgblack@eecs.umich.edu ccprintf(os, "%%tl"); 3993978Sgblack@eecs.umich.edu break; 4003978Sgblack@eecs.umich.edu case MISCREG_PIL: 4013978Sgblack@eecs.umich.edu ccprintf(os, "%%pil"); 4023978Sgblack@eecs.umich.edu break; 4033978Sgblack@eecs.umich.edu case MISCREG_CWP: 4043978Sgblack@eecs.umich.edu ccprintf(os, "%%cwp"); 4053978Sgblack@eecs.umich.edu break; 4063978Sgblack@eecs.umich.edu case MISCREG_GL: 4073978Sgblack@eecs.umich.edu ccprintf(os, "%%gl"); 4083978Sgblack@eecs.umich.edu break; 4093978Sgblack@eecs.umich.edu case MISCREG_HPSTATE: 4103978Sgblack@eecs.umich.edu ccprintf(os, "%%hpstate"); 4113978Sgblack@eecs.umich.edu break; 4123978Sgblack@eecs.umich.edu case MISCREG_HTSTATE: 4133978Sgblack@eecs.umich.edu ccprintf(os, "%%htstate"); 4143978Sgblack@eecs.umich.edu break; 4153978Sgblack@eecs.umich.edu case MISCREG_HINTP: 4163978Sgblack@eecs.umich.edu ccprintf(os, "%%hintp"); 4173978Sgblack@eecs.umich.edu break; 4183978Sgblack@eecs.umich.edu case MISCREG_HTBA: 4193978Sgblack@eecs.umich.edu ccprintf(os, "%%htba"); 4203978Sgblack@eecs.umich.edu break; 4213978Sgblack@eecs.umich.edu case MISCREG_HSTICK_CMPR: 4223978Sgblack@eecs.umich.edu ccprintf(os, "%%hstick_cmpr"); 4233978Sgblack@eecs.umich.edu break; 4243978Sgblack@eecs.umich.edu case MISCREG_HVER: 4253978Sgblack@eecs.umich.edu ccprintf(os, "%%hver"); 4263978Sgblack@eecs.umich.edu break; 4273978Sgblack@eecs.umich.edu case MISCREG_STRAND_STS_REG: 4283978Sgblack@eecs.umich.edu ccprintf(os, "%%strand_sts_reg"); 4293978Sgblack@eecs.umich.edu break; 4303978Sgblack@eecs.umich.edu case MISCREG_FSR: 4313978Sgblack@eecs.umich.edu ccprintf(os, "%%fsr"); 4323978Sgblack@eecs.umich.edu break; 4333978Sgblack@eecs.umich.edu default: 43412104Snathanael.premillieu@arm.com ccprintf(os, "%%ctrl%d", reg_idx); 4353978Sgblack@eecs.umich.edu } 4362469SN/A } 4372469SN/A } 4382469SN/A 4397741Sgblack@eecs.umich.edu std::string 4407741Sgblack@eecs.umich.edu SparcStaticInst::generateDisassembly(Addr pc, 4417741Sgblack@eecs.umich.edu const SymbolTable *symtab) const 4422030SN/A { 4432224SN/A std::stringstream ss; 4442030SN/A 4452516SN/A printMnemonic(ss, mnemonic); 4462030SN/A 4472224SN/A // just print the first two source regs... if there's 4482224SN/A // a third one, it's a read-modify-write dest (Rc), 4492224SN/A // e.g. for CMOVxx 4507741Sgblack@eecs.umich.edu if (_numSrcRegs > 0) 4512224SN/A printReg(ss, _srcRegIdx[0]); 4527741Sgblack@eecs.umich.edu if (_numSrcRegs > 1) { 4532224SN/A ss << ","; 4542224SN/A printReg(ss, _srcRegIdx[1]); 4552224SN/A } 4562224SN/A 4572224SN/A // just print the first dest... if there's a second one, 4582224SN/A // it's generally implicit 4597741Sgblack@eecs.umich.edu if (_numDestRegs > 0) { 4607741Sgblack@eecs.umich.edu if (_numSrcRegs > 0) 4612224SN/A ss << ","; 46211981Snikos.nikoleris@arm.com printReg(ss, _destRegIdx[0]); 4632224SN/A } 4642030SN/A 4652224SN/A return ss.str(); 4662030SN/A } 4672030SN/A 4687741Sgblack@eecs.umich.edu bool 4697741Sgblack@eecs.umich.edu passesFpCondition(uint32_t fcc, uint32_t condition) 4704004Sgblack@eecs.umich.edu { 4714004Sgblack@eecs.umich.edu bool u = (fcc == 3); 4724004Sgblack@eecs.umich.edu bool g = (fcc == 2); 4734004Sgblack@eecs.umich.edu bool l = (fcc == 1); 4744004Sgblack@eecs.umich.edu bool e = (fcc == 0); 4757741Sgblack@eecs.umich.edu switch (condition) { 4764004Sgblack@eecs.umich.edu case FAlways: 4774004Sgblack@eecs.umich.edu return 1; 4784004Sgblack@eecs.umich.edu case FNever: 4794004Sgblack@eecs.umich.edu return 0; 4804004Sgblack@eecs.umich.edu case FUnordered: 4814004Sgblack@eecs.umich.edu return u; 4824004Sgblack@eecs.umich.edu case FGreater: 4834004Sgblack@eecs.umich.edu return g; 4844004Sgblack@eecs.umich.edu case FUnorderedOrGreater: 4854004Sgblack@eecs.umich.edu return u || g; 4864004Sgblack@eecs.umich.edu case FLess: 4874004Sgblack@eecs.umich.edu return l; 4884004Sgblack@eecs.umich.edu case FUnorderedOrLess: 4894004Sgblack@eecs.umich.edu return u || l; 4904004Sgblack@eecs.umich.edu case FLessOrGreater: 4914004Sgblack@eecs.umich.edu return l || g; 4924004Sgblack@eecs.umich.edu case FNotEqual: 4934004Sgblack@eecs.umich.edu return l || g || u; 4944004Sgblack@eecs.umich.edu case FEqual: 4954004Sgblack@eecs.umich.edu return e; 4964004Sgblack@eecs.umich.edu case FUnorderedOrEqual: 4974004Sgblack@eecs.umich.edu return u || e; 4984004Sgblack@eecs.umich.edu case FGreaterOrEqual: 4994004Sgblack@eecs.umich.edu return g || e; 5004004Sgblack@eecs.umich.edu case FUnorderedOrGreaterOrEqual: 5014004Sgblack@eecs.umich.edu return u || g || e; 5024004Sgblack@eecs.umich.edu case FLessOrEqual: 5034004Sgblack@eecs.umich.edu return l || e; 5044004Sgblack@eecs.umich.edu case FUnorderedOrLessOrEqual: 5054004Sgblack@eecs.umich.edu return u || l || e; 5064004Sgblack@eecs.umich.edu case FOrdered: 5074004Sgblack@eecs.umich.edu return e || l || g; 5084004Sgblack@eecs.umich.edu } 5094004Sgblack@eecs.umich.edu panic("Tried testing condition nonexistant " 5104004Sgblack@eecs.umich.edu "condition code %d", condition); 5114004Sgblack@eecs.umich.edu } 5124004Sgblack@eecs.umich.edu 5137741Sgblack@eecs.umich.edu bool 5147741Sgblack@eecs.umich.edu passesCondition(uint32_t codes, uint32_t condition) 5152030SN/A { 5162482SN/A CondCodes condCodes; 5173603Ssaidi@eecs.umich.edu condCodes.bits = 0; 5183603Ssaidi@eecs.umich.edu condCodes.c = codes & 0x1 ? 1 : 0; 5193603Ssaidi@eecs.umich.edu condCodes.v = codes & 0x2 ? 1 : 0; 5203603Ssaidi@eecs.umich.edu condCodes.z = codes & 0x4 ? 1 : 0; 5213603Ssaidi@eecs.umich.edu condCodes.n = codes & 0x8 ? 1 : 0; 5223603Ssaidi@eecs.umich.edu 5237741Sgblack@eecs.umich.edu switch (condition) { 5242224SN/A case Always: 5252224SN/A return true; 5262224SN/A case Never: 5272224SN/A return false; 5282224SN/A case NotEqual: 5292482SN/A return !condCodes.z; 5302224SN/A case Equal: 5312482SN/A return condCodes.z; 5322224SN/A case Greater: 5332482SN/A return !(condCodes.z | (condCodes.n ^ condCodes.v)); 5342224SN/A case LessOrEqual: 5352482SN/A return condCodes.z | (condCodes.n ^ condCodes.v); 5362224SN/A case GreaterOrEqual: 5372482SN/A return !(condCodes.n ^ condCodes.v); 5382224SN/A case Less: 5392482SN/A return (condCodes.n ^ condCodes.v); 5402224SN/A case GreaterUnsigned: 5412482SN/A return !(condCodes.c | condCodes.z); 5422224SN/A case LessOrEqualUnsigned: 5432482SN/A return (condCodes.c | condCodes.z); 5442224SN/A case CarryClear: 5452482SN/A return !condCodes.c; 5462224SN/A case CarrySet: 5472482SN/A return condCodes.c; 5482224SN/A case Positive: 5492482SN/A return !condCodes.n; 5502224SN/A case Negative: 5512482SN/A return condCodes.n; 5522224SN/A case OverflowClear: 5532482SN/A return !condCodes.v; 5542224SN/A case OverflowSet: 5552482SN/A return condCodes.v; 5562224SN/A } 5572469SN/A panic("Tried testing condition nonexistant " 5582469SN/A "condition code %d", condition); 5592030SN/A } 5602030SN/A}}; 5612030SN/A 5623931Ssaidi@eecs.umich.eduoutput exec {{ 5633931Ssaidi@eecs.umich.edu /// Check "FP enabled" machine status bit. Called when executing any FP 5648565Sgblack@eecs.umich.edu /// instruction. 5653931Ssaidi@eecs.umich.edu /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled 5663931Ssaidi@eecs.umich.edu /// if not. Non-full-system mode: always returns NoFault. 5678565Sgblack@eecs.umich.edu static inline Fault 56810196SCurtis.Dunham@arm.com checkFpEnableFault(CPU_EXEC_CONTEXT *xc) 5693931Ssaidi@eecs.umich.edu { 5708738Sgblack@eecs.umich.edu if (FullSystem) { 5718829Sgblack@eecs.umich.edu PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE); 5728829Sgblack@eecs.umich.edu if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) { 5738565Sgblack@eecs.umich.edu return NoFault; 5748565Sgblack@eecs.umich.edu } else { 57510474Sandreas.hansson@arm.com return std::make_shared<FpDisabled>(); 5768565Sgblack@eecs.umich.edu } 5778565Sgblack@eecs.umich.edu } else { 5783931Ssaidi@eecs.umich.edu return NoFault; 5797741Sgblack@eecs.umich.edu } 5803931Ssaidi@eecs.umich.edu } 58112110SRekai.GonzalezAlberquilla@arm.com static inline Fault 58212110SRekai.GonzalezAlberquilla@arm.com checkVecEnableFault(CPU_EXEC_CONTEXT *xc) 58312110SRekai.GonzalezAlberquilla@arm.com { 58412110SRekai.GonzalezAlberquilla@arm.com return std::make_shared<VecDisabled>(); 58512110SRekai.GonzalezAlberquilla@arm.com } 5863931Ssaidi@eecs.umich.edu}}; 5873931Ssaidi@eecs.umich.edu 5883931Ssaidi@eecs.umich.edu 589