types.hh revision 7971:1e9c54ee5fd0
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 predecoder. 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 BitUnion8(Opcode) 108 Bitfield<7,3> top5; 109 Bitfield<2,0> bottom3; 110 EndBitUnion(Opcode) 111 112 BitUnion8(OperatingMode) 113 Bitfield<3> mode; 114 Bitfield<2,0> submode; 115 EndBitUnion(OperatingMode) 116 117 enum X86Mode { 118 LongMode, 119 LegacyMode 120 }; 121 122 enum X86SubMode { 123 SixtyFourBitMode, 124 CompatabilityMode, 125 ProtectedMode, 126 Virtual8086Mode, 127 RealMode 128 }; 129 130 //The intermediate structure the x86 predecoder returns. 131 struct ExtMachInst 132 { 133 //Prefixes 134 LegacyPrefixVector legacy; 135 Rex rex; 136 //This holds all of the bytes of the opcode 137 struct 138 { 139 //The number of bytes in this opcode. Right now, we ignore that 140 //this can be 3 in some cases 141 uint8_t num; 142 //The first byte detected in a 2+ byte opcode. Should be 0xF0. 143 uint8_t prefixA; 144 //The second byte detected in a 3+ byte opcode. Could be 0x38-0x3F 145 //for some SSE instructions. 3dNow! instructions are handled as 146 //two byte opcodes and then split out further by the immediate 147 //byte. 148 uint8_t prefixB; 149 //The main opcode byte. The highest addressed byte in the opcode. 150 Opcode op; 151 } opcode; 152 //Modifier bytes 153 ModRM modRM; 154 Sib sib; 155 //Immediate fields 156 uint64_t immediate; 157 uint64_t displacement; 158 159 //The effective operand size. 160 uint8_t opSize; 161 //The effective address size. 162 uint8_t addrSize; 163 //The effective stack size. 164 uint8_t stackSize; 165 //The size of the displacement 166 uint8_t dispSize; 167 168 //Mode information 169 OperatingMode mode; 170 }; 171 172 inline static std::ostream & 173 operator << (std::ostream & os, const ExtMachInst & emi) 174 { 175 ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t" 176 "op = {\n\t\tnum = %d,\n\t\top = %#x,\n\t\t" 177 "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t" 178 "modRM = %#x,\n\tsib = %#x,\n\t" 179 "immediate = %#x,\n\tdisplacement = %#x\n\t" 180 "dispSize = %d}\n", 181 (uint8_t)emi.legacy, (uint8_t)emi.rex, 182 emi.opcode.num, (uint8_t)emi.opcode.op, 183 emi.opcode.prefixA, emi.opcode.prefixB, 184 (uint8_t)emi.modRM, (uint8_t)emi.sib, 185 emi.immediate, emi.displacement, emi.dispSize); 186 return os; 187 } 188 189 inline static bool 190 operator == (const ExtMachInst &emi1, const ExtMachInst &emi2) 191 { 192 if(emi1.legacy != emi2.legacy) 193 return false; 194 if(emi1.rex != emi2.rex) 195 return false; 196 if(emi1.opcode.num != emi2.opcode.num) 197 return false; 198 if(emi1.opcode.op != emi2.opcode.op) 199 return false; 200 if(emi1.opcode.prefixA != emi2.opcode.prefixA) 201 return false; 202 if(emi1.opcode.prefixB != emi2.opcode.prefixB) 203 return false; 204 if(emi1.modRM != emi2.modRM) 205 return false; 206 if(emi1.sib != emi2.sib) 207 return false; 208 if(emi1.immediate != emi2.immediate) 209 return false; 210 if(emi1.displacement != emi2.displacement) 211 return false; 212 if(emi1.mode != emi2.mode) 213 return false; 214 if(emi1.opSize != emi2.opSize) 215 return false; 216 if(emi1.addrSize != emi2.addrSize) 217 return false; 218 if(emi1.stackSize != emi2.stackSize) 219 return false; 220 if(emi1.dispSize != emi2.dispSize) 221 return false; 222 return true; 223 } 224 225 class PCState : public GenericISA::UPCState<MachInst> 226 { 227 protected: 228 typedef GenericISA::UPCState<MachInst> Base; 229 230 uint8_t _size; 231 232 public: 233 void 234 set(Addr val) 235 { 236 Base::set(val); 237 _size = 0; 238 } 239 240 PCState() {} 241 PCState(Addr val) { set(val); } 242 243 uint8_t size() const { return _size; } 244 void size(uint8_t newSize) { _size = newSize; } 245 246 bool 247 branching() const 248 { 249 return this->npc() != this->pc() + size(); 250 } 251 252 void 253 advance() 254 { 255 Base::advance(); 256 _size = 0; 257 } 258 259 void 260 uEnd() 261 { 262 Base::uEnd(); 263 _size = 0; 264 } 265 266 void 267 serialize(std::ostream &os) 268 { 269 Base::serialize(os); 270 SERIALIZE_SCALAR(_size); 271 } 272 273 void 274 unserialize(Checkpoint *cp, const std::string §ion) 275 { 276 Base::unserialize(cp, section); 277 UNSERIALIZE_SCALAR(_size); 278 } 279 }; 280 281 struct CoreSpecific { 282 int core_type; 283 }; 284}; 285 286namespace __hash_namespace { 287 template<> 288 struct hash<X86ISA::ExtMachInst> { 289 size_t operator()(const X86ISA::ExtMachInst &emi) const { 290 return (((uint64_t)emi.legacy << 56) | 291 ((uint64_t)emi.rex << 48) | 292 ((uint64_t)emi.modRM << 40) | 293 ((uint64_t)emi.sib << 32) | 294 ((uint64_t)emi.opcode.num << 24) | 295 ((uint64_t)emi.opcode.prefixA << 16) | 296 ((uint64_t)emi.opcode.prefixB << 8) | 297 ((uint64_t)emi.opcode.op)) ^ 298 emi.immediate ^ emi.displacement ^ 299 emi.mode ^ 300 emi.opSize ^ emi.addrSize ^ 301 emi.stackSize ^ emi.dispSize; 302 }; 303 }; 304} 305 306// These two functions allow ExtMachInst to be used with SERIALIZE_SCALAR 307// and UNSERIALIZE_SCALAR. 308template <> 309void 310paramOut(std::ostream &os, const std::string &name, 311 const X86ISA::ExtMachInst &machInst); 312template <> 313void 314paramIn(Checkpoint *cp, const std::string §ion, 315 const std::string &name, X86ISA::ExtMachInst &machInst); 316 317#endif // __ARCH_X86_TYPES_HH__ 318