branch.cc revision 11793
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/branch.hh"
3211793Sbrandon.potter@amd.com
336691Stjones1@inf.ed.ac.uk#include "base/loader/symtab.hh"
347680Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
356691Stjones1@inf.ed.ac.uk
366691Stjones1@inf.ed.ac.ukusing namespace PowerISA;
376691Stjones1@inf.ed.ac.uk
386691Stjones1@inf.ed.ac.ukconst std::string &
396691Stjones1@inf.ed.ac.ukPCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab) const
406691Stjones1@inf.ed.ac.uk{
416691Stjones1@inf.ed.ac.uk    if (!cachedDisassembly ||
426691Stjones1@inf.ed.ac.uk        pc != cachedPC || symtab != cachedSymtab)
436691Stjones1@inf.ed.ac.uk    {
446691Stjones1@inf.ed.ac.uk        if (cachedDisassembly)
456691Stjones1@inf.ed.ac.uk            delete cachedDisassembly;
466691Stjones1@inf.ed.ac.uk
476691Stjones1@inf.ed.ac.uk        cachedDisassembly =
486691Stjones1@inf.ed.ac.uk            new std::string(generateDisassembly(pc, symtab));
496691Stjones1@inf.ed.ac.uk        cachedPC = pc;
506691Stjones1@inf.ed.ac.uk        cachedSymtab = symtab;
516691Stjones1@inf.ed.ac.uk    }
526691Stjones1@inf.ed.ac.uk
536691Stjones1@inf.ed.ac.uk    return *cachedDisassembly;
546691Stjones1@inf.ed.ac.uk}
556691Stjones1@inf.ed.ac.uk
567720Sgblack@eecs.umich.eduPowerISA::PCState
577720Sgblack@eecs.umich.eduBranchPCRel::branchTarget(const PowerISA::PCState &pc) const
586691Stjones1@inf.ed.ac.uk{
597720Sgblack@eecs.umich.edu    return (uint32_t)(pc.pc() + disp);
606691Stjones1@inf.ed.ac.uk}
616691Stjones1@inf.ed.ac.uk
626691Stjones1@inf.ed.ac.ukstd::string
636691Stjones1@inf.ed.ac.ukBranchPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
646691Stjones1@inf.ed.ac.uk{
656691Stjones1@inf.ed.ac.uk    std::stringstream ss;
666691Stjones1@inf.ed.ac.uk
676691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", mnemonic);
686691Stjones1@inf.ed.ac.uk
696691Stjones1@inf.ed.ac.uk    Addr target = pc + disp;
706691Stjones1@inf.ed.ac.uk
716691Stjones1@inf.ed.ac.uk    std::string str;
726691Stjones1@inf.ed.ac.uk    if (symtab && symtab->findSymbol(target, str))
736691Stjones1@inf.ed.ac.uk        ss << str;
746691Stjones1@inf.ed.ac.uk    else
756691Stjones1@inf.ed.ac.uk        ccprintf(ss, "0x%x", target);
766691Stjones1@inf.ed.ac.uk
776691Stjones1@inf.ed.ac.uk    return ss.str();
786691Stjones1@inf.ed.ac.uk}
796691Stjones1@inf.ed.ac.uk
807720Sgblack@eecs.umich.eduPowerISA::PCState
817720Sgblack@eecs.umich.eduBranchNonPCRel::branchTarget(const PowerISA::PCState &pc) const
826691Stjones1@inf.ed.ac.uk{
836691Stjones1@inf.ed.ac.uk    return targetAddr;
846691Stjones1@inf.ed.ac.uk}
856691Stjones1@inf.ed.ac.uk
866691Stjones1@inf.ed.ac.ukstd::string
876691Stjones1@inf.ed.ac.ukBranchNonPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
886691Stjones1@inf.ed.ac.uk{
896691Stjones1@inf.ed.ac.uk    std::stringstream ss;
906691Stjones1@inf.ed.ac.uk
916691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", mnemonic);
926691Stjones1@inf.ed.ac.uk
936691Stjones1@inf.ed.ac.uk    std::string str;
946691Stjones1@inf.ed.ac.uk    if (symtab && symtab->findSymbol(targetAddr, str))
956691Stjones1@inf.ed.ac.uk        ss << str;
966691Stjones1@inf.ed.ac.uk    else
976691Stjones1@inf.ed.ac.uk        ccprintf(ss, "0x%x", targetAddr);
986691Stjones1@inf.ed.ac.uk
996691Stjones1@inf.ed.ac.uk    return ss.str();
1006691Stjones1@inf.ed.ac.uk}
1016691Stjones1@inf.ed.ac.uk
1027720Sgblack@eecs.umich.eduPowerISA::PCState
1037720Sgblack@eecs.umich.eduBranchPCRelCond::branchTarget(const PowerISA::PCState &pc) const
1046691Stjones1@inf.ed.ac.uk{
1057720Sgblack@eecs.umich.edu    return (uint32_t)(pc.pc() + disp);
1066691Stjones1@inf.ed.ac.uk}
1076691Stjones1@inf.ed.ac.uk
1086691Stjones1@inf.ed.ac.ukstd::string
1096691Stjones1@inf.ed.ac.ukBranchPCRelCond::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1106691Stjones1@inf.ed.ac.uk{
1116691Stjones1@inf.ed.ac.uk    std::stringstream ss;
1126691Stjones1@inf.ed.ac.uk
1136691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", mnemonic);
1146691Stjones1@inf.ed.ac.uk
1156691Stjones1@inf.ed.ac.uk    ss << bo << ", " << bi << ", ";
1166691Stjones1@inf.ed.ac.uk
1176691Stjones1@inf.ed.ac.uk    Addr target = pc + disp;
1186691Stjones1@inf.ed.ac.uk
1196691Stjones1@inf.ed.ac.uk    std::string str;
1206691Stjones1@inf.ed.ac.uk    if (symtab && symtab->findSymbol(target, str))
1216691Stjones1@inf.ed.ac.uk        ss << str;
1226691Stjones1@inf.ed.ac.uk    else
1236691Stjones1@inf.ed.ac.uk        ccprintf(ss, "0x%x", target);
1246691Stjones1@inf.ed.ac.uk
1256691Stjones1@inf.ed.ac.uk    return ss.str();
1266691Stjones1@inf.ed.ac.uk}
1276691Stjones1@inf.ed.ac.uk
1287720Sgblack@eecs.umich.eduPowerISA::PCState
1297720Sgblack@eecs.umich.eduBranchNonPCRelCond::branchTarget(const PowerISA::PCState &pc) const
1306691Stjones1@inf.ed.ac.uk{
1316691Stjones1@inf.ed.ac.uk    return targetAddr;
1326691Stjones1@inf.ed.ac.uk}
1336691Stjones1@inf.ed.ac.uk
1346691Stjones1@inf.ed.ac.ukstd::string
1356691Stjones1@inf.ed.ac.ukBranchNonPCRelCond::generateDisassembly(Addr pc,
1366691Stjones1@inf.ed.ac.uk                                        const SymbolTable *symtab) const
1376691Stjones1@inf.ed.ac.uk{
1386691Stjones1@inf.ed.ac.uk    std::stringstream ss;
1396691Stjones1@inf.ed.ac.uk
1406691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", mnemonic);
1416691Stjones1@inf.ed.ac.uk
1426691Stjones1@inf.ed.ac.uk    ss << bo << ", " << bi << ", ";
1436691Stjones1@inf.ed.ac.uk
1446691Stjones1@inf.ed.ac.uk    std::string str;
1456691Stjones1@inf.ed.ac.uk    if (symtab && symtab->findSymbol(targetAddr, str))
1466691Stjones1@inf.ed.ac.uk        ss << str;
1476691Stjones1@inf.ed.ac.uk    else
1486691Stjones1@inf.ed.ac.uk        ccprintf(ss, "0x%x", targetAddr);
1496691Stjones1@inf.ed.ac.uk
1506691Stjones1@inf.ed.ac.uk    return ss.str();
1516691Stjones1@inf.ed.ac.uk}
1526691Stjones1@inf.ed.ac.uk
1537720Sgblack@eecs.umich.eduPowerISA::PCState
1546691Stjones1@inf.ed.ac.ukBranchRegCond::branchTarget(ThreadContext *tc) const
1556691Stjones1@inf.ed.ac.uk{
1566691Stjones1@inf.ed.ac.uk    uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]);
1577720Sgblack@eecs.umich.edu    return regVal & 0xfffffffc;
1586691Stjones1@inf.ed.ac.uk}
1596691Stjones1@inf.ed.ac.uk
1606691Stjones1@inf.ed.ac.ukstd::string
1616691Stjones1@inf.ed.ac.ukBranchRegCond::generateDisassembly(Addr pc,
1626691Stjones1@inf.ed.ac.uk                                   const SymbolTable *symtab) const
1636691Stjones1@inf.ed.ac.uk{
1646691Stjones1@inf.ed.ac.uk    std::stringstream ss;
1656691Stjones1@inf.ed.ac.uk
1666691Stjones1@inf.ed.ac.uk    ccprintf(ss, "%-10s ", mnemonic);
1676691Stjones1@inf.ed.ac.uk
1686691Stjones1@inf.ed.ac.uk    ss << bo << ", " << bi << ", ";
1696691Stjones1@inf.ed.ac.uk
1706691Stjones1@inf.ed.ac.uk    return ss.str();
1716691Stjones1@inf.ed.ac.uk}
172