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