112275Sgabeblack@google.com/* 212275Sgabeblack@google.com * Copyright (c) 2006-2007 The Regents of The University of Michigan 312275Sgabeblack@google.com * All rights reserved 412275Sgabeblack@google.com * Copyright 2017 Google Inc. 512275Sgabeblack@google.com * 612275Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 712275Sgabeblack@google.com * modification, are permitted provided that the following conditions are 812275Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 912275Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 1012275Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1112275Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1212275Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1312275Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1412275Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1512275Sgabeblack@google.com * this software without specific prior written permission. 1612275Sgabeblack@google.com * 1712275Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1812275Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1912275Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2012275Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2112275Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2212275Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2312275Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2412275Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2512275Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2612275Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2712275Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2812275Sgabeblack@google.com * 2912275Sgabeblack@google.com * Authors: Gabe Black 3012275Sgabeblack@google.com */ 3112275Sgabeblack@google.com 3212275Sgabeblack@google.com#include "arch/sparc/insts/static_inst.hh" 3312275Sgabeblack@google.com 3412275Sgabeblack@google.comnamespace SparcISA 3512275Sgabeblack@google.com{ 3612275Sgabeblack@google.com 3712275Sgabeblack@google.comconst char *CondTestAbbrev[] = 3812275Sgabeblack@google.com{ 3912275Sgabeblack@google.com [Never] = "nev", 4012275Sgabeblack@google.com [Equal] = "e", 4112275Sgabeblack@google.com [LessOrEqual] = "le", 4212275Sgabeblack@google.com [Less] = "l", 4312275Sgabeblack@google.com [LessOrEqualUnsigned] = "leu", 4412275Sgabeblack@google.com [CarrySet] = "c", 4512275Sgabeblack@google.com [Negative] = "n", 4612275Sgabeblack@google.com [OverflowSet] = "o", 4712275Sgabeblack@google.com [Always] = "a", 4812275Sgabeblack@google.com [NotEqual] = "ne", 4912275Sgabeblack@google.com [Greater] = "g", 5012275Sgabeblack@google.com [GreaterOrEqual] = "ge", 5112275Sgabeblack@google.com [GreaterUnsigned] = "gu", 5212275Sgabeblack@google.com [CarryClear] = "cc", 5312275Sgabeblack@google.com [Positive] = "p", 5412275Sgabeblack@google.com [OverflowClear] = "oc" 5512275Sgabeblack@google.com}; 5612275Sgabeblack@google.com 5712275Sgabeblack@google.comvoid 5812275Sgabeblack@google.comSparcStaticInst::printMnemonic(std::ostream &os, const char *mnemonic) 5912275Sgabeblack@google.com{ 6012275Sgabeblack@google.com ccprintf(os, "\t%s ", mnemonic); 6112275Sgabeblack@google.com} 6212275Sgabeblack@google.com 6312275Sgabeblack@google.comvoid 6412275Sgabeblack@google.comSparcStaticInst::printRegArray(std::ostream &os, const RegId indexArray[], 6512275Sgabeblack@google.com int num) const 6612275Sgabeblack@google.com{ 6712275Sgabeblack@google.com if (num <= 0) 6812275Sgabeblack@google.com return; 6912275Sgabeblack@google.com printReg(os, indexArray[0]); 7012275Sgabeblack@google.com for (int x = 1; x < num; x++) { 7112275Sgabeblack@google.com os << ", "; 7212275Sgabeblack@google.com printReg(os, indexArray[x]); 7312275Sgabeblack@google.com } 7412275Sgabeblack@google.com} 7512275Sgabeblack@google.com 7612275Sgabeblack@google.comvoid 7712275Sgabeblack@google.comSparcStaticInst::advancePC(SparcISA::PCState &pcState) const 7812275Sgabeblack@google.com{ 7912275Sgabeblack@google.com pcState.advance(); 8012275Sgabeblack@google.com} 8112275Sgabeblack@google.com 8212275Sgabeblack@google.comvoid 8312275Sgabeblack@google.comSparcStaticInst::printSrcReg(std::ostream &os, int reg) const 8412275Sgabeblack@google.com{ 8512275Sgabeblack@google.com if (_numSrcRegs > reg) 8612275Sgabeblack@google.com printReg(os, _srcRegIdx[reg]); 8712275Sgabeblack@google.com} 8812275Sgabeblack@google.com 8912275Sgabeblack@google.comvoid 9012275Sgabeblack@google.comSparcStaticInst::printDestReg(std::ostream &os, int reg) const 9112275Sgabeblack@google.com{ 9212275Sgabeblack@google.com if (_numDestRegs > reg) 9312275Sgabeblack@google.com printReg(os, _destRegIdx[reg]); 9412275Sgabeblack@google.com} 9512275Sgabeblack@google.com 9612275Sgabeblack@google.comvoid 9712275Sgabeblack@google.comSparcStaticInst::printReg(std::ostream &os, RegId reg) 9812275Sgabeblack@google.com{ 9912275Sgabeblack@google.com const int MaxGlobal = 8; 10012275Sgabeblack@google.com const int MaxOutput = 16; 10112275Sgabeblack@google.com const int MaxLocal = 24; 10212275Sgabeblack@google.com const int MaxInput = 32; 10312275Sgabeblack@google.com const int MaxMicroReg = 40; 10412275Sgabeblack@google.com RegIndex reg_idx = reg.index(); 10512275Sgabeblack@google.com if (reg.isIntReg()) { 10612275Sgabeblack@google.com // If we used a register from the next or previous window, 10712275Sgabeblack@google.com // take out the offset. 10812275Sgabeblack@google.com while (reg_idx >= MaxMicroReg) 10912275Sgabeblack@google.com reg_idx -= MaxMicroReg; 11012275Sgabeblack@google.com if (reg_idx == FramePointerReg) 11112275Sgabeblack@google.com ccprintf(os, "%%fp"); 11212275Sgabeblack@google.com else if (reg_idx == StackPointerReg) 11312275Sgabeblack@google.com ccprintf(os, "%%sp"); 11412275Sgabeblack@google.com else if (reg_idx < MaxGlobal) 11512275Sgabeblack@google.com ccprintf(os, "%%g%d", reg_idx); 11612275Sgabeblack@google.com else if (reg_idx < MaxOutput) 11712275Sgabeblack@google.com ccprintf(os, "%%o%d", reg_idx - MaxGlobal); 11812275Sgabeblack@google.com else if (reg_idx < MaxLocal) 11912275Sgabeblack@google.com ccprintf(os, "%%l%d", reg_idx - MaxOutput); 12012275Sgabeblack@google.com else if (reg_idx < MaxInput) 12112275Sgabeblack@google.com ccprintf(os, "%%i%d", reg_idx - MaxLocal); 12212275Sgabeblack@google.com else if (reg_idx < MaxMicroReg) 12312275Sgabeblack@google.com ccprintf(os, "%%u%d", reg_idx - MaxInput); 12412275Sgabeblack@google.com // The fake int regs that are really control regs 12512275Sgabeblack@google.com else { 12612275Sgabeblack@google.com switch (reg_idx - MaxMicroReg) { 12712275Sgabeblack@google.com case 1: 12812275Sgabeblack@google.com ccprintf(os, "%%y"); 12912275Sgabeblack@google.com break; 13012275Sgabeblack@google.com case 2: 13112275Sgabeblack@google.com ccprintf(os, "%%ccr"); 13212275Sgabeblack@google.com break; 13312275Sgabeblack@google.com case 3: 13412275Sgabeblack@google.com ccprintf(os, "%%cansave"); 13512275Sgabeblack@google.com break; 13612275Sgabeblack@google.com case 4: 13712275Sgabeblack@google.com ccprintf(os, "%%canrestore"); 13812275Sgabeblack@google.com break; 13912275Sgabeblack@google.com case 5: 14012275Sgabeblack@google.com ccprintf(os, "%%cleanwin"); 14112275Sgabeblack@google.com break; 14212275Sgabeblack@google.com case 6: 14312275Sgabeblack@google.com ccprintf(os, "%%otherwin"); 14412275Sgabeblack@google.com break; 14512275Sgabeblack@google.com case 7: 14612275Sgabeblack@google.com ccprintf(os, "%%wstate"); 14712275Sgabeblack@google.com break; 14812275Sgabeblack@google.com } 14912275Sgabeblack@google.com } 15012275Sgabeblack@google.com } else if (reg.isFloatReg()) { 15112275Sgabeblack@google.com ccprintf(os, "%%f%d", reg_idx); 15212275Sgabeblack@google.com } else { 15312275Sgabeblack@google.com switch (reg_idx) { 15412275Sgabeblack@google.com case MISCREG_ASI: 15512275Sgabeblack@google.com ccprintf(os, "%%asi"); 15612275Sgabeblack@google.com break; 15712275Sgabeblack@google.com case MISCREG_FPRS: 15812275Sgabeblack@google.com ccprintf(os, "%%fprs"); 15912275Sgabeblack@google.com break; 16012275Sgabeblack@google.com case MISCREG_PCR: 16112275Sgabeblack@google.com ccprintf(os, "%%pcr"); 16212275Sgabeblack@google.com break; 16312275Sgabeblack@google.com case MISCREG_PIC: 16412275Sgabeblack@google.com ccprintf(os, "%%pic"); 16512275Sgabeblack@google.com break; 16612275Sgabeblack@google.com case MISCREG_GSR: 16712275Sgabeblack@google.com ccprintf(os, "%%gsr"); 16812275Sgabeblack@google.com break; 16912275Sgabeblack@google.com case MISCREG_SOFTINT: 17012275Sgabeblack@google.com ccprintf(os, "%%softint"); 17112275Sgabeblack@google.com break; 17212275Sgabeblack@google.com case MISCREG_SOFTINT_SET: 17312275Sgabeblack@google.com ccprintf(os, "%%softint_set"); 17412275Sgabeblack@google.com break; 17512275Sgabeblack@google.com case MISCREG_SOFTINT_CLR: 17612275Sgabeblack@google.com ccprintf(os, "%%softint_clr"); 17712275Sgabeblack@google.com break; 17812275Sgabeblack@google.com case MISCREG_TICK_CMPR: 17912275Sgabeblack@google.com ccprintf(os, "%%tick_cmpr"); 18012275Sgabeblack@google.com break; 18112275Sgabeblack@google.com case MISCREG_STICK: 18212275Sgabeblack@google.com ccprintf(os, "%%stick"); 18312275Sgabeblack@google.com break; 18412275Sgabeblack@google.com case MISCREG_STICK_CMPR: 18512275Sgabeblack@google.com ccprintf(os, "%%stick_cmpr"); 18612275Sgabeblack@google.com break; 18712275Sgabeblack@google.com case MISCREG_TPC: 18812275Sgabeblack@google.com ccprintf(os, "%%tpc"); 18912275Sgabeblack@google.com break; 19012275Sgabeblack@google.com case MISCREG_TNPC: 19112275Sgabeblack@google.com ccprintf(os, "%%tnpc"); 19212275Sgabeblack@google.com break; 19312275Sgabeblack@google.com case MISCREG_TSTATE: 19412275Sgabeblack@google.com ccprintf(os, "%%tstate"); 19512275Sgabeblack@google.com break; 19612275Sgabeblack@google.com case MISCREG_TT: 19712275Sgabeblack@google.com ccprintf(os, "%%tt"); 19812275Sgabeblack@google.com break; 19912275Sgabeblack@google.com case MISCREG_TICK: 20012275Sgabeblack@google.com ccprintf(os, "%%tick"); 20112275Sgabeblack@google.com break; 20212275Sgabeblack@google.com case MISCREG_TBA: 20312275Sgabeblack@google.com ccprintf(os, "%%tba"); 20412275Sgabeblack@google.com break; 20512275Sgabeblack@google.com case MISCREG_PSTATE: 20612275Sgabeblack@google.com ccprintf(os, "%%pstate"); 20712275Sgabeblack@google.com break; 20812275Sgabeblack@google.com case MISCREG_TL: 20912275Sgabeblack@google.com ccprintf(os, "%%tl"); 21012275Sgabeblack@google.com break; 21112275Sgabeblack@google.com case MISCREG_PIL: 21212275Sgabeblack@google.com ccprintf(os, "%%pil"); 21312275Sgabeblack@google.com break; 21412275Sgabeblack@google.com case MISCREG_CWP: 21512275Sgabeblack@google.com ccprintf(os, "%%cwp"); 21612275Sgabeblack@google.com break; 21712275Sgabeblack@google.com case MISCREG_GL: 21812275Sgabeblack@google.com ccprintf(os, "%%gl"); 21912275Sgabeblack@google.com break; 22012275Sgabeblack@google.com case MISCREG_HPSTATE: 22112275Sgabeblack@google.com ccprintf(os, "%%hpstate"); 22212275Sgabeblack@google.com break; 22312275Sgabeblack@google.com case MISCREG_HTSTATE: 22412275Sgabeblack@google.com ccprintf(os, "%%htstate"); 22512275Sgabeblack@google.com break; 22612275Sgabeblack@google.com case MISCREG_HINTP: 22712275Sgabeblack@google.com ccprintf(os, "%%hintp"); 22812275Sgabeblack@google.com break; 22912275Sgabeblack@google.com case MISCREG_HTBA: 23012275Sgabeblack@google.com ccprintf(os, "%%htba"); 23112275Sgabeblack@google.com break; 23212275Sgabeblack@google.com case MISCREG_HSTICK_CMPR: 23312275Sgabeblack@google.com ccprintf(os, "%%hstick_cmpr"); 23412275Sgabeblack@google.com break; 23512275Sgabeblack@google.com case MISCREG_HVER: 23612275Sgabeblack@google.com ccprintf(os, "%%hver"); 23712275Sgabeblack@google.com break; 23812275Sgabeblack@google.com case MISCREG_STRAND_STS_REG: 23912275Sgabeblack@google.com ccprintf(os, "%%strand_sts_reg"); 24012275Sgabeblack@google.com break; 24112275Sgabeblack@google.com case MISCREG_FSR: 24212275Sgabeblack@google.com ccprintf(os, "%%fsr"); 24312275Sgabeblack@google.com break; 24412275Sgabeblack@google.com default: 24512275Sgabeblack@google.com ccprintf(os, "%%ctrl%d", reg_idx); 24612275Sgabeblack@google.com } 24712275Sgabeblack@google.com } 24812275Sgabeblack@google.com} 24912275Sgabeblack@google.com 25012275Sgabeblack@google.comstd::string 25112275Sgabeblack@google.comSparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const 25212275Sgabeblack@google.com{ 25312275Sgabeblack@google.com std::stringstream ss; 25412275Sgabeblack@google.com 25512275Sgabeblack@google.com printMnemonic(ss, mnemonic); 25612275Sgabeblack@google.com 25712275Sgabeblack@google.com // just print the first two source regs... if there's 25812275Sgabeblack@google.com // a third one, it's a read-modify-write dest (Rc), 25912275Sgabeblack@google.com // e.g. for CMOVxx 26012275Sgabeblack@google.com if (_numSrcRegs > 0) 26112275Sgabeblack@google.com printReg(ss, _srcRegIdx[0]); 26212275Sgabeblack@google.com if (_numSrcRegs > 1) { 26312275Sgabeblack@google.com ss << ","; 26412275Sgabeblack@google.com printReg(ss, _srcRegIdx[1]); 26512275Sgabeblack@google.com } 26612275Sgabeblack@google.com 26712275Sgabeblack@google.com // just print the first dest... if there's a second one, 26812275Sgabeblack@google.com // it's generally implicit 26912275Sgabeblack@google.com if (_numDestRegs > 0) { 27012275Sgabeblack@google.com if (_numSrcRegs > 0) 27112275Sgabeblack@google.com ss << ","; 27212275Sgabeblack@google.com printReg(ss, _destRegIdx[0]); 27312275Sgabeblack@google.com } 27412275Sgabeblack@google.com 27512275Sgabeblack@google.com return ss.str(); 27612275Sgabeblack@google.com} 27712275Sgabeblack@google.com 27812275Sgabeblack@google.combool 27912275Sgabeblack@google.comSparcStaticInst::passesFpCondition(uint32_t fcc, uint32_t condition) 28012275Sgabeblack@google.com{ 28112275Sgabeblack@google.com bool u = (fcc == 3); 28212275Sgabeblack@google.com bool g = (fcc == 2); 28312275Sgabeblack@google.com bool l = (fcc == 1); 28412275Sgabeblack@google.com bool e = (fcc == 0); 28512275Sgabeblack@google.com 28612275Sgabeblack@google.com switch (condition) { 28712275Sgabeblack@google.com case FAlways: 28812275Sgabeblack@google.com return 1; 28912275Sgabeblack@google.com case FNever: 29012275Sgabeblack@google.com return 0; 29112275Sgabeblack@google.com case FUnordered: 29212275Sgabeblack@google.com return u; 29312275Sgabeblack@google.com case FGreater: 29412275Sgabeblack@google.com return g; 29512275Sgabeblack@google.com case FUnorderedOrGreater: 29612275Sgabeblack@google.com return u || g; 29712275Sgabeblack@google.com case FLess: 29812275Sgabeblack@google.com return l; 29912275Sgabeblack@google.com case FUnorderedOrLess: 30012275Sgabeblack@google.com return u || l; 30112275Sgabeblack@google.com case FLessOrGreater: 30212275Sgabeblack@google.com return l || g; 30312275Sgabeblack@google.com case FNotEqual: 30412275Sgabeblack@google.com return l || g || u; 30512275Sgabeblack@google.com case FEqual: 30612275Sgabeblack@google.com return e; 30712275Sgabeblack@google.com case FUnorderedOrEqual: 30812275Sgabeblack@google.com return u || e; 30912275Sgabeblack@google.com case FGreaterOrEqual: 31012275Sgabeblack@google.com return g || e; 31112275Sgabeblack@google.com case FUnorderedOrGreaterOrEqual: 31212275Sgabeblack@google.com return u || g || e; 31312275Sgabeblack@google.com case FLessOrEqual: 31412275Sgabeblack@google.com return l || e; 31512275Sgabeblack@google.com case FUnorderedOrLessOrEqual: 31612275Sgabeblack@google.com return u || l || e; 31712275Sgabeblack@google.com case FOrdered: 31812275Sgabeblack@google.com return e || l || g; 31912275Sgabeblack@google.com } 32012275Sgabeblack@google.com panic("Tried testing condition nonexistant condition code %d", condition); 32112275Sgabeblack@google.com} 32212275Sgabeblack@google.com 32312275Sgabeblack@google.combool 32412275Sgabeblack@google.comSparcStaticInst::passesCondition(uint32_t codes, uint32_t condition) 32512275Sgabeblack@google.com{ 32612275Sgabeblack@google.com BitUnion32(CondCodes) 32712275Sgabeblack@google.com Bitfield<0> c; 32812275Sgabeblack@google.com Bitfield<1> v; 32912275Sgabeblack@google.com Bitfield<2> z; 33012275Sgabeblack@google.com Bitfield<3> n; 33112275Sgabeblack@google.com EndBitUnion(CondCodes) 33212275Sgabeblack@google.com CondCodes condCodes = codes; 33312275Sgabeblack@google.com 33412275Sgabeblack@google.com switch (condition) { 33512275Sgabeblack@google.com case Always: 33612275Sgabeblack@google.com return true; 33712275Sgabeblack@google.com case Never: 33812275Sgabeblack@google.com return false; 33912275Sgabeblack@google.com case NotEqual: 34012275Sgabeblack@google.com return !condCodes.z; 34112275Sgabeblack@google.com case Equal: 34212275Sgabeblack@google.com return condCodes.z; 34312275Sgabeblack@google.com case Greater: 34412275Sgabeblack@google.com return !(condCodes.z | (condCodes.n ^ condCodes.v)); 34512275Sgabeblack@google.com case LessOrEqual: 34612275Sgabeblack@google.com return condCodes.z | (condCodes.n ^ condCodes.v); 34712275Sgabeblack@google.com case GreaterOrEqual: 34812275Sgabeblack@google.com return !(condCodes.n ^ condCodes.v); 34912275Sgabeblack@google.com case Less: 35012275Sgabeblack@google.com return (condCodes.n ^ condCodes.v); 35112275Sgabeblack@google.com case GreaterUnsigned: 35212275Sgabeblack@google.com return !(condCodes.c | condCodes.z); 35312275Sgabeblack@google.com case LessOrEqualUnsigned: 35412275Sgabeblack@google.com return (condCodes.c | condCodes.z); 35512275Sgabeblack@google.com case CarryClear: 35612275Sgabeblack@google.com return !condCodes.c; 35712275Sgabeblack@google.com case CarrySet: 35812275Sgabeblack@google.com return condCodes.c; 35912275Sgabeblack@google.com case Positive: 36012275Sgabeblack@google.com return !condCodes.n; 36112275Sgabeblack@google.com case Negative: 36212275Sgabeblack@google.com return condCodes.n; 36312275Sgabeblack@google.com case OverflowClear: 36412275Sgabeblack@google.com return !condCodes.v; 36512275Sgabeblack@google.com case OverflowSet: 36612275Sgabeblack@google.com return condCodes.v; 36712275Sgabeblack@google.com } 36812275Sgabeblack@google.com panic("Tried testing condition nonexistant " 36912275Sgabeblack@google.com "condition code %d", condition); 37012275Sgabeblack@google.com} 37112275Sgabeblack@google.com 37212275Sgabeblack@google.com} 373