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