2 JPC-RR: A x86 PC Hardware Emulator
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009-2010 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 ProtectedModeUDecoder
implements Decoder
, InstructionSource
42 private static final boolean[] modrmArray
= new boolean[] { // true for opcodes that require a modrm byte
43 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
44 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
45 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
46 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
48 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
49 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
50 false, false, true, true, false, false, false, false, false, true, false, true, false, false, false, false,
51 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
53 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
54 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
55 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
56 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
58 true, true, false, false, true, true, true, true, false, false, false, false, false, false, false, false,
59 true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false,
60 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
61 false, false, false, false, false, false, true, true, false, false, false, false, false, false, true, true
64 private static final boolean[] sibArray
= new boolean[] { // true for modrm values that require a sib byte (32 bit addressing only)
65 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
66 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
67 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
68 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
70 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
71 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
72 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
73 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
75 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
76 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
77 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
78 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
80 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
81 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
82 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
83 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false
86 private static final boolean[] twoByte_0f_modrmArray
= new boolean[] { // true for opcodes that require a modrm byte
87 true, true, true, true, false, false, false, false, false, false, false, true, false, false, false, false,
88 true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, true,
89 true, true, true, true, true, false, true, false, true, true, true, true, true, true, true, true,
90 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
92 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
93 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
94 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
95 true, true, true, true, true, true, true, false, false, false, false, false, true, true, true, true,
97 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
98 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
99 false, false, false, true, true, true, false, false, false, false, false, true, true, true, true, true,
100 true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true,
102 true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false,
103 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
104 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
105 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true
108 private static final boolean[] twoByte_0f_sibArray
= new boolean[] { // true for modrm values that require a sib byte (32 bit addressing only)
109 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
110 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
111 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
112 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
114 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
115 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
116 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
117 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
119 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
120 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
121 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
122 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
124 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
125 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
126 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
127 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false
130 private static final int PREFICES_SG
= 0x7;
131 private static final int PREFICES_ES
= 0x1;
132 private static final int PREFICES_CS
= 0x2;
133 private static final int PREFICES_SS
= 0x3;
134 private static final int PREFICES_DS
= 0x4;
135 private static final int PREFICES_FS
= 0x5;
136 private static final int PREFICES_GS
= 0x6;
138 private static final int PREFICES_OPERAND
= 0x8;
139 private static final int PREFICES_ADDRESS
= 0x10;
141 private static final int PREFICES_REPNE
= 0x20;
142 private static final int PREFICES_REPE
= 0x40;
144 private static final int PREFICES_REP
= PREFICES_REPNE
| PREFICES_REPE
;
146 private static final int PREFICES_LOCK
= 0x80;
148 private ByteSource source
;
149 private Operation current
;
150 private Operation waiting
;
151 private Operation working
;
153 private boolean blockComplete
;
154 private boolean addressModeDecoded
;
155 private boolean operandSizeIs32Bit
;
157 private int decodeLimit
;
160 * TODO: throw UD exception if LOCK prefix is used with an invalid instruction
163 public ProtectedModeUDecoder()
165 this.current
= new Operation();
166 this.waiting
= new Operation();
167 this.working
= new Operation();
170 public InstructionSource
decodeReal(ByteSource source
, int limit
)
175 public InstructionSource
decodeVirtual8086(ByteSource source
, int limit
)
180 public InstructionSource
decodeProtected(ByteSource source
, boolean operandSize
, int limit
)
184 operandSizeIs32Bit
= operandSize
;
185 this.source
= source
;
190 private void blockFinished()
192 blockComplete
= true;
195 private void rotate()
197 Operation temp
= current
;
203 public boolean getNext()
205 decode(); //will put new block in working
206 rotate(); //moves buffer around
207 if (current
.decoded())
209 else if (current
.terminal()) {
221 blockComplete
= false;
224 public int getMicrocode()
226 return current
.getMicrocode();
229 public int getLength()
231 return current
.getLength();
234 public int getX86Length()
236 return current
.getX86Length();
240 private boolean decodingAddressMode()
242 if (addressModeDecoded
) {
245 return (addressModeDecoded
= true);
249 private void decodeComplete(int position
)
251 if (addressModeDecoded
) {
252 working
.write(MEM_RESET
);
253 addressModeDecoded
= false;
255 working
.finish(position
);
258 private void decode()
263 working
.makeTerminal();
269 length
= decodeOpcode(operandSizeIs32Bit
);
271 } catch (IllegalStateException e
) {
272 if (!waiting
.decoded()) {
273 System
.err
.println("Critical error: Instruction decoder failed.");
276 waiting
.write(EIP_UPDATE
);
277 working
.makeTerminal();
283 decodeComplete(-length
);
285 } else if (decodeLimit
<= 0) {
286 decodeComplete(length
);
287 working
.write(EIP_UPDATE
);
290 decodeComplete(length
);
293 private int decodeOpcode(boolean operandSizeIs32Bit
)
296 int opcodePrefix
= 0;
297 int prefices
= operandSizeIs32Bit ? PREFICES_OPERAND
| PREFICES_ADDRESS
: 0x00;
301 boolean lock
= false;
304 switch (opcode
= 0xff & source
.getByte()) {
306 opcodePrefix
= (opcodePrefix
<< 8) | opcode
;
307 opcode
= 0xff & source
.getByte();
319 opcodePrefix
= (opcodePrefix
<< 8) | opcode
;
321 modrm
= 0xff & source
.getByte();
326 prefices
&= ~PREFICES_SG
;
327 prefices
|= PREFICES_CS
;
330 prefices
&= ~PREFICES_SG
;
331 prefices
|= PREFICES_DS
;
334 prefices
&= ~PREFICES_SG
;
335 prefices
|= PREFICES_ES
;
338 prefices
&= ~PREFICES_SG
;
339 prefices
|= PREFICES_SS
;
342 prefices
&= ~PREFICES_SG
;
343 prefices
|= PREFICES_FS
;
346 prefices
&= ~PREFICES_SG
;
347 prefices
|= PREFICES_GS
;
350 if (operandSizeIs32Bit
)
351 prefices
= prefices
& ~PREFICES_OPERAND
;
353 prefices
= prefices
| PREFICES_OPERAND
;
356 if (operandSizeIs32Bit
)
357 prefices
= prefices
& ~PREFICES_ADDRESS
;
359 prefices
= prefices
| PREFICES_ADDRESS
;
362 prefices
|= PREFICES_REPNE
;
365 prefices
|= PREFICES_REPE
;
369 prefices
|= PREFICES_LOCK
;
377 if ((opcode
== 0xff) && (opcode
== 0xfe) && (opcode
!= 0xab) && (opcode
== 0xfc1)
378 && (opcode
!= 0x81) && (opcode
!= 0x83) && (opcode
!= 0x1) && (opcode
!= 0xfc7)
379 && (opcode
!= 0xba) && (opcode
!= 0xb3) && (opcode
!= 0x29) && (opcode
!= 0x9)
380 && (opcode
!= 0xb1) && (opcode
!= 0x21))
381 System
.err
.println("Emulated: Warning using LOCK prefix with opcode: " + Integer
.toHexString(opcode
));
383 opcode
= (opcodePrefix
<< 8) | opcode
;
384 switch (opcodePrefix
) {
386 if (modrmArray
[opcode
]) {
387 modrm
= 0xff & source
.getByte();
392 if ((modrm
== -1) || ((prefices
& PREFICES_ADDRESS
) == 0)) {
395 if (sibArray
[modrm
]) {
396 sib
= 0xff & source
.getByte();
404 if (twoByte_0f_modrmArray
[0xff & opcode
]) {
405 modrm
= 0xff & source
.getByte();
410 if ((modrm
== -1) || ((prefices
& PREFICES_ADDRESS
) == 0)) {
413 if (twoByte_0f_sibArray
[modrm
]) {
414 sib
= 0xff & source
.getByte();
429 if (sibArray
[modrm
]) {
430 sib
= 0xff & source
.getByte();
442 working
.write(INSTRUCTION_START
);
444 if (isJump(opcode
, modrm
))
445 working
.write(EIP_UPDATE
);
447 int displacement
= 0;
449 switch (operationHasDisplacement(prefices
, opcode
, modrm
, sib
)) {
453 displacement
= source
.getByte();
457 displacement
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00);
461 displacement
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00) | ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000);
465 System
.err
.println("Error: " + operationHasDisplacement(prefices
, opcode
, modrm
, sib
) +
466 " byte displacement invalid.");
472 switch (operationHasImmediate(prefices
, opcode
, modrm
)) {
476 immediate
= source
.getByte();
480 immediate
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00);
484 immediate
= ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000) | (source
.getByte() & 0xff);
488 immediate
= (source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00) | ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000);
492 immediate
= 0xffffffffl
& ((source
.getByte() & 0xff) | ((source
.getByte() << 8) & 0xff00) | ((source
.getByte() << 16) & 0xff0000) | ((source
.getByte() << 24) & 0xff000000));
493 immediate
|= ((source
.getByte() & 0xffl
) | ((source
.getByte() << 8) & 0xff00l
)) << 32;
497 System
.err
.println("Error: " + operationHasImmediate(prefices
, opcode
, modrm
) +
498 " byte immediate invalid.");
503 //write out input operands
504 writeInputOperands(prefices
, opcode
, modrm
, sib
, displacement
, immediate
);
506 //write out calculation
507 writeOperation(prefices
, opcode
, modrm
);
509 //write out output operands
510 writeOutputOperands(prefices
, opcode
, modrm
, sib
, displacement
);
513 writeFlags(prefices
, opcode
, modrm
);
515 if (isJump(opcode
, modrm
))
521 private void writeOperation(int prefices
, int opcode
, int modrm
)
524 case 0x00: //ADD Eb, Gb
525 case 0x01: //ADD Ev, Gv
526 case 0x02: //ADD Gb, Eb
527 case 0x03: //ADD Gv, Ev
528 case 0x04: //ADD AL, Ib
529 case 0x05: //ADD eAX, Iv
530 case 0xfc0: //XADD Eb, Gb
531 case 0xfc1: working
.write(ADD
); break; //XADD Ev, Gv
533 case 0x08: //OR Eb, Gb
534 case 0x09: //OR Ev, Gv
535 case 0x0a: //OR Gb, Eb
536 case 0x0b: //OR Gv, Ev
537 case 0x0c: //OR AL, Ib
538 case 0x0d: working
.write(OR
); break; //OR eAX, Iv
540 case 0x10: //ADC Eb, Gb
541 case 0x11: //ADC Ev, Gv
542 case 0x12: //ADC Gb, Eb
543 case 0x13: //ADC Gv, Ev
544 case 0x14: //ADC AL, Ib
545 case 0x15: working
.write(ADC
); break; //ADC eAX, Iv
547 case 0x18: //SBB Eb, Gb
548 case 0x19: //SBB Ev, Gv
549 case 0x1a: //SBB Gb, Eb
550 case 0x1b: //SBB Gv, Ev
551 case 0x1c: //SBB AL, Ib
552 case 0x1d: working
.write(SBB
); break; //SBB eAX, Iv
554 case 0x20: //AND Eb, Gb
555 case 0x21: //AND Ev, Gv
556 case 0x22: //AND Gb, Eb
557 case 0x23: //AND Gv, Ev
558 case 0x24: //AND AL, Ib
559 case 0x25: //AND eAX, Iv
560 case 0x84: //TEST Eb, Gb
561 case 0x85: //TEST Ev, Gv
562 case 0xa8: //TEST AL, Ib
563 case 0xa9: working
.write(AND
); break; //TEST eAX, Iv
565 case 0x27: working
.write(DAA
); break; //DAA
567 case 0x28: //SUB Eb, Gb
568 case 0x29: //SUB Ev, Gv
569 case 0x2a: //SUB Gb, Eb
570 case 0x2b: //SUB Gv, Ev
571 case 0x2c: //SUB AL, Ib
572 case 0x2d: //SUB eAX, Iv
573 case 0x38: //CMP Eb, Gb
574 case 0x39: //CMP Ev, Gv
575 case 0x3a: //CMP Gb, Eb
576 case 0x3b: //CMP Gv, Ev
577 case 0x3c: //CMP AL, Ib
578 case 0x3d: working
.write(SUB
); break; //CMP eAX, Iv
580 case 0x2f: working
.write(DAS
); break; //DAS
582 case 0x30: //XOR Eb, Gb
583 case 0x31: //XOR Ev, Gv
584 case 0x32: //XOR Gb, Eb
585 case 0x33: //XOR Gv, Ev
586 case 0x34: //XOR AL, Ib
587 case 0x35: working
.write(XOR
); break; //XOR eAX, Iv
589 case 0x37: working
.write(AAA
); break; //AAA
590 case 0x3f: working
.write(AAS
); break; //AAS
599 case 0x47: working
.write(INC
); break; //INC eDI
608 case 0x4f: working
.write(DEC
); break; //DEC eDI
614 case 0x50: //PUSH eAX
615 case 0x51: //PUSH eCX
616 case 0x52: //PUSH eDX
617 case 0x53: //PUSH eBX
618 case 0x54: //PUSH eSP
619 case 0x55: //PUSH eBP
620 case 0x56: //PUSH eSI
621 case 0x57: //PUSH eDI
624 case 0xfa0: //PUSH FS
625 case 0xfa8: //PUSH GS
626 switch (prefices
& PREFICES_OPERAND
) {
628 working
.write(PUSH_O16
); break;
629 case PREFICES_OPERAND
:
630 working
.write(PUSH_O32
); break;
635 switch (prefices
& PREFICES_OPERAND
) {
637 working
.write(PUSHF_O16
); break;
638 case PREFICES_OPERAND
:
639 working
.write(PUSHF_O32
); break;
657 switch (prefices
& PREFICES_OPERAND
) {
659 working
.write(POP_O16
); break;
660 case PREFICES_OPERAND
:
661 working
.write(POP_O32
); break;
666 switch (prefices
& PREFICES_OPERAND
) {
668 working
.write(POPF_O16
); break;
669 case PREFICES_OPERAND
:
670 working
.write(POPF_O32
); break;
675 switch (prefices
& PREFICES_OPERAND
) {
677 working
.write(PUSHA
); break;
678 case PREFICES_OPERAND
:
679 working
.write(PUSHAD
); break;
684 switch (prefices
& PREFICES_OPERAND
) {
686 working
.write(POPA
); break;
687 case PREFICES_OPERAND
:
688 working
.write(POPAD
); break;
693 if ((prefices
& PREFICES_OPERAND
) != 0)
694 working
.write(BOUND_O32
);
696 working
.write(BOUND_O16
);
699 case 0x69: //IMUL Gv, Ev, Iv
700 case 0x6b: //IMUL Gv, Ev, Ib
701 case 0xfaf: //IMUL Gv, Ev
702 if ((prefices
& PREFICES_OPERAND
) != 0)
703 working
.write(IMUL_O32
);
705 working
.write(IMUL_O16
);
709 if ((prefices
& PREFICES_REP
) != 0) {
710 if ((prefices
& PREFICES_ADDRESS
) != 0)
711 working
.write(REP_INSB_A32
);
713 working
.write(REP_INSB_A16
);
715 if ((prefices
& PREFICES_ADDRESS
) != 0)
716 working
.write(INSB_A32
);
718 working
.write(INSB_A16
);
723 if ((prefices
& PREFICES_OPERAND
) != 0) {
724 if ((prefices
& PREFICES_REP
) != 0) {
725 if ((prefices
& PREFICES_ADDRESS
) != 0)
726 working
.write(REP_INSD_A32
);
728 working
.write(REP_INSD_A16
);
730 if ((prefices
& PREFICES_ADDRESS
) != 0)
731 working
.write(INSD_A32
);
733 working
.write(INSD_A16
);
736 if ((prefices
& PREFICES_REP
) != 0) {
737 if ((prefices
& PREFICES_ADDRESS
) != 0)
738 working
.write(REP_INSW_A32
);
740 working
.write(REP_INSW_A16
);
742 if ((prefices
& PREFICES_ADDRESS
) != 0)
743 working
.write(INSW_A32
);
745 working
.write(INSW_A16
);
751 if ((prefices
& PREFICES_REP
) != 0) {
752 if ((prefices
& PREFICES_ADDRESS
) != 0)
753 working
.write(REP_OUTSB_A32
);
755 working
.write(REP_OUTSB_A16
);
757 if ((prefices
& PREFICES_ADDRESS
) != 0)
758 working
.write(OUTSB_A32
);
760 working
.write(OUTSB_A16
);
764 case 0x6f: //OUTS DX, Xv
765 if ((prefices
& PREFICES_OPERAND
) != 0) {
766 if ((prefices
& PREFICES_REP
) != 0) {
767 if ((prefices
& PREFICES_ADDRESS
) != 0)
768 working
.write(REP_OUTSD_A32
);
770 working
.write(REP_OUTSD_A16
);
772 if ((prefices
& PREFICES_ADDRESS
) != 0)
773 working
.write(OUTSD_A32
);
775 working
.write(OUTSD_A16
);
778 if ((prefices
& PREFICES_REP
) != 0) {
779 if ((prefices
& PREFICES_ADDRESS
) != 0)
780 working
.write(REP_OUTSW_A32
);
782 working
.write(REP_OUTSW_A16
);
784 if ((prefices
& PREFICES_ADDRESS
) != 0)
785 working
.write(OUTSW_A32
);
787 working
.write(OUTSW_A16
);
792 case 0x70: working
.write(JO_O8
); break; //JC Jb
793 case 0x71: working
.write(JNO_O8
); break; //JNC Jb
794 case 0x72: working
.write(JC_O8
); break; //JC Jb
795 case 0x73: working
.write(JNC_O8
); break; //JNC Jb
796 case 0x74: working
.write(JZ_O8
); break; //JZ Jb
797 case 0x75: working
.write(JNZ_O8
); break; //JNZ Jb
798 case 0x76: working
.write(JNA_O8
); break; //JNA Jb
799 case 0x77: working
.write(JA_O8
); break; //JA Jb
800 case 0x78: working
.write(JS_O8
); break; //JS Jb
801 case 0x79: working
.write(JNS_O8
); break; //JNS Jb
802 case 0x7a: working
.write(JP_O8
); break; //JP Jb
803 case 0x7b: working
.write(JNP_O8
); break; //JNP Jb
804 case 0x7c: working
.write(JL_O8
); break; //JL Jb
805 case 0x7d: working
.write(JNL_O8
); break; //JNL Jb
806 case 0x7e: working
.write(JNG_O8
); break; //JNG Jb
807 case 0x7f: working
.write(JG_O8
); break; //JG Jb
809 case 0x80: //IMM GP1 Eb, Ib
810 case 0x81: //IMM GP1 Ev, Iv
811 case 0x82: //IMM GP1 Eb, Ib
812 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
813 switch (modrm
& 0x38) {
815 working
.write(ADD
); break;
817 working
.write(OR
); break;
819 working
.write(ADC
); break;
821 working
.write(SBB
); break;
823 working
.write(AND
); break;
826 working
.write(SUB
); break;
828 working
.write(XOR
); break;
832 case 0x98: //CBW/CWDE
833 if ((prefices
& PREFICES_OPERAND
) != 0) {
834 working
.write(LOAD0_AX
);
835 working
.write(SIGN_EXTEND_16_32
);
836 working
.write(STORE0_EAX
);
838 working
.write(LOAD0_AL
);
839 working
.write(SIGN_EXTEND_8_16
);
840 working
.write(STORE0_AX
);
845 if ((prefices
& PREFICES_OPERAND
) != 0)
852 switch (prefices
& PREFICES_OPERAND
) {
854 working
.write(CALL_FAR_O16
); break;
855 case PREFICES_OPERAND
:
856 working
.write(CALL_FAR_O32
); break;
860 case 0x9b: working
.write(FWAIT
); break; //FWAIT
862 case 0x9e: working
.write(SAHF
); break;
863 case 0x9f: working
.write(LAHF
); break;
866 if ((prefices
& PREFICES_REP
) != 0) {
867 if ((prefices
& PREFICES_ADDRESS
) != 0)
868 working
.write(REP_MOVSB_A32
);
870 working
.write(REP_MOVSB_A16
);
872 if ((prefices
& PREFICES_ADDRESS
) != 0)
873 working
.write(MOVSB_A32
);
875 working
.write(MOVSB_A16
);
880 if ((prefices
& PREFICES_OPERAND
) != 0) {
881 if ((prefices
& PREFICES_REP
) != 0) {
882 if ((prefices
& PREFICES_ADDRESS
) != 0)
883 working
.write(REP_MOVSD_A32
);
885 working
.write(REP_MOVSD_A16
);
887 if ((prefices
& PREFICES_ADDRESS
) != 0)
888 working
.write(MOVSD_A32
);
890 working
.write(MOVSD_A16
);
893 if ((prefices
& PREFICES_REP
) != 0) {
894 if ((prefices
& PREFICES_ADDRESS
) != 0)
895 working
.write(REP_MOVSW_A32
);
897 working
.write(REP_MOVSW_A16
);
899 if ((prefices
& PREFICES_ADDRESS
) != 0)
900 working
.write(MOVSW_A32
);
902 working
.write(MOVSW_A16
);
908 if ((prefices
& PREFICES_REPE
) != 0) {
909 if ((prefices
& PREFICES_ADDRESS
) != 0)
910 working
.write(REPE_CMPSB_A32
);
912 working
.write(REPE_CMPSB_A16
);
913 } else if ((prefices
& PREFICES_REPNE
) != 0) {
914 if ((prefices
& PREFICES_ADDRESS
) != 0)
915 working
.write(REPNE_CMPSB_A32
);
917 working
.write(REPNE_CMPSB_A16
);
919 if ((prefices
& PREFICES_ADDRESS
) != 0)
920 working
.write(CMPSB_A32
);
922 working
.write(CMPSB_A16
);
927 if ((prefices
& PREFICES_OPERAND
) != 0) {
928 if ((prefices
& PREFICES_REPE
) != 0) {
929 if ((prefices
& PREFICES_ADDRESS
) != 0)
930 working
.write(REPE_CMPSD_A32
);
932 working
.write(REPE_CMPSD_A16
);
933 } else if ((prefices
& PREFICES_REPNE
) != 0) {
934 if ((prefices
& PREFICES_ADDRESS
) != 0)
935 working
.write(REPNE_CMPSD_A32
);
937 working
.write(REPNE_CMPSD_A16
);
939 if ((prefices
& PREFICES_ADDRESS
) != 0)
940 working
.write(CMPSD_A32
);
942 working
.write(CMPSD_A16
);
945 if ((prefices
& PREFICES_REPE
) != 0) {
946 if ((prefices
& PREFICES_ADDRESS
) != 0)
947 working
.write(REPE_CMPSW_A32
);
949 working
.write(REPE_CMPSW_A16
);
950 } else if ((prefices
& PREFICES_REPNE
) != 0) {
951 if ((prefices
& PREFICES_ADDRESS
) != 0)
952 working
.write(REPNE_CMPSW_A32
);
954 working
.write(REPNE_CMPSW_A16
);
956 if ((prefices
& PREFICES_ADDRESS
) != 0)
957 working
.write(CMPSW_A32
);
959 working
.write(CMPSW_A16
);
965 if ((prefices
& PREFICES_REP
) != 0) {
966 if ((prefices
& PREFICES_ADDRESS
) != 0)
967 working
.write(REP_STOSB_A32
);
969 working
.write(REP_STOSB_A16
);
971 if ((prefices
& PREFICES_ADDRESS
) != 0)
972 working
.write(STOSB_A32
);
974 working
.write(STOSB_A16
);
978 case 0xab: //STOSW/STOSD
979 if ((prefices
& PREFICES_OPERAND
) != 0) {
980 if ((prefices
& PREFICES_REP
) != 0) {
981 if ((prefices
& PREFICES_ADDRESS
) != 0)
982 working
.write(REP_STOSD_A32
);
984 working
.write(REP_STOSD_A16
);
986 if ((prefices
& PREFICES_ADDRESS
) != 0)
987 working
.write(STOSD_A32
);
989 working
.write(STOSD_A16
);
992 if ((prefices
& PREFICES_REP
) != 0) {
993 if ((prefices
& PREFICES_ADDRESS
) != 0)
994 working
.write(REP_STOSW_A32
);
996 working
.write(REP_STOSW_A16
);
998 if ((prefices
& PREFICES_ADDRESS
) != 0)
999 working
.write(STOSW_A32
);
1001 working
.write(STOSW_A16
);
1007 if ((prefices
& PREFICES_REP
) != 0) {
1008 if ((prefices
& PREFICES_ADDRESS
) != 0)
1009 working
.write(REP_LODSB_A32
);
1011 working
.write(REP_LODSB_A16
);
1013 if ((prefices
& PREFICES_ADDRESS
) != 0)
1014 working
.write(LODSB_A32
);
1016 working
.write(LODSB_A16
);
1020 case 0xad: //LODSW/LODSD
1021 if ((prefices
& PREFICES_OPERAND
) != 0) {
1022 if ((prefices
& PREFICES_REP
) != 0) {
1023 if ((prefices
& PREFICES_ADDRESS
) != 0)
1024 working
.write(REP_LODSD_A32
);
1026 working
.write(REP_LODSD_A16
);
1028 if ((prefices
& PREFICES_ADDRESS
) != 0)
1029 working
.write(LODSD_A32
);
1031 working
.write(LODSD_A16
);
1034 if ((prefices
& PREFICES_REP
) != 0) {
1035 if ((prefices
& PREFICES_ADDRESS
) != 0)
1036 working
.write(REP_LODSW_A32
);
1038 working
.write(REP_LODSW_A16
);
1040 if ((prefices
& PREFICES_ADDRESS
) != 0)
1041 working
.write(LODSW_A32
);
1043 working
.write(LODSW_A16
);
1049 if ((prefices
& PREFICES_REPE
) != 0) {
1050 if ((prefices
& PREFICES_ADDRESS
) != 0)
1051 working
.write(REPE_SCASB_A32
);
1053 working
.write(REPE_SCASB_A16
);
1054 } else if ((prefices
& PREFICES_REPNE
) != 0) {
1055 if ((prefices
& PREFICES_ADDRESS
) != 0)
1056 working
.write(REPNE_SCASB_A32
);
1058 working
.write(REPNE_SCASB_A16
);
1060 if ((prefices
& PREFICES_ADDRESS
) != 0)
1061 working
.write(SCASB_A32
);
1063 working
.write(SCASB_A16
);
1067 case 0xaf: //SCASW/D
1068 if ((prefices
& PREFICES_OPERAND
) != 0) {
1069 if ((prefices
& PREFICES_REPE
) != 0) {
1070 if ((prefices
& PREFICES_ADDRESS
) != 0)
1071 working
.write(REPE_SCASD_A32
);
1073 working
.write(REPE_SCASD_A16
);
1074 } else if ((prefices
& PREFICES_REPNE
) != 0) {
1075 if ((prefices
& PREFICES_ADDRESS
) != 0)
1076 working
.write(REPNE_SCASD_A32
);
1078 working
.write(REPNE_SCASD_A16
);
1080 if ((prefices
& PREFICES_ADDRESS
) != 0)
1081 working
.write(SCASD_A32
);
1083 working
.write(SCASD_A16
);
1086 if ((prefices
& PREFICES_REPE
) != 0) {
1087 if ((prefices
& PREFICES_ADDRESS
) != 0)
1088 working
.write(REPE_SCASW_A32
);
1090 working
.write(REPE_SCASW_A16
);
1091 } else if ((prefices
& PREFICES_REPNE
) != 0) {
1092 if ((prefices
& PREFICES_ADDRESS
) != 0)
1093 working
.write(REPNE_SCASW_A32
);
1095 working
.write(REPNE_SCASW_A16
);
1097 if ((prefices
& PREFICES_ADDRESS
) != 0)
1098 working
.write(SCASW_A32
);
1100 working
.write(SCASW_A16
);
1108 switch (modrm
& 0x38) {
1110 working
.write(ROL_O8
); break;
1112 working
.write(ROR_O8
); break;
1114 working
.write(RCL_O8
); break;
1116 working
.write(RCR_O8
); break;
1118 working
.write(SHL
); break;
1120 working
.write(SHR
); break;
1122 System
.err
.println("Emulated: invalid SHL encoding");
1123 working
.write(SHL
); break;
1125 working
.write(SAR_O8
); break;
1132 if ((prefices
& PREFICES_OPERAND
) != 0) {
1133 switch (modrm
& 0x38) {
1135 working
.write(ROL_O32
); break;
1137 working
.write(ROR_O32
); break;
1139 working
.write(RCL_O32
); break;
1141 working
.write(RCR_O32
); break;
1143 working
.write(SHL
); break;
1145 working
.write(SHR
); break;
1147 System
.err
.println("Emulated: invalid SHL encoding");
1148 working
.write(SHL
); break;
1150 working
.write(SAR_O32
); break;
1153 switch (modrm
& 0x38) {
1155 working
.write(ROL_O16
); break;
1157 working
.write(ROR_O16
); break;
1159 working
.write(RCL_O16
); break;
1161 working
.write(RCR_O16
); break;
1163 working
.write(SHL
); break;
1165 working
.write(SHR
); break;
1167 working
.write(SHL
); break;
1169 working
.write(SAR_O16
); break;
1175 switch (prefices
& PREFICES_OPERAND
) {
1177 working
.write(RET_IW_O16
); break;
1178 case PREFICES_OPERAND
:
1179 working
.write(RET_IW_O32
); break;
1184 switch (prefices
& PREFICES_OPERAND
) {
1186 working
.write(RET_O16
); break;
1187 case PREFICES_OPERAND
:
1188 working
.write(RET_O32
); break;
1193 switch (prefices
& PREFICES_OPERAND
) {
1195 working
.write(ENTER_O16
); break;
1196 case PREFICES_OPERAND
:
1197 working
.write(ENTER_O32
); break;
1202 switch (prefices
& PREFICES_OPERAND
) {
1204 working
.write(LEAVE_O16
); break;
1205 case PREFICES_OPERAND
:
1206 working
.write(LEAVE_O32
); break;
1211 switch (prefices
& PREFICES_OPERAND
) {
1213 working
.write(RET_FAR_IW_O16
); break;
1214 case PREFICES_OPERAND
:
1215 working
.write(RET_FAR_IW_O32
); break;
1220 switch (prefices
& PREFICES_OPERAND
) {
1222 working
.write(RET_FAR_O16
); break;
1223 case PREFICES_OPERAND
:
1224 working
.write(RET_FAR_O32
); break;
1229 switch (prefices
& PREFICES_OPERAND
) {
1231 working
.write(INT3_O16
); break;
1232 case PREFICES_OPERAND
:
1233 working
.write(INT3_O32
); break;
1238 switch (prefices
& PREFICES_OPERAND
) {
1240 working
.write(INT_O16
); break;
1241 case PREFICES_OPERAND
:
1242 working
.write(INT_O32
); break;
1247 switch (prefices
& PREFICES_OPERAND
) {
1249 working
.write(INTO_O16
); break;
1250 case PREFICES_OPERAND
:
1251 working
.write(INTO_O32
); break;
1256 switch (prefices
& PREFICES_OPERAND
) {
1258 working
.write(IRET_O16
); break;
1259 case PREFICES_OPERAND
:
1260 working
.write(IRET_O32
); break;
1264 case 0xd4: working
.write(AAM
); break; //AAM
1265 case 0xd5: working
.write(AAD
); break; //AAD
1267 case 0xd6: working
.write(SALC
); break; //SALC
1269 case 0xe0: //LOOPNZ Jb
1270 if ((prefices
& PREFICES_ADDRESS
) != 0)
1271 working
.write(LOOPNZ_ECX
);
1273 working
.write(LOOPNZ_CX
);
1276 case 0xe1: //LOOPZ Jb
1277 if ((prefices
& PREFICES_ADDRESS
) != 0)
1278 working
.write(LOOPZ_ECX
);
1280 working
.write(LOOPZ_CX
);
1283 case 0xe2: //LOOP Jb
1284 if ((prefices
& PREFICES_ADDRESS
) != 0)
1285 working
.write(LOOP_ECX
);
1287 working
.write(LOOP_CX
);
1291 if ((prefices
& PREFICES_ADDRESS
) != 0)
1292 working
.write(JECXZ
);
1294 working
.write(JCXZ
);
1297 case 0xe4: //IN AL, Ib
1298 case 0xec: working
.write(IN_O8
); break; //IN AL, DX
1300 case 0xe5: //IN eAX, Ib
1301 case 0xed: //IN eAX, DX
1302 if ((prefices
& PREFICES_OPERAND
) != 0)
1303 working
.write(IN_O32
);
1305 working
.write(IN_O16
);
1308 case 0xe6: //OUT Ib, AL
1309 case 0xee: working
.write(OUT_O8
); break; //OUT DX, AL
1311 case 0xe7: //OUT Ib, eAX
1312 case 0xef: //OUT DX, eAX
1313 if ((prefices
& PREFICES_OPERAND
) != 0)
1314 working
.write(OUT_O32
);
1316 working
.write(OUT_O16
);
1319 case 0xe8: //CALL Jv
1320 switch (prefices
& PREFICES_OPERAND
) {
1322 working
.write(CALL_O16
); break;
1323 case PREFICES_OPERAND
:
1324 working
.write(CALL_O32
); break;
1329 if ((prefices
& PREFICES_OPERAND
) != 0)
1330 working
.write(JUMP_O32
);
1332 working
.write(JUMP_O16
);
1335 case 0xea: //JMPF Ap
1336 if ((prefices
& PREFICES_OPERAND
) != 0)
1337 working
.write(JUMP_FAR_O32
);
1339 working
.write(JUMP_FAR_O16
);
1342 case 0xeb: working
.write(JUMP_O8
); break; //JMP Jb
1344 case 0xf4: working
.write(HALT
); break; //HLT
1346 case 0xf5: working
.write(CMC
); break; //CMC
1348 case 0xf6: //UNA GP3 Eb
1349 switch (modrm
& 0x38) {
1351 working
.write(AND
); break;
1353 working
.write(NOT
); break;
1355 working
.write(NEG
); break;
1357 working
.write(MUL_O8
); break;
1359 working
.write(IMULA_O8
); break;
1361 working
.write(DIV_O8
); break;
1363 working
.write(IDIV_O8
); break;
1364 default: throw new IllegalStateException("Invalid Gp 3 Instruction F6 /" + ((modrm
& 0x38) >> 3) + "?");
1368 case 0xf7: //UNA GP3 Ev
1369 if ((prefices
& PREFICES_OPERAND
) != 0) {
1370 switch (modrm
& 0x38) {
1372 working
.write(AND
); break;
1374 working
.write(NOT
); break;
1376 working
.write(NEG
); break;
1378 working
.write(MUL_O32
); break;
1380 working
.write(IMULA_O32
); break;
1382 working
.write(DIV_O32
); break;
1384 working
.write(IDIV_O32
); break;
1385 default: throw new IllegalStateException("Invalid Gp 3 Instruction O16 F7 /" + ((modrm
& 0x38) >> 3) + "?");
1388 switch (modrm
& 0x38) {
1390 working
.write(AND
); break;
1392 working
.write(NOT
); break;
1394 working
.write(NEG
); break;
1396 working
.write(MUL_O16
); break;
1398 working
.write(IMULA_O16
); break;
1400 working
.write(DIV_O16
); break;
1402 working
.write(IDIV_O16
); break;
1403 default: throw new IllegalStateException("Invalid Gp 3 Instruction O32 F7 /" + ((modrm
& 0x38) >> 3) + "?");
1408 case 0xf8: working
.write(CLC
); break; //CLC
1409 case 0xf9: working
.write(STC
); break; //STC
1410 case 0xfa: working
.write(CLI
); break; //CLI
1411 case 0xfb: working
.write(STI
); decodeLimit
= 2; // let one more instruction be decoded
1413 case 0xfc: working
.write(CLD
); break; //CLD
1414 case 0xfd: working
.write(STD
); break; //STD
1417 switch (modrm
& 0x38) {
1419 working
.write(INC
); break;
1421 working
.write(DEC
); break;
1422 default: throw new IllegalStateException("Invalid Gp 4 Instruction FE /" + ((modrm
& 0x38) >> 3) + "?");
1427 switch (modrm
& 0x38) {
1429 working
.write(INC
); break;
1431 working
.write(DEC
); break;
1433 switch (prefices
& PREFICES_OPERAND
) {
1435 working
.write(CALL_ABS_O16
); break;
1436 case PREFICES_OPERAND
:
1437 working
.write(CALL_ABS_O32
); break;
1441 switch (prefices
& PREFICES_OPERAND
) {
1443 working
.write(CALL_FAR_O16
); break;
1444 case PREFICES_OPERAND
:
1445 working
.write(CALL_FAR_O32
); break;
1449 if ((prefices
& PREFICES_OPERAND
) != 0)
1450 working
.write(JUMP_ABS_O32
);
1452 working
.write(JUMP_ABS_O16
);
1455 if ((prefices
& PREFICES_OPERAND
) != 0)
1456 working
.write(JUMP_FAR_O32
);
1458 working
.write(JUMP_FAR_O16
);
1461 switch (prefices
& PREFICES_OPERAND
) {
1463 working
.write(PUSH_O16
); break;
1464 case PREFICES_OPERAND
:
1465 working
.write(PUSH_O32
); break;
1468 default: 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
1477 case 0x86: //XCHG Eb, Gb
1478 case 0x87: //XCHG Ev, Gv
1479 case 0x88: //MOV Eb, Gb
1480 case 0x89: //MOV Ev, Gv
1481 case 0x8a: //MOV Gb, Eb
1482 case 0x8b: //MOV Gv, Ev
1483 case 0x8c: //MOV Ew, Sw
1484 case 0x8d: //LEA Gv, M
1485 case 0x8e: //MOV Sw, Ew
1488 case 0x91: //XCHG eAX, eCX
1489 case 0x92: //XCHG eAX, eCX
1490 case 0x93: //XCHG eAX, eCX
1491 case 0x94: //XCHG eAX, eCX
1492 case 0x95: //XCHG eAX, eCX
1493 case 0x96: //XCHG eAX, eCX
1494 case 0x97: //XCHG eAX, eCX
1496 case 0xa0: //MOV AL, Ob
1497 case 0xa1: //MOV eAX, Ov
1498 case 0xa2: //MOV Ob, AL
1499 case 0xa3: //MOV Ov, eAX
1501 case 0xb0: //MOV AL, Ib
1502 case 0xb1: //MOV CL, Ib
1503 case 0xb2: //MOV DL, Ib
1504 case 0xb3: //MOV BL, Ib
1505 case 0xb4: //MOV AH, Ib
1506 case 0xb5: //MOV CH, Ib
1507 case 0xb6: //MOV DH, Ib
1508 case 0xb7: //MOV BH, Ib
1510 case 0xb8: //MOV eAX, Iv
1511 case 0xb9: //MOV eCX, Iv
1512 case 0xba: //MOV eDX, Iv
1513 case 0xbb: //MOV eBX, Iv
1514 case 0xbc: //MOV eSP, Iv
1515 case 0xbd: //MOV eBP, Iv
1516 case 0xbe: //MOV eSI, Iv
1517 case 0xbf: //MOV eDI, Iv
1521 case 0xc6: //MOV GP11 Eb, Gb
1522 case 0xc7: //MOV GP11 Ev, Gv
1527 working
.write(UNDEFINED
); //this is encountered with win95 - not clear what to do
1531 throw new IllegalStateException("Missing Operation: 0x" + Integer
.toHexString(opcode
));
1535 case 0xf00: // Group 6
1536 switch (modrm
& 0x38) {
1538 working
.write(SLDT
); break;
1540 working
.write(STR
); break;
1542 working
.write(LLDT
); break;
1544 working
.write(LTR
); break;
1546 working
.write(VERR
); break;
1548 working
.write(VERW
); break;
1549 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F 00 /" + ((modrm
& 0x38) >> 3) + "?");
1553 switch (modrm
& 0x38) {
1555 if ((prefices
& PREFICES_OPERAND
) != 0)
1556 working
.write(SGDT_O32
);
1558 working
.write(SGDT_O16
);
1561 if ((prefices
& PREFICES_OPERAND
) != 0)
1562 working
.write(SIDT_O32
);
1564 working
.write(SIDT_O16
);
1567 if ((prefices
& PREFICES_OPERAND
) != 0)
1568 working
.write(LGDT_O32
);
1570 working
.write(LGDT_O16
);
1573 if ((prefices
& PREFICES_OPERAND
) != 0)
1574 working
.write(LIDT_O32
);
1576 working
.write(LIDT_O16
);
1579 working
.write(SMSW
); break;
1581 working
.write(LMSW
); break;
1583 working
.write(INVLPG
); break;
1584 default: throw new IllegalStateException("Invalid Gp 7 Instruction 0F 01 /" + ((modrm
& 0x38) >> 3) + "?");
1587 case 0xf02: // not thoroughly tested yet Load access right byte
1591 case 0xf03: // not thoroughly tested yet Load Segment size right byte
1597 case 0xf06: working
.write(CLTS
); break; //CLTS
1599 case 0xf09: working
.write(CPL_CHECK
); break; //WBINVD
1601 case 0xf0b: working
.write(UNDEFINED
); break;
1602 case 0xf1f: working
.write(MEM_RESET
); break; //multi byte NOP (read latest manual)
1604 case 0xf30: working
.write(WRMSR
); break; //WRMSR
1605 case 0xf31: working
.write(RDTSC
); break; //RDTSC
1606 case 0xf32: working
.write(RDMSR
); break; //RDMSR
1608 case 0xf34: working
.write(SYSENTER
); break; //SYSENTER
1609 case 0xf35: working
.write(SYSEXIT
); break; //SYSEXIT
1611 case 0xf40: working
.write(CMOVO
); break; //CMOVO
1612 case 0xf41: working
.write(CMOVNO
); break; //CMOVNO
1613 case 0xf42: working
.write(CMOVC
); break; //CMOVC
1614 case 0xf43: working
.write(CMOVNC
); break; //CMOVNC
1615 case 0xf44: working
.write(CMOVZ
); break; //CMOVZ
1616 case 0xf45: working
.write(CMOVNZ
); break; //CMOVNZ
1617 case 0xf46: working
.write(CMOVNA
); break; //CMOVNA
1618 case 0xf47: working
.write(CMOVA
); break; //CMOVA
1619 case 0xf48: working
.write(CMOVS
); break; //CMOVS
1620 case 0xf49: working
.write(CMOVNS
); break; //CMOVNS
1621 case 0xf4a: working
.write(CMOVP
); break; //CMOVP
1622 case 0xf4b: working
.write(CMOVNP
); break; //CMOVNP
1623 case 0xf4c: working
.write(CMOVL
); break; //CMOVL
1624 case 0xf4d: working
.write(CMOVNL
); break; //CMOVNL
1625 case 0xf4e: working
.write(CMOVNG
); break; //CMOVNG
1626 case 0xf4f: working
.write(CMOVG
); break; //CMOVG
1628 case 0xf80: if ((prefices
& PREFICES_OPERAND
) != 0)
1629 working
.write(JO_O32
);
1631 working
.write(JO_O16
);
1633 case 0xf81: if ((prefices
& PREFICES_OPERAND
) != 0)
1634 working
.write(JNO_O32
);
1636 working
.write(JNO_O16
);
1638 case 0xf82: if ((prefices
& PREFICES_OPERAND
) != 0)
1639 working
.write(JC_O32
);
1641 working
.write(JC_O16
);
1643 case 0xf83: if ((prefices
& PREFICES_OPERAND
) != 0)
1644 working
.write(JNC_O32
);
1646 working
.write(JNC_O16
);
1648 case 0xf84: if ((prefices
& PREFICES_OPERAND
) != 0)
1649 working
.write(JZ_O32
);
1651 working
.write(JZ_O16
);
1653 case 0xf85: if ((prefices
& PREFICES_OPERAND
) != 0)
1654 working
.write(JNZ_O32
);
1656 working
.write(JNZ_O16
);
1658 case 0xf86: if ((prefices
& PREFICES_OPERAND
) != 0)
1659 working
.write(JNA_O32
);
1661 working
.write(JNA_O16
);
1663 case 0xf87: if ((prefices
& PREFICES_OPERAND
) != 0)
1664 working
.write(JA_O32
);
1666 working
.write(JA_O16
);
1668 case 0xf88: if ((prefices
& PREFICES_OPERAND
) != 0)
1669 working
.write(JS_O32
);
1671 working
.write(JS_O16
);
1673 case 0xf89: if ((prefices
& PREFICES_OPERAND
) != 0)
1674 working
.write(JNS_O32
);
1676 working
.write(JNS_O16
);
1678 case 0xf8a: if ((prefices
& PREFICES_OPERAND
) != 0)
1679 working
.write(JP_O32
);
1681 working
.write(JP_O16
);
1683 case 0xf8b: if ((prefices
& PREFICES_OPERAND
) != 0)
1684 working
.write(JNP_O32
);
1686 working
.write(JNP_O16
);
1688 case 0xf8c: if ((prefices
& PREFICES_OPERAND
) != 0)
1689 working
.write(JL_O32
);
1691 working
.write(JL_O16
);
1693 case 0xf8d: if ((prefices
& PREFICES_OPERAND
) != 0)
1694 working
.write(JNL_O32
);
1696 working
.write(JNL_O16
);
1698 case 0xf8e: if ((prefices
& PREFICES_OPERAND
) != 0)
1699 working
.write(JNG_O32
);
1701 working
.write(JNG_O16
);
1703 case 0xf8f: if ((prefices
& PREFICES_OPERAND
) != 0)
1704 working
.write(JG_O32
);
1706 working
.write(JG_O16
);
1709 case 0xf90: working
.write(SETO
); break; //SETO
1710 case 0xf91: working
.write(SETNO
); break; //SETNO
1711 case 0xf92: working
.write(SETC
); break; //SETC
1712 case 0xf93: working
.write(SETNC
); break; //SETNC
1713 case 0xf94: working
.write(SETZ
); break; //SETZ
1714 case 0xf95: working
.write(SETNZ
); break; //SETNZ
1715 case 0xf96: working
.write(SETNA
); break; //SETNA
1716 case 0xf97: working
.write(SETA
); break; //SETA
1717 case 0xf98: working
.write(SETS
); break; //SETS
1718 case 0xf99: working
.write(SETNS
); break; //SETNS
1719 case 0xf9a: working
.write(SETP
); break; //SETP
1720 case 0xf9b: working
.write(SETNP
); break; //SETNP
1721 case 0xf9c: working
.write(SETL
); break; //SETL
1722 case 0xf9d: working
.write(SETNL
); break; //SETNL
1723 case 0xf9e: working
.write(SETNG
); break; //SETNG
1724 case 0xf9f: working
.write(SETG
); break; //SETG
1726 case 0xfa2: working
.write(CPUID
); break; //CPUID
1728 case 0xfa4: //SHLD Ev, Gv, Ib
1729 case 0xfa5: //SHLD Ev, Gv, CL
1730 if ((prefices
& PREFICES_OPERAND
) != 0)
1731 working
.write(SHLD_O32
);
1733 working
.write(SHLD_O16
);
1736 case 0xfac: //SHRD Ev, Gv, Ib
1737 case 0xfad: //SHRD Ev, Gv, CL
1738 if ((prefices
& PREFICES_OPERAND
) != 0)
1739 working
.write(SHRD_O32
);
1741 working
.write(SHRD_O16
);
1744 // working.write(FXSAVE);
1746 case 0xfb0: //CMPXCHG Eb, Gb
1747 case 0xfb1: //CMPXCHG Ev, Gv
1748 working
.write(CMPXCHG
); break;
1750 case 0xfa3: //BT Ev, Gv
1751 switch (modrm
& 0xc7) {
1752 default: working
.write(BT_MEM
); break;
1762 if ((prefices
& PREFICES_OPERAND
) != 0)
1763 working
.write(BT_O32
);
1765 working
.write(BT_O16
);
1769 case 0xfab: //BTS Ev, Gv
1770 switch (modrm
& 0xc7) {
1771 default: working
.write(BTS_MEM
); break;
1781 if ((prefices
& PREFICES_OPERAND
) != 0)
1782 working
.write(BTS_O32
);
1784 working
.write(BTS_O16
);
1788 case 0xfb3: //BTR Ev, Gv
1789 switch (modrm
& 0xc7) {
1790 default: working
.write(BTR_MEM
); break;
1800 if((prefices
& PREFICES_OPERAND
) != 0)
1801 working
.write(BTR_O32
);
1803 working
.write(BTR_O16
);
1807 case 0xfbb: //BTC Ev, Gv
1808 switch (modrm
& 0xc7) {
1809 default: working
.write(BTC_MEM
); break;
1819 if((prefices
& PREFICES_OPERAND
) != 0)
1820 working
.write(BTC_O32
);
1822 working
.write(BTC_O16
);
1826 case 0xfba: //Grp 8 Ev, Ib
1827 switch (modrm
& 0x38) {
1829 switch (modrm
& 0xc7) {
1830 default: working
.write(BT_MEM
); break;
1831 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1832 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1833 if((prefices
& PREFICES_OPERAND
) != 0)
1834 working
.write(BT_O32
);
1836 working
.write(BT_O16
);
1840 switch (modrm
& 0xc7) {
1841 default: working
.write(BTS_MEM
); break;
1842 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1843 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1844 if((prefices
& PREFICES_OPERAND
) != 0)
1845 working
.write(BTS_O32
);
1847 working
.write(BTS_O16
);
1851 switch (modrm
& 0xc7) {
1852 default: working
.write(BTR_MEM
); break;
1853 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1854 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1855 if((prefices
& PREFICES_OPERAND
) != 0)
1856 working
.write(BTR_O32
);
1858 working
.write(BTR_O16
);
1862 switch (modrm
& 0xc7) {
1863 default: working
.write(BTC_MEM
); break;
1864 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1865 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1866 if((prefices
& PREFICES_OPERAND
) != 0)
1867 working
.write(BTC_O32
);
1869 working
.write(BTC_O16
);
1872 default: throw new IllegalStateException("Invalid Gp 8 Instruction 0F BA /" + ((modrm
& 0x38) >> 3) + "?");
1875 case 0xfbc: working
.write(BSF
); break; //BSF Gv, Ev
1876 case 0xfbd: working
.write(BSR
); break; //BSR Gv, Ev
1878 case 0xfbe: //MOVSX Gv, Eb
1879 if((prefices
& PREFICES_OPERAND
) != 0)
1880 working
.write(SIGN_EXTEND_8_32
);
1882 working
.write(SIGN_EXTEND_8_16
);
1884 case 0xfbf: //MOVSX Gv, Ew
1885 if((prefices
& PREFICES_OPERAND
) != 0)
1886 working
.write(SIGN_EXTEND_16_32
);
1890 switch (modrm
& 0x38)
1892 case 0x08: working
.write(CMPXCHG8B
); break;
1893 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm
& 0x38) >> 3) + "?");
1905 working
.write(BSWAP
); break;
1907 case 0xf20: //MOV Rd, Cd
1908 case 0xf21: //MOV Rd, Dd
1909 case 0xf22: //MOV Cd, Rd
1910 case 0xf23: //MOV Dd, Rd
1911 case 0xfb2: //LSS Mp
1912 case 0xfb4: //LFS Mp
1913 case 0xfb5: //LGS Mp
1914 case 0xfb6: //MOVZX Gv, Eb
1915 case 0xfb7: //MOVZX Gv, Ew
1919 switch (modrm
& 0x38)
1921 case 0x00: working
.write(FADD
); break;
1922 case 0x08: working
.write(FMUL
); break;
1924 case 0x18: working
.write(FCOM
); break;
1926 case 0x28: working
.write(FSUB
); break;
1928 case 0x38: working
.write(FDIV
); break;
1933 if((modrm
& 0xc0) != 0xc0) {
1934 switch (modrm
& 0x38) {
1935 case 0x00: working
.write(FPUSH
); break;
1941 if((prefices
& PREFICES_OPERAND
) != 0)
1942 working
.write(FLDENV_28
);
1944 working
.write(FLDENV_14
);
1947 if((prefices
& PREFICES_OPERAND
) != 0)
1948 working
.write(FSTENV_28
);
1950 working
.write(FSTENV_14
);
1954 switch (modrm
& 0xf8) {
1955 case 0xc0: working
.write(FPUSH
); break;
1960 case 0xe0: working
.write(FCHS
); break;
1961 case 0xe1: working
.write(FABS
); break;
1962 case 0xe4: working
.write(FCOM
); break;
1963 case 0xe5: working
.write(FXAM
); break;
1970 case 0xee: working
.write(FPUSH
); break;
1971 case 0xf0: working
.write(F2XM1
); break;
1972 case 0xf1: working
.write(FYL2X
); break;
1973 case 0xf2: working
.write(FPTAN
); break;
1974 case 0xf3: working
.write(FPATAN
); break;
1975 case 0xf4: working
.write(FXTRACT
); break;
1976 case 0xf5: working
.write(FPREM1
); break;
1977 case 0xf6: working
.write(FDECSTP
); break;
1978 case 0xf7: working
.write(FINCSTP
); break;
1979 case 0xf8: working
.write(FPREM
); break;
1980 case 0xf9: working
.write(FYL2XP1
); break;
1981 case 0xfa: working
.write(FSQRT
); break;
1982 case 0xfb: working
.write(FSINCOS
); break;
1983 case 0xfc: working
.write(FRNDINT
); break;
1984 case 0xfd: working
.write(FSCALE
); break;
1985 case 0xfe: working
.write(FSIN
); break;
1986 case 0xff: working
.write(FCOS
); break;
1992 if((modrm
& 0xc0) != 0xc0) {
1993 switch (modrm
& 0x38) {
1994 case 0x00: working
.write(FADD
); break;
1995 case 0x08: working
.write(FMUL
); break;
1997 case 0x18: working
.write(FCOM
); break;
1999 case 0x28: working
.write(FSUB
); break;
2001 case 0x38: working
.write(FDIV
); break;
2004 switch (modrm
& 0xf8) {
2005 case 0xc0: working
.write(FCMOVB
); break;
2006 case 0xc8: working
.write(FCMOVE
); break;
2007 case 0xd0: working
.write(FCMOVBE
); break;
2008 case 0xd8: working
.write(FCMOVU
); break;
2012 case 0xe9: working
.write(FUCOM
); break;
2018 if ((modrm
& 0xc0) != 0xc0)
2020 switch (modrm
& 0x38)
2022 case 0x00: working
.write(FPUSH
); break;
2023 case 0x08: working
.write(FCHOP
); break;
2025 case 0x18: working
.write(FRNDINT
); break;
2026 case 0x28: working
.write(FPUSH
); break;
2032 switch (modrm
& 0xf8)
2034 case 0xc0: working
.write(FCMOVNB
); break;
2035 case 0xc8: working
.write(FCMOVNE
); break;
2036 case 0xd0: working
.write(FCMOVNBE
); break;
2037 case 0xd8: working
.write(FCMOVNU
); break;
2038 case 0xe8: working
.write(FUCOMI
); break;
2039 case 0xf0: working
.write(FCOMI
); break;
2043 case 0xe2: working
.write(FCLEX
); break;
2044 case 0xe3: working
.write(FINIT
); break;
2051 switch (modrm
& 0x38)
2053 case 0x00: working
.write(FADD
); break;
2054 case 0x08: working
.write(FMUL
); break;
2056 case 0x18: working
.write(FCOM
); break;
2058 case 0x28: working
.write(FSUB
); break;
2060 case 0x38: working
.write(FDIV
); break;
2065 if ((modrm
& 0xc0) != 0xc0)
2067 switch (modrm
& 0x38)
2069 case 0x00: working
.write(FPUSH
); break;
2070 case 0x08: working
.write(FCHOP
); break;
2075 if ((prefices
& PREFICES_OPERAND
) != 0)
2076 working
.write(FRSTOR_108
);
2078 working
.write(FRSTOR_94
);
2081 if ((prefices
& PREFICES_OPERAND
) != 0)
2082 working
.write(FSAVE_108
);
2084 working
.write(FSAVE_94
);
2090 switch (modrm
& 0xf8)
2092 case 0xc0: working
.write(FFREE
); break;
2096 case 0xe8: working
.write(FUCOM
); break;
2104 case 0xd9: working
.write(FCOM
); break;
2106 switch (modrm
& 0x38)
2108 case 0x00: working
.write(FADD
); break;
2109 case 0x08: working
.write(FMUL
); break;
2111 case 0x18: working
.write(FCOM
); break;
2113 case 0x28: working
.write(FSUB
); break;
2115 case 0x38: working
.write(FDIV
); break;
2121 if ((modrm
& 0xc0) != 0xc0)
2123 switch (modrm
& 0x38)
2125 case 0x00: working
.write(FPUSH
); break;
2126 case 0x08: working
.write(FCHOP
); break;
2129 case 0x38: working
.write(FRNDINT
); break;
2130 case 0x20: working
.write(FBCD2F
); break;
2131 case 0x28: working
.write(FPUSH
); break;
2132 case 0x30: working
.write(FF2BCD
); break;
2137 switch (modrm
& 0xf8)
2139 case 0xe8: working
.write(FUCOMI
); break;
2140 case 0xf0: working
.write(FCOMI
); break;
2148 private void writeFlags(int prefices
, int opcode
, int modrm
)
2151 case 0x00: //ADD Eb, Gb
2152 case 0x02: //ADD Gb, Eb
2153 case 0x04: //ADD AL, Ib
2154 case 0xfc0: //XADD Eb, Gb
2155 working
.write(ADD_O8_FLAGS
); break;
2157 case 0x10: //ADC Eb, Gb
2158 case 0x12: //ADC Gb, Eb
2159 case 0x14: //ADC AL, Ib
2160 working
.write(ADC_O8_FLAGS
); break;
2162 case 0x18: //SBB Eb, Gb
2163 case 0x1a: //SBB Gb, Eb
2164 case 0x1c: //SBB AL, Ib
2165 working
.write(SBB_O8_FLAGS
); break;
2167 case 0x28: //SUB Eb, Gb
2168 case 0x2a: //SUB Gb, Eb
2169 case 0x2c: //SUB AL, Ib
2170 case 0x38: //CMP Eb, Gb
2171 case 0x3a: //CMP Gb, Eb
2172 case 0x3c: //CMP AL, Ib
2173 working
.write(SUB_O8_FLAGS
); break;
2175 case 0x01: //ADD Ev, Gv
2176 case 0x03: //ADD Gv, Ev
2177 case 0x05: //ADD eAX, Iv
2178 case 0xfc1: //XADD Ev, Gv
2179 if ((prefices
& PREFICES_OPERAND
) != 0)
2180 working
.write(ADD_O32_FLAGS
);
2182 working
.write(ADD_O16_FLAGS
);
2185 case 0x11: //ADC Ev, Gv
2186 case 0x13: //ADC Gv, Ev
2187 case 0x15: //ADC eAX, Iv
2188 if ((prefices
& PREFICES_OPERAND
) != 0)
2189 working
.write(ADC_O32_FLAGS
);
2191 working
.write(ADC_O16_FLAGS
);
2194 case 0x19: //SBB Ev, Gv
2195 case 0x1b: //SBB Gv, Ev
2196 case 0x1d: //SBB eAX, Iv
2197 if ((prefices
& PREFICES_OPERAND
) != 0)
2198 working
.write(SBB_O32_FLAGS
);
2200 working
.write(SBB_O16_FLAGS
);
2203 case 0x29: //SUB Ev, Gv
2204 case 0x2b: //SUB Gv, Ev
2205 case 0x2d: //SUB eAX, Iv
2206 case 0x39: //CMP Ev, Gv
2207 case 0x3b: //CMP Gv, Ev
2208 case 0x3d: //CMP eAX, Iv
2209 if ((prefices
& PREFICES_OPERAND
) != 0)
2210 working
.write(SUB_O32_FLAGS
);
2212 working
.write(SUB_O16_FLAGS
);
2215 case 0x08: //OR Eb, Gb
2216 case 0x0a: //OR Gb, Eb
2217 case 0x0c: //OR AL, Ib
2218 case 0x20: //AND Eb, Gb
2219 case 0x22: //AND Gb, Eb
2220 case 0x24: //AND AL, Ib
2221 case 0x30: //XOR Eb, Gb
2222 case 0x32: //XOR Gb, Eb
2223 case 0x34: //XOR AL, Ib
2224 case 0x84: //TEST Eb, Gb
2225 case 0xa8: //TEST AL, Ib
2226 working
.write(BITWISE_FLAGS_O8
); break;
2228 case 0x09: //OR Ev, Gv
2229 case 0x0b: //OR Gv, Ev
2230 case 0x0d: //OR eAX, Iv
2231 case 0x21: //AND Ev, Gv
2232 case 0x23: //AND Gv, Ev
2233 case 0x25: //AND eAX, Iv
2234 case 0x31: //XOR Ev, Gv
2235 case 0x33: //XOR Gv, Ev
2236 case 0x35: //XOR eAX, Iv
2237 case 0x85: //TEST Ev, Gv
2238 case 0xa9: //TEST eAX, Iv
2239 if ((prefices
& PREFICES_OPERAND
) != 0)
2240 working
.write(BITWISE_FLAGS_O32
);
2242 working
.write(BITWISE_FLAGS_O16
);
2245 case 0x40: //INC eAX
2246 case 0x41: //INC eCX
2247 case 0x42: //INC eDX
2248 case 0x43: //INC eBX
2249 case 0x44: //INC eSP
2250 case 0x45: //INC eBP
2251 case 0x46: //INC eSI
2252 case 0x47: //INC eDI
2253 if ((prefices
& PREFICES_OPERAND
) != 0)
2254 working
.write(INC_O32_FLAGS
);
2256 working
.write(INC_O16_FLAGS
);
2259 case 0x48: //DEC eAX
2260 case 0x49: //DEC eCX
2261 case 0x4a: //DEC eDX
2262 case 0x4b: //DEC eBX
2263 case 0x4c: //DEC eSP
2264 case 0x4d: //DEC eBP
2265 case 0x4e: //DEC eSI
2266 case 0x4f: //DEC eDI
2267 if ((prefices
& PREFICES_OPERAND
) != 0)
2268 working
.write(DEC_O32_FLAGS
);
2270 working
.write(DEC_O16_FLAGS
);
2273 case 0x80: //IMM GP1 Eb, Ib
2274 case 0x82: //IMM GP1 Eb, Ib
2275 switch (modrm
& 0x38) {
2277 working
.write(ADD_O8_FLAGS
); break;
2279 working
.write(BITWISE_FLAGS_O8
); break;
2281 working
.write(ADC_O8_FLAGS
); break;
2283 working
.write(SBB_O8_FLAGS
); break;
2285 working
.write(BITWISE_FLAGS_O8
); break;
2288 working
.write(SUB_O8_FLAGS
); break;
2290 working
.write(BITWISE_FLAGS_O8
); break;
2294 case 0x81: //IMM GP1 Ev, Iv
2295 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
2296 if ((prefices
& PREFICES_OPERAND
) != 0) {
2297 switch (modrm
& 0x38) {
2299 working
.write(ADD_O32_FLAGS
); break;
2301 working
.write(BITWISE_FLAGS_O32
); break;
2303 working
.write(ADC_O32_FLAGS
); break;
2305 working
.write(SBB_O32_FLAGS
); break;
2307 working
.write(BITWISE_FLAGS_O32
); break;
2310 working
.write(SUB_O32_FLAGS
); break;
2312 working
.write(BITWISE_FLAGS_O32
); break;
2315 switch (modrm
& 0x38) {
2317 working
.write(ADD_O16_FLAGS
); break;
2319 working
.write(BITWISE_FLAGS_O16
); break;
2321 working
.write(ADC_O16_FLAGS
); break;
2323 working
.write(SBB_O16_FLAGS
); break;
2325 working
.write(BITWISE_FLAGS_O16
); break;
2328 working
.write(SUB_O16_FLAGS
); break;
2330 working
.write(BITWISE_FLAGS_O16
); break;
2338 switch (modrm
& 0x38) {
2340 working
.write(ROL_O8_FLAGS
); break;
2342 working
.write(ROR_O8_FLAGS
); break;
2344 working
.write(RCL_O8_FLAGS
); break;
2346 working
.write(RCR_O8_FLAGS
); break;
2348 working
.write(SHL_O8_FLAGS
); break;
2350 working
.write(SHR_O8_FLAGS
); break;
2352 System
.err
.println("Emulated: invalid SHL encoding");
2353 working
.write(SHL_O8_FLAGS
); break;
2355 working
.write(SAR_O8_FLAGS
); break;
2362 if ((prefices
& PREFICES_OPERAND
) != 0) {
2363 switch (modrm
& 0x38) {
2365 working
.write(ROL_O32_FLAGS
); break;
2367 working
.write(ROR_O32_FLAGS
); break;
2369 working
.write(RCL_O32_FLAGS
); break;
2371 working
.write(RCR_O32_FLAGS
); break;
2373 working
.write(SHL_O32_FLAGS
); break;
2375 working
.write(SHR_O32_FLAGS
); break;
2377 working
.write(SHL_O32_FLAGS
); break;
2379 working
.write(SAR_O32_FLAGS
); break;
2382 switch (modrm
& 0x38) {
2384 working
.write(ROL_O16_FLAGS
); break;
2386 working
.write(ROR_O16_FLAGS
); break;
2388 working
.write(RCL_O16_FLAGS
); break;
2390 working
.write(RCR_O16_FLAGS
); break;
2392 working
.write(SHL_O16_FLAGS
); break;
2394 working
.write(SHR_O16_FLAGS
); break;
2396 working
.write(SHL_O16_FLAGS
); break;
2398 working
.write(SAR_O16_FLAGS
); break;
2403 case 0xf6: //UNA GP3 Eb
2404 switch (modrm
& 0x38) {
2406 working
.write(BITWISE_FLAGS_O8
); break;
2408 working
.write(NEG_O8_FLAGS
); break;
2412 case 0xf7: //UNA GP3 Ev
2413 if ((prefices
& PREFICES_OPERAND
) != 0) {
2414 switch (modrm
& 0x38) {
2416 working
.write(BITWISE_FLAGS_O32
); break;
2418 working
.write(NEG_O32_FLAGS
); break;
2421 switch (modrm
& 0x38) {
2423 working
.write(BITWISE_FLAGS_O16
); break;
2425 working
.write(NEG_O16_FLAGS
); break;
2431 switch (modrm
& 0x38) {
2433 working
.write(INC_O8_FLAGS
); break;
2435 working
.write(DEC_O8_FLAGS
); break;
2440 switch (modrm
& 0x38) {
2442 if ((prefices
& PREFICES_OPERAND
) != 0)
2443 working
.write(INC_O32_FLAGS
);
2445 working
.write(INC_O16_FLAGS
);
2448 if ((prefices
& PREFICES_OPERAND
) != 0)
2449 working
.write(DEC_O32_FLAGS
);
2451 working
.write(DEC_O16_FLAGS
);
2459 case 0x58: //POP eAX
2460 case 0x59: //POP eCX
2461 case 0x5a: //POP eDX
2462 case 0x5b: //POP eBX
2463 case 0x5d: //POP eBP
2464 case 0x5e: //POP eSI
2465 case 0x5f: //POP eDI
2466 case 0xfa1: //POP FS
2467 case 0xfa9: working
.write(STORE1_ESP
); break; //POP GS
2470 case 0x8f: //POP Ev This is really annoying and not quite correct?
2471 for (int i
= 0; i
< working
.getLength(); i
++) {
2472 switch (working
.getMicrocodeAt(i
)) {
2475 working
.replace(i
, ADDR_REG1
);
2478 working
.replace(i
, ADDR_2REG1
);
2481 working
.replace(i
, ADDR_4REG1
);
2484 working
.replace(i
, ADDR_8REG1
);
2493 switch (working
.getMicrocodeAt(working
.getLength() - 1)) {
2495 case STORE0_SP
: break;
2496 default: working
.write(STORE1_ESP
);
2501 switch (prefices
& PREFICES_OPERAND
) {
2503 working
.write(STORE0_FLAGS
); break;
2504 case PREFICES_OPERAND
:
2505 working
.write(STORE0_EFLAGS
); break;
2509 case 0xf1f: break; //NOP
2510 case 0xfa4: //SHLD Ev, Gv, Ib
2511 case 0xfa5: //SHLD Ev, Gv, CL
2512 if ((prefices
& PREFICES_OPERAND
) != 0)
2513 working
.write(SHL_O32_FLAGS
);
2515 working
.write(SHL_O16_FLAGS
);
2518 case 0xfac: //SHRD Ev, Gv, Ib
2519 case 0xfad: //SHRD Ev, Gv, CL
2520 if ((prefices
& PREFICES_OPERAND
) != 0)
2521 working
.write(SHR_O32_FLAGS
);
2523 working
.write(SHR_O16_FLAGS
);
2526 case 0xfb0: //CMPXCHG Eb, Gb
2527 working
.write(CMPXCHG_O8_FLAGS
); break;
2528 case 0xfb1: //CMPXCHG Ev, Gv
2529 if ((prefices
& PREFICES_OPERAND
) != 0)
2530 working
.write(CMPXCHG_O32_FLAGS
);
2532 working
.write(CMPXCHG_O16_FLAGS
);
2535 case 0x06: //PUSH ES
2536 case 0x0e: //PUSH CS
2538 case 0x16: //PUSH SS
2539 case 0x1e: //PUSH DS
2547 case 0x50: //PUSH eAX
2548 case 0x51: //PUSH eCX
2549 case 0x52: //PUSH eDX
2550 case 0x53: //PUSH eBX
2551 case 0x54: //PUSH eSP
2552 case 0x55: //PUSH eBP
2553 case 0x56: //PUSH eSI
2554 case 0x57: //PUSH eDI
2555 case 0x5c: //POP eSP so don't write incremented stack pointer back
2557 case 0x60: //PUSHA/D
2560 case 0x63: //#UD (ARPL)
2561 case 0x68: //PUSH Iv
2562 case 0x69: //IMUL Gv, Ev, Iv
2563 case 0x6a: //PUSH Ib
2564 case 0x6b: //IMUL Gv, Ev, Ib
2568 case 0x6f: //OUTSW/D
2587 case 0x86: //XCHG Eb, Gb
2588 case 0x87: //XCHG Ev, Gv
2589 case 0x88: //MOV Eb, Gb
2590 case 0x89: //MOV Ev, Gv
2591 case 0x8a: //MOV Gb, Eb
2592 case 0x8b: //MOV Gv, Ev
2593 case 0x8c: //MOV Ew, Sw
2594 case 0x8d: //LEA Gv, M
2595 case 0x8e: //MOV Sw, Ew
2598 case 0x91: //XCHG eAX, eCX
2599 case 0x92: //XCHG eAX, eCX
2600 case 0x93: //XCHG eAX, eCX
2601 case 0x94: //XCHG eAX, eCX
2602 case 0x95: //XCHG eAX, eCX
2603 case 0x96: //XCHG eAX, eCX
2604 case 0x97: //XCHG eAX, eCX
2605 case 0x98: //CBW/CWDE
2606 case 0x99: //CWD/CDQ
2607 case 0x9a: //CALLF Ap
2614 case 0xa0: //MOV AL, Ob
2615 case 0xa1: //MOV eAX, Ov
2616 case 0xa2: //MOV Ob, AL
2617 case 0xa3: //MOV Ov, eAX
2619 case 0xa5: //MOVSW/D
2621 case 0xa7: //CMPSW/D
2623 case 0xab: //STOSW/D
2625 case 0xad: //LODSW/D
2627 case 0xaf: //SCASW/D
2629 case 0xb0: //MOV AL, Ib
2630 case 0xb1: //MOV CL, Ib
2631 case 0xb2: //MOV DL, Ib
2632 case 0xb3: //MOV BL, Ib
2633 case 0xb4: //MOV AH, Ib
2634 case 0xb5: //MOV CH, Ib
2635 case 0xb6: //MOV DH, Ib
2636 case 0xb7: //MOV BH, Ib
2637 case 0xb8: //MOV eAX, Iv
2638 case 0xb9: //MOV eCX, Iv
2639 case 0xba: //MOV eDX, Iv
2640 case 0xbb: //MOV eBX, Iv
2641 case 0xbc: //MOV eSP, Iv
2642 case 0xbd: //MOV eBP, Iv
2643 case 0xbe: //MOV eSI, Iv
2644 case 0xbf: //MOV eDI, Iv
2650 case 0xc6: //MOV GP11 Eb, Gb
2651 case 0xc7: //MOV GP11 Ev, Gv
2654 case 0xca: //RETF Iw
2669 case 0xe4: //IN AL, Ib
2670 case 0xe5: //IN eAX, Ib
2671 case 0xe6: //OUT Ib, AL
2672 case 0xe7: //OUT Ib, eAX
2673 case 0xe8: //CALL Jv
2675 case 0xea: //JMPF Ap
2677 case 0xec: //IN AL, DX
2678 case 0xed: //IN eAX, DX
2679 case 0xee: //OUT DX, AL
2680 case 0xef: //OUT DX, eAX
2691 case 0xf00: //Group 6
2692 case 0xf01: //Group 7
2693 case 0xf02: //LAR Gv, Ew
2694 case 0xf03: //LSL Gv, Ew
2696 case 0xf09: //WBINVD
2698 case 0xf20: //MOV Rd, Cd
2699 case 0xf21: //MOV Rd, Dd
2700 case 0xf22: //MOV Cd, Rd
2701 case 0xf23: //MOV Dd, Rd
2705 case 0xf34: //SYSENTER
2706 case 0xf35: //SYSEXIT
2708 case 0xf41: //CMOVNO
2710 case 0xf43: //CMOVNC
2712 case 0xf45: //CMOVNZ
2713 case 0xf46: //CMOVBE
2714 case 0xf47: //CMOVNBE
2716 case 0xf49: //CMOVNS
2718 case 0xf4b: //CMOVNP
2720 case 0xf4d: //CMOVNL
2721 case 0xf4e: //CMOVLE
2722 case 0xf4f: //CMOVNLE
2724 case 0xf81: //JNO Jv
2726 case 0xf83: //JNC Jv
2728 case 0xf85: //JNZ Jv
2729 case 0xf86: //JNA Jv
2732 case 0xf89: //JNS Jv
2734 case 0xf8b: //JNP Jv
2736 case 0xf8d: //JNL Jv
2737 case 0xf8e: //JNG Jv
2755 case 0xfa0: //PUSH FS
2757 case 0xfa8: //PUSH GS
2758 case 0xfaf: //IMUL Gv, Ev
2759 case 0xfa3: //BT Ev, Gv
2760 case 0xfab: //BTS Ev, Gv
2761 case 0xfb3: //BTR Ev, Gv
2762 case 0xfbb: //BTC Ev, Gv
2763 case 0xfb2: //LSS Mp
2764 case 0xfb4: //LFS Mp
2765 case 0xfb5: //LGS Mp
2766 case 0xfb6: //MOVZX Gv, Eb
2767 case 0xfb7: //MOVZX Gv, Ew
2768 case 0xfba: //Grp 8 Ev, Ib
2769 case 0xfbc: //BSF Gv, Ev
2770 case 0xfbd: //BSR Gv, Ev
2771 case 0xfbe: //MOVSX Gv, Eb
2772 case 0xfbf: //MOVSX Gv, Ew
2774 case 0xfc8: //BSWAP EAX
2775 case 0xfc9: //BSWAP ECX
2776 case 0xfca: //BSWAP EDX
2777 case 0xfcb: //BSWAP EBX
2778 case 0xfcc: //BSWAP ESP
2779 case 0xfcd: //BSWAP EBP
2780 case 0xfce: //BSWAP ESI
2781 case 0xfcf: //BSWAP EDI
2782 case 0xd800: // FPU OPS
2783 case 0xd900: // FPU OPS
2784 case 0xda00: // FPU OPS
2785 case 0xdb00: // FPU OPS
2786 case 0xdc00: // FPU OPS
2787 case 0xdd00: // FPU OPS
2788 case 0xde00: // FPU OPS
2789 case 0xdf00: // FPU OPS
2790 case 0x0fff: // Undefined instruction used by win 95
2794 throw new IllegalStateException("Missing Flags: 0x" + Integer
.toHexString(opcode
));
2798 private void writeInputOperands(int prefices
, int opcode
, int modrm
, int sib
, int displacement
, long immediate
)
2801 case 0x00: //ADD Eb, Gb
2802 case 0x08: //OR Eb, Gb
2803 case 0x10: //ADC Eb, Gb
2804 case 0x18: //SBB Eb, Gb
2805 case 0x20: //AND Eb, Gb
2806 case 0x28: //SUB Eb, Gb
2807 case 0x30: //XOR Eb, Gb
2808 case 0x38: //CMP Eb, Gb
2809 case 0x84: //TEST Eb, Gb
2810 case 0x86: //XCHG Eb, Gb
2811 load0_Eb(prefices
, modrm
, sib
, displacement
);
2815 case 0x88: //MOV Eb, Gb
2819 case 0x02: //ADD Gb, Eb
2820 case 0x0a: //OR Gb, Eb
2821 case 0x12: //ADC Gb, Eb
2822 case 0x1a: //SBB Gb, Eb
2823 case 0x22: //AND Gb, Eb
2824 case 0x2a: //SUB Gb, Eb
2825 case 0x32: //XOR Gb, Eb
2826 case 0x3a: //CMP Gb, Eb
2827 case 0xfc0: //XADD Eb, Gb
2829 load1_Eb(prefices
, modrm
, sib
, displacement
);
2832 case 0x8a: //MOV Gb, Eb
2833 case 0xfb6: //MOVZX Gv, Eb
2834 case 0xfbe: //MOVSX Gv, Eb
2835 load0_Eb(prefices
, modrm
, sib
, displacement
);
2838 case 0x01: //ADD Ev, Gv
2839 case 0x09: //OR Ev, Gv
2840 case 0x11: //ADC Ev, Gv
2841 case 0x19: //SBB Ev, Gv
2842 case 0x21: //AND Ev, Gv
2843 case 0x29: //SUB Ev, Gv
2844 case 0x31: //XOR Ev, Gv
2845 case 0x39: //CMP Ev, Gv
2846 case 0x85: //TEST Ev, Gv
2847 case 0x87: //XCHG Ev, Gv
2848 if ((prefices
& PREFICES_OPERAND
) != 0) {
2849 load0_Ed(prefices
, modrm
, sib
, displacement
);
2852 load0_Ew(prefices
, modrm
, sib
, displacement
);
2857 case 0x89: //MOV Ev, Gv
2858 if ((prefices
& PREFICES_OPERAND
) != 0) {
2865 case 0x03: //ADD Gv, Ev
2866 case 0x0b: //OR Gv, Ev
2867 case 0x13: //ADC Gv, Ev
2868 case 0x1b: //SBB Gv, Ev
2869 case 0x23: //AND Gv, Ev
2870 case 0x2b: //SUB Gv, Ev
2871 case 0x33: //XOR Gv, Ev
2872 case 0x3b: //CMP Gv, Ev
2873 case 0xfaf: //IMUL Gv, Ev
2874 case 0xfbc: //BSF Gv, Ev
2875 case 0xfbd: //BSR Gv, Ev
2876 case 0xfc1: //XADD Ev, Gv
2877 if ((prefices
& PREFICES_OPERAND
) != 0) {
2879 load1_Ed(prefices
, modrm
, sib
, displacement
);
2882 load1_Ew(prefices
, modrm
, sib
, displacement
);
2886 case 0x8b: //MOV Gv, Ev
2887 if ((prefices
& PREFICES_OPERAND
) != 0) {
2888 load0_Ed(prefices
, modrm
, sib
, displacement
);
2890 load0_Ew(prefices
, modrm
, sib
, displacement
);
2894 case 0xf02: //LAR Gv, Ew
2895 case 0xf03: //LSL Gv, Ew
2896 if ((prefices
& PREFICES_OPERAND
) != 0) {
2897 load0_Ew(prefices
, modrm
, sib
, displacement
);
2900 load0_Ew(prefices
, modrm
, sib
, displacement
);
2906 case 0xf41: //CMOVNO
2908 case 0xf43: //CMOVNC
2910 case 0xf45: //CMOVNZ
2911 case 0xf46: //CMOVBE
2912 case 0xf47: //CMOVNBE
2914 case 0xf49: //CMOVNS
2916 case 0xf4b: //CMOVNP
2918 case 0xf4d: //CMOVNL
2919 case 0xf4e: //CMOVLE
2920 case 0xf4f: //CMOVNLE
2921 if ((prefices
& PREFICES_OPERAND
) != 0) {
2923 load1_Ed(prefices
, modrm
, sib
, displacement
);
2926 load1_Ew(prefices
, modrm
, sib
, displacement
);
2930 case 0x8d: //LEA Gv, M
2931 load0_M(prefices
, modrm
, sib
, displacement
);
2935 case 0x80: //IMM G1 Eb, Ib
2936 case 0x82: //IMM G1 Eb, Ib
2937 case 0xc0: //SFT G2 Eb, Ib
2938 load0_Eb(prefices
, modrm
, sib
, displacement
);
2939 working
.write(LOAD1_IB
);
2940 working
.write((int)immediate
);
2943 case 0xc6: //MOV G11 Eb, Ib
2944 case 0xb0: //MOV AL, Ib
2945 case 0xb1: //MOV CL, Ib
2946 case 0xb2: //MOV DL, Ib
2947 case 0xb3: //MOV BL, Ib
2948 case 0xb4: //MOV AH, Ib
2949 case 0xb5: //MOV CH, Ib
2950 case 0xb6: //MOV DH, Ib
2951 case 0xb7: //MOV BH, Ib
2952 case 0xe4: //IN AL, Ib
2972 case 0xe0: //LOOPNZ Jb
2973 case 0xe1: //LOOPZ Jb
2974 case 0xe2: //LOOP Jb
2975 case 0xe3: //JCXZ Jb
2977 case 0xe5: //IN eAX, Ib
2978 working
.write(LOAD0_IB
);
2979 working
.write((int)immediate
);
2982 case 0x81: //IMM G1 Ev, Iv
2983 if ((prefices
& PREFICES_OPERAND
) != 0) {
2984 load0_Ed(prefices
, modrm
, sib
, displacement
);
2985 working
.write(LOAD1_ID
);
2986 working
.write((int)immediate
);
2988 load0_Ew(prefices
, modrm
, sib
, displacement
);
2989 working
.write(LOAD1_IW
);
2990 working
.write((int)immediate
);
2994 case 0xc7: //MOV G11 Ev, Iv
2995 case 0x68: //PUSH Iv
2996 case 0x6a: //PUSH Ib
2997 case 0xe8: //CALL Jv
3000 case 0xf81: //JNO Jv
3002 case 0xf83: //JNC Jv
3004 case 0xf85: //JNZ Jv
3005 case 0xf86: //JNA Jv
3008 case 0xf89: //JNS Jv
3010 case 0xf8b: //JNP Jv
3012 case 0xf8d: //JNL Jv
3013 case 0xf8e: //JNG Jv
3015 if ((prefices
& PREFICES_OPERAND
) != 0) {
3016 working
.write(LOAD0_ID
);
3017 working
.write((int)immediate
);
3019 working
.write(LOAD0_IW
);
3020 working
.write((int)immediate
);
3024 case 0xc1: //SFT G2 Ev, Ib
3025 if ((prefices
& PREFICES_OPERAND
) != 0) {
3026 load0_Ed(prefices
, modrm
, sib
, displacement
);
3027 working
.write(LOAD1_IB
);
3028 working
.write((int)immediate
);
3030 load0_Ew(prefices
, modrm
, sib
, displacement
);
3031 working
.write(LOAD1_IB
);
3032 working
.write((int)immediate
);
3036 case 0x83: //IMM G1 Ev, Ib sign extend the byte to 16/32 bits
3037 if ((prefices
& PREFICES_OPERAND
) != 0) {
3038 load0_Ed(prefices
, modrm
, sib
, displacement
);
3039 working
.write(LOAD1_ID
);
3040 working
.write((int)immediate
);
3042 load0_Ew(prefices
, modrm
, sib
, displacement
);
3043 working
.write(LOAD1_IW
);
3044 working
.write((int)immediate
);
3049 case 0x58: //POP eAX
3050 case 0x59: //POP eCX
3051 case 0x5a: //POP eDX
3052 case 0x5b: //POP eBX
3053 case 0x5c: //POP eSP
3054 case 0x5d: //POP eBP
3055 case 0x5e: //POP eSI
3056 case 0x5f: //POP eDI
3063 case 0xca: //RETF Iw
3064 working
.write(LOAD0_IW
);
3065 working
.write((int)immediate
);
3068 case 0x9a: //CALLF Ap
3069 case 0xea: //JMPF Ap
3070 if ((prefices
& PREFICES_OPERAND
) != 0) {
3071 working
.write(LOAD0_ID
);
3072 working
.write((int)immediate
);
3073 working
.write(LOAD1_IW
);
3074 working
.write((int)(immediate
>>> 32));
3076 working
.write(LOAD0_IW
);
3077 working
.write((int)(0xffff & immediate
));
3078 working
.write(LOAD1_IW
);
3079 working
.write((int)(immediate
>>> 16));
3084 switch (prefices
& PREFICES_OPERAND
) {
3086 working
.write(LOAD0_FLAGS
); break;
3087 case PREFICES_OPERAND
:
3088 working
.write(LOAD0_EFLAGS
); break;
3092 case 0xec: //IN AL, DX
3093 case 0xed: //IN eAX, DX
3094 working
.write(LOAD0_DX
);
3097 case 0xee: //OUT DX, AL
3098 working
.write(LOAD0_DX
);
3099 working
.write(LOAD1_AL
);
3102 case 0xef: //OUT DX, eAX
3103 if ((prefices
& PREFICES_OPERAND
) != 0) {
3104 working
.write(LOAD0_DX
);
3105 working
.write(LOAD1_EAX
);
3107 working
.write(LOAD0_DX
);
3108 working
.write(LOAD1_AX
);
3112 case 0x04: //ADD AL, Ib
3113 case 0x0c: //OR AL, Ib
3114 case 0x14: //ADC AL, Ib
3115 case 0x1c: //SBB AL, Ib
3116 case 0x24: //AND AL, Ib
3117 case 0x2c: //SUB AL, Ib
3118 case 0x34: //XOR AL, Ib
3119 case 0x3c: //CMP AL, Ib
3120 case 0xa8: //TEST AL, Ib
3121 working
.write(LOAD0_AL
);
3122 working
.write(LOAD1_IB
);
3123 working
.write((int)immediate
);
3126 case 0xc8: //ENTER Iw, Ib
3127 working
.write(LOAD0_IW
);
3128 working
.write((int)(0xffffl
& (immediate
>>> 16)));
3129 working
.write(LOAD1_IB
);
3130 working
.write((int)(0xffl
& immediate
));
3133 case 0x69: //IMUL Gv, Ev, Iv
3134 case 0x6b: //IMUL Gv, Ev, Ib
3135 if ((prefices
& PREFICES_OPERAND
) != 0) {
3136 load0_Ed(prefices
, modrm
, sib
, displacement
);
3137 working
.write(LOAD1_ID
);
3138 working
.write((int)immediate
);
3140 load0_Ew(prefices
, modrm
, sib
, displacement
);
3141 working
.write(LOAD1_IW
);
3142 working
.write((int)immediate
);
3146 case 0xe6: //OUT Ib, AL
3147 working
.write(LOAD0_IB
);
3148 working
.write((int)immediate
);
3149 working
.write(LOAD1_AL
);
3152 case 0x05: //ADD eAX, Iv
3153 case 0x0d: //OR eAX, Iv
3154 case 0x15: //ADC eAX, Iv
3155 case 0x1d: //SBB eAX, Iv
3156 case 0x25: //AND eAX, Iv
3157 case 0x2d: //SUB eAX, Iv
3158 case 0x35: //XOR eAX, Iv
3159 case 0x3d: //CMP eAX, Iv
3160 case 0xa9: //TEST eAX, Iv
3161 if ((prefices
& PREFICES_OPERAND
) != 0) {
3162 working
.write(LOAD0_EAX
);
3163 working
.write(LOAD1_ID
);
3164 working
.write((int)immediate
);
3166 working
.write(LOAD0_AX
);
3167 working
.write(LOAD1_IW
);
3168 working
.write((int)immediate
);
3172 case 0xb8: //MOV eAX, Iv
3173 case 0xb9: //MOV eCX, Iv
3174 case 0xba: //MOV eDX, Iv
3175 case 0xbb: //MOV eBX, Iv
3176 case 0xbc: //MOV eSP, Iv
3177 case 0xbd: //MOV eBP, Iv
3178 case 0xbe: //MOV eSI, Iv
3179 case 0xbf: //MOV eDI, Iv
3180 if ((prefices
& PREFICES_OPERAND
) != 0) {
3181 working
.write(LOAD0_ID
);
3182 working
.write((int)immediate
);
3184 working
.write(LOAD0_IW
);
3185 working
.write((int)immediate
);
3189 case 0xe7: //OUT Ib, eAX
3190 if ((prefices
& PREFICES_OPERAND
) != 0) {
3191 working
.write(LOAD0_IB
);
3192 working
.write((int)immediate
);
3193 working
.write(LOAD1_EAX
);
3195 working
.write(LOAD0_IB
);
3196 working
.write((int)immediate
);
3197 working
.write(LOAD1_AX
);
3201 case 0x40: //INC eAX
3202 case 0x48: //DEC eAX
3203 case 0x50: //PUSH eAX
3204 if ((prefices
& PREFICES_OPERAND
) != 0) {
3205 working
.write(LOAD0_EAX
);
3207 working
.write(LOAD0_AX
);
3211 case 0x41: //INC eCX
3212 case 0x49: //DEC eCX
3213 case 0x51: //PUSH eCX
3214 if ((prefices
& PREFICES_OPERAND
) != 0) {
3215 working
.write(LOAD0_ECX
);
3217 working
.write(LOAD0_CX
);
3221 case 0x42: //INC eDX
3222 case 0x4a: //DEC eDX
3223 case 0x52: //PUSH eDX
3224 if ((prefices
& PREFICES_OPERAND
) != 0) {
3225 working
.write(LOAD0_EDX
);
3227 working
.write(LOAD0_DX
);
3231 case 0x43: //INC eBX
3232 case 0x4b: //DEC eBX
3233 case 0x53: //PUSH eBX
3234 if ((prefices
& PREFICES_OPERAND
) != 0) {
3235 working
.write(LOAD0_EBX
);
3237 working
.write(LOAD0_BX
);
3241 case 0x44: //INC eSP
3242 case 0x4c: //DEC eSP
3243 case 0x54: //PUSH eSP
3244 if ((prefices
& PREFICES_OPERAND
) != 0) {
3245 working
.write(LOAD0_ESP
);
3247 working
.write(LOAD0_SP
);
3251 case 0x45: //INC eBP
3252 case 0x4d: //DEC eBP
3253 case 0x55: //PUSH eBP
3254 if ((prefices
& PREFICES_OPERAND
) != 0) {
3255 working
.write(LOAD0_EBP
);
3257 working
.write(LOAD0_BP
);
3261 case 0x46: //INC eSI
3262 case 0x4e: //DEC eSI
3263 case 0x56: //PUSH eSI
3264 if ((prefices
& PREFICES_OPERAND
) != 0) {
3265 working
.write(LOAD0_ESI
);
3267 working
.write(LOAD0_SI
);
3271 case 0x47: //INC eDI
3272 case 0x4f: //DEC eDI
3273 case 0x57: //PUSH eDI
3274 if ((prefices
& PREFICES_OPERAND
) != 0) {
3275 working
.write(LOAD0_EDI
);
3277 working
.write(LOAD0_DI
);
3281 case 0x91: //XCHG eAX, eCX
3282 if ((prefices
& PREFICES_OPERAND
) != 0) {
3283 working
.write(LOAD0_EAX
);
3284 working
.write(LOAD1_ECX
);
3286 working
.write(LOAD0_AX
);
3287 working
.write(LOAD1_CX
);
3291 case 0x92: //XCHG eAX, eDX
3292 if ((prefices
& PREFICES_OPERAND
) != 0) {
3293 working
.write(LOAD0_EAX
);
3294 working
.write(LOAD1_EDX
);
3296 working
.write(LOAD0_AX
);
3297 working
.write(LOAD1_DX
);
3301 case 0x93: //XCHG eAX, eBX
3302 if ((prefices
& PREFICES_OPERAND
) != 0) {
3303 working
.write(LOAD0_EAX
);
3304 working
.write(LOAD1_EBX
);
3306 working
.write(LOAD0_AX
);
3307 working
.write(LOAD1_BX
);
3311 case 0x94: //XCHG eAX, eSP
3312 if ((prefices
& PREFICES_OPERAND
) != 0) {
3313 working
.write(LOAD0_EAX
);
3314 working
.write(LOAD1_ESP
);
3316 working
.write(LOAD0_AX
);
3317 working
.write(LOAD1_SP
);
3321 case 0x95: //XCHG eAX, eBP
3322 if ((prefices
& PREFICES_OPERAND
) != 0) {
3323 working
.write(LOAD0_EAX
);
3324 working
.write(LOAD1_EBP
);
3326 working
.write(LOAD0_AX
);
3327 working
.write(LOAD1_BP
);
3331 case 0x96: //XCHG eAX, eSI
3332 if ((prefices
& PREFICES_OPERAND
) != 0) {
3333 working
.write(LOAD0_EAX
);
3334 working
.write(LOAD1_ESI
);
3336 working
.write(LOAD0_AX
);
3337 working
.write(LOAD1_SI
);
3341 case 0x97: //XCHG eAX, eDI
3342 if ((prefices
& PREFICES_OPERAND
) != 0) {
3343 working
.write(LOAD0_EAX
);
3344 working
.write(LOAD1_EDI
);
3346 working
.write(LOAD0_AX
);
3347 working
.write(LOAD1_DI
);
3351 case 0xd0: //SFT G2 Eb, 1
3352 load0_Eb(prefices
, modrm
, sib
, displacement
);
3353 working
.write(LOAD1_IB
);
3357 case 0xd2: //SFT G2 Eb, CL
3358 load0_Eb(prefices
, modrm
, sib
, displacement
);
3359 working
.write(LOAD1_CL
);
3362 case 0xd1: //SFT G2 Ev, 1
3363 if ((prefices
& PREFICES_OPERAND
) != 0) {
3364 load0_Ed(prefices
, modrm
, sib
, displacement
);
3365 working
.write(LOAD1_IB
);
3368 load0_Ew(prefices
, modrm
, sib
, displacement
);
3369 working
.write(LOAD1_IB
);
3374 case 0xd3: //SFT G2 Ev, CL
3375 if ((prefices
& PREFICES_OPERAND
) != 0) {
3376 load0_Ed(prefices
, modrm
, sib
, displacement
);
3377 working
.write(LOAD1_CL
);
3379 load0_Ew(prefices
, modrm
, sib
, displacement
);
3380 working
.write(LOAD1_CL
);
3384 case 0xf6: //UNA G3 Eb, ?
3385 switch (modrm
& 0x38) {
3386 case 0x00: //TEST Eb, Ib
3387 load0_Eb(prefices
, modrm
, sib
, displacement
);
3388 working
.write(LOAD1_IB
);
3389 working
.write((int)immediate
);
3393 load0_Eb(prefices
, modrm
, sib
, displacement
);
3397 load0_Eb(prefices
, modrm
, sib
, displacement
);
3401 load0_Eb(prefices
, modrm
, sib
, displacement
);
3406 case 0xf7: //UNA G3 Ev, ?
3407 if ((prefices
& PREFICES_OPERAND
) != 0) {
3408 switch (modrm
& 0x38) {
3409 case 0x00: //TEST Ed, Id
3410 load0_Ed(prefices
, modrm
, sib
, displacement
);
3411 working
.write(LOAD1_ID
);
3412 working
.write((int)immediate
);
3416 load0_Ed(prefices
, modrm
, sib
, displacement
);
3420 load0_Ed(prefices
, modrm
, sib
, displacement
);
3424 load0_Ed(prefices
, modrm
, sib
, displacement
);
3427 switch (modrm
& 0x38) {
3428 case 0x00: //TEST Ew, Iw
3429 load0_Ew(prefices
, modrm
, sib
, displacement
);
3430 working
.write(LOAD1_IW
);
3431 working
.write((int)immediate
);
3435 load0_Ew(prefices
, modrm
, sib
, displacement
);
3439 load0_Ew(prefices
, modrm
, sib
, displacement
);
3443 load0_Ew(prefices
, modrm
, sib
, displacement
);
3448 case 0xfe: //INC/DEC G4 Eb
3449 load0_Eb(prefices
, modrm
, sib
, displacement
);
3452 case 0x06: //PUSH ES
3453 working
.write(LOAD0_ES
);
3456 case 0x0e: //PUSH CS
3457 working
.write(LOAD0_CS
);
3460 case 0x16: //PUSH SS
3461 working
.write(LOAD0_SS
);
3464 case 0x1e: //PUSH DS
3465 working
.write(LOAD0_DS
);
3468 case 0x62: //BOUND Gv, Ma
3469 if ((prefices
& PREFICES_OPERAND
) != 0) {
3470 load0_Eq(prefices
, modrm
, sib
, displacement
);
3473 load0_Ed(prefices
, modrm
, sib
, displacement
);
3478 case 0x8c: //MOV Ew, Sw
3482 case 0x8e: //MOV Sw, Ew
3483 case 0xfb7: //MOV Gv, Ew
3484 case 0xfbf: //MOVSX Gv, Ew
3485 load0_Ew(prefices
, modrm
, sib
, displacement
);
3488 case 0xa0: //MOV AL, Ob
3489 load0_Ob(prefices
, displacement
);
3492 case 0xa2: //MOV Ob, AL
3493 working
.write(LOAD0_AL
);
3496 case 0xa1: //MOV eAX, Ov
3497 if ((prefices
& PREFICES_OPERAND
) != 0) {
3498 load0_Od(prefices
, displacement
);
3500 load0_Ow(prefices
, displacement
);
3504 case 0xa3: //MOV Ov, eAX
3505 if ((prefices
& PREFICES_OPERAND
) != 0) {
3506 working
.write(LOAD0_EAX
);
3508 working
.write(LOAD0_AX
);
3512 case 0x6c: //INS Yb, DX (prefices do not override segment)
3513 case 0x6d: //INS Yv, DX (prefices do not override segment)
3514 working
.write(LOAD0_DX
);
3517 case 0x6e: //OUTS DX, Xb
3518 case 0x6f: //OUTS DX, Xv
3519 working
.write(LOAD0_DX
);
3520 decodeSegmentPrefix(prefices
);
3523 case 0xa4: //MOVS Yb, Xb
3524 case 0xa5: //MOVS Yv, Xv
3525 case 0xa6: //CMPS Yb, Xb
3526 case 0xa7: //CMPS Xv, Yv
3527 case 0xac: //LODS AL, Xb
3528 case 0xad: //LODS eAX, Xv
3529 decodeSegmentPrefix(prefices
);
3532 case 0xaa: //STOS Yb, AL (prefices do not override segment)
3533 working
.write(LOAD0_AL
);
3536 case 0xab: //STOS Yv, eAX
3537 if ((prefices
& PREFICES_OPERAND
) != 0)
3538 working
.write(LOAD0_EAX
);
3540 working
.write(LOAD0_AX
);
3544 case 0xae: //SCAS AL, Yb (prefices do not override segment)
3545 working
.write(LOAD0_AL
);
3548 case 0xaf: //SCAS eAX, Yv
3549 if ((prefices
& PREFICES_OPERAND
) != 0)
3550 working
.write(LOAD0_EAX
);
3552 working
.write(LOAD0_AX
);
3555 case 0xff: //INC/DEC G5
3556 if ((prefices
& PREFICES_OPERAND
) != 0) {
3557 switch (modrm
& 0x38) {
3560 case 0x10: //CALLN Ed
3561 case 0x20: //JMPN Ed
3562 case 0x30: //PUSH Ed
3563 load0_Ed(prefices
, modrm
, sib
, displacement
);
3565 case 0x18: //CALLF Ep
3566 case 0x28: //JMPF Ep
3567 load0_Ed(prefices
, modrm
, sib
, displacement
);
3568 working
.write(ADDR_IB
);
3570 working
.write(LOAD1_MEM_WORD
);
3573 switch (modrm
& 0x38) {
3579 load0_Ew(prefices
, modrm
, sib
, displacement
);
3583 load0_Ew(prefices
, modrm
, sib
, displacement
);
3584 working
.write(ADDR_IB
);
3586 working
.write(LOAD1_MEM_WORD
);
3591 case 0xc4: //LES Gv, Mp
3592 case 0xc5: //LDS Gv, Mp
3593 case 0xfb2: //LSS Mp
3594 case 0xfb4: //LFS Mp
3595 case 0xfb5: //LGS Mp
3596 if ((prefices
& PREFICES_OPERAND
) != 0) {
3597 load0_Ed(prefices
, modrm
, sib
, displacement
);
3598 working
.write(ADDR_IB
);
3600 working
.write(LOAD1_MEM_WORD
);
3602 load0_Ew(prefices
, modrm
, sib
, displacement
);
3603 working
.write(ADDR_IB
);
3605 working
.write(LOAD1_MEM_WORD
);
3610 switch (prefices
& PREFICES_SG
) {
3611 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
3612 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
3613 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
3615 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
3616 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
3617 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
3620 if ((prefices
& PREFICES_ADDRESS
) != 0) {
3621 if (decodingAddressMode()) {
3622 working
.write(ADDR_EBX
);
3623 working
.write(ADDR_uAL
);
3626 if (decodingAddressMode()) {
3627 working
.write(ADDR_BX
);
3628 working
.write(ADDR_uAL
);
3629 working
.write(ADDR_MASK16
);
3632 working
.write(LOAD0_MEM_BYTE
);
3635 case 0xf00: // Group 6
3636 switch (modrm
& 0x38) {
3641 load0_Ew(prefices
, modrm
, sib
, displacement
); break;
3645 switch (modrm
& 0x38) {
3648 load0_Ew(prefices
, modrm
, sib
, displacement
);
3649 working
.write(ADDR_ID
);
3651 working
.write(LOAD1_MEM_DWORD
);
3653 case 0x30: load0_Ew(prefices
, modrm
, sib
, displacement
); break;
3654 case 0x38: decodeM(prefices
, modrm
, sib
, displacement
); break;
3657 case 0xfa0: //PUSH FS
3658 working
.write(LOAD0_FS
); break;
3659 case 0xfa8: //PUSH GS
3660 working
.write(LOAD0_GS
); break;
3662 case 0xf20: load0_Cd(modrm
); break; //MOV Rd, Cd
3664 case 0xf21: load0_Dd(modrm
); break; //MOV Rd, Dd
3666 case 0xf22: //MOV Cd, Rd
3667 case 0xf23: load0_Rd(modrm
); break; //MOV Dd, Rd
3670 working
.write(LOAD0_ECX
);
3671 working
.write(LOAD1_EDX
);
3672 working
.write(LOAD2_EAX
);
3676 working
.write(LOAD0_ECX
);
3679 case 0xf35: //SYSEXIT
3680 working
.write(LOAD0_ECX
);
3681 working
.write(LOAD1_EDX
);
3684 case 0xfa4: //SHLD Ev, Gv, Ib
3685 case 0xfac: //SHRD Ev, Gv, Ib
3686 if ((prefices
& PREFICES_OPERAND
) != 0) {
3687 load0_Ed(prefices
, modrm
, sib
, displacement
);
3689 working
.write(LOAD2_IB
);
3690 working
.write((int)immediate
);
3692 load0_Ew(prefices
, modrm
, sib
, displacement
);
3694 working
.write(LOAD2_IB
);
3695 working
.write((int)immediate
);
3698 case 0xfa5: //SHLD Ev, Gv, CL
3699 case 0xfad: //SHRD Ev, Gv, CL
3700 if ((prefices
& PREFICES_OPERAND
) != 0) {
3701 load0_Ed(prefices
, modrm
, sib
, displacement
);
3703 working
.write(LOAD2_CL
);
3705 load0_Ew(prefices
, modrm
, sib
, displacement
);
3707 working
.write(LOAD2_CL
);
3711 case 0xfb0: //CMPXCHG Eb, Gb
3712 load0_Eb(prefices
, modrm
, sib
, displacement
);
3714 working
.write(LOAD2_AL
);
3717 case 0xfb1: //CMPXCHG Ev, Gv
3718 if ((prefices
& PREFICES_OPERAND
) != 0) {
3719 load0_Ed(prefices
, modrm
, sib
, displacement
);
3721 working
.write(LOAD2_EAX
);
3723 load0_Ew(prefices
, modrm
, sib
, displacement
);
3725 working
.write(LOAD2_AX
);
3729 case 0xfa3: //BT Ev, Gv
3730 case 0xfab: //BTS Ev, Gv
3731 case 0xfb3: //BTR Ev, Gv
3732 case 0xfbb: //BTC Ev, Gv
3733 if ((prefices
& PREFICES_OPERAND
) != 0) {
3734 switch (modrm
& 0xc7) {
3735 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3737 case 0xc0: working
.write(LOAD0_EAX
); break;
3738 case 0xc1: working
.write(LOAD0_ECX
); break;
3739 case 0xc2: working
.write(LOAD0_EDX
); break;
3740 case 0xc3: working
.write(LOAD0_EBX
); break;
3741 case 0xc4: working
.write(LOAD0_ESP
); break;
3742 case 0xc5: working
.write(LOAD0_EBP
); break;
3743 case 0xc6: working
.write(LOAD0_ESI
); break;
3744 case 0xc7: working
.write(LOAD0_EDI
); break;
3748 switch (modrm
& 0xc7) {
3749 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3751 case 0xc0: working
.write(LOAD0_AX
); break;
3752 case 0xc1: working
.write(LOAD0_CX
); break;
3753 case 0xc2: working
.write(LOAD0_DX
); break;
3754 case 0xc3: working
.write(LOAD0_BX
); break;
3755 case 0xc4: working
.write(LOAD0_SP
); break;
3756 case 0xc5: working
.write(LOAD0_BP
); break;
3757 case 0xc6: working
.write(LOAD0_SI
); break;
3758 case 0xc7: working
.write(LOAD0_DI
); break;
3764 case 0xfba: //Grp 8 Ev, Ib
3765 if ((prefices
& PREFICES_OPERAND
) != 0) {
3766 switch (modrm
& 0xc7) {
3767 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3769 case 0xc0: working
.write(LOAD0_EAX
); break;
3770 case 0xc1: working
.write(LOAD0_ECX
); break;
3771 case 0xc2: working
.write(LOAD0_EDX
); break;
3772 case 0xc3: working
.write(LOAD0_EBX
); break;
3773 case 0xc4: working
.write(LOAD0_ESP
); break;
3774 case 0xc5: working
.write(LOAD0_EBP
); break;
3775 case 0xc6: working
.write(LOAD0_ESI
); break;
3776 case 0xc7: working
.write(LOAD0_EDI
); break;
3779 switch (modrm
& 0xc7) {
3780 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3782 case 0xc0: working
.write(LOAD0_AX
); break;
3783 case 0xc1: working
.write(LOAD0_CX
); break;
3784 case 0xc2: working
.write(LOAD0_DX
); break;
3785 case 0xc3: working
.write(LOAD0_BX
); break;
3786 case 0xc4: working
.write(LOAD0_SP
); break;
3787 case 0xc5: working
.write(LOAD0_BP
); break;
3788 case 0xc6: working
.write(LOAD0_SI
); break;
3789 case 0xc7: working
.write(LOAD0_DI
); break;
3792 working
.write(LOAD1_IB
);
3793 working
.write((int)immediate
& 0x1f);
3797 switch (modrm
& 0x38)
3800 decodeM(prefices
, modrm
, sib
, displacement
);
3801 working
.write(LOAD0_MEM_QWORD
);
3803 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm
& 0x38) >> 3) + "?");
3807 case 0xfc8: working
.write(LOAD0_EAX
); break; //BSWAP EAX
3808 case 0xfc9: working
.write(LOAD0_ECX
); break; //BSWAP ECX
3809 case 0xfca: working
.write(LOAD0_EDX
); break; //BSWAP EDX
3810 case 0xfcb: working
.write(LOAD0_EBX
); break; //BSWAP EBX
3811 case 0xfcc: working
.write(LOAD0_ESP
); break; //BSWAP ESP
3812 case 0xfcd: working
.write(LOAD0_EBP
); break; //BSWAP EBP
3813 case 0xfce: working
.write(LOAD0_ESI
); break; //BSWAP ESI
3814 case 0xfcf: working
.write(LOAD0_EDI
); break; //BSWAP EDI
3817 working
.write(FWAIT
);
3818 if ((modrm
& 0xc0) != 0xc0)
3820 switch (modrm
& 0x38)
3824 decodeM(prefices
, modrm
, sib
, displacement
);
3825 working
.write(FLOAD0_MEM_SINGLE
);
3826 working
.write(FLOAD1_ST0
);
3829 working
.write(FLOAD0_ST0
);
3830 decodeM(prefices
, modrm
, sib
, displacement
);
3831 working
.write(FLOAD1_MEM_SINGLE
);
3837 switch (modrm
& 0xf8)
3841 working
.write(FLOAD0_STN
);
3842 working
.write(modrm
& 0x07);
3843 working
.write(FLOAD1_ST0
);
3846 working
.write(FLOAD0_ST0
);
3847 working
.write(FLOAD1_STN
);
3848 working
.write(modrm
& 0x07);
3855 if ((modrm
& 0xc0) != 0xc0)
3857 switch (modrm
& 0x38)
3860 working
.write(FWAIT
);
3861 decodeM(prefices
, modrm
, sib
, displacement
);
3862 working
.write(FLOAD0_MEM_SINGLE
);
3866 working
.write(FWAIT
);
3867 working
.write(FLOAD0_ST0
); break;
3869 working
.write(FWAIT
);
3870 decodeM(prefices
, modrm
, sib
, displacement
);
3873 working
.write(FWAIT
);
3874 decodeM(prefices
, modrm
, sib
, displacement
);
3875 working
.write(LOAD0_MEM_WORD
);
3877 case 0x30: decodeM(prefices
, modrm
, sib
, displacement
); break;
3878 case 0x38: working
.write(LOAD0_FPUCW
); break;
3883 working
.write(FWAIT
);
3884 switch (modrm
& 0xf8)
3887 working
.write(FLOAD0_STN
);
3888 working
.write(modrm
& 0x07);
3891 working
.write(FLOAD0_ST0
);
3892 working
.write(FLOAD1_STN
);
3893 working
.write(modrm
& 0x07);
3911 case 0xff: working
.write(FLOAD0_ST0
); break;
3918 working
.write(FLOAD0_ST0
);
3919 working
.write(FLOAD1_STN
);
3923 working
.write(FLOAD0_ST0
);
3924 working
.write(FLOAD1_POS0
);
3926 case 0xe8: working
.write(FLOAD0_1
); break;
3927 case 0xe9: working
.write(FLOAD0_L2TEN
); break;
3928 case 0xea: working
.write(FLOAD0_L2E
); break;
3929 case 0xeb: working
.write(FLOAD0_PI
); break;
3930 case 0xec: working
.write(FLOAD0_LOG2
); break;
3931 case 0xed: working
.write(FLOAD0_LN2
); break;
3932 case 0xee: working
.write(FLOAD0_POS0
); break;
3938 working
.write(FWAIT
);
3939 if ((modrm
& 0xc0) != 0xc0)
3941 switch (modrm
& 0x38)
3945 decodeM(prefices
, modrm
, sib
, displacement
);
3946 working
.write(LOAD0_MEM_DWORD
);
3947 working
.write(FLOAD0_REG0
);
3948 working
.write(FLOAD1_ST0
);
3951 working
.write(FLOAD0_ST0
);
3952 decodeM(prefices
, modrm
, sib
, displacement
);
3953 working
.write(LOAD0_MEM_DWORD
);
3954 working
.write(FLOAD1_REG0
);
3960 switch (modrm
& 0xf8)
3966 working
.write(FLOAD0_STN
);
3967 working
.write(modrm
& 0x07);
3973 working
.write(FLOAD0_ST0
);
3974 working
.write(FLOAD1_STN
);
3982 if ((modrm
& 0xc0) != 0xc0)
3984 working
.write(FWAIT
);
3985 switch (modrm
& 0x38)
3988 decodeM(prefices
, modrm
, sib
, displacement
);
3989 working
.write(LOAD0_MEM_DWORD
);
3990 working
.write(FLOAD0_REG0
);
3995 case 0x38: working
.write(FLOAD0_ST0
); break;
3997 decodeM(prefices
, modrm
, sib
, displacement
);
3998 working
.write(FLOAD0_MEM_EXTENDED
);
4008 default: working
.write(FWAIT
); break;
4010 switch (modrm
& 0xf8)
4016 working
.write(FLOAD0_STN
);
4017 working
.write(modrm
& 0x07);
4021 working
.write(FLOAD0_ST0
);
4022 working
.write(FLOAD1_STN
);
4023 working
.write(modrm
& 0x07);
4030 working
.write(FWAIT
);
4031 if ((modrm
& 0xc0) != 0xc0)
4033 switch (modrm
& 0x38)
4037 decodeM(prefices
, modrm
, sib
, displacement
);
4038 working
.write(FLOAD0_MEM_DOUBLE
);
4039 working
.write(FLOAD1_ST0
);
4042 working
.write(FLOAD0_ST0
);
4043 decodeM(prefices
, modrm
, sib
, displacement
);
4044 working
.write(FLOAD1_MEM_DOUBLE
);
4050 switch (modrm
& 0xf8)
4054 working
.write(FLOAD0_STN
);
4055 working
.write(modrm
& 0x07);
4056 working
.write(FLOAD1_ST0
);
4059 working
.write(FLOAD0_ST0
);
4060 working
.write(FLOAD1_STN
);
4061 working
.write(modrm
& 0x07);
4068 if ((modrm
& 0xc0) != 0xc0)
4070 switch (modrm
& 0x38)
4073 working
.write(FWAIT
);
4074 decodeM(prefices
, modrm
, sib
, displacement
);
4075 working
.write(FLOAD0_MEM_DOUBLE
);
4080 working
.write(FWAIT
);
4081 working
.write(FLOAD0_ST0
);
4084 working
.write(FWAIT
);
4085 decodeM(prefices
, modrm
, sib
, displacement
);
4087 case 0x30: decodeM(prefices
, modrm
, sib
, displacement
); break;
4088 case 0x38: working
.write(LOAD0_FPUSW
); break;
4093 working
.write(FWAIT
);
4094 switch (modrm
& 0xf8)
4097 working
.write(LOAD0_ID
);
4098 working
.write(modrm
& 0x07);
4101 case 0xd8: working
.write(FLOAD0_ST0
); break;
4104 working
.write(FLOAD0_ST0
);
4105 working
.write(FLOAD1_STN
);
4106 working
.write(modrm
& 0x07);
4113 working
.write(FWAIT
);
4114 if ((modrm
& 0xc0) != 0xc0)
4116 switch (modrm
& 0x38)
4120 decodeM(prefices
, modrm
, sib
, displacement
);
4121 working
.write(LOAD0_MEM_WORD
);
4122 working
.write(FLOAD0_REG0
);
4123 working
.write(FLOAD1_ST0
);
4126 working
.write(FLOAD0_ST0
);
4127 decodeM(prefices
, modrm
, sib
, displacement
);
4128 working
.write(LOAD0_MEM_QWORD
);
4129 working
.write(FLOAD1_REG0L
);
4132 working
.write(FLOAD0_ST0
);
4133 decodeM(prefices
, modrm
, sib
, displacement
);
4134 working
.write(LOAD0_MEM_WORD
);
4135 working
.write(FLOAD1_REG0
);
4141 switch (modrm
& 0xf8) {
4146 working
.write(FLOAD0_ST0
);
4147 working
.write(FLOAD1_STN
);
4148 working
.write(modrm
& 0x07);
4152 working
.write(FLOAD1_ST0
);
4153 working
.write(FLOAD0_STN
);
4154 working
.write(modrm
& 0x07);
4160 working
.write(FLOAD0_ST0
);
4161 working
.write(FLOAD1_STN
);
4169 if ((modrm
& 0xc0) != 0xc0)
4171 working
.write(FWAIT
);
4172 switch (modrm
& 0x38)
4175 decodeM(prefices
, modrm
, sib
, displacement
);
4176 working
.write(LOAD0_MEM_WORD
);
4177 working
.write(FLOAD0_REG0
);
4180 decodeM(prefices
, modrm
, sib
, displacement
);
4181 working
.write(LOAD0_MEM_QWORD
);
4182 working
.write(FLOAD0_REG0L
);
4188 working
.write(FLOAD0_ST0
);
4191 working
.write(FLOAD0_ST0
);
4192 decodeM(prefices
, modrm
, sib
, displacement
);
4195 decodeM(prefices
, modrm
, sib
, displacement
);
4203 case 0xe0: working
.write(LOAD0_FPUSW
); break;
4204 default: working
.write(FWAIT
); break;
4206 switch (modrm
& 0xf8) {
4209 working
.write(FLOAD0_ST0
);
4210 working
.write(FLOAD1_STN
);
4211 working
.write(modrm
& 0x07);
4220 private void writeOutputOperands(int prefices
, int opcode
, int modrm
, int sib
, int displacement
)
4222 //Normal One Byte Operation
4224 case 0x00: //ADD Eb, Gb
4225 case 0x08: //OR Eb, Gb
4226 case 0x10: //ADC Eb, Gb
4227 case 0x18: //SBB Eb, Gb
4228 case 0x20: //AND Eb, Gb
4229 case 0x28: //SUB Eb, Gb
4230 case 0x30: //XOR Eb, Gb
4231 case 0x88: //MOV Eb, Gb
4232 case 0xc0: //SFT G2 Eb, Ib
4233 case 0xc6: //MOV G11 Eb, Ib
4234 case 0xfe: //INC/DEC G4 Eb
4242 case 0xf97: //SETNBE
4250 case 0xf9f: //SETNLE
4251 store0_Eb(prefices
, modrm
, sib
, displacement
);
4254 case 0xfb0: //CMPXCHG Eb, Gb
4255 working
.write(STORE1_AL
); //do store 1 first incase Eb is also AL/AX/EAX
4256 store0_Eb(prefices
, modrm
, sib
, displacement
);
4259 case 0x80: //IMM G1 Eb, Ib
4260 case 0x82: //IMM G1 Eb, Ib
4261 if ((modrm
& 0x38) == 0x38)
4263 store0_Eb(prefices
, modrm
, sib
, displacement
); break;
4265 case 0x86: //XCHG Eb, Gb
4267 store1_Eb(prefices
, modrm
, sib
, displacement
);
4270 case 0x02: //ADD Gb, Eb
4271 case 0x0a: //OR Gb, Eb
4272 case 0x12: //ADC Gb, Eb
4273 case 0x1a: //SBB Gb, Eb
4274 case 0x22: //AND Gb, Eb
4275 case 0x2a: //SUB Gb, Eb
4276 case 0x32: //XOR Gb, Eb
4277 case 0x8a: //MOV Gb, Eb
4281 case 0x01: //ADD Ev, Gv
4282 case 0x09: //OR Ev, Gv
4283 case 0x11: //ADC Ev, Gv
4284 case 0x19: //SBB Ev, Gv
4285 case 0x21: //AND Ev, Gv
4286 case 0x29: //SUB Ev, Gv
4287 case 0x31: //XOR Ev, Gv
4288 case 0x89: //MOV Ev, Gv
4289 case 0xc7: //MOV G11 Ev, Iv
4290 case 0xc1: //SFT G2 Ev, Ib
4292 case 0xd1: //SFT G2 Ev, 1
4293 case 0xd3: //SFT G2 Ev, CL
4294 if ((prefices
& PREFICES_OPERAND
) != 0) {
4295 store0_Ed(prefices
, modrm
, sib
, displacement
);
4297 store0_Ew(prefices
, modrm
, sib
, displacement
);
4301 case 0xfb1: //CMPXCHG Ev, Gv
4302 if ((prefices
& PREFICES_OPERAND
) != 0) {
4303 working
.write(STORE1_EAX
); //do store1 first incase Eb is same place
4304 store0_Ed(prefices
, modrm
, sib
, displacement
);
4306 working
.write(STORE1_AX
); //do store1 first incase Eb is same place
4307 store0_Ew(prefices
, modrm
, sib
, displacement
);
4311 case 0x81: //IMM G1 Ev, Iv
4312 case 0x83: //IMM G1 Ev, Ib
4313 if ((modrm
& 0x38) == 0x38)
4315 if ((prefices
& PREFICES_OPERAND
) != 0) {
4316 store0_Ed(prefices
, modrm
, sib
, displacement
);
4318 store0_Ew(prefices
, modrm
, sib
, displacement
);
4323 case 0x87: //XCHG Ev, Gv
4324 if ((prefices
& PREFICES_OPERAND
) != 0) {
4326 store1_Ed(prefices
, modrm
, sib
, displacement
);
4329 store1_Ew(prefices
, modrm
, sib
, displacement
);
4333 case 0x03: //ADD Gv, Ev
4334 case 0x0b: //OR Gv, Ev
4335 case 0x13: //ADC Gv, Ev
4336 case 0x1b: //SBB Gv, Ev
4337 case 0x23: //AND Gv, Ev
4338 case 0x2b: //SUB Gv, Ev
4339 case 0x33: //XOR Gv, Ev
4340 case 0x69: //IMUL Gv, Ev, Iv
4341 case 0x6b: //IMUL Gv, Ev, Ib
4342 case 0x8b: //MOV Gv, Ev
4343 case 0x8d: //LEA Gv, M
4344 case 0xf02: //LAR Gv, Ew
4345 case 0xf03: //LSL Gv, Ew
4347 case 0xf41: //CMOVNO
4349 case 0xf43: //CMOVNC
4351 case 0xf45: //CMOVNZ
4352 case 0xf46: //CMOVBE
4353 case 0xf47: //CMOVNBE
4355 case 0xf49: //CMOVNS
4357 case 0xf4b: //CMOVNP
4359 case 0xf4d: //CMOVNL
4360 case 0xf4e: //CMOVLE
4361 case 0xf4f: //CMOVNLE
4362 case 0xfaf: //IMUL Gv, Ev
4363 case 0xfb6: //MOVZX Gv, Eb
4364 case 0xfb7: //MOVZX Gv, Ew
4365 case 0xfbc: //BSF Gv, Ev
4366 case 0xfbd: //BSR Gv, Ev
4367 case 0xfbe: //MOVSX Gv, Eb
4368 case 0xfbf: //MOVSX Gv, Ew
4369 if ((prefices
& PREFICES_OPERAND
) != 0) {
4376 case 0xec: //IN AL, DX
4377 case 0x04: //ADD AL, Ib
4378 case 0x0c: //OR AL, Ib
4379 case 0x14: //ADC AL, Ib
4380 case 0x1c: //SBB AL, Ib
4381 case 0x24: //AND AL, Ib
4382 case 0x2c: //SUB AL, Ib
4383 case 0x34: //XOR AL, Ib
4384 case 0xe4: //IN AL, Ib
4385 case 0xb0: //MOV AL, Ib
4386 working
.write(STORE0_AL
);
4389 case 0xb1: //MOV CL, Ib
4390 working
.write(STORE0_CL
);
4393 case 0xb2: //MOV DL, Ib
4394 working
.write(STORE0_DL
);
4397 case 0xb3: //MOV BL, Ib
4398 working
.write(STORE0_BL
);
4401 case 0xb4: //MOV AH, Ib
4402 working
.write(STORE0_AH
);
4405 case 0xb5: //MOV CH, Ib
4406 working
.write(STORE0_CH
);
4409 case 0xb6: //MOV DH, Ib
4410 working
.write(STORE0_DH
);
4413 case 0xb7: //MOV BH, Ib
4414 working
.write(STORE0_BH
);
4419 case 0x05: //ADD eAX, Iv
4420 case 0x0d: //OR eAX, Iv
4421 case 0x15: //ADC eAX, Iv
4422 case 0x1d: //SBB eAX, Iv
4423 case 0x25: //AND eAX, Iv
4424 case 0x2d: //SUB eAX, Iv
4425 case 0x35: //XOR eAX, Iv
4426 case 0xb8: //MOV eAX, Iv
4427 case 0xe5: //IN eAX, Ib
4428 case 0x40: //INC eAX
4429 case 0x48: //DEC eAX
4430 case 0x58: //POP eAX
4431 case 0xed: //IN eAX, DX
4432 if ((prefices
& PREFICES_OPERAND
) != 0) {
4433 working
.write(STORE0_EAX
);
4435 working
.write(STORE0_AX
);
4439 case 0x41: //INC eCX
4440 case 0x49: //DEC eCX
4441 case 0x59: //POP eCX
4442 case 0xb9: //MOV eCX, Iv
4443 if ((prefices
& PREFICES_OPERAND
) != 0) {
4444 working
.write(STORE0_ECX
);
4446 working
.write(STORE0_CX
);
4450 case 0x42: //INC eDX
4451 case 0x4a: //DEC eDX
4452 case 0x5a: //POP eDX
4453 case 0xba: //MOV eDX, Iv
4454 if ((prefices
& PREFICES_OPERAND
) != 0) {
4455 working
.write(STORE0_EDX
);
4457 working
.write(STORE0_DX
);
4461 case 0x43: //INC eBX
4462 case 0x4b: //DEC eBX
4463 case 0x5b: //POP eBX
4464 case 0xbb: //MOV eBX, Iv
4465 if ((prefices
& PREFICES_OPERAND
) != 0) {
4466 working
.write(STORE0_EBX
);
4468 working
.write(STORE0_BX
);
4472 case 0x44: //INC eSP
4473 case 0x4c: //DEC eSP
4474 case 0x5c: //POP eSP
4475 case 0xbc: //MOV eSP, Iv
4476 if ((prefices
& PREFICES_OPERAND
) != 0) {
4477 working
.write(STORE0_ESP
);
4479 working
.write(STORE0_SP
);
4483 case 0x45: //INC eBP
4484 case 0x4d: //DEC eBP
4485 case 0x5d: //POP eBP
4486 case 0xbd: //MOV eBP, Iv
4487 if ((prefices
& PREFICES_OPERAND
) != 0) {
4488 working
.write(STORE0_EBP
);
4490 working
.write(STORE0_BP
);
4494 case 0x46: //INC eSI
4495 case 0x4e: //DEC eSI
4496 case 0x5e: //POP eSI
4497 case 0xbe: //MOV eSI, Iv
4498 if ((prefices
& PREFICES_OPERAND
) != 0) {
4499 working
.write(STORE0_ESI
);
4501 working
.write(STORE0_SI
);
4505 case 0x47: //INC eDI
4506 case 0x4f: //DEC eDI
4507 case 0x5f: //POP eDI
4508 case 0xbf: //MOV eDI, Iv
4509 if ((prefices
& PREFICES_OPERAND
) != 0) {
4510 working
.write(STORE0_EDI
);
4512 working
.write(STORE0_DI
);
4517 case 0x91: //XCHG eAX, eCX
4518 if ((prefices
& PREFICES_OPERAND
) != 0) {
4519 working
.write(STORE0_ECX
);
4520 working
.write(STORE1_EAX
);
4522 working
.write(STORE0_CX
);
4523 working
.write(STORE1_AX
);
4527 case 0x92: //XCHG eAX, eDX
4528 if ((prefices
& PREFICES_OPERAND
) != 0) {
4529 working
.write(STORE0_EDX
);
4530 working
.write(STORE1_EAX
);
4532 working
.write(STORE0_DX
);
4533 working
.write(STORE1_AX
);
4537 case 0x93: //XCHG eAX, eBX
4538 if ((prefices
& PREFICES_OPERAND
) != 0) {
4539 working
.write(STORE0_EBX
);
4540 working
.write(STORE1_EAX
);
4542 working
.write(STORE0_BX
);
4543 working
.write(STORE1_AX
);
4547 case 0x94: //XCHG eAX, eSP
4548 if ((prefices
& PREFICES_OPERAND
) != 0) {
4549 working
.write(STORE0_ESP
);
4550 working
.write(STORE1_EAX
);
4552 working
.write(STORE0_SP
);
4553 working
.write(STORE1_AX
);
4557 case 0x95: //XCHG eAX, eBP
4558 if ((prefices
& PREFICES_OPERAND
) != 0) {
4559 working
.write(STORE0_EBP
);
4560 working
.write(STORE1_EAX
);
4562 working
.write(STORE0_BP
);
4563 working
.write(STORE1_AX
);
4567 case 0x96: //XCHG eAX, eSI
4568 if ((prefices
& PREFICES_OPERAND
) != 0) {
4569 working
.write(STORE0_ESI
);
4570 working
.write(STORE1_EAX
);
4572 working
.write(STORE0_SI
);
4573 working
.write(STORE1_AX
);
4577 case 0x97: //XCHG eAX, eDI
4578 if ((prefices
& PREFICES_OPERAND
) != 0) {
4579 working
.write(STORE0_EDI
);
4580 working
.write(STORE1_EAX
);
4582 working
.write(STORE0_DI
);
4583 working
.write(STORE1_AX
);
4588 switch (prefices
& PREFICES_OPERAND
) {
4590 working
.write(STORE0_FLAGS
); break;
4591 case PREFICES_OPERAND
:
4592 working
.write(STORE0_EFLAGS
); break;
4596 case 0xd0: //SFT G2 Eb, 1
4597 case 0xd2: //SFT G2 Eb, CL
4598 store0_Eb(prefices
, modrm
, sib
, displacement
);
4603 case 0xf6: //UNA G3 Eb, ?
4604 switch (modrm
& 0x38) {
4607 store0_Eb(prefices
, modrm
, sib
, displacement
);
4612 case 0xf7: //UNA G3 Ev, ?
4613 if ((prefices
& PREFICES_OPERAND
) != 0) {
4614 switch (modrm
& 0x38) {
4617 store0_Ed(prefices
, modrm
, sib
, displacement
);
4621 switch (modrm
& 0x38) {
4624 store0_Ew(prefices
, modrm
, sib
, displacement
);
4632 working
.write(STORE0_ES
);
4636 working
.write(STORE0_SS
);
4640 working
.write(STORE0_DS
);
4643 case 0x8c: //MOV Ew, Sw
4644 if ((prefices
& PREFICES_OPERAND
) != 0) {
4645 store0_Ed(prefices
, modrm
, sib
, displacement
);
4647 store0_Ew(prefices
, modrm
, sib
, displacement
);
4651 case 0x8e: //MOV Sw, Ew
4655 case 0xa0: //MOV AL, Ob
4656 working
.write(STORE0_AL
);
4659 case 0xa2: //MOV Ob, AL
4660 store0_Ob(prefices
, displacement
);
4663 case 0xa1: //MOV eAX, Ov
4664 if ((prefices
& PREFICES_OPERAND
) != 0) {
4665 working
.write(STORE0_EAX
);
4667 working
.write(STORE0_AX
);
4671 case 0xa3: //MOV Ov, eAX
4672 if ((prefices
& PREFICES_OPERAND
) != 0) {
4673 store0_Od(prefices
, displacement
);
4675 store0_Ow(prefices
, displacement
);
4679 case 0xff: //INC/DEC G5
4680 if ((prefices
& PREFICES_OPERAND
) != 0) {
4681 switch (modrm
& 0x38) {
4684 store0_Ed(prefices
, modrm
, sib
, displacement
);
4687 switch (modrm
& 0x38) {
4690 store0_Ew(prefices
, modrm
, sib
, displacement
);
4695 case 0xc4: //LES Gv, Mp
4696 if ((prefices
& PREFICES_OPERAND
) != 0) {
4698 working
.write(STORE1_ES
);
4701 working
.write(STORE1_ES
);
4705 case 0xc5: //LDS Gv, Mp
4706 if ((prefices
& PREFICES_OPERAND
) != 0) {
4708 working
.write(STORE1_DS
);
4711 working
.write(STORE1_DS
);
4715 case 0xf00: // Group 6
4716 switch (modrm
& 0x38) {
4718 store0_Ew(prefices
, modrm
, sib
, displacement
); break;
4719 case 0x08: //STR (stores to a doubleword if a register, but a word if memory)
4720 if ((prefices
& PREFICES_OPERAND
) != 0) {
4721 switch (modrm
& 0xc7) {
4722 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_WORD
); break;
4724 case 0xc0: working
.write(STORE0_EAX
); break;
4725 case 0xc1: working
.write(STORE0_ECX
); break;
4726 case 0xc2: working
.write(STORE0_EDX
); break;
4727 case 0xc3: working
.write(STORE0_EBX
); break;
4728 case 0xc4: working
.write(STORE0_ESP
); break;
4729 case 0xc5: working
.write(STORE0_EBP
); break;
4730 case 0xc6: working
.write(STORE0_ESI
); break;
4731 case 0xc7: working
.write(STORE0_EDI
); break;
4735 store0_Ew(prefices
, modrm
, sib
, displacement
);
4740 switch (modrm
& 0x38) {
4743 store0_Ew(prefices
, modrm
, sib
, displacement
);
4744 working
.write(ADDR_ID
);
4746 working
.write(STORE1_MEM_DWORD
);
4748 case 0x20: store0_Ew(prefices
, modrm
, sib
, displacement
); break;
4751 case 0xf1f: break; //multi byte NOP (read latest manual)
4752 case 0xfa4: //SHLD Ev, Gv, Ib
4753 case 0xfa5: //SHLD Ev, Gv, CL
4754 case 0xfac: //SHRD Ev, Gv, Ib
4755 case 0xfad: //SHRD Ev, Gv, CL
4756 if ((prefices
& PREFICES_OPERAND
) != 0)
4757 store0_Ed(prefices
, modrm
, sib
, displacement
);
4759 store0_Ew(prefices
, modrm
, sib
, displacement
);
4762 case 0xfb2: //LSS Mp
4763 if ((prefices
& PREFICES_OPERAND
) != 0) {
4765 working
.write(STORE1_SS
);
4768 working
.write(STORE1_SS
);
4772 case 0xfb4: //LFS Mp
4773 if ((prefices
& PREFICES_OPERAND
) != 0) {
4775 working
.write(STORE1_FS
);
4778 working
.write(STORE1_FS
);
4782 case 0xfb5: //LGS Mp
4783 if ((prefices
& PREFICES_OPERAND
) != 0) {
4785 working
.write(STORE1_GS
);
4788 working
.write(STORE1_GS
);
4792 case 0xfc0: //XADD Eb, Gb
4793 store1_Gb(modrm
); //exchange first then add (so we write the result of the exchange first incase Eb and Gb are same reg)
4794 store0_Eb(prefices
, modrm
, sib
, displacement
);
4797 case 0xfc1: //XADD Eb, Gb
4798 if ((prefices
& PREFICES_OPERAND
) != 0) {
4799 store1_Gd(modrm
); //exchange first then add
4800 store0_Ed(prefices
, modrm
, sib
, displacement
);
4802 store1_Gw(modrm
); //exchange first then add
4803 store0_Ew(prefices
, modrm
, sib
, displacement
);
4809 working
.write(STORE0_AL
); break;
4811 case 0xf20: //MOV Rd, Cd
4812 case 0xf21: //MOV Rd, Dd
4813 store0_Rd(modrm
); break;
4815 case 0xf22: store0_Cd(modrm
); break; //MOV Cd, Rd
4816 case 0xf23: store0_Dd(modrm
); break; //MOV Dd, Rd
4820 working
.write(STORE0_EAX
);
4821 working
.write(STORE1_EDX
);
4825 case 0xfa1: //POP FS
4826 working
.write(STORE0_FS
); break;
4828 case 0xfa9: //POP GS
4829 working
.write(STORE0_GS
); break;
4831 case 0xfab: //BTS Ev, Gv
4832 case 0xfb3: //BTR Ev, Gv
4833 case 0xfbb: //BTC Ev, Gv
4834 if ((prefices
& PREFICES_OPERAND
) != 0) {
4835 if ((modrm
& 0xc0) == 0xc0)
4836 store0_Ed(prefices
, modrm
, sib
, displacement
);
4838 if ((modrm
& 0xc0) == 0xc0)
4839 store0_Ew(prefices
, modrm
, sib
, displacement
);
4843 case 0xfba: //Grp 8 Ev, Ib
4844 switch (modrm
& 0x38) {
4848 if ((prefices
& PREFICES_OPERAND
) != 0) {
4849 if ((modrm
& 0xc0) == 0xc0)
4850 store0_Ed(prefices
, modrm
, sib
, displacement
);
4852 if ((modrm
& 0xc0) == 0xc0)
4853 store0_Ew(prefices
, modrm
, sib
, displacement
);
4858 case 0xfc7: //CMPXCHG8B
4859 switch (modrm
& 0x38)
4862 decodeM(prefices
, modrm
, sib
, displacement
);
4863 working
.write(STORE0_MEM_QWORD
);
4865 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm
& 0x38) >> 3) + "?");
4869 case 0xfc8: working
.write(STORE0_EAX
); break; //BSWAP EAX
4870 case 0xfc9: working
.write(STORE0_ECX
); break; //BSWAP ECX
4871 case 0xfca: working
.write(STORE0_EDX
); break; //BSWAP EDX
4872 case 0xfcb: working
.write(STORE0_EBX
); break; //BSWAP EBX
4873 case 0xfcc: working
.write(STORE0_ESP
); break; //BSWAP ESP
4874 case 0xfcd: working
.write(STORE0_EBP
); break; //BSWAP EBP
4875 case 0xfce: working
.write(STORE0_ESI
); break; //BSWAP ESI
4876 case 0xfcf: working
.write(STORE0_EDI
); break; //BSWAP EDI
4879 switch (modrm
& 0x38)
4887 working
.write(FSTORE0_ST0
);
4888 working
.write(FCHECK0
);
4891 case 0x18: working
.write(FPOP
); break;
4896 if ((modrm
& 0xc0) != 0xc0)
4898 switch (modrm
& 0x38)
4905 decodeM(prefices
, modrm
, sib
, displacement
);
4906 working
.write(FSTORE0_MEM_SINGLE
);
4909 decodeM(prefices
, modrm
, sib
, displacement
);
4910 working
.write(FSTORE0_MEM_SINGLE
);
4911 working
.write(FPOP
);
4913 case 0x28: working
.write(STORE0_FPUCW
); break;
4915 decodeM(prefices
, modrm
, sib
, displacement
);
4916 working
.write(STORE0_MEM_WORD
);
4922 switch (modrm
& 0xf8)
4926 working
.write(FSTORE0_STN
);
4927 working
.write(modrm
& 0x07);
4928 working
.write(FSTORE1_ST0
);
4948 case 0xff: working
.write(FSTORE0_ST0
); break;
4955 working
.write(FSTORE0_ST0
);
4956 working
.write(FCHECK0
);
4959 working
.write(FSTORE0_ST0
);
4960 working
.write(FLOAD0_1
);
4961 working
.write(FPUSH
);
4965 working
.write(FPOP
);
4966 working
.write(FSTORE0_ST0
);
4969 working
.write(FPOP
);
4970 working
.write(FSTORE0_ST0
);
4971 working
.write(FCHECK0
);
4974 working
.write(FSTORE1_ST0
);
4975 working
.write(FPUSH
);
4978 working
.write(FSTORE1_ST0
);
4979 working
.write(FPUSH
);
4980 working
.write(FCHECK0
);
4981 working
.write(FCHECK1
);
4988 if ((modrm
& 0xc0) != 0xc0)
4990 switch (modrm
& 0x38)
4998 working
.write(FSTORE0_ST0
);
4999 working
.write(FCHECK0
);
5002 case 0x18: working
.write(FPOP
); break;
5010 working
.write(FPOP
);
5011 working
.write(FPOP
);
5018 if ((modrm
& 0xc0) != 0xc0)
5020 switch (modrm
& 0x38)
5025 decodeM(prefices
, modrm
, sib
, displacement
);
5026 working
.write(STORE0_MEM_DWORD
);
5030 decodeM(prefices
, modrm
, sib
, displacement
);
5031 working
.write(STORE0_MEM_DWORD
);
5032 working
.write(FPOP
);
5035 decodeM(prefices
, modrm
, sib
, displacement
);
5036 working
.write(FSTORE0_MEM_EXTENDED
);
5037 working
.write(FPOP
);
5044 if ((modrm
& 0xc0) != 0xc0)
5046 switch (modrm
& 0x38)
5054 working
.write(FSTORE0_ST0
);
5055 working
.write(FCHECK0
);
5058 case 0x18: working
.write(FPOP
); break;
5063 switch (modrm
& 0xf8)
5071 working
.write(FSTORE0_STN
);
5072 working
.write(modrm
& 0x07);
5073 working
.write(FCHECK0
);
5080 if ((modrm
& 0xc0) != 0xc0)
5082 switch (modrm
& 0x38)
5088 decodeM(prefices
, modrm
, sib
, displacement
);
5089 working
.write(STORE0_MEM_QWORD
);
5090 working
.write(FPOP
);
5093 decodeM(prefices
, modrm
, sib
, displacement
);
5094 working
.write(FSTORE0_MEM_DOUBLE
);
5097 decodeM(prefices
, modrm
, sib
, displacement
);
5098 working
.write(FSTORE0_MEM_DOUBLE
);
5099 working
.write(FPOP
);
5102 decodeM(prefices
, modrm
, sib
, displacement
);
5103 working
.write(STORE0_MEM_WORD
);
5109 switch (modrm
& 0xf8)
5114 working
.write(FSTORE0_STN
);
5115 working
.write(modrm
& 0x07);
5118 working
.write(FSTORE0_STN
);
5119 working
.write(modrm
& 0x07);
5120 working
.write(FPOP
);
5122 case 0xe8: working
.write(FPOP
); break;
5128 if ((modrm
& 0xc0) != 0xc0)
5130 switch (modrm
& 0x38)
5138 working
.write(FSTORE0_ST0
);
5139 working
.write(FCHECK0
);
5142 case 0x18: working
.write(FPOP
); break;
5147 switch (modrm
& 0xf8)
5155 working
.write(FSTORE0_STN
);
5156 working
.write(modrm
& 0x07);
5157 working
.write(FPOP
);
5158 working
.write(FCHECK0
);
5166 working
.write(FPOP
);
5167 working
.write(FPOP
);
5174 if ((modrm
& 0xc0) != 0xc0)
5176 switch (modrm
& 0x38)
5184 decodeM(prefices
, modrm
, sib
, displacement
);
5185 working
.write(STORE0_MEM_WORD
);
5186 working
.write(FPOP
);
5189 decodeM(prefices
, modrm
, sib
, displacement
);
5190 working
.write(STORE0_MEM_WORD
);
5193 decodeM(prefices
, modrm
, sib
, displacement
);
5194 working
.write(STORE0_MEM_QWORD
);
5195 working
.write(FPOP
);
5201 switch (modrm
& 0xf8)
5204 case 0xf0: working
.write(FPOP
); break;
5208 case 0xe0: working
.write(STORE0_AX
); break;
5216 private static int operationHasImmediate(int prefices
, int opcode
, int modrm
)
5219 case 0x04: //ADD AL, Ib
5220 case 0x0c: //OR AL, Ib
5221 case 0x14: //ADC AL, Ib
5222 case 0x1c: //SBB AL, Ib
5223 case 0x24: //AND AL, Ib
5224 case 0x2c: //SUB AL, Ib
5225 case 0x34: //XOR AL, Ib
5226 case 0x3c: //CMP AL, Ib
5227 case 0x6a: //PUSH Ib
5228 case 0x6b: //IMUL Gv, Ev, Ib
5245 case 0x80: //IMM G1 Eb, Ib
5246 case 0x82: //IMM G1 Eb, Ib
5247 case 0x83: //IMM G1 Ev, Ib
5248 case 0xa8: //TEST AL, Ib
5249 case 0xb0: //MOV AL, Ib
5250 case 0xb1: //MOV CL, Ib
5251 case 0xb2: //MOV DL, Ib
5252 case 0xb3: //MOV BL, Ib
5253 case 0xb4: //MOV AH, Ib
5254 case 0xb5: //MOV CH, Ib
5255 case 0xb6: //MOV DH, Ib
5256 case 0xb7: //MOV BH, Ib
5257 case 0xc0: //SFT G2 Eb, Ib
5258 case 0xc1: //SFT G2 Ev, Ib
5259 case 0xc6: //MOV G11 Eb, Ib
5263 case 0xe0: //LOOPNZ Jb
5264 case 0xe1: //LOOPZ Jb
5265 case 0xe2: //LOOP Jb
5266 case 0xe3: //JCXZ Jb
5267 case 0xe4: //IN AL, Ib
5268 case 0xe5: //IN eAX, Ib
5269 case 0xe6: //OUT Ib, AL
5270 case 0xe7: //OUT Ib, eAX
5272 case 0xfa4: //SHLD Ev, Gv, Ib
5273 case 0xfac: //SHRD Ev, Gv, Ib
5274 case 0xfba: //Grp 8 Ev, Ib
5278 case 0xca: //RETF Iw
5281 case 0xc8: //ENTER Iw, Ib
5284 case 0x05: //ADD eAX, Iv
5285 case 0x0d: //OR eAX, Iv
5286 case 0x15: //ADC eAX, Iv
5287 case 0x1d: //SBB eAX, Iv
5288 case 0x25: //AND eAX, Iv
5289 case 0x2d: //SUB eAX, Iv
5290 case 0x35: //XOR eAX, Iv
5291 case 0x3d: //CMP eAX, Iv
5292 case 0x68: //PUSH Iv
5293 case 0x69: //IMUL Gv, Ev, Iv
5294 case 0x81: //IMM G1 Ev, Iv
5295 case 0xa9: //TEST eAX, Iv
5296 case 0xb8: //MOV eAX, Iv
5297 case 0xb9: //MOV eCX, Iv
5298 case 0xba: //MOV eDX, Iv
5299 case 0xbb: //MOV eBX, Iv
5300 case 0xbc: //MOV eSP, Iv
5301 case 0xbd: //MOV eBP, Iv
5302 case 0xbe: //MOV eSI, Iv
5303 case 0xbf: //MOV eDI, Iv
5304 case 0xc7: //MOV G11 Ev, Iv
5305 case 0xe8: //CALL Jv
5308 case 0xf81: //JNO Jv
5310 case 0xf83: //JNC Jv
5312 case 0xf85: //JNZ Jv
5313 case 0xf86: //JNA Jv
5316 case 0xf89: //JNS Jv
5318 case 0xf8b: //JNP Jv
5320 case 0xf8d: //JNL Jv
5321 case 0xf8e: //JNG Jv
5323 if ((prefices
& PREFICES_OPERAND
) != 0)
5328 case 0x9a: //CALLF Ap
5329 case 0xea: //JMPF Ap
5330 if ((prefices
& PREFICES_OPERAND
) != 0)
5335 case 0xf6: //UNA G3 Eb, ?
5336 switch (modrm
& 0x38) {
5337 case 0x00: //TEST Eb, Ib
5343 case 0xf7: //UNA G3 Ev, ?
5344 switch (modrm
& 0x38) {
5345 case 0x00: //TEST Ev, Iv
5346 if ((prefices
& PREFICES_OPERAND
) != 0)
5357 private static int operationHasDisplacement(int prefices
, int opcode
, int modrm
, int sib
)
5361 case 0x00: //ADD Eb, Gb
5362 case 0x01: //ADD Ev, Gv
5363 case 0x02: //ADD Gb, Eb
5364 case 0x03: //ADD Gv, Ev
5365 case 0x08: //OR Eb, Gb
5366 case 0x09: //OR Ev, Gv
5367 case 0x0a: //OR Gb, Eb
5368 case 0x0b: //OR Gv, Ev
5369 case 0x10: //ADC Eb, Gb
5370 case 0x11: //ADC Ev, Gv
5371 case 0x12: //ADC Gb, Eb
5372 case 0x13: //ADC Gv, Ev
5373 case 0x18: //SBB Eb, Gb
5374 case 0x19: //SBB Ev, Gv
5375 case 0x1a: //SBB Gb, Eb
5376 case 0x1b: //SBB Gv, Ev
5377 case 0x20: //AND Eb, Gb
5378 case 0x21: //AND Ev, Gv
5379 case 0x22: //AND Gb, Eb
5380 case 0x23: //AND Gv, Ev
5381 case 0x28: //SUB Eb, Gb
5382 case 0x29: //SUB Ev, Gv
5383 case 0x2a: //SUB Gb, Eb
5384 case 0x2b: //SUB Gv, Ev
5385 case 0x30: //XOR Eb, Gb
5386 case 0x31: //XOR Ev, Gv
5387 case 0x32: //XOR Gb, Eb
5388 case 0x33: //XOR Gv, Ev
5389 case 0x38: //CMP Eb, Gb
5390 case 0x39: //CMP Ev, Gv
5391 case 0x3a: //CMP Gb, Eb
5392 case 0x3b: //CMP Gv, Ev
5393 case 0x62: //BOUND Gv, Ma
5394 case 0x69: //IMUL Gv, Ev, Iv
5395 case 0x6b: //IMUL Gv, Ev, Ib
5396 case 0x80: //IMM G1 Eb, Ib
5397 case 0x81: //IMM G1 Ev, Iv
5398 case 0x82: //IMM G1 Eb, Ib
5399 case 0x83: //IMM G1 Ev, Ib
5400 case 0x84: //TEST Eb, Gb
5401 case 0x85: //TEST Ev, Gv
5402 case 0x86: //XCHG Eb, Gb
5403 case 0x87: //XCHG Ev, Gv
5404 case 0x88: //MOV Eb, Gb
5405 case 0x89: //MOV Ev, Gv
5406 case 0x8a: //MOV Gb, Eb
5407 case 0x8b: //MOV Gv, Ev
5408 case 0x8c: //MOV Ew, Sw
5409 case 0x8d: //LEA Gv, M
5410 case 0x8e: //MOV Sw, Ew
5412 case 0xc0: //SFT G2 Eb, Ib
5413 case 0xc1: //SFT G2 Ev, Ib
5414 case 0xc4: //LES Gv, Mp
5415 case 0xc5: //LDS Gv, Mp
5416 case 0xc6: //MOV G11 Eb, Ib
5417 case 0xc7: //MOV G11 Ev, Iv
5418 case 0xd0: //SFT G2 Eb, 1
5419 case 0xd1: //SFT G2 Ev, 1
5420 case 0xd2: //SFT G2 Eb, CL
5421 case 0xd3: //SFT G2 Ev, CL
5422 case 0xf6: //UNA G3 Eb, ?
5423 case 0xf7: //UNA G3 Ev, ?
5424 case 0xfe: //INC/DEC G4 Eb
5425 case 0xff: //INC/DEC G5
5429 case 0xf02: //LAR Gv, Ew
5430 case 0xf03: //LSL Gv, Ew
5432 case 0xf20: //MOV Rd, Cd
5433 case 0xf22: //MOV Cd, Rd
5436 case 0xf41: //CMOVNO
5438 case 0xf43: //CMOVNC
5440 case 0xf45: //CMOVNZ
5441 case 0xf46: //CMOVBE
5442 case 0xf47: //CMOVNBE
5444 case 0xf49: //CMOVNS
5446 case 0xf4b: //CMOVNP
5448 case 0xf4d: //CMOVNL
5449 case 0xf4e: //CMOVLE
5450 case 0xf4f: //CMOVNLE
5459 case 0xf97: //SETNBE
5467 case 0xf9f: //SETNLE
5469 case 0xfa3: //BT Ev, Gv
5470 case 0xfa4: //SHLD Ev, Gv, Ib
5471 case 0xfa5: //SHLD Ev, Gv, CL
5472 case 0xfab: //BTS Ev, Gv
5473 case 0xfac: //SHRD Ev, Gv, Ib
5474 case 0xfad: //SHRD Ev, Gv, CL
5476 case 0xfaf: //IMUL Gv, Ev
5478 case 0xfb0: //CMPXCHG Eb, Gb
5479 case 0xfb1: //CMPXCHG Ev, Gv
5480 case 0xfb2: //LSS Mp
5481 case 0xfb3: //BTR Ev, Gv
5482 case 0xfb4: //LFS Mp
5483 case 0xfb5: //LGS Mp
5484 case 0xfb6: //MOVZX Gv, Eb
5485 case 0xfb7: //MOVZX Gv, Ew
5487 case 0xfba: //Grp 8 Ev, Ib
5488 case 0xfbb: //BTC Ev, Gv
5489 case 0xfbc: //BSF Gv, Ev
5490 case 0xfbd: //BSR Gv, Ev
5491 case 0xfbe: //MOVSX Gv, Eb
5492 case 0xfbf: //MOVSX Gv, Ew
5493 case 0xfc0: //XADD Eb, Gb
5494 case 0xfc1: //XADD Ev, Gv
5496 case 0xfc7: //CMPXCHG8B
5497 return modrmHasDisplacement(prefices
, modrm
, sib
);
5508 if ((modrm
& 0xc0) != 0xc0)
5509 return modrmHasDisplacement(prefices
, modrm
, sib
);
5514 case 0xa0: //MOV AL, Ob
5515 case 0xa2: //MOV Ob, AL
5516 case 0xa1: //MOV eAX, Ov
5517 case 0xa3: //MOV Ov, eAX
5518 if ((prefices
& PREFICES_ADDRESS
) != 0)
5528 private static int modrmHasDisplacement(int prefices
, int modrm
, int sib
)
5530 if ((prefices
& PREFICES_ADDRESS
) != 0) {
5531 //32 bit address size
5532 switch(modrm
& 0xc0) {
5534 switch (modrm
& 0x7) {
5536 if ((sib
& 0x7) == 0x5)
5543 case 0x40: return 1; //IB
5544 case 0x80: return 4; //ID
5547 //16 bit address size
5548 switch(modrm
& 0xc0) {
5550 if ((modrm
& 0x7) == 0x6)
5554 case 0x40: return 1; //IB
5555 case 0x80: return 2; //IW
5562 public static boolean isFarJump(int opcode
, int modrm
)
5566 case 0x9a: //CALLF Ap
5567 case 0xca: //RETF Iw
5573 case 0xea: //JMPF Ap
5575 case 0xf34: //SYSENTER
5576 case 0xf35: //SYSEXIT
5580 switch (modrm
& 0x38) {
5581 case 0x18: //CALLF Ep
5582 case 0x28: //JMPF Ep
5584 default: return false;
5592 public static boolean isNearJump(int opcode
, int modrm
)
5614 case 0xe0: //LOOPNZ Jb
5615 case 0xe1: //LOOPZ Jb
5616 case 0xe2: //LOOP Jb
5617 case 0xe3: //JCXZ Jb
5618 case 0xe8: //CALL Jv
5624 switch (modrm
& 0x38) {
5625 case 0x10: //CALLN Ed
5626 case 0x20: //JMPN Ed
5628 default: return false;
5631 case 0x0f80: //Jcc Jv
5653 public static boolean isModeSwitch(int opcode
, int modrm
)
5656 case 0x0f22: //MOV Cd, Ed
5659 return ((modrm
& 0x38) == 0x30);
5665 public static boolean isBlockTerminating(int opcode
, int modrm
)
5676 public static boolean isJump(int opcode
, int modrm
)
5678 return isNearJump(opcode
, modrm
) || isFarJump(opcode
, modrm
) || isModeSwitch(opcode
, modrm
) || isBlockTerminating(opcode
, modrm
);
5681 private void store0_Cd(int modrm
)
5683 switch(modrm
& 0x38) {
5684 case 0x00: working
.write(STORE0_CR0
); break;
5685 case 0x10: working
.write(STORE0_CR2
); break;
5686 case 0x18: working
.write(STORE0_CR3
); break;
5687 case 0x20: working
.write(STORE0_CR4
); break;
5688 default: throw new IllegalStateException("Unknown Control Register Operand");
5692 private void load0_Cd(int modrm
)
5694 switch(modrm
& 0x38) {
5695 case 0x00: working
.write(LOAD0_CR0
); break;
5696 case 0x10: working
.write(LOAD0_CR2
); break;
5697 case 0x18: working
.write(LOAD0_CR3
); break;
5698 case 0x20: working
.write(LOAD0_CR4
); break;
5699 default: throw new IllegalStateException("Unknown Control Register Operand");
5703 private void store0_Dd(int modrm
)
5705 switch(modrm
& 0x38) {
5706 case 0x00: working
.write(STORE0_DR0
); break;
5707 case 0x08: working
.write(STORE0_DR1
); break;
5708 case 0x10: working
.write(STORE0_DR2
); break;
5709 case 0x18: working
.write(STORE0_DR3
); break;
5710 case 0x30: working
.write(STORE0_DR6
); break;
5711 case 0x38: working
.write(STORE0_DR7
); break;
5712 default: throw new IllegalStateException("Unknown Debug Register Operand");
5716 private void load0_Dd(int modrm
)
5718 switch(modrm
& 0x38) {
5719 case 0x00: working
.write(LOAD0_DR0
); break;
5720 case 0x08: working
.write(LOAD0_DR1
); break;
5721 case 0x10: working
.write(LOAD0_DR2
); break;
5722 case 0x18: working
.write(LOAD0_DR3
); break;
5723 case 0x30: working
.write(LOAD0_DR6
); break;
5724 case 0x38: working
.write(LOAD0_DR7
); break;
5725 default: throw new IllegalStateException("Unknown Debug Register Operand");
5729 private void load0_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5731 switch(modrm
& 0xc7) {
5732 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_BYTE
); break;
5734 case 0xc0: working
.write(LOAD0_AL
); break;
5735 case 0xc1: working
.write(LOAD0_CL
); break;
5736 case 0xc2: working
.write(LOAD0_DL
); break;
5737 case 0xc3: working
.write(LOAD0_BL
); break;
5738 case 0xc4: working
.write(LOAD0_AH
); break;
5739 case 0xc5: working
.write(LOAD0_CH
); break;
5740 case 0xc6: working
.write(LOAD0_DH
); break;
5741 case 0xc7: working
.write(LOAD0_BH
); break;
5744 private void load1_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5746 switch(modrm
& 0xc7) {
5747 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_BYTE
); break;
5749 case 0xc0: working
.write(LOAD1_AL
); break;
5750 case 0xc1: working
.write(LOAD1_CL
); break;
5751 case 0xc2: working
.write(LOAD1_DL
); break;
5752 case 0xc3: working
.write(LOAD1_BL
); break;
5753 case 0xc4: working
.write(LOAD1_AH
); break;
5754 case 0xc5: working
.write(LOAD1_CH
); break;
5755 case 0xc6: working
.write(LOAD1_DH
); break;
5756 case 0xc7: working
.write(LOAD1_BH
); break;
5759 private void store0_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5761 switch(modrm
& 0xc7) {
5762 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_BYTE
); break;
5764 case 0xc0: working
.write(STORE0_AL
); break;
5765 case 0xc1: working
.write(STORE0_CL
); break;
5766 case 0xc2: working
.write(STORE0_DL
); break;
5767 case 0xc3: working
.write(STORE0_BL
); break;
5768 case 0xc4: working
.write(STORE0_AH
); break;
5769 case 0xc5: working
.write(STORE0_CH
); break;
5770 case 0xc6: working
.write(STORE0_DH
); break;
5771 case 0xc7: working
.write(STORE0_BH
); break;
5774 private void store1_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5776 switch(modrm
& 0xc7) {
5777 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_BYTE
); break;
5779 case 0xc0: working
.write(STORE1_AL
); break;
5780 case 0xc1: working
.write(STORE1_CL
); break;
5781 case 0xc2: working
.write(STORE1_DL
); break;
5782 case 0xc3: working
.write(STORE1_BL
); break;
5783 case 0xc4: working
.write(STORE1_AH
); break;
5784 case 0xc5: working
.write(STORE1_CH
); break;
5785 case 0xc6: working
.write(STORE1_DH
); break;
5786 case 0xc7: working
.write(STORE1_BH
); break;
5790 private void load0_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5792 switch (modrm
& 0xc7) {
5793 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_WORD
); break;
5795 case 0xc0: working
.write(LOAD0_AX
); break;
5796 case 0xc1: working
.write(LOAD0_CX
); break;
5797 case 0xc2: working
.write(LOAD0_DX
); break;
5798 case 0xc3: working
.write(LOAD0_BX
); break;
5799 case 0xc4: working
.write(LOAD0_SP
); break;
5800 case 0xc5: working
.write(LOAD0_BP
); break;
5801 case 0xc6: working
.write(LOAD0_SI
); break;
5802 case 0xc7: working
.write(LOAD0_DI
); break;
5805 private void store0_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5807 switch (modrm
& 0xc7) {
5808 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_WORD
); break;
5810 case 0xc0: working
.write(STORE0_AX
); break;
5811 case 0xc1: working
.write(STORE0_CX
); break;
5812 case 0xc2: working
.write(STORE0_DX
); break;
5813 case 0xc3: working
.write(STORE0_BX
); break;
5814 case 0xc4: working
.write(STORE0_SP
); break;
5815 case 0xc5: working
.write(STORE0_BP
); break;
5816 case 0xc6: working
.write(STORE0_SI
); break;
5817 case 0xc7: working
.write(STORE0_DI
); break;
5820 private void load1_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5822 switch (modrm
& 0xc7) {
5823 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_WORD
); break;
5825 case 0xc0: working
.write(LOAD1_AX
); break;
5826 case 0xc1: working
.write(LOAD1_CX
); break;
5827 case 0xc2: working
.write(LOAD1_DX
); break;
5828 case 0xc3: working
.write(LOAD1_BX
); break;
5829 case 0xc4: working
.write(LOAD1_SP
); break;
5830 case 0xc5: working
.write(LOAD1_BP
); break;
5831 case 0xc6: working
.write(LOAD1_SI
); break;
5832 case 0xc7: working
.write(LOAD1_DI
); break;
5835 private void store1_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5837 switch (modrm
& 0xc7) {
5838 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_WORD
); break;
5840 case 0xc0: working
.write(STORE1_AX
); break;
5841 case 0xc1: working
.write(STORE1_CX
); break;
5842 case 0xc2: working
.write(STORE1_DX
); break;
5843 case 0xc3: working
.write(STORE1_BX
); break;
5844 case 0xc4: working
.write(STORE1_SP
); break;
5845 case 0xc5: working
.write(STORE1_BP
); break;
5846 case 0xc6: working
.write(STORE1_SI
); break;
5847 case 0xc7: working
.write(STORE1_DI
); break;
5851 private void load0_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5853 switch (modrm
& 0xc7) {
5854 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_DWORD
); break;
5856 case 0xc0: working
.write(LOAD0_EAX
); break;
5857 case 0xc1: working
.write(LOAD0_ECX
); break;
5858 case 0xc2: working
.write(LOAD0_EDX
); break;
5859 case 0xc3: working
.write(LOAD0_EBX
); break;
5860 case 0xc4: working
.write(LOAD0_ESP
); break;
5861 case 0xc5: working
.write(LOAD0_EBP
); break;
5862 case 0xc6: working
.write(LOAD0_ESI
); break;
5863 case 0xc7: working
.write(LOAD0_EDI
); break;
5867 private void store0_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5869 switch (modrm
& 0xc7) {
5870 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_DWORD
); break;
5872 case 0xc0: working
.write(STORE0_EAX
); break;
5873 case 0xc1: working
.write(STORE0_ECX
); break;
5874 case 0xc2: working
.write(STORE0_EDX
); break;
5875 case 0xc3: working
.write(STORE0_EBX
); break;
5876 case 0xc4: working
.write(STORE0_ESP
); break;
5877 case 0xc5: working
.write(STORE0_EBP
); break;
5878 case 0xc6: working
.write(STORE0_ESI
); break;
5879 case 0xc7: working
.write(STORE0_EDI
); break;
5882 private void load1_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5884 switch (modrm
& 0xc7) {
5885 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_DWORD
); break;
5887 case 0xc0: working
.write(LOAD1_EAX
); break;
5888 case 0xc1: working
.write(LOAD1_ECX
); break;
5889 case 0xc2: working
.write(LOAD1_EDX
); break;
5890 case 0xc3: working
.write(LOAD1_EBX
); break;
5891 case 0xc4: working
.write(LOAD1_ESP
); break;
5892 case 0xc5: working
.write(LOAD1_EBP
); break;
5893 case 0xc6: working
.write(LOAD1_ESI
); break;
5894 case 0xc7: working
.write(LOAD1_EDI
); break;
5898 private void store1_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5900 switch (modrm
& 0xc7) {
5901 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_DWORD
); break;
5903 case 0xc0: working
.write(STORE1_EAX
); break;
5904 case 0xc1: working
.write(STORE1_ECX
); break;
5905 case 0xc2: working
.write(STORE1_EDX
); break;
5906 case 0xc3: working
.write(STORE1_EBX
); break;
5907 case 0xc4: working
.write(STORE1_ESP
); break;
5908 case 0xc5: working
.write(STORE1_EBP
); break;
5909 case 0xc6: working
.write(STORE1_ESI
); break;
5910 case 0xc7: working
.write(STORE1_EDI
); break;
5914 private void load0_Eq(int prefices
, int modrm
, int sib
, int displacement
)
5916 switch (modrm
& 0xc7) {
5917 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_QWORD
); break;
5926 throw new IllegalStateException("There are no 64bit GP Registers");
5930 private void load0_Gb(int modrm
)
5932 switch(modrm
& 0x38) {
5933 case 0x00: working
.write(LOAD0_AL
); break;
5934 case 0x08: working
.write(LOAD0_CL
); break;
5935 case 0x10: working
.write(LOAD0_DL
); break;
5936 case 0x18: working
.write(LOAD0_BL
); break;
5937 case 0x20: working
.write(LOAD0_AH
); break;
5938 case 0x28: working
.write(LOAD0_CH
); break;
5939 case 0x30: working
.write(LOAD0_DH
); break;
5940 case 0x38: working
.write(LOAD0_BH
); break;
5941 default: throw new IllegalStateException("Unknown Byte Register Operand");
5944 private void store0_Gb(int modrm
)
5946 switch(modrm
& 0x38) {
5947 case 0x00: working
.write(STORE0_AL
); break;
5948 case 0x08: working
.write(STORE0_CL
); break;
5949 case 0x10: working
.write(STORE0_DL
); break;
5950 case 0x18: working
.write(STORE0_BL
); break;
5951 case 0x20: working
.write(STORE0_AH
); break;
5952 case 0x28: working
.write(STORE0_CH
); break;
5953 case 0x30: working
.write(STORE0_DH
); break;
5954 case 0x38: working
.write(STORE0_BH
); break;
5955 default: throw new IllegalStateException("Unknown Byte Register Operand");
5958 private void load1_Gb(int modrm
)
5960 switch(modrm
& 0x38) {
5961 case 0x00: working
.write(LOAD1_AL
); break;
5962 case 0x08: working
.write(LOAD1_CL
); break;
5963 case 0x10: working
.write(LOAD1_DL
); break;
5964 case 0x18: working
.write(LOAD1_BL
); break;
5965 case 0x20: working
.write(LOAD1_AH
); break;
5966 case 0x28: working
.write(LOAD1_CH
); break;
5967 case 0x30: working
.write(LOAD1_DH
); break;
5968 case 0x38: working
.write(LOAD1_BH
); break;
5969 default: throw new IllegalStateException("Unknown Byte Register Operand");
5972 private void store1_Gb(int modrm
)
5974 switch(modrm
& 0x38) {
5975 case 0x00: working
.write(STORE1_AL
); break;
5976 case 0x08: working
.write(STORE1_CL
); break;
5977 case 0x10: working
.write(STORE1_DL
); break;
5978 case 0x18: working
.write(STORE1_BL
); break;
5979 case 0x20: working
.write(STORE1_AH
); break;
5980 case 0x28: working
.write(STORE1_CH
); break;
5981 case 0x30: working
.write(STORE1_DH
); break;
5982 case 0x38: working
.write(STORE1_BH
); break;
5983 default: throw new IllegalStateException("Unknown Byte Register Operand");
5987 private void load0_Gw(int modrm
)
5989 switch(modrm
& 0x38) {
5990 case 0x00: working
.write(LOAD0_AX
); break;
5991 case 0x08: working
.write(LOAD0_CX
); break;
5992 case 0x10: working
.write(LOAD0_DX
); break;
5993 case 0x18: working
.write(LOAD0_BX
); break;
5994 case 0x20: working
.write(LOAD0_SP
); break;
5995 case 0x28: working
.write(LOAD0_BP
); break;
5996 case 0x30: working
.write(LOAD0_SI
); break;
5997 case 0x38: working
.write(LOAD0_DI
); break;
5998 default: throw new IllegalStateException("Unknown Word Register Operand");
6001 private void store0_Gw(int modrm
)
6003 switch(modrm
& 0x38) {
6004 case 0x00: working
.write(STORE0_AX
); break;
6005 case 0x08: working
.write(STORE0_CX
); break;
6006 case 0x10: working
.write(STORE0_DX
); break;
6007 case 0x18: working
.write(STORE0_BX
); break;
6008 case 0x20: working
.write(STORE0_SP
); break;
6009 case 0x28: working
.write(STORE0_BP
); break;
6010 case 0x30: working
.write(STORE0_SI
); break;
6011 case 0x38: working
.write(STORE0_DI
); break;
6012 default: throw new IllegalStateException("Unknown Word Register Operand");
6015 private void load1_Gw(int modrm
)
6017 switch(modrm
& 0x38) {
6018 case 0x00: working
.write(LOAD1_AX
); break;
6019 case 0x08: working
.write(LOAD1_CX
); break;
6020 case 0x10: working
.write(LOAD1_DX
); break;
6021 case 0x18: working
.write(LOAD1_BX
); break;
6022 case 0x20: working
.write(LOAD1_SP
); break;
6023 case 0x28: working
.write(LOAD1_BP
); break;
6024 case 0x30: working
.write(LOAD1_SI
); break;
6025 case 0x38: working
.write(LOAD1_DI
); break;
6026 default: throw new IllegalStateException("Unknown Word Register Operand");
6029 private void store1_Gw(int modrm
)
6031 switch(modrm
& 0x38) {
6032 case 0x00: working
.write(STORE1_AX
); break;
6033 case 0x08: working
.write(STORE1_CX
); break;
6034 case 0x10: working
.write(STORE1_DX
); break;
6035 case 0x18: working
.write(STORE1_BX
); break;
6036 case 0x20: working
.write(STORE1_SP
); break;
6037 case 0x28: working
.write(STORE1_BP
); break;
6038 case 0x30: working
.write(STORE1_SI
); break;
6039 case 0x38: working
.write(STORE1_DI
); break;
6040 default: throw new IllegalStateException("Unknown Word Register Operand");
6044 private void load0_Gd(int modrm
)
6046 switch(modrm
& 0x38) {
6047 case 0x00: working
.write(LOAD0_EAX
); break;
6048 case 0x08: working
.write(LOAD0_ECX
); break;
6049 case 0x10: working
.write(LOAD0_EDX
); break;
6050 case 0x18: working
.write(LOAD0_EBX
); break;
6051 case 0x20: working
.write(LOAD0_ESP
); break;
6052 case 0x28: working
.write(LOAD0_EBP
); break;
6053 case 0x30: working
.write(LOAD0_ESI
); break;
6054 case 0x38: working
.write(LOAD0_EDI
); break;
6055 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6058 private void store0_Gd(int modrm
)
6060 switch(modrm
& 0x38) {
6061 case 0x00: working
.write(STORE0_EAX
); break;
6062 case 0x08: working
.write(STORE0_ECX
); break;
6063 case 0x10: working
.write(STORE0_EDX
); break;
6064 case 0x18: working
.write(STORE0_EBX
); break;
6065 case 0x20: working
.write(STORE0_ESP
); break;
6066 case 0x28: working
.write(STORE0_EBP
); break;
6067 case 0x30: working
.write(STORE0_ESI
); break;
6068 case 0x38: working
.write(STORE0_EDI
); break;
6069 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6072 private void load1_Gd(int modrm
)
6074 switch(modrm
& 0x38) {
6075 case 0x00: working
.write(LOAD1_EAX
); break;
6076 case 0x08: working
.write(LOAD1_ECX
); break;
6077 case 0x10: working
.write(LOAD1_EDX
); break;
6078 case 0x18: working
.write(LOAD1_EBX
); break;
6079 case 0x20: working
.write(LOAD1_ESP
); break;
6080 case 0x28: working
.write(LOAD1_EBP
); break;
6081 case 0x30: working
.write(LOAD1_ESI
); break;
6082 case 0x38: working
.write(LOAD1_EDI
); break;
6083 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6086 private void store1_Gd(int modrm
)
6088 switch(modrm
& 0x38) {
6089 case 0x00: working
.write(STORE1_EAX
); break;
6090 case 0x08: working
.write(STORE1_ECX
); break;
6091 case 0x10: working
.write(STORE1_EDX
); break;
6092 case 0x18: working
.write(STORE1_EBX
); break;
6093 case 0x20: working
.write(STORE1_ESP
); break;
6094 case 0x28: working
.write(STORE1_EBP
); break;
6095 case 0x30: working
.write(STORE1_ESI
); break;
6096 case 0x38: working
.write(STORE1_EDI
); break;
6097 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6101 private void load0_Sw(int modrm
)
6103 switch(modrm
& 0x38) {
6104 case 0x00: working
.write(LOAD0_ES
); break;
6105 case 0x08: working
.write(LOAD0_CS
); break;
6106 case 0x10: working
.write(LOAD0_SS
); break;
6107 case 0x18: working
.write(LOAD0_DS
); break;
6108 case 0x20: working
.write(LOAD0_FS
); break;
6109 case 0x28: working
.write(LOAD0_GS
); break;
6110 default: throw new IllegalStateException("Unknown Segment Register Operand");
6113 private void store0_Sw(int modrm
)
6115 switch(modrm
& 0x38) {
6116 case 0x00: working
.write(STORE0_ES
); break;
6117 case 0x08: working
.write(STORE0_CS
); break;
6118 case 0x10: working
.write(STORE0_SS
); break;
6119 case 0x18: working
.write(STORE0_DS
); break;
6120 case 0x20: working
.write(STORE0_FS
); break;
6121 case 0x28: working
.write(STORE0_GS
); break;
6122 default: throw new IllegalStateException("Unknown Segment Register Operand");
6126 private void decodeO(int prefices
, int displacement
)
6128 switch (prefices
& PREFICES_SG
) {
6130 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6131 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6132 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6133 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6134 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6135 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6138 if ((prefices
& PREFICES_ADDRESS
) != 0) {
6139 if (decodingAddressMode())
6140 working
.write(ADDR_ID
); working
.write(displacement
);
6142 if (decodingAddressMode()) {
6143 working
.write(ADDR_IW
); working
.write(displacement
);
6144 working
.write(ADDR_MASK16
);
6149 private void load0_Ob(int prefices
, int displacement
)
6151 decodeO(prefices
, displacement
);
6152 working
.write(LOAD0_MEM_BYTE
);
6154 private void store0_Ob(int prefices
, int displacement
)
6156 decodeO(prefices
, displacement
);
6157 working
.write(STORE0_MEM_BYTE
);
6160 private void load0_Ow(int prefices
, int displacement
)
6162 decodeO(prefices
, displacement
);
6163 working
.write(LOAD0_MEM_WORD
);
6165 private void store0_Ow(int prefices
, int displacement
)
6167 decodeO(prefices
, displacement
);
6168 working
.write(STORE0_MEM_WORD
);
6171 private void load0_Od(int prefices
, int displacement
)
6173 decodeO(prefices
, displacement
);
6174 working
.write(LOAD0_MEM_DWORD
);
6176 private void store0_Od(int prefices
, int displacement
)
6178 decodeO(prefices
, displacement
);
6179 working
.write(STORE0_MEM_DWORD
);
6182 private void load0_M(int prefices
, int modrm
, int sib
, int displacement
)
6184 decodeM(prefices
, modrm
, sib
, displacement
);
6185 working
.write(LOAD0_ADDR
);
6188 private void decodeM(int prefices
, int modrm
, int sib
, int displacement
)
6190 if (!decodingAddressMode()) return;
6192 if ((prefices
& PREFICES_ADDRESS
) != 0) {
6193 //32 bit address size
6196 switch (prefices
& PREFICES_SG
) {
6198 switch (modrm
& 0xc7) {
6199 default: working
.write(LOAD_SEG_DS
); break;
6202 case 0x84: break; //segment working.write will occur in decodeSIB
6204 case 0x85: working
.write(LOAD_SEG_SS
); break;
6207 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6208 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6209 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6210 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6211 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6212 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6216 switch(modrm
& 0x7) {
6217 case 0x0: working
.write(ADDR_EAX
); break;
6218 case 0x1: working
.write(ADDR_ECX
); break;
6219 case 0x2: working
.write(ADDR_EDX
); break;
6220 case 0x3: working
.write(ADDR_EBX
); break;
6221 case 0x4: decodeSIB(prefices
, modrm
, sib
, displacement
); break;
6223 if((modrm
& 0xc0) == 0x00) {
6224 working
.write(ADDR_ID
);
6225 working
.write(displacement
);
6227 working
.write(ADDR_EBP
);
6229 case 0x6: working
.write(ADDR_ESI
); break;
6230 case 0x7: working
.write(ADDR_EDI
); break;
6233 switch(modrm
& 0xc0) {
6234 case 0x40: working
.write(ADDR_IB
); working
.write(displacement
); break;
6235 case 0x80: working
.write(ADDR_ID
); working
.write(displacement
); break;
6238 //16 bit address size
6240 switch (prefices
& PREFICES_SG
) {
6242 switch (modrm
& 0xc7) {
6243 default: working
.write(LOAD_SEG_DS
); break;
6251 case 0x86: working
.write(LOAD_SEG_SS
); break;
6254 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6255 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6256 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6257 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6258 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6259 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6262 switch (modrm
& 0x7) {
6263 case 0x0: working
.write(ADDR_BX
); working
.write(ADDR_SI
); break;
6264 case 0x1: working
.write(ADDR_BX
); working
.write(ADDR_DI
); break;
6265 case 0x2: working
.write(ADDR_BP
); working
.write(ADDR_SI
); break;
6266 case 0x3: working
.write(ADDR_BP
); working
.write(ADDR_DI
); break;
6267 case 0x4: working
.write(ADDR_SI
); break;
6268 case 0x5: working
.write(ADDR_DI
); break;
6270 if ((modrm
& 0xc0) == 0x00) {
6271 working
.write(ADDR_IW
);
6272 working
.write(displacement
);
6274 working
.write(ADDR_BP
);
6277 case 0x7: working
.write(ADDR_BX
); break;
6280 switch (modrm
& 0xc0) {
6281 case 0x40: working
.write(ADDR_IB
); working
.write(displacement
); break;
6282 case 0x80: working
.write(ADDR_IW
); working
.write(displacement
); break;
6284 working
.write(ADDR_MASK16
);
6288 private void decodeSIB(int prefices
, int modrm
, int sib
, int displacement
)
6290 switch (prefices
& PREFICES_SG
) {
6292 switch (sib
& 0x7) {
6293 default: working
.write(LOAD_SEG_DS
); break;
6294 case 0x4: working
.write(LOAD_SEG_SS
); break;
6296 switch (modrm
& 0xc0) {
6297 default: working
.write(LOAD_SEG_SS
); break;
6298 case 0x00: working
.write(LOAD_SEG_DS
); break;
6301 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6302 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6303 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6304 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6305 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6306 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6310 switch (sib
& 0x7) {
6311 case 0x0: working
.write(ADDR_EAX
); break;
6312 case 0x1: working
.write(ADDR_ECX
); break;
6313 case 0x2: working
.write(ADDR_EDX
); break;
6314 case 0x3: working
.write(ADDR_EBX
); break;
6315 case 0x4: working
.write(ADDR_ESP
); break;
6317 switch (modrm
& 0xc0) {
6318 default: working
.write(ADDR_EBP
); break;
6319 case 0x00: working
.write(ADDR_ID
); working
.write(displacement
); break;
6321 case 0x6: working
.write(ADDR_ESI
); break;
6322 case 0x7: working
.write(ADDR_EDI
); break;
6326 switch (sib
& 0xf8) {
6327 case 0x00: working
.write(ADDR_EAX
); break;
6328 case 0x08: working
.write(ADDR_ECX
); break;
6329 case 0x10: working
.write(ADDR_EDX
); break;
6330 case 0x18: working
.write(ADDR_EBX
); break;
6331 case 0x20: break; //none
6332 case 0x28: working
.write(ADDR_EBP
); break;
6333 case 0x30: working
.write(ADDR_ESI
); break;
6334 case 0x38: working
.write(ADDR_EDI
); break;
6336 case 0x40: working
.write(ADDR_2EAX
); break;
6337 case 0x48: working
.write(ADDR_2ECX
); break;
6338 case 0x50: working
.write(ADDR_2EDX
); break;
6339 case 0x58: working
.write(ADDR_2EBX
); break;
6340 case 0x60: break; //none
6341 case 0x68: working
.write(ADDR_2EBP
); break;
6342 case 0x70: working
.write(ADDR_2ESI
); break;
6343 case 0x78: working
.write(ADDR_2EDI
); break;
6345 case 0x80: working
.write(ADDR_4EAX
); break;
6346 case 0x88: working
.write(ADDR_4ECX
); break;
6347 case 0x90: working
.write(ADDR_4EDX
); break;
6348 case 0x98: working
.write(ADDR_4EBX
); break;
6349 case 0xa0: break; //none
6350 case 0xa8: working
.write(ADDR_4EBP
); break;
6351 case 0xb0: working
.write(ADDR_4ESI
); break;
6352 case 0xb8: working
.write(ADDR_4EDI
); break;
6354 case 0xc0: working
.write(ADDR_8EAX
); break;
6355 case 0xc8: working
.write(ADDR_8ECX
); break;
6356 case 0xd0: working
.write(ADDR_8EDX
); break;
6357 case 0xd8: working
.write(ADDR_8EBX
); break;
6358 case 0xe0: break; //none
6359 case 0xe8: working
.write(ADDR_8EBP
); break;
6360 case 0xf0: working
.write(ADDR_8ESI
); break;
6361 case 0xf8: working
.write(ADDR_8EDI
); break;
6365 private void decodeSegmentPrefix(int prefices
)
6367 switch (prefices
& PREFICES_SG
) {
6369 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6370 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6371 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6372 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6373 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6374 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6378 private void store0_Rd(int modrm
)
6380 switch (modrm
& 0xc7) {
6381 case 0xc0: working
.write(STORE0_EAX
); break;
6382 case 0xc1: working
.write(STORE0_ECX
); break;
6383 case 0xc2: working
.write(STORE0_EDX
); break;
6384 case 0xc3: working
.write(STORE0_EBX
); break;
6385 case 0xc4: working
.write(STORE0_ESP
); break;
6386 case 0xc5: working
.write(STORE0_EBP
); break;
6387 case 0xc6: working
.write(STORE0_ESI
); break;
6388 case 0xc7: working
.write(STORE0_EDI
); break;
6389 default: throw new IllegalStateException("Rd cannot be a memory location");
6393 private void load0_Rd(int modrm
)
6395 switch (modrm
& 0xc7) {
6396 case 0xc0: working
.write(LOAD0_EAX
); break;
6397 case 0xc1: working
.write(LOAD0_ECX
); break;
6398 case 0xc2: working
.write(LOAD0_EDX
); break;
6399 case 0xc3: working
.write(LOAD0_EBX
); break;
6400 case 0xc4: working
.write(LOAD0_ESP
); break;
6401 case 0xc5: working
.write(LOAD0_EBP
); break;
6402 case 0xc6: working
.write(LOAD0_ESI
); break;
6403 case 0xc7: working
.write(LOAD0_EDI
); break;
6404 default: throw new IllegalStateException("Rd cannot be a memory location");
6408 private static class Operation
6410 private int[] microcodes
;
6411 private int microcodesLength
;
6412 private int x86Length
;
6413 private int readOffset
;
6414 private boolean decoded
;
6415 private boolean terminal
;
6419 microcodes
= new int[10];
6422 void write(int microcode
)
6425 microcodes
[microcodesLength
] = microcode
;
6427 } catch (ArrayIndexOutOfBoundsException e
) {
6428 int[] temp
= new int[2*microcodes
.length
];
6429 System
.arraycopy(microcodes
, 0, temp
, 0, microcodes
.length
);
6431 microcodes
[microcodesLength
++] = microcode
;
6435 void replace(int offset
, int microcode
)
6437 microcodes
[offset
] = microcode
;
6440 void finish(int x86Length
)
6442 this.x86Length
= x86Length
;
6464 microcodesLength
= 0;
6471 int getMicrocodeAt(int offset
)
6473 return microcodes
[offset
];
6478 if (readOffset
< microcodesLength
)
6479 return microcodes
[readOffset
++];
6481 System
.err
.println("Critical error: Attempted read outside microcode array.");
6482 throw new IllegalStateException("Attempted read outside microcode array");
6488 return microcodesLength
;