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