decoder.cc (9024:5851586f399c) decoder.cc (9376:270c9a75e91f)
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}