base.isa revision 4004
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 902561SN/A extern 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 1082951Sgblack@eecs.umich.edu void printReg(std::ostream &os, int 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, 1132944Sgblack@eecs.umich.edu const RegIndex indexArray[], int num) const; 1142030SN/A }; 1152030SN/A 1164004Sgblack@eecs.umich.edu bool passesFpCondition(uint32_t fcc, uint32_t condition); 1174004Sgblack@eecs.umich.edu 1182482SN/A bool passesCondition(uint32_t codes, uint32_t condition); 1192516SN/A 1202516SN/A inline int64_t sign_ext(uint64_t data, int origWidth) 1212516SN/A { 1222526SN/A int shiftAmount = 64 - origWidth; 1232516SN/A return (((int64_t)data) << shiftAmount) >> shiftAmount; 1242516SN/A } 1252482SN/A}}; 1262482SN/A 1272561SN/Aoutput decoder {{ 1282561SN/A 1292561SN/A char * CondTestAbbrev[] = 1302561SN/A { 1312561SN/A "nev", //Never 1322561SN/A "e", //Equal 1332561SN/A "le", //Less or Equal 1342561SN/A "l", //Less 1352561SN/A "leu", //Less or Equal Unsigned 1362561SN/A "c", //Carry set 1372561SN/A "n", //Negative 1382561SN/A "o", //Overflow set 1392561SN/A "a", //Always 1402561SN/A "ne", //Not Equal 1412561SN/A "g", //Greater 1422561SN/A "ge", //Greater or Equal 1432561SN/A "gu", //Greater Unsigned 1442561SN/A "cc", //Carry clear 1452561SN/A "p", //Positive 1462561SN/A "oc" //Overflow Clear 1472561SN/A }; 1482561SN/A}}; 1492561SN/A 1502482SN/Adef template ROrImmDecode {{ 1512482SN/A { 1522482SN/A return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 1532482SN/A : (SparcStaticInst *)(new %(class_name)s(machInst))); 1542482SN/A } 1552482SN/A}}; 1562482SN/A 1572482SN/Alet {{ 1582482SN/A def splitOutImm(code): 1592614SN/A matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') 1602482SN/A rOrImmMatch = matcher.search(code) 1612482SN/A if (rOrImmMatch == None): 1622516SN/A return (False, code, '', '', '') 1632516SN/A rString = rOrImmMatch.group("rNum") 1642614SN/A if (rOrImmMatch.group("typeQual") != None): 1652614SN/A rString += rOrImmMatch.group("typeQual") 1662516SN/A iString = rOrImmMatch.group("iNum") 1672482SN/A orig_code = code 1682614SN/A code = matcher.sub('Rs' + rString, orig_code) 1692482SN/A imm_code = matcher.sub('imm', orig_code) 1702516SN/A return (True, code, imm_code, rString, iString) 1712030SN/A}}; 1722030SN/A 1732030SN/Aoutput decoder {{ 1742030SN/A 1752516SN/A inline void printMnemonic(std::ostream &os, const char * mnemonic) 1762516SN/A { 1772516SN/A ccprintf(os, "\t%s ", mnemonic); 1782516SN/A } 1792516SN/A 1802944Sgblack@eecs.umich.edu void SparcStaticInst::printRegArray(std::ostream &os, 1812944Sgblack@eecs.umich.edu const RegIndex indexArray[], int num) const 1822944Sgblack@eecs.umich.edu { 1832944Sgblack@eecs.umich.edu if(num <= 0) 1842944Sgblack@eecs.umich.edu return; 1852944Sgblack@eecs.umich.edu printReg(os, indexArray[0]); 1862944Sgblack@eecs.umich.edu for(int x = 1; x < num; x++) 1872944Sgblack@eecs.umich.edu { 1882944Sgblack@eecs.umich.edu os << ", "; 1892944Sgblack@eecs.umich.edu printReg(os, indexArray[x]); 1902944Sgblack@eecs.umich.edu } 1912944Sgblack@eecs.umich.edu } 1922944Sgblack@eecs.umich.edu 1932469SN/A void 1942944Sgblack@eecs.umich.edu SparcStaticInst::printSrcReg(std::ostream &os, int reg) const 1952944Sgblack@eecs.umich.edu { 1962944Sgblack@eecs.umich.edu if(_numSrcRegs > reg) 1972944Sgblack@eecs.umich.edu printReg(os, _srcRegIdx[reg]); 1982944Sgblack@eecs.umich.edu } 1992944Sgblack@eecs.umich.edu 2002944Sgblack@eecs.umich.edu void 2012944Sgblack@eecs.umich.edu SparcStaticInst::printDestReg(std::ostream &os, int reg) const 2022944Sgblack@eecs.umich.edu { 2032944Sgblack@eecs.umich.edu if(_numDestRegs > reg) 2042944Sgblack@eecs.umich.edu printReg(os, _destRegIdx[reg]); 2052944Sgblack@eecs.umich.edu } 2062944Sgblack@eecs.umich.edu 2072944Sgblack@eecs.umich.edu void 2082951Sgblack@eecs.umich.edu SparcStaticInst::printReg(std::ostream &os, int reg) const 2092469SN/A { 2102516SN/A const int MaxGlobal = 8; 2112516SN/A const int MaxOutput = 16; 2122516SN/A const int MaxLocal = 24; 2132516SN/A const int MaxInput = 32; 2143978Sgblack@eecs.umich.edu const int MaxMicroReg = 40; 2153978Sgblack@eecs.umich.edu if (reg < FP_Base_DepTag) { 2163978Sgblack@eecs.umich.edu //If we used a register from the next or previous window, 2173978Sgblack@eecs.umich.edu //take out the offset. 2183978Sgblack@eecs.umich.edu while (reg >= MaxMicroReg) 2193978Sgblack@eecs.umich.edu reg -= MaxMicroReg; 2203978Sgblack@eecs.umich.edu if (reg == FramePointerReg) 2213978Sgblack@eecs.umich.edu ccprintf(os, "%%fp"); 2223978Sgblack@eecs.umich.edu else if (reg == StackPointerReg) 2233978Sgblack@eecs.umich.edu ccprintf(os, "%%sp"); 2243978Sgblack@eecs.umich.edu else if(reg < MaxGlobal) 2253978Sgblack@eecs.umich.edu ccprintf(os, "%%g%d", reg); 2263978Sgblack@eecs.umich.edu else if(reg < MaxOutput) 2273978Sgblack@eecs.umich.edu ccprintf(os, "%%o%d", reg - MaxGlobal); 2283978Sgblack@eecs.umich.edu else if(reg < MaxLocal) 2293978Sgblack@eecs.umich.edu ccprintf(os, "%%l%d", reg - MaxOutput); 2303978Sgblack@eecs.umich.edu else if(reg < MaxInput) 2313978Sgblack@eecs.umich.edu ccprintf(os, "%%i%d", reg - MaxLocal); 2323978Sgblack@eecs.umich.edu else if(reg < MaxMicroReg) 2333978Sgblack@eecs.umich.edu ccprintf(os, "%%u%d", reg - MaxInput); 2343978Sgblack@eecs.umich.edu //The fake int regs that are really control regs 2353978Sgblack@eecs.umich.edu else { 2363978Sgblack@eecs.umich.edu switch (reg - MaxMicroReg) { 2373978Sgblack@eecs.umich.edu case 1: 2383978Sgblack@eecs.umich.edu ccprintf(os, "%%y"); 2393978Sgblack@eecs.umich.edu break; 2403978Sgblack@eecs.umich.edu case 2: 2413978Sgblack@eecs.umich.edu ccprintf(os, "%%ccr"); 2423978Sgblack@eecs.umich.edu break; 2433978Sgblack@eecs.umich.edu case 3: 2443978Sgblack@eecs.umich.edu ccprintf(os, "%%cansave"); 2453978Sgblack@eecs.umich.edu break; 2463978Sgblack@eecs.umich.edu case 4: 2473978Sgblack@eecs.umich.edu ccprintf(os, "%%canrestore"); 2483978Sgblack@eecs.umich.edu break; 2493978Sgblack@eecs.umich.edu case 5: 2503978Sgblack@eecs.umich.edu ccprintf(os, "%%cleanwin"); 2513978Sgblack@eecs.umich.edu break; 2523978Sgblack@eecs.umich.edu case 6: 2533978Sgblack@eecs.umich.edu ccprintf(os, "%%otherwin"); 2543978Sgblack@eecs.umich.edu break; 2553978Sgblack@eecs.umich.edu case 7: 2563978Sgblack@eecs.umich.edu ccprintf(os, "%%wstate"); 2573978Sgblack@eecs.umich.edu break; 2583978Sgblack@eecs.umich.edu } 2593978Sgblack@eecs.umich.edu } 2603978Sgblack@eecs.umich.edu } else if (reg < Ctrl_Base_DepTag) { 2613978Sgblack@eecs.umich.edu ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 2623978Sgblack@eecs.umich.edu } else { 2633978Sgblack@eecs.umich.edu switch (reg - Ctrl_Base_DepTag) { 2643978Sgblack@eecs.umich.edu case MISCREG_ASI: 2653978Sgblack@eecs.umich.edu ccprintf(os, "%%asi"); 2663978Sgblack@eecs.umich.edu break; 2673978Sgblack@eecs.umich.edu case MISCREG_FPRS: 2683978Sgblack@eecs.umich.edu ccprintf(os, "%%fprs"); 2693978Sgblack@eecs.umich.edu break; 2703978Sgblack@eecs.umich.edu case MISCREG_PCR: 2713978Sgblack@eecs.umich.edu ccprintf(os, "%%pcr"); 2723978Sgblack@eecs.umich.edu break; 2733978Sgblack@eecs.umich.edu case MISCREG_PIC: 2743978Sgblack@eecs.umich.edu ccprintf(os, "%%pic"); 2753978Sgblack@eecs.umich.edu break; 2763978Sgblack@eecs.umich.edu case MISCREG_GSR: 2773978Sgblack@eecs.umich.edu ccprintf(os, "%%gsr"); 2783978Sgblack@eecs.umich.edu break; 2793978Sgblack@eecs.umich.edu case MISCREG_SOFTINT: 2803978Sgblack@eecs.umich.edu ccprintf(os, "%%softint"); 2813978Sgblack@eecs.umich.edu break; 2823978Sgblack@eecs.umich.edu case MISCREG_SOFTINT_SET: 2833978Sgblack@eecs.umich.edu ccprintf(os, "%%softint_set"); 2843978Sgblack@eecs.umich.edu break; 2853978Sgblack@eecs.umich.edu case MISCREG_SOFTINT_CLR: 2863978Sgblack@eecs.umich.edu ccprintf(os, "%%softint_clr"); 2873978Sgblack@eecs.umich.edu break; 2883978Sgblack@eecs.umich.edu case MISCREG_TICK_CMPR: 2893978Sgblack@eecs.umich.edu ccprintf(os, "%%tick_cmpr"); 2903978Sgblack@eecs.umich.edu break; 2913978Sgblack@eecs.umich.edu case MISCREG_STICK: 2923978Sgblack@eecs.umich.edu ccprintf(os, "%%stick"); 2933978Sgblack@eecs.umich.edu break; 2943978Sgblack@eecs.umich.edu case MISCREG_STICK_CMPR: 2953978Sgblack@eecs.umich.edu ccprintf(os, "%%stick_cmpr"); 2963978Sgblack@eecs.umich.edu break; 2973978Sgblack@eecs.umich.edu case MISCREG_TPC: 2983978Sgblack@eecs.umich.edu ccprintf(os, "%%tpc"); 2993978Sgblack@eecs.umich.edu break; 3003978Sgblack@eecs.umich.edu case MISCREG_TNPC: 3013978Sgblack@eecs.umich.edu ccprintf(os, "%%tnpc"); 3023978Sgblack@eecs.umich.edu break; 3033978Sgblack@eecs.umich.edu case MISCREG_TSTATE: 3043978Sgblack@eecs.umich.edu ccprintf(os, "%%tstate"); 3053978Sgblack@eecs.umich.edu break; 3063978Sgblack@eecs.umich.edu case MISCREG_TT: 3073978Sgblack@eecs.umich.edu ccprintf(os, "%%tt"); 3083978Sgblack@eecs.umich.edu break; 3093978Sgblack@eecs.umich.edu case MISCREG_TICK: 3103978Sgblack@eecs.umich.edu ccprintf(os, "%%tick"); 3113978Sgblack@eecs.umich.edu break; 3123978Sgblack@eecs.umich.edu case MISCREG_TBA: 3133978Sgblack@eecs.umich.edu ccprintf(os, "%%tba"); 3143978Sgblack@eecs.umich.edu break; 3153978Sgblack@eecs.umich.edu case MISCREG_PSTATE: 3163978Sgblack@eecs.umich.edu ccprintf(os, "%%pstate"); 3173978Sgblack@eecs.umich.edu break; 3183978Sgblack@eecs.umich.edu case MISCREG_TL: 3193978Sgblack@eecs.umich.edu ccprintf(os, "%%tl"); 3203978Sgblack@eecs.umich.edu break; 3213978Sgblack@eecs.umich.edu case MISCREG_PIL: 3223978Sgblack@eecs.umich.edu ccprintf(os, "%%pil"); 3233978Sgblack@eecs.umich.edu break; 3243978Sgblack@eecs.umich.edu case MISCREG_CWP: 3253978Sgblack@eecs.umich.edu ccprintf(os, "%%cwp"); 3263978Sgblack@eecs.umich.edu break; 3273978Sgblack@eecs.umich.edu case MISCREG_GL: 3283978Sgblack@eecs.umich.edu ccprintf(os, "%%gl"); 3293978Sgblack@eecs.umich.edu break; 3303978Sgblack@eecs.umich.edu case MISCREG_HPSTATE: 3313978Sgblack@eecs.umich.edu ccprintf(os, "%%hpstate"); 3323978Sgblack@eecs.umich.edu break; 3333978Sgblack@eecs.umich.edu case MISCREG_HTSTATE: 3343978Sgblack@eecs.umich.edu ccprintf(os, "%%htstate"); 3353978Sgblack@eecs.umich.edu break; 3363978Sgblack@eecs.umich.edu case MISCREG_HINTP: 3373978Sgblack@eecs.umich.edu ccprintf(os, "%%hintp"); 3383978Sgblack@eecs.umich.edu break; 3393978Sgblack@eecs.umich.edu case MISCREG_HTBA: 3403978Sgblack@eecs.umich.edu ccprintf(os, "%%htba"); 3413978Sgblack@eecs.umich.edu break; 3423978Sgblack@eecs.umich.edu case MISCREG_HSTICK_CMPR: 3433978Sgblack@eecs.umich.edu ccprintf(os, "%%hstick_cmpr"); 3443978Sgblack@eecs.umich.edu break; 3453978Sgblack@eecs.umich.edu case MISCREG_HVER: 3463978Sgblack@eecs.umich.edu ccprintf(os, "%%hver"); 3473978Sgblack@eecs.umich.edu break; 3483978Sgblack@eecs.umich.edu case MISCREG_STRAND_STS_REG: 3493978Sgblack@eecs.umich.edu ccprintf(os, "%%strand_sts_reg"); 3503978Sgblack@eecs.umich.edu break; 3513978Sgblack@eecs.umich.edu case MISCREG_FSR: 3523978Sgblack@eecs.umich.edu ccprintf(os, "%%fsr"); 3533978Sgblack@eecs.umich.edu break; 3543978Sgblack@eecs.umich.edu default: 3553978Sgblack@eecs.umich.edu ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag); 3563978Sgblack@eecs.umich.edu } 3572469SN/A } 3582469SN/A } 3592469SN/A 3602224SN/A std::string SparcStaticInst::generateDisassembly(Addr pc, 3612224SN/A const SymbolTable *symtab) const 3622030SN/A { 3632224SN/A std::stringstream ss; 3642030SN/A 3652516SN/A printMnemonic(ss, mnemonic); 3662030SN/A 3672224SN/A // just print the first two source regs... if there's 3682224SN/A // a third one, it's a read-modify-write dest (Rc), 3692224SN/A // e.g. for CMOVxx 3702224SN/A if(_numSrcRegs > 0) 3712224SN/A { 3722224SN/A printReg(ss, _srcRegIdx[0]); 3732224SN/A } 3742224SN/A if(_numSrcRegs > 1) 3752224SN/A { 3762224SN/A ss << ","; 3772224SN/A printReg(ss, _srcRegIdx[1]); 3782224SN/A } 3792224SN/A 3802224SN/A // just print the first dest... if there's a second one, 3812224SN/A // it's generally implicit 3822224SN/A if(_numDestRegs > 0) 3832224SN/A { 3842030SN/A if(_numSrcRegs > 0) 3852224SN/A ss << ","; 3862224SN/A printReg(ss, _destRegIdx[0]); 3872224SN/A } 3882030SN/A 3892224SN/A return ss.str(); 3902030SN/A } 3912030SN/A 3924004Sgblack@eecs.umich.edu bool passesFpCondition(uint32_t fcc, uint32_t condition) 3934004Sgblack@eecs.umich.edu { 3944004Sgblack@eecs.umich.edu bool u = (fcc == 3); 3954004Sgblack@eecs.umich.edu bool g = (fcc == 2); 3964004Sgblack@eecs.umich.edu bool l = (fcc == 1); 3974004Sgblack@eecs.umich.edu bool e = (fcc == 0); 3984004Sgblack@eecs.umich.edu switch(condition) 3994004Sgblack@eecs.umich.edu { 4004004Sgblack@eecs.umich.edu case FAlways: 4014004Sgblack@eecs.umich.edu return 1; 4024004Sgblack@eecs.umich.edu case FNever: 4034004Sgblack@eecs.umich.edu return 0; 4044004Sgblack@eecs.umich.edu case FUnordered: 4054004Sgblack@eecs.umich.edu return u; 4064004Sgblack@eecs.umich.edu case FGreater: 4074004Sgblack@eecs.umich.edu return g; 4084004Sgblack@eecs.umich.edu case FUnorderedOrGreater: 4094004Sgblack@eecs.umich.edu return u || g; 4104004Sgblack@eecs.umich.edu case FLess: 4114004Sgblack@eecs.umich.edu return l; 4124004Sgblack@eecs.umich.edu case FUnorderedOrLess: 4134004Sgblack@eecs.umich.edu return u || l; 4144004Sgblack@eecs.umich.edu case FLessOrGreater: 4154004Sgblack@eecs.umich.edu return l || g; 4164004Sgblack@eecs.umich.edu case FNotEqual: 4174004Sgblack@eecs.umich.edu return l || g || u; 4184004Sgblack@eecs.umich.edu case FEqual: 4194004Sgblack@eecs.umich.edu return e; 4204004Sgblack@eecs.umich.edu case FUnorderedOrEqual: 4214004Sgblack@eecs.umich.edu return u || e; 4224004Sgblack@eecs.umich.edu case FGreaterOrEqual: 4234004Sgblack@eecs.umich.edu return g || e; 4244004Sgblack@eecs.umich.edu case FUnorderedOrGreaterOrEqual: 4254004Sgblack@eecs.umich.edu return u || g || e; 4264004Sgblack@eecs.umich.edu case FLessOrEqual: 4274004Sgblack@eecs.umich.edu return l || e; 4284004Sgblack@eecs.umich.edu case FUnorderedOrLessOrEqual: 4294004Sgblack@eecs.umich.edu return u || l || e; 4304004Sgblack@eecs.umich.edu case FOrdered: 4314004Sgblack@eecs.umich.edu return e || l || g; 4324004Sgblack@eecs.umich.edu } 4334004Sgblack@eecs.umich.edu panic("Tried testing condition nonexistant " 4344004Sgblack@eecs.umich.edu "condition code %d", condition); 4354004Sgblack@eecs.umich.edu } 4364004Sgblack@eecs.umich.edu 4372482SN/A bool passesCondition(uint32_t codes, uint32_t condition) 4382030SN/A { 4392482SN/A CondCodes condCodes; 4403603Ssaidi@eecs.umich.edu condCodes.bits = 0; 4413603Ssaidi@eecs.umich.edu condCodes.c = codes & 0x1 ? 1 : 0; 4423603Ssaidi@eecs.umich.edu condCodes.v = codes & 0x2 ? 1 : 0; 4433603Ssaidi@eecs.umich.edu condCodes.z = codes & 0x4 ? 1 : 0; 4443603Ssaidi@eecs.umich.edu condCodes.n = codes & 0x8 ? 1 : 0; 4453603Ssaidi@eecs.umich.edu 4462224SN/A switch(condition) 4472224SN/A { 4482224SN/A case Always: 4492224SN/A return true; 4502224SN/A case Never: 4512224SN/A return false; 4522224SN/A case NotEqual: 4532482SN/A return !condCodes.z; 4542224SN/A case Equal: 4552482SN/A return condCodes.z; 4562224SN/A case Greater: 4572482SN/A return !(condCodes.z | (condCodes.n ^ condCodes.v)); 4582224SN/A case LessOrEqual: 4592482SN/A return condCodes.z | (condCodes.n ^ condCodes.v); 4602224SN/A case GreaterOrEqual: 4612482SN/A return !(condCodes.n ^ condCodes.v); 4622224SN/A case Less: 4632482SN/A return (condCodes.n ^ condCodes.v); 4642224SN/A case GreaterUnsigned: 4652482SN/A return !(condCodes.c | condCodes.z); 4662224SN/A case LessOrEqualUnsigned: 4672482SN/A return (condCodes.c | condCodes.z); 4682224SN/A case CarryClear: 4692482SN/A return !condCodes.c; 4702224SN/A case CarrySet: 4712482SN/A return condCodes.c; 4722224SN/A case Positive: 4732482SN/A return !condCodes.n; 4742224SN/A case Negative: 4752482SN/A return condCodes.n; 4762224SN/A case OverflowClear: 4772482SN/A return !condCodes.v; 4782224SN/A case OverflowSet: 4792482SN/A return condCodes.v; 4802224SN/A } 4812469SN/A panic("Tried testing condition nonexistant " 4822469SN/A "condition code %d", condition); 4832030SN/A } 4842030SN/A}}; 4852030SN/A 4863931Ssaidi@eecs.umich.eduoutput exec {{ 4873931Ssaidi@eecs.umich.edu /// Check "FP enabled" machine status bit. Called when executing any FP 4883931Ssaidi@eecs.umich.edu /// instruction in full-system mode. 4893931Ssaidi@eecs.umich.edu /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled 4903931Ssaidi@eecs.umich.edu /// if not. Non-full-system mode: always returns NoFault. 4913931Ssaidi@eecs.umich.edu#if FULL_SYSTEM 4923931Ssaidi@eecs.umich.edu inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) 4933931Ssaidi@eecs.umich.edu { 4943931Ssaidi@eecs.umich.edu Fault fault = NoFault; // dummy... this ipr access should not fault 4953931Ssaidi@eecs.umich.edu if (xc->readMiscRegWithEffect(MISCREG_PSTATE) & PSTATE::pef && 4963931Ssaidi@eecs.umich.edu xc->readMiscRegWithEffect(MISCREG_FPRS) & 0x4) 4973931Ssaidi@eecs.umich.edu return NoFault; 4983931Ssaidi@eecs.umich.edu else 4993931Ssaidi@eecs.umich.edu return new FpDisabled; 5003931Ssaidi@eecs.umich.edu } 5013931Ssaidi@eecs.umich.edu#else 5023931Ssaidi@eecs.umich.edu inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) 5033931Ssaidi@eecs.umich.edu { 5043931Ssaidi@eecs.umich.edu return NoFault; 5053931Ssaidi@eecs.umich.edu } 5063931Ssaidi@eecs.umich.edu#endif 5073931Ssaidi@eecs.umich.edu}}; 5083931Ssaidi@eecs.umich.edu 5093931Ssaidi@eecs.umich.edu 510