static_inst.cc revision 12104:edd63f9c6184
12929Sktlim@umich.edu/*
211504Sandreas.sandberg@arm.com * Copyright (c) 2007 The Hewlett-Packard Development Company
311504Sandreas.sandberg@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
411504Sandreas.sandberg@arm.com * All rights reserved.
511504Sandreas.sandberg@arm.com *
611504Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
711504Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
811504Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
911504Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
1011504Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1111504Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1211504Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1311504Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1411504Sandreas.sandberg@arm.com *
152932Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without
162929Sktlim@umich.edu * modification, are permitted provided that the following conditions are
172929Sktlim@umich.edu * met: redistributions of source code must retain the above copyright
182929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer;
192929Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright
202929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the
212929Sktlim@umich.edu * documentation and/or other materials provided with the distribution;
222929Sktlim@umich.edu * neither the name of the copyright holders nor the names of its
232929Sktlim@umich.edu * contributors may be used to endorse or promote products derived from
242929Sktlim@umich.edu * this software without specific prior written permission.
252929Sktlim@umich.edu *
262929Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
272929Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
282929Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
292929Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
302929Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
312929Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
322929Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
332929Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
342929Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
352929Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
362929Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
372929Sktlim@umich.edu *
382929Sktlim@umich.edu * Authors: Gabe Black
392929Sktlim@umich.edu */
402932Sktlim@umich.edu
412932Sktlim@umich.edu#include "arch/x86/insts/static_inst.hh"
422932Sktlim@umich.edu
4311504Sandreas.sandberg@arm.com#include "arch/x86/regs/segment.hh"
442929Sktlim@umich.edu#include "cpu/reg_class.hh"
4512563Sgabeblack@google.com
4612563Sgabeblack@google.comnamespace X86ISA
472929Sktlim@umich.edu{
4811504Sandreas.sandberg@arm.com    void X86StaticInst::printMnemonic(std::ostream &os,
4911504Sandreas.sandberg@arm.com            const char * mnemonic) const
5011504Sandreas.sandberg@arm.com    {
5111504Sandreas.sandberg@arm.com        ccprintf(os, "  %s   ", mnemonic);
5211504Sandreas.sandberg@arm.com    }
5311504Sandreas.sandberg@arm.com
5411504Sandreas.sandberg@arm.com    void X86StaticInst::printMnemonic(std::ostream &os,
5512246Sgabeblack@google.com            const char * instMnemonic, const char * mnemonic) const
562929Sktlim@umich.edu    {
572929Sktlim@umich.edu        ccprintf(os, "  %s : %s   ", instMnemonic, mnemonic);
582929Sktlim@umich.edu    }
598947Sandreas.hansson@arm.com
6012246Sgabeblack@google.com    void X86StaticInst::printSegment(std::ostream &os, int segment) const
618947Sandreas.hansson@arm.com    {
622929Sktlim@umich.edu        switch (segment)
632929Sktlim@umich.edu        {
6411504Sandreas.sandberg@arm.com          case SEGMENT_REG_ES:
6511504Sandreas.sandberg@arm.com            ccprintf(os, "ES");
6611504Sandreas.sandberg@arm.com            break;
6711504Sandreas.sandberg@arm.com          case SEGMENT_REG_CS:
6811504Sandreas.sandberg@arm.com            ccprintf(os, "CS");
6911504Sandreas.sandberg@arm.com            break;
7011504Sandreas.sandberg@arm.com          case SEGMENT_REG_SS:
712929Sktlim@umich.edu            ccprintf(os, "SS");
7211504Sandreas.sandberg@arm.com            break;
7311504Sandreas.sandberg@arm.com          case SEGMENT_REG_DS:
746007Ssteve.reinhardt@amd.com            ccprintf(os, "DS");
756007Ssteve.reinhardt@amd.com            break;
7611504Sandreas.sandberg@arm.com          case SEGMENT_REG_FS:
772929Sktlim@umich.edu            ccprintf(os, "FS");
782929Sktlim@umich.edu            break;
7911504Sandreas.sandberg@arm.com          case SEGMENT_REG_GS:
806007Ssteve.reinhardt@amd.com            ccprintf(os, "GS");
816007Ssteve.reinhardt@amd.com            break;
829781Sandreas.hansson@arm.com          case SEGMENT_REG_HS:
836007Ssteve.reinhardt@amd.com            ccprintf(os, "HS");
8411504Sandreas.sandberg@arm.com            break;
852929Sktlim@umich.edu          case SEGMENT_REG_TSL:
862929Sktlim@umich.edu            ccprintf(os, "TSL");
8711504Sandreas.sandberg@arm.com            break;
8811504Sandreas.sandberg@arm.com          case SEGMENT_REG_TSG:
8911504Sandreas.sandberg@arm.com            ccprintf(os, "TSG");
9011504Sandreas.sandberg@arm.com            break;
9111504Sandreas.sandberg@arm.com          case SEGMENT_REG_LS:
926007Ssteve.reinhardt@amd.com            ccprintf(os, "LS");
9311504Sandreas.sandberg@arm.com            break;
9411504Sandreas.sandberg@arm.com          case SEGMENT_REG_MS:
9511504Sandreas.sandberg@arm.com            ccprintf(os, "MS");
9611504Sandreas.sandberg@arm.com            break;
976007Ssteve.reinhardt@amd.com          case SYS_SEGMENT_REG_TR:
9811504Sandreas.sandberg@arm.com            ccprintf(os, "TR");
9911504Sandreas.sandberg@arm.com            break;
10011504Sandreas.sandberg@arm.com          case SYS_SEGMENT_REG_IDTR:
1016007Ssteve.reinhardt@amd.com            ccprintf(os, "IDTR");
1022929Sktlim@umich.edu            break;
1032929Sktlim@umich.edu          default:
1046007Ssteve.reinhardt@amd.com            panic("Unrecognized segment %d\n", segment);
1056007Ssteve.reinhardt@amd.com        }
1062929Sktlim@umich.edu    }
1072929Sktlim@umich.edu
1086007Ssteve.reinhardt@amd.com    void
1092929Sktlim@umich.edu    X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
1102929Sktlim@umich.edu    {
11111504Sandreas.sandberg@arm.com        if (_numSrcRegs > reg)
1128947Sandreas.hansson@arm.com            printReg(os, _srcRegIdx[reg], size);
11311504Sandreas.sandberg@arm.com    }
11411504Sandreas.sandberg@arm.com
1158947Sandreas.hansson@arm.com    void
11611504Sandreas.sandberg@arm.com    X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
11711504Sandreas.sandberg@arm.com    {
1188947Sandreas.hansson@arm.com        if (_numDestRegs > reg)
11911504Sandreas.sandberg@arm.com            printReg(os, _destRegIdx[reg], size);
12011504Sandreas.sandberg@arm.com    }
12111504Sandreas.sandberg@arm.com
1228947Sandreas.hansson@arm.com    void
12311504Sandreas.sandberg@arm.com    X86StaticInst::printReg(std::ostream &os, RegId reg, int size) const
12411504Sandreas.sandberg@arm.com    {
12511504Sandreas.sandberg@arm.com        assert(size == 1 || size == 2 || size == 4 || size == 8);
12611504Sandreas.sandberg@arm.com        static const char * abcdFormats[9] =
12711542Sandreas.sandberg@arm.com            {"", "%s",  "%sx",  "", "e%sx", "", "", "", "r%sx"};
12811542Sandreas.sandberg@arm.com        static const char * piFormats[9] =
12911542Sandreas.sandberg@arm.com            {"", "%s",  "%s",   "", "e%s",  "", "", "", "r%s"};
13011542Sandreas.sandberg@arm.com        static const char * longFormats[9] =
13111504Sandreas.sandberg@arm.com            {"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
13211504Sandreas.sandberg@arm.com        static const char * microFormats[9] =
13311504Sandreas.sandberg@arm.com            {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
13411504Sandreas.sandberg@arm.com
13511542Sandreas.sandberg@arm.com        RegIndex reg_idx = reg.regIdx;
13611504Sandreas.sandberg@arm.com
13711504Sandreas.sandberg@arm.com        switch (reg.regClass) {
13811504Sandreas.sandberg@arm.com          case IntRegClass: {
13911504Sandreas.sandberg@arm.com            const char * suffix = "";
14011504Sandreas.sandberg@arm.com            bool fold = reg_idx & IntFoldBit;
14112563Sgabeblack@google.com            reg_idx &= ~IntFoldBit;
1422929Sktlim@umich.edu
1432929Sktlim@umich.edu            if (fold)
14411504Sandreas.sandberg@arm.com                suffix = "h";
1454937Sstever@gmail.com            else if (reg_idx < 8 && size == 1)
1462929Sktlim@umich.edu                suffix = "l";
14711504Sandreas.sandberg@arm.com
1482929Sktlim@umich.edu            switch (reg_idx) {
14911504Sandreas.sandberg@arm.com              case INTREG_RAX:
15011504Sandreas.sandberg@arm.com                ccprintf(os, abcdFormats[size], "a");
1512929Sktlim@umich.edu                break;
15211504Sandreas.sandberg@arm.com              case INTREG_RBX:
15311504Sandreas.sandberg@arm.com                ccprintf(os, abcdFormats[size], "b");
1542929Sktlim@umich.edu                break;
15511504Sandreas.sandberg@arm.com              case INTREG_RCX:
15611504Sandreas.sandberg@arm.com                ccprintf(os, abcdFormats[size], "c");
15711504Sandreas.sandberg@arm.com                break;
15811504Sandreas.sandberg@arm.com              case INTREG_RDX:
15911504Sandreas.sandberg@arm.com                ccprintf(os, abcdFormats[size], "d");
16011504Sandreas.sandberg@arm.com                break;
16111504Sandreas.sandberg@arm.com              case INTREG_RSP:
16211504Sandreas.sandberg@arm.com                ccprintf(os, piFormats[size], "sp");
16311504Sandreas.sandberg@arm.com                break;
16411504Sandreas.sandberg@arm.com              case INTREG_RBP:
16511504Sandreas.sandberg@arm.com                ccprintf(os, piFormats[size], "bp");
16611504Sandreas.sandberg@arm.com                break;
16711542Sandreas.sandberg@arm.com              case INTREG_RSI:
16812563Sgabeblack@google.com                ccprintf(os, piFormats[size], "si");
16912563Sgabeblack@google.com                break;
17011504Sandreas.sandberg@arm.com              case INTREG_RDI:
17111504Sandreas.sandberg@arm.com                ccprintf(os, piFormats[size], "di");
17212563Sgabeblack@google.com                break;
17312563Sgabeblack@google.com              case INTREG_R8W:
17411504Sandreas.sandberg@arm.com                ccprintf(os, longFormats[size], "8");
17511542Sandreas.sandberg@arm.com                break;
17612563Sgabeblack@google.com              case INTREG_R9W:
17712563Sgabeblack@google.com                ccprintf(os, longFormats[size], "9");
17811504Sandreas.sandberg@arm.com                break;
17911504Sandreas.sandberg@arm.com              case INTREG_R10W:
18012563Sgabeblack@google.com                ccprintf(os, longFormats[size], "10");
18111504Sandreas.sandberg@arm.com                break;
18211504Sandreas.sandberg@arm.com              case INTREG_R11W:
1832929Sktlim@umich.edu                ccprintf(os, longFormats[size], "11");
1842929Sktlim@umich.edu                break;
1852929Sktlim@umich.edu              case INTREG_R12W:
18611504Sandreas.sandberg@arm.com                ccprintf(os, longFormats[size], "12");
1872929Sktlim@umich.edu                break;
1882929Sktlim@umich.edu              case INTREG_R13W:
1892929Sktlim@umich.edu                ccprintf(os, longFormats[size], "13");
1902929Sktlim@umich.edu                break;
19111504Sandreas.sandberg@arm.com              case INTREG_R14W:
1922997Sstever@eecs.umich.edu                ccprintf(os, longFormats[size], "14");
1932929Sktlim@umich.edu                break;
19411504Sandreas.sandberg@arm.com              case INTREG_R15W:
19511504Sandreas.sandberg@arm.com                ccprintf(os, longFormats[size], "15");
19611504Sandreas.sandberg@arm.com                break;
1972929Sktlim@umich.edu              default:
19811504Sandreas.sandberg@arm.com                ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS);
19911504Sandreas.sandberg@arm.com            }
2002929Sktlim@umich.edu            ccprintf(os, suffix);
20111504Sandreas.sandberg@arm.com            break;
20211504Sandreas.sandberg@arm.com          }
2032997Sstever@eecs.umich.edu
20411504Sandreas.sandberg@arm.com          case FloatRegClass: {
20511504Sandreas.sandberg@arm.com            if (reg_idx < NumMMXRegs) {
20611504Sandreas.sandberg@arm.com                ccprintf(os, "%%mmx%d", reg_idx);
20711504Sandreas.sandberg@arm.com                return;
2082997Sstever@eecs.umich.edu            }
20911504Sandreas.sandberg@arm.com            reg_idx -= NumMMXRegs;
21011504Sandreas.sandberg@arm.com            if (reg_idx < NumXMMRegs * 2) {
21111504Sandreas.sandberg@arm.com                ccprintf(os, "%%xmm%d_%s", reg_idx / 2,
21211504Sandreas.sandberg@arm.com                        (reg_idx % 2) ? "high": "low");
21311504Sandreas.sandberg@arm.com                return;
21411504Sandreas.sandberg@arm.com            }
2152929Sktlim@umich.edu            reg_idx -= NumXMMRegs * 2;
2162997Sstever@eecs.umich.edu            if (reg_idx < NumMicroFpRegs) {
2178120Sgblack@eecs.umich.edu                ccprintf(os, "%%ufp%d", reg_idx);
21811504Sandreas.sandberg@arm.com                return;
2192997Sstever@eecs.umich.edu            }
22011504Sandreas.sandberg@arm.com            reg_idx -= NumMicroFpRegs;
2212929Sktlim@umich.edu            ccprintf(os, "%%st(%d)", reg_idx);
2222997Sstever@eecs.umich.edu            break;
2232929Sktlim@umich.edu          }
22411504Sandreas.sandberg@arm.com
22511504Sandreas.sandberg@arm.com          case CCRegClass:
2262929Sktlim@umich.edu            ccprintf(os, "%%cc%d", reg_idx);
22711504Sandreas.sandberg@arm.com            break;
22811504Sandreas.sandberg@arm.com
2293691Shsul@eecs.umich.edu          case MiscRegClass:
23011504Sandreas.sandberg@arm.com            switch (reg_idx) {
2313005Sstever@eecs.umich.edu              default:
23211504Sandreas.sandberg@arm.com                ccprintf(os, "%%ctrl%d", reg_idx);
23311105Spower.jg@gmail.com            }
23411504Sandreas.sandberg@arm.com            break;
23511504Sandreas.sandberg@arm.com        }
23611504Sandreas.sandberg@arm.com    }
2376166Ssteve.reinhardt@amd.com
23811504Sandreas.sandberg@arm.com    void X86StaticInst::printMem(std::ostream &os, uint8_t segment,
23911504Sandreas.sandberg@arm.com            uint8_t scale, RegIndex index, RegIndex base,
24011504Sandreas.sandberg@arm.com            uint64_t disp, uint8_t addressSize, bool rip) const
24112563Sgabeblack@google.com    {
24211504Sandreas.sandberg@arm.com        bool someAddr = false;
24311504Sandreas.sandberg@arm.com        printSegment(os, segment);
24411504Sandreas.sandberg@arm.com        os << ":[";
24511504Sandreas.sandberg@arm.com        if (rip) {
24611504Sandreas.sandberg@arm.com            os << "rip";
24711504Sandreas.sandberg@arm.com            someAddr = true;
24811504Sandreas.sandberg@arm.com        } else {
24911504Sandreas.sandberg@arm.com            if (scale != 0 && index != ZeroReg)
25011504Sandreas.sandberg@arm.com            {
25111504Sandreas.sandberg@arm.com                if (scale != 1)
252                    ccprintf(os, "%d*", scale);
253                printReg(os, InstRegIndex(index), addressSize);
254                someAddr = true;
255            }
256            if (base != ZeroReg)
257            {
258                if (someAddr)
259                    os << " + ";
260                printReg(os, InstRegIndex(base), addressSize);
261                someAddr = true;
262            }
263        }
264        if (disp != 0)
265        {
266            if (someAddr)
267                os << " + ";
268            ccprintf(os, "%#x", disp);
269            someAddr = true;
270        }
271        if (!someAddr)
272            os << "0";
273        os << "]";
274    }
275
276    std::string X86StaticInst::generateDisassembly(Addr pc,
277        const SymbolTable *symtab) const
278    {
279        std::stringstream ss;
280
281        printMnemonic(ss, mnemonic);
282
283        return ss.str();
284    }
285}
286