decoder.hh (9037:2f84b98634ff) | decoder.hh (9376:270c9a75e91f) |
---|---|
1/* 2 * Copyright (c) 2012 Google 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 18 unchanged lines hidden (view full) --- 27 * 28 * Authors: Gabe Black 29 */ 30 31#ifndef __ARCH_X86_DECODER_HH__ 32#define __ARCH_X86_DECODER_HH__ 33 34#include <cassert> | 1/* 2 * Copyright (c) 2012 Google 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 18 unchanged lines hidden (view full) --- 27 * 28 * Authors: Gabe Black 29 */ 30 31#ifndef __ARCH_X86_DECODER_HH__ 32#define __ARCH_X86_DECODER_HH__ 33 34#include <cassert> |
35#include <vector> |
|
35 36#include "arch/x86/regs/misc.hh" 37#include "arch/x86/types.hh" 38#include "base/bitfield.hh" 39#include "base/misc.hh" 40#include "base/trace.hh" 41#include "base/types.hh" 42#include "cpu/decode_cache.hh" --- 10 unchanged lines hidden (view full) --- 53 private: 54 //These are defined and documented in decoder_tables.cc 55 static const uint8_t Prefixes[256]; 56 static const uint8_t UsesModRM[2][256]; 57 static const uint8_t ImmediateType[2][256]; 58 static const uint8_t SizeTypeToSize[3][10]; 59 60 protected: | 36 37#include "arch/x86/regs/misc.hh" 38#include "arch/x86/types.hh" 39#include "base/bitfield.hh" 40#include "base/misc.hh" 41#include "base/trace.hh" 42#include "base/types.hh" 43#include "cpu/decode_cache.hh" --- 10 unchanged lines hidden (view full) --- 54 private: 55 //These are defined and documented in decoder_tables.cc 56 static const uint8_t Prefixes[256]; 57 static const uint8_t UsesModRM[2][256]; 58 static const uint8_t ImmediateType[2][256]; 59 static const uint8_t SizeTypeToSize[3][10]; 60 61 protected: |
62 struct InstBytes 63 { 64 StaticInstPtr si; 65 std::vector<MachInst> chunks; 66 std::vector<MachInst> masks; 67 int lastOffset; 68 69 InstBytes() : lastOffset(0) 70 {} 71 }; 72 73 static InstBytes dummy; 74 |
|
61 ThreadContext * tc; 62 //The bytes to be predecoded 63 MachInst fetchChunk; | 75 ThreadContext * tc; 76 //The bytes to be predecoded 77 MachInst fetchChunk; |
78 InstBytes *instBytes; 79 int chunkIdx; |
|
64 //The pc of the start of fetchChunk 65 Addr basePC; 66 //The pc the current instruction started at 67 Addr origPC; 68 //The offset into fetchChunk of current processing 69 int offset; 70 //The extended machine instruction being generated 71 ExtMachInst emi; | 80 //The pc of the start of fetchChunk 81 Addr basePC; 82 //The pc the current instruction started at 83 Addr origPC; 84 //The offset into fetchChunk of current processing 85 int offset; 86 //The extended machine instruction being generated 87 ExtMachInst emi; |
72 HandyM5Reg m5Reg; | 88 //Predecoding state 89 X86Mode mode; 90 X86SubMode submode; 91 uint8_t altOp; 92 uint8_t defOp; 93 uint8_t altAddr; 94 uint8_t defAddr; 95 uint8_t stack; |
73 | 96 |
74 inline uint8_t getNextByte() | 97 uint8_t getNextByte() |
75 { 76 return ((uint8_t *)&fetchChunk)[offset]; 77 } 78 79 void getImmediate(int &collected, uint64_t ¤t, int size) 80 { 81 //Figure out how many bytes we still need to get for the 82 //immediate. --- 11 unchanged lines hidden (view full) --- 94 partialImm <<= (immediateCollected * 8); 95 //Put it into our displacement 96 current |= partialImm; 97 //Update how many bytes we've collected. 98 collected += toGet; 99 consumeBytes(toGet); 100 } 101 | 98 { 99 return ((uint8_t *)&fetchChunk)[offset]; 100 } 101 102 void getImmediate(int &collected, uint64_t ¤t, int size) 103 { 104 //Figure out how many bytes we still need to get for the 105 //immediate. --- 11 unchanged lines hidden (view full) --- 117 partialImm <<= (immediateCollected * 8); 118 //Put it into our displacement 119 current |= partialImm; 120 //Update how many bytes we've collected. 121 collected += toGet; 122 consumeBytes(toGet); 123 } 124 |
102 inline void consumeByte() | 125 void updateOffsetState() |
103 { | 126 { |
104 offset++; | |
105 assert(offset <= sizeof(MachInst)); | 127 assert(offset <= sizeof(MachInst)); |
106 if(offset == sizeof(MachInst)) 107 outOfBytes = true; | 128 if (offset == sizeof(MachInst)) { 129 DPRINTF(Decoder, "At the end of a chunk, idx = %d, chunks = %d.\n", 130 chunkIdx, instBytes->chunks.size()); 131 chunkIdx++; 132 if (chunkIdx == instBytes->chunks.size()) { 133 outOfBytes = true; 134 } else { 135 offset = 0; 136 fetchChunk = instBytes->chunks[chunkIdx]; 137 basePC += sizeof(MachInst); 138 } 139 } |
108 } 109 | 140 } 141 |
110 inline void consumeBytes(int numBytes) | 142 void consumeByte() |
111 { | 143 { |
144 offset++; 145 updateOffsetState(); 146 } 147 148 void consumeBytes(int numBytes) 149 { |
|
112 offset += numBytes; | 150 offset += numBytes; |
113 assert(offset <= sizeof(MachInst)); 114 if(offset == sizeof(MachInst)) 115 outOfBytes = true; | 151 updateOffsetState(); |
116 } 117 | 152 } 153 |
118 void doReset(); 119 | |
120 //State machine state 121 protected: 122 //Whether or not we're out of bytes 123 bool outOfBytes; 124 //Whether we've completed generating an ExtMachInst 125 bool instDone; 126 //The size of the displacement value 127 int displacementSize; 128 //The size of the immediate value 129 int immediateSize; 130 //This is how much of any immediate value we've gotten. This is used 131 //for both the actual immediate and the displacement. 132 int immediateCollected; 133 134 enum State { 135 ResetState, | 154 //State machine state 155 protected: 156 //Whether or not we're out of bytes 157 bool outOfBytes; 158 //Whether we've completed generating an ExtMachInst 159 bool instDone; 160 //The size of the displacement value 161 int displacementSize; 162 //The size of the immediate value 163 int immediateSize; 164 //This is how much of any immediate value we've gotten. This is used 165 //for both the actual immediate and the displacement. 166 int immediateCollected; 167 168 enum State { 169 ResetState, |
170 FromCacheState, |
|
136 PrefixState, 137 OpcodeState, 138 ModRMState, 139 SIBState, 140 DisplacementState, 141 ImmediateState, 142 //We should never get to this state. Getting here is an error. 143 ErrorState 144 }; 145 146 State state; 147 148 //Functions to handle each of the states | 171 PrefixState, 172 OpcodeState, 173 ModRMState, 174 SIBState, 175 DisplacementState, 176 ImmediateState, 177 //We should never get to this state. Getting here is an error. 178 ErrorState 179 }; 180 181 State state; 182 183 //Functions to handle each of the states |
184 State doResetState(); 185 State doFromCacheState(); |
|
149 State doPrefixState(uint8_t); 150 State doOpcodeState(uint8_t); 151 State doModRMState(uint8_t); 152 State doSIBState(uint8_t); 153 State doDisplacementState(); 154 State doImmediateState(); 155 | 186 State doPrefixState(uint8_t); 187 State doOpcodeState(uint8_t); 188 State doModRMState(uint8_t); 189 State doSIBState(uint8_t); 190 State doDisplacementState(); 191 State doImmediateState(); 192 |
193 protected: 194 /// Caching for decoded instruction objects. 195 196 typedef MiscReg CacheKey; 197 198 typedef DecodeCache::AddrMap<Decoder::InstBytes> DecodePages; 199 DecodePages *decodePages; 200 typedef m5::hash_map<CacheKey, DecodePages *> AddrCacheMap; 201 AddrCacheMap addrCacheMap; 202 203 DecodeCache::InstMap *instMap; 204 typedef m5::hash_map<CacheKey, DecodeCache::InstMap *> InstCacheMap; 205 static InstCacheMap instCacheMap; 206 |
|
156 public: 157 Decoder(ThreadContext * _tc) : 158 tc(_tc), basePC(0), origPC(0), offset(0), 159 outOfBytes(true), instDone(false), 160 state(ResetState) 161 { 162 memset(&emi, 0, sizeof(emi)); | 207 public: 208 Decoder(ThreadContext * _tc) : 209 tc(_tc), basePC(0), origPC(0), offset(0), 210 outOfBytes(true), instDone(false), 211 state(ResetState) 212 { 213 memset(&emi, 0, sizeof(emi)); |
163 emi.mode.mode = LongMode; 164 emi.mode.submode = SixtyFourBitMode; 165 m5Reg = 0; | 214 mode = LongMode; 215 submode = SixtyFourBitMode; 216 emi.mode.mode = mode; 217 emi.mode.submode = submode; 218 altOp = 0; 219 defOp = 0; 220 altAddr = 0; 221 defAddr = 0; 222 stack = 0; 223 instBytes = &dummy; 224 decodePages = NULL; 225 instMap = NULL; |
166 } 167 | 226 } 227 |
228 void setM5Reg(HandyM5Reg m5Reg) 229 { 230 mode = (X86Mode)(uint64_t)m5Reg.mode; 231 submode = (X86SubMode)(uint64_t)m5Reg.submode; 232 emi.mode.mode = mode; 233 emi.mode.submode = submode; 234 altOp = m5Reg.altOp; 235 defOp = m5Reg.defOp; 236 altAddr = m5Reg.altAddr; 237 defAddr = m5Reg.defAddr; 238 stack = m5Reg.stack; 239 240 AddrCacheMap::iterator amIter = addrCacheMap.find(m5Reg); 241 if (amIter != addrCacheMap.end()) { 242 decodePages = amIter->second; 243 } else { 244 decodePages = new DecodePages; 245 addrCacheMap[m5Reg] = decodePages; 246 } 247 248 InstCacheMap::iterator imIter = instCacheMap.find(m5Reg); 249 if (imIter != instCacheMap.end()) { 250 instMap = imIter->second; 251 } else { 252 instMap = new DecodeCache::InstMap; 253 instCacheMap[m5Reg] = instMap; 254 } 255 } 256 |
|
168 void reset() 169 { 170 state = ResetState; 171 } 172 173 ThreadContext * getTC() 174 { 175 return tc; --- 37 unchanged lines hidden (view full) --- 213 "Calculating the instruction size: " 214 "basePC: %#x offset: %#x origPC: %#x size: %d\n", 215 basePC, offset, origPC, size); 216 nextPC.size(size); 217 nextPC.npc(nextPC.pc() + size); 218 } 219 } 220 | 257 void reset() 258 { 259 state = ResetState; 260 } 261 262 ThreadContext * getTC() 263 { 264 return tc; --- 37 unchanged lines hidden (view full) --- 302 "Calculating the instruction size: " 303 "basePC: %#x offset: %#x origPC: %#x size: %d\n", 304 basePC, offset, origPC, size); 305 nextPC.size(size); 306 nextPC.npc(nextPC.pc() + size); 307 } 308 } 309 |
221 protected: 222 /// Caching for decoded instruction objects. 223 static DecodeCache::InstMap instMap; 224 static DecodeCache::AddrMap<StaticInstPtr> decodePages; 225 | |
226 public: 227 StaticInstPtr decodeInst(ExtMachInst mach_inst); 228 229 /// Decode a machine instruction. 230 /// @param mach_inst The binary instruction to decode. 231 /// @retval A pointer to the corresponding StaticInst object. 232 StaticInstPtr decode(ExtMachInst mach_inst, Addr addr); | 310 public: 311 StaticInstPtr decodeInst(ExtMachInst mach_inst); 312 313 /// Decode a machine instruction. 314 /// @param mach_inst The binary instruction to decode. 315 /// @retval A pointer to the corresponding StaticInst object. 316 StaticInstPtr decode(ExtMachInst mach_inst, Addr addr); |
233 234 StaticInstPtr 235 decode(X86ISA::PCState &nextPC) 236 { 237 if (!instDone) 238 return NULL; 239 instDone = false; 240 updateNPC(nextPC); 241 return decode(emi, origPC); 242 } | 317 StaticInstPtr decode(X86ISA::PCState &nextPC); |
243}; 244 245} // namespace X86ISA 246 247#endif // __ARCH_X86_DECODER_HH__ | 318}; 319 320} // namespace X86ISA 321 322#endif // __ARCH_X86_DECODER_HH__ |