Deleted Added
sdiff udiff text old ( 10924:d02e9c239892 ) new ( 11168:f98eb2da15a4 )
full compact
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__