16691Stjones1@inf.ed.ac.uk/*
26691Stjones1@inf.ed.ac.uk * Copyright (c) 2009 The University of Edinburgh
36691Stjones1@inf.ed.ac.uk * All rights reserved.
46691Stjones1@inf.ed.ac.uk *
56691Stjones1@inf.ed.ac.uk * Redistribution and use in source and binary forms, with or without
66691Stjones1@inf.ed.ac.uk * modification, are permitted provided that the following conditions are
76691Stjones1@inf.ed.ac.uk * met: redistributions of source code must retain the above copyright
86691Stjones1@inf.ed.ac.uk * notice, this list of conditions and the following disclaimer;
96691Stjones1@inf.ed.ac.uk * redistributions in binary form must reproduce the above copyright
106691Stjones1@inf.ed.ac.uk * notice, this list of conditions and the following disclaimer in the
116691Stjones1@inf.ed.ac.uk * documentation and/or other materials provided with the distribution;
126691Stjones1@inf.ed.ac.uk * neither the name of the copyright holders nor the names of its
136691Stjones1@inf.ed.ac.uk * contributors may be used to endorse or promote products derived from
146691Stjones1@inf.ed.ac.uk * this software without specific prior written permission.
156691Stjones1@inf.ed.ac.uk *
166691Stjones1@inf.ed.ac.uk * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176691Stjones1@inf.ed.ac.uk * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186691Stjones1@inf.ed.ac.uk * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196691Stjones1@inf.ed.ac.uk * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206691Stjones1@inf.ed.ac.uk * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216691Stjones1@inf.ed.ac.uk * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226691Stjones1@inf.ed.ac.uk * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236691Stjones1@inf.ed.ac.uk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246691Stjones1@inf.ed.ac.uk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256691Stjones1@inf.ed.ac.uk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266691Stjones1@inf.ed.ac.uk * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276691Stjones1@inf.ed.ac.uk *
286691Stjones1@inf.ed.ac.uk * Authors: Timothy M. Jones
296691Stjones1@inf.ed.ac.uk */
306691Stjones1@inf.ed.ac.uk
316691Stjones1@inf.ed.ac.uk#include "arch/power/insts/integer.hh"
326691Stjones1@inf.ed.ac.uk
336691Stjones1@inf.ed.ac.ukusing namespace std;
346691Stjones1@inf.ed.ac.ukusing namespace PowerISA;
356691Stjones1@inf.ed.ac.uk
366691Stjones1@inf.ed.ac.ukstring
376691Stjones1@inf.ed.ac.ukIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
386691Stjones1@inf.ed.ac.uk{
396691Stjones1@inf.ed.ac.uk    stringstream ss;
406691Stjones1@inf.ed.ac.uk    bool printDest = true;
416691Stjones1@inf.ed.ac.uk    bool printSrcs = true;
426691Stjones1@inf.ed.ac.uk    bool printSecondSrc = true;
436691Stjones1@inf.ed.ac.uk
446691Stjones1@inf.ed.ac.uk    // Generate the correct mnemonic
456691Stjones1@inf.ed.ac.uk    string myMnemonic(mnemonic);
466691Stjones1@inf.ed.ac.uk
476691Stjones1@inf.ed.ac.uk    // Special cases
486691Stjones1@inf.ed.ac.uk    if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) {
496691Stjones1@inf.ed.ac.uk        myMnemonic = "mr";
506691Stjones1@inf.ed.ac.uk        printSecondSrc = false;
516691Stjones1@inf.ed.ac.uk    } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) {
526691Stjones1@inf.ed.ac.uk        printDest = false;
536691Stjones1@inf.ed.ac.uk    } else if (!myMnemonic.compare("mflr")) {
546691Stjones1@inf.ed.ac.uk        printSrcs = false;
556691Stjones1@inf.ed.ac.uk    }
566691Stjones1@inf.ed.ac.uk
576691Stjones1@inf.ed.ac.uk    // Additional characters depending on isa bits being set
586691Stjones1@inf.ed.ac.uk    if (oeSet) myMnemonic = myMnemonic + "o";
596691Stjones1@inf.ed.ac.uk    if (rcSet) myMnemonic = myMnemonic + ".";
606691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", myMnemonic);
616691Stjones1@inf.ed.ac.uk
626691Stjones1@inf.ed.ac.uk    // Print the first destination only
636691Stjones1@inf.ed.ac.uk    if (_numDestRegs > 0 && printDest) {
646691Stjones1@inf.ed.ac.uk        printReg(ss, _destRegIdx[0]);
656691Stjones1@inf.ed.ac.uk    }
666691Stjones1@inf.ed.ac.uk
676691Stjones1@inf.ed.ac.uk    // Print the (possibly) two source registers
686691Stjones1@inf.ed.ac.uk    if (_numSrcRegs > 0 && printSrcs) {
696691Stjones1@inf.ed.ac.uk        if (_numDestRegs > 0 && printDest) {
706691Stjones1@inf.ed.ac.uk            ss << ", ";
716691Stjones1@inf.ed.ac.uk        }
726691Stjones1@inf.ed.ac.uk        printReg(ss, _srcRegIdx[0]);
736691Stjones1@inf.ed.ac.uk        if (_numSrcRegs > 1 && printSecondSrc) {
746691Stjones1@inf.ed.ac.uk          ss << ", ";
756691Stjones1@inf.ed.ac.uk          printReg(ss, _srcRegIdx[1]);
766691Stjones1@inf.ed.ac.uk        }
776691Stjones1@inf.ed.ac.uk    }
786691Stjones1@inf.ed.ac.uk
796691Stjones1@inf.ed.ac.uk    return ss.str();
806691Stjones1@inf.ed.ac.uk}
816691Stjones1@inf.ed.ac.uk
826691Stjones1@inf.ed.ac.uk
836691Stjones1@inf.ed.ac.ukstring
846691Stjones1@inf.ed.ac.ukIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
856691Stjones1@inf.ed.ac.uk{
866691Stjones1@inf.ed.ac.uk    stringstream ss;
876691Stjones1@inf.ed.ac.uk
886691Stjones1@inf.ed.ac.uk    // Generate the correct mnemonic
896691Stjones1@inf.ed.ac.uk    string myMnemonic(mnemonic);
906691Stjones1@inf.ed.ac.uk
916691Stjones1@inf.ed.ac.uk    // Special cases
926691Stjones1@inf.ed.ac.uk    if (!myMnemonic.compare("addi") && _numSrcRegs == 0) {
936691Stjones1@inf.ed.ac.uk        myMnemonic = "li";
946691Stjones1@inf.ed.ac.uk    } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) {
956691Stjones1@inf.ed.ac.uk        myMnemonic = "lis";
966691Stjones1@inf.ed.ac.uk    }
976691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", myMnemonic);
986691Stjones1@inf.ed.ac.uk
996691Stjones1@inf.ed.ac.uk    // Print the first destination only
1006691Stjones1@inf.ed.ac.uk    if (_numDestRegs > 0) {
1016691Stjones1@inf.ed.ac.uk        printReg(ss, _destRegIdx[0]);
1026691Stjones1@inf.ed.ac.uk    }
1036691Stjones1@inf.ed.ac.uk
1046691Stjones1@inf.ed.ac.uk    // Print the source register
1056691Stjones1@inf.ed.ac.uk    if (_numSrcRegs > 0) {
1066691Stjones1@inf.ed.ac.uk        if (_numDestRegs > 0) {
1076691Stjones1@inf.ed.ac.uk            ss << ", ";
1086691Stjones1@inf.ed.ac.uk        }
1096691Stjones1@inf.ed.ac.uk        printReg(ss, _srcRegIdx[0]);
1106691Stjones1@inf.ed.ac.uk    }
1116691Stjones1@inf.ed.ac.uk
1126691Stjones1@inf.ed.ac.uk    // Print the immediate value last
1136691Stjones1@inf.ed.ac.uk    ss << ", " << (int32_t)imm;
1146691Stjones1@inf.ed.ac.uk
1156691Stjones1@inf.ed.ac.uk    return ss.str();
1166691Stjones1@inf.ed.ac.uk}
1176691Stjones1@inf.ed.ac.uk
1186691Stjones1@inf.ed.ac.uk
1196691Stjones1@inf.ed.ac.ukstring
1206691Stjones1@inf.ed.ac.ukIntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1216691Stjones1@inf.ed.ac.uk{
1226691Stjones1@inf.ed.ac.uk    stringstream ss;
1236691Stjones1@inf.ed.ac.uk
1246691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", mnemonic);
1256691Stjones1@inf.ed.ac.uk
1266691Stjones1@inf.ed.ac.uk    // Print the first destination only
1276691Stjones1@inf.ed.ac.uk    if (_numDestRegs > 0) {
1286691Stjones1@inf.ed.ac.uk        printReg(ss, _destRegIdx[0]);
1296691Stjones1@inf.ed.ac.uk    }
1306691Stjones1@inf.ed.ac.uk
1316691Stjones1@inf.ed.ac.uk    // Print the first source register
1326691Stjones1@inf.ed.ac.uk    if (_numSrcRegs > 0) {
1336691Stjones1@inf.ed.ac.uk        if (_numDestRegs > 0) {
1346691Stjones1@inf.ed.ac.uk            ss << ", ";
1356691Stjones1@inf.ed.ac.uk        }
1366691Stjones1@inf.ed.ac.uk        printReg(ss, _srcRegIdx[0]);
1376691Stjones1@inf.ed.ac.uk    }
1386691Stjones1@inf.ed.ac.uk
1396691Stjones1@inf.ed.ac.uk    // Print the shift
1406691Stjones1@inf.ed.ac.uk    ss << ", " << sh;
1416691Stjones1@inf.ed.ac.uk
1426691Stjones1@inf.ed.ac.uk    return ss.str();
1436691Stjones1@inf.ed.ac.uk}
1446691Stjones1@inf.ed.ac.uk
1456691Stjones1@inf.ed.ac.uk
1466691Stjones1@inf.ed.ac.ukstring
1476691Stjones1@inf.ed.ac.ukIntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1486691Stjones1@inf.ed.ac.uk{
1496691Stjones1@inf.ed.ac.uk    stringstream ss;
1506691Stjones1@inf.ed.ac.uk
1516691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", mnemonic);
1526691Stjones1@inf.ed.ac.uk
1536691Stjones1@inf.ed.ac.uk    // Print the first destination only
1546691Stjones1@inf.ed.ac.uk    if (_numDestRegs > 0) {
1556691Stjones1@inf.ed.ac.uk        printReg(ss, _destRegIdx[0]);
1566691Stjones1@inf.ed.ac.uk    }
1576691Stjones1@inf.ed.ac.uk
1586691Stjones1@inf.ed.ac.uk    // Print the first source register
1596691Stjones1@inf.ed.ac.uk    if (_numSrcRegs > 0) {
1606691Stjones1@inf.ed.ac.uk        if (_numDestRegs > 0) {
1616691Stjones1@inf.ed.ac.uk            ss << ", ";
1626691Stjones1@inf.ed.ac.uk        }
1636691Stjones1@inf.ed.ac.uk        printReg(ss, _srcRegIdx[0]);
1646691Stjones1@inf.ed.ac.uk    }
1656691Stjones1@inf.ed.ac.uk
1666691Stjones1@inf.ed.ac.uk    // Print the shift, mask begin and mask end
1676691Stjones1@inf.ed.ac.uk    ss << ", " << sh << ", " << mb << ", " << me;
1686691Stjones1@inf.ed.ac.uk
1696691Stjones1@inf.ed.ac.uk    return ss.str();
1706691Stjones1@inf.ed.ac.uk}
171