types.hh revision 10593:a39de7b8d2c9
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 }; 72 73 BitUnion8(LegacyPrefixVector) 74 Bitfield<7, 4> decodeVal; 75 Bitfield<7> repne; 76 Bitfield<6> rep; 77 Bitfield<5> lock; 78 Bitfield<4> op; 79 Bitfield<3> addr; 80 //There can be only one segment override, so they share the 81 //first 3 bits in the legacyPrefixes bitfield. 82 Bitfield<2,0> seg; 83 EndBitUnion(LegacyPrefixVector) 84 85 BitUnion8(ModRM) 86 Bitfield<7,6> mod; 87 Bitfield<5,3> reg; 88 Bitfield<2,0> rm; 89 EndBitUnion(ModRM) 90 91 BitUnion8(Sib) 92 Bitfield<7,6> scale; 93 Bitfield<5,3> index; 94 Bitfield<2,0> base; 95 EndBitUnion(Sib) 96 97 BitUnion8(Rex) 98 //This bit doesn't mean anything according to the ISA, but in 99 //this implementation, it being set means an REX prefix was present. 100 Bitfield<6> present; 101 Bitfield<3> w; 102 Bitfield<2> r; 103 Bitfield<1> x; 104 Bitfield<0> b; 105 EndBitUnion(Rex) 106 107 enum OpcodeType { 108 BadOpcode, 109 OneByteOpcode, 110 TwoByteOpcode, 111 ThreeByte0F38Opcode, 112 ThreeByte0F3AOpcode 113 }; 114 115 static inline const char * 116 opcodeTypeToStr(OpcodeType type) 117 { 118 switch (type) { 119 case BadOpcode: 120 return "bad"; 121 case OneByteOpcode: 122 return "one byte"; 123 case TwoByteOpcode: 124 return "two byte"; 125 case ThreeByte0F38Opcode: 126 return "three byte 0f38"; 127 case ThreeByte0F3AOpcode: 128 return "three byte 0f3a"; 129 default: 130 return "unrecognized!"; 131 } 132 } 133 134 BitUnion8(Opcode) 135 Bitfield<7,3> top5; 136 Bitfield<2,0> bottom3; 137 EndBitUnion(Opcode) 138 139 BitUnion8(OperatingMode) 140 Bitfield<3> mode; 141 Bitfield<2,0> submode; 142 EndBitUnion(OperatingMode) 143 144 enum X86Mode { 145 LongMode, 146 LegacyMode 147 }; 148 149 enum X86SubMode { 150 SixtyFourBitMode, 151 CompatabilityMode, 152 ProtectedMode, 153 Virtual8086Mode, 154 RealMode 155 }; 156 157 //The intermediate structure used by the x86 decoder. 158 struct ExtMachInst 159 { 160 //Prefixes 161 LegacyPrefixVector legacy; 162 Rex rex; 163 //This holds all of the bytes of the opcode 164 struct 165 { 166 OpcodeType type; 167 //The main opcode byte. The highest addressed byte in the opcode. 168 Opcode op; 169 } opcode; 170 //Modifier bytes 171 ModRM modRM; 172 Sib sib; 173 //Immediate fields 174 uint64_t immediate; 175 uint64_t displacement; 176 177 //The effective operand size. 178 uint8_t opSize; 179 //The effective address size. 180 uint8_t addrSize; 181 //The effective stack size. 182 uint8_t stackSize; 183 //The size of the displacement 184 uint8_t dispSize; 185 186 //Mode information 187 OperatingMode mode; 188 }; 189 190 inline static std::ostream & 191 operator << (std::ostream & os, const ExtMachInst & emi) 192 { 193 ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t" 194 "op = {\n\t\ttype = %s,\n\t\top = %#x,\n\t\t},\n\t" 195 "modRM = %#x,\n\tsib = %#x,\n\t" 196 "immediate = %#x,\n\tdisplacement = %#x\n\t" 197 "dispSize = %d}\n", 198 (uint8_t)emi.legacy, (uint8_t)emi.rex, 199 opcodeTypeToStr(emi.opcode.type), (uint8_t)emi.opcode.op, 200 (uint8_t)emi.modRM, (uint8_t)emi.sib, 201 emi.immediate, emi.displacement, emi.dispSize); 202 return os; 203 } 204 205 inline static bool 206 operator == (const ExtMachInst &emi1, const ExtMachInst &emi2) 207 { 208 if(emi1.legacy != emi2.legacy) 209 return false; 210 if(emi1.rex != emi2.rex) 211 return false; 212 if(emi1.opcode.type != emi2.opcode.type) 213 return false; 214 if(emi1.opcode.op != emi2.opcode.op) 215 return false; 216 if(emi1.modRM != emi2.modRM) 217 return false; 218 if(emi1.sib != emi2.sib) 219 return false; 220 if(emi1.immediate != emi2.immediate) 221 return false; 222 if(emi1.displacement != emi2.displacement) 223 return false; 224 if(emi1.mode != emi2.mode) 225 return false; 226 if(emi1.opSize != emi2.opSize) 227 return false; 228 if(emi1.addrSize != emi2.addrSize) 229 return false; 230 if(emi1.stackSize != emi2.stackSize) 231 return false; 232 if(emi1.dispSize != emi2.dispSize) 233 return false; 234 return true; 235 } 236 237 class PCState : public GenericISA::UPCState<MachInst> 238 { 239 protected: 240 typedef GenericISA::UPCState<MachInst> Base; 241 242 uint8_t _size; 243 244 public: 245 void 246 set(Addr val) 247 { 248 Base::set(val); 249 _size = 0; 250 } 251 252 PCState() {} 253 PCState(Addr val) { set(val); } 254 255 uint8_t size() const { return _size; } 256 void size(uint8_t newSize) { _size = newSize; } 257 258 bool 259 branching() const 260 { 261 return this->npc() != this->pc() + size(); 262 } 263 264 void 265 advance() 266 { 267 Base::advance(); 268 _size = 0; 269 } 270 271 void 272 uEnd() 273 { 274 Base::uEnd(); 275 _size = 0; 276 } 277 278 void 279 serialize(std::ostream &os) 280 { 281 Base::serialize(os); 282 SERIALIZE_SCALAR(_size); 283 } 284 285 void 286 unserialize(Checkpoint *cp, const std::string §ion) 287 { 288 Base::unserialize(cp, section); 289 UNSERIALIZE_SCALAR(_size); 290 } 291 }; 292 293} 294 295__hash_namespace_begin 296 template<> 297 struct hash<X86ISA::ExtMachInst> { 298 size_t operator()(const X86ISA::ExtMachInst &emi) const { 299 return (((uint64_t)emi.legacy << 40) | 300 ((uint64_t)emi.rex << 32) | 301 ((uint64_t)emi.modRM << 24) | 302 ((uint64_t)emi.sib << 16) | 303 ((uint64_t)emi.opcode.type << 8) | 304 ((uint64_t)emi.opcode.op)) ^ 305 emi.immediate ^ emi.displacement ^ 306 emi.mode ^ 307 emi.opSize ^ emi.addrSize ^ 308 emi.stackSize ^ emi.dispSize; 309 }; 310 }; 311__hash_namespace_end 312 313// These two functions allow ExtMachInst to be used with SERIALIZE_SCALAR 314// and UNSERIALIZE_SCALAR. 315template <> 316void 317paramOut(std::ostream &os, const std::string &name, 318 const X86ISA::ExtMachInst &machInst); 319template <> 320void 321paramIn(Checkpoint *cp, const std::string §ion, 322 const std::string &name, X86ISA::ExtMachInst &machInst); 323 324#endif // __ARCH_X86_TYPES_HH__ 325