decoder.cc (12045:31d9a81ba286) decoder.cc (12229:932ed6601823)
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
33#include "arch/x86/regs/misc.hh"
34#include "base/misc.hh"
35#include "base/trace.hh"
36#include "base/types.hh"
37#include "debug/Decoder.hh"
38
39namespace X86ISA
40{
41
42Decoder::State
43Decoder::doResetState()
44{
45 origPC = basePC + offset;
46 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC);
47 instBytes = &decodePages->lookup(origPC);
48 chunkIdx = 0;
49
50 emi.rex = 0;
51 emi.legacy = 0;
52 emi.vex = 0;
53
54 emi.opcode.type = BadOpcode;
55 emi.opcode.op = 0;
56
57 immediateCollected = 0;
58 emi.immediate = 0;
59 emi.displacement = 0;
60 emi.dispSize = 0;
61
62 emi.modRM = 0;
63 emi.sib = 0;
64
65 if (instBytes->si) {
66 return FromCacheState;
67 } else {
68 instBytes->chunks.clear();
69 return PrefixState;
70 }
71}
72
73void
74Decoder::process()
75{
76 //This function drives the decoder state machine.
77
78 //Some sanity checks. You shouldn't try to process more bytes if
79 //there aren't any, and you shouldn't overwrite an already
80 //decoder ExtMachInst.
81 assert(!outOfBytes);
82 assert(!instDone);
83
84 if (state == ResetState)
85 state = doResetState();
86 if (state == FromCacheState) {
87 state = doFromCacheState();
88 } else {
89 instBytes->chunks.push_back(fetchChunk);
90 }
91
92 //While there's still something to do...
93 while (!instDone && !outOfBytes) {
94 uint8_t nextByte = getNextByte();
95 switch (state) {
96 case PrefixState:
97 state = doPrefixState(nextByte);
98 break;
99 case Vex2Of2State:
100 state = doVex2Of2State(nextByte);
101 break;
102 case Vex2Of3State:
103 state = doVex2Of3State(nextByte);
104 break;
105 case Vex3Of3State:
106 state = doVex3Of3State(nextByte);
107 break;
108 case VexOpcodeState:
109 state = doVexOpcodeState(nextByte);
110 break;
111 case OneByteOpcodeState:
112 state = doOneByteOpcodeState(nextByte);
113 break;
114 case TwoByteOpcodeState:
115 state = doTwoByteOpcodeState(nextByte);
116 break;
117 case ThreeByte0F38OpcodeState:
118 state = doThreeByte0F38OpcodeState(nextByte);
119 break;
120 case ThreeByte0F3AOpcodeState:
121 state = doThreeByte0F3AOpcodeState(nextByte);
122 break;
123 case ModRMState:
124 state = doModRMState(nextByte);
125 break;
126 case SIBState:
127 state = doSIBState(nextByte);
128 break;
129 case DisplacementState:
130 state = doDisplacementState();
131 break;
132 case ImmediateState:
133 state = doImmediateState();
134 break;
135 case ErrorState:
136 panic("Went to the error state in the decoder.\n");
137 default:
138 panic("Unrecognized state! %d\n", state);
139 }
140 }
141}
142
143Decoder::State
144Decoder::doFromCacheState()
145{
146 DPRINTF(Decoder, "Looking at cache state.\n");
147 if ((fetchChunk & instBytes->masks[chunkIdx]) !=
148 instBytes->chunks[chunkIdx]) {
149 DPRINTF(Decoder, "Decode cache miss.\n");
150 // The chached chunks didn't match what was fetched. Fall back to the
151 // predecoder.
152 instBytes->chunks[chunkIdx] = fetchChunk;
153 instBytes->chunks.resize(chunkIdx + 1);
154 instBytes->si = NULL;
155 chunkIdx = 0;
156 fetchChunk = instBytes->chunks[0];
157 offset = origPC % sizeof(MachInst);
158 basePC = origPC - offset;
159 return PrefixState;
160 } else if (chunkIdx == instBytes->chunks.size() - 1) {
161 // We matched the cache, so use its value.
162 instDone = true;
163 offset = instBytes->lastOffset;
164 if (offset == sizeof(MachInst))
165 outOfBytes = true;
166 return ResetState;
167 } else {
168 // We matched so far, but need to check more chunks.
169 chunkIdx++;
170 outOfBytes = true;
171 return FromCacheState;
172 }
173}
174
175//Either get a prefix and record it in the ExtMachInst, or send the
176//state machine on to get the opcode(s).
177Decoder::State
178Decoder::doPrefixState(uint8_t nextByte)
179{
180 uint8_t prefix = Prefixes[nextByte];
181 State nextState = PrefixState;
182 // REX prefixes are only recognized in 64 bit mode.
183 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode)
184 prefix = 0;
185 if (prefix)
186 consumeByte();
187 switch(prefix)
188 {
189 //Operand size override prefixes
190 case OperandSizeOverride:
191 DPRINTF(Decoder, "Found operand size override prefix.\n");
192 emi.legacy.op = true;
193 break;
194 case AddressSizeOverride:
195 DPRINTF(Decoder, "Found address size override prefix.\n");
196 emi.legacy.addr = true;
197 break;
198 //Segment override prefixes
199 case CSOverride:
200 case DSOverride:
201 case ESOverride:
202 case FSOverride:
203 case GSOverride:
204 case SSOverride:
205 DPRINTF(Decoder, "Found segment override.\n");
206 emi.legacy.seg = prefix;
207 break;
208 case Lock:
209 DPRINTF(Decoder, "Found lock prefix.\n");
210 emi.legacy.lock = true;
211 break;
212 case Rep:
213 DPRINTF(Decoder, "Found rep prefix.\n");
214 emi.legacy.rep = true;
215 break;
216 case Repne:
217 DPRINTF(Decoder, "Found repne prefix.\n");
218 emi.legacy.repne = true;
219 break;
220 case RexPrefix:
221 DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte);
222 emi.rex = nextByte;
223 break;
224 case Vex2Prefix:
225 DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte);
226 emi.vex.present = 1;
227 nextState = Vex2Of2State;
228 break;
229 case Vex3Prefix:
230 DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte);
231 emi.vex.present = 1;
232 nextState = Vex2Of3State;
233 break;
234 case 0:
235 nextState = OneByteOpcodeState;
236 break;
237
238 default:
239 panic("Unrecognized prefix %#x\n", nextByte);
240 }
241 return nextState;
242}
243
244Decoder::State
245Decoder::doVex2Of2State(uint8_t nextByte)
246{
247 consumeByte();
248 Vex2Of2 vex = nextByte;
249
250 emi.rex.r = !vex.r;
251
252 emi.vex.l = vex.l;
253 emi.vex.v = ~vex.v;
254
255 switch (vex.p) {
256 case 0:
257 break;
258 case 1:
259 emi.legacy.op = 1;
260 break;
261 case 2:
262 emi.legacy.rep = 1;
263 break;
264 case 3:
265 emi.legacy.repne = 1;
266 break;
267 }
268
269 emi.opcode.type = TwoByteOpcode;
270
271 return VexOpcodeState;
272}
273
274Decoder::State
275Decoder::doVex2Of3State(uint8_t nextByte)
276{
277 if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) {
278 // This was actually an LDS instruction. Reroute to that path.
279 emi.vex.present = 0;
280 emi.opcode.type = OneByteOpcode;
281 emi.opcode.op = 0xC4;
282 return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
283 nextByte >= 0xA0 && nextByte <= 0xA3);
284 }
285
286 consumeByte();
287 Vex2Of3 vex = nextByte;
288
289 emi.rex.r = !vex.r;
290 emi.rex.x = !vex.x;
291 emi.rex.b = !vex.b;
292
293 switch (vex.m) {
294 case 1:
295 emi.opcode.type = TwoByteOpcode;
296 break;
297 case 2:
298 emi.opcode.type = ThreeByte0F38Opcode;
299 break;
300 case 3:
301 emi.opcode.type = ThreeByte0F3AOpcode;
302 break;
303 default:
304 // These encodings are reserved. Pretend this was an undefined
305 // instruction so the main decoder will behave correctly, and stop
306 // trying to interpret bytes.
307 emi.opcode.type = TwoByteOpcode;
308 emi.opcode.op = 0x0B;
309 instDone = true;
310 return ResetState;
311 }
312 return Vex3Of3State;
313}
314
315Decoder::State
316Decoder::doVex3Of3State(uint8_t nextByte)
317{
318 if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) {
319 // This was actually an LES instruction. Reroute to that path.
320 emi.vex.present = 0;
321 emi.opcode.type = OneByteOpcode;
322 emi.opcode.op = 0xC5;
323 return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
324 nextByte >= 0xA0 && nextByte <= 0xA3);
325 }
326
327 consumeByte();
328 Vex3Of3 vex = nextByte;
329
330 emi.rex.w = vex.w;
331
332 emi.vex.l = vex.l;
333 emi.vex.v = ~vex.v;
334
335 switch (vex.p) {
336 case 0:
337 break;
338 case 1:
339 emi.legacy.op = 1;
340 break;
341 case 2:
342 emi.legacy.rep = 1;
343 break;
344 case 3:
345 emi.legacy.repne = 1;
346 break;
347 }
348
349 return VexOpcodeState;
350}
351
352Decoder::State
353Decoder::doVexOpcodeState(uint8_t nextByte)
354{
355 DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte);
356
357 emi.opcode.op = nextByte;
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
33#include "arch/x86/regs/misc.hh"
34#include "base/misc.hh"
35#include "base/trace.hh"
36#include "base/types.hh"
37#include "debug/Decoder.hh"
38
39namespace X86ISA
40{
41
42Decoder::State
43Decoder::doResetState()
44{
45 origPC = basePC + offset;
46 DPRINTF(Decoder, "Setting origPC to %#x\n", origPC);
47 instBytes = &decodePages->lookup(origPC);
48 chunkIdx = 0;
49
50 emi.rex = 0;
51 emi.legacy = 0;
52 emi.vex = 0;
53
54 emi.opcode.type = BadOpcode;
55 emi.opcode.op = 0;
56
57 immediateCollected = 0;
58 emi.immediate = 0;
59 emi.displacement = 0;
60 emi.dispSize = 0;
61
62 emi.modRM = 0;
63 emi.sib = 0;
64
65 if (instBytes->si) {
66 return FromCacheState;
67 } else {
68 instBytes->chunks.clear();
69 return PrefixState;
70 }
71}
72
73void
74Decoder::process()
75{
76 //This function drives the decoder state machine.
77
78 //Some sanity checks. You shouldn't try to process more bytes if
79 //there aren't any, and you shouldn't overwrite an already
80 //decoder ExtMachInst.
81 assert(!outOfBytes);
82 assert(!instDone);
83
84 if (state == ResetState)
85 state = doResetState();
86 if (state == FromCacheState) {
87 state = doFromCacheState();
88 } else {
89 instBytes->chunks.push_back(fetchChunk);
90 }
91
92 //While there's still something to do...
93 while (!instDone && !outOfBytes) {
94 uint8_t nextByte = getNextByte();
95 switch (state) {
96 case PrefixState:
97 state = doPrefixState(nextByte);
98 break;
99 case Vex2Of2State:
100 state = doVex2Of2State(nextByte);
101 break;
102 case Vex2Of3State:
103 state = doVex2Of3State(nextByte);
104 break;
105 case Vex3Of3State:
106 state = doVex3Of3State(nextByte);
107 break;
108 case VexOpcodeState:
109 state = doVexOpcodeState(nextByte);
110 break;
111 case OneByteOpcodeState:
112 state = doOneByteOpcodeState(nextByte);
113 break;
114 case TwoByteOpcodeState:
115 state = doTwoByteOpcodeState(nextByte);
116 break;
117 case ThreeByte0F38OpcodeState:
118 state = doThreeByte0F38OpcodeState(nextByte);
119 break;
120 case ThreeByte0F3AOpcodeState:
121 state = doThreeByte0F3AOpcodeState(nextByte);
122 break;
123 case ModRMState:
124 state = doModRMState(nextByte);
125 break;
126 case SIBState:
127 state = doSIBState(nextByte);
128 break;
129 case DisplacementState:
130 state = doDisplacementState();
131 break;
132 case ImmediateState:
133 state = doImmediateState();
134 break;
135 case ErrorState:
136 panic("Went to the error state in the decoder.\n");
137 default:
138 panic("Unrecognized state! %d\n", state);
139 }
140 }
141}
142
143Decoder::State
144Decoder::doFromCacheState()
145{
146 DPRINTF(Decoder, "Looking at cache state.\n");
147 if ((fetchChunk & instBytes->masks[chunkIdx]) !=
148 instBytes->chunks[chunkIdx]) {
149 DPRINTF(Decoder, "Decode cache miss.\n");
150 // The chached chunks didn't match what was fetched. Fall back to the
151 // predecoder.
152 instBytes->chunks[chunkIdx] = fetchChunk;
153 instBytes->chunks.resize(chunkIdx + 1);
154 instBytes->si = NULL;
155 chunkIdx = 0;
156 fetchChunk = instBytes->chunks[0];
157 offset = origPC % sizeof(MachInst);
158 basePC = origPC - offset;
159 return PrefixState;
160 } else if (chunkIdx == instBytes->chunks.size() - 1) {
161 // We matched the cache, so use its value.
162 instDone = true;
163 offset = instBytes->lastOffset;
164 if (offset == sizeof(MachInst))
165 outOfBytes = true;
166 return ResetState;
167 } else {
168 // We matched so far, but need to check more chunks.
169 chunkIdx++;
170 outOfBytes = true;
171 return FromCacheState;
172 }
173}
174
175//Either get a prefix and record it in the ExtMachInst, or send the
176//state machine on to get the opcode(s).
177Decoder::State
178Decoder::doPrefixState(uint8_t nextByte)
179{
180 uint8_t prefix = Prefixes[nextByte];
181 State nextState = PrefixState;
182 // REX prefixes are only recognized in 64 bit mode.
183 if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode)
184 prefix = 0;
185 if (prefix)
186 consumeByte();
187 switch(prefix)
188 {
189 //Operand size override prefixes
190 case OperandSizeOverride:
191 DPRINTF(Decoder, "Found operand size override prefix.\n");
192 emi.legacy.op = true;
193 break;
194 case AddressSizeOverride:
195 DPRINTF(Decoder, "Found address size override prefix.\n");
196 emi.legacy.addr = true;
197 break;
198 //Segment override prefixes
199 case CSOverride:
200 case DSOverride:
201 case ESOverride:
202 case FSOverride:
203 case GSOverride:
204 case SSOverride:
205 DPRINTF(Decoder, "Found segment override.\n");
206 emi.legacy.seg = prefix;
207 break;
208 case Lock:
209 DPRINTF(Decoder, "Found lock prefix.\n");
210 emi.legacy.lock = true;
211 break;
212 case Rep:
213 DPRINTF(Decoder, "Found rep prefix.\n");
214 emi.legacy.rep = true;
215 break;
216 case Repne:
217 DPRINTF(Decoder, "Found repne prefix.\n");
218 emi.legacy.repne = true;
219 break;
220 case RexPrefix:
221 DPRINTF(Decoder, "Found Rex prefix %#x.\n", nextByte);
222 emi.rex = nextByte;
223 break;
224 case Vex2Prefix:
225 DPRINTF(Decoder, "Found VEX two-byte prefix %#x.\n", nextByte);
226 emi.vex.present = 1;
227 nextState = Vex2Of2State;
228 break;
229 case Vex3Prefix:
230 DPRINTF(Decoder, "Found VEX three-byte prefix %#x.\n", nextByte);
231 emi.vex.present = 1;
232 nextState = Vex2Of3State;
233 break;
234 case 0:
235 nextState = OneByteOpcodeState;
236 break;
237
238 default:
239 panic("Unrecognized prefix %#x\n", nextByte);
240 }
241 return nextState;
242}
243
244Decoder::State
245Decoder::doVex2Of2State(uint8_t nextByte)
246{
247 consumeByte();
248 Vex2Of2 vex = nextByte;
249
250 emi.rex.r = !vex.r;
251
252 emi.vex.l = vex.l;
253 emi.vex.v = ~vex.v;
254
255 switch (vex.p) {
256 case 0:
257 break;
258 case 1:
259 emi.legacy.op = 1;
260 break;
261 case 2:
262 emi.legacy.rep = 1;
263 break;
264 case 3:
265 emi.legacy.repne = 1;
266 break;
267 }
268
269 emi.opcode.type = TwoByteOpcode;
270
271 return VexOpcodeState;
272}
273
274Decoder::State
275Decoder::doVex2Of3State(uint8_t nextByte)
276{
277 if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) {
278 // This was actually an LDS instruction. Reroute to that path.
279 emi.vex.present = 0;
280 emi.opcode.type = OneByteOpcode;
281 emi.opcode.op = 0xC4;
282 return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
283 nextByte >= 0xA0 && nextByte <= 0xA3);
284 }
285
286 consumeByte();
287 Vex2Of3 vex = nextByte;
288
289 emi.rex.r = !vex.r;
290 emi.rex.x = !vex.x;
291 emi.rex.b = !vex.b;
292
293 switch (vex.m) {
294 case 1:
295 emi.opcode.type = TwoByteOpcode;
296 break;
297 case 2:
298 emi.opcode.type = ThreeByte0F38Opcode;
299 break;
300 case 3:
301 emi.opcode.type = ThreeByte0F3AOpcode;
302 break;
303 default:
304 // These encodings are reserved. Pretend this was an undefined
305 // instruction so the main decoder will behave correctly, and stop
306 // trying to interpret bytes.
307 emi.opcode.type = TwoByteOpcode;
308 emi.opcode.op = 0x0B;
309 instDone = true;
310 return ResetState;
311 }
312 return Vex3Of3State;
313}
314
315Decoder::State
316Decoder::doVex3Of3State(uint8_t nextByte)
317{
318 if (emi.mode.submode != SixtyFourBitMode && bits(nextByte, 7, 6) == 0x3) {
319 // This was actually an LES instruction. Reroute to that path.
320 emi.vex.present = 0;
321 emi.opcode.type = OneByteOpcode;
322 emi.opcode.op = 0xC5;
323 return processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
324 nextByte >= 0xA0 && nextByte <= 0xA3);
325 }
326
327 consumeByte();
328 Vex3Of3 vex = nextByte;
329
330 emi.rex.w = vex.w;
331
332 emi.vex.l = vex.l;
333 emi.vex.v = ~vex.v;
334
335 switch (vex.p) {
336 case 0:
337 break;
338 case 1:
339 emi.legacy.op = 1;
340 break;
341 case 2:
342 emi.legacy.rep = 1;
343 break;
344 case 3:
345 emi.legacy.repne = 1;
346 break;
347 }
348
349 return VexOpcodeState;
350}
351
352Decoder::State
353Decoder::doVexOpcodeState(uint8_t nextByte)
354{
355 DPRINTF(Decoder, "Found VEX opcode %#x.\n", nextByte);
356
357 emi.opcode.op = nextByte;
358 consumeByte();
358
359 switch (emi.opcode.type) {
360 case TwoByteOpcode:
361 return processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
362 case ThreeByte0F38Opcode:
363 return processOpcode(ImmediateTypeThreeByte0F38,
364 UsesModRMThreeByte0F38);
365 case ThreeByte0F3AOpcode:
366 return processOpcode(ImmediateTypeThreeByte0F3A,
367 UsesModRMThreeByte0F3A);
368 default:
369 panic("Unrecognized opcode type %d.\n", emi.opcode.type);
370 }
371}
372
373// Load the first opcode byte. Determine if there are more opcode bytes, and
374// if not, what immediate and/or ModRM is needed.
375Decoder::State
376Decoder::doOneByteOpcodeState(uint8_t nextByte)
377{
378 State nextState = ErrorState;
379 consumeByte();
380
381 if (nextByte == 0x0f) {
382 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
383 nextState = TwoByteOpcodeState;
384 } else {
385 DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte);
386 emi.opcode.type = OneByteOpcode;
387 emi.opcode.op = nextByte;
388
389 nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
390 nextByte >= 0xA0 && nextByte <= 0xA3);
391 }
392 return nextState;
393}
394
395// Load the second opcode byte. Determine if there are more opcode bytes, and
396// if not, what immediate and/or ModRM is needed.
397Decoder::State
398Decoder::doTwoByteOpcodeState(uint8_t nextByte)
399{
400 State nextState = ErrorState;
401 consumeByte();
402 if (nextByte == 0x38) {
403 nextState = ThreeByte0F38OpcodeState;
404 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
405 } else if (nextByte == 0x3a) {
406 nextState = ThreeByte0F3AOpcodeState;
407 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
408 } else {
409 DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte);
410 emi.opcode.type = TwoByteOpcode;
411 emi.opcode.op = nextByte;
412
413 nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
414 }
415 return nextState;
416}
417
418// Load the third opcode byte and determine what immediate and/or ModRM is
419// needed.
420Decoder::State
421Decoder::doThreeByte0F38OpcodeState(uint8_t nextByte)
422{
423 consumeByte();
424
425 DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte);
426 emi.opcode.type = ThreeByte0F38Opcode;
427 emi.opcode.op = nextByte;
428
429 return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38);
430}
431
432// Load the third opcode byte and determine what immediate and/or ModRM is
433// needed.
434Decoder::State
435Decoder::doThreeByte0F3AOpcodeState(uint8_t nextByte)
436{
437 consumeByte();
438
439 DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte);
440 emi.opcode.type = ThreeByte0F3AOpcode;
441 emi.opcode.op = nextByte;
442
443 return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A);
444}
445
446// Generic opcode processing which determines the immediate size, and whether
447// or not there's a modrm byte.
448Decoder::State
449Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable,
450 bool addrSizedImm)
451{
452 State nextState = ErrorState;
453 const uint8_t opcode = emi.opcode.op;
454
455 //Figure out the effective operand size. This can be overriden to
456 //a fixed value at the decoder level.
457 int logOpSize;
458 if (emi.rex.w)
459 logOpSize = 3; // 64 bit operand size
460 else if (emi.legacy.op)
461 logOpSize = altOp;
462 else
463 logOpSize = defOp;
464
465 //Set the actual op size
466 emi.opSize = 1 << logOpSize;
467
468 //Figure out the effective address size. This can be overriden to
469 //a fixed value at the decoder level.
470 int logAddrSize;
471 if (emi.legacy.addr)
472 logAddrSize = altAddr;
473 else
474 logAddrSize = defAddr;
475
476 //Set the actual address size
477 emi.addrSize = 1 << logAddrSize;
478
479 //Figure out the effective stack width. This can be overriden to
480 //a fixed value at the decoder level.
481 emi.stackSize = 1 << stack;
482
483 //Figure out how big of an immediate we'll retreive based
484 //on the opcode.
485 int immType = immTable[opcode];
486 if (addrSizedImm)
487 immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
488 else
489 immediateSize = SizeTypeToSize[logOpSize - 1][immType];
490
491 //Determine what to expect next
492 if (modrmTable[opcode]) {
493 nextState = ModRMState;
494 } else {
495 if (immediateSize) {
496 nextState = ImmediateState;
497 } else {
498 instDone = true;
499 nextState = ResetState;
500 }
501 }
502 return nextState;
503}
504
505//Get the ModRM byte and determine what displacement, if any, there is.
506//Also determine whether or not to get the SIB byte, displacement, or
507//immediate next.
508Decoder::State
509Decoder::doModRMState(uint8_t nextByte)
510{
511 State nextState = ErrorState;
512 ModRM modRM = nextByte;
513 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte);
514 if (defOp == 1) {
515 //figure out 16 bit displacement size
516 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
517 displacementSize = 2;
518 else if (modRM.mod == 1)
519 displacementSize = 1;
520 else
521 displacementSize = 0;
522 } else {
523 //figure out 32/64 bit displacement size
524 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
525 displacementSize = 4;
526 else if (modRM.mod == 1)
527 displacementSize = 1;
528 else
529 displacementSize = 0;
530 }
531
532 // The "test" instruction in group 3 needs an immediate, even though
533 // the other instructions with the same actual opcode don't.
534 if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) {
535 if (emi.opcode.op == 0xF6)
536 immediateSize = 1;
537 else if (emi.opcode.op == 0xF7)
538 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize;
539 }
540
541 //If there's an SIB, get that next.
542 //There is no SIB in 16 bit mode.
543 if (modRM.rm == 4 && modRM.mod != 3) {
544 // && in 32/64 bit mode)
545 nextState = SIBState;
546 } else if (displacementSize) {
547 nextState = DisplacementState;
548 } else if (immediateSize) {
549 nextState = ImmediateState;
550 } else {
551 instDone = true;
552 nextState = ResetState;
553 }
554 //The ModRM byte is consumed no matter what
555 consumeByte();
556 emi.modRM = modRM;
557 return nextState;
558}
559
560//Get the SIB byte. We don't do anything with it at this point, other
561//than storing it in the ExtMachInst. Determine if we need to get a
562//displacement or immediate next.
563Decoder::State
564Decoder::doSIBState(uint8_t nextByte)
565{
566 State nextState = ErrorState;
567 emi.sib = nextByte;
568 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte);
569 consumeByte();
570 if (emi.modRM.mod == 0 && emi.sib.base == 5)
571 displacementSize = 4;
572 if (displacementSize) {
573 nextState = DisplacementState;
574 } else if (immediateSize) {
575 nextState = ImmediateState;
576 } else {
577 instDone = true;
578 nextState = ResetState;
579 }
580 return nextState;
581}
582
583//Gather up the displacement, or at least as much of it
584//as we can get.
585Decoder::State
586Decoder::doDisplacementState()
587{
588 State nextState = ErrorState;
589
590 getImmediate(immediateCollected,
591 emi.displacement,
592 displacementSize);
593
594 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n",
595 displacementSize, immediateCollected);
596
597 if (displacementSize == immediateCollected) {
598 //Reset this for other immediates.
599 immediateCollected = 0;
600 //Sign extend the displacement
601 switch(displacementSize)
602 {
603 case 1:
604 emi.displacement = sext<8>(emi.displacement);
605 break;
606 case 2:
607 emi.displacement = sext<16>(emi.displacement);
608 break;
609 case 4:
610 emi.displacement = sext<32>(emi.displacement);
611 break;
612 default:
613 panic("Undefined displacement size!\n");
614 }
615 DPRINTF(Decoder, "Collected displacement %#x.\n",
616 emi.displacement);
617 if (immediateSize) {
618 nextState = ImmediateState;
619 } else {
620 instDone = true;
621 nextState = ResetState;
622 }
623
624 emi.dispSize = displacementSize;
625 }
626 else
627 nextState = DisplacementState;
628 return nextState;
629}
630
631//Gather up the immediate, or at least as much of it
632//as we can get
633Decoder::State
634Decoder::doImmediateState()
635{
636 State nextState = ErrorState;
637
638 getImmediate(immediateCollected,
639 emi.immediate,
640 immediateSize);
641
642 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n",
643 immediateSize, immediateCollected);
644
645 if (immediateSize == immediateCollected)
646 {
647 //Reset this for other immediates.
648 immediateCollected = 0;
649
650 //XXX Warning! The following is an observed pattern and might
651 //not always be true!
652
653 //Instructions which use 64 bit operands but 32 bit immediates
654 //need to have the immediate sign extended to 64 bits.
655 //Instructions which use true 64 bit immediates won't be
656 //affected, and instructions that use true 32 bit immediates
657 //won't notice.
658 switch(immediateSize)
659 {
660 case 4:
661 emi.immediate = sext<32>(emi.immediate);
662 break;
663 case 1:
664 emi.immediate = sext<8>(emi.immediate);
665 }
666
667 DPRINTF(Decoder, "Collected immediate %#x.\n",
668 emi.immediate);
669 instDone = true;
670 nextState = ResetState;
671 }
672 else
673 nextState = ImmediateState;
674 return nextState;
675}
676
677Decoder::InstBytes Decoder::dummy;
678Decoder::InstCacheMap Decoder::instCacheMap;
679
680StaticInstPtr
681Decoder::decode(ExtMachInst mach_inst, Addr addr)
682{
683 DecodeCache::InstMap::iterator iter = instMap->find(mach_inst);
684 if (iter != instMap->end())
685 return iter->second;
686
687 StaticInstPtr si = decodeInst(mach_inst);
688 (*instMap)[mach_inst] = si;
689 return si;
690}
691
692StaticInstPtr
693Decoder::decode(PCState &nextPC)
694{
695 if (!instDone)
696 return NULL;
697 instDone = false;
698 updateNPC(nextPC);
699
700 StaticInstPtr &si = instBytes->si;
701 if (si)
702 return si;
703
704 // We didn't match in the AddrMap, but we still populated an entry. Fix
705 // up its byte masks.
706 const int chunkSize = sizeof(MachInst);
707
708 instBytes->lastOffset = offset;
709
710 Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize;
711 Addr firstOffset = origPC - firstBasePC;
712 Addr totalSize = instBytes->lastOffset - firstOffset +
713 (instBytes->chunks.size() - 1) * chunkSize;
714 int start = firstOffset;
715 instBytes->masks.clear();
716
717 while (totalSize) {
718 int end = start + totalSize;
719 end = (chunkSize < end) ? chunkSize : end;
720 int size = end - start;
721 int idx = instBytes->masks.size();
722
723 MachInst maskVal = mask(size * 8) << (start * 8);
724 assert(maskVal);
725
726 instBytes->masks.push_back(maskVal);
727 instBytes->chunks[idx] &= instBytes->masks[idx];
728 totalSize -= size;
729 start = 0;
730 }
731
732 si = decode(emi, origPC);
733 return si;
734}
735
736}
359
360 switch (emi.opcode.type) {
361 case TwoByteOpcode:
362 return processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
363 case ThreeByte0F38Opcode:
364 return processOpcode(ImmediateTypeThreeByte0F38,
365 UsesModRMThreeByte0F38);
366 case ThreeByte0F3AOpcode:
367 return processOpcode(ImmediateTypeThreeByte0F3A,
368 UsesModRMThreeByte0F3A);
369 default:
370 panic("Unrecognized opcode type %d.\n", emi.opcode.type);
371 }
372}
373
374// Load the first opcode byte. Determine if there are more opcode bytes, and
375// if not, what immediate and/or ModRM is needed.
376Decoder::State
377Decoder::doOneByteOpcodeState(uint8_t nextByte)
378{
379 State nextState = ErrorState;
380 consumeByte();
381
382 if (nextByte == 0x0f) {
383 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
384 nextState = TwoByteOpcodeState;
385 } else {
386 DPRINTF(Decoder, "Found one byte opcode %#x.\n", nextByte);
387 emi.opcode.type = OneByteOpcode;
388 emi.opcode.op = nextByte;
389
390 nextState = processOpcode(ImmediateTypeOneByte, UsesModRMOneByte,
391 nextByte >= 0xA0 && nextByte <= 0xA3);
392 }
393 return nextState;
394}
395
396// Load the second opcode byte. Determine if there are more opcode bytes, and
397// if not, what immediate and/or ModRM is needed.
398Decoder::State
399Decoder::doTwoByteOpcodeState(uint8_t nextByte)
400{
401 State nextState = ErrorState;
402 consumeByte();
403 if (nextByte == 0x38) {
404 nextState = ThreeByte0F38OpcodeState;
405 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
406 } else if (nextByte == 0x3a) {
407 nextState = ThreeByte0F3AOpcodeState;
408 DPRINTF(Decoder, "Found opcode escape byte %#x.\n", nextByte);
409 } else {
410 DPRINTF(Decoder, "Found two byte opcode %#x.\n", nextByte);
411 emi.opcode.type = TwoByteOpcode;
412 emi.opcode.op = nextByte;
413
414 nextState = processOpcode(ImmediateTypeTwoByte, UsesModRMTwoByte);
415 }
416 return nextState;
417}
418
419// Load the third opcode byte and determine what immediate and/or ModRM is
420// needed.
421Decoder::State
422Decoder::doThreeByte0F38OpcodeState(uint8_t nextByte)
423{
424 consumeByte();
425
426 DPRINTF(Decoder, "Found three byte 0F38 opcode %#x.\n", nextByte);
427 emi.opcode.type = ThreeByte0F38Opcode;
428 emi.opcode.op = nextByte;
429
430 return processOpcode(ImmediateTypeThreeByte0F38, UsesModRMThreeByte0F38);
431}
432
433// Load the third opcode byte and determine what immediate and/or ModRM is
434// needed.
435Decoder::State
436Decoder::doThreeByte0F3AOpcodeState(uint8_t nextByte)
437{
438 consumeByte();
439
440 DPRINTF(Decoder, "Found three byte 0F3A opcode %#x.\n", nextByte);
441 emi.opcode.type = ThreeByte0F3AOpcode;
442 emi.opcode.op = nextByte;
443
444 return processOpcode(ImmediateTypeThreeByte0F3A, UsesModRMThreeByte0F3A);
445}
446
447// Generic opcode processing which determines the immediate size, and whether
448// or not there's a modrm byte.
449Decoder::State
450Decoder::processOpcode(ByteTable &immTable, ByteTable &modrmTable,
451 bool addrSizedImm)
452{
453 State nextState = ErrorState;
454 const uint8_t opcode = emi.opcode.op;
455
456 //Figure out the effective operand size. This can be overriden to
457 //a fixed value at the decoder level.
458 int logOpSize;
459 if (emi.rex.w)
460 logOpSize = 3; // 64 bit operand size
461 else if (emi.legacy.op)
462 logOpSize = altOp;
463 else
464 logOpSize = defOp;
465
466 //Set the actual op size
467 emi.opSize = 1 << logOpSize;
468
469 //Figure out the effective address size. This can be overriden to
470 //a fixed value at the decoder level.
471 int logAddrSize;
472 if (emi.legacy.addr)
473 logAddrSize = altAddr;
474 else
475 logAddrSize = defAddr;
476
477 //Set the actual address size
478 emi.addrSize = 1 << logAddrSize;
479
480 //Figure out the effective stack width. This can be overriden to
481 //a fixed value at the decoder level.
482 emi.stackSize = 1 << stack;
483
484 //Figure out how big of an immediate we'll retreive based
485 //on the opcode.
486 int immType = immTable[opcode];
487 if (addrSizedImm)
488 immediateSize = SizeTypeToSize[logAddrSize - 1][immType];
489 else
490 immediateSize = SizeTypeToSize[logOpSize - 1][immType];
491
492 //Determine what to expect next
493 if (modrmTable[opcode]) {
494 nextState = ModRMState;
495 } else {
496 if (immediateSize) {
497 nextState = ImmediateState;
498 } else {
499 instDone = true;
500 nextState = ResetState;
501 }
502 }
503 return nextState;
504}
505
506//Get the ModRM byte and determine what displacement, if any, there is.
507//Also determine whether or not to get the SIB byte, displacement, or
508//immediate next.
509Decoder::State
510Decoder::doModRMState(uint8_t nextByte)
511{
512 State nextState = ErrorState;
513 ModRM modRM = nextByte;
514 DPRINTF(Decoder, "Found modrm byte %#x.\n", nextByte);
515 if (defOp == 1) {
516 //figure out 16 bit displacement size
517 if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
518 displacementSize = 2;
519 else if (modRM.mod == 1)
520 displacementSize = 1;
521 else
522 displacementSize = 0;
523 } else {
524 //figure out 32/64 bit displacement size
525 if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2)
526 displacementSize = 4;
527 else if (modRM.mod == 1)
528 displacementSize = 1;
529 else
530 displacementSize = 0;
531 }
532
533 // The "test" instruction in group 3 needs an immediate, even though
534 // the other instructions with the same actual opcode don't.
535 if (emi.opcode.type == OneByteOpcode && (modRM.reg & 0x6) == 0) {
536 if (emi.opcode.op == 0xF6)
537 immediateSize = 1;
538 else if (emi.opcode.op == 0xF7)
539 immediateSize = (emi.opSize == 8) ? 4 : emi.opSize;
540 }
541
542 //If there's an SIB, get that next.
543 //There is no SIB in 16 bit mode.
544 if (modRM.rm == 4 && modRM.mod != 3) {
545 // && in 32/64 bit mode)
546 nextState = SIBState;
547 } else if (displacementSize) {
548 nextState = DisplacementState;
549 } else if (immediateSize) {
550 nextState = ImmediateState;
551 } else {
552 instDone = true;
553 nextState = ResetState;
554 }
555 //The ModRM byte is consumed no matter what
556 consumeByte();
557 emi.modRM = modRM;
558 return nextState;
559}
560
561//Get the SIB byte. We don't do anything with it at this point, other
562//than storing it in the ExtMachInst. Determine if we need to get a
563//displacement or immediate next.
564Decoder::State
565Decoder::doSIBState(uint8_t nextByte)
566{
567 State nextState = ErrorState;
568 emi.sib = nextByte;
569 DPRINTF(Decoder, "Found SIB byte %#x.\n", nextByte);
570 consumeByte();
571 if (emi.modRM.mod == 0 && emi.sib.base == 5)
572 displacementSize = 4;
573 if (displacementSize) {
574 nextState = DisplacementState;
575 } else if (immediateSize) {
576 nextState = ImmediateState;
577 } else {
578 instDone = true;
579 nextState = ResetState;
580 }
581 return nextState;
582}
583
584//Gather up the displacement, or at least as much of it
585//as we can get.
586Decoder::State
587Decoder::doDisplacementState()
588{
589 State nextState = ErrorState;
590
591 getImmediate(immediateCollected,
592 emi.displacement,
593 displacementSize);
594
595 DPRINTF(Decoder, "Collecting %d byte displacement, got %d bytes.\n",
596 displacementSize, immediateCollected);
597
598 if (displacementSize == immediateCollected) {
599 //Reset this for other immediates.
600 immediateCollected = 0;
601 //Sign extend the displacement
602 switch(displacementSize)
603 {
604 case 1:
605 emi.displacement = sext<8>(emi.displacement);
606 break;
607 case 2:
608 emi.displacement = sext<16>(emi.displacement);
609 break;
610 case 4:
611 emi.displacement = sext<32>(emi.displacement);
612 break;
613 default:
614 panic("Undefined displacement size!\n");
615 }
616 DPRINTF(Decoder, "Collected displacement %#x.\n",
617 emi.displacement);
618 if (immediateSize) {
619 nextState = ImmediateState;
620 } else {
621 instDone = true;
622 nextState = ResetState;
623 }
624
625 emi.dispSize = displacementSize;
626 }
627 else
628 nextState = DisplacementState;
629 return nextState;
630}
631
632//Gather up the immediate, or at least as much of it
633//as we can get
634Decoder::State
635Decoder::doImmediateState()
636{
637 State nextState = ErrorState;
638
639 getImmediate(immediateCollected,
640 emi.immediate,
641 immediateSize);
642
643 DPRINTF(Decoder, "Collecting %d byte immediate, got %d bytes.\n",
644 immediateSize, immediateCollected);
645
646 if (immediateSize == immediateCollected)
647 {
648 //Reset this for other immediates.
649 immediateCollected = 0;
650
651 //XXX Warning! The following is an observed pattern and might
652 //not always be true!
653
654 //Instructions which use 64 bit operands but 32 bit immediates
655 //need to have the immediate sign extended to 64 bits.
656 //Instructions which use true 64 bit immediates won't be
657 //affected, and instructions that use true 32 bit immediates
658 //won't notice.
659 switch(immediateSize)
660 {
661 case 4:
662 emi.immediate = sext<32>(emi.immediate);
663 break;
664 case 1:
665 emi.immediate = sext<8>(emi.immediate);
666 }
667
668 DPRINTF(Decoder, "Collected immediate %#x.\n",
669 emi.immediate);
670 instDone = true;
671 nextState = ResetState;
672 }
673 else
674 nextState = ImmediateState;
675 return nextState;
676}
677
678Decoder::InstBytes Decoder::dummy;
679Decoder::InstCacheMap Decoder::instCacheMap;
680
681StaticInstPtr
682Decoder::decode(ExtMachInst mach_inst, Addr addr)
683{
684 DecodeCache::InstMap::iterator iter = instMap->find(mach_inst);
685 if (iter != instMap->end())
686 return iter->second;
687
688 StaticInstPtr si = decodeInst(mach_inst);
689 (*instMap)[mach_inst] = si;
690 return si;
691}
692
693StaticInstPtr
694Decoder::decode(PCState &nextPC)
695{
696 if (!instDone)
697 return NULL;
698 instDone = false;
699 updateNPC(nextPC);
700
701 StaticInstPtr &si = instBytes->si;
702 if (si)
703 return si;
704
705 // We didn't match in the AddrMap, but we still populated an entry. Fix
706 // up its byte masks.
707 const int chunkSize = sizeof(MachInst);
708
709 instBytes->lastOffset = offset;
710
711 Addr firstBasePC = basePC - (instBytes->chunks.size() - 1) * chunkSize;
712 Addr firstOffset = origPC - firstBasePC;
713 Addr totalSize = instBytes->lastOffset - firstOffset +
714 (instBytes->chunks.size() - 1) * chunkSize;
715 int start = firstOffset;
716 instBytes->masks.clear();
717
718 while (totalSize) {
719 int end = start + totalSize;
720 end = (chunkSize < end) ? chunkSize : end;
721 int size = end - start;
722 int idx = instBytes->masks.size();
723
724 MachInst maskVal = mask(size * 8) << (start * 8);
725 assert(maskVal);
726
727 instBytes->masks.push_back(maskVal);
728 instBytes->chunks[idx] &= instBytes->masks[idx];
729 totalSize -= size;
730 start = 0;
731 }
732
733 si = decode(emi, origPC);
734 return si;
735}
736
737}