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#ifndef __ARCH_POWER_INSTS_INTEGER_HH__
326691Stjones1@inf.ed.ac.uk#define __ARCH_POWER_INSTS_INTEGER_HH__
336691Stjones1@inf.ed.ac.uk
346691Stjones1@inf.ed.ac.uk#include "arch/power/insts/static_inst.hh"
358229Snate@binkert.org#include "base/bitfield.hh"
366691Stjones1@inf.ed.ac.uk#include "base/cprintf.hh"
376691Stjones1@inf.ed.ac.uk
386691Stjones1@inf.ed.ac.uknamespace PowerISA
396691Stjones1@inf.ed.ac.uk{
406691Stjones1@inf.ed.ac.uk
416691Stjones1@inf.ed.ac.uk/**
426691Stjones1@inf.ed.ac.uk * We provide a base class for integer operations and then inherit for
436691Stjones1@inf.ed.ac.uk * several other classes. These specialise for instructions using immediate
446691Stjones1@inf.ed.ac.uk * values and also rotate instructions. We also need to have versions that
456691Stjones1@inf.ed.ac.uk * consider the Rc and OE bits.
466691Stjones1@inf.ed.ac.uk */
476691Stjones1@inf.ed.ac.uk
486691Stjones1@inf.ed.ac.uk/**
496691Stjones1@inf.ed.ac.uk * Base class for integer operations.
506691Stjones1@inf.ed.ac.uk */
516691Stjones1@inf.ed.ac.ukclass IntOp : public PowerStaticInst
526691Stjones1@inf.ed.ac.uk{
536691Stjones1@inf.ed.ac.uk  protected:
546691Stjones1@inf.ed.ac.uk
556691Stjones1@inf.ed.ac.uk    bool rcSet;
566691Stjones1@inf.ed.ac.uk    bool oeSet;
576691Stjones1@inf.ed.ac.uk
586691Stjones1@inf.ed.ac.uk    // Needed for srawi only
596691Stjones1@inf.ed.ac.uk    uint32_t sh;
606691Stjones1@inf.ed.ac.uk
616691Stjones1@inf.ed.ac.uk    /// Constructor
626691Stjones1@inf.ed.ac.uk    IntOp(const char *mnem, MachInst _machInst, OpClass __opClass)
636691Stjones1@inf.ed.ac.uk      : PowerStaticInst(mnem, _machInst, __opClass),
646691Stjones1@inf.ed.ac.uk        rcSet(false), oeSet(false)
656691Stjones1@inf.ed.ac.uk    {
666691Stjones1@inf.ed.ac.uk    }
676691Stjones1@inf.ed.ac.uk
686691Stjones1@inf.ed.ac.uk    /* Compute the CR (condition register) field using signed comparison */
696691Stjones1@inf.ed.ac.uk    inline uint32_t
706691Stjones1@inf.ed.ac.uk    makeCRField(int32_t a, int32_t b, uint32_t xerSO) const
716691Stjones1@inf.ed.ac.uk    {
726691Stjones1@inf.ed.ac.uk        uint32_t c = xerSO;
736691Stjones1@inf.ed.ac.uk
746691Stjones1@inf.ed.ac.uk        /* We've pre-shifted the immediate values here */
756691Stjones1@inf.ed.ac.uk        if (a < b)      { c += 0x8; }
766691Stjones1@inf.ed.ac.uk        else if (a > b) { c += 0x4; }
776691Stjones1@inf.ed.ac.uk        else            { c += 0x2; }
786691Stjones1@inf.ed.ac.uk        return c;
796691Stjones1@inf.ed.ac.uk    }
806691Stjones1@inf.ed.ac.uk
816691Stjones1@inf.ed.ac.uk    /* Compute the CR (condition register) field using unsigned comparison */
826691Stjones1@inf.ed.ac.uk    inline uint32_t
836691Stjones1@inf.ed.ac.uk    makeCRField(uint32_t a, uint32_t b, uint32_t xerSO) const
846691Stjones1@inf.ed.ac.uk    {
856691Stjones1@inf.ed.ac.uk        uint32_t c = xerSO;
866691Stjones1@inf.ed.ac.uk
876691Stjones1@inf.ed.ac.uk        /* We've pre-shifted the immediate values here */
886691Stjones1@inf.ed.ac.uk        if (a < b)      { c += 0x8; }
896691Stjones1@inf.ed.ac.uk        else if (a > b) { c += 0x4; }
906691Stjones1@inf.ed.ac.uk        else            { c += 0x2; }
916691Stjones1@inf.ed.ac.uk        return c;
926691Stjones1@inf.ed.ac.uk    }
936691Stjones1@inf.ed.ac.uk
9412616Sgabeblack@google.com    std::string generateDisassembly(
9512616Sgabeblack@google.com            Addr pc, const SymbolTable *symtab) const override;
966691Stjones1@inf.ed.ac.uk};
976691Stjones1@inf.ed.ac.uk
986691Stjones1@inf.ed.ac.uk
996691Stjones1@inf.ed.ac.uk/**
1006691Stjones1@inf.ed.ac.uk * Class for integer immediate (signed and unsigned) operations.
1016691Stjones1@inf.ed.ac.uk */
1026691Stjones1@inf.ed.ac.ukclass IntImmOp : public IntOp
1036691Stjones1@inf.ed.ac.uk{
1046691Stjones1@inf.ed.ac.uk  protected:
1056691Stjones1@inf.ed.ac.uk
1066691Stjones1@inf.ed.ac.uk    int32_t imm;
1076691Stjones1@inf.ed.ac.uk    uint32_t uimm;
1086691Stjones1@inf.ed.ac.uk
1096691Stjones1@inf.ed.ac.uk    /// Constructor
1106691Stjones1@inf.ed.ac.uk    IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
1116691Stjones1@inf.ed.ac.uk      : IntOp(mnem, _machInst, __opClass),
1126691Stjones1@inf.ed.ac.uk        imm(sext<16>(machInst.si)),
1136691Stjones1@inf.ed.ac.uk        uimm(machInst.si)
1146691Stjones1@inf.ed.ac.uk    {
1156691Stjones1@inf.ed.ac.uk    }
1166691Stjones1@inf.ed.ac.uk
11712616Sgabeblack@google.com    std::string generateDisassembly(
11812616Sgabeblack@google.com            Addr pc, const SymbolTable *symtab) const override;
1196691Stjones1@inf.ed.ac.uk};
1206691Stjones1@inf.ed.ac.uk
1216691Stjones1@inf.ed.ac.uk
1226691Stjones1@inf.ed.ac.uk/**
1236691Stjones1@inf.ed.ac.uk * Class for integer operations with a shift.
1246691Stjones1@inf.ed.ac.uk */
1256691Stjones1@inf.ed.ac.ukclass IntShiftOp : public IntOp
1266691Stjones1@inf.ed.ac.uk{
1276691Stjones1@inf.ed.ac.uk  protected:
1286691Stjones1@inf.ed.ac.uk
1296691Stjones1@inf.ed.ac.uk    uint32_t sh;
1306691Stjones1@inf.ed.ac.uk
1316691Stjones1@inf.ed.ac.uk    /// Constructor
1326691Stjones1@inf.ed.ac.uk    IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
1336691Stjones1@inf.ed.ac.uk      : IntOp(mnem, _machInst, __opClass),
1346691Stjones1@inf.ed.ac.uk        sh(machInst.sh)
1356691Stjones1@inf.ed.ac.uk    {
1366691Stjones1@inf.ed.ac.uk    }
1376691Stjones1@inf.ed.ac.uk
13812616Sgabeblack@google.com    std::string generateDisassembly(
13912616Sgabeblack@google.com            Addr pc, const SymbolTable *symtab) const override;
1406691Stjones1@inf.ed.ac.uk};
1416691Stjones1@inf.ed.ac.uk
1426691Stjones1@inf.ed.ac.uk
1436691Stjones1@inf.ed.ac.uk/**
1446691Stjones1@inf.ed.ac.uk * Class for integer rotate operations.
1456691Stjones1@inf.ed.ac.uk */
1466691Stjones1@inf.ed.ac.ukclass IntRotateOp : public IntShiftOp
1476691Stjones1@inf.ed.ac.uk{
1486691Stjones1@inf.ed.ac.uk  protected:
1496691Stjones1@inf.ed.ac.uk
1506691Stjones1@inf.ed.ac.uk    uint32_t mb;
1516691Stjones1@inf.ed.ac.uk    uint32_t me;
1526691Stjones1@inf.ed.ac.uk    uint32_t fullMask;
1536691Stjones1@inf.ed.ac.uk
1546691Stjones1@inf.ed.ac.uk    /// Constructor
1556691Stjones1@inf.ed.ac.uk    IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
1566691Stjones1@inf.ed.ac.uk      : IntShiftOp(mnem, _machInst, __opClass),
1576691Stjones1@inf.ed.ac.uk        mb(machInst.mb),
1586691Stjones1@inf.ed.ac.uk        me(machInst.me)
1596691Stjones1@inf.ed.ac.uk    {
1606691Stjones1@inf.ed.ac.uk        if (me >= mb) {
1616691Stjones1@inf.ed.ac.uk            fullMask = mask(31 - mb, 31 - me);
1626691Stjones1@inf.ed.ac.uk        } else {
1636691Stjones1@inf.ed.ac.uk            fullMask = ~mask(31 - (me + 1), 31 - (mb - 1));
1646691Stjones1@inf.ed.ac.uk        }
1656691Stjones1@inf.ed.ac.uk    }
1666691Stjones1@inf.ed.ac.uk
1676691Stjones1@inf.ed.ac.uk    uint32_t
1686691Stjones1@inf.ed.ac.uk    rotateValue(uint32_t rs, uint32_t shift) const
1696691Stjones1@inf.ed.ac.uk    {
1706691Stjones1@inf.ed.ac.uk        uint32_t n = shift & 31;
1716691Stjones1@inf.ed.ac.uk        return (rs << n) | (rs >> (32 - n));
1726691Stjones1@inf.ed.ac.uk    }
1736691Stjones1@inf.ed.ac.uk
17412616Sgabeblack@google.com    std::string generateDisassembly(
17512616Sgabeblack@google.com            Addr pc, const SymbolTable *symtab) const override;
1766691Stjones1@inf.ed.ac.uk};
1776691Stjones1@inf.ed.ac.uk
1787811Ssteve.reinhardt@amd.com} // namespace PowerISA
1796691Stjones1@inf.ed.ac.uk
1806691Stjones1@inf.ed.ac.uk#endif //__ARCH_POWER_INSTS_INTEGER_HH__
181