Clean up emulator internal error messages
[jpcrr.git] / org / jpc / emulator / memory / codeblock / optimised / ProtectedModeUDecoder.java
blobb9123fe12a7d8a5947dc56738a522b5c7ae464f3
1 /*
2 JPC-RR: A x86 PC Hardware Emulator
3 Release 1
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009 H. Ilari Liusvaara
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as published by
10 the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 Based on JPC x86 PC Hardware emulator,
22 A project from the Physics Dept, The University of Oxford
24 Details about original JPC can be found at:
26 www-jpc.physics.ox.ac.uk
30 package org.jpc.emulator.memory.codeblock.optimised;
32 import org.jpc.emulator.memory.codeblock.*;
34 import static org.jpc.emulator.memory.codeblock.optimised.MicrocodeSet.*;
36 /**
38 * @author Chris Dennis
40 public final class ProtectedModeUDecoder implements Decoder, InstructionSource
42 private static final boolean[] modrmArray = new boolean[] { // true for opcodes that require a modrm byte
43 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
44 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
45 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
46 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
48 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
49 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
50 false, false, true, true, false, false, false, false, false, true, false, true, false, false, false, false,
51 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
53 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
54 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
55 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
56 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
58 true, true, false, false, true, true, true, true, false, false, false, false, false, false, false, false,
59 true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false,
60 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
61 false, false, false, false, false, false, true, true, false, false, false, false, false, false, true, true
64 private static final boolean[] sibArray = new boolean[] { // true for modrm values that require a sib byte (32 bit addressing only)
65 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
66 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
67 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
68 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
70 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
71 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
72 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
73 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
75 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
76 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
77 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
78 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
80 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
81 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
82 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
83 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false
86 private static final boolean[] twoByte_0f_modrmArray = new boolean[] { // true for opcodes that require a modrm byte
87 true, true, true, true, false, false, false, false, false, false, false, true, false, false, false, false,
88 true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, true,
89 true, true, true, true, true, false, true, false, true, true, true, true, true, true, true, true,
90 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
92 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
93 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
94 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
95 true, true, true, true, true, true, true, false, false, false, false, false, true, true, true, true,
97 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
98 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
99 false, false, false, true, true, true, false, false, false, false, false, true, true, true, true, true,
100 true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true,
102 true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false,
103 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
104 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
105 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true
108 private static final boolean[] twoByte_0f_sibArray = new boolean[] { // true for modrm values that require a sib byte (32 bit addressing only)
109 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
110 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
111 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
112 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
114 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
115 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
116 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
117 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
119 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
120 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
121 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
122 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
124 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
125 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
126 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
127 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false
130 private static final int PREFICES_SG = 0x7;
131 private static final int PREFICES_ES = 0x1;
132 private static final int PREFICES_CS = 0x2;
133 private static final int PREFICES_SS = 0x3;
134 private static final int PREFICES_DS = 0x4;
135 private static final int PREFICES_FS = 0x5;
136 private static final int PREFICES_GS = 0x6;
138 private static final int PREFICES_OPERAND = 0x8;
139 private static final int PREFICES_ADDRESS = 0x10;
141 private static final int PREFICES_REPNE = 0x20;
142 private static final int PREFICES_REPE = 0x40;
144 private static final int PREFICES_REP = PREFICES_REPNE | PREFICES_REPE;
146 private static final int PREFICES_LOCK = 0x80;
148 private ByteSource source;
149 private Operation current;
150 private Operation waiting;
151 private Operation working;
153 private boolean blockComplete;
154 private boolean addressModeDecoded;
155 private boolean operandSizeIs32Bit;
157 private int decodeLimit;
160 * TODO: throw UD exception if LOCK prefix is used with an invalid instruction
161 * */
163 public ProtectedModeUDecoder()
165 this.current = new Operation();
166 this.waiting = new Operation();
167 this.working = new Operation();
170 public InstructionSource decodeReal(ByteSource source, int limit)
172 return null;
175 public InstructionSource decodeVirtual8086(ByteSource source, int limit)
177 return null;
180 public InstructionSource decodeProtected(ByteSource source, boolean operandSize, int limit)
182 //limit=1;
183 reset();
184 operandSizeIs32Bit = operandSize;
185 this.source = source;
186 decodeLimit = limit;
187 return this;
190 private void blockFinished()
192 blockComplete = true;
195 private void rotate()
197 Operation temp = current;
198 current = waiting;
199 waiting = working;
200 working = temp;
203 public boolean getNext()
205 decode(); //will put new block in working
206 rotate(); //moves buffer around
207 if (current.decoded())
208 return true;
209 else if (current.terminal()) {
210 reset();
211 return false;
212 } else
213 return getNext();
216 public void reset()
218 working.reset();
219 waiting.reset();
220 current.reset();
221 blockComplete = false;
224 public int getMicrocode()
226 return current.getMicrocode();
229 public int getLength()
231 return current.getLength();
234 public int getX86Length()
236 return current.getX86Length();
240 private boolean decodingAddressMode()
242 if (addressModeDecoded) {
243 return false;
244 } else {
245 return (addressModeDecoded = true);
249 private void decodeComplete(int position)
251 if (addressModeDecoded) {
252 working.write(MEM_RESET);
253 addressModeDecoded = false;
255 working.finish(position);
258 private void decode()
260 working.reset();
262 if (blockComplete) {
263 working.makeTerminal();
264 return;
267 int length = 0;
268 try {
269 length = decodeOpcode(operandSizeIs32Bit);
270 decodeLimit--;
271 } catch (IllegalStateException e) {
272 if (!waiting.decoded()) {
273 System.err.println("Critical error: Instruction decoder failed.");
274 throw e;
276 waiting.write(EIP_UPDATE);
277 working.makeTerminal();
278 blockFinished();
279 return;
282 if (length < 0) {
283 decodeComplete(-length);
284 blockFinished();
285 } else if (decodeLimit <= 0) {
286 decodeComplete(length);
287 working.write(EIP_UPDATE);
288 blockFinished();
289 } else
290 decodeComplete(length);
293 private int decodeOpcode(boolean operandSizeIs32Bit)
295 int opcode = 0;
296 int opcodePrefix = 0;
297 int prefices = operandSizeIs32Bit ? PREFICES_OPERAND | PREFICES_ADDRESS : 0x00;
298 int bytesRead = 0;
299 int modrm = -1;
300 int sib = -1;
301 boolean lock = false;
302 while (true) {
303 bytesRead += 1;
304 switch (opcode = 0xff & source.getByte()) {
305 case 0x0f:
306 opcodePrefix = (opcodePrefix << 8) | opcode;
307 opcode = 0xff & source.getByte();
308 bytesRead += 1;
309 modrm = opcode;
310 break;
311 case 0xd8:
312 case 0xd9:
313 case 0xda:
314 case 0xdb:
315 case 0xdc:
316 case 0xdd:
317 case 0xde:
318 case 0xdf:
319 opcodePrefix = (opcodePrefix << 8) | opcode;
320 opcode = 0;
321 modrm = 0xff & source.getByte();
322 bytesRead += 1;
323 break;
324 //Prefices
325 case 0x2e:
326 prefices &= ~PREFICES_SG;
327 prefices |= PREFICES_CS;
328 continue;
329 case 0x3e:
330 prefices &= ~PREFICES_SG;
331 prefices |= PREFICES_DS;
332 continue;
333 case 0x26:
334 prefices &= ~PREFICES_SG;
335 prefices |= PREFICES_ES;
336 continue;
337 case 0x36:
338 prefices &= ~PREFICES_SG;
339 prefices |= PREFICES_SS;
340 continue;
341 case 0x64:
342 prefices &= ~PREFICES_SG;
343 prefices |= PREFICES_FS;
344 continue;
345 case 0x65:
346 prefices &= ~PREFICES_SG;
347 prefices |= PREFICES_GS;
348 continue;
349 case 0x66:
350 if (operandSizeIs32Bit)
351 prefices = prefices & ~PREFICES_OPERAND;
352 else
353 prefices = prefices | PREFICES_OPERAND;
354 continue;
355 case 0x67:
356 if (operandSizeIs32Bit)
357 prefices = prefices & ~PREFICES_ADDRESS;
358 else
359 prefices = prefices | PREFICES_ADDRESS;
360 continue;
361 case 0xf2:
362 prefices |= PREFICES_REPNE;
363 continue;
364 case 0xf3:
365 prefices |= PREFICES_REPE;
366 continue;
367 case 0xf0:
368 lock = true;
369 prefices |= PREFICES_LOCK;
370 continue;
371 default:
372 break;
374 break;
376 if (lock)
377 if ((opcode == 0xff) && (opcode == 0xfe) && (opcode != 0xab) && (opcode == 0xfc1)
378 && (opcode != 0x81) && (opcode != 0x83) && (opcode != 0x1) && (opcode != 0xfc7)
379 && (opcode != 0xba) && (opcode != 0xb3) && (opcode != 0x29) && (opcode != 0x9)
380 && (opcode != 0xb1) && (opcode != 0x21))
381 System.err.println("Emulated: Warning using LOCK prefix with opcode: " + Integer.toHexString(opcode));
383 opcode = (opcodePrefix << 8) | opcode;
384 switch (opcodePrefix) {
385 case 0x00:
386 if (modrmArray[opcode]) {
387 modrm = 0xff & source.getByte();
388 bytesRead += 1;
389 } else {
390 modrm = -1;
392 if ((modrm == -1) || ((prefices & PREFICES_ADDRESS) == 0)) {
393 sib = -1;
394 } else {
395 if (sibArray[modrm]) {
396 sib = 0xff & source.getByte();
397 bytesRead += 1;
398 } else {
399 sib = -1;
402 break;
403 case 0x0f:
404 if (twoByte_0f_modrmArray[0xff & opcode]) {
405 modrm = 0xff & source.getByte();
406 bytesRead += 1;
407 } else {
408 modrm = -1;
410 if ((modrm == -1) || ((prefices & PREFICES_ADDRESS) == 0)) {
411 sib = -1;
412 } else {
413 if (twoByte_0f_sibArray[modrm]) {
414 sib = 0xff & source.getByte();
415 bytesRead += 1;
416 } else {
417 sib = -1;
420 break;
421 case 0xd8:
422 case 0xd9:
423 case 0xda:
424 case 0xdb:
425 case 0xdc:
426 case 0xdd:
427 case 0xde:
428 case 0xdf:
429 if (sibArray[modrm]) {
430 sib = 0xff & source.getByte();
431 bytesRead += 1;
432 } else {
433 sib = -1;
435 break;
436 default:
437 modrm = -1;
438 sib = -1;
439 break;
442 working.write(INSTRUCTION_START);
444 if (isJump(opcode, modrm))
445 working.write(EIP_UPDATE);
447 int displacement = 0;
449 switch (operationHasDisplacement(prefices, opcode, modrm, sib)) {
450 case 0:
451 break;
452 case 1:
453 displacement = source.getByte();
454 bytesRead += 1;
455 break;
456 case 2:
457 displacement = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00);
458 bytesRead += 2;
459 break;
460 case 4:
461 displacement = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00) | ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000);
462 bytesRead += 4;
463 break;
464 default:
465 System.err.println("Error: " + operationHasDisplacement(prefices, opcode, modrm, sib) +
466 " byte displacement invalid.");
467 break;
470 long immediate = 0;
472 switch (operationHasImmediate(prefices, opcode, modrm)) {
473 case 0:
474 break;
475 case 1:
476 immediate = source.getByte();
477 bytesRead += 1;
478 break;
479 case 2:
480 immediate = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00);
481 bytesRead += 2;
482 break;
483 case 3:
484 immediate = ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000) | (source.getByte() & 0xff);
485 bytesRead += 3;
486 break;
487 case 4:
488 immediate = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00) | ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000);
489 bytesRead += 4;
490 break;
491 case 6:
492 immediate = 0xffffffffl & ((source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00) | ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000));
493 immediate |= ((source.getByte() & 0xffl) | ((source.getByte() << 8) & 0xff00l)) << 32;
494 bytesRead += 6;
495 break;
496 default:
497 System.err.println("Error: " + operationHasImmediate(prefices, opcode, modrm) +
498 " byte immediate invalid.");
499 break;
503 //write out input operands
504 writeInputOperands(prefices, opcode, modrm, sib, displacement, immediate);
506 //write out calculation
507 writeOperation(prefices, opcode, modrm);
509 //write out output operands
510 writeOutputOperands(prefices, opcode, modrm, sib, displacement);
512 //write out flags
513 writeFlags(prefices, opcode, modrm);
515 if (isJump(opcode, modrm))
516 return -bytesRead;
517 else
518 return bytesRead;
521 private void writeOperation(int prefices, int opcode, int modrm)
523 switch (opcode) {
524 case 0x00: //ADD Eb, Gb
525 case 0x01: //ADD Ev, Gv
526 case 0x02: //ADD Gb, Eb
527 case 0x03: //ADD Gv, Ev
528 case 0x04: //ADD AL, Ib
529 case 0x05: //ADD eAX, Iv
530 case 0xfc0: //XADD Eb, Gb
531 case 0xfc1: working.write(ADD); break; //XADD Ev, Gv
533 case 0x08: //OR Eb, Gb
534 case 0x09: //OR Ev, Gv
535 case 0x0a: //OR Gb, Eb
536 case 0x0b: //OR Gv, Ev
537 case 0x0c: //OR AL, Ib
538 case 0x0d: working.write(OR ); break; //OR eAX, Iv
540 case 0x10: //ADC Eb, Gb
541 case 0x11: //ADC Ev, Gv
542 case 0x12: //ADC Gb, Eb
543 case 0x13: //ADC Gv, Ev
544 case 0x14: //ADC AL, Ib
545 case 0x15: working.write(ADC); break; //ADC eAX, Iv
547 case 0x18: //SBB Eb, Gb
548 case 0x19: //SBB Ev, Gv
549 case 0x1a: //SBB Gb, Eb
550 case 0x1b: //SBB Gv, Ev
551 case 0x1c: //SBB AL, Ib
552 case 0x1d: working.write(SBB); break; //SBB eAX, Iv
554 case 0x20: //AND Eb, Gb
555 case 0x21: //AND Ev, Gv
556 case 0x22: //AND Gb, Eb
557 case 0x23: //AND Gv, Ev
558 case 0x24: //AND AL, Ib
559 case 0x25: //AND eAX, Iv
560 case 0x84: //TEST Eb, Gb
561 case 0x85: //TEST Ev, Gv
562 case 0xa8: //TEST AL, Ib
563 case 0xa9: working.write(AND); break; //TEST eAX, Iv
565 case 0x27: working.write(DAA); break; //DAA
567 case 0x28: //SUB Eb, Gb
568 case 0x29: //SUB Ev, Gv
569 case 0x2a: //SUB Gb, Eb
570 case 0x2b: //SUB Gv, Ev
571 case 0x2c: //SUB AL, Ib
572 case 0x2d: //SUB eAX, Iv
573 case 0x38: //CMP Eb, Gb
574 case 0x39: //CMP Ev, Gv
575 case 0x3a: //CMP Gb, Eb
576 case 0x3b: //CMP Gv, Ev
577 case 0x3c: //CMP AL, Ib
578 case 0x3d: working.write(SUB); break; //CMP eAX, Iv
580 case 0x2f: working.write(DAS); break; //DAS
582 case 0x30: //XOR Eb, Gb
583 case 0x31: //XOR Ev, Gv
584 case 0x32: //XOR Gb, Eb
585 case 0x33: //XOR Gv, Ev
586 case 0x34: //XOR AL, Ib
587 case 0x35: working.write(XOR); break; //XOR eAX, Iv
589 case 0x37: working.write(AAA); break; //AAA
590 case 0x3f: working.write(AAS); break; //AAS
592 case 0x40: //INC eAX
593 case 0x41: //INC eCX
594 case 0x42: //INC eDX
595 case 0x43: //INC eBX
596 case 0x44: //INC eSP
597 case 0x45: //INC eBP
598 case 0x46: //INC eSI
599 case 0x47: working.write(INC); break; //INC eDI
601 case 0x48: //DEC eAX
602 case 0x49: //DEC eCX
603 case 0x4a: //DEC eDX
604 case 0x4b: //DEC eBX
605 case 0x4c: //DEC eSP
606 case 0x4d: //DEC eBP
607 case 0x4e: //DEC eSI
608 case 0x4f: working.write(DEC); break; //DEC eDI
610 case 0x06: //PUSH ES
611 case 0x0e: //PUSH CS
612 case 0x16: //PUSH SS
613 case 0x1e: //PUSH DS
614 case 0x50: //PUSH eAX
615 case 0x51: //PUSH eCX
616 case 0x52: //PUSH eDX
617 case 0x53: //PUSH eBX
618 case 0x54: //PUSH eSP
619 case 0x55: //PUSH eBP
620 case 0x56: //PUSH eSI
621 case 0x57: //PUSH eDI
622 case 0x68: //PUSH Iv
623 case 0x6a: //PUSH Ib
624 case 0xfa0: //PUSH FS
625 case 0xfa8: //PUSH GS
626 switch (prefices & PREFICES_OPERAND) {
627 case 0:
628 working.write(PUSH_O16); break;
629 case PREFICES_OPERAND:
630 working.write(PUSH_O32); break;
632 break;
634 case 0x9c: //PUSHF
635 switch (prefices & PREFICES_OPERAND) {
636 case 0:
637 working.write(PUSHF_O16); break;
638 case PREFICES_OPERAND:
639 working.write(PUSHF_O32); break;
641 break;
643 case 0x07: //POP ES
644 case 0x17: //POP SS
645 case 0x1f: //POP DS
646 case 0x58: //POP eAX
647 case 0x59: //POP eCX
648 case 0x5a: //POP eDX
649 case 0x5b: //POP eBX
650 case 0x5c: //POP eSP
651 case 0x5d: //POP eBP
652 case 0x5e: //POP eSI
653 case 0x5f: //POP eDI
654 case 0x8f: //POP Ev
655 case 0xfa1: //POP FS
656 case 0xfa9: //POP GS
657 switch (prefices & PREFICES_OPERAND) {
658 case 0:
659 working.write(POP_O16); break;
660 case PREFICES_OPERAND:
661 working.write(POP_O32); break;
663 break;
665 case 0x9d: //POPF
666 switch (prefices & PREFICES_OPERAND) {
667 case 0:
668 working.write(POPF_O16); break;
669 case PREFICES_OPERAND:
670 working.write(POPF_O32); break;
672 break;
674 case 0x60: //PUSHA/D
675 switch (prefices & PREFICES_OPERAND) {
676 case 0:
677 working.write(PUSHA); break;
678 case PREFICES_OPERAND:
679 working.write(PUSHAD); break;
681 break;
683 case 0x61: //POPA/D
684 switch (prefices & PREFICES_OPERAND) {
685 case 0:
686 working.write(POPA); break;
687 case PREFICES_OPERAND:
688 working.write(POPAD); break;
690 break;
692 case 0x62: //BOUND
693 if ((prefices & PREFICES_OPERAND) != 0)
694 working.write(BOUND_O32);
695 else
696 working.write(BOUND_O16);
697 break;
699 case 0x69: //IMUL Gv, Ev, Iv
700 case 0x6b: //IMUL Gv, Ev, Ib
701 case 0xfaf: //IMUL Gv, Ev
702 if ((prefices & PREFICES_OPERAND) != 0)
703 working.write(IMUL_O32);
704 else
705 working.write(IMUL_O16);
706 break;
708 case 0x6c: //INSB
709 if ((prefices & PREFICES_REP) != 0) {
710 if ((prefices & PREFICES_ADDRESS) != 0)
711 working.write(REP_INSB_A32);
712 else
713 working.write(REP_INSB_A16);
714 } else {
715 if ((prefices & PREFICES_ADDRESS) != 0)
716 working.write(INSB_A32);
717 else
718 working.write(INSB_A16);
720 break;
722 case 0x6d: //INSW/D
723 if ((prefices & PREFICES_OPERAND) != 0) {
724 if ((prefices & PREFICES_REP) != 0) {
725 if ((prefices & PREFICES_ADDRESS) != 0)
726 working.write(REP_INSD_A32);
727 else
728 working.write(REP_INSD_A16);
729 } else {
730 if ((prefices & PREFICES_ADDRESS) != 0)
731 working.write(INSD_A32);
732 else
733 working.write(INSD_A16);
735 } else {
736 if ((prefices & PREFICES_REP) != 0) {
737 if ((prefices & PREFICES_ADDRESS) != 0)
738 working.write(REP_INSW_A32);
739 else
740 working.write(REP_INSW_A16);
741 } else {
742 if ((prefices & PREFICES_ADDRESS) != 0)
743 working.write(INSW_A32);
744 else
745 working.write(INSW_A16);
748 break;
750 case 0x6e: //OUTSB
751 if ((prefices & PREFICES_REP) != 0) {
752 if ((prefices & PREFICES_ADDRESS) != 0)
753 working.write(REP_OUTSB_A32);
754 else
755 working.write(REP_OUTSB_A16);
756 } else {
757 if ((prefices & PREFICES_ADDRESS) != 0)
758 working.write(OUTSB_A32);
759 else
760 working.write(OUTSB_A16);
762 break;
764 case 0x6f: //OUTS DX, Xv
765 if ((prefices & PREFICES_OPERAND) != 0) {
766 if ((prefices & PREFICES_REP) != 0) {
767 if ((prefices & PREFICES_ADDRESS) != 0)
768 working.write(REP_OUTSD_A32);
769 else
770 working.write(REP_OUTSD_A16);
771 } else {
772 if ((prefices & PREFICES_ADDRESS) != 0)
773 working.write(OUTSD_A32);
774 else
775 working.write(OUTSD_A16);
777 } else {
778 if ((prefices & PREFICES_REP) != 0) {
779 if ((prefices & PREFICES_ADDRESS) != 0)
780 working.write(REP_OUTSW_A32);
781 else
782 working.write(REP_OUTSW_A16);
783 } else {
784 if ((prefices & PREFICES_ADDRESS) != 0)
785 working.write(OUTSW_A32);
786 else
787 working.write(OUTSW_A16);
790 break;
792 case 0x70: working.write(JO_O8); break; //JC Jb
793 case 0x71: working.write(JNO_O8); break; //JNC Jb
794 case 0x72: working.write(JC_O8); break; //JC Jb
795 case 0x73: working.write(JNC_O8); break; //JNC Jb
796 case 0x74: working.write(JZ_O8); break; //JZ Jb
797 case 0x75: working.write(JNZ_O8); break; //JNZ Jb
798 case 0x76: working.write(JNA_O8); break; //JNA Jb
799 case 0x77: working.write(JA_O8); break; //JA Jb
800 case 0x78: working.write(JS_O8); break; //JS Jb
801 case 0x79: working.write(JNS_O8); break; //JNS Jb
802 case 0x7a: working.write(JP_O8); break; //JP Jb
803 case 0x7b: working.write(JNP_O8); break; //JNP Jb
804 case 0x7c: working.write(JL_O8); break; //JL Jb
805 case 0x7d: working.write(JNL_O8); break; //JNL Jb
806 case 0x7e: working.write(JNG_O8); break; //JNG Jb
807 case 0x7f: working.write(JG_O8); break; //JG Jb
809 case 0x80: //IMM GP1 Eb, Ib
810 case 0x81: //IMM GP1 Ev, Iv
811 case 0x82: //IMM GP1 Eb, Ib
812 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
813 switch (modrm & 0x38) {
814 case 0x00:
815 working.write(ADD); break;
816 case 0x08:
817 working.write(OR); break;
818 case 0x10:
819 working.write(ADC); break;
820 case 0x18:
821 working.write(SBB); break;
822 case 0x20:
823 working.write(AND); break;
824 case 0x28:
825 case 0x38: //CMP
826 working.write(SUB); break;
827 case 0x30:
828 working.write(XOR); break;
830 break;
832 case 0x98: //CBW/CWDE
833 if ((prefices & PREFICES_OPERAND) != 0) {
834 working.write(LOAD0_AX);
835 working.write(SIGN_EXTEND_16_32);
836 working.write(STORE0_EAX);
837 } else {
838 working.write(LOAD0_AL);
839 working.write(SIGN_EXTEND_8_16);
840 working.write(STORE0_AX);
842 break;
844 case 0x99:
845 if ((prefices & PREFICES_OPERAND) != 0)
846 working.write(CDQ);
847 else
848 working.write(CWD);
849 break;
851 case 0x9a: //CALLF
852 switch (prefices & PREFICES_OPERAND) {
853 case 0:
854 working.write(CALL_FAR_O16); break;
855 case PREFICES_OPERAND:
856 working.write(CALL_FAR_O32); break;
858 break;
860 case 0x9b: working.write(FWAIT); break; //FWAIT
862 case 0x9e: working.write(SAHF); break;
863 case 0x9f: working.write(LAHF); break;
865 case 0xa4: //MOVSB
866 if ((prefices & PREFICES_REP) != 0) {
867 if ((prefices & PREFICES_ADDRESS) != 0)
868 working.write(REP_MOVSB_A32);
869 else
870 working.write(REP_MOVSB_A16);
871 } else {
872 if ((prefices & PREFICES_ADDRESS) != 0)
873 working.write(MOVSB_A32);
874 else
875 working.write(MOVSB_A16);
877 break;
879 case 0xa5: //MOVSW/D
880 if ((prefices & PREFICES_OPERAND) != 0) {
881 if ((prefices & PREFICES_REP) != 0) {
882 if ((prefices & PREFICES_ADDRESS) != 0)
883 working.write(REP_MOVSD_A32);
884 else
885 working.write(REP_MOVSD_A16);
886 } else {
887 if ((prefices & PREFICES_ADDRESS) != 0)
888 working.write(MOVSD_A32);
889 else
890 working.write(MOVSD_A16);
892 } else {
893 if ((prefices & PREFICES_REP) != 0) {
894 if ((prefices & PREFICES_ADDRESS) != 0)
895 working.write(REP_MOVSW_A32);
896 else
897 working.write(REP_MOVSW_A16);
898 } else {
899 if ((prefices & PREFICES_ADDRESS) != 0)
900 working.write(MOVSW_A32);
901 else
902 working.write(MOVSW_A16);
905 break;
907 case 0xa6: //CMPSB
908 if ((prefices & PREFICES_REPE) != 0) {
909 if ((prefices & PREFICES_ADDRESS) != 0)
910 working.write(REPE_CMPSB_A32);
911 else
912 working.write(REPE_CMPSB_A16);
913 } else if ((prefices & PREFICES_REPNE) != 0) {
914 if ((prefices & PREFICES_ADDRESS) != 0)
915 working.write(REPNE_CMPSB_A32);
916 else
917 working.write(REPNE_CMPSB_A16);
918 } else {
919 if ((prefices & PREFICES_ADDRESS) != 0)
920 working.write(CMPSB_A32);
921 else
922 working.write(CMPSB_A16);
924 break;
926 case 0xa7: //CMPSW/D
927 if ((prefices & PREFICES_OPERAND) != 0) {
928 if ((prefices & PREFICES_REPE) != 0) {
929 if ((prefices & PREFICES_ADDRESS) != 0)
930 working.write(REPE_CMPSD_A32);
931 else
932 working.write(REPE_CMPSD_A16);
933 } else if ((prefices & PREFICES_REPNE) != 0) {
934 if ((prefices & PREFICES_ADDRESS) != 0)
935 working.write(REPNE_CMPSD_A32);
936 else
937 working.write(REPNE_CMPSD_A16);
938 } else {
939 if ((prefices & PREFICES_ADDRESS) != 0)
940 working.write(CMPSD_A32);
941 else
942 working.write(CMPSD_A16);
944 } else {
945 if ((prefices & PREFICES_REPE) != 0) {
946 if ((prefices & PREFICES_ADDRESS) != 0)
947 working.write(REPE_CMPSW_A32);
948 else
949 working.write(REPE_CMPSW_A16);
950 } else if ((prefices & PREFICES_REPNE) != 0) {
951 if ((prefices & PREFICES_ADDRESS) != 0)
952 working.write(REPNE_CMPSW_A32);
953 else
954 working.write(REPNE_CMPSW_A16);
955 } else {
956 if ((prefices & PREFICES_ADDRESS) != 0)
957 working.write(CMPSW_A32);
958 else
959 working.write(CMPSW_A16);
962 break;
964 case 0xaa: //STOSB
965 if ((prefices & PREFICES_REP) != 0) {
966 if ((prefices & PREFICES_ADDRESS) != 0)
967 working.write(REP_STOSB_A32);
968 else
969 working.write(REP_STOSB_A16);
970 } else {
971 if ((prefices & PREFICES_ADDRESS) != 0)
972 working.write(STOSB_A32);
973 else
974 working.write(STOSB_A16);
976 break;
978 case 0xab: //STOSW/STOSD
979 if ((prefices & PREFICES_OPERAND) != 0) {
980 if ((prefices & PREFICES_REP) != 0) {
981 if ((prefices & PREFICES_ADDRESS) != 0)
982 working.write(REP_STOSD_A32);
983 else
984 working.write(REP_STOSD_A16);
985 } else {
986 if ((prefices & PREFICES_ADDRESS) != 0)
987 working.write(STOSD_A32);
988 else
989 working.write(STOSD_A16);
991 } else {
992 if ((prefices & PREFICES_REP) != 0) {
993 if ((prefices & PREFICES_ADDRESS) != 0)
994 working.write(REP_STOSW_A32);
995 else
996 working.write(REP_STOSW_A16);
997 } else {
998 if ((prefices & PREFICES_ADDRESS) != 0)
999 working.write(STOSW_A32);
1000 else
1001 working.write(STOSW_A16);
1004 break;
1006 case 0xac: //LODSB
1007 if ((prefices & PREFICES_REP) != 0) {
1008 if ((prefices & PREFICES_ADDRESS) != 0)
1009 working.write(REP_LODSB_A32);
1010 else
1011 working.write(REP_LODSB_A16);
1012 } else {
1013 if ((prefices & PREFICES_ADDRESS) != 0)
1014 working.write(LODSB_A32);
1015 else
1016 working.write(LODSB_A16);
1018 break;
1020 case 0xad: //LODSW/LODSD
1021 if ((prefices & PREFICES_OPERAND) != 0) {
1022 if ((prefices & PREFICES_REP) != 0) {
1023 if ((prefices & PREFICES_ADDRESS) != 0)
1024 working.write(REP_LODSD_A32);
1025 else
1026 working.write(REP_LODSD_A16);
1027 } else {
1028 if ((prefices & PREFICES_ADDRESS) != 0)
1029 working.write(LODSD_A32);
1030 else
1031 working.write(LODSD_A16);
1033 } else {
1034 if ((prefices & PREFICES_REP) != 0) {
1035 if ((prefices & PREFICES_ADDRESS) != 0)
1036 working.write(REP_LODSW_A32);
1037 else
1038 working.write(REP_LODSW_A16);
1039 } else {
1040 if ((prefices & PREFICES_ADDRESS) != 0)
1041 working.write(LODSW_A32);
1042 else
1043 working.write(LODSW_A16);
1046 break;
1048 case 0xae: //SCASB
1049 if ((prefices & PREFICES_REPE) != 0) {
1050 if ((prefices & PREFICES_ADDRESS) != 0)
1051 working.write(REPE_SCASB_A32);
1052 else
1053 working.write(REPE_SCASB_A16);
1054 } else if ((prefices & PREFICES_REPNE) != 0) {
1055 if ((prefices & PREFICES_ADDRESS) != 0)
1056 working.write(REPNE_SCASB_A32);
1057 else
1058 working.write(REPNE_SCASB_A16);
1059 } else {
1060 if ((prefices & PREFICES_ADDRESS) != 0)
1061 working.write(SCASB_A32);
1062 else
1063 working.write(SCASB_A16);
1065 break;
1067 case 0xaf: //SCASW/D
1068 if ((prefices & PREFICES_OPERAND) != 0) {
1069 if ((prefices & PREFICES_REPE) != 0) {
1070 if ((prefices & PREFICES_ADDRESS) != 0)
1071 working.write(REPE_SCASD_A32);
1072 else
1073 working.write(REPE_SCASD_A16);
1074 } else if ((prefices & PREFICES_REPNE) != 0) {
1075 if ((prefices & PREFICES_ADDRESS) != 0)
1076 working.write(REPNE_SCASD_A32);
1077 else
1078 working.write(REPNE_SCASD_A16);
1079 } else {
1080 if ((prefices & PREFICES_ADDRESS) != 0)
1081 working.write(SCASD_A32);
1082 else
1083 working.write(SCASD_A16);
1085 } else {
1086 if ((prefices & PREFICES_REPE) != 0) {
1087 if ((prefices & PREFICES_ADDRESS) != 0)
1088 working.write(REPE_SCASW_A32);
1089 else
1090 working.write(REPE_SCASW_A16);
1091 } else if ((prefices & PREFICES_REPNE) != 0) {
1092 if ((prefices & PREFICES_ADDRESS) != 0)
1093 working.write(REPNE_SCASW_A32);
1094 else
1095 working.write(REPNE_SCASW_A16);
1096 } else {
1097 if ((prefices & PREFICES_ADDRESS) != 0)
1098 working.write(SCASW_A32);
1099 else
1100 working.write(SCASW_A16);
1103 break;
1105 case 0xc0:
1106 case 0xd0:
1107 case 0xd2:
1108 switch (modrm & 0x38) {
1109 case 0x00:
1110 working.write(ROL_O8); break;
1111 case 0x08:
1112 working.write(ROR_O8); break;
1113 case 0x10:
1114 working.write(RCL_O8); break;
1115 case 0x18:
1116 working.write(RCR_O8); break;
1117 case 0x20:
1118 working.write(SHL); break;
1119 case 0x28:
1120 working.write(SHR); break;
1121 case 0x30:
1122 System.err.println("Emulated: invalid SHL encoding");
1123 working.write(SHL); break;
1124 case 0x38:
1125 working.write(SAR_O8); break;
1127 break;
1129 case 0xc1:
1130 case 0xd1:
1131 case 0xd3:
1132 if ((prefices & PREFICES_OPERAND) != 0) {
1133 switch (modrm & 0x38) {
1134 case 0x00:
1135 working.write(ROL_O32); break;
1136 case 0x08:
1137 working.write(ROR_O32); break;
1138 case 0x10:
1139 working.write(RCL_O32); break;
1140 case 0x18:
1141 working.write(RCR_O32); break;
1142 case 0x20:
1143 working.write(SHL); break;
1144 case 0x28:
1145 working.write(SHR); break;
1146 case 0x30:
1147 System.err.println("Emulated: invalid SHL encoding");
1148 working.write(SHL); break;
1149 case 0x38:
1150 working.write(SAR_O32); break;
1152 } else {
1153 switch (modrm & 0x38) {
1154 case 0x00:
1155 working.write(ROL_O16); break;
1156 case 0x08:
1157 working.write(ROR_O16); break;
1158 case 0x10:
1159 working.write(RCL_O16); break;
1160 case 0x18:
1161 working.write(RCR_O16); break;
1162 case 0x20:
1163 working.write(SHL); break;
1164 case 0x28:
1165 working.write(SHR); break;
1166 case 0x30:
1167 working.write(SHL); break;
1168 case 0x38:
1169 working.write(SAR_O16); break;
1172 break;
1174 case 0xc2:
1175 switch (prefices & PREFICES_OPERAND) {
1176 case 0:
1177 working.write(RET_IW_O16); break;
1178 case PREFICES_OPERAND:
1179 working.write(RET_IW_O32); break;
1181 break;
1183 case 0xc3: //RET
1184 switch (prefices & PREFICES_OPERAND) {
1185 case 0:
1186 working.write(RET_O16); break;
1187 case PREFICES_OPERAND:
1188 working.write(RET_O32); break;
1190 break;
1192 case 0xc8:
1193 switch (prefices & PREFICES_OPERAND) {
1194 case 0:
1195 working.write(ENTER_O16); break;
1196 case PREFICES_OPERAND:
1197 working.write(ENTER_O32); break;
1199 break;
1201 case 0xc9:
1202 switch (prefices & PREFICES_OPERAND) {
1203 case 0:
1204 working.write(LEAVE_O16); break;
1205 case PREFICES_OPERAND:
1206 working.write(LEAVE_O32); break;
1208 break;
1210 case 0xca:
1211 switch (prefices & PREFICES_OPERAND) {
1212 case 0:
1213 working.write(RET_FAR_IW_O16); break;
1214 case PREFICES_OPERAND:
1215 working.write(RET_FAR_IW_O32); break;
1217 break;
1219 case 0xcb:
1220 switch (prefices & PREFICES_OPERAND) {
1221 case 0:
1222 working.write(RET_FAR_O16); break;
1223 case PREFICES_OPERAND:
1224 working.write(RET_FAR_O32); break;
1226 break;
1228 case 0xcc:
1229 switch (prefices & PREFICES_OPERAND) {
1230 case 0:
1231 working.write(INT3_O16); break;
1232 case PREFICES_OPERAND:
1233 working.write(INT3_O32); break;
1235 break;
1237 case 0xcd:
1238 switch (prefices & PREFICES_OPERAND) {
1239 case 0:
1240 working.write(INT_O16); break;
1241 case PREFICES_OPERAND:
1242 working.write(INT_O32); break;
1244 break;
1246 case 0xce:
1247 switch (prefices & PREFICES_OPERAND) {
1248 case 0:
1249 working.write(INTO_O16); break;
1250 case PREFICES_OPERAND:
1251 working.write(INTO_O32); break;
1253 break;
1255 case 0xcf:
1256 switch (prefices & PREFICES_OPERAND) {
1257 case 0:
1258 working.write(IRET_O16); break;
1259 case PREFICES_OPERAND:
1260 working.write(IRET_O32); break;
1262 break;
1264 case 0xd4: working.write(AAM); break; //AAM
1265 case 0xd5: working.write(AAD); break; //AAD
1267 case 0xd6: working.write(SALC); break; //SALC
1269 case 0xe0: //LOOPNZ Jb
1270 if ((prefices & PREFICES_ADDRESS) != 0)
1271 working.write(LOOPNZ_ECX);
1272 else
1273 working.write(LOOPNZ_CX);
1274 break;
1276 case 0xe1: //LOOPZ Jb
1277 if ((prefices & PREFICES_ADDRESS) != 0)
1278 working.write(LOOPZ_ECX);
1279 else
1280 working.write(LOOPZ_CX);
1281 break;
1283 case 0xe2: //LOOP Jb
1284 if ((prefices & PREFICES_ADDRESS) != 0)
1285 working.write(LOOP_ECX);
1286 else
1287 working.write(LOOP_CX);
1288 break;
1290 case 0xe3: //JCXZ
1291 if ((prefices & PREFICES_ADDRESS) != 0)
1292 working.write(JECXZ);
1293 else
1294 working.write(JCXZ);
1295 break;
1297 case 0xe4: //IN AL, Ib
1298 case 0xec: working.write(IN_O8); break; //IN AL, DX
1300 case 0xe5: //IN eAX, Ib
1301 case 0xed: //IN eAX, DX
1302 if ((prefices & PREFICES_OPERAND) != 0)
1303 working.write(IN_O32);
1304 else
1305 working.write(IN_O16);
1306 break;
1308 case 0xe6: //OUT Ib, AL
1309 case 0xee: working.write(OUT_O8); break; //OUT DX, AL
1311 case 0xe7: //OUT Ib, eAX
1312 case 0xef: //OUT DX, eAX
1313 if ((prefices & PREFICES_OPERAND) != 0)
1314 working.write(OUT_O32);
1315 else
1316 working.write(OUT_O16);
1317 break;
1319 case 0xe8: //CALL Jv
1320 switch (prefices & PREFICES_OPERAND) {
1321 case 0:
1322 working.write(CALL_O16); break;
1323 case PREFICES_OPERAND:
1324 working.write(CALL_O32); break;
1326 break;
1328 case 0xe9: //JMP Jv
1329 if ((prefices & PREFICES_OPERAND) != 0)
1330 working.write(JUMP_O32);
1331 else
1332 working.write(JUMP_O16);
1333 break;
1335 case 0xea: //JMPF Ap
1336 if ((prefices & PREFICES_OPERAND) != 0)
1337 working.write(JUMP_FAR_O32);
1338 else
1339 working.write(JUMP_FAR_O16);
1340 break;
1342 case 0xeb: working.write(JUMP_O8); break; //JMP Jb
1344 case 0xf4: working.write(HALT); break; //HLT
1346 case 0xf5: working.write(CMC); break; //CMC
1348 case 0xf6: //UNA GP3 Eb
1349 switch (modrm & 0x38) {
1350 case 0x00:
1351 working.write(AND); break;
1352 case 0x10:
1353 working.write(NOT); break;
1354 case 0x18:
1355 working.write(NEG); break;
1356 case 0x20:
1357 working.write(MUL_O8); break;
1358 case 0x28:
1359 working.write(IMULA_O8); break;
1360 case 0x30:
1361 working.write(DIV_O8); break;
1362 case 0x38:
1363 working.write(IDIV_O8); break;
1364 default: throw new IllegalStateException("Invalid Gp 3 Instruction F6 /" + ((modrm & 0x38) >> 3) + "?");
1366 break;
1368 case 0xf7: //UNA GP3 Ev
1369 if ((prefices & PREFICES_OPERAND) != 0) {
1370 switch (modrm & 0x38) {
1371 case 0x00:
1372 working.write(AND); break;
1373 case 0x10:
1374 working.write(NOT); break;
1375 case 0x18:
1376 working.write(NEG); break;
1377 case 0x20:
1378 working.write(MUL_O32); break;
1379 case 0x28:
1380 working.write(IMULA_O32); break;
1381 case 0x30:
1382 working.write(DIV_O32); break;
1383 case 0x38:
1384 working.write(IDIV_O32); break;
1385 default: throw new IllegalStateException("Invalid Gp 3 Instruction O16 F7 /" + ((modrm & 0x38) >> 3) + "?");
1387 } else {
1388 switch (modrm & 0x38) {
1389 case 0x00:
1390 working.write(AND); break;
1391 case 0x10:
1392 working.write(NOT); break;
1393 case 0x18:
1394 working.write(NEG); break;
1395 case 0x20:
1396 working.write(MUL_O16); break;
1397 case 0x28:
1398 working.write(IMULA_O16); break;
1399 case 0x30:
1400 working.write(DIV_O16); break;
1401 case 0x38:
1402 working.write(IDIV_O16); break;
1403 default: throw new IllegalStateException("Invalid Gp 3 Instruction O32 F7 /" + ((modrm & 0x38) >> 3) + "?");
1406 break;
1408 case 0xf8: working.write(CLC); break; //CLC
1409 case 0xf9: working.write(STC); break; //STC
1410 case 0xfa: working.write(CLI); break; //CLI
1411 case 0xfb: working.write(STI); decodeLimit = 2; // let one more instruction be decoded
1412 break; //STI
1413 case 0xfc: working.write(CLD); break; //CLD
1414 case 0xfd: working.write(STD); break; //STD
1416 case 0xfe:
1417 switch (modrm & 0x38) {
1418 case 0x00: //INC Eb
1419 working.write(INC); break;
1420 case 0x08: //DEC Eb
1421 working.write(DEC); break;
1422 default: throw new IllegalStateException("Invalid Gp 4 Instruction FE /" + ((modrm & 0x38) >> 3) + "?");
1424 break;
1426 case 0xff:
1427 switch (modrm & 0x38) {
1428 case 0x00: //INC Ev
1429 working.write(INC); break;
1430 case 0x08: //DEC Ev
1431 working.write(DEC); break;
1432 case 0x10:
1433 switch (prefices & PREFICES_OPERAND) {
1434 case 0:
1435 working.write(CALL_ABS_O16); break;
1436 case PREFICES_OPERAND:
1437 working.write(CALL_ABS_O32); break;
1439 break;
1440 case 0x18:
1441 switch (prefices & PREFICES_OPERAND) {
1442 case 0:
1443 working.write(CALL_FAR_O16); break;
1444 case PREFICES_OPERAND:
1445 working.write(CALL_FAR_O32); break;
1447 break;
1448 case 0x20:
1449 if ((prefices & PREFICES_OPERAND) != 0)
1450 working.write(JUMP_ABS_O32);
1451 else
1452 working.write(JUMP_ABS_O16);
1453 break;
1454 case 0x28:
1455 if ((prefices & PREFICES_OPERAND) != 0)
1456 working.write(JUMP_FAR_O32);
1457 else
1458 working.write(JUMP_FAR_O16);
1459 break;
1460 case 0x30:
1461 switch (prefices & PREFICES_OPERAND) {
1462 case 0:
1463 working.write(PUSH_O16); break;
1464 case PREFICES_OPERAND:
1465 working.write(PUSH_O32); break;
1467 break;
1468 default: throw new IllegalStateException("Invalid Gp 5 Instruction FF /" + ((modrm & 0x38) >> 3) + "?");
1470 break;
1472 //case 0x63: working.write(UNDEFINED); break; //ARPL
1473 case 0x90:
1474 working.write(MEM_RESET); //use mem_reset as Nop
1475 break;
1477 case 0x86: //XCHG Eb, Gb
1478 case 0x87: //XCHG Ev, Gv
1479 case 0x88: //MOV Eb, Gb
1480 case 0x89: //MOV Ev, Gv
1481 case 0x8a: //MOV Gb, Eb
1482 case 0x8b: //MOV Gv, Ev
1483 case 0x8c: //MOV Ew, Sw
1484 case 0x8d: //LEA Gv, M
1485 case 0x8e: //MOV Sw, Ew
1487 //case 0x90: //NOP
1488 case 0x91: //XCHG eAX, eCX
1489 case 0x92: //XCHG eAX, eCX
1490 case 0x93: //XCHG eAX, eCX
1491 case 0x94: //XCHG eAX, eCX
1492 case 0x95: //XCHG eAX, eCX
1493 case 0x96: //XCHG eAX, eCX
1494 case 0x97: //XCHG eAX, eCX
1496 case 0xa0: //MOV AL, Ob
1497 case 0xa1: //MOV eAX, Ov
1498 case 0xa2: //MOV Ob, AL
1499 case 0xa3: //MOV Ov, eAX
1501 case 0xb0: //MOV AL, Ib
1502 case 0xb1: //MOV CL, Ib
1503 case 0xb2: //MOV DL, Ib
1504 case 0xb3: //MOV BL, Ib
1505 case 0xb4: //MOV AH, Ib
1506 case 0xb5: //MOV CH, Ib
1507 case 0xb6: //MOV DH, Ib
1508 case 0xb7: //MOV BH, Ib
1510 case 0xb8: //MOV eAX, Iv
1511 case 0xb9: //MOV eCX, Iv
1512 case 0xba: //MOV eDX, Iv
1513 case 0xbb: //MOV eBX, Iv
1514 case 0xbc: //MOV eSP, Iv
1515 case 0xbd: //MOV eBP, Iv
1516 case 0xbe: //MOV eSI, Iv
1517 case 0xbf: //MOV eDI, Iv
1519 case 0xc4: //LES
1520 case 0xc5: //LDS
1521 case 0xc6: //MOV GP11 Eb, Gb
1522 case 0xc7: //MOV GP11 Ev, Gv
1524 case 0xd7: //XLAT
1525 break;
1526 case 0x0fff:
1527 working.write(UNDEFINED); //this is encountered with win95 - not clear what to do
1528 break;
1530 default:
1531 throw new IllegalStateException("Missing Operation: 0x" + Integer.toHexString(opcode));
1533 //2 Byte Operations
1535 case 0xf00: // Group 6
1536 switch (modrm & 0x38) {
1537 case 0x00:
1538 working.write(SLDT); break;
1539 case 0x08:
1540 working.write(STR); break;
1541 case 0x10:
1542 working.write(LLDT); break;
1543 case 0x18:
1544 working.write(LTR); break;
1545 case 0x20:
1546 working.write(VERR); break;
1547 case 0x28:
1548 working.write(VERW); break;
1549 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F 00 /" + ((modrm & 0x38) >> 3) + "?");
1550 } break;
1552 case 0xf01:
1553 switch (modrm & 0x38) {
1554 case 0x00:
1555 if ((prefices & PREFICES_OPERAND) != 0)
1556 working.write(SGDT_O32);
1557 else
1558 working.write(SGDT_O16);
1559 break;
1560 case 0x08:
1561 if ((prefices & PREFICES_OPERAND) != 0)
1562 working.write(SIDT_O32);
1563 else
1564 working.write(SIDT_O16);
1565 break;
1566 case 0x10:
1567 if ((prefices & PREFICES_OPERAND) != 0)
1568 working.write(LGDT_O32);
1569 else
1570 working.write(LGDT_O16);
1571 break;
1572 case 0x18:
1573 if ((prefices & PREFICES_OPERAND) != 0)
1574 working.write(LIDT_O32);
1575 else
1576 working.write(LIDT_O16);
1577 break;
1578 case 0x20:
1579 working.write(SMSW); break;
1580 case 0x30:
1581 working.write(LMSW); break;
1582 case 0x38:
1583 working.write(INVLPG); break;
1584 default: throw new IllegalStateException("Invalid Gp 7 Instruction 0F 01 /" + ((modrm & 0x38) >> 3) + "?");
1585 } break;
1587 case 0xf02: // not thoroughly tested yet Load access right byte
1588 working.write(LAR);
1589 break;
1591 case 0xf03: // not thoroughly tested yet Load Segment size right byte
1592 working.write(LSL);
1593 break;
1597 case 0xf06: working.write(CLTS); break; //CLTS
1599 case 0xf09: working.write(CPL_CHECK); break; //WBINVD
1601 case 0xf0b: working.write(UNDEFINED); break;
1602 case 0xf1f: working.write(MEM_RESET); break; //multi byte NOP (read latest manual)
1604 case 0xf30: working.write(WRMSR); break; //WRMSR
1605 case 0xf31: working.write(RDTSC); break; //RDTSC
1606 case 0xf32: working.write(RDMSR); break; //RDMSR
1608 case 0xf34: working.write(SYSENTER); break; //SYSENTER
1609 case 0xf35: working.write(SYSEXIT); break; //SYSEXIT
1611 case 0xf40: working.write(CMOVO); break; //CMOVO
1612 case 0xf41: working.write(CMOVNO); break; //CMOVNO
1613 case 0xf42: working.write(CMOVC); break; //CMOVC
1614 case 0xf43: working.write(CMOVNC); break; //CMOVNC
1615 case 0xf44: working.write(CMOVZ); break; //CMOVZ
1616 case 0xf45: working.write(CMOVNZ); break; //CMOVNZ
1617 case 0xf46: working.write(CMOVNA); break; //CMOVNA
1618 case 0xf47: working.write(CMOVA); break; //CMOVA
1619 case 0xf48: working.write(CMOVS); break; //CMOVS
1620 case 0xf49: working.write(CMOVNS); break; //CMOVNS
1621 case 0xf4a: working.write(CMOVP); break; //CMOVP
1622 case 0xf4b: working.write(CMOVNP); break; //CMOVNP
1623 case 0xf4c: working.write(CMOVL); break; //CMOVL
1624 case 0xf4d: working.write(CMOVNL); break; //CMOVNL
1625 case 0xf4e: working.write(CMOVNG); break; //CMOVNG
1626 case 0xf4f: working.write(CMOVG); break; //CMOVG
1628 case 0xf80: if ((prefices & PREFICES_OPERAND) != 0)
1629 working.write(JO_O32);
1630 else
1631 working.write(JO_O16);
1632 break; //JO Jb
1633 case 0xf81: if ((prefices & PREFICES_OPERAND) != 0)
1634 working.write(JNO_O32);
1635 else
1636 working.write(JNO_O16);
1637 break; //JNO Jb
1638 case 0xf82: if ((prefices & PREFICES_OPERAND) != 0)
1639 working.write(JC_O32);
1640 else
1641 working.write(JC_O16);
1642 break; //JC Jb
1643 case 0xf83: if ((prefices & PREFICES_OPERAND) != 0)
1644 working.write(JNC_O32);
1645 else
1646 working.write(JNC_O16);
1647 break; //JNC Jb
1648 case 0xf84: if ((prefices & PREFICES_OPERAND) != 0)
1649 working.write(JZ_O32);
1650 else
1651 working.write(JZ_O16);
1652 break; //JZ Jb
1653 case 0xf85: if ((prefices & PREFICES_OPERAND) != 0)
1654 working.write(JNZ_O32);
1655 else
1656 working.write(JNZ_O16);
1657 break; //JNZ Jb
1658 case 0xf86: if ((prefices & PREFICES_OPERAND) != 0)
1659 working.write(JNA_O32);
1660 else
1661 working.write(JNA_O16);
1662 break; //JNA Jb
1663 case 0xf87: if ((prefices & PREFICES_OPERAND) != 0)
1664 working.write(JA_O32);
1665 else
1666 working.write(JA_O16);
1667 break; //JA Jb
1668 case 0xf88: if ((prefices & PREFICES_OPERAND) != 0)
1669 working.write(JS_O32);
1670 else
1671 working.write(JS_O16);
1672 break; //JS Jb
1673 case 0xf89: if ((prefices & PREFICES_OPERAND) != 0)
1674 working.write(JNS_O32);
1675 else
1676 working.write(JNS_O16);
1677 break; //JNS Jb
1678 case 0xf8a: if ((prefices & PREFICES_OPERAND) != 0)
1679 working.write(JP_O32);
1680 else
1681 working.write(JP_O16);
1682 break; //JP Jb
1683 case 0xf8b: if ((prefices & PREFICES_OPERAND) != 0)
1684 working.write(JNP_O32);
1685 else
1686 working.write(JNP_O16);
1687 break; //JNP Jb
1688 case 0xf8c: if ((prefices & PREFICES_OPERAND) != 0)
1689 working.write(JL_O32);
1690 else
1691 working.write(JL_O16);
1692 break; //JL Jb
1693 case 0xf8d: if ((prefices & PREFICES_OPERAND) != 0)
1694 working.write(JNL_O32);
1695 else
1696 working.write(JNL_O16);
1697 break; //JNL Jb
1698 case 0xf8e: if ((prefices & PREFICES_OPERAND) != 0)
1699 working.write(JNG_O32);
1700 else
1701 working.write(JNG_O16);
1702 break; //JNG Jb
1703 case 0xf8f: if ((prefices & PREFICES_OPERAND) != 0)
1704 working.write(JG_O32);
1705 else
1706 working.write(JG_O16);
1707 break; //JG Jb
1709 case 0xf90: working.write(SETO); break; //SETO
1710 case 0xf91: working.write(SETNO); break; //SETNO
1711 case 0xf92: working.write(SETC); break; //SETC
1712 case 0xf93: working.write(SETNC); break; //SETNC
1713 case 0xf94: working.write(SETZ); break; //SETZ
1714 case 0xf95: working.write(SETNZ); break; //SETNZ
1715 case 0xf96: working.write(SETNA); break; //SETNA
1716 case 0xf97: working.write(SETA); break; //SETA
1717 case 0xf98: working.write(SETS); break; //SETS
1718 case 0xf99: working.write(SETNS); break; //SETNS
1719 case 0xf9a: working.write(SETP); break; //SETP
1720 case 0xf9b: working.write(SETNP); break; //SETNP
1721 case 0xf9c: working.write(SETL); break; //SETL
1722 case 0xf9d: working.write(SETNL); break; //SETNL
1723 case 0xf9e: working.write(SETNG); break; //SETNG
1724 case 0xf9f: working.write(SETG); break; //SETG
1726 case 0xfa2: working.write(CPUID); break; //CPUID
1728 case 0xfa4: //SHLD Ev, Gv, Ib
1729 case 0xfa5: //SHLD Ev, Gv, CL
1730 if ((prefices & PREFICES_OPERAND) != 0)
1731 working.write(SHLD_O32);
1732 else
1733 working.write(SHLD_O16);
1734 break;
1736 case 0xfac: //SHRD Ev, Gv, Ib
1737 case 0xfad: //SHRD Ev, Gv, CL
1738 if ((prefices & PREFICES_OPERAND) != 0)
1739 working.write(SHRD_O32);
1740 else
1741 working.write(SHRD_O16);
1742 break;
1743 // case 0xfae:
1744 // working.write(FXSAVE);
1745 // break;
1746 case 0xfb0: //CMPXCHG Eb, Gb
1747 case 0xfb1: //CMPXCHG Ev, Gv
1748 working.write(CMPXCHG); break;
1750 case 0xfa3: //BT Ev, Gv
1751 switch (modrm & 0xc7) {
1752 default: working.write(BT_MEM); break;
1754 case 0xc0:
1755 case 0xc1:
1756 case 0xc2:
1757 case 0xc3:
1758 case 0xc4:
1759 case 0xc5:
1760 case 0xc6:
1761 case 0xc7:
1762 if ((prefices & PREFICES_OPERAND) != 0)
1763 working.write(BT_O32);
1764 else
1765 working.write(BT_O16);
1766 break;
1767 } break;
1769 case 0xfab: //BTS Ev, Gv
1770 switch (modrm & 0xc7) {
1771 default: working.write(BTS_MEM); break;
1773 case 0xc0:
1774 case 0xc1:
1775 case 0xc2:
1776 case 0xc3:
1777 case 0xc4:
1778 case 0xc5:
1779 case 0xc6:
1780 case 0xc7:
1781 if ((prefices & PREFICES_OPERAND) != 0)
1782 working.write(BTS_O32);
1783 else
1784 working.write(BTS_O16);
1785 break;
1786 } break;
1788 case 0xfb3: //BTR Ev, Gv
1789 switch (modrm & 0xc7) {
1790 default: working.write(BTR_MEM); break;
1792 case 0xc0:
1793 case 0xc1:
1794 case 0xc2:
1795 case 0xc3:
1796 case 0xc4:
1797 case 0xc5:
1798 case 0xc6:
1799 case 0xc7:
1800 if ((prefices & PREFICES_OPERAND) != 0)
1801 working.write(BTR_O32);
1802 else
1803 working.write(BTR_O16);
1804 break;
1805 } break;
1807 case 0xfbb: //BTC Ev, Gv
1808 switch (modrm & 0xc7) {
1809 default: working.write(BTC_MEM); break;
1811 case 0xc0:
1812 case 0xc1:
1813 case 0xc2:
1814 case 0xc3:
1815 case 0xc4:
1816 case 0xc5:
1817 case 0xc6:
1818 case 0xc7:
1819 if ((prefices & PREFICES_OPERAND) != 0)
1820 working.write(BTC_O32);
1821 else
1822 working.write(BTC_O16);
1823 break;
1824 } break;
1826 case 0xfba: //Grp 8 Ev, Ib
1827 switch (modrm & 0x38) {
1828 case 0x20:
1829 switch (modrm & 0xc7) {
1830 default: working.write(BT_MEM); break;
1831 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1832 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1833 if ((prefices & PREFICES_OPERAND) != 0)
1834 working.write(BT_O32);
1835 else
1836 working.write(BT_O16);
1837 break;
1838 } break;
1839 case 0x28:
1840 switch (modrm & 0xc7) {
1841 default: working.write(BTS_MEM); break;
1842 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1843 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1844 if ((prefices & PREFICES_OPERAND) != 0)
1845 working.write(BTS_O32);
1846 else
1847 working.write(BTS_O16);
1848 break;
1849 } break;
1850 case 0x30:
1851 switch (modrm & 0xc7) {
1852 default: working.write(BTR_MEM); break;
1853 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1854 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1855 if ((prefices & PREFICES_OPERAND) != 0)
1856 working.write(BTR_O32);
1857 else
1858 working.write(BTR_O16);
1859 break;
1860 } break;
1861 case 0x38:
1862 switch (modrm & 0xc7) {
1863 default: working.write(BTC_MEM); break;
1864 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1865 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1866 if ((prefices & PREFICES_OPERAND) != 0)
1867 working.write(BTC_O32);
1868 else
1869 working.write(BTC_O16);
1870 break;
1871 } break;
1872 default: throw new IllegalStateException("Invalid Gp 8 Instruction 0F BA /" + ((modrm & 0x38) >> 3) + "?");
1873 } break;
1875 case 0xfbc: working.write(BSF); break; //BSF Gv, Ev
1876 case 0xfbd: working.write(BSR); break; //BSR Gv, Ev
1878 case 0xfbe: //MOVSX Gv, Eb
1879 if ((prefices & PREFICES_OPERAND) != 0)
1880 working.write(SIGN_EXTEND_8_32);
1881 else
1882 working.write(SIGN_EXTEND_8_16);
1883 break;
1884 case 0xfbf: //MOVSX Gv, Ew
1885 if ((prefices & PREFICES_OPERAND) != 0)
1886 working.write(SIGN_EXTEND_16_32);
1887 break;
1889 case 0xfc7:
1890 switch (modrm & 0x38)
1892 case 0x08: working.write(CMPXCHG8B); break;
1893 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm & 0x38) >> 3) + "?");
1895 break;
1897 case 0xfc8:
1898 case 0xfc9:
1899 case 0xfca:
1900 case 0xfcb:
1901 case 0xfcc:
1902 case 0xfcd:
1903 case 0xfce:
1904 case 0xfcf:
1905 working.write(BSWAP); break;
1907 case 0xf20: //MOV Rd, Cd
1908 case 0xf21: //MOV Rd, Dd
1909 case 0xf22: //MOV Cd, Rd
1910 case 0xf23: //MOV Dd, Rd
1911 case 0xfb2: //LSS Mp
1912 case 0xfb4: //LFS Mp
1913 case 0xfb5: //LGS Mp
1914 case 0xfb6: //MOVZX Gv, Eb
1915 case 0xfb7: //MOVZX Gv, Ew
1916 break;
1918 case 0xd800:
1919 switch (modrm & 0x38)
1921 case 0x00: working.write(FADD); break;
1922 case 0x08: working.write(FMUL); break;
1923 case 0x10:
1924 case 0x18: working.write(FCOM); break;
1925 case 0x20:
1926 case 0x28: working.write(FSUB); break;
1927 case 0x30:
1928 case 0x38: working.write(FDIV); break;
1930 break;
1932 case 0xd900:
1933 if ((modrm & 0xc0) != 0xc0)
1935 switch (modrm & 0x38)
1937 case 0x00: working.write(FPUSH); break;
1938 case 0x10:
1939 case 0x18:
1940 case 0x28:
1941 case 0x38: break;
1942 case 0x20:
1943 if ((prefices & PREFICES_OPERAND) != 0)
1944 working.write(FLDENV_28);
1945 else
1946 working.write(FLDENV_14);
1947 break;
1948 case 0x30:
1949 if ((prefices & PREFICES_OPERAND) != 0)
1950 working.write(FSTENV_28);
1951 else
1952 working.write(FSTENV_14);
1953 break;
1956 else
1958 switch (modrm & 0xf8)
1960 case 0xc0: working.write(FPUSH); break;
1961 case 0xc8: break;
1963 switch (modrm)
1965 case 0xd0: break;
1966 case 0xe0: working.write(FCHS); break;
1967 case 0xe1: working.write(FABS); break;
1968 case 0xe4: working.write(FCOM); break;
1969 case 0xe5: working.write(FXAM); break;
1970 case 0xe8:
1971 case 0xe9:
1972 case 0xea:
1973 case 0xeb:
1974 case 0xec:
1975 case 0xed:
1976 case 0xee: working.write(FPUSH); break;
1977 case 0xf0: working.write(F2XM1); break;
1978 case 0xf1: working.write(FYL2X); break;
1979 case 0xf2: working.write(FPTAN); break;
1980 case 0xf3: working.write(FPATAN); break;
1981 case 0xf4: working.write(FXTRACT); break;
1982 case 0xf5: working.write(FPREM1); break;
1983 case 0xf6: working.write(FDECSTP); break;
1984 case 0xf7: working.write(FINCSTP); break;
1985 case 0xf8: working.write(FPREM); break;
1986 case 0xf9: working.write(FYL2XP1); break;
1987 case 0xfa: working.write(FSQRT); break;
1988 case 0xfb: working.write(FSINCOS); break;
1989 case 0xfc: working.write(FRNDINT); break;
1990 case 0xfd: working.write(FSCALE); break;
1991 case 0xfe: working.write(FSIN); break;
1992 case 0xff: working.write(FCOS); break;
1995 break;
1997 case 0xda00:
1998 if ((modrm & 0xc0) != 0xc0)
2000 switch (modrm & 0x38)
2002 case 0x00: working.write(FADD); break;
2003 case 0x08: working.write(FMUL); break;
2004 case 0x10:
2005 case 0x18: working.write(FCOM); break;
2006 case 0x20:
2007 case 0x28: working.write(FSUB); break;
2008 case 0x30:
2009 case 0x38: working.write(FDIV); break;
2012 else
2014 switch (modrm & 0xf8)
2016 case 0xc0: working.write(FCMOVB); break;
2017 case 0xc8: working.write(FCMOVE); break;
2018 case 0xd0: working.write(FCMOVBE); break;
2019 case 0xd8: working.write(FCMOVU); break;
2021 switch (modrm)
2023 case 0xe9: working.write(FUCOM); break;
2026 break;
2028 case 0xdb00:
2029 if ((modrm & 0xc0) != 0xc0)
2031 switch (modrm & 0x38)
2033 case 0x00: working.write(FPUSH); break;
2034 case 0x08: working.write(FCHOP); break;
2035 case 0x10:
2036 case 0x18: working.write(FRNDINT); break;
2037 case 0x28: working.write(FPUSH); break;
2038 case 0x38: break;
2041 else
2043 switch (modrm & 0xf8)
2045 case 0xc0: working.write(FCMOVNB); break;
2046 case 0xc8: working.write(FCMOVNE); break;
2047 case 0xd0: working.write(FCMOVNBE); break;
2048 case 0xd8: working.write(FCMOVNU); break;
2049 case 0xe8: working.write(FUCOMI); break;
2050 case 0xf0: working.write(FCOMI); break;
2052 switch (modrm)
2054 case 0xe2: working.write(FCLEX); break;
2055 case 0xe3: working.write(FINIT); break;
2056 case 0xe4: break;
2059 break;
2061 case 0xdc00:
2062 switch (modrm & 0x38)
2064 case 0x00: working.write(FADD); break;
2065 case 0x08: working.write(FMUL); break;
2066 case 0x10:
2067 case 0x18: working.write(FCOM); break;
2068 case 0x20:
2069 case 0x28: working.write(FSUB); break;
2070 case 0x30:
2071 case 0x38: working.write(FDIV); break;
2073 break;
2075 case 0xdd00:
2076 if ((modrm & 0xc0) != 0xc0)
2078 switch (modrm & 0x38)
2080 case 0x00: working.write(FPUSH); break;
2081 case 0x08: working.write(FCHOP); break;
2082 case 0x10:
2083 case 0x18:
2084 case 0x38: break;
2085 case 0x20:
2086 if ((prefices & PREFICES_OPERAND) != 0)
2087 working.write(FRSTOR_108);
2088 else
2089 working.write(FRSTOR_94);
2090 break;
2091 case 0x30:
2092 if ((prefices & PREFICES_OPERAND) != 0)
2093 working.write(FSAVE_108);
2094 else
2095 working.write(FSAVE_94);
2096 break;
2099 else
2101 switch (modrm & 0xf8)
2103 case 0xc0: working.write(FFREE); break;
2104 case 0xd0:
2105 case 0xd8: break;
2106 case 0xe0:
2107 case 0xe8: working.write(FUCOM); break;
2110 break;
2112 case 0xde00:
2113 switch (modrm)
2115 case 0xd9: working.write(FCOM); break;
2116 default:
2117 switch (modrm & 0x38)
2119 case 0x00: working.write(FADD); break;
2120 case 0x08: working.write(FMUL); break;
2121 case 0x10:
2122 case 0x18: working.write(FCOM); break;
2123 case 0x20:
2124 case 0x28: working.write(FSUB); break;
2125 case 0x30:
2126 case 0x38: working.write(FDIV); break;
2129 break;
2131 case 0xdf00:
2132 if ((modrm & 0xc0) != 0xc0)
2134 switch (modrm & 0x38)
2136 case 0x00: working.write(FPUSH); break;
2137 case 0x08: working.write(FCHOP); break;
2138 case 0x10:
2139 case 0x18:
2140 case 0x38: working.write(FRNDINT); break;
2141 case 0x20: working.write(FBCD2F); break;
2142 case 0x28: working.write(FPUSH); break;
2143 case 0x30: working.write(FF2BCD); break;
2146 else
2148 switch (modrm & 0xf8)
2150 case 0xe8: working.write(FUCOMI); break;
2151 case 0xf0: working.write(FCOMI); break;
2154 break;
2159 private void writeFlags(int prefices, int opcode, int modrm)
2161 switch (opcode) {
2162 case 0x00: //ADD Eb, Gb
2163 case 0x02: //ADD Gb, Eb
2164 case 0x04: //ADD AL, Ib
2165 case 0xfc0: //XADD Eb, Gb
2166 working.write(ADD_O8_FLAGS); break;
2168 case 0x10: //ADC Eb, Gb
2169 case 0x12: //ADC Gb, Eb
2170 case 0x14: //ADC AL, Ib
2171 working.write(ADC_O8_FLAGS); break;
2173 case 0x18: //SBB Eb, Gb
2174 case 0x1a: //SBB Gb, Eb
2175 case 0x1c: //SBB AL, Ib
2176 working.write(SBB_O8_FLAGS); break;
2178 case 0x28: //SUB Eb, Gb
2179 case 0x2a: //SUB Gb, Eb
2180 case 0x2c: //SUB AL, Ib
2181 case 0x38: //CMP Eb, Gb
2182 case 0x3a: //CMP Gb, Eb
2183 case 0x3c: //CMP AL, Ib
2184 working.write(SUB_O8_FLAGS); break;
2186 case 0x01: //ADD Ev, Gv
2187 case 0x03: //ADD Gv, Ev
2188 case 0x05: //ADD eAX, Iv
2189 case 0xfc1: //XADD Ev, Gv
2190 if ((prefices & PREFICES_OPERAND) != 0)
2191 working.write(ADD_O32_FLAGS);
2192 else
2193 working.write(ADD_O16_FLAGS);
2194 break;
2196 case 0x11: //ADC Ev, Gv
2197 case 0x13: //ADC Gv, Ev
2198 case 0x15: //ADC eAX, Iv
2199 if ((prefices & PREFICES_OPERAND) != 0)
2200 working.write(ADC_O32_FLAGS);
2201 else
2202 working.write(ADC_O16_FLAGS);
2203 break;
2205 case 0x19: //SBB Ev, Gv
2206 case 0x1b: //SBB Gv, Ev
2207 case 0x1d: //SBB eAX, Iv
2208 if ((prefices & PREFICES_OPERAND) != 0)
2209 working.write(SBB_O32_FLAGS);
2210 else
2211 working.write(SBB_O16_FLAGS);
2212 break;
2214 case 0x29: //SUB Ev, Gv
2215 case 0x2b: //SUB Gv, Ev
2216 case 0x2d: //SUB eAX, Iv
2217 case 0x39: //CMP Ev, Gv
2218 case 0x3b: //CMP Gv, Ev
2219 case 0x3d: //CMP eAX, Iv
2220 if ((prefices & PREFICES_OPERAND) != 0)
2221 working.write(SUB_O32_FLAGS);
2222 else
2223 working.write(SUB_O16_FLAGS);
2224 break;
2226 case 0x08: //OR Eb, Gb
2227 case 0x0a: //OR Gb, Eb
2228 case 0x0c: //OR AL, Ib
2229 case 0x20: //AND Eb, Gb
2230 case 0x22: //AND Gb, Eb
2231 case 0x24: //AND AL, Ib
2232 case 0x30: //XOR Eb, Gb
2233 case 0x32: //XOR Gb, Eb
2234 case 0x34: //XOR AL, Ib
2235 case 0x84: //TEST Eb, Gb
2236 case 0xa8: //TEST AL, Ib
2237 working.write(BITWISE_FLAGS_O8); break;
2239 case 0x09: //OR Ev, Gv
2240 case 0x0b: //OR Gv, Ev
2241 case 0x0d: //OR eAX, Iv
2242 case 0x21: //AND Ev, Gv
2243 case 0x23: //AND Gv, Ev
2244 case 0x25: //AND eAX, Iv
2245 case 0x31: //XOR Ev, Gv
2246 case 0x33: //XOR Gv, Ev
2247 case 0x35: //XOR eAX, Iv
2248 case 0x85: //TEST Ev, Gv
2249 case 0xa9: //TEST eAX, Iv
2250 if ((prefices & PREFICES_OPERAND) != 0)
2251 working.write(BITWISE_FLAGS_O32);
2252 else
2253 working.write(BITWISE_FLAGS_O16);
2254 break;
2256 case 0x40: //INC eAX
2257 case 0x41: //INC eCX
2258 case 0x42: //INC eDX
2259 case 0x43: //INC eBX
2260 case 0x44: //INC eSP
2261 case 0x45: //INC eBP
2262 case 0x46: //INC eSI
2263 case 0x47: //INC eDI
2264 if ((prefices & PREFICES_OPERAND) != 0)
2265 working.write(INC_O32_FLAGS);
2266 else
2267 working.write(INC_O16_FLAGS);
2268 break;
2270 case 0x48: //DEC eAX
2271 case 0x49: //DEC eCX
2272 case 0x4a: //DEC eDX
2273 case 0x4b: //DEC eBX
2274 case 0x4c: //DEC eSP
2275 case 0x4d: //DEC eBP
2276 case 0x4e: //DEC eSI
2277 case 0x4f: //DEC eDI
2278 if ((prefices & PREFICES_OPERAND) != 0)
2279 working.write(DEC_O32_FLAGS);
2280 else
2281 working.write(DEC_O16_FLAGS);
2282 break;
2284 case 0x80: //IMM GP1 Eb, Ib
2285 case 0x82: //IMM GP1 Eb, Ib
2286 switch (modrm & 0x38) {
2287 case 0x00:
2288 working.write(ADD_O8_FLAGS); break;
2289 case 0x08:
2290 working.write(BITWISE_FLAGS_O8); break;
2291 case 0x10:
2292 working.write(ADC_O8_FLAGS); break;
2293 case 0x18:
2294 working.write(SBB_O8_FLAGS); break;
2295 case 0x20:
2296 working.write(BITWISE_FLAGS_O8); break;
2297 case 0x28:
2298 case 0x38:
2299 working.write(SUB_O8_FLAGS); break;
2300 case 0x30:
2301 working.write(BITWISE_FLAGS_O8); break;
2303 break;
2305 case 0x81: //IMM GP1 Ev, Iv
2306 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
2307 if ((prefices & PREFICES_OPERAND) != 0) {
2308 switch (modrm & 0x38) {
2309 case 0x00:
2310 working.write(ADD_O32_FLAGS); break;
2311 case 0x08:
2312 working.write(BITWISE_FLAGS_O32); break;
2313 case 0x10:
2314 working.write(ADC_O32_FLAGS); break;
2315 case 0x18:
2316 working.write(SBB_O32_FLAGS); break;
2317 case 0x20:
2318 working.write(BITWISE_FLAGS_O32); break;
2319 case 0x28:
2320 case 0x38:
2321 working.write(SUB_O32_FLAGS); break;
2322 case 0x30:
2323 working.write(BITWISE_FLAGS_O32); break;
2325 } else {
2326 switch (modrm & 0x38) {
2327 case 0x00:
2328 working.write(ADD_O16_FLAGS); break;
2329 case 0x08:
2330 working.write(BITWISE_FLAGS_O16); break;
2331 case 0x10:
2332 working.write(ADC_O16_FLAGS); break;
2333 case 0x18:
2334 working.write(SBB_O16_FLAGS); break;
2335 case 0x20:
2336 working.write(BITWISE_FLAGS_O16); break;
2337 case 0x28:
2338 case 0x38:
2339 working.write(SUB_O16_FLAGS); break;
2340 case 0x30:
2341 working.write(BITWISE_FLAGS_O16); break;
2344 break;
2346 case 0xc0:
2347 case 0xd0:
2348 case 0xd2:
2349 switch (modrm & 0x38) {
2350 case 0x00:
2351 working.write(ROL_O8_FLAGS); break;
2352 case 0x08:
2353 working.write(ROR_O8_FLAGS); break;
2354 case 0x10:
2355 working.write(RCL_O8_FLAGS); break;
2356 case 0x18:
2357 working.write(RCR_O8_FLAGS); break;
2358 case 0x20:
2359 working.write(SHL_O8_FLAGS); break;
2360 case 0x28:
2361 working.write(SHR_O8_FLAGS); break;
2362 case 0x30:
2363 System.err.println("Emulated: invalid SHL encoding");
2364 working.write(SHL_O8_FLAGS); break;
2365 case 0x38:
2366 working.write(SAR_O8_FLAGS); break;
2368 break;
2370 case 0xc1:
2371 case 0xd1:
2372 case 0xd3:
2373 if ((prefices & PREFICES_OPERAND) != 0) {
2374 switch (modrm & 0x38) {
2375 case 0x00:
2376 working.write(ROL_O32_FLAGS); break;
2377 case 0x08:
2378 working.write(ROR_O32_FLAGS); break;
2379 case 0x10:
2380 working.write(RCL_O32_FLAGS); break;
2381 case 0x18:
2382 working.write(RCR_O32_FLAGS); break;
2383 case 0x20:
2384 working.write(SHL_O32_FLAGS); break;
2385 case 0x28:
2386 working.write(SHR_O32_FLAGS); break;
2387 case 0x30:
2388 working.write(SHL_O32_FLAGS); break;
2389 case 0x38:
2390 working.write(SAR_O32_FLAGS); break;
2392 } else {
2393 switch (modrm & 0x38) {
2394 case 0x00:
2395 working.write(ROL_O16_FLAGS); break;
2396 case 0x08:
2397 working.write(ROR_O16_FLAGS); break;
2398 case 0x10:
2399 working.write(RCL_O16_FLAGS); break;
2400 case 0x18:
2401 working.write(RCR_O16_FLAGS); break;
2402 case 0x20:
2403 working.write(SHL_O16_FLAGS); break;
2404 case 0x28:
2405 working.write(SHR_O16_FLAGS); break;
2406 case 0x30:
2407 working.write(SHL_O16_FLAGS); break;
2408 case 0x38:
2409 working.write(SAR_O16_FLAGS); break;
2412 break;
2414 case 0xf6: //UNA GP3 Eb
2415 switch (modrm & 0x38) {
2416 case 0x00:
2417 working.write(BITWISE_FLAGS_O8); break;
2418 case 0x18:
2419 working.write(NEG_O8_FLAGS); break;
2421 break;
2423 case 0xf7: //UNA GP3 Ev
2424 if ((prefices & PREFICES_OPERAND) != 0) {
2425 switch (modrm & 0x38) {
2426 case 0x00:
2427 working.write(BITWISE_FLAGS_O32); break;
2428 case 0x18:
2429 working.write(NEG_O32_FLAGS); break;
2431 } else {
2432 switch (modrm & 0x38) {
2433 case 0x00:
2434 working.write(BITWISE_FLAGS_O16); break;
2435 case 0x18:
2436 working.write(NEG_O16_FLAGS); break;
2439 break;
2441 case 0xfe:
2442 switch (modrm & 0x38) {
2443 case 0x00: //INC Eb
2444 working.write(INC_O8_FLAGS); break;
2445 case 0x08: //DEC Eb
2446 working.write(DEC_O8_FLAGS); break;
2448 break;
2450 case 0xff:
2451 switch (modrm & 0x38) {
2452 case 0x00: //INC Eb
2453 if ((prefices & PREFICES_OPERAND) != 0)
2454 working.write(INC_O32_FLAGS);
2455 else
2456 working.write(INC_O16_FLAGS);
2457 break;
2458 case 0x08: //DEC Eb
2459 if ((prefices & PREFICES_OPERAND) != 0)
2460 working.write(DEC_O32_FLAGS);
2461 else
2462 working.write(DEC_O16_FLAGS);
2463 break;
2465 break;
2467 case 0x07: //POP ES
2468 case 0x17: //POP SS
2469 case 0x1f: //POP DS
2470 case 0x58: //POP eAX
2471 case 0x59: //POP eCX
2472 case 0x5a: //POP eDX
2473 case 0x5b: //POP eBX
2474 case 0x5d: //POP eBP
2475 case 0x5e: //POP eSI
2476 case 0x5f: //POP eDI
2477 case 0xfa1: //POP FS
2478 case 0xfa9: working.write(STORE1_ESP); break; //POP GS
2481 case 0x8f: //POP Ev This is really annoying and not quite correct?
2482 for (int i = 0; i < working.getLength(); i++) {
2483 switch (working.getMicrocodeAt(i)) {
2484 case ADDR_SP:
2485 case ADDR_ESP:
2486 working.replace(i, ADDR_REG1);
2487 break;
2488 case ADDR_2ESP:
2489 working.replace(i, ADDR_2REG1);
2490 break;
2491 case ADDR_4ESP:
2492 working.replace(i, ADDR_4REG1);
2493 break;
2494 case ADDR_8ESP:
2495 working.replace(i, ADDR_8REG1);
2496 break;
2497 case ADDR_IB:
2498 case ADDR_IW:
2499 case ADDR_ID:
2500 i++;
2501 break;
2504 switch (working.getMicrocodeAt(working.getLength() - 1)) {
2505 case STORE0_ESP:
2506 case STORE0_SP: break;
2507 default: working.write(STORE1_ESP);
2509 break;
2511 case 0xcf: //IRET
2512 switch (prefices & PREFICES_OPERAND) {
2513 case 0:
2514 working.write(STORE0_FLAGS); break;
2515 case PREFICES_OPERAND:
2516 working.write(STORE0_EFLAGS); break;
2518 break;
2520 case 0xf1f: break; //NOP
2521 case 0xfa4: //SHLD Ev, Gv, Ib
2522 case 0xfa5: //SHLD Ev, Gv, CL
2523 if ((prefices & PREFICES_OPERAND) != 0)
2524 working.write(SHL_O32_FLAGS);
2525 else
2526 working.write(SHL_O16_FLAGS);
2527 break;
2529 case 0xfac: //SHRD Ev, Gv, Ib
2530 case 0xfad: //SHRD Ev, Gv, CL
2531 if ((prefices & PREFICES_OPERAND) != 0)
2532 working.write(SHR_O32_FLAGS);
2533 else
2534 working.write(SHR_O16_FLAGS);
2535 break;
2537 case 0xfb0: //CMPXCHG Eb, Gb
2538 working.write(CMPXCHG_O8_FLAGS); break;
2539 case 0xfb1: //CMPXCHG Ev, Gv
2540 if ((prefices & PREFICES_OPERAND) != 0)
2541 working.write(CMPXCHG_O32_FLAGS);
2542 else
2543 working.write(CMPXCHG_O16_FLAGS);
2544 break;
2546 case 0x06: //PUSH ES
2547 case 0x0e: //PUSH CS
2549 case 0x16: //PUSH SS
2550 case 0x1e: //PUSH DS
2552 case 0x27: //DAA
2553 case 0x2f: //DAS
2555 case 0x37: //AAA
2556 case 0x3f: //AAS
2558 case 0x50: //PUSH eAX
2559 case 0x51: //PUSH eCX
2560 case 0x52: //PUSH eDX
2561 case 0x53: //PUSH eBX
2562 case 0x54: //PUSH eSP
2563 case 0x55: //PUSH eBP
2564 case 0x56: //PUSH eSI
2565 case 0x57: //PUSH eDI
2566 case 0x5c: //POP eSP so don't write incremented stack pointer back
2568 case 0x60: //PUSHA/D
2569 case 0x61: //POPA/D
2570 case 0x62: //BOUND
2571 case 0x63: //#UD (ARPL)
2572 case 0x68: //PUSH Iv
2573 case 0x69: //IMUL Gv, Ev, Iv
2574 case 0x6a: //PUSH Ib
2575 case 0x6b: //IMUL Gv, Ev, Ib
2576 case 0x6c: //INSB
2577 case 0x6d: //INSW/D
2578 case 0x6e: //OUTSB
2579 case 0x6f: //OUTSW/D
2581 case 0x70: //JO Jb
2582 case 0x71: //JNO Jb
2583 case 0x72: //JC Jb
2584 case 0x73: //JNC Jb
2585 case 0x74: //JZ Jb
2586 case 0x75: //JNZ Jb
2587 case 0x76: //JNA Jb
2588 case 0x77: //JA Jb
2589 case 0x78: //JS Jb
2590 case 0x79: //JNS Jb
2591 case 0x7a: //JP Jb
2592 case 0x7b: //JNP Jb
2593 case 0x7c: //JL Jb
2594 case 0x7d: //JNL Jb
2595 case 0x7e: //JNG Jb
2596 case 0x7f: //JG Jb
2598 case 0x86: //XCHG Eb, Gb
2599 case 0x87: //XCHG Ev, Gv
2600 case 0x88: //MOV Eb, Gb
2601 case 0x89: //MOV Ev, Gv
2602 case 0x8a: //MOV Gb, Eb
2603 case 0x8b: //MOV Gv, Ev
2604 case 0x8c: //MOV Ew, Sw
2605 case 0x8d: //LEA Gv, M
2606 case 0x8e: //MOV Sw, Ew
2608 case 0x90: //NOP
2609 case 0x91: //XCHG eAX, eCX
2610 case 0x92: //XCHG eAX, eCX
2611 case 0x93: //XCHG eAX, eCX
2612 case 0x94: //XCHG eAX, eCX
2613 case 0x95: //XCHG eAX, eCX
2614 case 0x96: //XCHG eAX, eCX
2615 case 0x97: //XCHG eAX, eCX
2616 case 0x98: //CBW/CWDE
2617 case 0x99: //CWD/CDQ
2618 case 0x9a: //CALLF Ap
2619 case 0x9b: //FWAIT
2620 case 0x9c: //PUSHF
2621 case 0x9d: //POPF
2622 case 0x9e: //SAHF
2623 case 0x9f: //LAHF
2625 case 0xa0: //MOV AL, Ob
2626 case 0xa1: //MOV eAX, Ov
2627 case 0xa2: //MOV Ob, AL
2628 case 0xa3: //MOV Ov, eAX
2629 case 0xa4: //MOVSB
2630 case 0xa5: //MOVSW/D
2631 case 0xa6: //CMPSB
2632 case 0xa7: //CMPSW/D
2633 case 0xaa: //STOSB
2634 case 0xab: //STOSW/D
2635 case 0xac: //LODSB
2636 case 0xad: //LODSW/D
2637 case 0xae: //SCASB
2638 case 0xaf: //SCASW/D
2640 case 0xb0: //MOV AL, Ib
2641 case 0xb1: //MOV CL, Ib
2642 case 0xb2: //MOV DL, Ib
2643 case 0xb3: //MOV BL, Ib
2644 case 0xb4: //MOV AH, Ib
2645 case 0xb5: //MOV CH, Ib
2646 case 0xb6: //MOV DH, Ib
2647 case 0xb7: //MOV BH, Ib
2648 case 0xb8: //MOV eAX, Iv
2649 case 0xb9: //MOV eCX, Iv
2650 case 0xba: //MOV eDX, Iv
2651 case 0xbb: //MOV eBX, Iv
2652 case 0xbc: //MOV eSP, Iv
2653 case 0xbd: //MOV eBP, Iv
2654 case 0xbe: //MOV eSI, Iv
2655 case 0xbf: //MOV eDI, Iv
2657 case 0xc2: //RET Iw
2658 case 0xc3: //RET
2659 case 0xc4: //LES
2660 case 0xc5: //LDS
2661 case 0xc6: //MOV GP11 Eb, Gb
2662 case 0xc7: //MOV GP11 Ev, Gv
2663 case 0xc8: //ENTER
2664 case 0xc9: //LEAVE
2665 case 0xca: //RETF Iw
2666 case 0xcb: //RETF
2667 case 0xcc: //INT3
2668 case 0xcd: //INT Ib
2669 case 0xce: //INTO
2671 case 0xd4: //AAM
2672 case 0xd5: //AAD
2673 case 0xd6: //SALC
2674 case 0xd7: //XLAT
2676 case 0xe0: //LOOPNZ
2677 case 0xe1: //LOOPZ
2678 case 0xe2: //LOOP
2679 case 0xe3: //JCXZ
2680 case 0xe4: //IN AL, Ib
2681 case 0xe5: //IN eAX, Ib
2682 case 0xe6: //OUT Ib, AL
2683 case 0xe7: //OUT Ib, eAX
2684 case 0xe8: //CALL Jv
2685 case 0xe9: //JMP Jv
2686 case 0xea: //JMPF Ap
2687 case 0xeb: //JMP Jb
2688 case 0xec: //IN AL, DX
2689 case 0xed: //IN eAX, DX
2690 case 0xee: //OUT DX, AL
2691 case 0xef: //OUT DX, eAX
2693 case 0xf4: //HLT
2694 case 0xf5: //CMC
2695 case 0xf8: //CLC
2696 case 0xf9: //STC
2697 case 0xfa: //CLI
2698 case 0xfb: //STI
2699 case 0xfc: //CLD
2700 case 0xfd: //STD
2702 case 0xf00: //Group 6
2703 case 0xf01: //Group 7
2704 case 0xf02: //LAR Gv, Ew
2705 case 0xf03: //LSL Gv, Ew
2706 case 0xf06: //CLTS
2707 case 0xf09: //WBINVD
2708 case 0xf0b: //UD2
2709 case 0xf20: //MOV Rd, Cd
2710 case 0xf21: //MOV Rd, Dd
2711 case 0xf22: //MOV Cd, Rd
2712 case 0xf23: //MOV Dd, Rd
2713 case 0xf30: //WRMSR
2714 case 0xf31: //RDTSC
2715 case 0xf32: //RDMSR
2716 case 0xf34: //SYSENTER
2717 case 0xf35: //SYSEXIT
2718 case 0xf40: //CMOVO
2719 case 0xf41: //CMOVNO
2720 case 0xf42: //CMOVC
2721 case 0xf43: //CMOVNC
2722 case 0xf44: //CMOVZ
2723 case 0xf45: //CMOVNZ
2724 case 0xf46: //CMOVBE
2725 case 0xf47: //CMOVNBE
2726 case 0xf48: //CMOVS
2727 case 0xf49: //CMOVNS
2728 case 0xf4a: //CMOVP
2729 case 0xf4b: //CMOVNP
2730 case 0xf4c: //CMOVL
2731 case 0xf4d: //CMOVNL
2732 case 0xf4e: //CMOVLE
2733 case 0xf4f: //CMOVNLE
2734 case 0xf80: //JO Jv
2735 case 0xf81: //JNO Jv
2736 case 0xf82: //JC Jv
2737 case 0xf83: //JNC Jv
2738 case 0xf84: //JZ Jv
2739 case 0xf85: //JNZ Jv
2740 case 0xf86: //JNA Jv
2741 case 0xf87: //JA Jv
2742 case 0xf88: //JS Jv
2743 case 0xf89: //JNS Jv
2744 case 0xf8a: //JP Jv
2745 case 0xf8b: //JNP Jv
2746 case 0xf8c: //JL Jv
2747 case 0xf8d: //JNL Jv
2748 case 0xf8e: //JNG Jv
2749 case 0xf8f: //JG Jv
2750 case 0xf90: //SETO
2751 case 0xf91: //SETNO
2752 case 0xf92: //SETC
2753 case 0xf93: //SETNC
2754 case 0xf94: //SETZ
2755 case 0xf95: //SETNZ
2756 case 0xf96: //SETNA
2757 case 0xf97: //SETA
2758 case 0xf98: //SETS
2759 case 0xf99: //SETNS
2760 case 0xf9a: //SETP
2761 case 0xf9b: //SETNP
2762 case 0xf9c: //SETL
2763 case 0xf9d: //SETNL
2764 case 0xf9e: //SETNG
2765 case 0xf9f: //SETG
2766 case 0xfa0: //PUSH FS
2767 case 0xfa2: //CPUID
2768 case 0xfa8: //PUSH GS
2769 case 0xfaf: //IMUL Gv, Ev
2770 case 0xfa3: //BT Ev, Gv
2771 case 0xfab: //BTS Ev, Gv
2772 case 0xfb3: //BTR Ev, Gv
2773 case 0xfbb: //BTC Ev, Gv
2774 case 0xfb2: //LSS Mp
2775 case 0xfb4: //LFS Mp
2776 case 0xfb5: //LGS Mp
2777 case 0xfb6: //MOVZX Gv, Eb
2778 case 0xfb7: //MOVZX Gv, Ew
2779 case 0xfba: //Grp 8 Ev, Ib
2780 case 0xfbc: //BSF Gv, Ev
2781 case 0xfbd: //BSR Gv, Ev
2782 case 0xfbe: //MOVSX Gv, Eb
2783 case 0xfbf: //MOVSX Gv, Ew
2784 case 0xfc7:
2785 case 0xfc8: //BSWAP EAX
2786 case 0xfc9: //BSWAP ECX
2787 case 0xfca: //BSWAP EDX
2788 case 0xfcb: //BSWAP EBX
2789 case 0xfcc: //BSWAP ESP
2790 case 0xfcd: //BSWAP EBP
2791 case 0xfce: //BSWAP ESI
2792 case 0xfcf: //BSWAP EDI
2793 case 0xd800: // FPU OPS
2794 case 0xd900: // FPU OPS
2795 case 0xda00: // FPU OPS
2796 case 0xdb00: // FPU OPS
2797 case 0xdc00: // FPU OPS
2798 case 0xdd00: // FPU OPS
2799 case 0xde00: // FPU OPS
2800 case 0xdf00: // FPU OPS
2801 case 0x0fff: // Undefined instruction used by win 95
2802 return;
2804 default:
2805 throw new IllegalStateException("Missing Flags: 0x" + Integer.toHexString(opcode));
2809 private void writeInputOperands(int prefices, int opcode, int modrm, int sib, int displacement, long immediate)
2811 switch (opcode) {
2812 case 0x00: //ADD Eb, Gb
2813 case 0x08: //OR Eb, Gb
2814 case 0x10: //ADC Eb, Gb
2815 case 0x18: //SBB Eb, Gb
2816 case 0x20: //AND Eb, Gb
2817 case 0x28: //SUB Eb, Gb
2818 case 0x30: //XOR Eb, Gb
2819 case 0x38: //CMP Eb, Gb
2820 case 0x84: //TEST Eb, Gb
2821 case 0x86: //XCHG Eb, Gb
2822 load0_Eb(prefices, modrm, sib, displacement);
2823 load1_Gb(modrm);
2824 break;
2826 case 0x88: //MOV Eb, Gb
2827 load0_Gb(modrm);
2828 break;
2830 case 0x02: //ADD Gb, Eb
2831 case 0x0a: //OR Gb, Eb
2832 case 0x12: //ADC Gb, Eb
2833 case 0x1a: //SBB Gb, Eb
2834 case 0x22: //AND Gb, Eb
2835 case 0x2a: //SUB Gb, Eb
2836 case 0x32: //XOR Gb, Eb
2837 case 0x3a: //CMP Gb, Eb
2838 case 0xfc0: //XADD Eb, Gb
2839 load0_Gb(modrm);
2840 load1_Eb(prefices, modrm, sib, displacement);
2841 break;
2843 case 0x8a: //MOV Gb, Eb
2844 case 0xfb6: //MOVZX Gv, Eb
2845 case 0xfbe: //MOVSX Gv, Eb
2846 load0_Eb(prefices, modrm, sib, displacement);
2847 break;
2849 case 0x01: //ADD Ev, Gv
2850 case 0x09: //OR Ev, Gv
2851 case 0x11: //ADC Ev, Gv
2852 case 0x19: //SBB Ev, Gv
2853 case 0x21: //AND Ev, Gv
2854 case 0x29: //SUB Ev, Gv
2855 case 0x31: //XOR Ev, Gv
2856 case 0x39: //CMP Ev, Gv
2857 case 0x85: //TEST Ev, Gv
2858 case 0x87: //XCHG Ev, Gv
2859 if ((prefices & PREFICES_OPERAND) != 0) {
2860 load0_Ed(prefices, modrm, sib, displacement);
2861 load1_Gd(modrm);
2862 } else {
2863 load0_Ew(prefices, modrm, sib, displacement);
2864 load1_Gw(modrm);
2866 break;
2868 case 0x89: //MOV Ev, Gv
2869 if ((prefices & PREFICES_OPERAND) != 0) {
2870 load0_Gd(modrm);
2871 } else {
2872 load0_Gw(modrm);
2874 break;
2876 case 0x03: //ADD Gv, Ev
2877 case 0x0b: //OR Gv, Ev
2878 case 0x13: //ADC Gv, Ev
2879 case 0x1b: //SBB Gv, Ev
2880 case 0x23: //AND Gv, Ev
2881 case 0x2b: //SUB Gv, Ev
2882 case 0x33: //XOR Gv, Ev
2883 case 0x3b: //CMP Gv, Ev
2884 case 0xfaf: //IMUL Gv, Ev
2885 case 0xfbc: //BSF Gv, Ev
2886 case 0xfbd: //BSR Gv, Ev
2887 case 0xfc1: //XADD Ev, Gv
2888 if ((prefices & PREFICES_OPERAND) != 0) {
2889 load0_Gd(modrm);
2890 load1_Ed(prefices, modrm, sib, displacement);
2891 } else {
2892 load0_Gw(modrm);
2893 load1_Ew(prefices, modrm, sib, displacement);
2895 break;
2897 case 0x8b: //MOV Gv, Ev
2898 if ((prefices & PREFICES_OPERAND) != 0) {
2899 load0_Ed(prefices, modrm, sib, displacement);
2900 } else {
2901 load0_Ew(prefices, modrm, sib, displacement);
2903 break;
2905 case 0xf02: //LAR Gv, Ew
2906 case 0xf03: //LSL Gv, Ew
2907 if ((prefices & PREFICES_OPERAND) != 0) {
2908 load0_Ew(prefices, modrm, sib, displacement);
2909 load1_Gd(modrm);
2910 } else {
2911 load0_Ew(prefices, modrm, sib, displacement);
2912 load1_Gw(modrm);
2914 break;
2916 case 0xf40: //CMOVO
2917 case 0xf41: //CMOVNO
2918 case 0xf42: //CMOVC
2919 case 0xf43: //CMOVNC
2920 case 0xf44: //CMOVZ
2921 case 0xf45: //CMOVNZ
2922 case 0xf46: //CMOVBE
2923 case 0xf47: //CMOVNBE
2924 case 0xf48: //CMOVS
2925 case 0xf49: //CMOVNS
2926 case 0xf4a: //CMOVP
2927 case 0xf4b: //CMOVNP
2928 case 0xf4c: //CMOVL
2929 case 0xf4d: //CMOVNL
2930 case 0xf4e: //CMOVLE
2931 case 0xf4f: //CMOVNLE
2932 if ((prefices & PREFICES_OPERAND) != 0) {
2933 load0_Gd(modrm);
2934 load1_Ed(prefices, modrm, sib, displacement);
2935 } else {
2936 load0_Gw(modrm);
2937 load1_Ew(prefices, modrm, sib, displacement);
2939 break;
2941 case 0x8d: //LEA Gv, M
2942 load0_M(prefices, modrm, sib, displacement);
2943 break;
2946 case 0x80: //IMM G1 Eb, Ib
2947 case 0x82: //IMM G1 Eb, Ib
2948 case 0xc0: //SFT G2 Eb, Ib
2949 load0_Eb(prefices, modrm, sib, displacement);
2950 working.write(LOAD1_IB);
2951 working.write((int)immediate);
2952 break;
2954 case 0xc6: //MOV G11 Eb, Ib
2955 case 0xb0: //MOV AL, Ib
2956 case 0xb1: //MOV CL, Ib
2957 case 0xb2: //MOV DL, Ib
2958 case 0xb3: //MOV BL, Ib
2959 case 0xb4: //MOV AH, Ib
2960 case 0xb5: //MOV CH, Ib
2961 case 0xb6: //MOV DH, Ib
2962 case 0xb7: //MOV BH, Ib
2963 case 0xe4: //IN AL, Ib
2964 case 0x70: //Jcc Jb
2965 case 0x71:
2966 case 0x72:
2967 case 0x73:
2968 case 0x74:
2969 case 0x75:
2970 case 0x76:
2971 case 0x77:
2972 case 0x78:
2973 case 0x79:
2974 case 0x7a:
2975 case 0x7b:
2976 case 0x7c:
2977 case 0x7d:
2978 case 0x7e:
2979 case 0x7f:
2980 case 0xcd: //INT Ib
2981 case 0xd4: //AAM Ib
2982 case 0xd5: //AAD Ib
2983 case 0xe0: //LOOPNZ Jb
2984 case 0xe1: //LOOPZ Jb
2985 case 0xe2: //LOOP Jb
2986 case 0xe3: //JCXZ Jb
2987 case 0xeb: //JMP Jb
2988 case 0xe5: //IN eAX, Ib
2989 working.write(LOAD0_IB);
2990 working.write((int)immediate);
2991 break;
2993 case 0x81: //IMM G1 Ev, Iv
2994 if ((prefices & PREFICES_OPERAND) != 0) {
2995 load0_Ed(prefices, modrm, sib, displacement);
2996 working.write(LOAD1_ID);
2997 working.write((int)immediate);
2998 } else {
2999 load0_Ew(prefices, modrm, sib, displacement);
3000 working.write(LOAD1_IW);
3001 working.write((int)immediate);
3003 break;
3005 case 0xc7: //MOV G11 Ev, Iv
3006 case 0x68: //PUSH Iv
3007 case 0x6a: //PUSH Ib
3008 case 0xe8: //CALL Jv
3009 case 0xe9: //JMP Jv
3010 case 0xf80: //JO Jv
3011 case 0xf81: //JNO Jv
3012 case 0xf82: //JC Jv
3013 case 0xf83: //JNC Jv
3014 case 0xf84: //JZ Jv
3015 case 0xf85: //JNZ Jv
3016 case 0xf86: //JNA Jv
3017 case 0xf87: //JA Jv
3018 case 0xf88: //JS Jv
3019 case 0xf89: //JNS Jv
3020 case 0xf8a: //JP Jv
3021 case 0xf8b: //JNP Jv
3022 case 0xf8c: //JL Jv
3023 case 0xf8d: //JNL Jv
3024 case 0xf8e: //JNG Jv
3025 case 0xf8f: //JG Jv
3026 if ((prefices & PREFICES_OPERAND) != 0) {
3027 working.write(LOAD0_ID);
3028 working.write((int)immediate);
3029 } else {
3030 working.write(LOAD0_IW);
3031 working.write((int)immediate);
3033 break;
3035 case 0xc1: //SFT G2 Ev, Ib
3036 if ((prefices & PREFICES_OPERAND) != 0) {
3037 load0_Ed(prefices, modrm, sib, displacement);
3038 working.write(LOAD1_IB);
3039 working.write((int)immediate);
3040 } else {
3041 load0_Ew(prefices, modrm, sib, displacement);
3042 working.write(LOAD1_IB);
3043 working.write((int)immediate);
3045 break;
3047 case 0x83: //IMM G1 Ev, Ib sign extend the byte to 16/32 bits
3048 if ((prefices & PREFICES_OPERAND) != 0) {
3049 load0_Ed(prefices, modrm, sib, displacement);
3050 working.write(LOAD1_ID);
3051 working.write((int)immediate);
3052 } else {
3053 load0_Ew(prefices, modrm, sib, displacement);
3054 working.write(LOAD1_IW);
3055 working.write((int)immediate);
3057 break;
3059 case 0x8f: //POP Ev
3060 case 0x58: //POP eAX
3061 case 0x59: //POP eCX
3062 case 0x5a: //POP eDX
3063 case 0x5b: //POP eBX
3064 case 0x5c: //POP eSP
3065 case 0x5d: //POP eBP
3066 case 0x5e: //POP eSI
3067 case 0x5f: //POP eDI
3068 case 0x07: //POP ES
3069 case 0x17: //POP SS
3070 case 0x1f: //POP DS
3071 break;
3073 case 0xc2: //RET Iw
3074 case 0xca: //RETF Iw
3075 working.write(LOAD0_IW);
3076 working.write((int)immediate);
3077 break;
3079 case 0x9a: //CALLF Ap
3080 case 0xea: //JMPF Ap
3081 if ((prefices & PREFICES_OPERAND) != 0) {
3082 working.write(LOAD0_ID);
3083 working.write((int)immediate);
3084 working.write(LOAD1_IW);
3085 working.write((int)(immediate >>> 32));
3086 } else {
3087 working.write(LOAD0_IW);
3088 working.write((int)(0xffff & immediate));
3089 working.write(LOAD1_IW);
3090 working.write((int)(immediate >>> 16));
3092 break;
3094 case 0x9c:
3095 switch (prefices & PREFICES_OPERAND) {
3096 case 0:
3097 working.write(LOAD0_FLAGS); break;
3098 case PREFICES_OPERAND:
3099 working.write(LOAD0_EFLAGS); break;
3101 break;
3103 case 0xec: //IN AL, DX
3104 case 0xed: //IN eAX, DX
3105 working.write(LOAD0_DX);
3106 break;
3108 case 0xee: //OUT DX, AL
3109 working.write(LOAD0_DX);
3110 working.write(LOAD1_AL);
3111 break;
3113 case 0xef: //OUT DX, eAX
3114 if ((prefices & PREFICES_OPERAND) != 0) {
3115 working.write(LOAD0_DX);
3116 working.write(LOAD1_EAX);
3117 } else {
3118 working.write(LOAD0_DX);
3119 working.write(LOAD1_AX);
3121 break;
3123 case 0x04: //ADD AL, Ib
3124 case 0x0c: //OR AL, Ib
3125 case 0x14: //ADC AL, Ib
3126 case 0x1c: //SBB AL, Ib
3127 case 0x24: //AND AL, Ib
3128 case 0x2c: //SUB AL, Ib
3129 case 0x34: //XOR AL, Ib
3130 case 0x3c: //CMP AL, Ib
3131 case 0xa8: //TEST AL, Ib
3132 working.write(LOAD0_AL);
3133 working.write(LOAD1_IB);
3134 working.write((int)immediate);
3135 break;
3137 case 0xc8: //ENTER Iw, Ib
3138 working.write(LOAD0_IW);
3139 working.write((int)(0xffffl & (immediate >>> 16)));
3140 working.write(LOAD1_IB);
3141 working.write((int)(0xffl & immediate));
3142 break;
3144 case 0x69: //IMUL Gv, Ev, Iv
3145 case 0x6b: //IMUL Gv, Ev, Ib
3146 if ((prefices & PREFICES_OPERAND) != 0) {
3147 load0_Ed(prefices, modrm, sib, displacement);
3148 working.write(LOAD1_ID);
3149 working.write((int)immediate);
3150 } else {
3151 load0_Ew(prefices, modrm, sib, displacement);
3152 working.write(LOAD1_IW);
3153 working.write((int)immediate);
3155 break;
3157 case 0xe6: //OUT Ib, AL
3158 working.write(LOAD0_IB);
3159 working.write((int)immediate);
3160 working.write(LOAD1_AL);
3161 break;
3163 case 0x05: //ADD eAX, Iv
3164 case 0x0d: //OR eAX, Iv
3165 case 0x15: //ADC eAX, Iv
3166 case 0x1d: //SBB eAX, Iv
3167 case 0x25: //AND eAX, Iv
3168 case 0x2d: //SUB eAX, Iv
3169 case 0x35: //XOR eAX, Iv
3170 case 0x3d: //CMP eAX, Iv
3171 case 0xa9: //TEST eAX, Iv
3172 if ((prefices & PREFICES_OPERAND) != 0) {
3173 working.write(LOAD0_EAX);
3174 working.write(LOAD1_ID);
3175 working.write((int)immediate);
3176 } else {
3177 working.write(LOAD0_AX);
3178 working.write(LOAD1_IW);
3179 working.write((int)immediate);
3181 break;
3183 case 0xb8: //MOV eAX, Iv
3184 case 0xb9: //MOV eCX, Iv
3185 case 0xba: //MOV eDX, Iv
3186 case 0xbb: //MOV eBX, Iv
3187 case 0xbc: //MOV eSP, Iv
3188 case 0xbd: //MOV eBP, Iv
3189 case 0xbe: //MOV eSI, Iv
3190 case 0xbf: //MOV eDI, Iv
3191 if ((prefices & PREFICES_OPERAND) != 0) {
3192 working.write(LOAD0_ID);
3193 working.write((int)immediate);
3194 } else {
3195 working.write(LOAD0_IW);
3196 working.write((int)immediate);
3198 break;
3200 case 0xe7: //OUT Ib, eAX
3201 if ((prefices & PREFICES_OPERAND) != 0) {
3202 working.write(LOAD0_IB);
3203 working.write((int)immediate);
3204 working.write(LOAD1_EAX);
3205 } else {
3206 working.write(LOAD0_IB);
3207 working.write((int)immediate);
3208 working.write(LOAD1_AX);
3210 break;
3212 case 0x40: //INC eAX
3213 case 0x48: //DEC eAX
3214 case 0x50: //PUSH eAX
3215 if ((prefices & PREFICES_OPERAND) != 0) {
3216 working.write(LOAD0_EAX);
3217 } else {
3218 working.write(LOAD0_AX);
3220 break;
3222 case 0x41: //INC eCX
3223 case 0x49: //DEC eCX
3224 case 0x51: //PUSH eCX
3225 if ((prefices & PREFICES_OPERAND) != 0) {
3226 working.write(LOAD0_ECX);
3227 } else {
3228 working.write(LOAD0_CX);
3230 break;
3232 case 0x42: //INC eDX
3233 case 0x4a: //DEC eDX
3234 case 0x52: //PUSH eDX
3235 if ((prefices & PREFICES_OPERAND) != 0) {
3236 working.write(LOAD0_EDX);
3237 } else {
3238 working.write(LOAD0_DX);
3240 break;
3242 case 0x43: //INC eBX
3243 case 0x4b: //DEC eBX
3244 case 0x53: //PUSH eBX
3245 if ((prefices & PREFICES_OPERAND) != 0) {
3246 working.write(LOAD0_EBX);
3247 } else {
3248 working.write(LOAD0_BX);
3250 break;
3252 case 0x44: //INC eSP
3253 case 0x4c: //DEC eSP
3254 case 0x54: //PUSH eSP
3255 if ((prefices & PREFICES_OPERAND) != 0) {
3256 working.write(LOAD0_ESP);
3257 } else {
3258 working.write(LOAD0_SP);
3260 break;
3262 case 0x45: //INC eBP
3263 case 0x4d: //DEC eBP
3264 case 0x55: //PUSH eBP
3265 if ((prefices & PREFICES_OPERAND) != 0) {
3266 working.write(LOAD0_EBP);
3267 } else {
3268 working.write(LOAD0_BP);
3270 break;
3272 case 0x46: //INC eSI
3273 case 0x4e: //DEC eSI
3274 case 0x56: //PUSH eSI
3275 if ((prefices & PREFICES_OPERAND) != 0) {
3276 working.write(LOAD0_ESI);
3277 } else {
3278 working.write(LOAD0_SI);
3280 break;
3282 case 0x47: //INC eDI
3283 case 0x4f: //DEC eDI
3284 case 0x57: //PUSH eDI
3285 if ((prefices & PREFICES_OPERAND) != 0) {
3286 working.write(LOAD0_EDI);
3287 } else {
3288 working.write(LOAD0_DI);
3290 break;
3292 case 0x91: //XCHG eAX, eCX
3293 if ((prefices & PREFICES_OPERAND) != 0) {
3294 working.write(LOAD0_EAX);
3295 working.write(LOAD1_ECX);
3296 } else {
3297 working.write(LOAD0_AX);
3298 working.write(LOAD1_CX);
3300 break;
3302 case 0x92: //XCHG eAX, eDX
3303 if ((prefices & PREFICES_OPERAND) != 0) {
3304 working.write(LOAD0_EAX);
3305 working.write(LOAD1_EDX);
3306 } else {
3307 working.write(LOAD0_AX);
3308 working.write(LOAD1_DX);
3310 break;
3312 case 0x93: //XCHG eAX, eBX
3313 if ((prefices & PREFICES_OPERAND) != 0) {
3314 working.write(LOAD0_EAX);
3315 working.write(LOAD1_EBX);
3316 } else {
3317 working.write(LOAD0_AX);
3318 working.write(LOAD1_BX);
3320 break;
3322 case 0x94: //XCHG eAX, eSP
3323 if ((prefices & PREFICES_OPERAND) != 0) {
3324 working.write(LOAD0_EAX);
3325 working.write(LOAD1_ESP);
3326 } else {
3327 working.write(LOAD0_AX);
3328 working.write(LOAD1_SP);
3330 break;
3332 case 0x95: //XCHG eAX, eBP
3333 if ((prefices & PREFICES_OPERAND) != 0) {
3334 working.write(LOAD0_EAX);
3335 working.write(LOAD1_EBP);
3336 } else {
3337 working.write(LOAD0_AX);
3338 working.write(LOAD1_BP);
3340 break;
3342 case 0x96: //XCHG eAX, eSI
3343 if ((prefices & PREFICES_OPERAND) != 0) {
3344 working.write(LOAD0_EAX);
3345 working.write(LOAD1_ESI);
3346 } else {
3347 working.write(LOAD0_AX);
3348 working.write(LOAD1_SI);
3350 break;
3352 case 0x97: //XCHG eAX, eDI
3353 if ((prefices & PREFICES_OPERAND) != 0) {
3354 working.write(LOAD0_EAX);
3355 working.write(LOAD1_EDI);
3356 } else {
3357 working.write(LOAD0_AX);
3358 working.write(LOAD1_DI);
3360 break;
3362 case 0xd0: //SFT G2 Eb, 1
3363 load0_Eb(prefices, modrm, sib, displacement);
3364 working.write(LOAD1_IB);
3365 working.write(1);
3366 break;
3368 case 0xd2: //SFT G2 Eb, CL
3369 load0_Eb(prefices, modrm, sib, displacement);
3370 working.write(LOAD1_CL);
3371 break;
3373 case 0xd1: //SFT G2 Ev, 1
3374 if ((prefices & PREFICES_OPERAND) != 0) {
3375 load0_Ed(prefices, modrm, sib, displacement);
3376 working.write(LOAD1_IB);
3377 working.write(1);
3378 } else {
3379 load0_Ew(prefices, modrm, sib, displacement);
3380 working.write(LOAD1_IB);
3381 working.write(1);
3383 break;
3385 case 0xd3: //SFT G2 Ev, CL
3386 if ((prefices & PREFICES_OPERAND) != 0) {
3387 load0_Ed(prefices, modrm, sib, displacement);
3388 working.write(LOAD1_CL);
3389 } else {
3390 load0_Ew(prefices, modrm, sib, displacement);
3391 working.write(LOAD1_CL);
3393 break;
3395 case 0xf6: //UNA G3 Eb, ?
3396 switch (modrm & 0x38) {
3397 case 0x00: //TEST Eb, Ib
3398 load0_Eb(prefices, modrm, sib, displacement);
3399 working.write(LOAD1_IB);
3400 working.write((int)immediate);
3401 break;
3402 case 0x10:
3403 case 0x18:
3404 load0_Eb(prefices, modrm, sib, displacement);
3405 break;
3406 case 0x20:
3407 case 0x28:
3408 load0_Eb(prefices, modrm, sib, displacement);
3409 break;
3410 case 0x30:
3411 case 0x38:
3412 load0_Eb(prefices, modrm, sib, displacement);
3413 break;
3415 break;
3417 case 0xf7: //UNA G3 Ev, ?
3418 if ((prefices & PREFICES_OPERAND) != 0) {
3419 switch (modrm & 0x38) {
3420 case 0x00: //TEST Ed, Id
3421 load0_Ed(prefices, modrm, sib, displacement);
3422 working.write(LOAD1_ID);
3423 working.write((int)immediate);
3424 break;
3425 case 0x10:
3426 case 0x18:
3427 load0_Ed(prefices, modrm, sib, displacement);
3428 break;
3429 case 0x20:
3430 case 0x28:
3431 load0_Ed(prefices, modrm, sib, displacement);
3432 break;
3433 case 0x30:
3434 case 0x38:
3435 load0_Ed(prefices, modrm, sib, displacement);
3437 } else {
3438 switch (modrm & 0x38) {
3439 case 0x00: //TEST Ew, Iw
3440 load0_Ew(prefices, modrm, sib, displacement);
3441 working.write(LOAD1_IW);
3442 working.write((int)immediate);
3443 break;
3444 case 0x10:
3445 case 0x18:
3446 load0_Ew(prefices, modrm, sib, displacement);
3447 break;
3448 case 0x20:
3449 case 0x28:
3450 load0_Ew(prefices, modrm, sib, displacement);
3451 break;
3452 case 0x30:
3453 case 0x38:
3454 load0_Ew(prefices, modrm, sib, displacement);
3457 break;
3459 case 0xfe: //INC/DEC G4 Eb
3460 load0_Eb(prefices, modrm, sib, displacement);
3461 break;
3463 case 0x06: //PUSH ES
3464 working.write(LOAD0_ES);
3465 break;
3467 case 0x0e: //PUSH CS
3468 working.write(LOAD0_CS);
3469 break;
3471 case 0x16: //PUSH SS
3472 working.write(LOAD0_SS);
3473 break;
3475 case 0x1e: //PUSH DS
3476 working.write(LOAD0_DS);
3477 break;
3479 case 0x62: //BOUND Gv, Ma
3480 if ((prefices & PREFICES_OPERAND) != 0) {
3481 load0_Eq(prefices, modrm, sib, displacement);
3482 load1_Gd(modrm);
3483 } else {
3484 load0_Ed(prefices, modrm, sib, displacement);
3485 load1_Gw(modrm);
3487 break;
3489 case 0x8c: //MOV Ew, Sw
3490 load0_Sw(modrm);
3491 break;
3493 case 0x8e: //MOV Sw, Ew
3494 case 0xfb7: //MOV Gv, Ew
3495 case 0xfbf: //MOVSX Gv, Ew
3496 load0_Ew(prefices, modrm, sib, displacement);
3497 break;
3499 case 0xa0: //MOV AL, Ob
3500 load0_Ob(prefices, displacement);
3501 break;
3503 case 0xa2: //MOV Ob, AL
3504 working.write(LOAD0_AL);
3505 break;
3507 case 0xa1: //MOV eAX, Ov
3508 if ((prefices & PREFICES_OPERAND) != 0) {
3509 load0_Od(prefices, displacement);
3510 } else {
3511 load0_Ow(prefices, displacement);
3513 break;
3515 case 0xa3: //MOV Ov, eAX
3516 if ((prefices & PREFICES_OPERAND) != 0) {
3517 working.write(LOAD0_EAX);
3518 } else {
3519 working.write(LOAD0_AX);
3521 break;
3523 case 0x6c: //INS Yb, DX (prefices do not override segment)
3524 case 0x6d: //INS Yv, DX (prefices do not override segment)
3525 working.write(LOAD0_DX);
3526 break;
3528 case 0x6e: //OUTS DX, Xb
3529 case 0x6f: //OUTS DX, Xv
3530 working.write(LOAD0_DX);
3531 decodeSegmentPrefix(prefices);
3532 break;
3534 case 0xa4: //MOVS Yb, Xb
3535 case 0xa5: //MOVS Yv, Xv
3536 case 0xa6: //CMPS Yb, Xb
3537 case 0xa7: //CMPS Xv, Yv
3538 case 0xac: //LODS AL, Xb
3539 case 0xad: //LODS eAX, Xv
3540 decodeSegmentPrefix(prefices);
3541 break;
3543 case 0xaa: //STOS Yb, AL (prefices do not override segment)
3544 working.write(LOAD0_AL);
3545 break;
3547 case 0xab: //STOS Yv, eAX
3548 if ((prefices & PREFICES_OPERAND) != 0)
3549 working.write(LOAD0_EAX);
3550 else
3551 working.write(LOAD0_AX);
3552 break;
3555 case 0xae: //SCAS AL, Yb (prefices do not override segment)
3556 working.write(LOAD0_AL);
3557 break;
3559 case 0xaf: //SCAS eAX, Yv
3560 if ((prefices & PREFICES_OPERAND) != 0)
3561 working.write(LOAD0_EAX);
3562 else
3563 working.write(LOAD0_AX);
3564 break;
3566 case 0xff: //INC/DEC G5
3567 if ((prefices & PREFICES_OPERAND) != 0) {
3568 switch (modrm & 0x38) {
3569 case 0x00: //INC Ed
3570 case 0x08: //DEC Ed
3571 case 0x10: //CALLN Ed
3572 case 0x20: //JMPN Ed
3573 case 0x30: //PUSH Ed
3574 load0_Ed(prefices, modrm, sib, displacement);
3575 break;
3576 case 0x18: //CALLF Ep
3577 case 0x28: //JMPF Ep
3578 load0_Ed(prefices, modrm, sib, displacement);
3579 working.write(ADDR_IB);
3580 working.write(4);
3581 working.write(LOAD1_MEM_WORD);
3583 } else {
3584 switch (modrm & 0x38) {
3585 case 0x00:
3586 case 0x08:
3587 case 0x10:
3588 case 0x20:
3589 case 0x30:
3590 load0_Ew(prefices, modrm, sib, displacement);
3591 break;
3592 case 0x18:
3593 case 0x28:
3594 load0_Ew(prefices, modrm, sib, displacement);
3595 working.write(ADDR_IB);
3596 working.write(2);
3597 working.write(LOAD1_MEM_WORD);
3600 break;
3602 case 0xc4: //LES Gv, Mp
3603 case 0xc5: //LDS Gv, Mp
3604 case 0xfb2: //LSS Mp
3605 case 0xfb4: //LFS Mp
3606 case 0xfb5: //LGS Mp
3607 if ((prefices & PREFICES_OPERAND) != 0) {
3608 load0_Ed(prefices, modrm, sib, displacement);
3609 working.write(ADDR_IB);
3610 working.write(4);
3611 working.write(LOAD1_MEM_WORD);
3612 } else {
3613 load0_Ew(prefices, modrm, sib, displacement);
3614 working.write(ADDR_IB);
3615 working.write(2);
3616 working.write(LOAD1_MEM_WORD);
3618 break;
3620 case 0xd7: // XLAT
3621 switch (prefices & PREFICES_SG) {
3622 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
3623 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
3624 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
3625 default:
3626 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
3627 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
3628 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
3631 if ((prefices & PREFICES_ADDRESS) != 0) {
3632 if (decodingAddressMode()) {
3633 working.write(ADDR_EBX);
3634 working.write(ADDR_uAL);
3636 } else {
3637 if (decodingAddressMode()) {
3638 working.write(ADDR_BX);
3639 working.write(ADDR_uAL);
3640 working.write(ADDR_MASK16);
3643 working.write(LOAD0_MEM_BYTE);
3644 break;
3646 case 0xf00: // Group 6
3647 switch (modrm & 0x38) {
3648 case 0x10: //LLDT
3649 case 0x18: //LTR
3650 case 0x20: //VERR
3651 case 0x28: //VERW
3652 load0_Ew(prefices, modrm, sib, displacement); break;
3653 } break;
3655 case 0xf01:
3656 switch (modrm & 0x38) {
3657 case 0x10:
3658 case 0x18:
3659 load0_Ew(prefices, modrm, sib, displacement);
3660 working.write(ADDR_ID);
3661 working.write(2);
3662 working.write(LOAD1_MEM_DWORD);
3663 break;
3664 case 0x30: load0_Ew(prefices, modrm, sib, displacement); break;
3665 case 0x38: decodeM(prefices, modrm, sib, displacement); break;
3666 } break;
3668 case 0xfa0: //PUSH FS
3669 working.write(LOAD0_FS); break;
3670 case 0xfa8: //PUSH GS
3671 working.write(LOAD0_GS); break;
3673 case 0xf20: load0_Cd(modrm); break; //MOV Rd, Cd
3675 case 0xf21: load0_Dd(modrm); break; //MOV Rd, Dd
3677 case 0xf22: //MOV Cd, Rd
3678 case 0xf23: load0_Rd(modrm); break; //MOV Dd, Rd
3680 case 0xf30: //WRMSR
3681 working.write(LOAD0_ECX);
3682 working.write(LOAD1_EDX);
3683 working.write(LOAD2_EAX);
3684 break;
3686 case 0xf32: //RDMSR
3687 working.write(LOAD0_ECX);
3688 break;
3690 case 0xf35: //SYSEXIT
3691 working.write(LOAD0_ECX);
3692 working.write(LOAD1_EDX);
3693 break;
3695 case 0xfa4: //SHLD Ev, Gv, Ib
3696 case 0xfac: //SHRD Ev, Gv, Ib
3697 if ((prefices & PREFICES_OPERAND) != 0) {
3698 load0_Ed(prefices, modrm, sib, displacement);
3699 load1_Gd(modrm);
3700 working.write(LOAD2_IB);
3701 working.write((int)immediate);
3702 } else {
3703 load0_Ew(prefices, modrm, sib, displacement);
3704 load1_Gw(modrm);
3705 working.write(LOAD2_IB);
3706 working.write((int)immediate);
3708 break;
3709 case 0xfa5: //SHLD Ev, Gv, CL
3710 case 0xfad: //SHRD Ev, Gv, CL
3711 if ((prefices & PREFICES_OPERAND) != 0) {
3712 load0_Ed(prefices, modrm, sib, displacement);
3713 load1_Gd(modrm);
3714 working.write(LOAD2_CL);
3715 } else {
3716 load0_Ew(prefices, modrm, sib, displacement);
3717 load1_Gw(modrm);
3718 working.write(LOAD2_CL);
3720 break;
3722 case 0xfb0: //CMPXCHG Eb, Gb
3723 load0_Eb(prefices, modrm, sib, displacement);
3724 load1_Gb(modrm);
3725 working.write(LOAD2_AL);
3726 break;
3728 case 0xfb1: //CMPXCHG Ev, Gv
3729 if ((prefices & PREFICES_OPERAND) != 0) {
3730 load0_Ed(prefices, modrm, sib, displacement);
3731 load1_Gd(modrm);
3732 working.write(LOAD2_EAX);
3733 } else {
3734 load0_Ew(prefices, modrm, sib, displacement);
3735 load1_Gw(modrm);
3736 working.write(LOAD2_AX);
3738 break;
3740 case 0xfa3: //BT Ev, Gv
3741 case 0xfab: //BTS Ev, Gv
3742 case 0xfb3: //BTR Ev, Gv
3743 case 0xfbb: //BTC Ev, Gv
3744 if ((prefices & PREFICES_OPERAND) != 0) {
3745 switch (modrm & 0xc7) {
3746 default: decodeM(prefices, modrm, sib, displacement); break;
3748 case 0xc0: working.write(LOAD0_EAX); break;
3749 case 0xc1: working.write(LOAD0_ECX); break;
3750 case 0xc2: working.write(LOAD0_EDX); break;
3751 case 0xc3: working.write(LOAD0_EBX); break;
3752 case 0xc4: working.write(LOAD0_ESP); break;
3753 case 0xc5: working.write(LOAD0_EBP); break;
3754 case 0xc6: working.write(LOAD0_ESI); break;
3755 case 0xc7: working.write(LOAD0_EDI); break;
3757 load1_Gd(modrm);
3758 } else {
3759 switch (modrm & 0xc7) {
3760 default: decodeM(prefices, modrm, sib, displacement); break;
3762 case 0xc0: working.write(LOAD0_AX); break;
3763 case 0xc1: working.write(LOAD0_CX); break;
3764 case 0xc2: working.write(LOAD0_DX); break;
3765 case 0xc3: working.write(LOAD0_BX); break;
3766 case 0xc4: working.write(LOAD0_SP); break;
3767 case 0xc5: working.write(LOAD0_BP); break;
3768 case 0xc6: working.write(LOAD0_SI); break;
3769 case 0xc7: working.write(LOAD0_DI); break;
3771 load1_Gw(modrm);
3773 break;
3775 case 0xfba: //Grp 8 Ev, Ib
3776 if ((prefices & PREFICES_OPERAND) != 0) {
3777 switch (modrm & 0xc7) {
3778 default: decodeM(prefices, modrm, sib, displacement); break;
3780 case 0xc0: working.write(LOAD0_EAX); break;
3781 case 0xc1: working.write(LOAD0_ECX); break;
3782 case 0xc2: working.write(LOAD0_EDX); break;
3783 case 0xc3: working.write(LOAD0_EBX); break;
3784 case 0xc4: working.write(LOAD0_ESP); break;
3785 case 0xc5: working.write(LOAD0_EBP); break;
3786 case 0xc6: working.write(LOAD0_ESI); break;
3787 case 0xc7: working.write(LOAD0_EDI); break;
3789 } else {
3790 switch (modrm & 0xc7) {
3791 default: decodeM(prefices, modrm, sib, displacement); break;
3793 case 0xc0: working.write(LOAD0_AX); break;
3794 case 0xc1: working.write(LOAD0_CX); break;
3795 case 0xc2: working.write(LOAD0_DX); break;
3796 case 0xc3: working.write(LOAD0_BX); break;
3797 case 0xc4: working.write(LOAD0_SP); break;
3798 case 0xc5: working.write(LOAD0_BP); break;
3799 case 0xc6: working.write(LOAD0_SI); break;
3800 case 0xc7: working.write(LOAD0_DI); break;
3803 working.write(LOAD1_IB);
3804 working.write((int)immediate & 0x1f);
3805 break;
3807 case 0xfc7:
3808 switch (modrm & 0x38)
3810 case 0x08:
3811 decodeM(prefices, modrm, sib, displacement);
3812 working.write(LOAD0_MEM_QWORD);
3813 break;
3814 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm & 0x38) >> 3) + "?");
3816 break;
3818 case 0xfc8: working.write(LOAD0_EAX); break; //BSWAP EAX
3819 case 0xfc9: working.write(LOAD0_ECX); break; //BSWAP ECX
3820 case 0xfca: working.write(LOAD0_EDX); break; //BSWAP EDX
3821 case 0xfcb: working.write(LOAD0_EBX); break; //BSWAP EBX
3822 case 0xfcc: working.write(LOAD0_ESP); break; //BSWAP ESP
3823 case 0xfcd: working.write(LOAD0_EBP); break; //BSWAP EBP
3824 case 0xfce: working.write(LOAD0_ESI); break; //BSWAP ESI
3825 case 0xfcf: working.write(LOAD0_EDI); break; //BSWAP EDI
3827 case 0xd800:
3828 working.write(FWAIT);
3829 if ((modrm & 0xc0) != 0xc0)
3831 switch (modrm & 0x38)
3833 case 0x28:
3834 case 0x38:
3835 decodeM(prefices, modrm, sib, displacement);
3836 working.write(FLOAD0_MEM_SINGLE);
3837 working.write(FLOAD1_ST0);
3838 break;
3839 default:
3840 working.write(FLOAD0_ST0);
3841 decodeM(prefices, modrm, sib, displacement);
3842 working.write(FLOAD1_MEM_SINGLE);
3843 break;
3846 else
3848 switch (modrm & 0xf8)
3850 case 0xe8:
3851 case 0xf8:
3852 working.write(FLOAD0_STN);
3853 working.write(modrm & 0x07);
3854 working.write(FLOAD1_ST0);
3855 break;
3856 default:
3857 working.write(FLOAD0_ST0);
3858 working.write(FLOAD1_STN);
3859 working.write(modrm & 0x07);
3860 break;
3863 break;
3865 case 0xd900:
3866 if ((modrm & 0xc0) != 0xc0)
3868 switch (modrm & 0x38)
3870 case 0x00:
3871 working.write(FWAIT);
3872 decodeM(prefices, modrm, sib, displacement);
3873 working.write(FLOAD0_MEM_SINGLE);
3874 break;
3875 case 0x10:
3876 case 0x18:
3877 working.write(FWAIT);
3878 working.write(FLOAD0_ST0); break;
3879 case 0x20:
3880 working.write(FWAIT);
3881 decodeM(prefices, modrm, sib, displacement);
3882 break;
3883 case 0x28:
3884 working.write(FWAIT);
3885 decodeM(prefices, modrm, sib, displacement);
3886 working.write(LOAD0_MEM_WORD);
3887 break;
3888 case 0x30: decodeM(prefices, modrm, sib, displacement); break;
3889 case 0x38: working.write(LOAD0_FPUCW); break;
3892 else
3894 working.write(FWAIT);
3895 switch (modrm & 0xf8)
3897 case 0xc0:
3898 working.write(FLOAD0_STN);
3899 working.write(modrm & 0x07);
3900 break;
3901 case 0xc8:
3902 working.write(FLOAD0_ST0);
3903 working.write(FLOAD1_STN);
3904 working.write(modrm & 0x07);
3905 break;
3907 switch (modrm)
3909 case 0xd0:
3910 case 0xf6:
3911 case 0xf7: break;
3912 case 0xe0:
3913 case 0xe1:
3914 case 0xe5:
3915 case 0xf0:
3916 case 0xf2:
3917 case 0xf4:
3918 case 0xfa:
3919 case 0xfb:
3920 case 0xfc:
3921 case 0xfe:
3922 case 0xff: working.write(FLOAD0_ST0); break;
3923 case 0xf1:
3924 case 0xf3:
3925 case 0xf5:
3926 case 0xf8:
3927 case 0xf9:
3928 case 0xfd:
3929 working.write(FLOAD0_ST0);
3930 working.write(FLOAD1_STN);
3931 working.write(1);
3932 break;
3933 case 0xe4:
3934 working.write(FLOAD0_ST0);
3935 working.write(FLOAD1_POS0);
3936 break;
3937 case 0xe8: working.write(FLOAD0_1); break;
3938 case 0xe9: working.write(FLOAD0_L2TEN); break;
3939 case 0xea: working.write(FLOAD0_L2E); break;
3940 case 0xeb: working.write(FLOAD0_PI); break;
3941 case 0xec: working.write(FLOAD0_LOG2); break;
3942 case 0xed: working.write(FLOAD0_LN2); break;
3943 case 0xee: working.write(FLOAD0_POS0); break;
3946 break;
3948 case 0xda00:
3949 working.write(FWAIT);
3950 if ((modrm & 0xc0) != 0xc0)
3952 switch (modrm & 0x38)
3954 case 0x28:
3955 case 0x38:
3956 decodeM(prefices, modrm, sib, displacement);
3957 working.write(LOAD0_MEM_DWORD);
3958 working.write(FLOAD0_REG0);
3959 working.write(FLOAD1_ST0);
3960 break;
3961 default:
3962 working.write(FLOAD0_ST0);
3963 decodeM(prefices, modrm, sib, displacement);
3964 working.write(LOAD0_MEM_DWORD);
3965 working.write(FLOAD1_REG0);
3966 break;
3969 else
3971 switch (modrm & 0xf8)
3973 case 0xc0:
3974 case 0xc8:
3975 case 0xd0:
3976 case 0xd8:
3977 working.write(FLOAD0_STN);
3978 working.write(modrm & 0x07);
3979 break;
3981 switch (modrm)
3983 case 0xe9:
3984 working.write(FLOAD0_ST0);
3985 working.write(FLOAD1_STN);
3986 working.write(1);
3987 break;
3990 break;
3992 case 0xdb00:
3993 if ((modrm & 0xc0) != 0xc0)
3995 working.write(FWAIT);
3996 switch (modrm & 0x38)
3998 case 0x00:
3999 decodeM(prefices, modrm, sib, displacement);
4000 working.write(LOAD0_MEM_DWORD);
4001 working.write(FLOAD0_REG0);
4002 break;
4003 case 0x08:
4004 case 0x10:
4005 case 0x18:
4006 case 0x38: working.write(FLOAD0_ST0); break;
4007 case 0x28:
4008 decodeM(prefices, modrm, sib, displacement);
4009 working.write(FLOAD0_MEM_EXTENDED);
4010 break;
4013 else
4015 switch (modrm)
4017 case 0xe2:
4018 case 0xe3: break;
4019 default: working.write(FWAIT); break;
4021 switch (modrm & 0xf8)
4023 case 0xc0:
4024 case 0xc8:
4025 case 0xd0:
4026 case 0xd8:
4027 working.write(FLOAD0_STN);
4028 working.write(modrm & 0x07);
4029 break;
4030 case 0xe8:
4031 case 0xf0:
4032 working.write(FLOAD0_ST0);
4033 working.write(FLOAD1_STN);
4034 working.write(modrm & 0x07);
4035 break;
4038 break;
4040 case 0xdc00:
4041 working.write(FWAIT);
4042 if ((modrm & 0xc0) != 0xc0)
4044 switch (modrm & 0x38)
4046 case 0x28:
4047 case 0x38:
4048 decodeM(prefices, modrm, sib, displacement);
4049 working.write(FLOAD0_MEM_DOUBLE);
4050 working.write(FLOAD1_ST0);
4051 break;
4052 default:
4053 working.write(FLOAD0_ST0);
4054 decodeM(prefices, modrm, sib, displacement);
4055 working.write(FLOAD1_MEM_DOUBLE);
4056 break;
4059 else
4061 switch (modrm & 0xf8)
4063 case 0xe8:
4064 case 0xf8:
4065 working.write(FLOAD0_STN);
4066 working.write(modrm & 0x07);
4067 working.write(FLOAD1_ST0);
4068 break;
4069 default:
4070 working.write(FLOAD0_ST0);
4071 working.write(FLOAD1_STN);
4072 working.write(modrm & 0x07);
4073 break;
4076 break;
4078 case 0xdd00:
4079 if ((modrm & 0xc0) != 0xc0)
4081 switch (modrm & 0x38)
4083 case 0x00:
4084 working.write(FWAIT);
4085 decodeM(prefices, modrm, sib, displacement);
4086 working.write(FLOAD0_MEM_DOUBLE);
4087 break;
4088 case 0x08:
4089 case 0x10:
4090 case 0x18:
4091 working.write(FWAIT);
4092 working.write(FLOAD0_ST0);
4093 break;
4094 case 0x20:
4095 working.write(FWAIT);
4096 decodeM(prefices, modrm, sib, displacement);
4097 break;
4098 case 0x30: decodeM(prefices, modrm, sib, displacement); break;
4099 case 0x38: working.write(LOAD0_FPUSW); break;
4102 else
4104 working.write(FWAIT);
4105 switch (modrm & 0xf8)
4107 case 0xc0:
4108 working.write(LOAD0_ID);
4109 working.write(modrm & 0x07);
4110 break;
4111 case 0xd0:
4112 case 0xd8: working.write(FLOAD0_ST0); break;
4113 case 0xe0:
4114 case 0xe8:
4115 working.write(FLOAD0_ST0);
4116 working.write(FLOAD1_STN);
4117 working.write(modrm & 0x07);
4118 break;
4121 break;
4123 case 0xde00:
4124 working.write(FWAIT);
4125 if ((modrm & 0xc0) != 0xc0)
4127 switch (modrm & 0x38)
4129 case 0x28:
4130 case 0x38:
4131 decodeM(prefices, modrm, sib, displacement);
4132 working.write(LOAD0_MEM_WORD);
4133 working.write(FLOAD0_REG0);
4134 working.write(FLOAD1_ST0);
4135 break;
4136 case 0x30:
4137 working.write(FLOAD0_ST0);
4138 decodeM(prefices, modrm, sib, displacement);
4139 working.write(LOAD0_MEM_QWORD);
4140 working.write(FLOAD1_REG0L);
4141 break;
4142 default:
4143 working.write(FLOAD0_ST0);
4144 decodeM(prefices, modrm, sib, displacement);
4145 working.write(LOAD0_MEM_WORD);
4146 working.write(FLOAD1_REG0);
4147 break;
4150 else
4152 switch (modrm & 0xf8) {
4153 case 0xc0:
4154 case 0xc8:
4155 case 0xe0:
4156 case 0xf0:
4157 working.write(FLOAD0_ST0);
4158 working.write(FLOAD1_STN);
4159 working.write(modrm & 0x07);
4160 break;
4161 case 0xe8:
4162 case 0xf8:
4163 working.write(FLOAD1_ST0);
4164 working.write(FLOAD0_STN);
4165 working.write(modrm & 0x07);
4166 break;
4168 switch (modrm)
4170 case 0xd9:
4171 working.write(FLOAD0_ST0);
4172 working.write(FLOAD1_STN);
4173 working.write(1);
4174 break;
4177 break;
4179 case 0xdf00:
4180 if ((modrm & 0xc0) != 0xc0)
4182 working.write(FWAIT);
4183 switch (modrm & 0x38)
4185 case 0x00:
4186 decodeM(prefices, modrm, sib, displacement);
4187 working.write(LOAD0_MEM_WORD);
4188 working.write(FLOAD0_REG0);
4189 break;
4190 case 0x28:
4191 decodeM(prefices, modrm, sib, displacement);
4192 working.write(LOAD0_MEM_QWORD);
4193 working.write(FLOAD0_REG0L);
4194 break;
4195 case 0x08:
4196 case 0x10:
4197 case 0x18:
4198 case 0x38:
4199 working.write(FLOAD0_ST0);
4200 break;
4201 case 0x30:
4202 working.write(FLOAD0_ST0);
4203 decodeM(prefices, modrm, sib, displacement);
4204 break;
4205 case 0x20:
4206 decodeM(prefices, modrm, sib, displacement);
4207 break;
4210 else
4212 switch (modrm)
4214 case 0xe0: working.write(LOAD0_FPUSW); break;
4215 default: working.write(FWAIT); break;
4217 switch (modrm & 0xf8) {
4218 case 0xe8:
4219 case 0xf0:
4220 working.write(FLOAD0_ST0);
4221 working.write(FLOAD1_STN);
4222 working.write(modrm & 0x07);
4223 break;
4226 break;
4231 private void writeOutputOperands(int prefices, int opcode, int modrm, int sib, int displacement)
4233 //Normal One Byte Operation
4234 switch (opcode) {
4235 case 0x00: //ADD Eb, Gb
4236 case 0x08: //OR Eb, Gb
4237 case 0x10: //ADC Eb, Gb
4238 case 0x18: //SBB Eb, Gb
4239 case 0x20: //AND Eb, Gb
4240 case 0x28: //SUB Eb, Gb
4241 case 0x30: //XOR Eb, Gb
4242 case 0x88: //MOV Eb, Gb
4243 case 0xc0: //SFT G2 Eb, Ib
4244 case 0xc6: //MOV G11 Eb, Ib
4245 case 0xfe: //INC/DEC G4 Eb
4246 case 0xf90: //SETO
4247 case 0xf91: //SETNO
4248 case 0xf92: //SETC
4249 case 0xf93: //SETNC
4250 case 0xf94: //SETZ
4251 case 0xf95: //SETNZ
4252 case 0xf96: //SETBE
4253 case 0xf97: //SETNBE
4254 case 0xf98: //SETS
4255 case 0xf99: //SETNS
4256 case 0xf9a: //SETP
4257 case 0xf9b: //SETNP
4258 case 0xf9c: //SETL
4259 case 0xf9d: //SETNL
4260 case 0xf9e: //SETLE
4261 case 0xf9f: //SETNLE
4262 store0_Eb(prefices, modrm, sib, displacement);
4263 break;
4265 case 0xfb0: //CMPXCHG Eb, Gb
4266 working.write(STORE1_AL); //do store 1 first incase Eb is also AL/AX/EAX
4267 store0_Eb(prefices, modrm, sib, displacement);
4268 break;
4270 case 0x80: //IMM G1 Eb, Ib
4271 case 0x82: //IMM G1 Eb, Ib
4272 if ((modrm & 0x38) == 0x38)
4273 break;
4274 store0_Eb(prefices, modrm, sib, displacement); break;
4276 case 0x86: //XCHG Eb, Gb
4277 store0_Gb(modrm);
4278 store1_Eb(prefices, modrm, sib, displacement);
4279 break;
4281 case 0x02: //ADD Gb, Eb
4282 case 0x0a: //OR Gb, Eb
4283 case 0x12: //ADC Gb, Eb
4284 case 0x1a: //SBB Gb, Eb
4285 case 0x22: //AND Gb, Eb
4286 case 0x2a: //SUB Gb, Eb
4287 case 0x32: //XOR Gb, Eb
4288 case 0x8a: //MOV Gb, Eb
4289 store0_Gb(modrm);
4290 break;
4292 case 0x01: //ADD Ev, Gv
4293 case 0x09: //OR Ev, Gv
4294 case 0x11: //ADC Ev, Gv
4295 case 0x19: //SBB Ev, Gv
4296 case 0x21: //AND Ev, Gv
4297 case 0x29: //SUB Ev, Gv
4298 case 0x31: //XOR Ev, Gv
4299 case 0x89: //MOV Ev, Gv
4300 case 0xc7: //MOV G11 Ev, Iv
4301 case 0xc1: //SFT G2 Ev, Ib
4302 case 0x8f: //POP Ev
4303 case 0xd1: //SFT G2 Ev, 1
4304 case 0xd3: //SFT G2 Ev, CL
4305 if ((prefices & PREFICES_OPERAND) != 0) {
4306 store0_Ed(prefices, modrm, sib, displacement);
4307 } else {
4308 store0_Ew(prefices, modrm, sib, displacement);
4310 break;
4312 case 0xfb1: //CMPXCHG Ev, Gv
4313 if ((prefices & PREFICES_OPERAND) != 0) {
4314 working.write(STORE1_EAX); //do store1 first incase Eb is same place
4315 store0_Ed(prefices, modrm, sib, displacement);
4316 } else {
4317 working.write(STORE1_AX); //do store1 first incase Eb is same place
4318 store0_Ew(prefices, modrm, sib, displacement);
4320 break;
4322 case 0x81: //IMM G1 Ev, Iv
4323 case 0x83: //IMM G1 Ev, Ib
4324 if ((modrm & 0x38) == 0x38)
4325 break;
4326 if ((prefices & PREFICES_OPERAND) != 0) {
4327 store0_Ed(prefices, modrm, sib, displacement);
4328 } else {
4329 store0_Ew(prefices, modrm, sib, displacement);
4331 break;
4334 case 0x87: //XCHG Ev, Gv
4335 if ((prefices & PREFICES_OPERAND) != 0) {
4336 store0_Gd(modrm);
4337 store1_Ed(prefices, modrm, sib, displacement);
4338 } else {
4339 store0_Gw(modrm);
4340 store1_Ew(prefices, modrm, sib, displacement);
4342 break;
4344 case 0x03: //ADD Gv, Ev
4345 case 0x0b: //OR Gv, Ev
4346 case 0x13: //ADC Gv, Ev
4347 case 0x1b: //SBB Gv, Ev
4348 case 0x23: //AND Gv, Ev
4349 case 0x2b: //SUB Gv, Ev
4350 case 0x33: //XOR Gv, Ev
4351 case 0x69: //IMUL Gv, Ev, Iv
4352 case 0x6b: //IMUL Gv, Ev, Ib
4353 case 0x8b: //MOV Gv, Ev
4354 case 0x8d: //LEA Gv, M
4355 case 0xf02: //LAR Gv, Ew
4356 case 0xf03: //LSL Gv, Ew
4357 case 0xf40: //CMOVO
4358 case 0xf41: //CMOVNO
4359 case 0xf42: //CMOVC
4360 case 0xf43: //CMOVNC
4361 case 0xf44: //CMOVZ
4362 case 0xf45: //CMOVNZ
4363 case 0xf46: //CMOVBE
4364 case 0xf47: //CMOVNBE
4365 case 0xf48: //CMOVS
4366 case 0xf49: //CMOVNS
4367 case 0xf4a: //CMOVP
4368 case 0xf4b: //CMOVNP
4369 case 0xf4c: //CMOVL
4370 case 0xf4d: //CMOVNL
4371 case 0xf4e: //CMOVLE
4372 case 0xf4f: //CMOVNLE
4373 case 0xfaf: //IMUL Gv, Ev
4374 case 0xfb6: //MOVZX Gv, Eb
4375 case 0xfb7: //MOVZX Gv, Ew
4376 case 0xfbc: //BSF Gv, Ev
4377 case 0xfbd: //BSR Gv, Ev
4378 case 0xfbe: //MOVSX Gv, Eb
4379 case 0xfbf: //MOVSX Gv, Ew
4380 if ((prefices & PREFICES_OPERAND) != 0) {
4381 store0_Gd(modrm);
4382 } else {
4383 store0_Gw(modrm);
4385 break;
4387 case 0xec: //IN AL, DX
4388 case 0x04: //ADD AL, Ib
4389 case 0x0c: //OR AL, Ib
4390 case 0x14: //ADC AL, Ib
4391 case 0x1c: //SBB AL, Ib
4392 case 0x24: //AND AL, Ib
4393 case 0x2c: //SUB AL, Ib
4394 case 0x34: //XOR AL, Ib
4395 case 0xe4: //IN AL, Ib
4396 case 0xb0: //MOV AL, Ib
4397 working.write(STORE0_AL);
4398 break;
4400 case 0xb1: //MOV CL, Ib
4401 working.write(STORE0_CL);
4402 break;
4404 case 0xb2: //MOV DL, Ib
4405 working.write(STORE0_DL);
4406 break;
4408 case 0xb3: //MOV BL, Ib
4409 working.write(STORE0_BL);
4410 break;
4412 case 0xb4: //MOV AH, Ib
4413 working.write(STORE0_AH);
4414 break;
4416 case 0xb5: //MOV CH, Ib
4417 working.write(STORE0_CH);
4418 break;
4420 case 0xb6: //MOV DH, Ib
4421 working.write(STORE0_DH);
4422 break;
4424 case 0xb7: //MOV BH, Ib
4425 working.write(STORE0_BH);
4426 break;
4430 case 0x05: //ADD eAX, Iv
4431 case 0x0d: //OR eAX, Iv
4432 case 0x15: //ADC eAX, Iv
4433 case 0x1d: //SBB eAX, Iv
4434 case 0x25: //AND eAX, Iv
4435 case 0x2d: //SUB eAX, Iv
4436 case 0x35: //XOR eAX, Iv
4437 case 0xb8: //MOV eAX, Iv
4438 case 0xe5: //IN eAX, Ib
4439 case 0x40: //INC eAX
4440 case 0x48: //DEC eAX
4441 case 0x58: //POP eAX
4442 case 0xed: //IN eAX, DX
4443 if ((prefices & PREFICES_OPERAND) != 0) {
4444 working.write(STORE0_EAX);
4445 } else {
4446 working.write(STORE0_AX);
4448 break;
4450 case 0x41: //INC eCX
4451 case 0x49: //DEC eCX
4452 case 0x59: //POP eCX
4453 case 0xb9: //MOV eCX, Iv
4454 if ((prefices & PREFICES_OPERAND) != 0) {
4455 working.write(STORE0_ECX);
4456 } else {
4457 working.write(STORE0_CX);
4459 break;
4461 case 0x42: //INC eDX
4462 case 0x4a: //DEC eDX
4463 case 0x5a: //POP eDX
4464 case 0xba: //MOV eDX, Iv
4465 if ((prefices & PREFICES_OPERAND) != 0) {
4466 working.write(STORE0_EDX);
4467 } else {
4468 working.write(STORE0_DX);
4470 break;
4472 case 0x43: //INC eBX
4473 case 0x4b: //DEC eBX
4474 case 0x5b: //POP eBX
4475 case 0xbb: //MOV eBX, Iv
4476 if ((prefices & PREFICES_OPERAND) != 0) {
4477 working.write(STORE0_EBX);
4478 } else {
4479 working.write(STORE0_BX);
4481 break;
4483 case 0x44: //INC eSP
4484 case 0x4c: //DEC eSP
4485 case 0x5c: //POP eSP
4486 case 0xbc: //MOV eSP, Iv
4487 if ((prefices & PREFICES_OPERAND) != 0) {
4488 working.write(STORE0_ESP);
4489 } else {
4490 working.write(STORE0_SP);
4492 break;
4494 case 0x45: //INC eBP
4495 case 0x4d: //DEC eBP
4496 case 0x5d: //POP eBP
4497 case 0xbd: //MOV eBP, Iv
4498 if ((prefices & PREFICES_OPERAND) != 0) {
4499 working.write(STORE0_EBP);
4500 } else {
4501 working.write(STORE0_BP);
4503 break;
4505 case 0x46: //INC eSI
4506 case 0x4e: //DEC eSI
4507 case 0x5e: //POP eSI
4508 case 0xbe: //MOV eSI, Iv
4509 if ((prefices & PREFICES_OPERAND) != 0) {
4510 working.write(STORE0_ESI);
4511 } else {
4512 working.write(STORE0_SI);
4514 break;
4516 case 0x47: //INC eDI
4517 case 0x4f: //DEC eDI
4518 case 0x5f: //POP eDI
4519 case 0xbf: //MOV eDI, Iv
4520 if ((prefices & PREFICES_OPERAND) != 0) {
4521 working.write(STORE0_EDI);
4522 } else {
4523 working.write(STORE0_DI);
4525 break;
4528 case 0x91: //XCHG eAX, eCX
4529 if ((prefices & PREFICES_OPERAND) != 0) {
4530 working.write(STORE0_ECX);
4531 working.write(STORE1_EAX);
4532 } else {
4533 working.write(STORE0_CX);
4534 working.write(STORE1_AX);
4536 break;
4538 case 0x92: //XCHG eAX, eDX
4539 if ((prefices & PREFICES_OPERAND) != 0) {
4540 working.write(STORE0_EDX);
4541 working.write(STORE1_EAX);
4542 } else {
4543 working.write(STORE0_DX);
4544 working.write(STORE1_AX);
4546 break;
4548 case 0x93: //XCHG eAX, eBX
4549 if ((prefices & PREFICES_OPERAND) != 0) {
4550 working.write(STORE0_EBX);
4551 working.write(STORE1_EAX);
4552 } else {
4553 working.write(STORE0_BX);
4554 working.write(STORE1_AX);
4556 break;
4558 case 0x94: //XCHG eAX, eSP
4559 if ((prefices & PREFICES_OPERAND) != 0) {
4560 working.write(STORE0_ESP);
4561 working.write(STORE1_EAX);
4562 } else {
4563 working.write(STORE0_SP);
4564 working.write(STORE1_AX);
4566 break;
4568 case 0x95: //XCHG eAX, eBP
4569 if ((prefices & PREFICES_OPERAND) != 0) {
4570 working.write(STORE0_EBP);
4571 working.write(STORE1_EAX);
4572 } else {
4573 working.write(STORE0_BP);
4574 working.write(STORE1_AX);
4576 break;
4578 case 0x96: //XCHG eAX, eSI
4579 if ((prefices & PREFICES_OPERAND) != 0) {
4580 working.write(STORE0_ESI);
4581 working.write(STORE1_EAX);
4582 } else {
4583 working.write(STORE0_SI);
4584 working.write(STORE1_AX);
4586 break;
4588 case 0x97: //XCHG eAX, eDI
4589 if ((prefices & PREFICES_OPERAND) != 0) {
4590 working.write(STORE0_EDI);
4591 working.write(STORE1_EAX);
4592 } else {
4593 working.write(STORE0_DI);
4594 working.write(STORE1_AX);
4596 break;
4598 case 0x9d:
4599 switch (prefices & PREFICES_OPERAND) {
4600 case 0:
4601 working.write(STORE0_FLAGS); break;
4602 case PREFICES_OPERAND:
4603 working.write(STORE0_EFLAGS); break;
4605 break;
4607 case 0xd0: //SFT G2 Eb, 1
4608 case 0xd2: //SFT G2 Eb, CL
4609 store0_Eb(prefices, modrm, sib, displacement);
4610 break;
4614 case 0xf6: //UNA G3 Eb, ?
4615 switch (modrm & 0x38) {
4616 case 0x10:
4617 case 0x18:
4618 store0_Eb(prefices, modrm, sib, displacement);
4619 break;
4621 break;
4623 case 0xf7: //UNA G3 Ev, ?
4624 if ((prefices & PREFICES_OPERAND) != 0) {
4625 switch (modrm & 0x38) {
4626 case 0x10:
4627 case 0x18:
4628 store0_Ed(prefices, modrm, sib, displacement);
4629 break;
4631 } else {
4632 switch (modrm & 0x38) {
4633 case 0x10:
4634 case 0x18:
4635 store0_Ew(prefices, modrm, sib, displacement);
4636 break;
4639 break;
4642 case 0x07: //POP ES
4643 working.write(STORE0_ES);
4644 break;
4646 case 0x17: //POP SS
4647 working.write(STORE0_SS);
4648 break;
4650 case 0x1f: //POP DS
4651 working.write(STORE0_DS);
4652 break;
4654 case 0x8c: //MOV Ew, Sw
4655 if ((prefices & PREFICES_OPERAND) != 0) {
4656 store0_Ed(prefices, modrm, sib, displacement);
4657 } else {
4658 store0_Ew(prefices, modrm, sib, displacement);
4660 break;
4662 case 0x8e: //MOV Sw, Ew
4663 store0_Sw(modrm);
4664 break;
4666 case 0xa0: //MOV AL, Ob
4667 working.write(STORE0_AL);
4668 break;
4670 case 0xa2: //MOV Ob, AL
4671 store0_Ob(prefices, displacement);
4672 break;
4674 case 0xa1: //MOV eAX, Ov
4675 if ((prefices & PREFICES_OPERAND) != 0) {
4676 working.write(STORE0_EAX);
4677 } else {
4678 working.write(STORE0_AX);
4680 break;
4682 case 0xa3: //MOV Ov, eAX
4683 if ((prefices & PREFICES_OPERAND) != 0) {
4684 store0_Od(prefices, displacement);
4685 } else {
4686 store0_Ow(prefices, displacement);
4688 break;
4690 case 0xff: //INC/DEC G5
4691 if ((prefices & PREFICES_OPERAND) != 0) {
4692 switch (modrm & 0x38) {
4693 case 0x00: //INC Ed
4694 case 0x08: //DEC Ed
4695 store0_Ed(prefices, modrm, sib, displacement);
4697 } else {
4698 switch (modrm & 0x38) {
4699 case 0x00:
4700 case 0x08:
4701 store0_Ew(prefices, modrm, sib, displacement);
4704 break;
4706 case 0xc4: //LES Gv, Mp
4707 if ((prefices & PREFICES_OPERAND) != 0) {
4708 store0_Gd(modrm);
4709 working.write(STORE1_ES);
4710 } else {
4711 store0_Gw(modrm);
4712 working.write(STORE1_ES);
4714 break;
4716 case 0xc5: //LDS Gv, Mp
4717 if ((prefices & PREFICES_OPERAND) != 0) {
4718 store0_Gd(modrm);
4719 working.write(STORE1_DS);
4720 } else {
4721 store0_Gw(modrm);
4722 working.write(STORE1_DS);
4724 break;
4726 case 0xf00: // Group 6
4727 switch (modrm & 0x38) {
4728 case 0x00: //SLDT
4729 store0_Ew(prefices, modrm, sib, displacement); break;
4730 case 0x08: //STR (stores to a doubleword if a register, but a word if memory)
4731 if ((prefices & PREFICES_OPERAND) != 0) {
4732 switch (modrm & 0xc7) {
4733 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_WORD); break;
4735 case 0xc0: working.write(STORE0_EAX); break;
4736 case 0xc1: working.write(STORE0_ECX); break;
4737 case 0xc2: working.write(STORE0_EDX); break;
4738 case 0xc3: working.write(STORE0_EBX); break;
4739 case 0xc4: working.write(STORE0_ESP); break;
4740 case 0xc5: working.write(STORE0_EBP); break;
4741 case 0xc6: working.write(STORE0_ESI); break;
4742 case 0xc7: working.write(STORE0_EDI); break;
4745 else
4746 store0_Ew(prefices, modrm, sib, displacement);
4747 break;
4748 } break;
4750 case 0xf01:
4751 switch (modrm & 0x38) {
4752 case 0x00:
4753 case 0x08:
4754 store0_Ew(prefices, modrm, sib, displacement);
4755 working.write(ADDR_ID);
4756 working.write(2);
4757 working.write(STORE1_MEM_DWORD);
4758 break;
4759 case 0x20: store0_Ew(prefices, modrm, sib, displacement); break;
4760 } break;
4762 case 0xf1f: break; //multi byte NOP (read latest manual)
4763 case 0xfa4: //SHLD Ev, Gv, Ib
4764 case 0xfa5: //SHLD Ev, Gv, CL
4765 case 0xfac: //SHRD Ev, Gv, Ib
4766 case 0xfad: //SHRD Ev, Gv, CL
4767 if ((prefices & PREFICES_OPERAND) != 0)
4768 store0_Ed(prefices, modrm, sib, displacement);
4769 else
4770 store0_Ew(prefices, modrm, sib, displacement);
4771 break;
4773 case 0xfb2: //LSS Mp
4774 if ((prefices & PREFICES_OPERAND) != 0) {
4775 store0_Gd(modrm);
4776 working.write(STORE1_SS);
4777 } else {
4778 store0_Gw(modrm);
4779 working.write(STORE1_SS);
4781 break;
4783 case 0xfb4: //LFS Mp
4784 if ((prefices & PREFICES_OPERAND) != 0) {
4785 store0_Gd(modrm);
4786 working.write(STORE1_FS);
4787 } else {
4788 store0_Gw(modrm);
4789 working.write(STORE1_FS);
4791 break;
4793 case 0xfb5: //LGS Mp
4794 if ((prefices & PREFICES_OPERAND) != 0) {
4795 store0_Gd(modrm);
4796 working.write(STORE1_GS);
4797 } else {
4798 store0_Gw(modrm);
4799 working.write(STORE1_GS);
4801 break;
4803 case 0xfc0: //XADD Eb, Gb
4804 store1_Gb(modrm); //exchange first then add (so we write the result of the exchange first incase Eb and Gb are same reg)
4805 store0_Eb(prefices, modrm, sib, displacement);
4806 break;
4808 case 0xfc1: //XADD Eb, Gb
4809 if ((prefices & PREFICES_OPERAND) != 0) {
4810 store1_Gd(modrm); //exchange first then add
4811 store0_Ed(prefices, modrm, sib, displacement);
4812 } else {
4813 store1_Gw(modrm); //exchange first then add
4814 store0_Ew(prefices, modrm, sib, displacement);
4816 break;
4818 case 0xd6: //SALC
4819 case 0xd7: // XLAT
4820 working.write(STORE0_AL); break;
4822 case 0xf20: //MOV Rd, Cd
4823 case 0xf21: //MOV Rd, Dd
4824 store0_Rd(modrm); break;
4826 case 0xf22: store0_Cd(modrm); break; //MOV Cd, Rd
4827 case 0xf23: store0_Dd(modrm); break; //MOV Dd, Rd
4829 case 0xf31: //RDTSC
4830 case 0xf32: //RDMSR
4831 working.write(STORE0_EAX);
4832 working.write(STORE1_EDX);
4833 break;
4836 case 0xfa1: //POP FS
4837 working.write(STORE0_FS); break;
4839 case 0xfa9: //POP GS
4840 working.write(STORE0_GS); break;
4842 case 0xfab: //BTS Ev, Gv
4843 case 0xfb3: //BTR Ev, Gv
4844 case 0xfbb: //BTC Ev, Gv
4845 if ((prefices & PREFICES_OPERAND) != 0) {
4846 if ((modrm & 0xc0) == 0xc0)
4847 store0_Ed(prefices, modrm, sib, displacement);
4848 } else {
4849 if ((modrm & 0xc0) == 0xc0)
4850 store0_Ew(prefices, modrm, sib, displacement);
4852 break;
4854 case 0xfba: //Grp 8 Ev, Ib
4855 switch (modrm & 0x38) {
4856 case 0x28:
4857 case 0x30:
4858 case 0x38:
4859 if ((prefices & PREFICES_OPERAND) != 0) {
4860 if ((modrm & 0xc0) == 0xc0)
4861 store0_Ed(prefices, modrm, sib, displacement);
4862 } else {
4863 if ((modrm & 0xc0) == 0xc0)
4864 store0_Ew(prefices, modrm, sib, displacement);
4866 break;
4867 } break;
4869 case 0xfc7: //CMPXCHG8B
4870 switch (modrm & 0x38)
4872 case 0x08:
4873 decodeM(prefices, modrm, sib, displacement);
4874 working.write(STORE0_MEM_QWORD);
4875 break;
4876 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm & 0x38) >> 3) + "?");
4878 break;
4880 case 0xfc8: working.write(STORE0_EAX); break; //BSWAP EAX
4881 case 0xfc9: working.write(STORE0_ECX); break; //BSWAP ECX
4882 case 0xfca: working.write(STORE0_EDX); break; //BSWAP EDX
4883 case 0xfcb: working.write(STORE0_EBX); break; //BSWAP EBX
4884 case 0xfcc: working.write(STORE0_ESP); break; //BSWAP ESP
4885 case 0xfcd: working.write(STORE0_EBP); break; //BSWAP EBP
4886 case 0xfce: working.write(STORE0_ESI); break; //BSWAP ESI
4887 case 0xfcf: working.write(STORE0_EDI); break; //BSWAP EDI
4889 case 0xd800:
4890 switch (modrm & 0x38)
4892 case 0x00:
4893 case 0x08:
4894 case 0x20:
4895 case 0x28:
4896 case 0x30:
4897 case 0x38:
4898 working.write(FSTORE0_ST0);
4899 working.write(FCHECK0);
4900 break;
4901 case 0x10: break;
4902 case 0x18: working.write(FPOP); break;
4904 break;
4906 case 0xd900:
4907 if ((modrm & 0xc0) != 0xc0)
4909 switch (modrm & 0x38)
4911 case 0x00:
4912 case 0x20:
4913 case 0x30:
4914 break;
4915 case 0x10:
4916 decodeM(prefices, modrm, sib, displacement);
4917 working.write(FSTORE0_MEM_SINGLE);
4918 break;
4919 case 0x18:
4920 decodeM(prefices, modrm, sib, displacement);
4921 working.write(FSTORE0_MEM_SINGLE);
4922 working.write(FPOP);
4923 break;
4924 case 0x28: working.write(STORE0_FPUCW); break;
4925 case 0x38:
4926 decodeM(prefices, modrm, sib, displacement);
4927 working.write(STORE0_MEM_WORD);
4928 break;
4931 else
4933 switch (modrm & 0xf8)
4935 case 0xc0: break;
4936 case 0xc8:
4937 working.write(FSTORE0_STN);
4938 working.write(modrm & 0x07);
4939 working.write(FSTORE1_ST0);
4940 break;
4942 switch (modrm)
4944 case 0xd0:
4945 case 0xe4:
4946 case 0xe5:
4947 case 0xe8:
4948 case 0xe9:
4949 case 0xea:
4950 case 0xeb:
4951 case 0xec:
4952 case 0xed:
4953 case 0xee:
4954 case 0xf6:
4955 case 0xf7: break;
4956 case 0xe0:
4957 case 0xe1:
4958 case 0xfe:
4959 case 0xff: working.write(FSTORE0_ST0); break;
4960 case 0xf0:
4961 case 0xf5:
4962 case 0xf8:
4963 case 0xfa:
4964 case 0xfc:
4965 case 0xfd:
4966 working.write(FSTORE0_ST0);
4967 working.write(FCHECK0);
4968 break;
4969 case 0xf2:
4970 working.write(FSTORE0_ST0);
4971 working.write(FLOAD0_1);
4972 working.write(FPUSH);
4973 break;
4974 case 0xf1:
4975 case 0xf3:
4976 working.write(FPOP);
4977 working.write(FSTORE0_ST0);
4978 break;
4979 case 0xf9:
4980 working.write(FPOP);
4981 working.write(FSTORE0_ST0);
4982 working.write(FCHECK0);
4983 break;
4984 case 0xf4:
4985 working.write(FSTORE1_ST0);
4986 working.write(FPUSH);
4987 break;
4988 case 0xfb:
4989 working.write(FSTORE1_ST0);
4990 working.write(FPUSH);
4991 working.write(FCHECK0);
4992 working.write(FCHECK1);
4993 break;
4996 break;
4998 case 0xda00:
4999 if ((modrm & 0xc0) != 0xc0)
5001 switch (modrm & 0x38)
5003 case 0x00:
5004 case 0x08:
5005 case 0x20:
5006 case 0x28:
5007 case 0x30:
5008 case 0x38:
5009 working.write(FSTORE0_ST0);
5010 working.write(FCHECK0);
5011 break;
5012 case 0x10: break;
5013 case 0x18: working.write(FPOP); break;
5016 else
5018 switch (modrm)
5020 case 0xe9:
5021 working.write(FPOP);
5022 working.write(FPOP);
5023 break;
5026 break;
5028 case 0xdb00:
5029 if ((modrm & 0xc0) != 0xc0)
5031 switch (modrm & 0x38)
5033 case 0x00:
5034 case 0x28: break;
5035 case 0x10:
5036 decodeM(prefices, modrm, sib, displacement);
5037 working.write(STORE0_MEM_DWORD);
5038 break;
5039 case 0x08:
5040 case 0x18:
5041 decodeM(prefices, modrm, sib, displacement);
5042 working.write(STORE0_MEM_DWORD);
5043 working.write(FPOP);
5044 break;
5045 case 0x38:
5046 decodeM(prefices, modrm, sib, displacement);
5047 working.write(FSTORE0_MEM_EXTENDED);
5048 working.write(FPOP);
5049 break;
5052 break;
5054 case 0xdc00:
5055 if ((modrm & 0xc0) != 0xc0)
5057 switch (modrm & 0x38)
5059 case 0x00:
5060 case 0x08:
5061 case 0x20:
5062 case 0x28:
5063 case 0x30:
5064 case 0x38:
5065 working.write(FSTORE0_ST0);
5066 working.write(FCHECK0);
5067 break;
5068 case 0x10: break;
5069 case 0x18: working.write(FPOP); break;
5072 else
5074 switch (modrm & 0xf8)
5076 case 0xc0:
5077 case 0xc8:
5078 case 0xe0:
5079 case 0xe8:
5080 case 0xf0:
5081 case 0xf8:
5082 working.write(FSTORE0_STN);
5083 working.write(modrm & 0x07);
5084 working.write(FCHECK0);
5085 break;
5088 break;
5090 case 0xdd00:
5091 if ((modrm & 0xc0) != 0xc0)
5093 switch (modrm & 0x38)
5095 case 0x00:
5096 case 0x20:
5097 case 0x30: break;
5098 case 0x08:
5099 decodeM(prefices, modrm, sib, displacement);
5100 working.write(STORE0_MEM_QWORD);
5101 working.write(FPOP);
5102 break;
5103 case 0x10:
5104 decodeM(prefices, modrm, sib, displacement);
5105 working.write(FSTORE0_MEM_DOUBLE);
5106 break;
5107 case 0x18:
5108 decodeM(prefices, modrm, sib, displacement);
5109 working.write(FSTORE0_MEM_DOUBLE);
5110 working.write(FPOP);
5111 break;
5112 case 0x38:
5113 decodeM(prefices, modrm, sib, displacement);
5114 working.write(STORE0_MEM_WORD);
5115 break;
5118 else
5120 switch (modrm & 0xf8)
5122 case 0xc0:
5123 case 0xe0: break;
5124 case 0xd0:
5125 working.write(FSTORE0_STN);
5126 working.write(modrm & 0x07);
5127 break;
5128 case 0xd8:
5129 working.write(FSTORE0_STN);
5130 working.write(modrm & 0x07);
5131 working.write(FPOP);
5132 break;
5133 case 0xe8: working.write(FPOP); break;
5136 break;
5138 case 0xde00:
5139 if ((modrm & 0xc0) != 0xc0)
5141 switch (modrm & 0x38)
5143 case 0x00:
5144 case 0x08:
5145 case 0x20:
5146 case 0x28:
5147 case 0x30:
5148 case 0x38:
5149 working.write(FSTORE0_ST0);
5150 working.write(FCHECK0);
5151 break;
5152 case 0x10: break;
5153 case 0x18: working.write(FPOP); break;
5156 else
5158 switch (modrm & 0xf8)
5160 case 0xc0:
5161 case 0xc8:
5162 case 0xe0:
5163 case 0xe8:
5164 case 0xf0:
5165 case 0xf8:
5166 working.write(FSTORE0_STN);
5167 working.write(modrm & 0x07);
5168 working.write(FPOP);
5169 working.write(FCHECK0);
5170 break;
5171 case 0xd0:
5172 case 0xd8: break;
5174 switch (modrm)
5176 case 0xd9:
5177 working.write(FPOP);
5178 working.write(FPOP);
5179 break;
5182 break;
5184 case 0xdf00:
5185 if ((modrm & 0xc0) != 0xc0)
5187 switch (modrm & 0x38)
5189 case 0x00:
5190 case 0x20:
5191 case 0x28:
5192 case 0x30: break;
5193 case 0x08:
5194 case 0x18:
5195 decodeM(prefices, modrm, sib, displacement);
5196 working.write(STORE0_MEM_WORD);
5197 working.write(FPOP);
5198 break;
5199 case 0x10:
5200 decodeM(prefices, modrm, sib, displacement);
5201 working.write(STORE0_MEM_WORD);
5202 break;
5203 case 0x38:
5204 decodeM(prefices, modrm, sib, displacement);
5205 working.write(STORE0_MEM_QWORD);
5206 working.write(FPOP);
5207 break;
5210 else
5212 switch (modrm & 0xf8)
5214 case 0xe8:
5215 case 0xf0: working.write(FPOP); break;
5217 switch (modrm)
5219 case 0xe0: working.write(STORE0_AX); break;
5222 break;
5227 private static int operationHasImmediate(int prefices, int opcode, int modrm)
5229 switch (opcode) {
5230 case 0x04: //ADD AL, Ib
5231 case 0x0c: //OR AL, Ib
5232 case 0x14: //ADC AL, Ib
5233 case 0x1c: //SBB AL, Ib
5234 case 0x24: //AND AL, Ib
5235 case 0x2c: //SUB AL, Ib
5236 case 0x34: //XOR AL, Ib
5237 case 0x3c: //CMP AL, Ib
5238 case 0x6a: //PUSH Ib
5239 case 0x6b: //IMUL Gv, Ev, Ib
5240 case 0x70: //Jcc Jb
5241 case 0x71:
5242 case 0x72:
5243 case 0x73:
5244 case 0x74:
5245 case 0x75:
5246 case 0x76:
5247 case 0x77:
5248 case 0x78:
5249 case 0x79:
5250 case 0x7a:
5251 case 0x7b:
5252 case 0x7c:
5253 case 0x7d:
5254 case 0x7e:
5255 case 0x7f:
5256 case 0x80: //IMM G1 Eb, Ib
5257 case 0x82: //IMM G1 Eb, Ib
5258 case 0x83: //IMM G1 Ev, Ib
5259 case 0xa8: //TEST AL, Ib
5260 case 0xb0: //MOV AL, Ib
5261 case 0xb1: //MOV CL, Ib
5262 case 0xb2: //MOV DL, Ib
5263 case 0xb3: //MOV BL, Ib
5264 case 0xb4: //MOV AH, Ib
5265 case 0xb5: //MOV CH, Ib
5266 case 0xb6: //MOV DH, Ib
5267 case 0xb7: //MOV BH, Ib
5268 case 0xc0: //SFT G2 Eb, Ib
5269 case 0xc1: //SFT G2 Ev, Ib
5270 case 0xc6: //MOV G11 Eb, Ib
5271 case 0xcd: //INT Ib
5272 case 0xd4: //AAM Ib
5273 case 0xd5: //AAD Ib
5274 case 0xe0: //LOOPNZ Jb
5275 case 0xe1: //LOOPZ Jb
5276 case 0xe2: //LOOP Jb
5277 case 0xe3: //JCXZ Jb
5278 case 0xe4: //IN AL, Ib
5279 case 0xe5: //IN eAX, Ib
5280 case 0xe6: //OUT Ib, AL
5281 case 0xe7: //OUT Ib, eAX
5282 case 0xeb: //JMP Jb
5283 case 0xfa4: //SHLD Ev, Gv, Ib
5284 case 0xfac: //SHRD Ev, Gv, Ib
5285 case 0xfba: //Grp 8 Ev, Ib
5286 return 1;
5288 case 0xc2: //RET Iw
5289 case 0xca: //RETF Iw
5290 return 2;
5292 case 0xc8: //ENTER Iw, Ib
5293 return 3;
5295 case 0x05: //ADD eAX, Iv
5296 case 0x0d: //OR eAX, Iv
5297 case 0x15: //ADC eAX, Iv
5298 case 0x1d: //SBB eAX, Iv
5299 case 0x25: //AND eAX, Iv
5300 case 0x2d: //SUB eAX, Iv
5301 case 0x35: //XOR eAX, Iv
5302 case 0x3d: //CMP eAX, Iv
5303 case 0x68: //PUSH Iv
5304 case 0x69: //IMUL Gv, Ev, Iv
5305 case 0x81: //IMM G1 Ev, Iv
5306 case 0xa9: //TEST eAX, Iv
5307 case 0xb8: //MOV eAX, Iv
5308 case 0xb9: //MOV eCX, Iv
5309 case 0xba: //MOV eDX, Iv
5310 case 0xbb: //MOV eBX, Iv
5311 case 0xbc: //MOV eSP, Iv
5312 case 0xbd: //MOV eBP, Iv
5313 case 0xbe: //MOV eSI, Iv
5314 case 0xbf: //MOV eDI, Iv
5315 case 0xc7: //MOV G11 Ev, Iv
5316 case 0xe8: //CALL Jv
5317 case 0xe9: //JMP Jv
5318 case 0xf80: //JO Jv
5319 case 0xf81: //JNO Jv
5320 case 0xf82: //JC Jv
5321 case 0xf83: //JNC Jv
5322 case 0xf84: //JZ Jv
5323 case 0xf85: //JNZ Jv
5324 case 0xf86: //JNA Jv
5325 case 0xf87: //JA Jv
5326 case 0xf88: //JS Jv
5327 case 0xf89: //JNS Jv
5328 case 0xf8a: //JP Jv
5329 case 0xf8b: //JNP Jv
5330 case 0xf8c: //JL Jv
5331 case 0xf8d: //JNL Jv
5332 case 0xf8e: //JNG Jv
5333 case 0xf8f: //JG Jv
5334 if ((prefices & PREFICES_OPERAND) != 0)
5335 return 4;
5336 else
5337 return 2;
5339 case 0x9a: //CALLF Ap
5340 case 0xea: //JMPF Ap
5341 if ((prefices & PREFICES_OPERAND) != 0)
5342 return 6;
5343 else
5344 return 4;
5346 case 0xf6: //UNA G3 Eb, ?
5347 switch (modrm & 0x38) {
5348 case 0x00: //TEST Eb, Ib
5349 return 1;
5350 default:
5351 return 0;
5354 case 0xf7: //UNA G3 Ev, ?
5355 switch (modrm & 0x38) {
5356 case 0x00: //TEST Ev, Iv
5357 if ((prefices & PREFICES_OPERAND) != 0)
5358 return 4;
5359 else
5360 return 2;
5361 default:
5362 return 0;
5365 return 0;
5368 private static int operationHasDisplacement(int prefices, int opcode, int modrm, int sib)
5370 switch (opcode) {
5371 //modrm things
5372 case 0x00: //ADD Eb, Gb
5373 case 0x01: //ADD Ev, Gv
5374 case 0x02: //ADD Gb, Eb
5375 case 0x03: //ADD Gv, Ev
5376 case 0x08: //OR Eb, Gb
5377 case 0x09: //OR Ev, Gv
5378 case 0x0a: //OR Gb, Eb
5379 case 0x0b: //OR Gv, Ev
5380 case 0x10: //ADC Eb, Gb
5381 case 0x11: //ADC Ev, Gv
5382 case 0x12: //ADC Gb, Eb
5383 case 0x13: //ADC Gv, Ev
5384 case 0x18: //SBB Eb, Gb
5385 case 0x19: //SBB Ev, Gv
5386 case 0x1a: //SBB Gb, Eb
5387 case 0x1b: //SBB Gv, Ev
5388 case 0x20: //AND Eb, Gb
5389 case 0x21: //AND Ev, Gv
5390 case 0x22: //AND Gb, Eb
5391 case 0x23: //AND Gv, Ev
5392 case 0x28: //SUB Eb, Gb
5393 case 0x29: //SUB Ev, Gv
5394 case 0x2a: //SUB Gb, Eb
5395 case 0x2b: //SUB Gv, Ev
5396 case 0x30: //XOR Eb, Gb
5397 case 0x31: //XOR Ev, Gv
5398 case 0x32: //XOR Gb, Eb
5399 case 0x33: //XOR Gv, Ev
5400 case 0x38: //CMP Eb, Gb
5401 case 0x39: //CMP Ev, Gv
5402 case 0x3a: //CMP Gb, Eb
5403 case 0x3b: //CMP Gv, Ev
5404 case 0x62: //BOUND Gv, Ma
5405 case 0x69: //IMUL Gv, Ev, Iv
5406 case 0x6b: //IMUL Gv, Ev, Ib
5407 case 0x80: //IMM G1 Eb, Ib
5408 case 0x81: //IMM G1 Ev, Iv
5409 case 0x82: //IMM G1 Eb, Ib
5410 case 0x83: //IMM G1 Ev, Ib
5411 case 0x84: //TEST Eb, Gb
5412 case 0x85: //TEST Ev, Gv
5413 case 0x86: //XCHG Eb, Gb
5414 case 0x87: //XCHG Ev, Gv
5415 case 0x88: //MOV Eb, Gb
5416 case 0x89: //MOV Ev, Gv
5417 case 0x8a: //MOV Gb, Eb
5418 case 0x8b: //MOV Gv, Ev
5419 case 0x8c: //MOV Ew, Sw
5420 case 0x8d: //LEA Gv, M
5421 case 0x8e: //MOV Sw, Ew
5422 case 0x8f: //POP Ev
5423 case 0xc0: //SFT G2 Eb, Ib
5424 case 0xc1: //SFT G2 Ev, Ib
5425 case 0xc4: //LES Gv, Mp
5426 case 0xc5: //LDS Gv, Mp
5427 case 0xc6: //MOV G11 Eb, Ib
5428 case 0xc7: //MOV G11 Ev, Iv
5429 case 0xd0: //SFT G2 Eb, 1
5430 case 0xd1: //SFT G2 Ev, 1
5431 case 0xd2: //SFT G2 Eb, CL
5432 case 0xd3: //SFT G2 Ev, CL
5433 case 0xf6: //UNA G3 Eb, ?
5434 case 0xf7: //UNA G3 Ev, ?
5435 case 0xfe: //INC/DEC G4 Eb
5436 case 0xff: //INC/DEC G5
5438 case 0xf00: //Grp 6
5439 case 0xf01: //Grp 7
5440 case 0xf02: //LAR Gv, Ew
5441 case 0xf03: //LSL Gv, Ew
5443 case 0xf20: //MOV Rd, Cd
5444 case 0xf22: //MOV Cd, Rd
5446 case 0xf40: //CMOVO
5447 case 0xf41: //CMOVNO
5448 case 0xf42: //CMOVC
5449 case 0xf43: //CMOVNC
5450 case 0xf44: //CMOVZ
5451 case 0xf45: //CMOVNZ
5452 case 0xf46: //CMOVBE
5453 case 0xf47: //CMOVNBE
5454 case 0xf48: //CMOVS
5455 case 0xf49: //CMOVNS
5456 case 0xf4a: //CMOVP
5457 case 0xf4b: //CMOVNP
5458 case 0xf4c: //CMOVL
5459 case 0xf4d: //CMOVNL
5460 case 0xf4e: //CMOVLE
5461 case 0xf4f: //CMOVNLE
5463 case 0xf90: //SETO
5464 case 0xf91: //SETNO
5465 case 0xf92: //SETC
5466 case 0xf93: //SETNC
5467 case 0xf94: //SETZ
5468 case 0xf95: //SETNZ
5469 case 0xf96: //SETBE
5470 case 0xf97: //SETNBE
5471 case 0xf98: //SETS
5472 case 0xf99: //SETNS
5473 case 0xf9a: //SETP
5474 case 0xf9b: //SETNP
5475 case 0xf9c: //SETL
5476 case 0xf9d: //SETNL
5477 case 0xf9e: //SETLE
5478 case 0xf9f: //SETNLE
5480 case 0xfa3: //BT Ev, Gv
5481 case 0xfa4: //SHLD Ev, Gv, Ib
5482 case 0xfa5: //SHLD Ev, Gv, CL
5483 case 0xfab: //BTS Ev, Gv
5484 case 0xfac: //SHRD Ev, Gv, Ib
5485 case 0xfad: //SHRD Ev, Gv, CL
5487 case 0xfaf: //IMUL Gv, Ev
5489 case 0xfb0: //CMPXCHG Eb, Gb
5490 case 0xfb1: //CMPXCHG Ev, Gv
5491 case 0xfb2: //LSS Mp
5492 case 0xfb3: //BTR Ev, Gv
5493 case 0xfb4: //LFS Mp
5494 case 0xfb5: //LGS Mp
5495 case 0xfb6: //MOVZX Gv, Eb
5496 case 0xfb7: //MOVZX Gv, Ew
5498 case 0xfba: //Grp 8 Ev, Ib
5499 case 0xfbb: //BTC Ev, Gv
5500 case 0xfbc: //BSF Gv, Ev
5501 case 0xfbd: //BSR Gv, Ev
5502 case 0xfbe: //MOVSX Gv, Eb
5503 case 0xfbf: //MOVSX Gv, Ew
5504 case 0xfc0: //XADD Eb, Gb
5505 case 0xfc1: //XADD Ev, Gv
5507 case 0xfc7: //CMPXCHG8B
5508 return modrmHasDisplacement(prefices, modrm, sib);
5510 //From Input
5511 case 0xd800:
5512 case 0xd900:
5513 case 0xda00:
5514 case 0xdb00:
5515 case 0xdc00:
5516 case 0xdd00:
5517 case 0xde00:
5518 case 0xdf00:
5519 if ((modrm & 0xc0) != 0xc0)
5520 return modrmHasDisplacement(prefices, modrm, sib);
5521 else
5522 return 0;
5524 //special cases
5525 case 0xa0: //MOV AL, Ob
5526 case 0xa2: //MOV Ob, AL
5527 case 0xa1: //MOV eAX, Ov
5528 case 0xa3: //MOV Ov, eAX
5529 if ((prefices & PREFICES_ADDRESS) != 0)
5530 return 4;
5531 else
5532 return 2;
5534 default: return 0;
5539 private static int modrmHasDisplacement(int prefices, int modrm, int sib)
5541 if ((prefices & PREFICES_ADDRESS) != 0) {
5542 //32 bit address size
5543 switch(modrm & 0xc0) {
5544 case 0x00:
5545 switch (modrm & 0x7) {
5546 case 0x4:
5547 if ((sib & 0x7) == 0x5)
5548 return 4;
5549 else
5550 return 0;
5551 case 0x5: return 4;
5553 break;
5554 case 0x40: return 1; //IB
5555 case 0x80: return 4; //ID
5557 } else {
5558 //16 bit address size
5559 switch(modrm & 0xc0) {
5560 case 0x00:
5561 if ((modrm & 0x7) == 0x6)
5562 return 2;
5563 else
5564 return 0;
5565 case 0x40: return 1; //IB
5566 case 0x80: return 2; //IW
5570 return 0;
5573 public static boolean isFarJump(int opcode, int modrm)
5575 switch (opcode)
5577 case 0x9a: //CALLF Ap
5578 case 0xca: //RETF Iw
5579 case 0xcb: //RETF
5580 case 0xcc: //INT 3
5581 case 0xcd: //INT Ib
5582 case 0xce: //INTO
5583 case 0xcf: //IRET
5584 case 0xea: //JMPF Ap
5585 case 0xf1: //INT 1
5586 case 0xf34: //SYSENTER
5587 case 0xf35: //SYSEXIT
5588 return true;
5590 case 0xff:
5591 switch (modrm & 0x38) {
5592 case 0x18: //CALLF Ep
5593 case 0x28: //JMPF Ep
5594 return true;
5595 default: return false;
5598 default:
5599 return false;
5603 public static boolean isNearJump(int opcode, int modrm)
5605 switch (opcode)
5607 case 0x70: //Jcc Jb
5608 case 0x71:
5609 case 0x72:
5610 case 0x73:
5611 case 0x74:
5612 case 0x75:
5613 case 0x76:
5614 case 0x77:
5615 case 0x78:
5616 case 0x79:
5617 case 0x7a:
5618 case 0x7b:
5619 case 0x7c:
5620 case 0x7d:
5621 case 0x7e:
5622 case 0x7f:
5623 case 0xc2: //RET Iw
5624 case 0xc3: //RET
5625 case 0xe0: //LOOPNZ Jb
5626 case 0xe1: //LOOPZ Jb
5627 case 0xe2: //LOOP Jb
5628 case 0xe3: //JCXZ Jb
5629 case 0xe8: //CALL Jv
5630 case 0xe9: //JMP Jv
5631 case 0xeb: //JMP Jb
5632 return true;
5634 case 0xff:
5635 switch (modrm & 0x38) {
5636 case 0x10: //CALLN Ed
5637 case 0x20: //JMPN Ed
5638 return true;
5639 default: return false;
5642 case 0x0f80: //Jcc Jv
5643 case 0x0f81:
5644 case 0x0f82:
5645 case 0x0f83:
5646 case 0x0f84:
5647 case 0x0f85:
5648 case 0x0f86:
5649 case 0x0f87:
5650 case 0x0f88:
5651 case 0x0f89:
5652 case 0x0f8a:
5653 case 0x0f8b:
5654 case 0x0f8c:
5655 case 0x0f8d:
5656 case 0x0f8e:
5657 case 0x0f8f:
5658 return true;
5659 default:
5660 return false;
5664 public static boolean isModeSwitch(int opcode, int modrm)
5666 switch (opcode) {
5667 case 0x0f22: //MOV Cd, Ed
5668 return true;
5669 case 0x0f01: //LMSW
5670 return ((modrm & 0x38) == 0x30);
5671 default:
5672 return false;
5676 public static boolean isBlockTerminating(int opcode, int modrm)
5678 switch (opcode) {
5679 //case 0xfb: //STI
5680 case 0xf4: //HLT
5681 return true;
5682 default:
5683 return false;
5687 public static boolean isJump(int opcode, int modrm)
5689 return isNearJump(opcode, modrm) || isFarJump(opcode, modrm) || isModeSwitch(opcode, modrm) || isBlockTerminating(opcode, modrm);
5692 private void store0_Cd(int modrm)
5694 switch(modrm & 0x38) {
5695 case 0x00: working.write(STORE0_CR0); break;
5696 case 0x10: working.write(STORE0_CR2); break;
5697 case 0x18: working.write(STORE0_CR3); break;
5698 case 0x20: working.write(STORE0_CR4); break;
5699 default: throw new IllegalStateException("Unknown Control Register Operand");
5703 private void load0_Cd(int modrm)
5705 switch(modrm & 0x38) {
5706 case 0x00: working.write(LOAD0_CR0); break;
5707 case 0x10: working.write(LOAD0_CR2); break;
5708 case 0x18: working.write(LOAD0_CR3); break;
5709 case 0x20: working.write(LOAD0_CR4); break;
5710 default: throw new IllegalStateException("Unknown Control Register Operand");
5714 private void store0_Dd(int modrm)
5716 switch(modrm & 0x38) {
5717 case 0x00: working.write(STORE0_DR0); break;
5718 case 0x08: working.write(STORE0_DR1); break;
5719 case 0x10: working.write(STORE0_DR2); break;
5720 case 0x18: working.write(STORE0_DR3); break;
5721 case 0x30: working.write(STORE0_DR6); break;
5722 case 0x38: working.write(STORE0_DR7); break;
5723 default: throw new IllegalStateException("Unknown Debug Register Operand");
5727 private void load0_Dd(int modrm)
5729 switch(modrm & 0x38) {
5730 case 0x00: working.write(LOAD0_DR0); break;
5731 case 0x08: working.write(LOAD0_DR1); break;
5732 case 0x10: working.write(LOAD0_DR2); break;
5733 case 0x18: working.write(LOAD0_DR3); break;
5734 case 0x30: working.write(LOAD0_DR6); break;
5735 case 0x38: working.write(LOAD0_DR7); break;
5736 default: throw new IllegalStateException("Unknown Debug Register Operand");
5740 private void load0_Eb(int prefices, int modrm, int sib, int displacement)
5742 switch(modrm & 0xc7) {
5743 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_BYTE); break;
5745 case 0xc0: working.write(LOAD0_AL); break;
5746 case 0xc1: working.write(LOAD0_CL); break;
5747 case 0xc2: working.write(LOAD0_DL); break;
5748 case 0xc3: working.write(LOAD0_BL); break;
5749 case 0xc4: working.write(LOAD0_AH); break;
5750 case 0xc5: working.write(LOAD0_CH); break;
5751 case 0xc6: working.write(LOAD0_DH); break;
5752 case 0xc7: working.write(LOAD0_BH); break;
5755 private void load1_Eb(int prefices, int modrm, int sib, int displacement)
5757 switch(modrm & 0xc7) {
5758 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD1_MEM_BYTE); break;
5760 case 0xc0: working.write(LOAD1_AL); break;
5761 case 0xc1: working.write(LOAD1_CL); break;
5762 case 0xc2: working.write(LOAD1_DL); break;
5763 case 0xc3: working.write(LOAD1_BL); break;
5764 case 0xc4: working.write(LOAD1_AH); break;
5765 case 0xc5: working.write(LOAD1_CH); break;
5766 case 0xc6: working.write(LOAD1_DH); break;
5767 case 0xc7: working.write(LOAD1_BH); break;
5770 private void store0_Eb(int prefices, int modrm, int sib, int displacement)
5772 switch(modrm & 0xc7) {
5773 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_BYTE); break;
5775 case 0xc0: working.write(STORE0_AL); break;
5776 case 0xc1: working.write(STORE0_CL); break;
5777 case 0xc2: working.write(STORE0_DL); break;
5778 case 0xc3: working.write(STORE0_BL); break;
5779 case 0xc4: working.write(STORE0_AH); break;
5780 case 0xc5: working.write(STORE0_CH); break;
5781 case 0xc6: working.write(STORE0_DH); break;
5782 case 0xc7: working.write(STORE0_BH); break;
5785 private void store1_Eb(int prefices, int modrm, int sib, int displacement)
5787 switch(modrm & 0xc7) {
5788 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE1_MEM_BYTE); break;
5790 case 0xc0: working.write(STORE1_AL); break;
5791 case 0xc1: working.write(STORE1_CL); break;
5792 case 0xc2: working.write(STORE1_DL); break;
5793 case 0xc3: working.write(STORE1_BL); break;
5794 case 0xc4: working.write(STORE1_AH); break;
5795 case 0xc5: working.write(STORE1_CH); break;
5796 case 0xc6: working.write(STORE1_DH); break;
5797 case 0xc7: working.write(STORE1_BH); break;
5801 private void load0_Ew(int prefices, int modrm, int sib, int displacement)
5803 switch (modrm & 0xc7) {
5804 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_WORD); break;
5806 case 0xc0: working.write(LOAD0_AX); break;
5807 case 0xc1: working.write(LOAD0_CX); break;
5808 case 0xc2: working.write(LOAD0_DX); break;
5809 case 0xc3: working.write(LOAD0_BX); break;
5810 case 0xc4: working.write(LOAD0_SP); break;
5811 case 0xc5: working.write(LOAD0_BP); break;
5812 case 0xc6: working.write(LOAD0_SI); break;
5813 case 0xc7: working.write(LOAD0_DI); break;
5816 private void store0_Ew(int prefices, int modrm, int sib, int displacement)
5818 switch (modrm & 0xc7) {
5819 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_WORD); break;
5821 case 0xc0: working.write(STORE0_AX); break;
5822 case 0xc1: working.write(STORE0_CX); break;
5823 case 0xc2: working.write(STORE0_DX); break;
5824 case 0xc3: working.write(STORE0_BX); break;
5825 case 0xc4: working.write(STORE0_SP); break;
5826 case 0xc5: working.write(STORE0_BP); break;
5827 case 0xc6: working.write(STORE0_SI); break;
5828 case 0xc7: working.write(STORE0_DI); break;
5831 private void load1_Ew(int prefices, int modrm, int sib, int displacement)
5833 switch (modrm & 0xc7) {
5834 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD1_MEM_WORD); break;
5836 case 0xc0: working.write(LOAD1_AX); break;
5837 case 0xc1: working.write(LOAD1_CX); break;
5838 case 0xc2: working.write(LOAD1_DX); break;
5839 case 0xc3: working.write(LOAD1_BX); break;
5840 case 0xc4: working.write(LOAD1_SP); break;
5841 case 0xc5: working.write(LOAD1_BP); break;
5842 case 0xc6: working.write(LOAD1_SI); break;
5843 case 0xc7: working.write(LOAD1_DI); break;
5846 private void store1_Ew(int prefices, int modrm, int sib, int displacement)
5848 switch (modrm & 0xc7) {
5849 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE1_MEM_WORD); break;
5851 case 0xc0: working.write(STORE1_AX); break;
5852 case 0xc1: working.write(STORE1_CX); break;
5853 case 0xc2: working.write(STORE1_DX); break;
5854 case 0xc3: working.write(STORE1_BX); break;
5855 case 0xc4: working.write(STORE1_SP); break;
5856 case 0xc5: working.write(STORE1_BP); break;
5857 case 0xc6: working.write(STORE1_SI); break;
5858 case 0xc7: working.write(STORE1_DI); break;
5862 private void load0_Ed(int prefices, int modrm, int sib, int displacement)
5864 switch (modrm & 0xc7) {
5865 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_DWORD); break;
5867 case 0xc0: working.write(LOAD0_EAX); break;
5868 case 0xc1: working.write(LOAD0_ECX); break;
5869 case 0xc2: working.write(LOAD0_EDX); break;
5870 case 0xc3: working.write(LOAD0_EBX); break;
5871 case 0xc4: working.write(LOAD0_ESP); break;
5872 case 0xc5: working.write(LOAD0_EBP); break;
5873 case 0xc6: working.write(LOAD0_ESI); break;
5874 case 0xc7: working.write(LOAD0_EDI); break;
5878 private void store0_Ed(int prefices, int modrm, int sib, int displacement)
5880 switch (modrm & 0xc7) {
5881 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_DWORD); break;
5883 case 0xc0: working.write(STORE0_EAX); break;
5884 case 0xc1: working.write(STORE0_ECX); break;
5885 case 0xc2: working.write(STORE0_EDX); break;
5886 case 0xc3: working.write(STORE0_EBX); break;
5887 case 0xc4: working.write(STORE0_ESP); break;
5888 case 0xc5: working.write(STORE0_EBP); break;
5889 case 0xc6: working.write(STORE0_ESI); break;
5890 case 0xc7: working.write(STORE0_EDI); break;
5893 private void load1_Ed(int prefices, int modrm, int sib, int displacement)
5895 switch (modrm & 0xc7) {
5896 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD1_MEM_DWORD); break;
5898 case 0xc0: working.write(LOAD1_EAX); break;
5899 case 0xc1: working.write(LOAD1_ECX); break;
5900 case 0xc2: working.write(LOAD1_EDX); break;
5901 case 0xc3: working.write(LOAD1_EBX); break;
5902 case 0xc4: working.write(LOAD1_ESP); break;
5903 case 0xc5: working.write(LOAD1_EBP); break;
5904 case 0xc6: working.write(LOAD1_ESI); break;
5905 case 0xc7: working.write(LOAD1_EDI); break;
5909 private void store1_Ed(int prefices, int modrm, int sib, int displacement)
5911 switch (modrm & 0xc7) {
5912 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE1_MEM_DWORD); break;
5914 case 0xc0: working.write(STORE1_EAX); break;
5915 case 0xc1: working.write(STORE1_ECX); break;
5916 case 0xc2: working.write(STORE1_EDX); break;
5917 case 0xc3: working.write(STORE1_EBX); break;
5918 case 0xc4: working.write(STORE1_ESP); break;
5919 case 0xc5: working.write(STORE1_EBP); break;
5920 case 0xc6: working.write(STORE1_ESI); break;
5921 case 0xc7: working.write(STORE1_EDI); break;
5925 private void load0_Eq(int prefices, int modrm, int sib, int displacement)
5927 switch (modrm & 0xc7) {
5928 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_QWORD); break;
5930 case 0xc1:
5931 case 0xc2:
5932 case 0xc3:
5933 case 0xc4:
5934 case 0xc5:
5935 case 0xc6:
5936 case 0xc7:
5937 throw new IllegalStateException("There are no 64bit GP Registers");
5941 private void load0_Gb(int modrm)
5943 switch(modrm & 0x38) {
5944 case 0x00: working.write(LOAD0_AL); break;
5945 case 0x08: working.write(LOAD0_CL); break;
5946 case 0x10: working.write(LOAD0_DL); break;
5947 case 0x18: working.write(LOAD0_BL); break;
5948 case 0x20: working.write(LOAD0_AH); break;
5949 case 0x28: working.write(LOAD0_CH); break;
5950 case 0x30: working.write(LOAD0_DH); break;
5951 case 0x38: working.write(LOAD0_BH); break;
5952 default: throw new IllegalStateException("Unknown Byte Register Operand");
5955 private void store0_Gb(int modrm)
5957 switch(modrm & 0x38) {
5958 case 0x00: working.write(STORE0_AL); break;
5959 case 0x08: working.write(STORE0_CL); break;
5960 case 0x10: working.write(STORE0_DL); break;
5961 case 0x18: working.write(STORE0_BL); break;
5962 case 0x20: working.write(STORE0_AH); break;
5963 case 0x28: working.write(STORE0_CH); break;
5964 case 0x30: working.write(STORE0_DH); break;
5965 case 0x38: working.write(STORE0_BH); break;
5966 default: throw new IllegalStateException("Unknown Byte Register Operand");
5969 private void load1_Gb(int modrm)
5971 switch(modrm & 0x38) {
5972 case 0x00: working.write(LOAD1_AL); break;
5973 case 0x08: working.write(LOAD1_CL); break;
5974 case 0x10: working.write(LOAD1_DL); break;
5975 case 0x18: working.write(LOAD1_BL); break;
5976 case 0x20: working.write(LOAD1_AH); break;
5977 case 0x28: working.write(LOAD1_CH); break;
5978 case 0x30: working.write(LOAD1_DH); break;
5979 case 0x38: working.write(LOAD1_BH); break;
5980 default: throw new IllegalStateException("Unknown Byte Register Operand");
5983 private void store1_Gb(int modrm)
5985 switch(modrm & 0x38) {
5986 case 0x00: working.write(STORE1_AL); break;
5987 case 0x08: working.write(STORE1_CL); break;
5988 case 0x10: working.write(STORE1_DL); break;
5989 case 0x18: working.write(STORE1_BL); break;
5990 case 0x20: working.write(STORE1_AH); break;
5991 case 0x28: working.write(STORE1_CH); break;
5992 case 0x30: working.write(STORE1_DH); break;
5993 case 0x38: working.write(STORE1_BH); break;
5994 default: throw new IllegalStateException("Unknown Byte Register Operand");
5998 private void load0_Gw(int modrm)
6000 switch(modrm & 0x38) {
6001 case 0x00: working.write(LOAD0_AX); break;
6002 case 0x08: working.write(LOAD0_CX); break;
6003 case 0x10: working.write(LOAD0_DX); break;
6004 case 0x18: working.write(LOAD0_BX); break;
6005 case 0x20: working.write(LOAD0_SP); break;
6006 case 0x28: working.write(LOAD0_BP); break;
6007 case 0x30: working.write(LOAD0_SI); break;
6008 case 0x38: working.write(LOAD0_DI); break;
6009 default: throw new IllegalStateException("Unknown Word Register Operand");
6012 private void store0_Gw(int modrm)
6014 switch(modrm & 0x38) {
6015 case 0x00: working.write(STORE0_AX); break;
6016 case 0x08: working.write(STORE0_CX); break;
6017 case 0x10: working.write(STORE0_DX); break;
6018 case 0x18: working.write(STORE0_BX); break;
6019 case 0x20: working.write(STORE0_SP); break;
6020 case 0x28: working.write(STORE0_BP); break;
6021 case 0x30: working.write(STORE0_SI); break;
6022 case 0x38: working.write(STORE0_DI); break;
6023 default: throw new IllegalStateException("Unknown Word Register Operand");
6026 private void load1_Gw(int modrm)
6028 switch(modrm & 0x38) {
6029 case 0x00: working.write(LOAD1_AX); break;
6030 case 0x08: working.write(LOAD1_CX); break;
6031 case 0x10: working.write(LOAD1_DX); break;
6032 case 0x18: working.write(LOAD1_BX); break;
6033 case 0x20: working.write(LOAD1_SP); break;
6034 case 0x28: working.write(LOAD1_BP); break;
6035 case 0x30: working.write(LOAD1_SI); break;
6036 case 0x38: working.write(LOAD1_DI); break;
6037 default: throw new IllegalStateException("Unknown Word Register Operand");
6040 private void store1_Gw(int modrm)
6042 switch(modrm & 0x38) {
6043 case 0x00: working.write(STORE1_AX); break;
6044 case 0x08: working.write(STORE1_CX); break;
6045 case 0x10: working.write(STORE1_DX); break;
6046 case 0x18: working.write(STORE1_BX); break;
6047 case 0x20: working.write(STORE1_SP); break;
6048 case 0x28: working.write(STORE1_BP); break;
6049 case 0x30: working.write(STORE1_SI); break;
6050 case 0x38: working.write(STORE1_DI); break;
6051 default: throw new IllegalStateException("Unknown Word Register Operand");
6055 private void load0_Gd(int modrm)
6057 switch(modrm & 0x38) {
6058 case 0x00: working.write(LOAD0_EAX); break;
6059 case 0x08: working.write(LOAD0_ECX); break;
6060 case 0x10: working.write(LOAD0_EDX); break;
6061 case 0x18: working.write(LOAD0_EBX); break;
6062 case 0x20: working.write(LOAD0_ESP); break;
6063 case 0x28: working.write(LOAD0_EBP); break;
6064 case 0x30: working.write(LOAD0_ESI); break;
6065 case 0x38: working.write(LOAD0_EDI); break;
6066 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6069 private void store0_Gd(int modrm)
6071 switch(modrm & 0x38) {
6072 case 0x00: working.write(STORE0_EAX); break;
6073 case 0x08: working.write(STORE0_ECX); break;
6074 case 0x10: working.write(STORE0_EDX); break;
6075 case 0x18: working.write(STORE0_EBX); break;
6076 case 0x20: working.write(STORE0_ESP); break;
6077 case 0x28: working.write(STORE0_EBP); break;
6078 case 0x30: working.write(STORE0_ESI); break;
6079 case 0x38: working.write(STORE0_EDI); break;
6080 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6083 private void load1_Gd(int modrm)
6085 switch(modrm & 0x38) {
6086 case 0x00: working.write(LOAD1_EAX); break;
6087 case 0x08: working.write(LOAD1_ECX); break;
6088 case 0x10: working.write(LOAD1_EDX); break;
6089 case 0x18: working.write(LOAD1_EBX); break;
6090 case 0x20: working.write(LOAD1_ESP); break;
6091 case 0x28: working.write(LOAD1_EBP); break;
6092 case 0x30: working.write(LOAD1_ESI); break;
6093 case 0x38: working.write(LOAD1_EDI); break;
6094 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6097 private void store1_Gd(int modrm)
6099 switch(modrm & 0x38) {
6100 case 0x00: working.write(STORE1_EAX); break;
6101 case 0x08: working.write(STORE1_ECX); break;
6102 case 0x10: working.write(STORE1_EDX); break;
6103 case 0x18: working.write(STORE1_EBX); break;
6104 case 0x20: working.write(STORE1_ESP); break;
6105 case 0x28: working.write(STORE1_EBP); break;
6106 case 0x30: working.write(STORE1_ESI); break;
6107 case 0x38: working.write(STORE1_EDI); break;
6108 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6112 private void load0_Sw(int modrm)
6114 switch(modrm & 0x38) {
6115 case 0x00: working.write(LOAD0_ES); break;
6116 case 0x08: working.write(LOAD0_CS); break;
6117 case 0x10: working.write(LOAD0_SS); break;
6118 case 0x18: working.write(LOAD0_DS); break;
6119 case 0x20: working.write(LOAD0_FS); break;
6120 case 0x28: working.write(LOAD0_GS); break;
6121 default: throw new IllegalStateException("Unknown Segment Register Operand");
6124 private void store0_Sw(int modrm)
6126 switch(modrm & 0x38) {
6127 case 0x00: working.write(STORE0_ES); break;
6128 case 0x08: working.write(STORE0_CS); break;
6129 case 0x10: working.write(STORE0_SS); break;
6130 case 0x18: working.write(STORE0_DS); break;
6131 case 0x20: working.write(STORE0_FS); break;
6132 case 0x28: working.write(STORE0_GS); break;
6133 default: throw new IllegalStateException("Unknown Segment Register Operand");
6137 private void decodeO(int prefices, int displacement)
6139 switch (prefices & PREFICES_SG) {
6140 default:
6141 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6142 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6143 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6144 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6145 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6146 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6149 if ((prefices & PREFICES_ADDRESS) != 0) {
6150 if (decodingAddressMode())
6151 working.write(ADDR_ID); working.write(displacement);
6152 } else {
6153 if (decodingAddressMode()) {
6154 working.write(ADDR_IW); working.write(displacement);
6155 working.write(ADDR_MASK16);
6160 private void load0_Ob(int prefices, int displacement)
6162 decodeO(prefices, displacement);
6163 working.write(LOAD0_MEM_BYTE);
6165 private void store0_Ob(int prefices, int displacement)
6167 decodeO(prefices, displacement);
6168 working.write(STORE0_MEM_BYTE);
6171 private void load0_Ow(int prefices, int displacement)
6173 decodeO(prefices, displacement);
6174 working.write(LOAD0_MEM_WORD);
6176 private void store0_Ow(int prefices, int displacement)
6178 decodeO(prefices, displacement);
6179 working.write(STORE0_MEM_WORD);
6182 private void load0_Od(int prefices, int displacement)
6184 decodeO(prefices, displacement);
6185 working.write(LOAD0_MEM_DWORD);
6187 private void store0_Od(int prefices, int displacement)
6189 decodeO(prefices, displacement);
6190 working.write(STORE0_MEM_DWORD);
6193 private void load0_M(int prefices, int modrm, int sib, int displacement)
6195 decodeM(prefices, modrm, sib, displacement);
6196 working.write(LOAD0_ADDR);
6199 private void decodeM(int prefices, int modrm, int sib, int displacement)
6201 if (!decodingAddressMode()) return;
6203 if ((prefices & PREFICES_ADDRESS) != 0) {
6204 //32 bit address size
6206 //Segment load
6207 switch (prefices & PREFICES_SG) {
6208 default:
6209 switch (modrm & 0xc7) {
6210 default: working.write(LOAD_SEG_DS); break;
6211 case 0x04:
6212 case 0x44:
6213 case 0x84: break; //segment working.write will occur in decodeSIB
6214 case 0x45:
6215 case 0x85: working.write(LOAD_SEG_SS); break;
6217 break;
6218 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6219 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6220 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6221 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6222 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6223 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6226 //Address Load
6227 switch(modrm & 0x7) {
6228 case 0x0: working.write(ADDR_EAX); break;
6229 case 0x1: working.write(ADDR_ECX); break;
6230 case 0x2: working.write(ADDR_EDX); break;
6231 case 0x3: working.write(ADDR_EBX); break;
6232 case 0x4: decodeSIB(prefices, modrm, sib, displacement); break;
6233 case 0x5:
6234 if((modrm & 0xc0) == 0x00) {
6235 working.write(ADDR_ID);
6236 working.write(displacement);
6237 } else
6238 working.write(ADDR_EBP);
6239 break;
6240 case 0x6: working.write(ADDR_ESI); break;
6241 case 0x7: working.write(ADDR_EDI); break;
6244 switch(modrm & 0xc0) {
6245 case 0x40: working.write(ADDR_IB); working.write(displacement); break;
6246 case 0x80: working.write(ADDR_ID); working.write(displacement); break;
6248 } else {
6249 //16 bit address size
6250 //Segment load
6251 switch (prefices & PREFICES_SG) {
6252 default:
6253 switch (modrm & 0xc7) {
6254 default: working.write(LOAD_SEG_DS); break;
6255 case 0x02:
6256 case 0x03:
6257 case 0x42:
6258 case 0x43:
6259 case 0x46:
6260 case 0x82:
6261 case 0x83:
6262 case 0x86: working.write(LOAD_SEG_SS); break;
6264 break;
6265 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6266 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6267 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6268 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6269 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6270 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6273 switch (modrm & 0x7) {
6274 case 0x0: working.write(ADDR_BX); working.write(ADDR_SI); break;
6275 case 0x1: working.write(ADDR_BX); working.write(ADDR_DI); break;
6276 case 0x2: working.write(ADDR_BP); working.write(ADDR_SI); break;
6277 case 0x3: working.write(ADDR_BP); working.write(ADDR_DI); break;
6278 case 0x4: working.write(ADDR_SI); break;
6279 case 0x5: working.write(ADDR_DI); break;
6280 case 0x6:
6281 if ((modrm & 0xc0) == 0x00) {
6282 working.write(ADDR_IW);
6283 working.write(displacement);
6284 } else {
6285 working.write(ADDR_BP);
6287 break;
6288 case 0x7: working.write(ADDR_BX); break;
6291 switch (modrm & 0xc0) {
6292 case 0x40: working.write(ADDR_IB); working.write(displacement); break;
6293 case 0x80: working.write(ADDR_IW); working.write(displacement); break;
6295 working.write(ADDR_MASK16);
6299 private void decodeSIB(int prefices, int modrm, int sib, int displacement)
6301 switch (prefices & PREFICES_SG) {
6302 default:
6303 switch (sib & 0x7) {
6304 default: working.write(LOAD_SEG_DS); break;
6305 case 0x4: working.write(LOAD_SEG_SS); break;
6306 case 0x5:
6307 switch (modrm & 0xc0) {
6308 default: working.write(LOAD_SEG_SS); break;
6309 case 0x00: working.write(LOAD_SEG_DS); break;
6310 } break;
6311 } break;
6312 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6313 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6314 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6315 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6316 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6317 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6320 // base register
6321 switch (sib & 0x7) {
6322 case 0x0: working.write(ADDR_EAX); break;
6323 case 0x1: working.write(ADDR_ECX); break;
6324 case 0x2: working.write(ADDR_EDX); break;
6325 case 0x3: working.write(ADDR_EBX); break;
6326 case 0x4: working.write(ADDR_ESP); break;
6327 case 0x5:
6328 switch (modrm & 0xc0) {
6329 default: working.write(ADDR_EBP); break;
6330 case 0x00: working.write(ADDR_ID); working.write(displacement); break;
6331 } break;
6332 case 0x6: working.write(ADDR_ESI); break;
6333 case 0x7: working.write(ADDR_EDI); break;
6336 // index register
6337 switch (sib & 0xf8) {
6338 case 0x00: working.write(ADDR_EAX); break;
6339 case 0x08: working.write(ADDR_ECX); break;
6340 case 0x10: working.write(ADDR_EDX); break;
6341 case 0x18: working.write(ADDR_EBX); break;
6342 case 0x20: break; //none
6343 case 0x28: working.write(ADDR_EBP); break;
6344 case 0x30: working.write(ADDR_ESI); break;
6345 case 0x38: working.write(ADDR_EDI); break;
6347 case 0x40: working.write(ADDR_2EAX); break;
6348 case 0x48: working.write(ADDR_2ECX); break;
6349 case 0x50: working.write(ADDR_2EDX); break;
6350 case 0x58: working.write(ADDR_2EBX); break;
6351 case 0x60: break; //none
6352 case 0x68: working.write(ADDR_2EBP); break;
6353 case 0x70: working.write(ADDR_2ESI); break;
6354 case 0x78: working.write(ADDR_2EDI); break;
6356 case 0x80: working.write(ADDR_4EAX); break;
6357 case 0x88: working.write(ADDR_4ECX); break;
6358 case 0x90: working.write(ADDR_4EDX); break;
6359 case 0x98: working.write(ADDR_4EBX); break;
6360 case 0xa0: break; //none
6361 case 0xa8: working.write(ADDR_4EBP); break;
6362 case 0xb0: working.write(ADDR_4ESI); break;
6363 case 0xb8: working.write(ADDR_4EDI); break;
6365 case 0xc0: working.write(ADDR_8EAX); break;
6366 case 0xc8: working.write(ADDR_8ECX); break;
6367 case 0xd0: working.write(ADDR_8EDX); break;
6368 case 0xd8: working.write(ADDR_8EBX); break;
6369 case 0xe0: break; //none
6370 case 0xe8: working.write(ADDR_8EBP); break;
6371 case 0xf0: working.write(ADDR_8ESI); break;
6372 case 0xf8: working.write(ADDR_8EDI); break;
6376 private void decodeSegmentPrefix(int prefices)
6378 switch (prefices & PREFICES_SG) {
6379 default:
6380 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6381 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6382 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6383 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6384 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6385 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6389 private void store0_Rd(int modrm)
6391 switch (modrm & 0xc7) {
6392 case 0xc0: working.write(STORE0_EAX); break;
6393 case 0xc1: working.write(STORE0_ECX); break;
6394 case 0xc2: working.write(STORE0_EDX); break;
6395 case 0xc3: working.write(STORE0_EBX); break;
6396 case 0xc4: working.write(STORE0_ESP); break;
6397 case 0xc5: working.write(STORE0_EBP); break;
6398 case 0xc6: working.write(STORE0_ESI); break;
6399 case 0xc7: working.write(STORE0_EDI); break;
6400 default: throw new IllegalStateException("Rd cannot be a memory location");
6404 private void load0_Rd(int modrm)
6406 switch (modrm & 0xc7) {
6407 case 0xc0: working.write(LOAD0_EAX); break;
6408 case 0xc1: working.write(LOAD0_ECX); break;
6409 case 0xc2: working.write(LOAD0_EDX); break;
6410 case 0xc3: working.write(LOAD0_EBX); break;
6411 case 0xc4: working.write(LOAD0_ESP); break;
6412 case 0xc5: working.write(LOAD0_EBP); break;
6413 case 0xc6: working.write(LOAD0_ESI); break;
6414 case 0xc7: working.write(LOAD0_EDI); break;
6415 default: throw new IllegalStateException("Rd cannot be a memory location");
6419 private static class Operation
6421 private int[] microcodes;
6422 private int microcodesLength;
6423 private int x86Length;
6424 private int readOffset;
6425 private boolean decoded;
6426 private boolean terminal;
6428 Operation()
6430 microcodes = new int[10];
6433 void write(int microcode)
6435 try {
6436 microcodes[microcodesLength] = microcode;
6437 microcodesLength++;
6438 } catch (ArrayIndexOutOfBoundsException e) {
6439 int[] temp = new int[2*microcodes.length];
6440 System.arraycopy(microcodes, 0, temp, 0, microcodes.length);
6441 microcodes = temp;
6442 microcodes[microcodesLength++] = microcode;
6446 void replace(int offset, int microcode)
6448 microcodes[offset] = microcode;
6451 void finish(int x86Length)
6453 this.x86Length = x86Length;
6454 decoded = true;
6457 void makeTerminal()
6459 reset();
6460 terminal = true;
6463 boolean terminal()
6465 return terminal;
6468 boolean decoded()
6470 return decoded;
6473 void reset()
6475 microcodesLength = 0;
6476 x86Length = 0;
6477 readOffset = 0;
6478 decoded = false;
6479 terminal = false;
6482 int getMicrocodeAt(int offset)
6484 return microcodes[offset];
6487 int getMicrocode()
6489 if (readOffset < microcodesLength)
6490 return microcodes[readOffset++];
6491 else {
6492 System.err.println("Critical error: Attempted read outside microcode array.");
6493 throw new IllegalStateException("Attempted read outside microcode array");
6497 int getLength()
6499 return microcodesLength;
6502 int getX86Length()
6504 return x86Length;