Merge ARM into the head. ARM will compile but may not actually work.
[gem5.git] / src / arch / x86 / predecoder.cc
1 /*
2 * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
3 * All rights reserved.
4 *
5 * Redistribution and use of this software in source and binary forms,
6 * with or without modification, are permitted provided that the
7 * following conditions are met:
8 *
9 * The software must be used only for Non-Commercial Use which means any
10 * use which is NOT directed to receiving any direct monetary
11 * compensation for, or commercial advantage from such use. Illustrative
12 * examples of non-commercial use are academic research, personal study,
13 * teaching, education and corporate research & development.
14 * Illustrative examples of commercial use are distributing products for
15 * commercial advantage and providing services using the software for
16 * commercial advantage.
17 *
18 * If you wish to use this software or functionality therein that may be
19 * covered by patents for commercial use, please contact:
20 * Director of Intellectual Property Licensing
21 * Office of Strategy and Technology
22 * Hewlett-Packard Company
23 * 1501 Page Mill Road
24 * Palo Alto, California 94304
25 *
26 * Redistributions of source code must retain the above copyright notice,
27 * this list of conditions and the following disclaimer. Redistributions
28 * in binary form must reproduce the above copyright notice, this list of
29 * conditions and the following disclaimer in the documentation and/or
30 * other materials provided with the distribution. Neither the name of
31 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
32 * contributors may be used to endorse or promote products derived from
33 * this software without specific prior written permission. No right of
34 * sublicense is granted herewith. Derivatives of the software and
35 * output created using the software may be prepared, but only for
36 * Non-Commercial Uses. Derivatives of the software may be shared with
37 * others provided: (i) the others agree to abide by the list of
38 * conditions herein which includes the Non-Commercial Use restrictions;
39 * and (ii) such Derivatives of the software include the above copyright
40 * notice to acknowledge the contribution from this software where
41 * applicable, this list of conditions and the disclaimer below.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 *
55 * Authors: Gabe Black
56 */
57
58 #include "arch/x86/miscregs.hh"
59 #include "arch/x86/predecoder.hh"
60 #include "base/misc.hh"
61 #include "base/trace.hh"
62 #include "cpu/thread_context.hh"
63 #include "sim/host.hh"
64
65 namespace X86ISA
66 {
67 void Predecoder::doReset()
68 {
69 origPC = basePC + offset;
70 DPRINTF(Predecoder, "Setting origPC to %#x\n", origPC);
71 emi.rex = 0;
72 emi.legacy = 0;
73 emi.opcode.num = 0;
74 emi.opcode.op = 0;
75 emi.opcode.prefixA = emi.opcode.prefixB = 0;
76
77 immediateCollected = 0;
78 emi.immediate = 0;
79 emi.displacement = 0;
80
81 emi.modRM = 0;
82 emi.sib = 0;
83 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
84 emi.mode.mode = m5reg.mode;
85 emi.mode.submode = m5reg.submode;
86 }
87
88 void Predecoder::process()
89 {
90 //This function drives the predecoder state machine.
91
92 //Some sanity checks. You shouldn't try to process more bytes if
93 //there aren't any, and you shouldn't overwrite an already
94 //predecoder ExtMachInst.
95 assert(!outOfBytes);
96 assert(!emiIsReady);
97
98 //While there's still something to do...
99 while(!emiIsReady && !outOfBytes)
100 {
101 uint8_t nextByte = getNextByte();
102 switch(state)
103 {
104 case ResetState:
105 doReset();
106 state = PrefixState;
107 case PrefixState:
108 state = doPrefixState(nextByte);
109 break;
110 case OpcodeState:
111 state = doOpcodeState(nextByte);
112 break;
113 case ModRMState:
114 state = doModRMState(nextByte);
115 break;
116 case SIBState:
117 state = doSIBState(nextByte);
118 break;
119 case DisplacementState:
120 state = doDisplacementState();
121 break;
122 case ImmediateState:
123 state = doImmediateState();
124 break;
125 case ErrorState:
126 panic("Went to the error state in the predecoder.\n");
127 default:
128 panic("Unrecognized state! %d\n", state);
129 }
130 }
131 }
132
133 //Either get a prefix and record it in the ExtMachInst, or send the
134 //state machine on to get the opcode(s).
135 Predecoder::State Predecoder::doPrefixState(uint8_t nextByte)
136 {
137 uint8_t prefix = Prefixes[nextByte];
138 State nextState = PrefixState;
139 // REX prefixes are only recognized in 64 bit mode.
140 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode)
141 prefix = 0;
142 if (prefix)
143 consumeByte();
144 switch(prefix)
145 {
146 //Operand size override prefixes
147 case OperandSizeOverride:
148 DPRINTF(Predecoder, "Found operand size override prefix.\n");
149 emi.legacy.op = true;
150 break;
151 case AddressSizeOverride:
152 DPRINTF(Predecoder, "Found address size override prefix.\n");
153 emi.legacy.addr = true;
154 break;
155 //Segment override prefixes
156 case CSOverride:
157 case DSOverride:
158 case ESOverride:
159 case FSOverride:
160 case GSOverride:
161 case SSOverride:
162 DPRINTF(Predecoder, "Found segment override.\n");
163 emi.legacy.seg = prefix;
164 break;
165 case Lock:
166 DPRINTF(Predecoder, "Found lock prefix.\n");
167 emi.legacy.lock = true;
168 break;
169 case Rep:
170 DPRINTF(Predecoder, "Found rep prefix.\n");
171 emi.legacy.rep = true;
172 break;
173 case Repne:
174 DPRINTF(Predecoder, "Found repne prefix.\n");
175 emi.legacy.repne = true;
176 break;
177 case RexPrefix:
178 DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte);
179 emi.rex = nextByte;
180 break;
181 case 0:
182 nextState = OpcodeState;
183 break;
184 default:
185 panic("Unrecognized prefix %#x\n", nextByte);
186 }
187 return nextState;
188 }
189
190 //Load all the opcodes (currently up to 2) and then figure out
191 //what immediate and/or ModRM is needed.
192 Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte)
193 {
194 State nextState = ErrorState;
195 emi.opcode.num++;
196 //We can't handle 3+ byte opcodes right now
197 assert(emi.opcode.num < 3);
198 consumeByte();
199 if(emi.opcode.num == 1 && nextByte == 0x0f)
200 {
201 nextState = OpcodeState;
202 DPRINTF(Predecoder, "Found two byte opcode.\n");
203 emi.opcode.prefixA = nextByte;
204 }
205 else if(emi.opcode.num == 2 &&
206 (nextByte == 0x0f ||
207 (nextByte & 0xf8) == 0x38))
208 {
209 panic("Three byte opcodes aren't yet supported!\n");
210 nextState = OpcodeState;
211 DPRINTF(Predecoder, "Found three byte opcode.\n");
212 emi.opcode.prefixB = nextByte;
213 }
214 else
215 {
216 DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
217 emi.opcode.op = nextByte;
218
219 SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
220
221 //Figure out the effective operand size. This can be overriden to
222 //a fixed value at the decoder level.
223 int logOpSize;
224 if (emi.mode.submode == SixtyFourBitMode)
225 {
226 if(emi.rex.w)
227 logOpSize = 3; // 64 bit operand size
228 else if(emi.legacy.op)
229 logOpSize = 1; // 16 bit operand size
230 else
231 logOpSize = 2; // 32 bit operand size
232 }
233 else if(csAttr.defaultSize)
234 {
235 if(emi.legacy.op)
236 logOpSize = 1; // 16 bit operand size
237 else
238 logOpSize = 2; // 32 bit operand size
239 }
240 else // 16 bit default operand size
241 {
242 if(emi.legacy.op)
243 logOpSize = 2; // 32 bit operand size
244 else
245 logOpSize = 1; // 16 bit operand size
246 }
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.mode.submode == SixtyFourBitMode)
255 {
256 if(emi.legacy.addr)
257 logAddrSize = 2; // 32 bit address size
258 else
259 logAddrSize = 3; // 64 bit address size
260 }
261 else if(csAttr.defaultSize)
262 {
263 if(emi.legacy.addr)
264 logAddrSize = 1; // 16 bit address size
265 else
266 logAddrSize = 2; // 32 bit address size
267 }
268 else // 16 bit default operand size
269 {
270 if(emi.legacy.addr)
271 logAddrSize = 2; // 32 bit address size
272 else
273 logAddrSize = 1; // 16 bit address size
274 }
275
276 SegAttr ssAttr = tc->readMiscRegNoEffect(MISCREG_SS_ATTR);
277 //Figure out the effective stack width. This can be overriden to
278 //a fixed value at the decoder level.
279 if(emi.mode.submode == SixtyFourBitMode)
280 emi.stackSize = 8; // 64 bit stack width
281 else if(ssAttr.defaultSize)
282 emi.stackSize = 4; // 32 bit stack width
283 else
284 emi.stackSize = 2; // 16 bit stack width
285
286 //Set the actual address size
287 emi.addrSize = 1 << logAddrSize;
288
289 //Figure out how big of an immediate we'll retreive based
290 //on the opcode.
291 int immType = ImmediateType[emi.opcode.num - 1][nextByte];
292 if (emi.opcode.num == 1 && nextByte >= 0xA0 && nextByte <= 0xA3)
293 immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
294 else
295 immediateSize = SizeTypeToSize[logOpSize - 1][immType];
296
297 //Determine what to expect next
298 if (UsesModRM[emi.opcode.num - 1][nextByte]) {
299 nextState = ModRMState;
300 } else {
301 if(immediateSize) {
302 nextState = ImmediateState;
303 } else {
304 emiIsReady = true;
305 nextState = ResetState;
306 }
307 }
308 }
309 return nextState;
310 }
311
312 //Get the ModRM byte and determine what displacement, if any, there is.
313 //Also determine whether or not to get the SIB byte, displacement, or
314 //immediate next.
315 Predecoder::State Predecoder::doModRMState(uint8_t nextByte)
316 {
317 State nextState = ErrorState;
318 ModRM modRM;
319 modRM = nextByte;
320 DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
321 SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
322 if (emi.mode.submode != SixtyFourBitMode &&
323 !csAttr.defaultSize) {
324 //figure out 16 bit displacement size
325 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
326 displacementSize = 2;
327 else if (modRM.mod == 1)
328 displacementSize = 1;
329 else
330 displacementSize = 0;
331 } else {
332 //figure out 32/64 bit displacement size
333 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
334 displacementSize = 4;
335 else if (modRM.mod == 1)
336 displacementSize = 1;
337 else
338 displacementSize = 0;
339 }
340
341 // The "test" instruction in group 3 needs an immediate, even though
342 // the other instructions with the same actual opcode don't.
343 if (emi.opcode.num == 1 && (modRM.reg & 0x6) == 0) {
344 if (emi.opcode.op == 0xF6)
345 immediateSize = 1;
346 else if (emi.opcode.op == 0xF7)
347 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize;
348 }
349
350 //If there's an SIB, get that next.
351 //There is no SIB in 16 bit mode.
352 if (modRM.rm == 4 && modRM.mod != 3) {
353 // && in 32/64 bit mode)
354 nextState = SIBState;
355 } else if(displacementSize) {
356 nextState = DisplacementState;
357 } else if(immediateSize) {
358 nextState = ImmediateState;
359 } else {
360 emiIsReady = true;
361 nextState = ResetState;
362 }
363 //The ModRM byte is consumed no matter what
364 consumeByte();
365 emi.modRM = modRM;
366 return nextState;
367 }
368
369 //Get the SIB byte. We don't do anything with it at this point, other
370 //than storing it in the ExtMachInst. Determine if we need to get a
371 //displacement or immediate next.
372 Predecoder::State Predecoder::doSIBState(uint8_t nextByte)
373 {
374 State nextState = ErrorState;
375 emi.sib = nextByte;
376 DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
377 consumeByte();
378 if (emi.modRM.mod == 0 && emi.sib.base == 5)
379 displacementSize = 4;
380 if (displacementSize) {
381 nextState = DisplacementState;
382 } else if(immediateSize) {
383 nextState = ImmediateState;
384 } else {
385 emiIsReady = true;
386 nextState = ResetState;
387 }
388 return nextState;
389 }
390
391 //Gather up the displacement, or at least as much of it
392 //as we can get.
393 Predecoder::State Predecoder::doDisplacementState()
394 {
395 State nextState = ErrorState;
396
397 getImmediate(immediateCollected,
398 emi.displacement,
399 displacementSize);
400
401 DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
402 displacementSize, immediateCollected);
403
404 if(displacementSize == immediateCollected) {
405 //Reset this for other immediates.
406 immediateCollected = 0;
407 //Sign extend the displacement
408 switch(displacementSize)
409 {
410 case 1:
411 emi.displacement = sext<8>(emi.displacement);
412 break;
413 case 2:
414 emi.displacement = sext<16>(emi.displacement);
415 break;
416 case 4:
417 emi.displacement = sext<32>(emi.displacement);
418 break;
419 default:
420 panic("Undefined displacement size!\n");
421 }
422 DPRINTF(Predecoder, "Collected displacement %#x.\n",
423 emi.displacement);
424 if(immediateSize) {
425 nextState = ImmediateState;
426 } else {
427 emiIsReady = true;
428 nextState = ResetState;
429 }
430 }
431 else
432 nextState = DisplacementState;
433 return nextState;
434 }
435
436 //Gather up the immediate, or at least as much of it
437 //as we can get
438 Predecoder::State Predecoder::doImmediateState()
439 {
440 State nextState = ErrorState;
441
442 getImmediate(immediateCollected,
443 emi.immediate,
444 immediateSize);
445
446 DPRINTF(Predecoder, "Collecting %d byte immediate, got %d bytes.\n",
447 immediateSize, immediateCollected);
448
449 if(immediateSize == immediateCollected)
450 {
451 //Reset this for other immediates.
452 immediateCollected = 0;
453
454 //XXX Warning! The following is an observed pattern and might
455 //not always be true!
456
457 //Instructions which use 64 bit operands but 32 bit immediates
458 //need to have the immediate sign extended to 64 bits.
459 //Instructions which use true 64 bit immediates won't be
460 //affected, and instructions that use true 32 bit immediates
461 //won't notice.
462 switch(immediateSize)
463 {
464 case 4:
465 emi.immediate = sext<32>(emi.immediate);
466 break;
467 case 1:
468 emi.immediate = sext<8>(emi.immediate);
469 }
470
471 DPRINTF(Predecoder, "Collected immediate %#x.\n",
472 emi.immediate);
473 emiIsReady = true;
474 nextState = ResetState;
475 }
476 else
477 nextState = ImmediateState;
478 return nextState;
479 }
480 }