2 JPC-RR: A x86 PC Hardware Emulator
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
.*;
38 * @author Chris Dennis
40 public final class RealModeUDecoder
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
;
156 private int decodeLimit
;
158 public RealModeUDecoder()
160 this.current
= new Operation();
161 this.waiting
= new Operation();
162 this.working
= new Operation();
165 public InstructionSource
decodeReal(ByteSource source
, int limit
)
168 this.source
= source
;
173 public InstructionSource
decodeVirtual8086(ByteSource source
, int limit
)
176 this.source
= source
;
181 public InstructionSource
decodeProtected(ByteSource source
, boolean operandSize
, int limit
)
186 private void blockFinished()
188 blockComplete
= true;
191 private void rotate()
193 Operation temp
= current
;
199 public boolean getNext()
201 decode(); //will put new block in working
202 rotate(); //moves buffer around
203 if (current
.decoded())
205 else if (current
.terminal()) {
217 blockComplete
= false;
220 public int getMicrocode()
222 return current
.getMicrocode();
225 public int getLength()
227 return current
.getLength();
230 public int getX86Length()
232 return current
.getX86Length();
235 private boolean decodingAddressMode()
237 if (addressModeDecoded
) {
240 return (addressModeDecoded
= true);
244 private void decodeComplete(int position
)
246 if (addressModeDecoded
) {
247 working
.write(MEM_RESET
);
248 addressModeDecoded
= false;
250 working
.finish(position
);
253 private void decode()
258 working
.makeTerminal();
264 length
= decodeOpcode();
266 } catch (IllegalStateException e
) {
267 if (!waiting
.decoded()) {
268 System
.err
.println("Critical error: Instruction decoding error: " + e
);
271 waiting
.write(EIP_UPDATE
);
272 working
.makeTerminal();
278 decodeComplete(-length
);
280 } else if (decodeLimit
<= 0) {
281 decodeComplete(length
);
282 working
.write(EIP_UPDATE
);
285 decodeComplete(length
);
289 private int decodeOpcode()
292 int opcodePrefix
= 0;
300 switch (opcode
= 0xff & source
.getByte()) {
302 opcodePrefix
= (opcodePrefix
<< 8) | opcode
;
303 opcode
= 0xff & source
.getByte();
315 opcodePrefix
= (opcodePrefix
<< 8) | opcode
;
317 modrm
= 0xff & source
.getByte();
322 prefices
&= ~PREFICES_SG
;
323 prefices
|= PREFICES_CS
;
326 prefices
&= ~PREFICES_SG
;
327 prefices
|= PREFICES_DS
;
330 prefices
&= ~PREFICES_SG
;
331 prefices
|= PREFICES_ES
;
334 prefices
&= ~PREFICES_SG
;
335 prefices
|= PREFICES_SS
;
338 prefices
&= ~PREFICES_SG
;
339 prefices
|= PREFICES_FS
;
342 prefices
&= ~PREFICES_SG
;
343 prefices
|= PREFICES_GS
;
346 if ((prefices
& PREFICES_OPERAND
) != 0)
347 System
.err
.println("Warning: repeated operand override prefix 0x66 in real mode");
348 //prefices = prefices ^ PREFICES_OPERAND;
349 prefices
|= PREFICES_OPERAND
;
352 prefices
|= PREFICES_ADDRESS
;
355 prefices
|= PREFICES_REPNE
;
358 prefices
|= PREFICES_REPE
;
361 prefices
|= PREFICES_LOCK
;
369 opcode
= (opcodePrefix
<< 8) | opcode
;
371 switch (opcodePrefix
) {
373 if (modrmArray
[opcode
]) {
374 modrm
= 0xff & source
.getByte();
379 if ((modrm
== -1) || ((prefices
& PREFICES_ADDRESS
) == 0)) {
382 if (sibArray
[modrm
]) {
383 sib
= 0xff & source
.getByte();
391 if (twoByte_0f_modrmArray
[0xff & opcode
]) {
392 modrm
= 0xff & source
.getByte();
397 if ((modrm
== -1) || ((prefices
& PREFICES_ADDRESS
) == 0)) {
400 if (twoByte_0f_sibArray
[modrm
]) {
401 sib
= 0xff & source
.getByte();
416 if (sibArray
[modrm
]) {
417 sib
= 0xff & source
.getByte();
429 working
.write(INSTRUCTION_START
);
431 if (isJump(opcode
, modrm
))
432 working
.write(EIP_UPDATE
);
434 int displacement
= 0;
436 switch (operationHasDisplacement(prefices
, opcode
, modrm
, sib
)) {
440 displacement
= source
.getByte();
444 displacement
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00);
448 displacement
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00) | ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000);
452 System
.err
.println("Error: " + Integer
.valueOf(operationHasDisplacement(prefices
, opcode
, modrm
, sib
)) +
453 " byte displacement Invalid.");
459 switch (operationHasImmediate(prefices
, opcode
, modrm
)) {
463 immediate
= source
.getByte();
467 immediate
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00);
471 immediate
= ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000) | (source
.getByte() & 0xff);
475 immediate
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00) | ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000);
479 immediate
= 0xffffffffl
& ((source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00) | ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000));
480 immediate
|= ((source
.getByte() & 0xffl
) | ((source
.getByte() << 8) & 0xff00l
)) << 32;
484 System
.err
.println("Error: " + Integer
.valueOf(operationHasImmediate(prefices
, opcode
, modrm
)) +
485 " byte immediate invalid.");
489 //write out input operands
490 writeInputOperands(prefices
, opcode
, modrm
, sib
, displacement
, immediate
);
492 //write out calculation
493 writeOperation(prefices
, opcode
, modrm
);
495 //write out output operands
496 writeOutputOperands(prefices
, opcode
, modrm
, sib
, displacement
);
499 writeFlags(prefices
, opcode
, modrm
);
501 if (isJump(opcode
, modrm
))
507 private void writeOperation(int prefices
, int opcode
, int modrm
)
510 case 0x00: //ADD Eb, Gb
511 case 0x01: //ADD Ev, Gv
512 case 0x02: //ADD Gb, Eb
513 case 0x03: //ADD Gv, Ev
514 case 0x04: //ADD AL, Ib
515 case 0x05: //ADD eAX, Iv
516 case 0xfc0: //XADD Eb, Gb
517 case 0xfc1: working
.write(ADD
); break; //XADD Ev, Gv
519 case 0x08: //OR Eb, Gb
520 case 0x09: //OR Ev, Gv
521 case 0x0a: //OR Gb, Eb
522 case 0x0b: //OR Gv, Ev
523 case 0x0c: //OR AL, Ib
524 case 0x0d: working
.write(OR
); break; //OR eAX, Iv
526 case 0x10: //ADC Eb, Gb
527 case 0x11: //ADC Ev, Gv
528 case 0x12: //ADC Gb, Eb
529 case 0x13: //ADC Gv, Ev
530 case 0x14: //ADC AL, Ib
531 case 0x15: working
.write(ADC
); break; //ADC eAX, Iv
533 case 0x18: //SBB Eb, Gb
534 case 0x19: //SBB Ev, Gv
535 case 0x1a: //SBB Gb, Eb
536 case 0x1b: //SBB Gv, Ev
537 case 0x1c: //SBB AL, Ib
538 case 0x1d: working
.write(SBB
); break; //SBB eAX, Iv
540 case 0x20: //AND Eb, Gb
541 case 0x21: //AND Ev, Gv
542 case 0x22: //AND Gb, Eb
543 case 0x23: //AND Gv, Ev
544 case 0x24: //AND AL, Ib
545 case 0x25: //AND eAX, Iv
546 case 0x84: //TEST Eb, Gb
547 case 0x85: //TEST Ev, Gv
548 case 0xa8: //TEST AL, Ib
549 case 0xa9: working
.write(AND
); break; //TEST eAX, Iv
551 case 0x27: working
.write(DAA
); break; //DAA
553 case 0x28: //SUB Eb, Gb
554 case 0x29: //SUB Ev, Gv
555 case 0x2a: //SUB Gb, Eb
556 case 0x2b: //SUB Gv, Ev
557 case 0x2c: //SUB AL, Ib
558 case 0x2d: //SUB eAX, Iv
559 case 0x38: //CMP Eb, Gb
560 case 0x39: //CMP Ev, Gv
561 case 0x3a: //CMP Gb, Eb
562 case 0x3b: //CMP Gv, Ev
563 case 0x3c: //CMP AL, Ib
564 case 0x3d: working
.write(SUB
); break; //CMP eAX, Iv
566 case 0x2f: working
.write(DAS
); break; //DAS
568 case 0x30: //XOR Eb, Gb
569 case 0x31: //XOR Ev, Gv
570 case 0x32: //XOR Gb, Eb
571 case 0x33: //XOR Gv, Ev
572 case 0x34: //XOR AL, Ib
573 case 0x35: working
.write(XOR
); break; //XOR eAX, Iv
575 case 0x37: working
.write(AAA
); break; //AAA
576 case 0x3f: working
.write(AAS
); break; //AAS
585 case 0x47: working
.write(INC
); break; //INC eDI
594 case 0x4f: working
.write(DEC
); break; //DEC eDI
600 case 0x50: //PUSH eAX
601 case 0x51: //PUSH eCX
602 case 0x52: //PUSH eDX
603 case 0x53: //PUSH eBX
604 case 0x54: //PUSH eSP
605 case 0x55: //PUSH eBP
606 case 0x56: //PUSH eSI
607 case 0x57: //PUSH eDI
610 case 0xfa0: //PUSH FS
611 case 0xfa8: //PUSH GS
612 switch (prefices
& PREFICES_OPERAND
) {
614 working
.write(PUSH_O16
); break;
615 case PREFICES_OPERAND
:
616 working
.write(PUSH_O32
); break;
621 switch (prefices
& PREFICES_OPERAND
) {
623 working
.write(PUSHF_O16
); break;
624 case PREFICES_OPERAND
:
625 working
.write(PUSHF_O32
); break;
643 switch (prefices
& PREFICES_OPERAND
) {
645 working
.write(POP_O16
); break;
646 case PREFICES_OPERAND
:
647 working
.write(POP_O32
); break;
648 case PREFICES_ADDRESS
:
653 switch (prefices
& PREFICES_OPERAND
) {
655 working
.write(POPF_O16
); break;
656 case PREFICES_OPERAND
:
657 working
.write(POPF_O32
); break;
662 switch (prefices
& PREFICES_OPERAND
) {
664 working
.write(PUSHA
); break;
665 case PREFICES_OPERAND
:
666 working
.write(PUSHAD
); break;
671 switch (prefices
& PREFICES_OPERAND
) {
673 working
.write(POPA
); break;
674 case PREFICES_OPERAND
:
675 working
.write(POPAD
); break;
680 if ((prefices
& PREFICES_OPERAND
) != 0)
681 working
.write(BOUND_O32
);
683 working
.write(BOUND_O16
);
686 case 0x69: //IMUL Gv, Ev, Iv
687 case 0x6b: //IMUL Gv, Ev, Ib
688 case 0xfaf: //IMUL Gv, Ev
689 if ((prefices
& PREFICES_OPERAND
) != 0)
690 working
.write(IMUL_O32
);
692 working
.write(IMUL_O16
);
696 if ((prefices
& PREFICES_REP
) != 0) {
697 if ((prefices
& PREFICES_ADDRESS
) != 0)
698 working
.write(REP_INSB_A32
);
700 working
.write(REP_INSB_A16
);
702 if ((prefices
& PREFICES_ADDRESS
) != 0)
703 working
.write(INSB_A32
);
705 working
.write(INSB_A16
);
710 if ((prefices
& PREFICES_OPERAND
) != 0) {
711 if ((prefices
& PREFICES_REP
) != 0) {
712 if ((prefices
& PREFICES_ADDRESS
) != 0)
713 working
.write(REP_INSD_A32
);
715 working
.write(REP_INSD_A16
);
717 if ((prefices
& PREFICES_ADDRESS
) != 0)
718 working
.write(INSD_A32
);
720 working
.write(INSD_A16
);
723 if ((prefices
& PREFICES_REP
) != 0) {
724 if ((prefices
& PREFICES_ADDRESS
) != 0)
725 working
.write(REP_INSW_A32
);
727 working
.write(REP_INSW_A16
);
729 if ((prefices
& PREFICES_ADDRESS
) != 0)
730 working
.write(INSW_A32
);
732 working
.write(INSW_A16
);
738 if ((prefices
& PREFICES_REP
) != 0) {
739 if ((prefices
& PREFICES_ADDRESS
) != 0)
740 working
.write(REP_OUTSB_A32
);
742 working
.write(REP_OUTSB_A16
);
744 if ((prefices
& PREFICES_ADDRESS
) != 0)
745 working
.write(OUTSB_A32
);
747 working
.write(OUTSB_A16
);
751 case 0x6f: //OUTS DX, Xv
752 if ((prefices
& PREFICES_OPERAND
) != 0) {
753 if ((prefices
& PREFICES_REP
) != 0) {
754 if ((prefices
& PREFICES_ADDRESS
) != 0)
755 working
.write(REP_OUTSD_A32
);
757 working
.write(REP_OUTSD_A16
);
759 if ((prefices
& PREFICES_ADDRESS
) != 0)
760 working
.write(OUTSD_A32
);
762 working
.write(OUTSD_A16
);
765 if ((prefices
& PREFICES_REP
) != 0) {
766 if ((prefices
& PREFICES_ADDRESS
) != 0)
767 working
.write(REP_OUTSW_A32
);
769 working
.write(REP_OUTSW_A16
);
771 if ((prefices
& PREFICES_ADDRESS
) != 0)
772 working
.write(OUTSW_A32
);
774 working
.write(OUTSW_A16
);
779 case 0x70: working
.write(JO_O8
); break; //JC Jb
780 case 0x71: working
.write(JNO_O8
); break; //JNC Jb
781 case 0x72: working
.write(JC_O8
); break; //JC Jb
782 case 0x73: working
.write(JNC_O8
); break; //JNC Jb
783 case 0x74: working
.write(JZ_O8
); break; //JZ Jb
784 case 0x75: working
.write(JNZ_O8
); break; //JNZ Jb
785 case 0x76: working
.write(JNA_O8
); break; //JNA Jb
786 case 0x77: working
.write(JA_O8
); break; //JA Jb
787 case 0x78: working
.write(JS_O8
); break; //JS Jb
788 case 0x79: working
.write(JNS_O8
); break; //JNS Jb
789 case 0x7a: working
.write(JP_O8
); break; //JP Jb
790 case 0x7b: working
.write(JNP_O8
); break; //JNP Jb
791 case 0x7c: working
.write(JL_O8
); break; //JL Jb
792 case 0x7d: working
.write(JNL_O8
); break; //JNL Jb
793 case 0x7e: working
.write(JNG_O8
); break; //JNG Jb
794 case 0x7f: working
.write(JG_O8
); break; //JG Jb
796 case 0x80: //IMM GP1 Eb, Ib
797 case 0x81: //IMM GP1 Ev, Iv
798 case 0x82: //IMM GP1 Eb, Ib
799 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
800 switch (modrm
& 0x38) {
802 working
.write(ADD
); break;
804 working
.write(OR
); break;
806 working
.write(ADC
); break;
808 working
.write(SBB
); break;
810 working
.write(AND
); break;
813 working
.write(SUB
); break;
815 working
.write(XOR
); break;
819 case 0x98: //CBW/CWDE
820 if ((prefices
& PREFICES_OPERAND
) != 0) {
821 working
.write(LOAD0_AX
);
822 working
.write(SIGN_EXTEND_16_32
);
823 working
.write(STORE0_EAX
);
825 working
.write(LOAD0_AL
);
826 working
.write(SIGN_EXTEND_8_16
);
827 working
.write(STORE0_AX
);
832 if ((prefices
& PREFICES_OPERAND
) != 0)
839 switch (prefices
& PREFICES_OPERAND
) {
841 working
.write(CALL_FAR_O16
); break;
842 case PREFICES_OPERAND
:
843 working
.write(CALL_FAR_O32
); break;
847 case 0x9b: working
.write(FWAIT
); break; //FWAIT
849 case 0x9e: working
.write(SAHF
); break;
850 case 0x9f: working
.write(LAHF
); break;
853 if ((prefices
& PREFICES_REP
) != 0) {
854 if ((prefices
& PREFICES_ADDRESS
) != 0)
855 working
.write(REP_MOVSB_A32
);
857 working
.write(REP_MOVSB_A16
);
859 if ((prefices
& PREFICES_ADDRESS
) != 0)
860 working
.write(MOVSB_A32
);
862 working
.write(MOVSB_A16
);
867 if ((prefices
& PREFICES_OPERAND
) != 0) {
868 if ((prefices
& PREFICES_REP
) != 0) {
869 if ((prefices
& PREFICES_ADDRESS
) != 0)
870 working
.write(REP_MOVSD_A32
);
872 working
.write(REP_MOVSD_A16
);
874 if ((prefices
& PREFICES_ADDRESS
) != 0)
875 working
.write(MOVSD_A32
);
877 working
.write(MOVSD_A16
);
880 if ((prefices
& PREFICES_REP
) != 0) {
881 if ((prefices
& PREFICES_ADDRESS
) != 0)
882 working
.write(REP_MOVSW_A32
);
884 working
.write(REP_MOVSW_A16
);
886 if ((prefices
& PREFICES_ADDRESS
) != 0)
887 working
.write(MOVSW_A32
);
889 working
.write(MOVSW_A16
);
895 if ((prefices
& PREFICES_REPE
) != 0) {
896 if ((prefices
& PREFICES_ADDRESS
) != 0)
897 working
.write(REPE_CMPSB_A32
);
899 working
.write(REPE_CMPSB_A16
);
900 } else if ((prefices
& PREFICES_REPNE
) != 0) {
901 if ((prefices
& PREFICES_ADDRESS
) != 0)
902 working
.write(REPNE_CMPSB_A32
);
904 working
.write(REPNE_CMPSB_A16
);
906 if ((prefices
& PREFICES_ADDRESS
) != 0)
907 working
.write(CMPSB_A32
);
909 working
.write(CMPSB_A16
);
914 if ((prefices
& PREFICES_OPERAND
) != 0) {
915 if ((prefices
& PREFICES_REPE
) != 0) {
916 if ((prefices
& PREFICES_ADDRESS
) != 0)
917 working
.write(REPE_CMPSD_A32
);
919 working
.write(REPE_CMPSD_A16
);
920 } else if ((prefices
& PREFICES_REPNE
) != 0) {
921 if ((prefices
& PREFICES_ADDRESS
) != 0)
922 working
.write(REPNE_CMPSD_A32
);
924 working
.write(REPNE_CMPSD_A16
);
926 if ((prefices
& PREFICES_ADDRESS
) != 0)
927 working
.write(CMPSD_A32
);
929 working
.write(CMPSD_A16
);
932 if ((prefices
& PREFICES_REPE
) != 0) {
933 if ((prefices
& PREFICES_ADDRESS
) != 0)
934 working
.write(REPE_CMPSW_A32
);
936 working
.write(REPE_CMPSW_A16
);
937 } else if ((prefices
& PREFICES_REPNE
) != 0) {
938 if ((prefices
& PREFICES_ADDRESS
) != 0)
939 working
.write(REPNE_CMPSW_A32
);
941 working
.write(REPNE_CMPSW_A16
);
943 if ((prefices
& PREFICES_ADDRESS
) != 0)
944 working
.write(CMPSW_A32
);
946 working
.write(CMPSW_A16
);
952 if ((prefices
& PREFICES_REP
) != 0) {
953 if ((prefices
& PREFICES_ADDRESS
) != 0)
954 working
.write(REP_STOSB_A32
);
956 working
.write(REP_STOSB_A16
);
958 if ((prefices
& PREFICES_ADDRESS
) != 0)
959 working
.write(STOSB_A32
);
961 working
.write(STOSB_A16
);
965 case 0xab: //STOSW/STOSD
966 if ((prefices
& PREFICES_OPERAND
) != 0) {
967 if ((prefices
& PREFICES_REP
) != 0) {
968 if ((prefices
& PREFICES_ADDRESS
) != 0)
969 working
.write(REP_STOSD_A32
);
971 working
.write(REP_STOSD_A16
);
973 if ((prefices
& PREFICES_ADDRESS
) != 0)
974 working
.write(STOSD_A32
);
976 working
.write(STOSD_A16
);
979 if ((prefices
& PREFICES_REP
) != 0) {
980 if ((prefices
& PREFICES_ADDRESS
) != 0)
981 working
.write(REP_STOSW_A32
);
983 working
.write(REP_STOSW_A16
);
985 if ((prefices
& PREFICES_ADDRESS
) != 0)
986 working
.write(STOSW_A32
);
988 working
.write(STOSW_A16
);
994 if ((prefices
& PREFICES_REP
) != 0) {
995 if ((prefices
& PREFICES_ADDRESS
) != 0)
996 working
.write(REP_LODSB_A32
);
998 working
.write(REP_LODSB_A16
);
1000 if ((prefices
& PREFICES_ADDRESS
) != 0)
1001 working
.write(LODSB_A32
);
1003 working
.write(LODSB_A16
);
1007 case 0xad: //LODSW/LODSD
1008 if ((prefices
& PREFICES_OPERAND
) != 0) {
1009 if ((prefices
& PREFICES_REP
) != 0) {
1010 if ((prefices
& PREFICES_ADDRESS
) != 0)
1011 working
.write(REP_LODSD_A32
);
1013 working
.write(REP_LODSD_A16
);
1015 if ((prefices
& PREFICES_ADDRESS
) != 0)
1016 working
.write(LODSD_A32
);
1018 working
.write(LODSD_A16
);
1021 if ((prefices
& PREFICES_REP
) != 0) {
1022 if ((prefices
& PREFICES_ADDRESS
) != 0)
1023 working
.write(REP_LODSW_A32
);
1025 working
.write(REP_LODSW_A16
);
1027 if ((prefices
& PREFICES_ADDRESS
) != 0)
1028 working
.write(LODSW_A32
);
1030 working
.write(LODSW_A16
);
1036 if ((prefices
& PREFICES_REPE
) != 0) {
1037 if ((prefices
& PREFICES_ADDRESS
) != 0)
1038 working
.write(REPE_SCASB_A32
);
1040 working
.write(REPE_SCASB_A16
);
1041 } else if ((prefices
& PREFICES_REPNE
) != 0) {
1042 if ((prefices
& PREFICES_ADDRESS
) != 0)
1043 working
.write(REPNE_SCASB_A32
);
1045 working
.write(REPNE_SCASB_A16
);
1047 if ((prefices
& PREFICES_ADDRESS
) != 0)
1048 working
.write(SCASB_A32
);
1050 working
.write(SCASB_A16
);
1054 case 0xaf: //SCASW/D
1055 if ((prefices
& PREFICES_OPERAND
) != 0) {
1056 if ((prefices
& PREFICES_REPE
) != 0) {
1057 if ((prefices
& PREFICES_ADDRESS
) != 0)
1058 working
.write(REPE_SCASD_A32
);
1060 working
.write(REPE_SCASD_A16
);
1061 } else if ((prefices
& PREFICES_REPNE
) != 0) {
1062 if ((prefices
& PREFICES_ADDRESS
) != 0)
1063 working
.write(REPNE_SCASD_A32
);
1065 working
.write(REPNE_SCASD_A16
);
1067 if ((prefices
& PREFICES_ADDRESS
) != 0)
1068 working
.write(SCASD_A32
);
1070 working
.write(SCASD_A16
);
1073 if ((prefices
& PREFICES_REPE
) != 0) {
1074 if ((prefices
& PREFICES_ADDRESS
) != 0)
1075 working
.write(REPE_SCASW_A32
);
1077 working
.write(REPE_SCASW_A16
);
1078 } else if ((prefices
& PREFICES_REPNE
) != 0) {
1079 if ((prefices
& PREFICES_ADDRESS
) != 0)
1080 working
.write(REPNE_SCASW_A32
);
1082 working
.write(REPNE_SCASW_A16
);
1084 if ((prefices
& PREFICES_ADDRESS
) != 0)
1085 working
.write(SCASW_A32
);
1087 working
.write(SCASW_A16
);
1095 switch (modrm
& 0x38) {
1097 working
.write(ROL_O8
); break;
1099 working
.write(ROR_O8
); break;
1101 working
.write(RCL_O8
); break;
1103 working
.write(RCR_O8
); break;
1105 working
.write(SHL
); break;
1107 working
.write(SHR
); break;
1109 System
.err
.println("Emulated: invalid SHL encoding");
1110 working
.write(SHL
); break;
1112 working
.write(SAR_O8
); break;
1119 if ((prefices
& PREFICES_OPERAND
) != 0) {
1120 switch (modrm
& 0x38) {
1122 working
.write(ROL_O32
); break;
1124 working
.write(ROR_O32
); break;
1126 working
.write(RCL_O32
); break;
1128 working
.write(RCR_O32
); break;
1130 working
.write(SHL
); break;
1132 working
.write(SHR
); break;
1134 System
.err
.println("Emulated: invalid SHL encoding");
1135 working
.write(SHL
); break;
1137 working
.write(SAR_O32
); break;
1140 switch (modrm
& 0x38) {
1142 working
.write(ROL_O16
); break;
1144 working
.write(ROR_O16
); break;
1146 working
.write(RCL_O16
); break;
1148 working
.write(RCR_O16
); break;
1150 working
.write(SHL
); break;
1152 working
.write(SHR
); break;
1154 System
.err
.println("Emulated: invalid SHL encoding");
1155 working
.write(SHL
); break;
1157 working
.write(SAR_O16
); break;
1163 switch (prefices
& PREFICES_OPERAND
) {
1165 working
.write(RET_IW_O16
); break;
1166 case PREFICES_OPERAND
:
1167 working
.write(RET_IW_O32
); break;
1172 switch (prefices
& PREFICES_OPERAND
) {
1174 working
.write(RET_O16
); break;
1175 case PREFICES_OPERAND
:
1176 working
.write(RET_O32
); break;
1181 switch (prefices
& PREFICES_OPERAND
) {
1183 working
.write(ENTER_O16
); break;
1184 case PREFICES_OPERAND
:
1185 working
.write(ENTER_O32
); break;
1190 switch (prefices
& PREFICES_OPERAND
) {
1192 working
.write(LEAVE_O16
); break;
1193 case PREFICES_OPERAND
:
1194 working
.write(LEAVE_O32
); break;
1199 switch (prefices
& PREFICES_OPERAND
) {
1201 working
.write(RET_FAR_IW_O16
); break;
1202 case PREFICES_OPERAND
:
1203 working
.write(RET_FAR_IW_O32
); break;
1208 switch (prefices
& PREFICES_OPERAND
) {
1210 working
.write(RET_FAR_O16
); break;
1211 case PREFICES_OPERAND
:
1212 working
.write(RET_FAR_O32
); break;
1217 switch (prefices
& PREFICES_OPERAND
) {
1219 working
.write(INT3_O16
); break;
1220 case PREFICES_OPERAND
:
1221 working
.write(INT3_O32
); break;
1226 switch (prefices
& PREFICES_OPERAND
) {
1228 working
.write(INT_O16
); break;
1229 case PREFICES_OPERAND
:
1230 working
.write(INT_O32
); break;
1235 switch (prefices
& PREFICES_OPERAND
) {
1237 working
.write(INTO_O16
); break;
1238 case PREFICES_OPERAND
:
1239 working
.write(INTO_O32
); break;
1244 switch (prefices
& PREFICES_OPERAND
) {
1246 working
.write(IRET_O16
); break;
1247 case PREFICES_OPERAND
:
1248 working
.write(IRET_O32
); break;
1252 case 0xd4: working
.write(AAM
); break; //AAM
1253 case 0xd5: working
.write(AAD
); break; //AAD
1255 case 0xd6: working
.write(SALC
); break; //SALC
1257 case 0xe0: //LOOPNZ Jb
1258 if ((prefices
& PREFICES_ADDRESS
) != 0)
1259 working
.write(LOOPNZ_ECX
);
1261 working
.write(LOOPNZ_CX
);
1264 case 0xe1: //LOOPZ Jb
1265 if ((prefices
& PREFICES_ADDRESS
) != 0)
1266 working
.write(LOOPZ_ECX
);
1268 working
.write(LOOPZ_CX
);
1271 case 0xe2: //LOOP Jb
1272 if ((prefices
& PREFICES_ADDRESS
) != 0)
1273 working
.write(LOOP_ECX
);
1275 working
.write(LOOP_CX
);
1279 if ((prefices
& PREFICES_ADDRESS
) != 0)
1280 working
.write(JECXZ
);
1282 working
.write(JCXZ
);
1285 case 0xe4: //IN AL, Ib
1286 case 0xec: working
.write(IN_O8
); break; //IN AL, DX
1288 case 0xe5: //IN eAX, Ib
1289 case 0xed: //IN eAX, DX
1290 if ((prefices
& PREFICES_OPERAND
) != 0)
1291 working
.write(IN_O32
);
1293 working
.write(IN_O16
);
1296 case 0xe6: //OUT Ib, AL
1297 case 0xee: working
.write(OUT_O8
); break; //OUT DX, AL
1299 case 0xe7: //OUT Ib, eAX
1300 case 0xef: //OUT DX, eAX
1301 if ((prefices
& PREFICES_OPERAND
) != 0)
1302 working
.write(OUT_O32
);
1304 working
.write(OUT_O16
);
1307 case 0xe8: //CALL Jv
1308 switch (prefices
& PREFICES_OPERAND
) {
1310 working
.write(CALL_O16
); break;
1311 case PREFICES_OPERAND
:
1312 working
.write(CALL_O32
); break;
1317 if ((prefices
& PREFICES_OPERAND
) != 0)
1318 working
.write(JUMP_O32
);
1320 working
.write(JUMP_O16
);
1323 case 0xea: //JMPF Ap
1324 if ((prefices
& PREFICES_OPERAND
) != 0)
1325 working
.write(JUMP_FAR_O32
);
1327 working
.write(JUMP_FAR_O16
);
1330 case 0xeb: working
.write(JUMP_O8
); break; //JMP Jb
1333 switch (prefices
& PREFICES_OPERAND
) {
1335 working
.write(INT1_O16
); break;
1336 case PREFICES_OPERAND
:
1337 working
.write(INT1_O32
); break;
1341 case 0xf4: working
.write(HALT
); break; //HLT
1343 case 0xf5: working
.write(CMC
); break; //CMC
1345 case 0xf6: //UNA GP3 Eb
1346 switch (modrm
& 0x38) {
1348 working
.write(AND
); break;
1350 working
.write(NOT
); break;
1352 working
.write(NEG
); break;
1354 working
.write(MUL_O8
); break;
1356 working
.write(IMULA_O8
); break;
1358 working
.write(DIV_O8
); break;
1360 working
.write(IDIV_O8
); break;
1361 default: throw new IllegalStateException("Invalid Gp 3 Instruction F6 /" + ((modrm
& 0x38) >> 3) + "?");
1365 case 0xf7: //UNA GP3 Ev
1366 if ((prefices
& PREFICES_OPERAND
) != 0) {
1367 switch (modrm
& 0x38) {
1369 working
.write(AND
); break;
1371 working
.write(NOT
); break;
1373 working
.write(NEG
); break;
1375 working
.write(MUL_O32
); break;
1377 working
.write(IMULA_O32
); break;
1379 working
.write(DIV_O32
); break;
1381 working
.write(IDIV_O32
); break;
1382 default: throw new IllegalStateException("Invalid Gp 3 Instruction O32 F7 /" + ((modrm
& 0x38) >> 3) + "?");
1385 switch (modrm
& 0x38) {
1387 working
.write(AND
); break;
1389 working
.write(NOT
); break;
1391 working
.write(NEG
); break;
1393 working
.write(MUL_O16
); break;
1395 working
.write(IMULA_O16
); break;
1397 working
.write(DIV_O16
); break;
1399 working
.write(IDIV_O16
); break;
1400 default: throw new IllegalStateException("Invalid Gp 3 Instruction O16 F7 /" + ((modrm
& 0x38) >> 3) + "?");
1405 case 0xf8: working
.write(CLC
); break; //CLC
1406 case 0xf9: working
.write(STC
); break; //STC
1407 case 0xfa: working
.write(CLI
); break; //CLI
1408 case 0xfb: working
.write(STI
); break; //STI
1409 case 0xfc: working
.write(CLD
); break; //CLD
1410 case 0xfd: working
.write(STD
); break; //STD
1413 switch (modrm
& 0x38) {
1415 working
.write(INC
); break;
1417 working
.write(DEC
); break;
1418 default: throw new IllegalStateException("Invalid Gp 4 Instruction FE /" + ((modrm
& 0x38) >> 3) + "?");
1423 switch (modrm
& 0x38) {
1425 working
.write(INC
); break;
1427 working
.write(DEC
); break;
1429 switch (prefices
& PREFICES_OPERAND
) {
1431 working
.write(CALL_ABS_O16
); break;
1432 case PREFICES_OPERAND
:
1433 working
.write(CALL_ABS_O32
); break;
1437 switch (prefices
& PREFICES_OPERAND
) {
1439 working
.write(CALL_FAR_O16
); break;
1440 case PREFICES_OPERAND
:
1441 working
.write(CALL_FAR_O32
); break;
1445 if ((prefices
& PREFICES_OPERAND
) != 0)
1446 working
.write(JUMP_ABS_O32
);
1448 working
.write(JUMP_ABS_O16
);
1451 if ((prefices
& PREFICES_OPERAND
) != 0)
1452 working
.write(JUMP_FAR_O32
);
1454 working
.write(JUMP_FAR_O16
);
1457 switch (prefices
& PREFICES_OPERAND
) {
1459 working
.write(PUSH_O16
); break;
1460 case PREFICES_OPERAND
:
1461 working
.write(PUSH_O32
); break;
1465 working
.write(UNDEFINED
);
1468 throw new IllegalStateException("Invalid Gp 5 Instruction FF /" + ((modrm
& 0x38) >> 3) + "?");
1472 case 0x63: working
.write(UNDEFINED
); break; //ARPL
1474 working
.write(MEM_RESET
); //use mem_reset as Nop
1476 case 0x86: //XCHG Eb, Gb
1477 case 0x87: //XCHG Ev, Gv
1478 case 0x88: //MOV Eb, Gb
1479 case 0x89: //MOV Ev, Gv
1480 case 0x8a: //MOV Gb, Eb
1481 case 0x8b: //MOV Gv, Ev
1482 case 0x8c: //MOV Ew, Sw
1483 case 0x8d: //LEA Gv, M
1484 case 0x8e: //MOV Sw, Ew
1486 case 0x91: //XCHG eAX, eCX
1487 case 0x92: //XCHG eAX, eCX
1488 case 0x93: //XCHG eAX, eCX
1489 case 0x94: //XCHG eAX, eCX
1490 case 0x95: //XCHG eAX, eCX
1491 case 0x96: //XCHG eAX, eCX
1492 case 0x97: //XCHG eAX, eCX
1494 case 0xa0: //MOV AL, Ob
1495 case 0xa1: //MOV eAX, Ov
1496 case 0xa2: //MOV Ob, AL
1497 case 0xa3: //MOV Ov, eAX
1499 case 0xb0: //MOV AL, Ib
1500 case 0xb1: //MOV CL, Ib
1501 case 0xb2: //MOV DL, Ib
1502 case 0xb3: //MOV BL, Ib
1503 case 0xb4: //MOV AH, Ib
1504 case 0xb5: //MOV CH, Ib
1505 case 0xb6: //MOV DH, Ib
1506 case 0xb7: //MOV BH, Ib
1508 case 0xb8: //MOV eAX, Iv
1509 case 0xb9: //MOV eCX, Iv
1510 case 0xba: //MOV eDX, Iv
1511 case 0xbb: //MOV eBX, Iv
1512 case 0xbc: //MOV eSP, Iv
1513 case 0xbd: //MOV eBP, Iv
1514 case 0xbe: //MOV eSI, Iv
1515 case 0xbf: //MOV eDI, Iv
1519 case 0xc6: //MOV GP11 Eb, Gb
1520 case 0xc7: //MOV GP11 Ev, Gv
1526 throw new IllegalStateException("Missing Operation: 0x" + Integer
.toHexString(opcode
));
1530 case 0xf00: // Group 6
1531 switch (modrm
& 0x38) {
1533 working
.write(SLDT
); break;
1535 working
.write(STR
); break;
1537 working
.write(LLDT
); break;
1539 working
.write(LTR
); break;
1541 working
.write(VERR
); break;
1543 working
.write(VERW
); break;
1544 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F 00 /" + ((modrm
& 0x38) >> 3) + "?");
1548 switch (modrm
& 0x38) {
1550 if ((prefices
& PREFICES_OPERAND
) != 0)
1551 working
.write(SGDT_O32
);
1553 working
.write(SGDT_O16
);
1556 if ((prefices
& PREFICES_OPERAND
) != 0)
1557 working
.write(SIDT_O32
);
1559 working
.write(SIDT_O16
);
1562 if ((prefices
& PREFICES_OPERAND
) != 0)
1563 working
.write(LGDT_O32
);
1565 working
.write(LGDT_O16
);
1568 if ((prefices
& PREFICES_OPERAND
) != 0)
1569 working
.write(LIDT_O32
);
1571 working
.write(LIDT_O16
);
1574 working
.write(SMSW
); break;
1576 working
.write(LMSW
); break;
1578 working
.write(INVLPG
); break;
1579 default: throw new IllegalStateException("Invalid Gp 7 Instruction 0F 01 /" + ((modrm
& 0x38) >> 3) + "?");
1582 case 0xf06: working
.write(CLTS
); break; //CLTS
1583 case 0xf09: working
.write(MEM_RESET
); break; //WBINVD
1584 case 0xf1f: working
.write(MEM_RESET
); break; //multi byte NOP (read latest manual)
1585 case 0xf30: working
.write(WRMSR
); break; //WRMSR
1586 case 0xf31: working
.write(RDTSC
); break; //RDTSC
1587 case 0xf32: working
.write(RDMSR
); break; //RDMSR
1589 case 0xf40: working
.write(CMOVO
); break; //CMOVO
1590 case 0xf41: working
.write(CMOVNO
); break; //CMOVNO
1591 case 0xf42: working
.write(CMOVC
); break; //CMOVC
1592 case 0xf43: working
.write(CMOVNC
); break; //CMOVNC
1593 case 0xf44: working
.write(CMOVZ
); break; //CMOVZ
1594 case 0xf45: working
.write(CMOVNZ
); break; //CMOVNZ
1595 case 0xf46: working
.write(CMOVNA
); break; //CMOVNA
1596 case 0xf47: working
.write(CMOVA
); break; //CMOVA
1597 case 0xf48: working
.write(CMOVS
); break; //CMOVS
1598 case 0xf49: working
.write(CMOVNS
); break; //CMOVNS
1599 case 0xf4a: working
.write(CMOVP
); break; //CMOVP
1600 case 0xf4b: working
.write(CMOVNP
); break; //CMOVNP
1601 case 0xf4c: working
.write(CMOVL
); break; //CMOVL
1602 case 0xf4d: working
.write(CMOVNL
); break; //CMOVNL
1603 case 0xf4e: working
.write(CMOVNG
); break; //CMOVNG
1604 case 0xf4f: working
.write(CMOVG
); break; //CMOVG
1606 case 0xf80: if ((prefices
& PREFICES_OPERAND
) != 0)
1607 working
.write(JO_O32
);
1609 working
.write(JO_O16
);
1611 case 0xf81: if ((prefices
& PREFICES_OPERAND
) != 0)
1612 working
.write(JNO_O32
);
1614 working
.write(JNO_O16
);
1616 case 0xf82: if ((prefices
& PREFICES_OPERAND
) != 0)
1617 working
.write(JC_O32
);
1619 working
.write(JC_O16
);
1621 case 0xf83: if ((prefices
& PREFICES_OPERAND
) != 0)
1622 working
.write(JNC_O32
);
1624 working
.write(JNC_O16
);
1626 case 0xf84: if ((prefices
& PREFICES_OPERAND
) != 0)
1627 working
.write(JZ_O32
);
1629 working
.write(JZ_O16
);
1631 case 0xf85: if ((prefices
& PREFICES_OPERAND
) != 0)
1632 working
.write(JNZ_O32
);
1634 working
.write(JNZ_O16
);
1636 case 0xf86: if ((prefices
& PREFICES_OPERAND
) != 0)
1637 working
.write(JNA_O32
);
1639 working
.write(JNA_O16
);
1641 case 0xf87: if ((prefices
& PREFICES_OPERAND
) != 0)
1642 working
.write(JA_O32
);
1644 working
.write(JA_O16
);
1646 case 0xf88: if ((prefices
& PREFICES_OPERAND
) != 0)
1647 working
.write(JS_O32
);
1649 working
.write(JS_O16
);
1651 case 0xf89: if ((prefices
& PREFICES_OPERAND
) != 0)
1652 working
.write(JNS_O32
);
1654 working
.write(JNS_O16
);
1656 case 0xf8a: if ((prefices
& PREFICES_OPERAND
) != 0)
1657 working
.write(JP_O32
);
1659 working
.write(JP_O16
);
1661 case 0xf8b: if ((prefices
& PREFICES_OPERAND
) != 0)
1662 working
.write(JNP_O32
);
1664 working
.write(JNP_O16
);
1666 case 0xf8c: if ((prefices
& PREFICES_OPERAND
) != 0)
1667 working
.write(JL_O32
);
1669 working
.write(JL_O16
);
1671 case 0xf8d: if ((prefices
& PREFICES_OPERAND
) != 0)
1672 working
.write(JNL_O32
);
1674 working
.write(JNL_O16
);
1676 case 0xf8e: if ((prefices
& PREFICES_OPERAND
) != 0)
1677 working
.write(JNG_O32
);
1679 working
.write(JNG_O16
);
1681 case 0xf8f: if ((prefices
& PREFICES_OPERAND
) != 0)
1682 working
.write(JG_O32
);
1684 working
.write(JG_O16
);
1687 case 0xf90: working
.write(SETO
); break; //SETO
1688 case 0xf91: working
.write(SETNO
); break; //SETNO
1689 case 0xf92: working
.write(SETC
); break; //SETC
1690 case 0xf93: working
.write(SETNC
); break; //SETNC
1691 case 0xf94: working
.write(SETZ
); break; //SETZ
1692 case 0xf95: working
.write(SETNZ
); break; //SETNZ
1693 case 0xf96: working
.write(SETNA
); break; //SETNA
1694 case 0xf97: working
.write(SETA
); break; //SETA
1695 case 0xf98: working
.write(SETS
); break; //SETS
1696 case 0xf99: working
.write(SETNS
); break; //SETNS
1697 case 0xf9a: working
.write(SETP
); break; //SETP
1698 case 0xf9b: working
.write(SETNP
); break; //SETNP
1699 case 0xf9c: working
.write(SETL
); break; //SETL
1700 case 0xf9d: working
.write(SETNL
); break; //SETNL
1701 case 0xf9e: working
.write(SETNG
); break; //SETNG
1702 case 0xf9f: working
.write(SETG
); break; //SETG
1704 case 0xfa2: working
.write(CPUID
); break; //CPUID
1706 case 0xfa4: //SHLD Ev, Gv, Ib
1707 case 0xfa5: //SHLD Ev, Gv, CL
1708 if ((prefices
& PREFICES_OPERAND
) != 0)
1709 working
.write(SHLD_O32
);
1711 working
.write(SHLD_O16
);
1714 case 0xfac: //SHRD Ev, Gv, Ib
1715 case 0xfad: //SHRD Ev, Gv, CL
1716 if ((prefices
& PREFICES_OPERAND
) != 0)
1717 working
.write(SHRD_O32
);
1719 working
.write(SHRD_O16
);
1722 case 0xfb0: //CMPXCHG Eb, Gb
1723 case 0xfb1: //CMPXCHG Ev, Gv
1724 working
.write(CMPXCHG
); break;
1726 case 0xfa3: //BT Ev, Gv
1727 switch (modrm
& 0xc7) {
1728 default: working
.write(BT_MEM
); break;
1738 if ((prefices
& PREFICES_OPERAND
) != 0)
1739 working
.write(BT_O32
);
1741 working
.write(BT_O16
);
1745 case 0xfab: //BTS Ev, Gv
1746 switch (modrm
& 0xc7) {
1747 default: working
.write(BTS_MEM
); break;
1757 if ((prefices
& PREFICES_OPERAND
) != 0)
1758 working
.write(BTS_O32
);
1760 working
.write(BTS_O16
);
1764 case 0xfb3: //BTR Ev, Gv
1765 switch (modrm
& 0xc7) {
1766 default: working
.write(BTR_MEM
); break;
1776 if ((prefices
& PREFICES_OPERAND
) != 0)
1777 working
.write(BTR_O32
);
1779 working
.write(BTR_O16
);
1783 case 0xfbb: //BTC Ev, Gv
1784 switch (modrm
& 0xc7) {
1785 default: working
.write(BTC_MEM
); break;
1795 if ((prefices
& PREFICES_OPERAND
) != 0)
1796 working
.write(BTC_O32
);
1798 working
.write(BTC_O16
);
1802 case 0xfba: //Grp 8 Ev, Ib
1803 switch (modrm
& 0x38) {
1805 switch (modrm
& 0xc7) {
1806 default: working
.write(BT_MEM
); break;
1807 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1808 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1809 if ((prefices
& PREFICES_OPERAND
) != 0)
1810 working
.write(BT_O32
);
1812 working
.write(BT_O16
);
1816 switch (modrm
& 0xc7) {
1817 default: working
.write(BTS_MEM
); break;
1818 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1819 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1820 if ((prefices
& PREFICES_OPERAND
) != 0)
1821 working
.write(BTS_O32
);
1823 working
.write(BTS_O16
);
1827 switch (modrm
& 0xc7) {
1828 default: working
.write(BTR_MEM
); break;
1829 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1830 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1831 if ((prefices
& PREFICES_OPERAND
) != 0)
1832 working
.write(BTR_O32
);
1834 working
.write(BTR_O16
);
1838 switch (modrm
& 0xc7) {
1839 default: working
.write(BTC_MEM
); break;
1840 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1841 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1842 if ((prefices
& PREFICES_OPERAND
) != 0)
1843 working
.write(BTC_O32
);
1845 working
.write(BTC_O16
);
1848 default: throw new IllegalStateException("Invalid Gp 8 Instruction 0F BA /" + ((modrm
& 0x38) >> 3) + "?");
1851 case 0xfbc: working
.write(BSF
); break; //BSF Gv, Ev
1852 case 0xfbd: working
.write(BSR
); break; //BSR Gv, Ev
1854 case 0xfbe: //MOVSX Gv, Eb
1855 if ((prefices
& PREFICES_OPERAND
) != 0)
1856 working
.write(SIGN_EXTEND_8_32
);
1858 working
.write(SIGN_EXTEND_8_16
);
1860 case 0xfbf: //MOVSX Gv, Ew
1861 if ((prefices
& PREFICES_OPERAND
) != 0)
1862 working
.write(SIGN_EXTEND_16_32
);
1873 working
.write(BSWAP
); break;
1875 case 0xf20: //MOV Rd, Cd
1876 case 0xf21: //MOV Rd, Dd
1877 case 0xf22: //MOV Cd, Rd
1878 case 0xf23: //MOV Dd, Rd
1879 case 0xfb2: //LSS Mp
1880 case 0xfb4: //LFS Mp
1881 case 0xfb5: //LGS Mp
1882 case 0xfb6: //MOVZX Gv, Eb
1883 case 0xfb7: //MOVZX Gv, Ew
1887 switch (modrm
& 0x38)
1889 case 0x00: working
.write(FADD
); break;
1890 case 0x08: working
.write(FMUL
); break;
1892 case 0x18: working
.write(FCOM
); break;
1894 case 0x28: working
.write(FSUB
); break;
1896 case 0x38: working
.write(FDIV
); break;
1901 if ((modrm
& 0xc0) != 0xc0)
1903 switch (modrm
& 0x38)
1905 case 0x00: working
.write(FPUSH
); break;
1911 if ((prefices
& PREFICES_OPERAND
) != 0)
1912 working
.write(FLDENV_28
);
1914 working
.write(FLDENV_14
);
1917 if ((prefices
& PREFICES_OPERAND
) != 0)
1918 working
.write(FSTENV_28
);
1920 working
.write(FSTENV_14
);
1926 switch (modrm
& 0xf8)
1928 case 0xc0: working
.write(FPUSH
); break;
1934 case 0xe0: working
.write(FCHS
); break;
1935 case 0xe1: working
.write(FABS
); break;
1936 case 0xe4: working
.write(FCOM
); break;
1937 case 0xe5: working
.write(FXAM
); break;
1944 case 0xee: working
.write(FPUSH
); break;
1945 case 0xf0: working
.write(F2XM1
); break;
1946 case 0xf1: working
.write(FYL2X
); break;
1947 case 0xf2: working
.write(FPTAN
); break;
1948 case 0xf3: working
.write(FPATAN
); break;
1949 case 0xf4: working
.write(FXTRACT
); break;
1950 case 0xf5: working
.write(FPREM1
); break;
1951 case 0xf6: working
.write(FDECSTP
); break;
1952 case 0xf7: working
.write(FINCSTP
); break;
1953 case 0xf8: working
.write(FPREM
); break;
1954 case 0xf9: working
.write(FYL2XP1
); break;
1955 case 0xfa: working
.write(FSQRT
); break;
1956 case 0xfb: working
.write(FSINCOS
); break;
1957 case 0xfc: working
.write(FRNDINT
); break;
1958 case 0xfd: working
.write(FSCALE
); break;
1959 case 0xfe: working
.write(FSIN
); break;
1960 case 0xff: working
.write(FCOS
); break;
1966 if ((modrm
& 0xc0) != 0xc0)
1968 switch (modrm
& 0x38)
1970 case 0x00: working
.write(FADD
); break;
1971 case 0x08: working
.write(FMUL
); break;
1973 case 0x18: working
.write(FCOM
); break;
1975 case 0x28: working
.write(FSUB
); break;
1977 case 0x38: working
.write(FDIV
); break;
1982 switch (modrm
& 0xf8)
1984 case 0xc0: working
.write(FCMOVB
); break;
1985 case 0xc8: working
.write(FCMOVE
); break;
1986 case 0xd0: working
.write(FCMOVBE
); break;
1987 case 0xd8: working
.write(FCMOVU
); break;
1991 case 0xe9: working
.write(FUCOM
); break;
1997 if ((modrm
& 0xc0) != 0xc0)
1999 switch (modrm
& 0x38)
2001 case 0x00: working
.write(FPUSH
); break;
2002 case 0x08: working
.write(FCHOP
); break;
2004 case 0x18: working
.write(FRNDINT
); break;
2005 case 0x28: working
.write(FPUSH
); break;
2011 switch (modrm
& 0xf8)
2013 case 0xc0: working
.write(FCMOVNB
); break;
2014 case 0xc8: working
.write(FCMOVNE
); break;
2015 case 0xd0: working
.write(FCMOVNBE
); break;
2016 case 0xd8: working
.write(FCMOVNU
); break;
2017 case 0xe8: working
.write(FUCOMI
); break;
2018 case 0xf0: working
.write(FCOMI
); break;
2022 case 0xe2: working
.write(FCLEX
); break;
2023 case 0xe3: working
.write(FINIT
); break;
2030 switch (modrm
& 0x38)
2032 case 0x00: working
.write(FADD
); break;
2033 case 0x08: working
.write(FMUL
); break;
2035 case 0x18: working
.write(FCOM
); break;
2037 case 0x28: working
.write(FSUB
); break;
2039 case 0x38: working
.write(FDIV
); break;
2044 if ((modrm
& 0xc0) != 0xc0)
2046 switch (modrm
& 0x38)
2048 case 0x00: working
.write(FPUSH
); break;
2049 case 0x08: working
.write(FCHOP
); break;
2054 if ((prefices
& PREFICES_OPERAND
) != 0)
2055 working
.write(FRSTOR_108
);
2057 working
.write(FRSTOR_94
);
2060 if ((prefices
& PREFICES_OPERAND
) != 0)
2061 working
.write(FSAVE_108
);
2063 working
.write(FSAVE_94
);
2069 switch (modrm
& 0xf8)
2071 case 0xc0: working
.write(FFREE
); break;
2075 case 0xe8: working
.write(FUCOM
); break;
2083 case 0xd9: working
.write(FCOM
); break;
2085 switch (modrm
& 0x38)
2087 case 0x00: working
.write(FADD
); break;
2088 case 0x08: working
.write(FMUL
); break;
2090 case 0x18: working
.write(FCOM
); break;
2092 case 0x28: working
.write(FSUB
); break;
2094 case 0x38: working
.write(FDIV
); break;
2100 if ((modrm
& 0xc0) != 0xc0)
2102 switch (modrm
& 0x38)
2104 case 0x00: working
.write(FPUSH
); break;
2105 case 0x08: working
.write(FCHOP
); break;
2108 case 0x38: working
.write(FRNDINT
); break;
2109 case 0x20: working
.write(FBCD2F
); break;
2110 case 0x28: working
.write(FPUSH
); break;
2111 case 0x30: working
.write(FF2BCD
); break;
2116 switch (modrm
& 0xf8)
2118 case 0xe8: working
.write(FUCOMI
); break;
2119 case 0xf0: working
.write(FCOMI
); break;
2127 private void writeFlags(int prefices
, int opcode
, int modrm
)
2130 case 0x00: //ADD Eb, Gb
2131 case 0x02: //ADD Gb, Eb
2132 case 0x04: //ADD AL, Ib
2133 case 0xfc0: //XADD Eb, Gb
2134 working
.write(ADD_O8_FLAGS
); break;
2136 case 0x10: //ADC Eb, Gb
2137 case 0x12: //ADC Gb, Eb
2138 case 0x14: //ADC AL, Ib
2139 working
.write(ADC_O8_FLAGS
); break;
2141 case 0x18: //SBB Eb, Gb
2142 case 0x1a: //SBB Gb, Eb
2143 case 0x1c: //SBB AL, Ib
2144 working
.write(SBB_O8_FLAGS
); break;
2146 case 0x28: //SUB Eb, Gb
2147 case 0x2a: //SUB Gb, Eb
2148 case 0x2c: //SUB AL, Ib
2149 case 0x38: //CMP Eb, Gb
2150 case 0x3a: //CMP Gb, Eb
2151 case 0x3c: //CMP AL, Ib
2152 working
.write(SUB_O8_FLAGS
); break;
2154 case 0x01: //ADD Ev, Gv
2155 case 0x03: //ADD Gv, Ev
2156 case 0x05: //ADD eAX, Iv
2157 case 0xfc1: //XADD Ev, Gv
2158 if ((prefices
& PREFICES_OPERAND
) != 0)
2159 working
.write(ADD_O32_FLAGS
);
2161 working
.write(ADD_O16_FLAGS
);
2164 case 0x11: //ADC Ev, Gv
2165 case 0x13: //ADC Gv, Ev
2166 case 0x15: //ADC eAX, Iv
2167 if ((prefices
& PREFICES_OPERAND
) != 0)
2168 working
.write(ADC_O32_FLAGS
);
2170 working
.write(ADC_O16_FLAGS
);
2173 case 0x19: //SBB Ev, Gv
2174 case 0x1b: //SBB Gv, Ev
2175 case 0x1d: //SBB eAX, Iv
2176 if ((prefices
& PREFICES_OPERAND
) != 0)
2177 working
.write(SBB_O32_FLAGS
);
2179 working
.write(SBB_O16_FLAGS
);
2182 case 0x29: //SUB Ev, Gv
2183 case 0x2b: //SUB Gv, Ev
2184 case 0x2d: //SUB eAX, Iv
2185 case 0x39: //CMP Ev, Gv
2186 case 0x3b: //CMP Gv, Ev
2187 case 0x3d: //CMP eAX, Iv
2188 if ((prefices
& PREFICES_OPERAND
) != 0)
2189 working
.write(SUB_O32_FLAGS
);
2191 working
.write(SUB_O16_FLAGS
);
2194 case 0x08: //OR Eb, Gb
2195 case 0x0a: //OR Gb, Eb
2196 case 0x0c: //OR AL, Ib
2197 case 0x20: //AND Eb, Gb
2198 case 0x22: //AND Gb, Eb
2199 case 0x24: //AND AL, Ib
2200 case 0x30: //XOR Eb, Gb
2201 case 0x32: //XOR Gb, Eb
2202 case 0x34: //XOR AL, Ib
2203 case 0x84: //TEST Eb, Gb
2204 case 0xa8: //TEST AL, Ib
2205 working
.write(BITWISE_FLAGS_O8
); break;
2207 case 0x09: //OR Ev, Gv
2208 case 0x0b: //OR Gv, Ev
2209 case 0x0d: //OR eAX, Iv
2210 case 0x21: //AND Ev, Gv
2211 case 0x23: //AND Gv, Ev
2212 case 0x25: //AND eAX, Iv
2213 case 0x31: //XOR Ev, Gv
2214 case 0x33: //XOR Gv, Ev
2215 case 0x35: //XOR eAX, Iv
2216 case 0x85: //TEST Ev, Gv
2217 case 0xa9: //TEST eAX, Iv
2218 if ((prefices
& PREFICES_OPERAND
) != 0)
2219 working
.write(BITWISE_FLAGS_O32
);
2221 working
.write(BITWISE_FLAGS_O16
);
2224 case 0x40: //INC eAX
2225 case 0x41: //INC eCX
2226 case 0x42: //INC eDX
2227 case 0x43: //INC eBX
2228 case 0x44: //INC eSP
2229 case 0x45: //INC eBP
2230 case 0x46: //INC eSI
2231 case 0x47: //INC eDI
2232 if ((prefices
& PREFICES_OPERAND
) != 0)
2233 working
.write(INC_O32_FLAGS
);
2235 working
.write(INC_O16_FLAGS
);
2238 case 0x48: //DEC eAX
2239 case 0x49: //DEC eCX
2240 case 0x4a: //DEC eDX
2241 case 0x4b: //DEC eBX
2242 case 0x4c: //DEC eSP
2243 case 0x4d: //DEC eBP
2244 case 0x4e: //DEC eSI
2245 case 0x4f: //DEC eDI
2246 if ((prefices
& PREFICES_OPERAND
) != 0)
2247 working
.write(DEC_O32_FLAGS
);
2249 working
.write(DEC_O16_FLAGS
);
2252 case 0x80: //IMM GP1 Eb, Ib
2253 case 0x82: //IMM GP1 Eb, Ib
2254 switch (modrm
& 0x38) {
2256 working
.write(ADD_O8_FLAGS
); break;
2258 working
.write(BITWISE_FLAGS_O8
); break;
2260 working
.write(ADC_O8_FLAGS
); break;
2262 working
.write(SBB_O8_FLAGS
); break;
2264 working
.write(BITWISE_FLAGS_O8
); break;
2267 working
.write(SUB_O8_FLAGS
); break;
2269 working
.write(BITWISE_FLAGS_O8
); break;
2273 case 0x81: //IMM GP1 Ev, Iv
2274 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
2275 if ((prefices
& PREFICES_OPERAND
) != 0) {
2276 switch (modrm
& 0x38) {
2278 working
.write(ADD_O32_FLAGS
); break;
2280 working
.write(BITWISE_FLAGS_O32
); break;
2282 working
.write(ADC_O32_FLAGS
); break;
2284 working
.write(SBB_O32_FLAGS
); break;
2286 working
.write(BITWISE_FLAGS_O32
); break;
2289 working
.write(SUB_O32_FLAGS
); break;
2291 working
.write(BITWISE_FLAGS_O32
); break;
2294 switch (modrm
& 0x38) {
2296 working
.write(ADD_O16_FLAGS
); break;
2298 working
.write(BITWISE_FLAGS_O16
); break;
2300 working
.write(ADC_O16_FLAGS
); break;
2302 working
.write(SBB_O16_FLAGS
); break;
2304 working
.write(BITWISE_FLAGS_O16
); break;
2307 working
.write(SUB_O16_FLAGS
); break;
2309 working
.write(BITWISE_FLAGS_O16
); break;
2317 switch (modrm
& 0x38) {
2319 working
.write(ROL_O8_FLAGS
); break;
2321 working
.write(ROR_O8_FLAGS
); break;
2323 working
.write(RCL_O8_FLAGS
); break;
2325 working
.write(RCR_O8_FLAGS
); break;
2327 working
.write(SHL_O8_FLAGS
); break;
2329 working
.write(SHR_O8_FLAGS
); break;
2331 working
.write(SHL_O8_FLAGS
); break;
2333 working
.write(SAR_O8_FLAGS
); break;
2340 if ((prefices
& PREFICES_OPERAND
) != 0) {
2341 switch (modrm
& 0x38) {
2343 working
.write(ROL_O32_FLAGS
); break;
2345 working
.write(ROR_O32_FLAGS
); break;
2347 working
.write(RCL_O32_FLAGS
); break;
2349 working
.write(RCR_O32_FLAGS
); break;
2351 working
.write(SHL_O32_FLAGS
); break;
2353 working
.write(SHR_O32_FLAGS
); break;
2355 working
.write(SHL_O32_FLAGS
); break;
2357 working
.write(SAR_O32_FLAGS
); break;
2360 switch (modrm
& 0x38) {
2362 working
.write(ROL_O16_FLAGS
); break;
2364 working
.write(ROR_O16_FLAGS
); break;
2366 working
.write(RCL_O16_FLAGS
); break;
2368 working
.write(RCR_O16_FLAGS
); break;
2370 working
.write(SHL_O16_FLAGS
); break;
2372 working
.write(SHR_O16_FLAGS
); break;
2374 working
.write(SHL_O16_FLAGS
); break;
2376 working
.write(SAR_O16_FLAGS
); break;
2381 case 0xf6: //UNA GP3 Eb
2382 switch (modrm
& 0x38) {
2384 working
.write(BITWISE_FLAGS_O8
); break;
2386 working
.write(NEG_O8_FLAGS
); break;
2390 case 0xf7: //UNA GP3 Ev
2391 if ((prefices
& PREFICES_OPERAND
) != 0) {
2392 switch (modrm
& 0x38) {
2394 working
.write(BITWISE_FLAGS_O32
); break;
2396 working
.write(NEG_O32_FLAGS
); break;
2399 switch (modrm
& 0x38) {
2401 working
.write(BITWISE_FLAGS_O16
); break;
2403 working
.write(NEG_O16_FLAGS
); break;
2409 switch (modrm
& 0x38) {
2411 working
.write(INC_O8_FLAGS
); break;
2413 working
.write(DEC_O8_FLAGS
); break;
2418 switch (modrm
& 0x38) {
2420 if ((prefices
& PREFICES_OPERAND
) != 0)
2421 working
.write(INC_O32_FLAGS
);
2423 working
.write(INC_O16_FLAGS
);
2426 if ((prefices
& PREFICES_OPERAND
) != 0)
2427 working
.write(DEC_O32_FLAGS
);
2429 working
.write(DEC_O16_FLAGS
);
2437 case 0x58: //POP eAX
2438 case 0x59: //POP eCX
2439 case 0x5a: //POP eDX
2440 case 0x5b: //POP eBX
2441 case 0x5d: //POP eBP
2442 case 0x5e: //POP eSI
2443 case 0x5f: //POP eDI
2444 case 0xfa1: //POP FS
2445 case 0xfa9: working
.write(STORE1_ESP
); break; //POP GS
2448 case 0x8f: //POP Ev This is really annoying and not quite correct?
2449 for (int i
= 0; i
< working
.getLength(); i
++) {
2450 switch (working
.getMicrocodeAt(i
)) {
2453 working
.replace(i
, ADDR_REG1
);
2456 working
.replace(i
, ADDR_2REG1
);
2459 working
.replace(i
, ADDR_4REG1
);
2462 working
.replace(i
, ADDR_8REG1
);
2471 switch (working
.getMicrocodeAt(working
.getLength() - 1)) {
2473 case STORE0_SP
: break;
2474 default: working
.write(STORE1_ESP
);
2479 if ((prefices
& PREFICES_REPE
) != 0) {
2480 working
.write(REP_SUB_O8_FLAGS
);
2481 } else if ((prefices
& PREFICES_REPNE
) != 0) {
2482 working
.write(REP_SUB_O8_FLAGS
);
2484 working
.write(SUB_O8_FLAGS
);
2488 case 0xa7: //CMPSW/D
2489 if ((prefices
& PREFICES_OPERAND
) != 0) {
2490 if ((prefices
& PREFICES_REPE
) != 0) {
2491 working
.write(REP_SUB_O32_FLAGS
);
2492 } else if ((prefices
& PREFICES_REPNE
) != 0) {
2493 working
.write(REP_SUB_O32_FLAGS
);
2495 working
.write(SUB_O32_FLAGS
);
2498 if ((prefices
& PREFICES_REPE
) != 0) {
2499 working
.write(REP_SUB_O16_FLAGS
);
2500 } else if ((prefices
& PREFICES_REPNE
) != 0) {
2501 working
.write(REP_SUB_O16_FLAGS
);
2503 working
.write(SUB_O16_FLAGS
);
2509 if ((prefices
& PREFICES_REPE
) != 0) {
2510 working
.write(REP_SUB_O8_FLAGS
);
2511 } else if ((prefices
& PREFICES_REPNE
) != 0) {
2512 working
.write(REP_SUB_O8_FLAGS
);
2514 working
.write(SUB_O8_FLAGS
);
2518 case 0xaf: //SCASW/D
2519 if ((prefices
& PREFICES_OPERAND
) != 0) {
2520 if ((prefices
& PREFICES_REPE
) != 0) {
2521 working
.write(REP_SUB_O32_FLAGS
);
2522 } else if ((prefices
& PREFICES_REPNE
) != 0) {
2523 working
.write(REP_SUB_O32_FLAGS
);
2525 working
.write(SUB_O32_FLAGS
);
2528 if ((prefices
& PREFICES_REPE
) != 0) {
2529 working
.write(REP_SUB_O16_FLAGS
);
2530 } else if ((prefices
& PREFICES_REPNE
) != 0) {
2531 working
.write(REP_SUB_O16_FLAGS
);
2533 working
.write(SUB_O16_FLAGS
);
2541 switch (prefices
& PREFICES_OPERAND
) {
2543 working
.write(STORE0_FLAGS
); break;
2544 case PREFICES_OPERAND
:
2545 working
.write(STORE0_EFLAGS
); break;
2550 case 0xd4: working
.write(BITWISE_FLAGS_O8
); break; //AAM
2552 case 0xf1f: break; //NOP
2553 case 0xfa4: //SHLD Ev, Gv, Ib
2554 case 0xfa5: //SHLD Ev, Gv, CL
2555 if ((prefices
& PREFICES_OPERAND
) != 0)
2556 working
.write(SHL_O32_FLAGS
);
2558 working
.write(SHL_O16_FLAGS
);
2561 case 0xfac: //SHRD Ev, Gv, Ib
2562 case 0xfad: //SHRD Ev, Gv, CL
2563 if ((prefices
& PREFICES_OPERAND
) != 0)
2564 working
.write(SHR_O32_FLAGS
);
2566 working
.write(SHR_O16_FLAGS
);
2569 case 0xfb0: //CMPXCHG Eb, Gb
2570 working
.write(CMPXCHG_O8_FLAGS
); break;
2571 case 0xfb1: //CMPXCHG Ev, Gv
2572 if ((prefices
& PREFICES_OPERAND
) != 0)
2573 working
.write(CMPXCHG_O32_FLAGS
);
2575 working
.write(CMPXCHG_O16_FLAGS
);
2581 case 0x06: //PUSH ES
2582 case 0x0e: //PUSH CS
2584 case 0x16: //PUSH SS
2585 case 0x1e: //PUSH DS
2593 case 0x50: //PUSH eAX
2594 case 0x51: //PUSH eCX
2595 case 0x52: //PUSH eDX
2596 case 0x53: //PUSH eBX
2597 case 0x54: //PUSH eSP
2598 case 0x55: //PUSH eBP
2599 case 0x56: //PUSH eSI
2600 case 0x57: //PUSH eDI
2601 case 0x5c: //POP eSP so don't write incremented stack pointer back
2603 case 0x60: //PUSHA/D
2606 case 0x63: //#UD (ARPL)
2607 case 0x68: //PUSH Iv
2608 case 0x69: //IMUL Gv, Ev, Iv
2609 case 0x6a: //PUSH Ib
2610 case 0x6b: //IMUL Gv, Ev, Ib
2614 case 0x6f: //OUTSW/D
2633 case 0x86: //XCHG Eb, Gb
2634 case 0x87: //XCHG Ev, Gv
2635 case 0x88: //MOV Eb, Gb
2636 case 0x89: //MOV Ev, Gv
2637 case 0x8a: //MOV Gb, Eb
2638 case 0x8b: //MOV Gv, Ev
2639 case 0x8c: //MOV Ew, Sw
2640 case 0x8d: //LEA Gv, M
2641 case 0x8e: //MOV Sw, Ew
2644 case 0x91: //XCHG eAX, eCX
2645 case 0x92: //XCHG eAX, eCX
2646 case 0x93: //XCHG eAX, eCX
2647 case 0x94: //XCHG eAX, eCX
2648 case 0x95: //XCHG eAX, eCX
2649 case 0x96: //XCHG eAX, eCX
2650 case 0x97: //XCHG eAX, eCX
2651 case 0x98: //CBW/CWDE
2652 case 0x99: //CWD/CDQ
2653 case 0x9a: //CALLF Ap
2660 case 0xa0: //MOV AL, Ob
2661 case 0xa1: //MOV eAX, Ov
2662 case 0xa2: //MOV Ob, AL
2663 case 0xa3: //MOV Ov, eAX
2665 case 0xa5: //MOVSW/D
2667 case 0xab: //STOSW/D
2669 case 0xad: //LODSW/D
2671 case 0xb0: //MOV AL, Ib
2672 case 0xb1: //MOV CL, Ib
2673 case 0xb2: //MOV DL, Ib
2674 case 0xb3: //MOV BL, Ib
2675 case 0xb4: //MOV AH, Ib
2676 case 0xb5: //MOV CH, Ib
2677 case 0xb6: //MOV DH, Ib
2678 case 0xb7: //MOV BH, Ib
2679 case 0xb8: //MOV eAX, Iv
2680 case 0xb9: //MOV eCX, Iv
2681 case 0xba: //MOV eDX, Iv
2682 case 0xbb: //MOV eBX, Iv
2683 case 0xbc: //MOV eSP, Iv
2684 case 0xbd: //MOV eBP, Iv
2685 case 0xbe: //MOV eSI, Iv
2686 case 0xbf: //MOV eDI, Iv
2692 case 0xc6: //MOV GP11 Eb, Gb
2693 case 0xc7: //MOV GP11 Ev, Gv
2696 case 0xca: //RETF Iw
2710 case 0xe4: //IN AL, Ib
2711 case 0xe5: //IN eAX, Ib
2712 case 0xe6: //OUT Ib, AL
2713 case 0xe7: //OUT Ib, eAX
2714 case 0xe8: //CALL Jv
2716 case 0xea: //JMPF Ap
2718 case 0xec: //IN AL, DX
2719 case 0xed: //IN eAX, DX
2720 case 0xee: //OUT DX, AL
2721 case 0xef: //OUT DX, eAX
2734 case 0xf00: //Group 6
2735 case 0xf01: //Group 7
2737 case 0xf09: //WBINVD
2738 case 0xf20: //MOV Rd, Cd
2739 case 0xf21: //MOV Rd, Dd
2740 case 0xf22: //MOV Cd, Rd
2741 case 0xf23: //MOV Dd, Rd
2746 case 0xf41: //CMOVNO
2748 case 0xf43: //CMOVNC
2750 case 0xf45: //CMOVNZ
2751 case 0xf46: //CMOVBE
2752 case 0xf47: //CMOVNBE
2754 case 0xf49: //CMOVNS
2756 case 0xf4b: //CMOVNP
2758 case 0xf4d: //CMOVNL
2759 case 0xf4e: //CMOVLE
2760 case 0xf4f: //CMOVNLE
2762 case 0xf81: //JNO Jv
2764 case 0xf83: //JNC Jv
2766 case 0xf85: //JNZ Jv
2767 case 0xf86: //JNA Jv
2770 case 0xf89: //JNS Jv
2772 case 0xf8b: //JNP Jv
2774 case 0xf8d: //JNL Jv
2775 case 0xf8e: //JNG Jv
2793 case 0xfa0: //PUSH FS
2795 case 0xfa8: //PUSH GS
2796 case 0xfaf: //IMUL Gv, Ev
2797 case 0xfa3: //BT Ev, Gv
2798 case 0xfab: //BTS Ev, Gv
2799 case 0xfb3: //BTR Ev, Gv
2800 case 0xfbb: //BTC Ev, Gv
2801 case 0xfb2: //LSS Mp
2802 case 0xfb4: //LFS Mp
2803 case 0xfb5: //LGS Mp
2804 case 0xfb6: //MOVZX Gv, Eb
2805 case 0xfb7: //MOVZX Gv, Ew
2806 case 0xfba: //Grp 8 Ev, Ib
2807 case 0xfbc: //BSF Gv, Ev
2808 case 0xfbd: //BSR Gv, Ev
2809 case 0xfbe: //MOVSX Gv, Eb
2810 case 0xfbf: //MOVSX Gv, Ew
2811 case 0xfc8: //BSWAP EAX
2812 case 0xfc9: //BSWAP ECX
2813 case 0xfca: //BSWAP EDX
2814 case 0xfcb: //BSWAP EBX
2815 case 0xfcc: //BSWAP ESP
2816 case 0xfcd: //BSWAP EBP
2817 case 0xfce: //BSWAP ESI
2818 case 0xfcf: //BSWAP EDI
2819 case 0xd800: // FPU OPS
2820 case 0xd900: // FPU OPS
2821 case 0xda00: // FPU OPS
2822 case 0xdb00: // FPU OPS
2823 case 0xdc00: // FPU OPS
2824 case 0xdd00: // FPU OPS
2825 case 0xde00: // FPU OPS
2826 case 0xdf00: // FPU OPS
2832 throw new IllegalStateException("Missing Flags: 0x" + Integer
.toHexString(opcode
));
2836 private void writeInputOperands(int prefices
, int opcode
, int modrm
, int sib
, int displacement
, long immediate
)
2839 case 0x00: //ADD Eb, Gb
2840 case 0x08: //OR Eb, Gb
2841 case 0x10: //ADC Eb, Gb
2842 case 0x18: //SBB Eb, Gb
2843 case 0x20: //AND Eb, Gb
2844 case 0x28: //SUB Eb, Gb
2845 case 0x30: //XOR Eb, Gb
2846 case 0x38: //CMP Eb, Gb
2847 case 0x84: //TEST Eb, Gb
2848 case 0x86: //XCHG Eb, Gb
2849 load0_Eb(prefices
, modrm
, sib
, displacement
);
2853 case 0x88: //MOV Eb, Gb
2857 case 0x02: //ADD Gb, Eb
2858 case 0x0a: //OR Gb, Eb
2859 case 0x12: //ADC Gb, Eb
2860 case 0x1a: //SBB Gb, Eb
2861 case 0x22: //AND Gb, Eb
2862 case 0x2a: //SUB Gb, Eb
2863 case 0x32: //XOR Gb, Eb
2864 case 0x3a: //CMP Gb, Eb
2865 case 0xfc0: //XADD Eb, Gb
2867 load1_Eb(prefices
, modrm
, sib
, displacement
);
2870 case 0x8a: //MOV Gb, Eb
2871 case 0xfb6: //MOVZX Gv, Eb
2872 case 0xfbe: //MOVSX Gv, Eb
2873 load0_Eb(prefices
, modrm
, sib
, displacement
);
2876 case 0x01: //ADD Ev, Gv
2877 case 0x09: //OR Ev, Gv
2878 case 0x11: //ADC Ev, Gv
2879 case 0x19: //SBB Ev, Gv
2880 case 0x21: //AND Ev, Gv
2881 case 0x29: //SUB Ev, Gv
2882 case 0x31: //XOR Ev, Gv
2883 case 0x39: //CMP Ev, Gv
2884 case 0x85: //TEST Ev, Gv
2885 case 0x87: //XCHG Ev, Gv
2886 if ((prefices
& PREFICES_OPERAND
) != 0) {
2887 load0_Ed(prefices
, modrm
, sib
, displacement
);
2890 load0_Ew(prefices
, modrm
, sib
, displacement
);
2895 case 0x89: //MOV Ev, Gv
2896 if ((prefices
& PREFICES_OPERAND
) != 0) {
2903 case 0x03: //ADD Gv, Ev
2904 case 0x0b: //OR Gv, Ev
2905 case 0x13: //ADC Gv, Ev
2906 case 0x1b: //SBB Gv, Ev
2907 case 0x23: //AND Gv, Ev
2908 case 0x2b: //SUB Gv, Ev
2909 case 0x33: //XOR Gv, Ev
2910 case 0x3b: //CMP Gv, Ev
2911 case 0xfaf: //IMUL Gv, Ev
2912 case 0xfbc: //BSF Gv, Ev
2913 case 0xfbd: //BSR Gv, Ev
2914 case 0xfc1: //XADD Ev, Gv
2915 if ((prefices
& PREFICES_OPERAND
) != 0) {
2917 load1_Ed(prefices
, modrm
, sib
, displacement
);
2920 load1_Ew(prefices
, modrm
, sib
, displacement
);
2924 case 0x8b: //MOV Gv, Ev
2925 if ((prefices
& PREFICES_OPERAND
) != 0) {
2926 load0_Ed(prefices
, modrm
, sib
, displacement
);
2928 load0_Ew(prefices
, modrm
, sib
, displacement
);
2933 case 0xf41: //CMOVNO
2935 case 0xf43: //CMOVNC
2937 case 0xf45: //CMOVNZ
2938 case 0xf46: //CMOVBE
2939 case 0xf47: //CMOVNBE
2941 case 0xf49: //CMOVNS
2943 case 0xf4b: //CMOVNP
2945 case 0xf4d: //CMOVNL
2946 case 0xf4e: //CMOVLE
2947 case 0xf4f: //CMOVNLE
2948 if ((prefices
& PREFICES_OPERAND
) != 0) {
2950 load1_Ed(prefices
, modrm
, sib
, displacement
);
2953 load1_Ew(prefices
, modrm
, sib
, displacement
);
2957 case 0x8d: //LEA Gv, M
2958 load0_M(prefices
, modrm
, sib
, displacement
);
2962 case 0x80: //IMM G1 Eb, Ib
2963 case 0x82: //IMM G1 Eb, Ib
2964 case 0xc0: //SFT G2 Eb, Ib
2965 load0_Eb(prefices
, modrm
, sib
, displacement
);
2966 working
.write(LOAD1_IB
);
2967 working
.write((int)immediate
);
2970 case 0xc6: //MOV G11 Eb, Ib
2971 case 0xb0: //MOV AL, Ib
2972 case 0xb1: //MOV CL, Ib
2973 case 0xb2: //MOV DL, Ib
2974 case 0xb3: //MOV BL, Ib
2975 case 0xb4: //MOV AH, Ib
2976 case 0xb5: //MOV CH, Ib
2977 case 0xb6: //MOV DH, Ib
2978 case 0xb7: //MOV BH, Ib
2979 case 0xe4: //IN AL, Ib
2999 case 0xe0: //LOOPNZ Jb
3000 case 0xe1: //LOOPZ Jb
3001 case 0xe2: //LOOP Jb
3002 case 0xe3: //JCXZ Jb
3004 case 0xe5: //IN eAX, Ib
3005 working
.write(LOAD0_IB
);
3006 working
.write((int)immediate
);
3009 case 0x81: //IMM G1 Ev, Iv
3010 if ((prefices
& PREFICES_OPERAND
) != 0) {
3011 load0_Ed(prefices
, modrm
, sib
, displacement
);
3012 working
.write(LOAD1_ID
);
3013 working
.write((int)immediate
);
3015 load0_Ew(prefices
, modrm
, sib
, displacement
);
3016 working
.write(LOAD1_IW
);
3017 working
.write((int)immediate
);
3021 case 0xc7: //MOV G11 Ev, Iv
3022 case 0x68: //PUSH Iv
3023 case 0x6a: //PUSH Ib
3024 case 0xe8: //CALL Jv
3027 case 0xf81: //JNO Jv
3029 case 0xf83: //JNC Jv
3031 case 0xf85: //JNZ Jv
3032 case 0xf86: //JNA Jv
3035 case 0xf89: //JNS Jv
3037 case 0xf8b: //JNP Jv
3039 case 0xf8d: //JNL Jv
3040 case 0xf8e: //JNG Jv
3042 if ((prefices
& PREFICES_OPERAND
) != 0) {
3043 working
.write(LOAD0_ID
);
3044 working
.write((int)immediate
);
3046 working
.write(LOAD0_IW
);
3047 working
.write((int)immediate
);
3051 case 0xc1: //SFT G2 Ev, Ib
3052 if ((prefices
& PREFICES_OPERAND
) != 0) {
3053 load0_Ed(prefices
, modrm
, sib
, displacement
);
3054 working
.write(LOAD1_IB
);
3055 working
.write((int)immediate
);
3057 load0_Ew(prefices
, modrm
, sib
, displacement
);
3058 working
.write(LOAD1_IB
);
3059 working
.write((int)immediate
);
3063 case 0x83: //IMM G1 Ev, Ib sign extend the byte to 16/32 bits
3064 if ((prefices
& PREFICES_OPERAND
) != 0) {
3065 load0_Ed(prefices
, modrm
, sib
, displacement
);
3066 working
.write(LOAD1_ID
);
3067 working
.write((int)immediate
);
3069 load0_Ew(prefices
, modrm
, sib
, displacement
);
3070 working
.write(LOAD1_IW
);
3071 working
.write((int)immediate
);
3076 case 0x58: //POP eAX
3077 case 0x59: //POP eCX
3078 case 0x5a: //POP eDX
3079 case 0x5b: //POP eBX
3080 case 0x5c: //POP eSP
3081 case 0x5d: //POP eBP
3082 case 0x5e: //POP eSI
3083 case 0x5f: //POP eDI
3090 case 0xca: //RETF Iw
3091 working
.write(LOAD0_IW
);
3092 working
.write((int)immediate
);
3095 case 0x9a: //CALLF Ap
3096 case 0xea: //JMPF Ap
3097 if ((prefices
& PREFICES_OPERAND
) != 0) {
3098 working
.write(LOAD0_ID
);
3099 working
.write((int)immediate
);
3100 working
.write(LOAD1_IW
);
3101 working
.write((int)(immediate
>>> 32));
3103 working
.write(LOAD0_IW
);
3104 working
.write((int)(0xffff & immediate
));
3105 working
.write(LOAD1_IW
);
3106 working
.write((int)(immediate
>>> 16));
3111 switch (prefices
& PREFICES_OPERAND
) {
3113 working
.write(LOAD0_FLAGS
); break;
3114 case PREFICES_OPERAND
:
3115 working
.write(LOAD0_EFLAGS
); break;
3119 case 0xec: //IN AL, DX
3120 case 0xed: //IN eAX, DX
3121 working
.write(LOAD0_DX
);
3124 case 0xee: //OUT DX, AL
3125 working
.write(LOAD0_DX
);
3126 working
.write(LOAD1_AL
);
3129 case 0xef: //OUT DX, eAX
3130 if ((prefices
& PREFICES_OPERAND
) != 0) {
3131 working
.write(LOAD0_DX
);
3132 working
.write(LOAD1_EAX
);
3134 working
.write(LOAD0_DX
);
3135 working
.write(LOAD1_AX
);
3139 case 0x04: //ADD AL, Ib
3140 case 0x0c: //OR AL, Ib
3141 case 0x14: //ADC AL, Ib
3142 case 0x1c: //SBB AL, Ib
3143 case 0x24: //AND AL, Ib
3144 case 0x2c: //SUB AL, Ib
3145 case 0x34: //XOR AL, Ib
3146 case 0x3c: //CMP AL, Ib
3147 case 0xa8: //TEST AL, Ib
3148 working
.write(LOAD0_AL
);
3149 working
.write(LOAD1_IB
);
3150 working
.write((int)immediate
);
3153 case 0xc8: //ENTER Iw, Ib
3154 working
.write(LOAD0_IW
);
3155 working
.write((int)(0xffffl
& (immediate
>>> 16)));
3156 working
.write(LOAD1_IB
);
3157 working
.write((int)(0xffl
& immediate
));
3160 case 0x69: //IMUL Gv, Ev, Iv
3161 case 0x6b: //IMUL Gv, Ev, Ib
3162 if ((prefices
& PREFICES_OPERAND
) != 0) {
3163 load0_Ed(prefices
, modrm
, sib
, displacement
);
3164 working
.write(LOAD1_ID
);
3165 working
.write((int)immediate
);
3167 load0_Ew(prefices
, modrm
, sib
, displacement
);
3168 working
.write(LOAD1_IW
);
3169 working
.write((int)immediate
);
3173 case 0xe6: //OUT Ib, AL
3174 working
.write(LOAD0_IB
);
3175 working
.write((int)immediate
);
3176 working
.write(LOAD1_AL
);
3179 case 0x05: //ADD eAX, Iv
3180 case 0x0d: //OR eAX, Iv
3181 case 0x15: //ADC eAX, Iv
3182 case 0x1d: //SBB eAX, Iv
3183 case 0x25: //AND eAX, Iv
3184 case 0x2d: //SUB eAX, Iv
3185 case 0x35: //XOR eAX, Iv
3186 case 0x3d: //CMP eAX, Iv
3187 case 0xa9: //TEST eAX, Iv
3188 if ((prefices
& PREFICES_OPERAND
) != 0) {
3189 working
.write(LOAD0_EAX
);
3190 working
.write(LOAD1_ID
);
3191 working
.write((int)immediate
);
3193 working
.write(LOAD0_AX
);
3194 working
.write(LOAD1_IW
);
3195 working
.write((int)immediate
);
3199 case 0xb8: //MOV eAX, Iv
3200 case 0xb9: //MOV eCX, Iv
3201 case 0xba: //MOV eDX, Iv
3202 case 0xbb: //MOV eBX, Iv
3203 case 0xbc: //MOV eSP, Iv
3204 case 0xbd: //MOV eBP, Iv
3205 case 0xbe: //MOV eSI, Iv
3206 case 0xbf: //MOV eDI, Iv
3207 if ((prefices
& PREFICES_OPERAND
) != 0) {
3208 working
.write(LOAD0_ID
);
3209 working
.write((int)immediate
);
3211 working
.write(LOAD0_IW
);
3212 working
.write((int)immediate
);
3216 case 0xe7: //OUT Ib, eAX
3217 if ((prefices
& PREFICES_OPERAND
) != 0) {
3218 working
.write(LOAD0_IB
);
3219 working
.write((int)immediate
);
3220 working
.write(LOAD1_EAX
);
3222 working
.write(LOAD0_IB
);
3223 working
.write((int)immediate
);
3224 working
.write(LOAD1_AX
);
3228 case 0x40: //INC eAX
3229 case 0x48: //DEC eAX
3230 case 0x50: //PUSH eAX
3231 if ((prefices
& PREFICES_OPERAND
) != 0) {
3232 working
.write(LOAD0_EAX
);
3234 working
.write(LOAD0_AX
);
3238 case 0x41: //INC eCX
3239 case 0x49: //DEC eCX
3240 case 0x51: //PUSH eCX
3241 if ((prefices
& PREFICES_OPERAND
) != 0) {
3242 working
.write(LOAD0_ECX
);
3244 working
.write(LOAD0_CX
);
3248 case 0x42: //INC eDX
3249 case 0x4a: //DEC eDX
3250 case 0x52: //PUSH eDX
3251 if ((prefices
& PREFICES_OPERAND
) != 0) {
3252 working
.write(LOAD0_EDX
);
3254 working
.write(LOAD0_DX
);
3258 case 0x43: //INC eBX
3259 case 0x4b: //DEC eBX
3260 case 0x53: //PUSH eBX
3261 if ((prefices
& PREFICES_OPERAND
) != 0) {
3262 working
.write(LOAD0_EBX
);
3264 working
.write(LOAD0_BX
);
3268 case 0x44: //INC eSP
3269 case 0x4c: //DEC eSP
3270 case 0x54: //PUSH eSP
3271 if ((prefices
& PREFICES_OPERAND
) != 0) {
3272 working
.write(LOAD0_ESP
);
3274 working
.write(LOAD0_SP
);
3278 case 0x45: //INC eBP
3279 case 0x4d: //DEC eBP
3280 case 0x55: //PUSH eBP
3281 if ((prefices
& PREFICES_OPERAND
) != 0) {
3282 working
.write(LOAD0_EBP
);
3284 working
.write(LOAD0_BP
);
3288 case 0x46: //INC eSI
3289 case 0x4e: //DEC eSI
3290 case 0x56: //PUSH eSI
3291 if ((prefices
& PREFICES_OPERAND
) != 0) {
3292 working
.write(LOAD0_ESI
);
3294 working
.write(LOAD0_SI
);
3298 case 0x47: //INC eDI
3299 case 0x4f: //DEC eDI
3300 case 0x57: //PUSH eDI
3301 if ((prefices
& PREFICES_OPERAND
) != 0) {
3302 working
.write(LOAD0_EDI
);
3304 working
.write(LOAD0_DI
);
3308 case 0x91: //XCHG eAX, eCX
3309 if ((prefices
& PREFICES_OPERAND
) != 0) {
3310 working
.write(LOAD0_EAX
);
3311 working
.write(LOAD1_ECX
);
3313 working
.write(LOAD0_AX
);
3314 working
.write(LOAD1_CX
);
3318 case 0x92: //XCHG eAX, eDX
3319 if ((prefices
& PREFICES_OPERAND
) != 0) {
3320 working
.write(LOAD0_EAX
);
3321 working
.write(LOAD1_EDX
);
3323 working
.write(LOAD0_AX
);
3324 working
.write(LOAD1_DX
);
3328 case 0x93: //XCHG eAX, eBX
3329 if ((prefices
& PREFICES_OPERAND
) != 0) {
3330 working
.write(LOAD0_EAX
);
3331 working
.write(LOAD1_EBX
);
3333 working
.write(LOAD0_AX
);
3334 working
.write(LOAD1_BX
);
3338 case 0x94: //XCHG eAX, eSP
3339 if ((prefices
& PREFICES_OPERAND
) != 0) {
3340 working
.write(LOAD0_EAX
);
3341 working
.write(LOAD1_ESP
);
3343 working
.write(LOAD0_AX
);
3344 working
.write(LOAD1_SP
);
3348 case 0x95: //XCHG eAX, eBP
3349 if ((prefices
& PREFICES_OPERAND
) != 0) {
3350 working
.write(LOAD0_EAX
);
3351 working
.write(LOAD1_EBP
);
3353 working
.write(LOAD0_AX
);
3354 working
.write(LOAD1_BP
);
3358 case 0x96: //XCHG eAX, eSI
3359 if ((prefices
& PREFICES_OPERAND
) != 0) {
3360 working
.write(LOAD0_EAX
);
3361 working
.write(LOAD1_ESI
);
3363 working
.write(LOAD0_AX
);
3364 working
.write(LOAD1_SI
);
3368 case 0x97: //XCHG eAX, eDI
3369 if ((prefices
& PREFICES_OPERAND
) != 0) {
3370 working
.write(LOAD0_EAX
);
3371 working
.write(LOAD1_EDI
);
3373 working
.write(LOAD0_AX
);
3374 working
.write(LOAD1_DI
);
3378 case 0xd0: //SFT G2 Eb, 1
3379 load0_Eb(prefices
, modrm
, sib
, displacement
);
3380 working
.write(LOAD1_IB
);
3384 case 0xd2: //SFT G2 Eb, CL
3385 load0_Eb(prefices
, modrm
, sib
, displacement
);
3386 working
.write(LOAD1_CL
);
3389 case 0xd1: //SFT G2 Ev, 1
3390 if ((prefices
& PREFICES_OPERAND
) != 0) {
3391 load0_Ed(prefices
, modrm
, sib
, displacement
);
3392 working
.write(LOAD1_IB
);
3395 load0_Ew(prefices
, modrm
, sib
, displacement
);
3396 working
.write(LOAD1_IB
);
3401 case 0xd3: //SFT G2 Ev, CL
3402 if ((prefices
& PREFICES_OPERAND
) != 0) {
3403 load0_Ed(prefices
, modrm
, sib
, displacement
);
3404 working
.write(LOAD1_CL
);
3406 load0_Ew(prefices
, modrm
, sib
, displacement
);
3407 working
.write(LOAD1_CL
);
3411 case 0xf6: //UNA G3 Eb, ?
3412 switch (modrm
& 0x38) {
3413 case 0x00: //TEST Eb, Ib
3414 load0_Eb(prefices
, modrm
, sib
, displacement
);
3415 working
.write(LOAD1_IB
);
3416 working
.write((int)immediate
);
3420 load0_Eb(prefices
, modrm
, sib
, displacement
);
3424 load0_Eb(prefices
, modrm
, sib
, displacement
);
3428 load0_Eb(prefices
, modrm
, sib
, displacement
);
3433 case 0xf7: //UNA G3 Ev, ?
3434 if ((prefices
& PREFICES_OPERAND
) != 0) {
3435 switch (modrm
& 0x38) {
3436 case 0x00: //TEST Ed, Id
3437 load0_Ed(prefices
, modrm
, sib
, displacement
);
3438 working
.write(LOAD1_ID
);
3439 working
.write((int)immediate
);
3443 load0_Ed(prefices
, modrm
, sib
, displacement
);
3447 load0_Ed(prefices
, modrm
, sib
, displacement
);
3451 load0_Ed(prefices
, modrm
, sib
, displacement
);
3454 switch (modrm
& 0x38) {
3455 case 0x00: //TEST Ew, Iw
3456 load0_Ew(prefices
, modrm
, sib
, displacement
);
3457 working
.write(LOAD1_IW
);
3458 working
.write((int)immediate
);
3462 load0_Ew(prefices
, modrm
, sib
, displacement
);
3466 load0_Ew(prefices
, modrm
, sib
, displacement
);
3470 load0_Ew(prefices
, modrm
, sib
, displacement
);
3475 case 0xfe: //INC/DEC G4 Eb
3476 load0_Eb(prefices
, modrm
, sib
, displacement
);
3479 case 0x06: //PUSH ES
3480 working
.write(LOAD0_ES
);
3483 case 0x0e: //PUSH CS
3484 working
.write(LOAD0_CS
);
3487 case 0x16: //PUSH SS
3488 working
.write(LOAD0_SS
);
3491 case 0x1e: //PUSH DS
3492 working
.write(LOAD0_DS
);
3495 case 0x62: //BOUND Gv, Ma
3496 if ((prefices
& PREFICES_OPERAND
) != 0) {
3497 load0_Eq(prefices
, modrm
, sib
, displacement
);
3500 load0_Ed(prefices
, modrm
, sib
, displacement
);
3505 case 0x8c: //MOV Ew, Sw
3509 case 0x8e: //MOV Sw, Ew
3510 case 0xfb7: //MOV Gv, Ew
3511 case 0xfbf: //MOVSX Gv, Ew
3512 load0_Ew(prefices
, modrm
, sib
, displacement
);
3515 case 0xa0: //MOV AL, Ob
3516 load0_Ob(prefices
, displacement
);
3519 case 0xa2: //MOV Ob, AL
3520 working
.write(LOAD0_AL
);
3523 case 0xa1: //MOV eAX, Ov
3524 if ((prefices
& PREFICES_OPERAND
) != 0) {
3525 load0_Od(prefices
, displacement
);
3527 load0_Ow(prefices
, displacement
);
3531 case 0xa3: //MOV Ov, eAX
3532 if ((prefices
& PREFICES_OPERAND
) != 0) {
3533 working
.write(LOAD0_EAX
);
3535 working
.write(LOAD0_AX
);
3539 case 0x6c: //INS Yb, DX (prefices do not override segment)
3540 case 0x6d: //INS Yv, DX (prefices do not override segment)
3541 working
.write(LOAD0_DX
);
3544 case 0x6e: //OUTS DX, Xb
3545 case 0x6f: //OUTS DX, Xv
3546 working
.write(LOAD0_DX
);
3547 decodeSegmentPrefix(prefices
);
3550 case 0xa4: //MOVS Yb, Xb
3551 case 0xa5: //MOVS Yv, Xv
3552 case 0xa6: //CMPS Yb, Xb
3553 case 0xa7: //CMPS Xv, Yv
3554 case 0xac: //LODS AL, Xb
3555 case 0xad: //LODS eAX, Xv
3556 decodeSegmentPrefix(prefices
);
3559 case 0xaa: //STOS Yb, AL (prefices do not override segment)
3560 working
.write(LOAD0_AL
);
3563 case 0xab: //STOS Yv, eAX
3564 if ((prefices
& PREFICES_OPERAND
) != 0)
3565 working
.write(LOAD0_EAX
);
3567 working
.write(LOAD0_AX
);
3571 case 0xae: //SCAS AL, Yb (prefices do not override segment)
3572 working
.write(LOAD0_AL
);
3575 case 0xaf: //SCAS eAX, Yv
3576 if ((prefices
& PREFICES_OPERAND
) != 0)
3577 working
.write(LOAD0_EAX
);
3579 working
.write(LOAD0_AX
);
3582 case 0xff: //INC/DEC G5
3583 if ((prefices
& PREFICES_OPERAND
) != 0) {
3584 switch (modrm
& 0x38) {
3587 case 0x10: //CALLN Ed
3588 case 0x20: //JMPN Ed
3589 case 0x30: //PUSH Ed
3590 load0_Ed(prefices
, modrm
, sib
, displacement
);
3592 case 0x18: //CALLF Ep
3593 case 0x28: //JMPF Ep
3594 load0_Ed(prefices
, modrm
, sib
, displacement
);
3595 working
.write(ADDR_IB
);
3597 working
.write(LOAD1_MEM_WORD
);
3600 switch (modrm
& 0x38) {
3606 load0_Ew(prefices
, modrm
, sib
, displacement
);
3610 load0_Ew(prefices
, modrm
, sib
, displacement
);
3611 working
.write(ADDR_IB
);
3613 working
.write(LOAD1_MEM_WORD
);
3618 case 0xc4: //LES Gv, Mp
3619 case 0xc5: //LDS Gv, Mp
3620 case 0xfb2: //LSS Mp
3621 case 0xfb4: //LFS Mp
3622 case 0xfb5: //LGS Mp
3623 if ((prefices
& PREFICES_OPERAND
) != 0) {
3624 load0_Ed(prefices
, modrm
, sib
, displacement
);
3625 working
.write(ADDR_IB
);
3627 working
.write(LOAD1_MEM_WORD
);
3629 load0_Ew(prefices
, modrm
, sib
, displacement
);
3630 working
.write(ADDR_IB
);
3632 working
.write(LOAD1_MEM_WORD
);
3637 switch (prefices
& PREFICES_SG
) {
3638 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
3639 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
3640 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
3642 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
3643 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
3644 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
3647 if ((prefices
& PREFICES_ADDRESS
) != 0) {
3648 if (decodingAddressMode()) {
3649 working
.write(ADDR_EBX
);
3650 working
.write(ADDR_uAL
);
3653 if (decodingAddressMode()) {
3654 working
.write(ADDR_BX
);
3655 working
.write(ADDR_uAL
);
3656 working
.write(ADDR_MASK16
);
3659 working
.write(LOAD0_MEM_BYTE
);
3662 case 0xf00: // Group 6
3663 switch (modrm
& 0x38) {
3668 load0_Ew(prefices
, modrm
, sib
, displacement
); break;
3672 switch (modrm
& 0x38) {
3675 load0_Ew(prefices
, modrm
, sib
, displacement
);
3676 working
.write(ADDR_ID
);
3678 working
.write(LOAD1_MEM_DWORD
);
3680 case 0x30: load0_Ew(prefices
, modrm
, sib
, displacement
); break;
3681 case 0x38: decodeM(prefices
, modrm
, sib
, displacement
); break;
3684 case 0xf09: break; //WBINVD
3686 case 0xfa0: //PUSH FS
3687 working
.write(LOAD0_FS
); break;
3688 case 0xfa8: //PUSH GS
3689 working
.write(LOAD0_GS
); break;
3691 case 0xf20: load0_Cd(modrm
); break; //MOV Rd, Cd
3693 case 0xf21: load0_Dd(modrm
); break; //MOV Rd, Dd
3695 case 0xf22: //MOV Cd, Rd
3696 case 0xf23: load0_Rd(modrm
); break; //MOV Dd, Rd
3699 working
.write(LOAD0_ECX
);
3700 working
.write(LOAD1_EDX
);
3701 working
.write(LOAD2_EAX
);
3705 working
.write(LOAD0_ECX
);
3708 case 0xfa4: //SHLD Ev, Gv, Ib
3709 case 0xfac: //SHRD Ev, Gv, Ib
3710 if ((prefices
& PREFICES_OPERAND
) != 0) {
3711 load0_Ed(prefices
, modrm
, sib
, displacement
);
3713 working
.write(LOAD2_IB
);
3714 working
.write((int)immediate
);
3716 load0_Ew(prefices
, modrm
, sib
, displacement
);
3718 working
.write(LOAD2_IB
);
3719 working
.write((int)immediate
);
3722 case 0xfa5: //SHLD Ev, Gv, CL
3723 case 0xfad: //SHRD Ev, Gv, CL
3724 if ((prefices
& PREFICES_OPERAND
) != 0) {
3725 load0_Ed(prefices
, modrm
, sib
, displacement
);
3727 working
.write(LOAD2_CL
);
3729 load0_Ew(prefices
, modrm
, sib
, displacement
);
3731 working
.write(LOAD2_CL
);
3735 case 0xfb0: //CMPXCHG Eb, Gb
3736 load0_Eb(prefices
, modrm
, sib
, displacement
);
3738 working
.write(LOAD2_AL
);
3741 case 0xfb1: //CMPXCHG Ev, Gv
3742 if ((prefices
& PREFICES_OPERAND
) != 0) {
3743 load0_Ed(prefices
, modrm
, sib
, displacement
);
3745 working
.write(LOAD2_EAX
);
3747 load0_Ew(prefices
, modrm
, sib
, displacement
);
3749 working
.write(LOAD2_AX
);
3753 case 0xfa3: //BT Ev, Gv
3754 case 0xfab: //BTS Ev, Gv
3755 case 0xfb3: //BTR Ev, Gv
3756 case 0xfbb: //BTC Ev, Gv
3757 if ((prefices
& PREFICES_OPERAND
) != 0) {
3758 switch (modrm
& 0xc7) {
3759 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3761 case 0xc0: working
.write(LOAD0_EAX
); break;
3762 case 0xc1: working
.write(LOAD0_ECX
); break;
3763 case 0xc2: working
.write(LOAD0_EDX
); break;
3764 case 0xc3: working
.write(LOAD0_EBX
); break;
3765 case 0xc4: working
.write(LOAD0_ESP
); break;
3766 case 0xc5: working
.write(LOAD0_EBP
); break;
3767 case 0xc6: working
.write(LOAD0_ESI
); break;
3768 case 0xc7: working
.write(LOAD0_EDI
); break;
3772 switch (modrm
& 0xc7) {
3773 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3775 case 0xc0: working
.write(LOAD0_AX
); break;
3776 case 0xc1: working
.write(LOAD0_CX
); break;
3777 case 0xc2: working
.write(LOAD0_DX
); break;
3778 case 0xc3: working
.write(LOAD0_BX
); break;
3779 case 0xc4: working
.write(LOAD0_SP
); break;
3780 case 0xc5: working
.write(LOAD0_BP
); break;
3781 case 0xc6: working
.write(LOAD0_SI
); break;
3782 case 0xc7: working
.write(LOAD0_DI
); break;
3788 case 0xfba: //Grp 8 Ev, Ib
3789 if ((prefices
& PREFICES_OPERAND
) != 0) {
3790 switch (modrm
& 0xc7) {
3791 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3793 case 0xc0: working
.write(LOAD0_EAX
); break;
3794 case 0xc1: working
.write(LOAD0_ECX
); break;
3795 case 0xc2: working
.write(LOAD0_EDX
); break;
3796 case 0xc3: working
.write(LOAD0_EBX
); break;
3797 case 0xc4: working
.write(LOAD0_ESP
); break;
3798 case 0xc5: working
.write(LOAD0_EBP
); break;
3799 case 0xc6: working
.write(LOAD0_ESI
); break;
3800 case 0xc7: working
.write(LOAD0_EDI
); break;
3803 switch (modrm
& 0xc7) {
3804 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3806 case 0xc0: working
.write(LOAD0_AX
); break;
3807 case 0xc1: working
.write(LOAD0_CX
); break;
3808 case 0xc2: working
.write(LOAD0_DX
); break;
3809 case 0xc3: working
.write(LOAD0_BX
); break;
3810 case 0xc4: working
.write(LOAD0_SP
); break;
3811 case 0xc5: working
.write(LOAD0_BP
); break;
3812 case 0xc6: working
.write(LOAD0_SI
); break;
3813 case 0xc7: working
.write(LOAD0_DI
); break;
3816 working
.write(LOAD1_IB
);
3817 working
.write((int)immediate
& 0x1f);
3820 case 0xfc8: working
.write(LOAD0_EAX
); break; //BSWAP EAX
3821 case 0xfc9: working
.write(LOAD0_ECX
); break; //BSWAP ECX
3822 case 0xfca: working
.write(LOAD0_EDX
); break; //BSWAP EDX
3823 case 0xfcb: working
.write(LOAD0_EBX
); break; //BSWAP EBX
3824 case 0xfcc: working
.write(LOAD0_ESP
); break; //BSWAP ESP
3825 case 0xfcd: working
.write(LOAD0_EBP
); break; //BSWAP EBP
3826 case 0xfce: working
.write(LOAD0_ESI
); break; //BSWAP ESI
3827 case 0xfcf: working
.write(LOAD0_EDI
); break; //BSWAP EDI
3830 working
.write(FWAIT
);
3831 if ((modrm
& 0xc0) != 0xc0)
3833 switch (modrm
& 0x38)
3837 decodeM(prefices
, modrm
, sib
, displacement
);
3838 working
.write(FLOAD0_MEM_SINGLE
);
3839 working
.write(FLOAD1_ST0
);
3842 working
.write(FLOAD0_ST0
);
3843 decodeM(prefices
, modrm
, sib
, displacement
);
3844 working
.write(FLOAD1_MEM_SINGLE
);
3850 switch (modrm
& 0xf8)
3854 working
.write(FLOAD0_STN
);
3855 working
.write(modrm
& 0x07);
3856 working
.write(FLOAD1_ST0
);
3859 working
.write(FLOAD0_ST0
);
3860 working
.write(FLOAD1_STN
);
3861 working
.write(modrm
& 0x07);
3868 if ((modrm
& 0xc0) != 0xc0)
3870 switch (modrm
& 0x38)
3873 working
.write(FWAIT
);
3874 decodeM(prefices
, modrm
, sib
, displacement
);
3875 working
.write(FLOAD0_MEM_SINGLE
);
3879 working
.write(FWAIT
);
3880 working
.write(FLOAD0_ST0
); break;
3882 working
.write(FWAIT
);
3883 decodeM(prefices
, modrm
, sib
, displacement
);
3886 working
.write(FWAIT
);
3887 decodeM(prefices
, modrm
, sib
, displacement
);
3888 working
.write(LOAD0_MEM_WORD
);
3890 case 0x30: decodeM(prefices
, modrm
, sib
, displacement
); break;
3891 case 0x38: working
.write(LOAD0_FPUCW
); break;
3896 working
.write(FWAIT
);
3897 switch (modrm
& 0xf8)
3900 working
.write(FLOAD0_STN
);
3901 working
.write(modrm
& 0x07);
3904 working
.write(FLOAD0_ST0
);
3905 working
.write(FLOAD1_STN
);
3906 working
.write(modrm
& 0x07);
3924 case 0xff: working
.write(FLOAD0_ST0
); break;
3931 working
.write(FLOAD0_ST0
);
3932 working
.write(FLOAD1_STN
);
3936 working
.write(FLOAD0_ST0
);
3937 working
.write(FLOAD1_POS0
);
3939 case 0xe8: working
.write(FLOAD0_1
); break;
3940 case 0xe9: working
.write(FLOAD0_L2TEN
); break;
3941 case 0xea: working
.write(FLOAD0_L2E
); break;
3942 case 0xeb: working
.write(FLOAD0_PI
); break;
3943 case 0xec: working
.write(FLOAD0_LOG2
); break;
3944 case 0xed: working
.write(FLOAD0_LN2
); break;
3945 case 0xee: working
.write(FLOAD0_POS0
); break;
3951 working
.write(FWAIT
);
3952 if ((modrm
& 0xc0) != 0xc0)
3954 switch (modrm
& 0x38)
3958 decodeM(prefices
, modrm
, sib
, displacement
);
3959 working
.write(LOAD0_MEM_DWORD
);
3960 working
.write(FLOAD0_REG0
);
3961 working
.write(FLOAD1_ST0
);
3964 working
.write(FLOAD0_ST0
);
3965 decodeM(prefices
, modrm
, sib
, displacement
);
3966 working
.write(LOAD0_MEM_DWORD
);
3967 working
.write(FLOAD1_REG0
);
3973 switch (modrm
& 0xf8)
3979 working
.write(FLOAD0_STN
);
3980 working
.write(modrm
& 0x07);
3986 working
.write(FLOAD0_ST0
);
3987 working
.write(FLOAD1_STN
);
3995 if ((modrm
& 0xc0) != 0xc0)
3997 working
.write(FWAIT
);
3998 switch (modrm
& 0x38)
4001 decodeM(prefices
, modrm
, sib
, displacement
);
4002 working
.write(LOAD0_MEM_DWORD
);
4003 working
.write(FLOAD0_REG0
);
4008 case 0x38: working
.write(FLOAD0_ST0
); break;
4010 decodeM(prefices
, modrm
, sib
, displacement
);
4011 working
.write(FLOAD0_MEM_EXTENDED
);
4021 default: working
.write(FWAIT
); break;
4023 switch (modrm
& 0xf8)
4029 working
.write(FLOAD0_STN
);
4030 working
.write(modrm
& 0x07);
4034 working
.write(FLOAD0_ST0
);
4035 working
.write(FLOAD1_STN
);
4036 working
.write(modrm
& 0x07);
4043 working
.write(FWAIT
);
4044 if ((modrm
& 0xc0) != 0xc0)
4046 switch (modrm
& 0x38)
4050 decodeM(prefices
, modrm
, sib
, displacement
);
4051 working
.write(FLOAD0_MEM_DOUBLE
);
4052 working
.write(FLOAD1_ST0
);
4055 working
.write(FLOAD0_ST0
);
4056 decodeM(prefices
, modrm
, sib
, displacement
);
4057 working
.write(FLOAD1_MEM_DOUBLE
);
4063 switch (modrm
& 0xf8)
4067 working
.write(FLOAD0_STN
);
4068 working
.write(modrm
& 0x07);
4069 working
.write(FLOAD1_ST0
);
4072 working
.write(FLOAD0_ST0
);
4073 working
.write(FLOAD1_STN
);
4074 working
.write(modrm
& 0x07);
4081 if ((modrm
& 0xc0) != 0xc0)
4083 switch (modrm
& 0x38)
4086 working
.write(FWAIT
);
4087 decodeM(prefices
, modrm
, sib
, displacement
);
4088 working
.write(FLOAD0_MEM_DOUBLE
);
4093 working
.write(FWAIT
);
4094 working
.write(FLOAD0_ST0
);
4097 working
.write(FWAIT
);
4098 decodeM(prefices
, modrm
, sib
, displacement
);
4100 case 0x30: decodeM(prefices
, modrm
, sib
, displacement
); break;
4101 case 0x38: working
.write(LOAD0_FPUSW
); break;
4106 working
.write(FWAIT
);
4107 switch (modrm
& 0xf8)
4110 working
.write(LOAD0_ID
);
4111 working
.write(modrm
& 0x07);
4114 case 0xd8: working
.write(FLOAD0_ST0
); break;
4117 working
.write(FLOAD0_ST0
);
4118 working
.write(FLOAD1_STN
);
4119 working
.write(modrm
& 0x07);
4126 working
.write(FWAIT
);
4127 if ((modrm
& 0xc0) != 0xc0)
4129 switch (modrm
& 0x38)
4133 decodeM(prefices
, modrm
, sib
, displacement
);
4134 working
.write(LOAD0_MEM_WORD
);
4135 working
.write(FLOAD0_REG0
);
4136 working
.write(FLOAD1_ST0
);
4139 working
.write(FLOAD0_ST0
);
4140 decodeM(prefices
, modrm
, sib
, displacement
);
4141 working
.write(LOAD0_MEM_QWORD
);
4142 working
.write(FLOAD1_REG0L
);
4145 working
.write(FLOAD0_ST0
);
4146 decodeM(prefices
, modrm
, sib
, displacement
);
4147 working
.write(LOAD0_MEM_WORD
);
4148 working
.write(FLOAD1_REG0
);
4154 switch (modrm
& 0xf8) {
4159 working
.write(FLOAD0_ST0
);
4160 working
.write(FLOAD1_STN
);
4161 working
.write(modrm
& 0x07);
4165 working
.write(FLOAD1_ST0
);
4166 working
.write(FLOAD0_STN
);
4167 working
.write(modrm
& 0x07);
4173 working
.write(FLOAD0_ST0
);
4174 working
.write(FLOAD1_STN
);
4182 if ((modrm
& 0xc0) != 0xc0)
4184 working
.write(FWAIT
);
4185 switch (modrm
& 0x38)
4188 decodeM(prefices
, modrm
, sib
, displacement
);
4189 working
.write(LOAD0_MEM_WORD
);
4190 working
.write(FLOAD0_REG0
);
4193 decodeM(prefices
, modrm
, sib
, displacement
);
4194 working
.write(LOAD0_MEM_QWORD
);
4195 working
.write(FLOAD0_REG0L
);
4201 working
.write(FLOAD0_ST0
);
4204 working
.write(FLOAD0_ST0
);
4205 decodeM(prefices
, modrm
, sib
, displacement
);
4208 decodeM(prefices
, modrm
, sib
, displacement
);
4216 case 0xe0: working
.write(LOAD0_FPUSW
); break;
4217 default: working
.write(FWAIT
); break;
4219 switch (modrm
& 0xf8) {
4222 working
.write(FLOAD0_ST0
);
4223 working
.write(FLOAD1_STN
);
4224 working
.write(modrm
& 0x07);
4233 private void writeOutputOperands(int prefices
, int opcode
, int modrm
, int sib
, int displacement
)
4235 //Normal One Byte Operation
4237 case 0x00: //ADD Eb, Gb
4238 case 0x08: //OR Eb, Gb
4239 case 0x10: //ADC Eb, Gb
4240 case 0x18: //SBB Eb, Gb
4241 case 0x20: //AND Eb, Gb
4242 case 0x28: //SUB Eb, Gb
4243 case 0x30: //XOR Eb, Gb
4244 case 0x88: //MOV Eb, Gb
4245 case 0xc0: //SFT G2 Eb, Ib
4246 case 0xc6: //MOV G11 Eb, Ib
4247 case 0xfe: //INC/DEC G4 Eb
4255 case 0xf97: //SETNBE
4263 case 0xf9f: //SETNLE
4264 store0_Eb(prefices
, modrm
, sib
, displacement
);
4267 case 0xfb0: //CMPXCHG Eb, Gb
4268 working
.write(STORE1_AL
); //do store 1 first incase Eb is also AL/AX/EAX
4269 store0_Eb(prefices
, modrm
, sib
, displacement
);
4272 case 0x80: //IMM G1 Eb, Ib
4273 case 0x82: //IMM G1 Eb, Ib
4274 if ((modrm
& 0x38) == 0x38)
4276 store0_Eb(prefices
, modrm
, sib
, displacement
); break;
4278 case 0x86: //XCHG Eb, Gb
4280 store1_Eb(prefices
, modrm
, sib
, displacement
);
4283 case 0x02: //ADD Gb, Eb
4284 case 0x0a: //OR Gb, Eb
4285 case 0x12: //ADC Gb, Eb
4286 case 0x1a: //SBB Gb, Eb
4287 case 0x22: //AND Gb, Eb
4288 case 0x2a: //SUB Gb, Eb
4289 case 0x32: //XOR Gb, Eb
4290 case 0x8a: //MOV Gb, Eb
4294 case 0x01: //ADD Ev, Gv
4295 case 0x09: //OR Ev, Gv
4296 case 0x11: //ADC Ev, Gv
4297 case 0x19: //SBB Ev, Gv
4298 case 0x21: //AND Ev, Gv
4299 case 0x29: //SUB Ev, Gv
4300 case 0x31: //XOR Ev, Gv
4301 case 0x89: //MOV Ev, Gv
4302 case 0xc7: //MOV G11 Ev, Iv
4303 case 0xc1: //SFT G2 Ev, Ib
4305 case 0xd1: //SFT G2 Ev, 1
4306 case 0xd3: //SFT G2 Ev, CL
4307 if ((prefices
& PREFICES_OPERAND
) != 0) {
4308 store0_Ed(prefices
, modrm
, sib
, displacement
);
4310 store0_Ew(prefices
, modrm
, sib
, displacement
);
4314 case 0xfb1: //CMPXCHG Ev, Gv
4315 if ((prefices
& PREFICES_OPERAND
) != 0) {
4316 working
.write(STORE1_EAX
); //do store1 first incase Eb is same place
4317 store0_Ed(prefices
, modrm
, sib
, displacement
);
4319 working
.write(STORE1_AX
); //do store1 first incase Eb is same place
4320 store0_Ew(prefices
, modrm
, sib
, displacement
);
4324 case 0x81: //IMM G1 Ev, Iv
4325 case 0x83: //IMM G1 Ev, Ib
4326 if ((modrm
& 0x38) == 0x38)
4328 if ((prefices
& PREFICES_OPERAND
) != 0) {
4329 store0_Ed(prefices
, modrm
, sib
, displacement
);
4331 store0_Ew(prefices
, modrm
, sib
, displacement
);
4336 case 0x87: //XCHG Ev, Gv
4337 if ((prefices
& PREFICES_OPERAND
) != 0) {
4339 store1_Ed(prefices
, modrm
, sib
, displacement
);
4342 store1_Ew(prefices
, modrm
, sib
, displacement
);
4346 case 0x03: //ADD Gv, Ev
4347 case 0x0b: //OR Gv, Ev
4348 case 0x13: //ADC Gv, Ev
4349 case 0x1b: //SBB Gv, Ev
4350 case 0x23: //AND Gv, Ev
4351 case 0x2b: //SUB Gv, Ev
4352 case 0x33: //XOR Gv, Ev
4353 case 0x69: //IMUL Gv, Ev, Iv
4354 case 0x6b: //IMUL Gv, Ev, Ib
4355 case 0x8b: //MOV Gv, Ev
4356 case 0x8d: //LEA Gv, M
4358 case 0xf41: //CMOVNO
4360 case 0xf43: //CMOVNC
4362 case 0xf45: //CMOVNZ
4363 case 0xf46: //CMOVBE
4364 case 0xf47: //CMOVNBE
4366 case 0xf49: //CMOVNS
4368 case 0xf4b: //CMOVNP
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) {
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
);
4400 case 0xb1: //MOV CL, Ib
4401 working
.write(STORE0_CL
);
4404 case 0xb2: //MOV DL, Ib
4405 working
.write(STORE0_DL
);
4408 case 0xb3: //MOV BL, Ib
4409 working
.write(STORE0_BL
);
4412 case 0xb4: //MOV AH, Ib
4413 working
.write(STORE0_AH
);
4416 case 0xb5: //MOV CH, Ib
4417 working
.write(STORE0_CH
);
4420 case 0xb6: //MOV DH, Ib
4421 working
.write(STORE0_DH
);
4424 case 0xb7: //MOV BH, Ib
4425 working
.write(STORE0_BH
);
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
);
4446 working
.write(STORE0_AX
);
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
);
4457 working
.write(STORE0_CX
);
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
);
4468 working
.write(STORE0_DX
);
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
);
4479 working
.write(STORE0_BX
);
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
);
4490 working
.write(STORE0_SP
);
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
);
4501 working
.write(STORE0_BP
);
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
);
4512 working
.write(STORE0_SI
);
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
);
4523 working
.write(STORE0_DI
);
4528 case 0x91: //XCHG eAX, eCX
4529 if ((prefices
& PREFICES_OPERAND
) != 0) {
4530 working
.write(STORE0_ECX
);
4531 working
.write(STORE1_EAX
);
4533 working
.write(STORE0_CX
);
4534 working
.write(STORE1_AX
);
4538 case 0x92: //XCHG eAX, eDX
4539 if ((prefices
& PREFICES_OPERAND
) != 0) {
4540 working
.write(STORE0_EDX
);
4541 working
.write(STORE1_EAX
);
4543 working
.write(STORE0_DX
);
4544 working
.write(STORE1_AX
);
4548 case 0x93: //XCHG eAX, eBX
4549 if ((prefices
& PREFICES_OPERAND
) != 0) {
4550 working
.write(STORE0_EBX
);
4551 working
.write(STORE1_EAX
);
4553 working
.write(STORE0_BX
);
4554 working
.write(STORE1_AX
);
4558 case 0x94: //XCHG eAX, eSP
4559 if ((prefices
& PREFICES_OPERAND
) != 0) {
4560 working
.write(STORE0_ESP
);
4561 working
.write(STORE1_EAX
);
4563 working
.write(STORE0_SP
);
4564 working
.write(STORE1_AX
);
4568 case 0x95: //XCHG eAX, eBP
4569 if ((prefices
& PREFICES_OPERAND
) != 0) {
4570 working
.write(STORE0_EBP
);
4571 working
.write(STORE1_EAX
);
4573 working
.write(STORE0_BP
);
4574 working
.write(STORE1_AX
);
4578 case 0x96: //XCHG eAX, eSI
4579 if ((prefices
& PREFICES_OPERAND
) != 0) {
4580 working
.write(STORE0_ESI
);
4581 working
.write(STORE1_EAX
);
4583 working
.write(STORE0_SI
);
4584 working
.write(STORE1_AX
);
4588 case 0x97: //XCHG eAX, eDI
4589 if ((prefices
& PREFICES_OPERAND
) != 0) {
4590 working
.write(STORE0_EDI
);
4591 working
.write(STORE1_EAX
);
4593 working
.write(STORE0_DI
);
4594 working
.write(STORE1_AX
);
4599 switch (prefices
& PREFICES_OPERAND
) {
4601 working
.write(STORE0_FLAGS
); break;
4602 case PREFICES_OPERAND
:
4603 working
.write(STORE0_EFLAGS
); break;
4607 case 0xd0: //SFT G2 Eb, 1
4608 case 0xd2: //SFT G2 Eb, CL
4609 store0_Eb(prefices
, modrm
, sib
, displacement
);
4614 case 0xf6: //UNA G3 Eb, ?
4615 switch (modrm
& 0x38) {
4618 store0_Eb(prefices
, modrm
, sib
, displacement
);
4623 case 0xf7: //UNA G3 Ev, ?
4624 if ((prefices
& PREFICES_OPERAND
) != 0) {
4625 switch (modrm
& 0x38) {
4628 store0_Ed(prefices
, modrm
, sib
, displacement
);
4632 switch (modrm
& 0x38) {
4635 store0_Ew(prefices
, modrm
, sib
, displacement
);
4643 working
.write(STORE0_ES
);
4647 working
.write(STORE0_SS
);
4651 working
.write(STORE0_DS
);
4654 case 0x8c: //MOV Ew, Sw
4655 if ((prefices
& PREFICES_OPERAND
) != 0) {
4656 store0_Ed(prefices
, modrm
, sib
, displacement
);
4658 store0_Ew(prefices
, modrm
, sib
, displacement
);
4662 case 0x8e: //MOV Sw, Ew
4666 case 0xa0: //MOV AL, Ob
4667 working
.write(STORE0_AL
);
4670 case 0xa2: //MOV Ob, AL
4671 store0_Ob(prefices
, displacement
);
4674 case 0xa1: //MOV eAX, Ov
4675 if ((prefices
& PREFICES_OPERAND
) != 0) {
4676 working
.write(STORE0_EAX
);
4678 working
.write(STORE0_AX
);
4682 case 0xa3: //MOV Ov, eAX
4683 if ((prefices
& PREFICES_OPERAND
) != 0) {
4684 store0_Od(prefices
, displacement
);
4686 store0_Ow(prefices
, displacement
);
4690 case 0xff: //INC/DEC G5
4691 if ((prefices
& PREFICES_OPERAND
) != 0) {
4692 switch (modrm
& 0x38) {
4695 store0_Ed(prefices
, modrm
, sib
, displacement
);
4698 switch (modrm
& 0x38) {
4701 store0_Ew(prefices
, modrm
, sib
, displacement
);
4706 case 0xc4: //LES Gv, Mp
4707 if ((prefices
& PREFICES_OPERAND
) != 0) {
4709 working
.write(STORE1_ES
);
4712 working
.write(STORE1_ES
);
4716 case 0xc5: //LDS Gv, Mp
4717 if ((prefices
& PREFICES_OPERAND
) != 0) {
4719 working
.write(STORE1_DS
);
4722 working
.write(STORE1_DS
);
4726 case 0xf00: // Group 6
4727 switch (modrm
& 0x38) {
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;
4746 store0_Ew(prefices
, modrm
, sib
, displacement
);
4751 switch (modrm
& 0x38) {
4754 store0_Ew(prefices
, modrm
, sib
, displacement
);
4755 working
.write(ADDR_ID
);
4757 working
.write(STORE1_MEM_DWORD
);
4759 case 0x20: store0_Ew(prefices
, modrm
, sib
, displacement
); break;
4762 case 0xfa4: //SHLD Ev, Gv, Ib
4763 case 0xfa5: //SHLD Ev, Gv, CL
4764 case 0xfac: //SHRD Ev, Gv, Ib
4765 case 0xfad: //SHRD Ev, Gv, CL
4766 if ((prefices
& PREFICES_OPERAND
) != 0)
4767 store0_Ed(prefices
, modrm
, sib
, displacement
);
4769 store0_Ew(prefices
, modrm
, sib
, displacement
);
4772 case 0xfb2: //LSS Mp
4773 if ((prefices
& PREFICES_OPERAND
) != 0) {
4775 working
.write(STORE1_SS
);
4778 working
.write(STORE1_SS
);
4782 case 0xfb4: //LFS Mp
4783 if ((prefices
& PREFICES_OPERAND
) != 0) {
4785 working
.write(STORE1_FS
);
4788 working
.write(STORE1_FS
);
4792 case 0xfb5: //LGS Mp
4793 if ((prefices
& PREFICES_OPERAND
) != 0) {
4795 working
.write(STORE1_GS
);
4798 working
.write(STORE1_GS
);
4802 case 0xfc0: //XADD Eb, Gb
4803 store1_Gb(modrm
); //exchange first then add (so we write the result of the exchange first incase Eb and Gb are same reg)
4804 store0_Eb(prefices
, modrm
, sib
, displacement
);
4807 case 0xfc1: //XADD Eb, Gb
4808 if ((prefices
& PREFICES_OPERAND
) != 0) {
4809 store1_Gd(modrm
); //exchange first then add
4810 store0_Ed(prefices
, modrm
, sib
, displacement
);
4812 store1_Gw(modrm
); //exchange first then add
4813 store0_Ew(prefices
, modrm
, sib
, displacement
);
4819 working
.write(STORE0_AL
); break;
4821 case 0xf20: //MOV Rd, Cd
4822 case 0xf21: //MOV Rd, Dd
4823 store0_Rd(modrm
); break;
4825 case 0xf22: store0_Cd(modrm
); break; //MOV Cd, Rd
4826 case 0xf23: store0_Dd(modrm
); break; //MOV Dd, Rd
4830 working
.write(STORE0_EAX
);
4831 working
.write(STORE1_EDX
);
4834 case 0xfa1: //POP FS
4835 working
.write(STORE0_FS
); break;
4837 case 0xfa9: //POP GS
4838 working
.write(STORE0_GS
); break;
4840 case 0xfab: //BTS Ev, Gv
4841 case 0xfb3: //BTR Ev, Gv
4842 case 0xfbb: //BTC Ev, Gv
4843 if ((prefices
& PREFICES_OPERAND
) != 0) {
4844 if ((modrm
& 0xc0) == 0xc0)
4845 store0_Ed(prefices
, modrm
, sib
, displacement
);
4847 if ((modrm
& 0xc0) == 0xc0)
4848 store0_Ew(prefices
, modrm
, sib
, displacement
);
4852 case 0xfba: //Grp 8 Ev, Ib
4853 switch (modrm
& 0x38) {
4857 if ((prefices
& PREFICES_OPERAND
) != 0) {
4858 if ((modrm
& 0xc0) == 0xc0)
4859 store0_Ed(prefices
, modrm
, sib
, displacement
);
4861 if ((modrm
& 0xc0) == 0xc0)
4862 store0_Ew(prefices
, modrm
, sib
, displacement
);
4867 case 0xfc8: working
.write(STORE0_EAX
); break; //BSWAP EAX
4868 case 0xfc9: working
.write(STORE0_ECX
); break; //BSWAP ECX
4869 case 0xfca: working
.write(STORE0_EDX
); break; //BSWAP EDX
4870 case 0xfcb: working
.write(STORE0_EBX
); break; //BSWAP EBX
4871 case 0xfcc: working
.write(STORE0_ESP
); break; //BSWAP ESP
4872 case 0xfcd: working
.write(STORE0_EBP
); break; //BSWAP EBP
4873 case 0xfce: working
.write(STORE0_ESI
); break; //BSWAP ESI
4874 case 0xfcf: working
.write(STORE0_EDI
); break; //BSWAP EDI
4877 switch (modrm
& 0x38)
4885 working
.write(FSTORE0_ST0
);
4886 working
.write(FCHECK0
);
4889 case 0x18: working
.write(FPOP
); break;
4894 if ((modrm
& 0xc0) != 0xc0)
4896 switch (modrm
& 0x38)
4903 decodeM(prefices
, modrm
, sib
, displacement
);
4904 working
.write(FSTORE0_MEM_SINGLE
);
4907 decodeM(prefices
, modrm
, sib
, displacement
);
4908 working
.write(FSTORE0_MEM_SINGLE
);
4909 working
.write(FPOP
);
4911 case 0x28: working
.write(STORE0_FPUCW
); break;
4913 decodeM(prefices
, modrm
, sib
, displacement
);
4914 working
.write(STORE0_MEM_WORD
);
4920 switch (modrm
& 0xf8)
4924 working
.write(FSTORE0_STN
);
4925 working
.write(modrm
& 0x07);
4926 working
.write(FSTORE1_ST0
);
4946 case 0xff: working
.write(FSTORE0_ST0
); break;
4953 working
.write(FSTORE0_ST0
);
4954 working
.write(FCHECK0
);
4957 working
.write(FSTORE0_ST0
);
4958 working
.write(FLOAD0_1
);
4959 working
.write(FPUSH
);
4963 working
.write(FPOP
);
4964 working
.write(FSTORE0_ST0
);
4967 working
.write(FPOP
);
4968 working
.write(FSTORE0_ST0
);
4969 working
.write(FCHECK0
);
4972 working
.write(FSTORE1_ST0
);
4973 working
.write(FPUSH
);
4976 working
.write(FSTORE1_ST0
);
4977 working
.write(FPUSH
);
4978 working
.write(FCHECK0
);
4979 working
.write(FCHECK1
);
4986 if ((modrm
& 0xc0) != 0xc0)
4988 switch (modrm
& 0x38)
4996 working
.write(FSTORE0_ST0
);
4997 working
.write(FCHECK0
);
5000 case 0x18: working
.write(FPOP
); break;
5008 working
.write(FPOP
);
5009 working
.write(FPOP
);
5016 if ((modrm
& 0xc0) != 0xc0)
5018 switch (modrm
& 0x38)
5023 decodeM(prefices
, modrm
, sib
, displacement
);
5024 working
.write(STORE0_MEM_DWORD
);
5028 decodeM(prefices
, modrm
, sib
, displacement
);
5029 working
.write(STORE0_MEM_DWORD
);
5030 working
.write(FPOP
);
5033 decodeM(prefices
, modrm
, sib
, displacement
);
5034 working
.write(FSTORE0_MEM_EXTENDED
);
5035 working
.write(FPOP
);
5042 if ((modrm
& 0xc0) != 0xc0)
5044 switch (modrm
& 0x38)
5052 working
.write(FSTORE0_ST0
);
5053 working
.write(FCHECK0
);
5056 case 0x18: working
.write(FPOP
); break;
5061 switch (modrm
& 0xf8)
5069 working
.write(FSTORE0_STN
);
5070 working
.write(modrm
& 0x07);
5071 working
.write(FCHECK0
);
5078 if ((modrm
& 0xc0) != 0xc0)
5080 switch (modrm
& 0x38)
5086 decodeM(prefices
, modrm
, sib
, displacement
);
5087 working
.write(STORE0_MEM_QWORD
);
5088 working
.write(FPOP
);
5091 decodeM(prefices
, modrm
, sib
, displacement
);
5092 working
.write(FSTORE0_MEM_DOUBLE
);
5095 decodeM(prefices
, modrm
, sib
, displacement
);
5096 working
.write(FSTORE0_MEM_DOUBLE
);
5097 working
.write(FPOP
);
5100 decodeM(prefices
, modrm
, sib
, displacement
);
5101 working
.write(STORE0_MEM_WORD
);
5107 switch (modrm
& 0xf8)
5112 working
.write(FSTORE0_STN
);
5113 working
.write(modrm
& 0x07);
5116 working
.write(FSTORE0_STN
);
5117 working
.write(modrm
& 0x07);
5118 working
.write(FPOP
);
5120 case 0xe8: working
.write(FPOP
); break;
5126 if ((modrm
& 0xc0) != 0xc0)
5128 switch (modrm
& 0x38)
5136 working
.write(FSTORE0_ST0
);
5137 working
.write(FCHECK0
);
5140 case 0x18: working
.write(FPOP
); break;
5145 switch (modrm
& 0xf8)
5153 working
.write(FSTORE0_STN
);
5154 working
.write(modrm
& 0x07);
5155 working
.write(FPOP
);
5156 working
.write(FCHECK0
);
5164 working
.write(FPOP
);
5165 working
.write(FPOP
);
5172 if ((modrm
& 0xc0) != 0xc0)
5174 switch (modrm
& 0x38)
5182 decodeM(prefices
, modrm
, sib
, displacement
);
5183 working
.write(STORE0_MEM_WORD
);
5184 working
.write(FPOP
);
5187 decodeM(prefices
, modrm
, sib
, displacement
);
5188 working
.write(STORE0_MEM_WORD
);
5191 decodeM(prefices
, modrm
, sib
, displacement
);
5192 working
.write(STORE0_MEM_QWORD
);
5193 working
.write(FPOP
);
5199 switch (modrm
& 0xf8)
5202 case 0xf0: working
.write(FPOP
); break;
5206 case 0xe0: working
.write(STORE0_AX
); break;
5214 private static int operationHasImmediate(int prefices
, int opcode
, int modrm
)
5217 case 0x04: //ADD AL, Ib
5218 case 0x0c: //OR AL, Ib
5219 case 0x14: //ADC AL, Ib
5220 case 0x1c: //SBB AL, Ib
5221 case 0x24: //AND AL, Ib
5222 case 0x2c: //SUB AL, Ib
5223 case 0x34: //XOR AL, Ib
5224 case 0x3c: //CMP AL, Ib
5225 case 0x6a: //PUSH Ib
5226 case 0x6b: //IMUL Gv, Ev, Ib
5243 case 0x80: //IMM G1 Eb, Ib
5244 case 0x82: //IMM G1 Eb, Ib
5245 case 0x83: //IMM G1 Ev, Ib
5246 case 0xa8: //TEST AL, Ib
5247 case 0xb0: //MOV AL, Ib
5248 case 0xb1: //MOV CL, Ib
5249 case 0xb2: //MOV DL, Ib
5250 case 0xb3: //MOV BL, Ib
5251 case 0xb4: //MOV AH, Ib
5252 case 0xb5: //MOV CH, Ib
5253 case 0xb6: //MOV DH, Ib
5254 case 0xb7: //MOV BH, Ib
5255 case 0xc0: //SFT G2 Eb, Ib
5256 case 0xc1: //SFT G2 Ev, Ib
5257 case 0xc6: //MOV G11 Eb, Ib
5261 case 0xe0: //LOOPNZ Jb
5262 case 0xe1: //LOOPZ Jb
5263 case 0xe2: //LOOP Jb
5264 case 0xe3: //JCXZ Jb
5265 case 0xe4: //IN AL, Ib
5266 case 0xe5: //IN eAX, Ib
5267 case 0xe6: //OUT Ib, AL
5268 case 0xe7: //OUT Ib, eAX
5270 case 0xfa4: //SHLD Ev, Gv, Ib
5271 case 0xfac: //SHRD Ev, Gv, Ib
5272 case 0xfba: //Grp 8 Ev, Ib
5276 case 0xca: //RETF Iw
5279 case 0xc8: //ENTER Iw, Ib
5282 case 0x05: //ADD eAX, Iv
5283 case 0x0d: //OR eAX, Iv
5284 case 0x15: //ADC eAX, Iv
5285 case 0x1d: //SBB eAX, Iv
5286 case 0x25: //AND eAX, Iv
5287 case 0x2d: //SUB eAX, Iv
5288 case 0x35: //XOR eAX, Iv
5289 case 0x3d: //CMP eAX, Iv
5290 case 0x68: //PUSH Iv
5291 case 0x69: //IMUL Gv, Ev, Iv
5292 case 0x81: //IMM G1 Ev, Iv
5293 case 0xa9: //TEST eAX, Iv
5294 case 0xb8: //MOV eAX, Iv
5295 case 0xb9: //MOV eCX, Iv
5296 case 0xba: //MOV eDX, Iv
5297 case 0xbb: //MOV eBX, Iv
5298 case 0xbc: //MOV eSP, Iv
5299 case 0xbd: //MOV eBP, Iv
5300 case 0xbe: //MOV eSI, Iv
5301 case 0xbf: //MOV eDI, Iv
5302 case 0xc7: //MOV G11 Ev, Iv
5303 case 0xe8: //CALL Jv
5306 case 0xf81: //JNO Jv
5308 case 0xf83: //JNC Jv
5310 case 0xf85: //JNZ Jv
5311 case 0xf86: //JNA Jv
5314 case 0xf89: //JNS Jv
5316 case 0xf8b: //JNP Jv
5318 case 0xf8d: //JNL Jv
5319 case 0xf8e: //JNG Jv
5321 if ((prefices
& PREFICES_OPERAND
) != 0)
5326 case 0x9a: //CALLF Ap
5327 case 0xea: //JMPF Ap
5328 if ((prefices
& PREFICES_OPERAND
) != 0)
5333 case 0xf6: //UNA G3 Eb, ?
5334 switch (modrm
& 0x38) {
5335 case 0x00: //TEST Eb, Ib
5341 case 0xf7: //UNA G3 Ev, ?
5342 switch (modrm
& 0x38) {
5343 case 0x00: //TEST Ev, Iv
5344 if ((prefices
& PREFICES_OPERAND
) != 0)
5355 private static int operationHasDisplacement(int prefices
, int opcode
, int modrm
, int sib
)
5359 case 0x00: //ADD Eb, Gb
5360 case 0x01: //ADD Ev, Gv
5361 case 0x02: //ADD Gb, Eb
5362 case 0x03: //ADD Gv, Ev
5363 case 0x08: //OR Eb, Gb
5364 case 0x09: //OR Ev, Gv
5365 case 0x0a: //OR Gb, Eb
5366 case 0x0b: //OR Gv, Ev
5367 case 0x10: //ADC Eb, Gb
5368 case 0x11: //ADC Ev, Gv
5369 case 0x12: //ADC Gb, Eb
5370 case 0x13: //ADC Gv, Ev
5371 case 0x18: //SBB Eb, Gb
5372 case 0x19: //SBB Ev, Gv
5373 case 0x1a: //SBB Gb, Eb
5374 case 0x1b: //SBB Gv, Ev
5375 case 0x20: //AND Eb, Gb
5376 case 0x21: //AND Ev, Gv
5377 case 0x22: //AND Gb, Eb
5378 case 0x23: //AND Gv, Ev
5379 case 0x28: //SUB Eb, Gb
5380 case 0x29: //SUB Ev, Gv
5381 case 0x2a: //SUB Gb, Eb
5382 case 0x2b: //SUB Gv, Ev
5383 case 0x30: //XOR Eb, Gb
5384 case 0x31: //XOR Ev, Gv
5385 case 0x32: //XOR Gb, Eb
5386 case 0x33: //XOR Gv, Ev
5387 case 0x38: //CMP Eb, Gb
5388 case 0x39: //CMP Ev, Gv
5389 case 0x3a: //CMP Gb, Eb
5390 case 0x3b: //CMP Gv, Ev
5391 case 0x62: //BOUND Gv, Ma
5392 case 0x69: //IMUL Gv, Ev, Iv
5393 case 0x6b: //IMUL Gv, Ev, Ib
5394 case 0x80: //IMM G1 Eb, Ib
5395 case 0x81: //IMM G1 Ev, Iv
5396 case 0x82: //IMM G1 Eb, Ib
5397 case 0x83: //IMM G1 Ev, Ib
5398 case 0x84: //TEST Eb, Gb
5399 case 0x85: //TEST Ev, Gv
5400 case 0x86: //XCHG Eb, Gb
5401 case 0x87: //XCHG Ev, Gv
5402 case 0x88: //MOV Eb, Gb
5403 case 0x89: //MOV Ev, Gv
5404 case 0x8a: //MOV Gb, Eb
5405 case 0x8b: //MOV Gv, Ev
5406 case 0x8c: //MOV Ew, Sw
5407 case 0x8d: //LEA Gv, M
5408 case 0x8e: //MOV Sw, Ew
5410 case 0xc0: //SFT G2 Eb, Ib
5411 case 0xc1: //SFT G2 Ev, Ib
5412 case 0xc4: //LES Gv, Mp
5413 case 0xc5: //LDS Gv, Mp
5414 case 0xc6: //MOV G11 Eb, Ib
5415 case 0xc7: //MOV G11 Ev, Iv
5416 case 0xd0: //SFT G2 Eb, 1
5417 case 0xd1: //SFT G2 Ev, 1
5418 case 0xd2: //SFT G2 Eb, CL
5419 case 0xd3: //SFT G2 Ev, CL
5420 case 0xf6: //UNA G3 Eb, ?
5421 case 0xf7: //UNA G3 Ev, ?
5422 case 0xfe: //INC/DEC G4 Eb
5423 case 0xff: //INC/DEC G5
5428 case 0xf20: //MOV Rd, Cd
5429 case 0xf22: //MOV Cd, Rd
5432 case 0xf41: //CMOVNO
5434 case 0xf43: //CMOVNC
5436 case 0xf45: //CMOVNZ
5437 case 0xf46: //CMOVBE
5438 case 0xf47: //CMOVNBE
5440 case 0xf49: //CMOVNS
5442 case 0xf4b: //CMOVNP
5444 case 0xf4d: //CMOVNL
5445 case 0xf4e: //CMOVLE
5446 case 0xf4f: //CMOVNLE
5455 case 0xf97: //SETNBE
5463 case 0xf9f: //SETNLE
5465 case 0xfa3: //BT Ev, Gv
5466 case 0xfa4: //SHLD Ev, Gv, Ib
5467 case 0xfa5: //SHLD Ev, Gv, CL
5468 case 0xfab: //BTS Ev, Gv
5469 case 0xfac: //SHRD Ev, Gv, Ib
5470 case 0xfad: //SHRD Ev, Gv, CL
5472 case 0xfaf: //IMUL Gv, Ev
5474 case 0xfb0: //CMPXCHG Eb, Gb
5475 case 0xfb1: //CMPXCHG Ev, Gv
5476 case 0xfb2: //LSS Mp
5477 case 0xfb3: //BTR Ev, Gv
5478 case 0xfb4: //LFS Mp
5479 case 0xfb5: //LGS Mp
5480 case 0xfb6: //MOVZX Gv, Eb
5481 case 0xfb7: //MOVZX Gv, Ew
5483 case 0xfba: //Grp 8 Ev, Ib
5484 case 0xfbb: //BTC Ev, Gv
5485 case 0xfbc: //BSF Gv, Ev
5486 case 0xfbd: //BSR Gv, Ev
5487 case 0xfbe: //MOVSX Gv, Eb
5488 case 0xfbf: //MOVSX Gv, Ew
5489 case 0xfc0: //XADD Eb, Gb
5490 case 0xfc1: //XADD Ev, Gv
5491 return modrmHasDisplacement(prefices
, modrm
, sib
);
5502 if ((modrm
& 0xc0) != 0xc0)
5503 return modrmHasDisplacement(prefices
, modrm
, sib
);
5508 case 0xa0: //MOV AL, Ob
5509 case 0xa2: //MOV Ob, AL
5510 case 0xa1: //MOV eAX, Ov
5511 case 0xa3: //MOV Ov, eAX
5512 if ((prefices
& PREFICES_ADDRESS
) != 0)
5522 private static int modrmHasDisplacement(int prefices
, int modrm
, int sib
)
5524 if ((prefices
& PREFICES_ADDRESS
) != 0) {
5525 //32 bit address size
5526 switch(modrm
& 0xc0) {
5528 switch (modrm
& 0x7) {
5530 if ((sib
& 0x7) == 0x5)
5537 case 0x40: return 1; //IB
5538 case 0x80: return 4; //ID
5541 //16 bit address size
5542 switch(modrm
& 0xc0) {
5544 if ((modrm
& 0x7) == 0x6)
5548 case 0x40: return 1; //IB
5549 case 0x80: return 2; //IW
5556 public static boolean isFarJump(int opcode
, int modrm
)
5560 case 0x9a: //CALLF Ap
5561 case 0xca: //RETF Iw
5567 case 0xea: //JMPF Ap
5572 switch (modrm
& 0x38) {
5573 case 0x18: //CALLF Ep
5574 case 0x28: //JMPF Ep
5576 default: return false;
5584 public static boolean isNearJump(int opcode
, int modrm
)
5606 case 0xe0: //LOOPNZ Jb
5607 case 0xe1: //LOOPZ Jb
5608 case 0xe2: //LOOP Jb
5609 case 0xe3: //JCXZ Jb
5610 case 0xe8: //CALL Jv
5616 switch (modrm
& 0x38) {
5617 case 0x10: //CALLN Ed
5618 case 0x20: //JMPN Ed
5620 default: return false;
5623 case 0x0f80: //Jcc Jv
5645 public static boolean isModeSwitch(int opcode
, int modrm
)
5648 case 0x0f22: //MOV Cd, Ed
5651 return ((modrm
& 0x38) == 0x30);
5657 public static boolean isBlockTerminating(int opcode
, int modrm
)
5668 public static boolean isJump(int opcode
, int modrm
)
5670 return isNearJump(opcode
, modrm
) || isFarJump(opcode
, modrm
) || isModeSwitch(opcode
, modrm
) || isBlockTerminating(opcode
, modrm
);
5673 private void store0_Cd(int modrm
)
5675 switch(modrm
& 0x38) {
5676 case 0x00: working
.write(STORE0_CR0
); break;
5677 case 0x10: working
.write(STORE0_CR2
); break;
5678 case 0x18: working
.write(STORE0_CR3
); break;
5679 case 0x20: working
.write(STORE0_CR4
); break;
5680 default: throw new IllegalStateException("Unknown Control Register Operand");
5684 private void load0_Cd(int modrm
)
5686 switch(modrm
& 0x38) {
5687 case 0x00: working
.write(LOAD0_CR0
); break;
5688 case 0x10: working
.write(LOAD0_CR2
); break;
5689 case 0x18: working
.write(LOAD0_CR3
); break;
5690 case 0x20: working
.write(LOAD0_CR4
); break;
5691 default: throw new IllegalStateException("Unknown Control Register Operand "+ modrm
);
5695 private void store0_Dd(int modrm
)
5697 switch(modrm
& 0x38) {
5698 case 0x00: working
.write(STORE0_DR0
); break;
5699 case 0x08: working
.write(STORE0_DR1
); break;
5700 case 0x10: working
.write(STORE0_DR2
); break;
5701 case 0x18: working
.write(STORE0_DR3
); break;
5702 case 0x30: working
.write(STORE0_DR6
); break;
5703 case 0x38: working
.write(STORE0_DR7
); break;
5704 default: throw new IllegalStateException("Unknown Debug Register Operand");
5708 private void load0_Dd(int modrm
)
5710 switch(modrm
& 0x38) {
5711 case 0x00: working
.write(LOAD0_DR0
); break;
5712 case 0x08: working
.write(LOAD0_DR1
); break;
5713 case 0x10: working
.write(LOAD0_DR2
); break;
5714 case 0x18: working
.write(LOAD0_DR3
); break;
5715 case 0x30: working
.write(LOAD0_DR6
); break;
5716 case 0x38: working
.write(LOAD0_DR7
); break;
5717 default: throw new IllegalStateException("Unknown Debug Register Operand");
5721 private void load0_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5723 switch(modrm
& 0xc7) {
5724 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_BYTE
); break;
5726 case 0xc0: working
.write(LOAD0_AL
); break;
5727 case 0xc1: working
.write(LOAD0_CL
); break;
5728 case 0xc2: working
.write(LOAD0_DL
); break;
5729 case 0xc3: working
.write(LOAD0_BL
); break;
5730 case 0xc4: working
.write(LOAD0_AH
); break;
5731 case 0xc5: working
.write(LOAD0_CH
); break;
5732 case 0xc6: working
.write(LOAD0_DH
); break;
5733 case 0xc7: working
.write(LOAD0_BH
); break;
5736 private void load1_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5738 switch(modrm
& 0xc7) {
5739 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_BYTE
); break;
5741 case 0xc0: working
.write(LOAD1_AL
); break;
5742 case 0xc1: working
.write(LOAD1_CL
); break;
5743 case 0xc2: working
.write(LOAD1_DL
); break;
5744 case 0xc3: working
.write(LOAD1_BL
); break;
5745 case 0xc4: working
.write(LOAD1_AH
); break;
5746 case 0xc5: working
.write(LOAD1_CH
); break;
5747 case 0xc6: working
.write(LOAD1_DH
); break;
5748 case 0xc7: working
.write(LOAD1_BH
); break;
5751 private void store0_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5753 switch(modrm
& 0xc7) {
5754 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_BYTE
); break;
5756 case 0xc0: working
.write(STORE0_AL
); break;
5757 case 0xc1: working
.write(STORE0_CL
); break;
5758 case 0xc2: working
.write(STORE0_DL
); break;
5759 case 0xc3: working
.write(STORE0_BL
); break;
5760 case 0xc4: working
.write(STORE0_AH
); break;
5761 case 0xc5: working
.write(STORE0_CH
); break;
5762 case 0xc6: working
.write(STORE0_DH
); break;
5763 case 0xc7: working
.write(STORE0_BH
); break;
5766 private void store1_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5768 switch(modrm
& 0xc7) {
5769 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_BYTE
); break;
5771 case 0xc0: working
.write(STORE1_AL
); break;
5772 case 0xc1: working
.write(STORE1_CL
); break;
5773 case 0xc2: working
.write(STORE1_DL
); break;
5774 case 0xc3: working
.write(STORE1_BL
); break;
5775 case 0xc4: working
.write(STORE1_AH
); break;
5776 case 0xc5: working
.write(STORE1_CH
); break;
5777 case 0xc6: working
.write(STORE1_DH
); break;
5778 case 0xc7: working
.write(STORE1_BH
); break;
5782 private void load0_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5784 switch (modrm
& 0xc7) {
5785 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_WORD
); break;
5787 case 0xc0: working
.write(LOAD0_AX
); break;
5788 case 0xc1: working
.write(LOAD0_CX
); break;
5789 case 0xc2: working
.write(LOAD0_DX
); break;
5790 case 0xc3: working
.write(LOAD0_BX
); break;
5791 case 0xc4: working
.write(LOAD0_SP
); break;
5792 case 0xc5: working
.write(LOAD0_BP
); break;
5793 case 0xc6: working
.write(LOAD0_SI
); break;
5794 case 0xc7: working
.write(LOAD0_DI
); break;
5797 private void store0_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5799 switch (modrm
& 0xc7) {
5800 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_WORD
); break;
5802 case 0xc0: working
.write(STORE0_AX
); break;
5803 case 0xc1: working
.write(STORE0_CX
); break;
5804 case 0xc2: working
.write(STORE0_DX
); break;
5805 case 0xc3: working
.write(STORE0_BX
); break;
5806 case 0xc4: working
.write(STORE0_SP
); break;
5807 case 0xc5: working
.write(STORE0_BP
); break;
5808 case 0xc6: working
.write(STORE0_SI
); break;
5809 case 0xc7: working
.write(STORE0_DI
); break;
5812 private void load1_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5814 switch (modrm
& 0xc7) {
5815 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_WORD
); break;
5817 case 0xc0: working
.write(LOAD1_AX
); break;
5818 case 0xc1: working
.write(LOAD1_CX
); break;
5819 case 0xc2: working
.write(LOAD1_DX
); break;
5820 case 0xc3: working
.write(LOAD1_BX
); break;
5821 case 0xc4: working
.write(LOAD1_SP
); break;
5822 case 0xc5: working
.write(LOAD1_BP
); break;
5823 case 0xc6: working
.write(LOAD1_SI
); break;
5824 case 0xc7: working
.write(LOAD1_DI
); break;
5827 private void store1_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5829 switch (modrm
& 0xc7) {
5830 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_WORD
); break;
5832 case 0xc0: working
.write(STORE1_AX
); break;
5833 case 0xc1: working
.write(STORE1_CX
); break;
5834 case 0xc2: working
.write(STORE1_DX
); break;
5835 case 0xc3: working
.write(STORE1_BX
); break;
5836 case 0xc4: working
.write(STORE1_SP
); break;
5837 case 0xc5: working
.write(STORE1_BP
); break;
5838 case 0xc6: working
.write(STORE1_SI
); break;
5839 case 0xc7: working
.write(STORE1_DI
); break;
5843 private void load0_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5845 switch (modrm
& 0xc7) {
5846 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_DWORD
); break;
5848 case 0xc0: working
.write(LOAD0_EAX
); break;
5849 case 0xc1: working
.write(LOAD0_ECX
); break;
5850 case 0xc2: working
.write(LOAD0_EDX
); break;
5851 case 0xc3: working
.write(LOAD0_EBX
); break;
5852 case 0xc4: working
.write(LOAD0_ESP
); break;
5853 case 0xc5: working
.write(LOAD0_EBP
); break;
5854 case 0xc6: working
.write(LOAD0_ESI
); break;
5855 case 0xc7: working
.write(LOAD0_EDI
); break;
5859 private void store0_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5861 switch (modrm
& 0xc7) {
5862 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_DWORD
); break;
5864 case 0xc0: working
.write(STORE0_EAX
); break;
5865 case 0xc1: working
.write(STORE0_ECX
); break;
5866 case 0xc2: working
.write(STORE0_EDX
); break;
5867 case 0xc3: working
.write(STORE0_EBX
); break;
5868 case 0xc4: working
.write(STORE0_ESP
); break;
5869 case 0xc5: working
.write(STORE0_EBP
); break;
5870 case 0xc6: working
.write(STORE0_ESI
); break;
5871 case 0xc7: working
.write(STORE0_EDI
); break;
5874 private void load1_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5876 switch (modrm
& 0xc7) {
5877 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_DWORD
); break;
5879 case 0xc0: working
.write(LOAD1_EAX
); break;
5880 case 0xc1: working
.write(LOAD1_ECX
); break;
5881 case 0xc2: working
.write(LOAD1_EDX
); break;
5882 case 0xc3: working
.write(LOAD1_EBX
); break;
5883 case 0xc4: working
.write(LOAD1_ESP
); break;
5884 case 0xc5: working
.write(LOAD1_EBP
); break;
5885 case 0xc6: working
.write(LOAD1_ESI
); break;
5886 case 0xc7: working
.write(LOAD1_EDI
); break;
5890 private void store1_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5892 switch (modrm
& 0xc7) {
5893 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_DWORD
); break;
5895 case 0xc0: working
.write(STORE1_EAX
); break;
5896 case 0xc1: working
.write(STORE1_ECX
); break;
5897 case 0xc2: working
.write(STORE1_EDX
); break;
5898 case 0xc3: working
.write(STORE1_EBX
); break;
5899 case 0xc4: working
.write(STORE1_ESP
); break;
5900 case 0xc5: working
.write(STORE1_EBP
); break;
5901 case 0xc6: working
.write(STORE1_ESI
); break;
5902 case 0xc7: working
.write(STORE1_EDI
); break;
5906 private void load0_Eq(int prefices
, int modrm
, int sib
, int displacement
)
5908 switch (modrm
& 0xc7) {
5909 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_QWORD
); break;
5918 throw new IllegalStateException("There are no 64bit GP Registers");
5922 private void load0_Gb(int modrm
)
5924 switch(modrm
& 0x38) {
5925 case 0x00: working
.write(LOAD0_AL
); break;
5926 case 0x08: working
.write(LOAD0_CL
); break;
5927 case 0x10: working
.write(LOAD0_DL
); break;
5928 case 0x18: working
.write(LOAD0_BL
); break;
5929 case 0x20: working
.write(LOAD0_AH
); break;
5930 case 0x28: working
.write(LOAD0_CH
); break;
5931 case 0x30: working
.write(LOAD0_DH
); break;
5932 case 0x38: working
.write(LOAD0_BH
); break;
5933 default: throw new IllegalStateException("Unknown Byte Register Operand");
5936 private void store0_Gb(int modrm
)
5938 switch(modrm
& 0x38) {
5939 case 0x00: working
.write(STORE0_AL
); break;
5940 case 0x08: working
.write(STORE0_CL
); break;
5941 case 0x10: working
.write(STORE0_DL
); break;
5942 case 0x18: working
.write(STORE0_BL
); break;
5943 case 0x20: working
.write(STORE0_AH
); break;
5944 case 0x28: working
.write(STORE0_CH
); break;
5945 case 0x30: working
.write(STORE0_DH
); break;
5946 case 0x38: working
.write(STORE0_BH
); break;
5947 default: throw new IllegalStateException("Unknown Byte Register Operand");
5950 private void load1_Gb(int modrm
)
5952 switch(modrm
& 0x38) {
5953 case 0x00: working
.write(LOAD1_AL
); break;
5954 case 0x08: working
.write(LOAD1_CL
); break;
5955 case 0x10: working
.write(LOAD1_DL
); break;
5956 case 0x18: working
.write(LOAD1_BL
); break;
5957 case 0x20: working
.write(LOAD1_AH
); break;
5958 case 0x28: working
.write(LOAD1_CH
); break;
5959 case 0x30: working
.write(LOAD1_DH
); break;
5960 case 0x38: working
.write(LOAD1_BH
); break;
5961 default: throw new IllegalStateException("Unknown Byte Register Operand");
5964 private void store1_Gb(int modrm
)
5966 switch(modrm
& 0x38) {
5967 case 0x00: working
.write(STORE1_AL
); break;
5968 case 0x08: working
.write(STORE1_CL
); break;
5969 case 0x10: working
.write(STORE1_DL
); break;
5970 case 0x18: working
.write(STORE1_BL
); break;
5971 case 0x20: working
.write(STORE1_AH
); break;
5972 case 0x28: working
.write(STORE1_CH
); break;
5973 case 0x30: working
.write(STORE1_DH
); break;
5974 case 0x38: working
.write(STORE1_BH
); break;
5975 default: throw new IllegalStateException("Unknown Byte Register Operand");
5979 private void load0_Gw(int modrm
)
5981 switch(modrm
& 0x38) {
5982 case 0x00: working
.write(LOAD0_AX
); break;
5983 case 0x08: working
.write(LOAD0_CX
); break;
5984 case 0x10: working
.write(LOAD0_DX
); break;
5985 case 0x18: working
.write(LOAD0_BX
); break;
5986 case 0x20: working
.write(LOAD0_SP
); break;
5987 case 0x28: working
.write(LOAD0_BP
); break;
5988 case 0x30: working
.write(LOAD0_SI
); break;
5989 case 0x38: working
.write(LOAD0_DI
); break;
5990 default: throw new IllegalStateException("Unknown Word Register Operand");
5993 private void store0_Gw(int modrm
)
5995 switch(modrm
& 0x38) {
5996 case 0x00: working
.write(STORE0_AX
); break;
5997 case 0x08: working
.write(STORE0_CX
); break;
5998 case 0x10: working
.write(STORE0_DX
); break;
5999 case 0x18: working
.write(STORE0_BX
); break;
6000 case 0x20: working
.write(STORE0_SP
); break;
6001 case 0x28: working
.write(STORE0_BP
); break;
6002 case 0x30: working
.write(STORE0_SI
); break;
6003 case 0x38: working
.write(STORE0_DI
); break;
6004 default: throw new IllegalStateException("Unknown Word Register Operand");
6007 private void load1_Gw(int modrm
)
6009 switch(modrm
& 0x38) {
6010 case 0x00: working
.write(LOAD1_AX
); break;
6011 case 0x08: working
.write(LOAD1_CX
); break;
6012 case 0x10: working
.write(LOAD1_DX
); break;
6013 case 0x18: working
.write(LOAD1_BX
); break;
6014 case 0x20: working
.write(LOAD1_SP
); break;
6015 case 0x28: working
.write(LOAD1_BP
); break;
6016 case 0x30: working
.write(LOAD1_SI
); break;
6017 case 0x38: working
.write(LOAD1_DI
); break;
6018 default: throw new IllegalStateException("Unknown Word Register Operand");
6021 private void store1_Gw(int modrm
)
6023 switch(modrm
& 0x38) {
6024 case 0x00: working
.write(STORE1_AX
); break;
6025 case 0x08: working
.write(STORE1_CX
); break;
6026 case 0x10: working
.write(STORE1_DX
); break;
6027 case 0x18: working
.write(STORE1_BX
); break;
6028 case 0x20: working
.write(STORE1_SP
); break;
6029 case 0x28: working
.write(STORE1_BP
); break;
6030 case 0x30: working
.write(STORE1_SI
); break;
6031 case 0x38: working
.write(STORE1_DI
); break;
6032 default: throw new IllegalStateException("Unknown Word Register Operand");
6036 private void load0_Gd(int modrm
)
6038 switch(modrm
& 0x38) {
6039 case 0x00: working
.write(LOAD0_EAX
); break;
6040 case 0x08: working
.write(LOAD0_ECX
); break;
6041 case 0x10: working
.write(LOAD0_EDX
); break;
6042 case 0x18: working
.write(LOAD0_EBX
); break;
6043 case 0x20: working
.write(LOAD0_ESP
); break;
6044 case 0x28: working
.write(LOAD0_EBP
); break;
6045 case 0x30: working
.write(LOAD0_ESI
); break;
6046 case 0x38: working
.write(LOAD0_EDI
); break;
6047 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6050 private void store0_Gd(int modrm
)
6052 switch(modrm
& 0x38) {
6053 case 0x00: working
.write(STORE0_EAX
); break;
6054 case 0x08: working
.write(STORE0_ECX
); break;
6055 case 0x10: working
.write(STORE0_EDX
); break;
6056 case 0x18: working
.write(STORE0_EBX
); break;
6057 case 0x20: working
.write(STORE0_ESP
); break;
6058 case 0x28: working
.write(STORE0_EBP
); break;
6059 case 0x30: working
.write(STORE0_ESI
); break;
6060 case 0x38: working
.write(STORE0_EDI
); break;
6061 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6064 private void load1_Gd(int modrm
)
6066 switch(modrm
& 0x38) {
6067 case 0x00: working
.write(LOAD1_EAX
); break;
6068 case 0x08: working
.write(LOAD1_ECX
); break;
6069 case 0x10: working
.write(LOAD1_EDX
); break;
6070 case 0x18: working
.write(LOAD1_EBX
); break;
6071 case 0x20: working
.write(LOAD1_ESP
); break;
6072 case 0x28: working
.write(LOAD1_EBP
); break;
6073 case 0x30: working
.write(LOAD1_ESI
); break;
6074 case 0x38: working
.write(LOAD1_EDI
); break;
6075 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6078 private void store1_Gd(int modrm
)
6080 switch(modrm
& 0x38) {
6081 case 0x00: working
.write(STORE1_EAX
); break;
6082 case 0x08: working
.write(STORE1_ECX
); break;
6083 case 0x10: working
.write(STORE1_EDX
); break;
6084 case 0x18: working
.write(STORE1_EBX
); break;
6085 case 0x20: working
.write(STORE1_ESP
); break;
6086 case 0x28: working
.write(STORE1_EBP
); break;
6087 case 0x30: working
.write(STORE1_ESI
); break;
6088 case 0x38: working
.write(STORE1_EDI
); break;
6089 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6093 private void load0_Sw(int modrm
)
6095 switch(modrm
& 0x38) {
6096 case 0x00: working
.write(LOAD0_ES
); break;
6097 case 0x08: working
.write(LOAD0_CS
); break;
6098 case 0x10: working
.write(LOAD0_SS
); break;
6099 case 0x18: working
.write(LOAD0_DS
); break;
6100 case 0x20: working
.write(LOAD0_FS
); break;
6101 case 0x28: working
.write(LOAD0_GS
); break;
6102 default: throw new IllegalStateException("Unknown Segment Register Operand");
6105 private void store0_Sw(int modrm
)
6107 switch(modrm
& 0x38) {
6108 case 0x00: working
.write(STORE0_ES
); break;
6109 case 0x08: working
.write(STORE0_CS
); break;
6110 case 0x10: working
.write(STORE0_SS
); break;
6111 case 0x18: working
.write(STORE0_DS
); break;
6112 case 0x20: working
.write(STORE0_FS
); break;
6113 case 0x28: working
.write(STORE0_GS
); break;
6114 default: throw new IllegalStateException("Unknown Segment Register Operand");
6117 private void decodeO(int prefices
, int displacement
)
6119 switch (prefices
& PREFICES_SG
) {
6121 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6122 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6123 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6124 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6125 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6126 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6129 if ((prefices
& PREFICES_ADDRESS
) != 0) {
6130 if (decodingAddressMode())
6131 working
.write(ADDR_ID
); working
.write(displacement
);
6133 if (decodingAddressMode()) {
6134 working
.write(ADDR_IW
); working
.write(displacement
);
6135 working
.write(ADDR_MASK16
);
6140 private void load0_Ob(int prefices
, int displacement
)
6142 decodeO(prefices
, displacement
);
6143 working
.write(LOAD0_MEM_BYTE
);
6145 private void store0_Ob(int prefices
, int displacement
)
6147 decodeO(prefices
, displacement
);
6148 working
.write(STORE0_MEM_BYTE
);
6151 private void load0_Ow(int prefices
, int displacement
)
6153 decodeO(prefices
, displacement
);
6154 working
.write(LOAD0_MEM_WORD
);
6156 private void store0_Ow(int prefices
, int displacement
)
6158 decodeO(prefices
, displacement
);
6159 working
.write(STORE0_MEM_WORD
);
6162 private void load0_Od(int prefices
, int displacement
)
6164 decodeO(prefices
, displacement
);
6165 working
.write(LOAD0_MEM_DWORD
);
6167 private void store0_Od(int prefices
, int displacement
)
6169 decodeO(prefices
, displacement
);
6170 working
.write(STORE0_MEM_DWORD
);
6173 private void load0_M(int prefices
, int modrm
, int sib
, int displacement
)
6175 decodeM(prefices
, modrm
, sib
, displacement
);
6176 working
.write(LOAD0_ADDR
);
6179 private void decodeM(int prefices
, int modrm
, int sib
, int displacement
)
6181 if (!decodingAddressMode()) return;
6183 if ((prefices
& PREFICES_ADDRESS
) != 0) {
6184 //32 bit address size
6187 switch (prefices
& PREFICES_SG
) {
6189 switch (modrm
& 0xc7) {
6190 default: working
.write(LOAD_SEG_DS
); break;
6193 case 0x84: break; //segment working.write will occur in decodeSIB
6195 case 0x85: working
.write(LOAD_SEG_SS
); break;
6198 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6199 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6200 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6201 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6202 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6203 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6207 switch(modrm
& 0x7) {
6208 case 0x0: working
.write(ADDR_EAX
); break;
6209 case 0x1: working
.write(ADDR_ECX
); break;
6210 case 0x2: working
.write(ADDR_EDX
); break;
6211 case 0x3: working
.write(ADDR_EBX
); break;
6212 case 0x4: decodeSIB(prefices
, modrm
, sib
, displacement
); break;
6214 if((modrm
& 0xc0) == 0x00) {
6215 working
.write(ADDR_ID
);
6216 working
.write(displacement
);
6218 working
.write(ADDR_EBP
);
6220 case 0x6: working
.write(ADDR_ESI
); break;
6221 case 0x7: working
.write(ADDR_EDI
); break;
6224 switch(modrm
& 0xc0) {
6225 case 0x40: working
.write(ADDR_IB
); working
.write(displacement
); break;
6226 case 0x80: working
.write(ADDR_ID
); working
.write(displacement
); break;
6229 //16 bit address size
6231 switch (prefices
& PREFICES_SG
) {
6233 switch (modrm
& 0xc7) {
6234 default: working
.write(LOAD_SEG_DS
); break;
6242 case 0x86: working
.write(LOAD_SEG_SS
); break;
6245 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6246 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6247 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6248 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6249 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6250 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6253 switch (modrm
& 0x7) {
6254 case 0x0: working
.write(ADDR_BX
); working
.write(ADDR_SI
); break;
6255 case 0x1: working
.write(ADDR_BX
); working
.write(ADDR_DI
); break;
6256 case 0x2: working
.write(ADDR_BP
); working
.write(ADDR_SI
); break;
6257 case 0x3: working
.write(ADDR_BP
); working
.write(ADDR_DI
); break;
6258 case 0x4: working
.write(ADDR_SI
); break;
6259 case 0x5: working
.write(ADDR_DI
); break;
6261 if ((modrm
& 0xc0) == 0x00) {
6262 working
.write(ADDR_IW
);
6263 working
.write(displacement
);
6265 working
.write(ADDR_BP
);
6268 case 0x7: working
.write(ADDR_BX
); break;
6271 switch (modrm
& 0xc0) {
6272 case 0x40: working
.write(ADDR_IB
); working
.write(displacement
); break;
6273 case 0x80: working
.write(ADDR_IW
); working
.write(displacement
); break;
6275 working
.write(ADDR_MASK16
);
6279 private void decodeSIB(int prefices
, int modrm
, int sib
, int displacement
)
6281 switch (prefices
& PREFICES_SG
) {
6283 switch (sib
& 0x7) {
6284 default: working
.write(LOAD_SEG_DS
); break;
6285 case 0x4: working
.write(LOAD_SEG_SS
); break;
6287 switch (modrm
& 0xc0) {
6288 default: working
.write(LOAD_SEG_SS
); break;
6289 case 0x00: working
.write(LOAD_SEG_DS
); break;
6292 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6293 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6294 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6295 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6296 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6297 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6301 switch (sib
& 0x7) {
6302 case 0x0: working
.write(ADDR_EAX
); break;
6303 case 0x1: working
.write(ADDR_ECX
); break;
6304 case 0x2: working
.write(ADDR_EDX
); break;
6305 case 0x3: working
.write(ADDR_EBX
); break;
6306 case 0x4: working
.write(ADDR_ESP
); break;
6308 switch (modrm
& 0xc0) {
6309 default: working
.write(ADDR_EBP
); break;
6310 case 0x00: working
.write(ADDR_ID
); working
.write(displacement
); break;
6312 case 0x6: working
.write(ADDR_ESI
); break;
6313 case 0x7: working
.write(ADDR_EDI
); break;
6317 switch (sib
& 0xf8) {
6318 case 0x00: working
.write(ADDR_EAX
); break;
6319 case 0x08: working
.write(ADDR_ECX
); break;
6320 case 0x10: working
.write(ADDR_EDX
); break;
6321 case 0x18: working
.write(ADDR_EBX
); break;
6322 case 0x20: break; //none
6323 case 0x28: working
.write(ADDR_EBP
); break;
6324 case 0x30: working
.write(ADDR_ESI
); break;
6325 case 0x38: working
.write(ADDR_EDI
); break;
6327 case 0x40: working
.write(ADDR_2EAX
); break;
6328 case 0x48: working
.write(ADDR_2ECX
); break;
6329 case 0x50: working
.write(ADDR_2EDX
); break;
6330 case 0x58: working
.write(ADDR_2EBX
); break;
6331 case 0x60: break; //none
6332 case 0x68: working
.write(ADDR_2EBP
); break;
6333 case 0x70: working
.write(ADDR_2ESI
); break;
6334 case 0x78: working
.write(ADDR_2EDI
); break;
6336 case 0x80: working
.write(ADDR_4EAX
); break;
6337 case 0x88: working
.write(ADDR_4ECX
); break;
6338 case 0x90: working
.write(ADDR_4EDX
); break;
6339 case 0x98: working
.write(ADDR_4EBX
); break;
6340 case 0xa0: break; //none
6341 case 0xa8: working
.write(ADDR_4EBP
); break;
6342 case 0xb0: working
.write(ADDR_4ESI
); break;
6343 case 0xb8: working
.write(ADDR_4EDI
); break;
6345 case 0xc0: working
.write(ADDR_8EAX
); break;
6346 case 0xc8: working
.write(ADDR_8ECX
); break;
6347 case 0xd0: working
.write(ADDR_8EDX
); break;
6348 case 0xd8: working
.write(ADDR_8EBX
); break;
6349 case 0xe0: break; //none
6350 case 0xe8: working
.write(ADDR_8EBP
); break;
6351 case 0xf0: working
.write(ADDR_8ESI
); break;
6352 case 0xf8: working
.write(ADDR_8EDI
); break;
6356 private void decodeSegmentPrefix(int prefices
)
6358 switch (prefices
& PREFICES_SG
) {
6360 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6361 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6362 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6363 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6364 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6365 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6369 private void store0_Rd(int modrm
)
6371 switch (modrm
& 0xc7) {
6372 case 0xc0: working
.write(STORE0_EAX
); break;
6373 case 0xc1: working
.write(STORE0_ECX
); break;
6374 case 0xc2: working
.write(STORE0_EDX
); break;
6375 case 0xc3: working
.write(STORE0_EBX
); break;
6376 case 0xc4: working
.write(STORE0_ESP
); break;
6377 case 0xc5: working
.write(STORE0_EBP
); break;
6378 case 0xc6: working
.write(STORE0_ESI
); break;
6379 case 0xc7: working
.write(STORE0_EDI
); break;
6380 default: throw new IllegalStateException("Rd cannot be a memory location");
6384 private void load0_Rd(int modrm
)
6386 switch (modrm
& 0xc7) {
6387 case 0xc0: working
.write(LOAD0_EAX
); break;
6388 case 0xc1: working
.write(LOAD0_ECX
); break;
6389 case 0xc2: working
.write(LOAD0_EDX
); break;
6390 case 0xc3: working
.write(LOAD0_EBX
); break;
6391 case 0xc4: working
.write(LOAD0_ESP
); break;
6392 case 0xc5: working
.write(LOAD0_EBP
); break;
6393 case 0xc6: working
.write(LOAD0_ESI
); break;
6394 case 0xc7: working
.write(LOAD0_EDI
); break;
6395 default: throw new IllegalStateException("Rd cannot be a memory location");
6399 private static class Operation
6401 private int[] microcodes
;
6402 private int microcodesLength
;
6403 private int x86Length
;
6404 private int readOffset
;
6405 private boolean decoded
;
6406 private boolean terminal
;
6410 microcodes
= new int[10];
6413 void write(int microcode
)
6416 microcodes
[microcodesLength
] = microcode
;
6418 } catch (ArrayIndexOutOfBoundsException e
) {
6419 int[] temp
= new int[2*microcodes
.length
];
6420 System
.arraycopy(microcodes
, 0, temp
, 0, microcodes
.length
);
6422 microcodes
[microcodesLength
++] = microcode
;
6426 void replace(int offset
, int microcode
)
6428 microcodes
[offset
] = microcode
;
6431 void finish(int x86Length
)
6433 this.x86Length
= x86Length
;
6455 microcodesLength
= 0;
6462 int getMicrocodeAt(int offset
)
6464 return microcodes
[offset
];
6469 if (readOffset
< microcodesLength
)
6470 return microcodes
[readOffset
++];
6472 System
.err
.println("Critical error: Attempted to read outside microcode array.");
6473 throw new IllegalStateException("Attempted read outside microcode array");
6479 return microcodesLength
;