1/* 2 * Copyright (c) 2011 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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Gabe Black 29 */ 30 31#include "arch/x86/decoder.hh" 32#include "arch/x86/regs/misc.hh" 33#include "base/misc.hh" 34#include "base/trace.hh" 35#include "base/types.hh" 36#include "cpu/thread_context.hh" 37#include "debug/Decoder.hh" 38 39namespace X86ISA 40{
| 1/* 2 * Copyright (c) 2011 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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Gabe Black 29 */ 30 31#include "arch/x86/decoder.hh" 32#include "arch/x86/regs/misc.hh" 33#include "base/misc.hh" 34#include "base/trace.hh" 35#include "base/types.hh" 36#include "cpu/thread_context.hh" 37#include "debug/Decoder.hh" 38 39namespace X86ISA 40{
|
41void Decoder::doReset()
| 41 42Decoder::State 43Decoder::doResetState()
|
42{ 43 origPC = basePC + offset; 44 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC);
| 44{ 45 origPC = basePC + offset; 46 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC);
|
| 47 instBytes = &decodePages->lookup(origPC); 48 chunkIdx = 0; 49
|
45 emi.rex = 0; 46 emi.legacy = 0; 47 emi.opcode.num = 0; 48 emi.opcode.op = 0; 49 emi.opcode.prefixA = emi.opcode.prefixB = 0; 50 51 immediateCollected = 0; 52 emi.immediate = 0; 53 emi.displacement = 0; 54 emi.dispSize = 0; 55 56 emi.modRM = 0; 57 emi.sib = 0;
| 50 emi.rex = 0; 51 emi.legacy = 0; 52 emi.opcode.num = 0; 53 emi.opcode.op = 0; 54 emi.opcode.prefixA = emi.opcode.prefixB = 0; 55 56 immediateCollected = 0; 57 emi.immediate = 0; 58 emi.displacement = 0; 59 emi.dispSize = 0; 60 61 emi.modRM = 0; 62 emi.sib = 0;
|
58 m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 59 emi.mode.mode = m5Reg.mode; 60 emi.mode.submode = m5Reg.submode;
| 63 64 if (instBytes->si) { 65 return FromCacheState; 66 } else { 67 instBytes->chunks.clear(); 68 return PrefixState; 69 }
|
61} 62
| 70} 71
|
63void Decoder::process()
| 72void 73Decoder::process()
|
64{ 65 //This function drives the decoder state machine. 66 67 //Some sanity checks. You shouldn't try to process more bytes if 68 //there aren't any, and you shouldn't overwrite an already 69 //decoder ExtMachInst. 70 assert(!outOfBytes); 71 assert(!instDone); 72
| 74{ 75 //This function drives the decoder state machine. 76 77 //Some sanity checks. You shouldn't try to process more bytes if 78 //there aren't any, and you shouldn't overwrite an already 79 //decoder ExtMachInst. 80 assert(!outOfBytes); 81 assert(!instDone); 82
|
| 83 if (state == ResetState) 84 state = doResetState(); 85 if (state == FromCacheState) { 86 state = doFromCacheState(); 87 } else { 88 instBytes->chunks.push_back(fetchChunk); 89 } 90
|
73 //While there's still something to do...
| 91 //While there's still something to do...
|
74 while(!instDone && !outOfBytes) 75 {
| 92 while (!instDone && !outOfBytes) {
|
76 uint8_t nextByte = getNextByte();
| 93 uint8_t nextByte = getNextByte();
|
77 switch(state) 78 { 79 case ResetState: 80 doReset(); 81 state = PrefixState;
| 94 switch (state) {
|
82 case PrefixState: 83 state = doPrefixState(nextByte); 84 break; 85 case OpcodeState: 86 state = doOpcodeState(nextByte); 87 break; 88 case ModRMState: 89 state = doModRMState(nextByte); 90 break; 91 case SIBState: 92 state = doSIBState(nextByte); 93 break; 94 case DisplacementState: 95 state = doDisplacementState(); 96 break; 97 case ImmediateState: 98 state = doImmediateState(); 99 break; 100 case ErrorState: 101 panic("Went to the error state in the decoder.\n"); 102 default: 103 panic("Unrecognized state! %d\n", state); 104 } 105 } 106} 107
| 95 case PrefixState: 96 state = doPrefixState(nextByte); 97 break; 98 case OpcodeState: 99 state = doOpcodeState(nextByte); 100 break; 101 case ModRMState: 102 state = doModRMState(nextByte); 103 break; 104 case SIBState: 105 state = doSIBState(nextByte); 106 break; 107 case DisplacementState: 108 state = doDisplacementState(); 109 break; 110 case ImmediateState: 111 state = doImmediateState(); 112 break; 113 case ErrorState: 114 panic("Went to the error state in the decoder.\n"); 115 default: 116 panic("Unrecognized state! %d\n", state); 117 } 118 } 119} 120
|
| 121Decoder::State 122Decoder::doFromCacheState() 123{ 124 DPRINTF(Decoder, "Looking at cache state.\n"); 125 if ((fetchChunk & instBytes->masks[chunkIdx]) != 126 instBytes->chunks[chunkIdx]) { 127 DPRINTF(Decoder, "Decode cache miss.\n"); 128 // The chached chunks didn't match what was fetched. Fall back to the 129 // predecoder. 130 instBytes->chunks[chunkIdx] = fetchChunk; 131 instBytes->chunks.resize(chunkIdx + 1); 132 instBytes->si = NULL; 133 chunkIdx = 0; 134 fetchChunk = instBytes->chunks[0]; 135 offset = origPC % sizeof(MachInst); 136 basePC = origPC - offset; 137 return PrefixState; 138 } else if (chunkIdx == instBytes->chunks.size() - 1) { 139 // We matched the cache, so use its value. 140 instDone = true; 141 offset = instBytes->lastOffset; 142 if (offset == sizeof(MachInst)) 143 outOfBytes = true; 144 return ResetState; 145 } else { 146 // We matched so far, but need to check more chunks. 147 chunkIdx++; 148 outOfBytes = true; 149 return FromCacheState; 150 } 151} 152
|
108//Either get a prefix and record it in the ExtMachInst, or send the 109//state machine on to get the opcode(s).
| 153//Either get a prefix and record it in the ExtMachInst, or send the 154//state machine on to get the opcode(s).
|
110Decoder::State Decoder::doPrefixState(uint8_t nextByte)
| 155Decoder::State 156Decoder::doPrefixState(uint8_t nextByte)
|
111{ 112 uint8_t prefix = Prefixes[nextByte]; 113 State nextState = PrefixState; 114 // REX prefixes are only recognized in 64 bit mode. 115 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) 116 prefix = 0; 117 if (prefix) 118 consumeByte(); 119 switch(prefix) 120 { 121 //Operand size override prefixes 122 case OperandSizeOverride: 123 DPRINTF(Decoder, "Found operand size override prefix.\n"); 124 emi.legacy.op = true; 125 break; 126 case AddressSizeOverride: 127 DPRINTF(Decoder, "Found address size override prefix.\n"); 128 emi.legacy.addr = true; 129 break; 130 //Segment override prefixes 131 case CSOverride: 132 case DSOverride: 133 case ESOverride: 134 case FSOverride: 135 case GSOverride: 136 case SSOverride: 137 DPRINTF(Decoder, "Found segment override.\n"); 138 emi.legacy.seg = prefix; 139 break; 140 case Lock: 141 DPRINTF(Decoder, "Found lock prefix.\n"); 142 emi.legacy.lock = true; 143 break; 144 case Rep: 145 DPRINTF(Decoder, "Found rep prefix.\n"); 146 emi.legacy.rep = true; 147 break; 148 case Repne: 149 DPRINTF(Decoder, "Found repne prefix.\n"); 150 emi.legacy.repne = true; 151 break; 152 case RexPrefix: 153 DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte); 154 emi.rex = nextByte; 155 break; 156 case 0: 157 nextState = OpcodeState; 158 break; 159 default: 160 panic("Unrecognized prefix %#x\n", nextByte); 161 } 162 return nextState; 163} 164 165//Load all the opcodes (currently up to 2) and then figure out 166//what immediate and/or ModRM is needed.
| 157{ 158 uint8_t prefix = Prefixes[nextByte]; 159 State nextState = PrefixState; 160 // REX prefixes are only recognized in 64 bit mode. 161 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) 162 prefix = 0; 163 if (prefix) 164 consumeByte(); 165 switch(prefix) 166 { 167 //Operand size override prefixes 168 case OperandSizeOverride: 169 DPRINTF(Decoder, "Found operand size override prefix.\n"); 170 emi.legacy.op = true; 171 break; 172 case AddressSizeOverride: 173 DPRINTF(Decoder, "Found address size override prefix.\n"); 174 emi.legacy.addr = true; 175 break; 176 //Segment override prefixes 177 case CSOverride: 178 case DSOverride: 179 case ESOverride: 180 case FSOverride: 181 case GSOverride: 182 case SSOverride: 183 DPRINTF(Decoder, "Found segment override.\n"); 184 emi.legacy.seg = prefix; 185 break; 186 case Lock: 187 DPRINTF(Decoder, "Found lock prefix.\n"); 188 emi.legacy.lock = true; 189 break; 190 case Rep: 191 DPRINTF(Decoder, "Found rep prefix.\n"); 192 emi.legacy.rep = true; 193 break; 194 case Repne: 195 DPRINTF(Decoder, "Found repne prefix.\n"); 196 emi.legacy.repne = true; 197 break; 198 case RexPrefix: 199 DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte); 200 emi.rex = nextByte; 201 break; 202 case 0: 203 nextState = OpcodeState; 204 break; 205 default: 206 panic("Unrecognized prefix %#x\n", nextByte); 207 } 208 return nextState; 209} 210 211//Load all the opcodes (currently up to 2) and then figure out 212//what immediate and/or ModRM is needed.
|
167Decoder::State Decoder::doOpcodeState(uint8_t nextByte)
| 213Decoder::State 214Decoder::doOpcodeState(uint8_t nextByte)
|
168{ 169 State nextState = ErrorState; 170 emi.opcode.num++; 171 //We can't handle 3+ byte opcodes right now 172 assert(emi.opcode.num < 4); 173 consumeByte(); 174 if(emi.opcode.num == 1 && nextByte == 0x0f) 175 { 176 nextState = OpcodeState; 177 DPRINTF(Decoder, "Found two byte opcode.\n"); 178 emi.opcode.prefixA = nextByte; 179 } 180 else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3A)) 181 { 182 nextState = OpcodeState; 183 DPRINTF(Decoder, "Found three byte opcode.\n"); 184 emi.opcode.prefixB = nextByte; 185 } 186 else 187 { 188 DPRINTF(Decoder, "Found opcode %#x.\n", nextByte); 189 emi.opcode.op = nextByte; 190 191 //Figure out the effective operand size. This can be overriden to 192 //a fixed value at the decoder level. 193 int logOpSize; 194 if (emi.rex.w) 195 logOpSize = 3; // 64 bit operand size 196 else if (emi.legacy.op)
| 215{ 216 State nextState = ErrorState; 217 emi.opcode.num++; 218 //We can't handle 3+ byte opcodes right now 219 assert(emi.opcode.num < 4); 220 consumeByte(); 221 if(emi.opcode.num == 1 && nextByte == 0x0f) 222 { 223 nextState = OpcodeState; 224 DPRINTF(Decoder, "Found two byte opcode.\n"); 225 emi.opcode.prefixA = nextByte; 226 } 227 else if(emi.opcode.num == 2 && (nextByte == 0x38 || nextByte == 0x3A)) 228 { 229 nextState = OpcodeState; 230 DPRINTF(Decoder, "Found three byte opcode.\n"); 231 emi.opcode.prefixB = nextByte; 232 } 233 else 234 { 235 DPRINTF(Decoder, "Found opcode %#x.\n", nextByte); 236 emi.opcode.op = nextByte; 237 238 //Figure out the effective operand size. This can be overriden to 239 //a fixed value at the decoder level. 240 int logOpSize; 241 if (emi.rex.w) 242 logOpSize = 3; // 64 bit operand size 243 else if (emi.legacy.op)
|
197 logOpSize = m5Reg.altOp;
| 244 logOpSize = altOp;
|
198 else
| 245 else
|
199 logOpSize = m5Reg.defOp;
| 246 logOpSize = defOp;
|
200 201 //Set the actual op size 202 emi.opSize = 1 << logOpSize; 203 204 //Figure out the effective address size. This can be overriden to 205 //a fixed value at the decoder level. 206 int logAddrSize; 207 if(emi.legacy.addr)
| 247 248 //Set the actual op size 249 emi.opSize = 1 << logOpSize; 250 251 //Figure out the effective address size. This can be overriden to 252 //a fixed value at the decoder level. 253 int logAddrSize; 254 if(emi.legacy.addr)
|
208 logAddrSize = m5Reg.altAddr;
| 255 logAddrSize = altAddr;
|
209 else
| 256 else
|
210 logAddrSize = m5Reg.defAddr;
| 257 logAddrSize = defAddr;
|
211 212 //Set the actual address size 213 emi.addrSize = 1 << logAddrSize; 214 215 //Figure out the effective stack width. This can be overriden to 216 //a fixed value at the decoder level.
| 258 259 //Set the actual address size 260 emi.addrSize = 1 << logAddrSize; 261 262 //Figure out the effective stack width. This can be overriden to 263 //a fixed value at the decoder level.
|
217 emi.stackSize = 1 << m5Reg.stack;
| 264 emi.stackSize = 1 << stack;
|
218 219 //Figure out how big of an immediate we'll retreive based 220 //on the opcode. 221 int immType = ImmediateType[emi.opcode.num - 1][nextByte]; 222 if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3) 223 immediateSize = SizeTypeToSize[logAddrSize - 1][immType]; 224 else 225 immediateSize = SizeTypeToSize[logOpSize - 1][immType]; 226 227 //Determine what to expect next 228 if (UsesModRM[emi.opcode.num - 1][nextByte]) { 229 nextState = ModRMState; 230 } else { 231 if(immediateSize) { 232 nextState = ImmediateState; 233 } else { 234 instDone = true; 235 nextState = ResetState; 236 } 237 } 238 } 239 return nextState; 240} 241 242//Get the ModRM byte and determine what displacement, if any, there is. 243//Also determine whether or not to get the SIB byte, displacement, or 244//immediate next.
| 265 266 //Figure out how big of an immediate we'll retreive based 267 //on the opcode. 268 int immType = ImmediateType[emi.opcode.num - 1][nextByte]; 269 if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3) 270 immediateSize = SizeTypeToSize[logAddrSize - 1][immType]; 271 else 272 immediateSize = SizeTypeToSize[logOpSize - 1][immType]; 273 274 //Determine what to expect next 275 if (UsesModRM[emi.opcode.num - 1][nextByte]) { 276 nextState = ModRMState; 277 } else { 278 if(immediateSize) { 279 nextState = ImmediateState; 280 } else { 281 instDone = true; 282 nextState = ResetState; 283 } 284 } 285 } 286 return nextState; 287} 288 289//Get the ModRM byte and determine what displacement, if any, there is. 290//Also determine whether or not to get the SIB byte, displacement, or 291//immediate next.
|
245Decoder::State Decoder::doModRMState(uint8_t nextByte)
| 292Decoder::State 293Decoder::doModRMState(uint8_t nextByte)
|
246{ 247 State nextState = ErrorState; 248 ModRM modRM; 249 modRM = nextByte; 250 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte);
| 294{ 295 State nextState = ErrorState; 296 ModRM modRM; 297 modRM = nextByte; 298 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte);
|
251 if (m5Reg.defOp == 1) {
| 299 if (defOp == 1) {
|
252 //figure out 16 bit displacement size 253 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) 254 displacementSize = 2; 255 else if (modRM.mod == 1) 256 displacementSize = 1; 257 else 258 displacementSize = 0; 259 } else { 260 //figure out 32/64 bit displacement size 261 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2) 262 displacementSize = 4; 263 else if (modRM.mod == 1) 264 displacementSize = 1; 265 else 266 displacementSize = 0; 267 } 268 269 // The "test" instruction in group 3 needs an immediate, even though 270 // the other instructions with the same actual opcode don't. 271 if (emi.opcode.num == 1 && (modRM.reg & 0x6) == 0) { 272 if (emi.opcode.op == 0xF6) 273 immediateSize = 1; 274 else if (emi.opcode.op == 0xF7) 275 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize; 276 } 277 278 //If there's an SIB, get that next. 279 //There is no SIB in 16 bit mode. 280 if (modRM.rm == 4 && modRM.mod != 3) { 281 // && in 32/64 bit mode) 282 nextState = SIBState; 283 } else if(displacementSize) { 284 nextState = DisplacementState; 285 } else if(immediateSize) { 286 nextState = ImmediateState; 287 } else { 288 instDone = true; 289 nextState = ResetState; 290 } 291 //The ModRM byte is consumed no matter what 292 consumeByte(); 293 emi.modRM = modRM; 294 return nextState; 295} 296 297//Get the SIB byte. We don't do anything with it at this point, other 298//than storing it in the ExtMachInst. Determine if we need to get a 299//displacement or immediate next.
| 300 //figure out 16 bit displacement size 301 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) 302 displacementSize = 2; 303 else if (modRM.mod == 1) 304 displacementSize = 1; 305 else 306 displacementSize = 0; 307 } else { 308 //figure out 32/64 bit displacement size 309 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2) 310 displacementSize = 4; 311 else if (modRM.mod == 1) 312 displacementSize = 1; 313 else 314 displacementSize = 0; 315 } 316 317 // The "test" instruction in group 3 needs an immediate, even though 318 // the other instructions with the same actual opcode don't. 319 if (emi.opcode.num == 1 && (modRM.reg & 0x6) == 0) { 320 if (emi.opcode.op == 0xF6) 321 immediateSize = 1; 322 else if (emi.opcode.op == 0xF7) 323 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize; 324 } 325 326 //If there's an SIB, get that next. 327 //There is no SIB in 16 bit mode. 328 if (modRM.rm == 4 && modRM.mod != 3) { 329 // && in 32/64 bit mode) 330 nextState = SIBState; 331 } else if(displacementSize) { 332 nextState = DisplacementState; 333 } else if(immediateSize) { 334 nextState = ImmediateState; 335 } else { 336 instDone = true; 337 nextState = ResetState; 338 } 339 //The ModRM byte is consumed no matter what 340 consumeByte(); 341 emi.modRM = modRM; 342 return nextState; 343} 344 345//Get the SIB byte. We don't do anything with it at this point, other 346//than storing it in the ExtMachInst. Determine if we need to get a 347//displacement or immediate next.
|
300Decoder::State Decoder::doSIBState(uint8_t nextByte)
| 348Decoder::State 349Decoder::doSIBState(uint8_t nextByte)
|
301{ 302 State nextState = ErrorState; 303 emi.sib = nextByte; 304 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte); 305 consumeByte(); 306 if (emi.modRM.mod == 0 && emi.sib.base == 5) 307 displacementSize = 4; 308 if (displacementSize) { 309 nextState = DisplacementState; 310 } else if(immediateSize) { 311 nextState = ImmediateState; 312 } else { 313 instDone = true; 314 nextState = ResetState; 315 } 316 return nextState; 317} 318 319//Gather up the displacement, or at least as much of it 320//as we can get.
| 350{ 351 State nextState = ErrorState; 352 emi.sib = nextByte; 353 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte); 354 consumeByte(); 355 if (emi.modRM.mod == 0 && emi.sib.base == 5) 356 displacementSize = 4; 357 if (displacementSize) { 358 nextState = DisplacementState; 359 } else if(immediateSize) { 360 nextState = ImmediateState; 361 } else { 362 instDone = true; 363 nextState = ResetState; 364 } 365 return nextState; 366} 367 368//Gather up the displacement, or at least as much of it 369//as we can get.
|
321Decoder::State Decoder::doDisplacementState()
| 370Decoder::State 371Decoder::doDisplacementState()
|
322{ 323 State nextState = ErrorState; 324 325 getImmediate(immediateCollected, 326 emi.displacement, 327 displacementSize); 328 329 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n", 330 displacementSize, immediateCollected); 331 332 if(displacementSize == immediateCollected) { 333 //Reset this for other immediates. 334 immediateCollected = 0; 335 //Sign extend the displacement 336 switch(displacementSize) 337 { 338 case 1: 339 emi.displacement = sext<8>(emi.displacement); 340 break; 341 case 2: 342 emi.displacement = sext<16>(emi.displacement); 343 break; 344 case 4: 345 emi.displacement = sext<32>(emi.displacement); 346 break; 347 default: 348 panic("Undefined displacement size!\n"); 349 } 350 DPRINTF(Decoder, "Collected displacement %#x.\n", 351 emi.displacement); 352 if(immediateSize) { 353 nextState = ImmediateState; 354 } else { 355 instDone = true; 356 nextState = ResetState; 357 } 358 359 emi.dispSize = displacementSize; 360 } 361 else 362 nextState = DisplacementState; 363 return nextState; 364} 365 366//Gather up the immediate, or at least as much of it 367//as we can get
| 372{ 373 State nextState = ErrorState; 374 375 getImmediate(immediateCollected, 376 emi.displacement, 377 displacementSize); 378 379 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n", 380 displacementSize, immediateCollected); 381 382 if(displacementSize == immediateCollected) { 383 //Reset this for other immediates. 384 immediateCollected = 0; 385 //Sign extend the displacement 386 switch(displacementSize) 387 { 388 case 1: 389 emi.displacement = sext<8>(emi.displacement); 390 break; 391 case 2: 392 emi.displacement = sext<16>(emi.displacement); 393 break; 394 case 4: 395 emi.displacement = sext<32>(emi.displacement); 396 break; 397 default: 398 panic("Undefined displacement size!\n"); 399 } 400 DPRINTF(Decoder, "Collected displacement %#x.\n", 401 emi.displacement); 402 if(immediateSize) { 403 nextState = ImmediateState; 404 } else { 405 instDone = true; 406 nextState = ResetState; 407 } 408 409 emi.dispSize = displacementSize; 410 } 411 else 412 nextState = DisplacementState; 413 return nextState; 414} 415 416//Gather up the immediate, or at least as much of it 417//as we can get
|
368Decoder::State Decoder::doImmediateState()
| 418Decoder::State 419Decoder::doImmediateState()
|
369{ 370 State nextState = ErrorState; 371 372 getImmediate(immediateCollected, 373 emi.immediate, 374 immediateSize); 375 376 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n", 377 immediateSize, immediateCollected); 378 379 if(immediateSize == immediateCollected) 380 { 381 //Reset this for other immediates. 382 immediateCollected = 0; 383 384 //XXX Warning! The following is an observed pattern and might 385 //not always be true! 386 387 //Instructions which use 64 bit operands but 32 bit immediates 388 //need to have the immediate sign extended to 64 bits. 389 //Instructions which use true 64 bit immediates won't be 390 //affected, and instructions that use true 32 bit immediates 391 //won't notice. 392 switch(immediateSize) 393 { 394 case 4: 395 emi.immediate = sext<32>(emi.immediate); 396 break; 397 case 1: 398 emi.immediate = sext<8>(emi.immediate); 399 } 400 401 DPRINTF(Decoder, "Collected immediate %#x.\n", 402 emi.immediate); 403 instDone = true; 404 nextState = ResetState; 405 } 406 else 407 nextState = ImmediateState; 408 return nextState; 409} 410
| 420{ 421 State nextState = ErrorState; 422 423 getImmediate(immediateCollected, 424 emi.immediate, 425 immediateSize); 426 427 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n", 428 immediateSize, immediateCollected); 429 430 if(immediateSize == immediateCollected) 431 { 432 //Reset this for other immediates. 433 immediateCollected = 0; 434 435 //XXX Warning! The following is an observed pattern and might 436 //not always be true! 437 438 //Instructions which use 64 bit operands but 32 bit immediates 439 //need to have the immediate sign extended to 64 bits. 440 //Instructions which use true 64 bit immediates won't be 441 //affected, and instructions that use true 32 bit immediates 442 //won't notice. 443 switch(immediateSize) 444 { 445 case 4: 446 emi.immediate = sext<32>(emi.immediate); 447 break; 448 case 1: 449 emi.immediate = sext<8>(emi.immediate); 450 } 451 452 DPRINTF(Decoder, "Collected immediate %#x.\n", 453 emi.immediate); 454 instDone = true; 455 nextState = ResetState; 456 } 457 else 458 nextState = ImmediateState; 459 return nextState; 460} 461
|
411DecodeCache::InstMap Decoder::instMap; 412DecodeCache::AddrMap<StaticInstPtr> Decoder::decodePages;
| 462Decoder::InstBytes Decoder::dummy; 463Decoder::InstCacheMap Decoder::instCacheMap;
|
413 414StaticInstPtr 415Decoder::decode(ExtMachInst mach_inst, Addr addr) 416{
| 464 465StaticInstPtr 466Decoder::decode(ExtMachInst mach_inst, Addr addr) 467{
|
417 StaticInstPtr &si = decodePages.lookup(addr); 418 if (si && (si->machInst == mach_inst)) 419 return si;
| 468 DecodeCache::InstMap::iterator iter = instMap->find(mach_inst); 469 if (iter != instMap->end()) 470 return iter->second;
|
420
| 471
|
421 DecodeCache::InstMap::iterator iter = instMap.find(mach_inst); 422 if (iter != instMap.end()) { 423 si = iter->second;
| 472 StaticInstPtr si = decodeInst(mach_inst); 473 (*instMap)[mach_inst] = si; 474 return si; 475} 476 477StaticInstPtr 478Decoder::decode(PCState &nextPC) 479{ 480 if (!instDone) 481 return NULL; 482 instDone = false; 483 updateNPC(nextPC); 484 485 StaticInstPtr &si = instBytes->si; 486 if (si)
|
424 return si;
| 487 return si;
|
| 488 489 // We didn't match in the AddrMap, but we still populated an entry. Fix 490 // up its byte masks. 491 const int chunkSize = sizeof(MachInst); 492 493 instBytes->lastOffset = offset; 494 495 Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize; 496 Addr firstOffset = origPC - firstBasePC; 497 Addr totalSize = instBytes->lastOffset - firstOffset + 498 (instBytes->chunks.size() - 1) * chunkSize; 499 int start = firstOffset; 500 instBytes->masks.clear(); 501 502 while (totalSize) { 503 int end = start + totalSize; 504 end = (chunkSize < end) ? chunkSize : end; 505 int size = end - start; 506 int idx = instBytes->masks.size(); 507 508 MachInst maskVal = mask(size * 8) << (start * 8); 509 assert(maskVal); 510 511 instBytes->masks.push_back(maskVal); 512 instBytes->chunks[idx] &= instBytes->masks[idx]; 513 totalSize -= size; 514 start = 0;
|
425 } 426
| 515 } 516
|
427 si = decodeInst(mach_inst); 428 instMap[mach_inst] = si;
| 517 si = decode(emi, origPC);
|
429 return si; 430} 431 432}
| 518 return si; 519} 520 521}
|