types.hh revision 10924:d02e9c239892
1/*
2 * Copyright (c) 2007 The Hewlett-Packard Development Company
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Gabe Black
38 */
39
40#ifndef __ARCH_X86_TYPES_HH__
41#define __ARCH_X86_TYPES_HH__
42
43#include <iostream>
44
45#include "arch/generic/types.hh"
46#include "base/bitunion.hh"
47#include "base/cprintf.hh"
48#include "base/hashmap.hh"
49#include "base/types.hh"
50#include "sim/serialize.hh"
51
52namespace X86ISA
53{
54    //This really determines how many bytes are passed to the decoder.
55    typedef uint64_t MachInst;
56
57    enum Prefixes {
58        NoOverride,
59        ESOverride,
60        CSOverride,
61        SSOverride,
62        DSOverride,
63        FSOverride,
64        GSOverride,
65        RexPrefix,
66        OperandSizeOverride,
67        AddressSizeOverride,
68        Lock,
69        Rep,
70        Repne,
71        Vex2Prefix,
72        Vex3Prefix,
73        XopPrefix,
74    };
75
76    BitUnion8(LegacyPrefixVector)
77        Bitfield<7, 4> decodeVal;
78        Bitfield<7> repne;
79        Bitfield<6> rep;
80        Bitfield<5> lock;
81        Bitfield<4> op;
82        Bitfield<3> addr;
83        //There can be only one segment override, so they share the
84        //first 3 bits in the legacyPrefixes bitfield.
85        Bitfield<2,0> seg;
86    EndBitUnion(LegacyPrefixVector)
87
88    BitUnion8(ModRM)
89        Bitfield<7,6> mod;
90        Bitfield<5,3> reg;
91        Bitfield<2,0> rm;
92    EndBitUnion(ModRM)
93
94    BitUnion8(Sib)
95        Bitfield<7,6> scale;
96        Bitfield<5,3> index;
97        Bitfield<2,0> base;
98    EndBitUnion(Sib)
99
100    BitUnion8(Rex)
101        //This bit doesn't mean anything according to the ISA, but in
102        //this implementation, it being set means an REX prefix was present.
103        Bitfield<6> present;
104        Bitfield<3> w;
105        Bitfield<2> r;
106        Bitfield<1> x;
107        Bitfield<0> b;
108    EndBitUnion(Rex)
109
110    BitUnion(uint32_t, ThreeByteVex)
111        Bitfield<7,0> zero;
112        SubBitUnion(first, 15, 8)
113            // Inverted one-bit extension of ModRM reg field
114            Bitfield<15> r;
115            // Inverted one-bit extension of SIB index field
116            Bitfield<14> x;
117            // Inverted one-bit extension, r/m field or SIB base field
118            Bitfield<13> b;
119            // Opcode map select
120            Bitfield<12, 8> map_select;
121        EndSubBitUnion(first)
122        SubBitUnion(second, 23, 16)
123            // Default operand size override for a general purpose register to
124            // 64-bit size in 64-bit mode; operand configuration specifier for
125            // certain YMM/XMM-based operations.
126            Bitfield<23> w;
127            // Source or destination register selector, in ones' complement
128            // format
129            Bitfield<22, 19>  vvvv;
130            // Vector length specifier
131            Bitfield<18> l;
132            // Implied 66, F2, or F3 opcode extension
133            Bitfield<17, 16> pp;
134        EndSubBitUnion(second)
135    EndBitUnion(ThreeByteVex)
136
137    BitUnion16(TwoByteVex)
138        Bitfield<7,0> zero;
139        SubBitUnion(first, 15, 8)
140            // Inverted one-bit extension of ModRM reg field
141            Bitfield<15> r;
142            // Source or destination register selector, in ones' complement
143            // format
144            Bitfield<14, 11>  vvvv;
145            // Vector length specifier
146            Bitfield<10> l;
147            // Implied 66, F2, or F3 opcode extension
148            Bitfield<9, 8> pp;
149        EndSubBitUnion(first)
150    EndBitUnion(TwoByteVex)
151
152    enum OpcodeType {
153        BadOpcode,
154        OneByteOpcode,
155        TwoByteOpcode,
156        ThreeByte0F38Opcode,
157        ThreeByte0F3AOpcode,
158        Vex,
159    };
160
161    static inline const char *
162    opcodeTypeToStr(OpcodeType type)
163    {
164        switch (type) {
165          case BadOpcode:
166            return "bad";
167          case OneByteOpcode:
168            return "one byte";
169          case TwoByteOpcode:
170            return "two byte";
171          case ThreeByte0F38Opcode:
172            return "three byte 0f38";
173          case ThreeByte0F3AOpcode:
174            return "three byte 0f3a";
175          case Vex:
176            return "vex";
177          default:
178            return "unrecognized!";
179        }
180    }
181
182    BitUnion8(Opcode)
183        Bitfield<7,3> top5;
184        Bitfield<2,0> bottom3;
185    EndBitUnion(Opcode)
186
187    BitUnion8(OperatingMode)
188        Bitfield<3> mode;
189        Bitfield<2,0> submode;
190    EndBitUnion(OperatingMode)
191
192    enum X86Mode {
193        LongMode,
194        LegacyMode
195    };
196
197    enum X86SubMode {
198        SixtyFourBitMode,
199        CompatabilityMode,
200        ProtectedMode,
201        Virtual8086Mode,
202        RealMode
203    };
204
205    //The intermediate structure used by the x86 decoder.
206    struct ExtMachInst
207    {
208        //Prefixes
209        LegacyPrefixVector legacy;
210        Rex rex;
211        // We use the following field for encoding both two byte and three byte
212        // escape sequences
213        ThreeByteVex vex;
214
215        //This holds all of the bytes of the opcode
216        struct
217        {
218            OpcodeType type;
219            //The main opcode byte. The highest addressed byte in the opcode.
220            Opcode op;
221        } opcode;
222        //Modifier bytes
223        ModRM modRM;
224        Sib sib;
225        //Immediate fields
226        uint64_t immediate;
227        uint64_t displacement;
228
229        //The effective operand size.
230        uint8_t opSize;
231        //The effective address size.
232        uint8_t addrSize;
233        //The effective stack size.
234        uint8_t stackSize;
235        //The size of the displacement
236        uint8_t dispSize;
237
238        //Mode information
239        OperatingMode mode;
240    };
241
242    inline static std::ostream &
243        operator << (std::ostream & os, const ExtMachInst & emi)
244    {
245        ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t"
246                     "vex/xop = %#x,\n\t"
247                     "op = {\n\t\ttype = %s,\n\t\top = %#x,\n\t\t},\n\t"
248                     "modRM = %#x,\n\tsib = %#x,\n\t"
249                     "immediate = %#x,\n\tdisplacement = %#x\n\t"
250                     "dispSize = %d}\n",
251                     (uint8_t)emi.legacy, (uint8_t)emi.rex,
252                     (uint32_t)emi.vex,
253                     opcodeTypeToStr(emi.opcode.type), (uint8_t)emi.opcode.op,
254                     (uint8_t)emi.modRM, (uint8_t)emi.sib,
255                     emi.immediate, emi.displacement, emi.dispSize);
256        return os;
257    }
258
259    inline static bool
260        operator == (const ExtMachInst &emi1, const ExtMachInst &emi2)
261    {
262        if(emi1.legacy != emi2.legacy)
263            return false;
264        if(emi1.rex != emi2.rex)
265            return false;
266        if(emi1.opcode.type != emi2.opcode.type)
267            return false;
268        if(emi1.opcode.op != emi2.opcode.op)
269            return false;
270        if(emi1.modRM != emi2.modRM)
271            return false;
272        if(emi1.sib != emi2.sib)
273            return false;
274        if(emi1.immediate != emi2.immediate)
275            return false;
276        if(emi1.displacement != emi2.displacement)
277            return false;
278        if(emi1.mode != emi2.mode)
279            return false;
280        if(emi1.opSize != emi2.opSize)
281            return false;
282        if(emi1.addrSize != emi2.addrSize)
283            return false;
284        if(emi1.stackSize != emi2.stackSize)
285            return false;
286        if(emi1.dispSize != emi2.dispSize)
287            return false;
288        return true;
289    }
290
291    class PCState : public GenericISA::UPCState<MachInst>
292    {
293      protected:
294        typedef GenericISA::UPCState<MachInst> Base;
295
296        uint8_t _size;
297
298      public:
299        void
300        set(Addr val)
301        {
302            Base::set(val);
303            _size = 0;
304        }
305
306        PCState() {}
307        PCState(Addr val) { set(val); }
308
309        uint8_t size() const { return _size; }
310        void size(uint8_t newSize) { _size = newSize; }
311
312        bool
313        branching() const
314        {
315            return this->npc() != this->pc() + size();
316        }
317
318        void
319        advance()
320        {
321            Base::advance();
322            _size = 0;
323        }
324
325        void
326        uEnd()
327        {
328            Base::uEnd();
329            _size = 0;
330        }
331
332        void
333        serialize(CheckpointOut &cp) const
334        {
335            Base::serialize(cp);
336            SERIALIZE_SCALAR(_size);
337        }
338
339        void
340        unserialize(CheckpointIn &cp)
341        {
342            Base::unserialize(cp);
343            UNSERIALIZE_SCALAR(_size);
344        }
345    };
346
347}
348
349__hash_namespace_begin
350    template<>
351    struct hash<X86ISA::ExtMachInst> {
352        size_t operator()(const X86ISA::ExtMachInst &emi) const {
353            return (((uint64_t)emi.legacy << 40) |
354                    ((uint64_t)emi.rex  << 32) |
355                    ((uint64_t)emi.modRM << 24) |
356                    ((uint64_t)emi.sib << 16) |
357                    ((uint64_t)emi.opcode.type << 8) |
358                    ((uint64_t)emi.opcode.op)) ^
359                    emi.immediate ^ emi.displacement ^
360                    emi.mode ^
361                    emi.opSize ^ emi.addrSize ^
362                    emi.stackSize ^ emi.dispSize;
363        };
364    };
365__hash_namespace_end
366
367// These two functions allow ExtMachInst to be used with SERIALIZE_SCALAR
368// and UNSERIALIZE_SCALAR.
369template <>
370void
371paramOut(CheckpointOut &cp, const std::string &name,
372         const X86ISA::ExtMachInst &machInst);
373template <>
374void
375paramIn(CheckpointIn &cp, const std::string &name,
376        X86ISA::ExtMachInst &machInst);
377
378#endif // __ARCH_X86_TYPES_HH__
379