2 JPC-RR: A x86 PC Hardware Emulator
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009 H. Ilari Liusvaara
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as published by
10 the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 Based on JPC x86 PC Hardware emulator,
22 A project from the Physics Dept, The University of Oxford
24 Details about original JPC can be found at:
26 www-jpc.physics.ox.ac.uk
30 package org
.jpc
.emulator
.memory
.codeblock
.optimised
;
32 import org
.jpc
.emulator
.memory
.codeblock
.*;
34 import static org
.jpc
.emulator
.memory
.codeblock
.optimised
.MicrocodeSet
.*;
38 * @author Chris Dennis
40 public final class 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)
1935 switch (modrm
& 0x38)
1937 case 0x00: working
.write(FPUSH
); break;
1943 if ((prefices
& PREFICES_OPERAND
) != 0)
1944 working
.write(FLDENV_28
);
1946 working
.write(FLDENV_14
);
1949 if ((prefices
& PREFICES_OPERAND
) != 0)
1950 working
.write(FSTENV_28
);
1952 working
.write(FSTENV_14
);
1958 switch (modrm
& 0xf8)
1960 case 0xc0: working
.write(FPUSH
); break;
1966 case 0xe0: working
.write(FCHS
); break;
1967 case 0xe1: working
.write(FABS
); break;
1968 case 0xe4: working
.write(FCOM
); break;
1969 case 0xe5: working
.write(FXAM
); break;
1976 case 0xee: working
.write(FPUSH
); break;
1977 case 0xf0: working
.write(F2XM1
); break;
1978 case 0xf1: working
.write(FYL2X
); break;
1979 case 0xf2: working
.write(FPTAN
); break;
1980 case 0xf3: working
.write(FPATAN
); break;
1981 case 0xf4: working
.write(FXTRACT
); break;
1982 case 0xf5: working
.write(FPREM1
); break;
1983 case 0xf6: working
.write(FDECSTP
); break;
1984 case 0xf7: working
.write(FINCSTP
); break;
1985 case 0xf8: working
.write(FPREM
); break;
1986 case 0xf9: working
.write(FYL2XP1
); break;
1987 case 0xfa: working
.write(FSQRT
); break;
1988 case 0xfb: working
.write(FSINCOS
); break;
1989 case 0xfc: working
.write(FRNDINT
); break;
1990 case 0xfd: working
.write(FSCALE
); break;
1991 case 0xfe: working
.write(FSIN
); break;
1992 case 0xff: working
.write(FCOS
); break;
1998 if ((modrm
& 0xc0) != 0xc0)
2000 switch (modrm
& 0x38)
2002 case 0x00: working
.write(FADD
); break;
2003 case 0x08: working
.write(FMUL
); break;
2005 case 0x18: working
.write(FCOM
); break;
2007 case 0x28: working
.write(FSUB
); break;
2009 case 0x38: working
.write(FDIV
); break;
2014 switch (modrm
& 0xf8)
2016 case 0xc0: working
.write(FCMOVB
); break;
2017 case 0xc8: working
.write(FCMOVE
); break;
2018 case 0xd0: working
.write(FCMOVBE
); break;
2019 case 0xd8: working
.write(FCMOVU
); break;
2023 case 0xe9: working
.write(FUCOM
); break;
2029 if ((modrm
& 0xc0) != 0xc0)
2031 switch (modrm
& 0x38)
2033 case 0x00: working
.write(FPUSH
); break;
2034 case 0x08: working
.write(FCHOP
); break;
2036 case 0x18: working
.write(FRNDINT
); break;
2037 case 0x28: working
.write(FPUSH
); break;
2043 switch (modrm
& 0xf8)
2045 case 0xc0: working
.write(FCMOVNB
); break;
2046 case 0xc8: working
.write(FCMOVNE
); break;
2047 case 0xd0: working
.write(FCMOVNBE
); break;
2048 case 0xd8: working
.write(FCMOVNU
); break;
2049 case 0xe8: working
.write(FUCOMI
); break;
2050 case 0xf0: working
.write(FCOMI
); break;
2054 case 0xe2: working
.write(FCLEX
); break;
2055 case 0xe3: working
.write(FINIT
); break;
2062 switch (modrm
& 0x38)
2064 case 0x00: working
.write(FADD
); break;
2065 case 0x08: working
.write(FMUL
); break;
2067 case 0x18: working
.write(FCOM
); break;
2069 case 0x28: working
.write(FSUB
); break;
2071 case 0x38: working
.write(FDIV
); break;
2076 if ((modrm
& 0xc0) != 0xc0)
2078 switch (modrm
& 0x38)
2080 case 0x00: working
.write(FPUSH
); break;
2081 case 0x08: working
.write(FCHOP
); break;
2086 if ((prefices
& PREFICES_OPERAND
) != 0)
2087 working
.write(FRSTOR_108
);
2089 working
.write(FRSTOR_94
);
2092 if ((prefices
& PREFICES_OPERAND
) != 0)
2093 working
.write(FSAVE_108
);
2095 working
.write(FSAVE_94
);
2101 switch (modrm
& 0xf8)
2103 case 0xc0: working
.write(FFREE
); break;
2107 case 0xe8: working
.write(FUCOM
); break;
2115 case 0xd9: working
.write(FCOM
); break;
2117 switch (modrm
& 0x38)
2119 case 0x00: working
.write(FADD
); break;
2120 case 0x08: working
.write(FMUL
); break;
2122 case 0x18: working
.write(FCOM
); break;
2124 case 0x28: working
.write(FSUB
); break;
2126 case 0x38: working
.write(FDIV
); break;
2132 if ((modrm
& 0xc0) != 0xc0)
2134 switch (modrm
& 0x38)
2136 case 0x00: working
.write(FPUSH
); break;
2137 case 0x08: working
.write(FCHOP
); break;
2140 case 0x38: working
.write(FRNDINT
); break;
2141 case 0x20: working
.write(FBCD2F
); break;
2142 case 0x28: working
.write(FPUSH
); break;
2143 case 0x30: working
.write(FF2BCD
); break;
2148 switch (modrm
& 0xf8)
2150 case 0xe8: working
.write(FUCOMI
); break;
2151 case 0xf0: working
.write(FCOMI
); break;
2159 private void writeFlags(int prefices
, int opcode
, int modrm
)
2162 case 0x00: //ADD Eb, Gb
2163 case 0x02: //ADD Gb, Eb
2164 case 0x04: //ADD AL, Ib
2165 case 0xfc0: //XADD Eb, Gb
2166 working
.write(ADD_O8_FLAGS
); break;
2168 case 0x10: //ADC Eb, Gb
2169 case 0x12: //ADC Gb, Eb
2170 case 0x14: //ADC AL, Ib
2171 working
.write(ADC_O8_FLAGS
); break;
2173 case 0x18: //SBB Eb, Gb
2174 case 0x1a: //SBB Gb, Eb
2175 case 0x1c: //SBB AL, Ib
2176 working
.write(SBB_O8_FLAGS
); break;
2178 case 0x28: //SUB Eb, Gb
2179 case 0x2a: //SUB Gb, Eb
2180 case 0x2c: //SUB AL, Ib
2181 case 0x38: //CMP Eb, Gb
2182 case 0x3a: //CMP Gb, Eb
2183 case 0x3c: //CMP AL, Ib
2184 working
.write(SUB_O8_FLAGS
); break;
2186 case 0x01: //ADD Ev, Gv
2187 case 0x03: //ADD Gv, Ev
2188 case 0x05: //ADD eAX, Iv
2189 case 0xfc1: //XADD Ev, Gv
2190 if ((prefices
& PREFICES_OPERAND
) != 0)
2191 working
.write(ADD_O32_FLAGS
);
2193 working
.write(ADD_O16_FLAGS
);
2196 case 0x11: //ADC Ev, Gv
2197 case 0x13: //ADC Gv, Ev
2198 case 0x15: //ADC eAX, Iv
2199 if ((prefices
& PREFICES_OPERAND
) != 0)
2200 working
.write(ADC_O32_FLAGS
);
2202 working
.write(ADC_O16_FLAGS
);
2205 case 0x19: //SBB Ev, Gv
2206 case 0x1b: //SBB Gv, Ev
2207 case 0x1d: //SBB eAX, Iv
2208 if ((prefices
& PREFICES_OPERAND
) != 0)
2209 working
.write(SBB_O32_FLAGS
);
2211 working
.write(SBB_O16_FLAGS
);
2214 case 0x29: //SUB Ev, Gv
2215 case 0x2b: //SUB Gv, Ev
2216 case 0x2d: //SUB eAX, Iv
2217 case 0x39: //CMP Ev, Gv
2218 case 0x3b: //CMP Gv, Ev
2219 case 0x3d: //CMP eAX, Iv
2220 if ((prefices
& PREFICES_OPERAND
) != 0)
2221 working
.write(SUB_O32_FLAGS
);
2223 working
.write(SUB_O16_FLAGS
);
2226 case 0x08: //OR Eb, Gb
2227 case 0x0a: //OR Gb, Eb
2228 case 0x0c: //OR AL, Ib
2229 case 0x20: //AND Eb, Gb
2230 case 0x22: //AND Gb, Eb
2231 case 0x24: //AND AL, Ib
2232 case 0x30: //XOR Eb, Gb
2233 case 0x32: //XOR Gb, Eb
2234 case 0x34: //XOR AL, Ib
2235 case 0x84: //TEST Eb, Gb
2236 case 0xa8: //TEST AL, Ib
2237 working
.write(BITWISE_FLAGS_O8
); break;
2239 case 0x09: //OR Ev, Gv
2240 case 0x0b: //OR Gv, Ev
2241 case 0x0d: //OR eAX, Iv
2242 case 0x21: //AND Ev, Gv
2243 case 0x23: //AND Gv, Ev
2244 case 0x25: //AND eAX, Iv
2245 case 0x31: //XOR Ev, Gv
2246 case 0x33: //XOR Gv, Ev
2247 case 0x35: //XOR eAX, Iv
2248 case 0x85: //TEST Ev, Gv
2249 case 0xa9: //TEST eAX, Iv
2250 if ((prefices
& PREFICES_OPERAND
) != 0)
2251 working
.write(BITWISE_FLAGS_O32
);
2253 working
.write(BITWISE_FLAGS_O16
);
2256 case 0x40: //INC eAX
2257 case 0x41: //INC eCX
2258 case 0x42: //INC eDX
2259 case 0x43: //INC eBX
2260 case 0x44: //INC eSP
2261 case 0x45: //INC eBP
2262 case 0x46: //INC eSI
2263 case 0x47: //INC eDI
2264 if ((prefices
& PREFICES_OPERAND
) != 0)
2265 working
.write(INC_O32_FLAGS
);
2267 working
.write(INC_O16_FLAGS
);
2270 case 0x48: //DEC eAX
2271 case 0x49: //DEC eCX
2272 case 0x4a: //DEC eDX
2273 case 0x4b: //DEC eBX
2274 case 0x4c: //DEC eSP
2275 case 0x4d: //DEC eBP
2276 case 0x4e: //DEC eSI
2277 case 0x4f: //DEC eDI
2278 if ((prefices
& PREFICES_OPERAND
) != 0)
2279 working
.write(DEC_O32_FLAGS
);
2281 working
.write(DEC_O16_FLAGS
);
2284 case 0x80: //IMM GP1 Eb, Ib
2285 case 0x82: //IMM GP1 Eb, Ib
2286 switch (modrm
& 0x38) {
2288 working
.write(ADD_O8_FLAGS
); break;
2290 working
.write(BITWISE_FLAGS_O8
); break;
2292 working
.write(ADC_O8_FLAGS
); break;
2294 working
.write(SBB_O8_FLAGS
); break;
2296 working
.write(BITWISE_FLAGS_O8
); break;
2299 working
.write(SUB_O8_FLAGS
); break;
2301 working
.write(BITWISE_FLAGS_O8
); break;
2305 case 0x81: //IMM GP1 Ev, Iv
2306 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
2307 if ((prefices
& PREFICES_OPERAND
) != 0) {
2308 switch (modrm
& 0x38) {
2310 working
.write(ADD_O32_FLAGS
); break;
2312 working
.write(BITWISE_FLAGS_O32
); break;
2314 working
.write(ADC_O32_FLAGS
); break;
2316 working
.write(SBB_O32_FLAGS
); break;
2318 working
.write(BITWISE_FLAGS_O32
); break;
2321 working
.write(SUB_O32_FLAGS
); break;
2323 working
.write(BITWISE_FLAGS_O32
); break;
2326 switch (modrm
& 0x38) {
2328 working
.write(ADD_O16_FLAGS
); break;
2330 working
.write(BITWISE_FLAGS_O16
); break;
2332 working
.write(ADC_O16_FLAGS
); break;
2334 working
.write(SBB_O16_FLAGS
); break;
2336 working
.write(BITWISE_FLAGS_O16
); break;
2339 working
.write(SUB_O16_FLAGS
); break;
2341 working
.write(BITWISE_FLAGS_O16
); break;
2349 switch (modrm
& 0x38) {
2351 working
.write(ROL_O8_FLAGS
); break;
2353 working
.write(ROR_O8_FLAGS
); break;
2355 working
.write(RCL_O8_FLAGS
); break;
2357 working
.write(RCR_O8_FLAGS
); break;
2359 working
.write(SHL_O8_FLAGS
); break;
2361 working
.write(SHR_O8_FLAGS
); break;
2363 System
.err
.println("Emulated: invalid SHL encoding");
2364 working
.write(SHL_O8_FLAGS
); break;
2366 working
.write(SAR_O8_FLAGS
); break;
2373 if ((prefices
& PREFICES_OPERAND
) != 0) {
2374 switch (modrm
& 0x38) {
2376 working
.write(ROL_O32_FLAGS
); break;
2378 working
.write(ROR_O32_FLAGS
); break;
2380 working
.write(RCL_O32_FLAGS
); break;
2382 working
.write(RCR_O32_FLAGS
); break;
2384 working
.write(SHL_O32_FLAGS
); break;
2386 working
.write(SHR_O32_FLAGS
); break;
2388 working
.write(SHL_O32_FLAGS
); break;
2390 working
.write(SAR_O32_FLAGS
); break;
2393 switch (modrm
& 0x38) {
2395 working
.write(ROL_O16_FLAGS
); break;
2397 working
.write(ROR_O16_FLAGS
); break;
2399 working
.write(RCL_O16_FLAGS
); break;
2401 working
.write(RCR_O16_FLAGS
); break;
2403 working
.write(SHL_O16_FLAGS
); break;
2405 working
.write(SHR_O16_FLAGS
); break;
2407 working
.write(SHL_O16_FLAGS
); break;
2409 working
.write(SAR_O16_FLAGS
); break;
2414 case 0xf6: //UNA GP3 Eb
2415 switch (modrm
& 0x38) {
2417 working
.write(BITWISE_FLAGS_O8
); break;
2419 working
.write(NEG_O8_FLAGS
); break;
2423 case 0xf7: //UNA GP3 Ev
2424 if ((prefices
& PREFICES_OPERAND
) != 0) {
2425 switch (modrm
& 0x38) {
2427 working
.write(BITWISE_FLAGS_O32
); break;
2429 working
.write(NEG_O32_FLAGS
); break;
2432 switch (modrm
& 0x38) {
2434 working
.write(BITWISE_FLAGS_O16
); break;
2436 working
.write(NEG_O16_FLAGS
); break;
2442 switch (modrm
& 0x38) {
2444 working
.write(INC_O8_FLAGS
); break;
2446 working
.write(DEC_O8_FLAGS
); break;
2451 switch (modrm
& 0x38) {
2453 if ((prefices
& PREFICES_OPERAND
) != 0)
2454 working
.write(INC_O32_FLAGS
);
2456 working
.write(INC_O16_FLAGS
);
2459 if ((prefices
& PREFICES_OPERAND
) != 0)
2460 working
.write(DEC_O32_FLAGS
);
2462 working
.write(DEC_O16_FLAGS
);
2470 case 0x58: //POP eAX
2471 case 0x59: //POP eCX
2472 case 0x5a: //POP eDX
2473 case 0x5b: //POP eBX
2474 case 0x5d: //POP eBP
2475 case 0x5e: //POP eSI
2476 case 0x5f: //POP eDI
2477 case 0xfa1: //POP FS
2478 case 0xfa9: working
.write(STORE1_ESP
); break; //POP GS
2481 case 0x8f: //POP Ev This is really annoying and not quite correct?
2482 for (int i
= 0; i
< working
.getLength(); i
++) {
2483 switch (working
.getMicrocodeAt(i
)) {
2486 working
.replace(i
, ADDR_REG1
);
2489 working
.replace(i
, ADDR_2REG1
);
2492 working
.replace(i
, ADDR_4REG1
);
2495 working
.replace(i
, ADDR_8REG1
);
2504 switch (working
.getMicrocodeAt(working
.getLength() - 1)) {
2506 case STORE0_SP
: break;
2507 default: working
.write(STORE1_ESP
);
2512 switch (prefices
& PREFICES_OPERAND
) {
2514 working
.write(STORE0_FLAGS
); break;
2515 case PREFICES_OPERAND
:
2516 working
.write(STORE0_EFLAGS
); break;
2520 case 0xf1f: break; //NOP
2521 case 0xfa4: //SHLD Ev, Gv, Ib
2522 case 0xfa5: //SHLD Ev, Gv, CL
2523 if ((prefices
& PREFICES_OPERAND
) != 0)
2524 working
.write(SHL_O32_FLAGS
);
2526 working
.write(SHL_O16_FLAGS
);
2529 case 0xfac: //SHRD Ev, Gv, Ib
2530 case 0xfad: //SHRD Ev, Gv, CL
2531 if ((prefices
& PREFICES_OPERAND
) != 0)
2532 working
.write(SHR_O32_FLAGS
);
2534 working
.write(SHR_O16_FLAGS
);
2537 case 0xfb0: //CMPXCHG Eb, Gb
2538 working
.write(CMPXCHG_O8_FLAGS
); break;
2539 case 0xfb1: //CMPXCHG Ev, Gv
2540 if ((prefices
& PREFICES_OPERAND
) != 0)
2541 working
.write(CMPXCHG_O32_FLAGS
);
2543 working
.write(CMPXCHG_O16_FLAGS
);
2546 case 0x06: //PUSH ES
2547 case 0x0e: //PUSH CS
2549 case 0x16: //PUSH SS
2550 case 0x1e: //PUSH DS
2558 case 0x50: //PUSH eAX
2559 case 0x51: //PUSH eCX
2560 case 0x52: //PUSH eDX
2561 case 0x53: //PUSH eBX
2562 case 0x54: //PUSH eSP
2563 case 0x55: //PUSH eBP
2564 case 0x56: //PUSH eSI
2565 case 0x57: //PUSH eDI
2566 case 0x5c: //POP eSP so don't write incremented stack pointer back
2568 case 0x60: //PUSHA/D
2571 case 0x63: //#UD (ARPL)
2572 case 0x68: //PUSH Iv
2573 case 0x69: //IMUL Gv, Ev, Iv
2574 case 0x6a: //PUSH Ib
2575 case 0x6b: //IMUL Gv, Ev, Ib
2579 case 0x6f: //OUTSW/D
2598 case 0x86: //XCHG Eb, Gb
2599 case 0x87: //XCHG Ev, Gv
2600 case 0x88: //MOV Eb, Gb
2601 case 0x89: //MOV Ev, Gv
2602 case 0x8a: //MOV Gb, Eb
2603 case 0x8b: //MOV Gv, Ev
2604 case 0x8c: //MOV Ew, Sw
2605 case 0x8d: //LEA Gv, M
2606 case 0x8e: //MOV Sw, Ew
2609 case 0x91: //XCHG eAX, eCX
2610 case 0x92: //XCHG eAX, eCX
2611 case 0x93: //XCHG eAX, eCX
2612 case 0x94: //XCHG eAX, eCX
2613 case 0x95: //XCHG eAX, eCX
2614 case 0x96: //XCHG eAX, eCX
2615 case 0x97: //XCHG eAX, eCX
2616 case 0x98: //CBW/CWDE
2617 case 0x99: //CWD/CDQ
2618 case 0x9a: //CALLF Ap
2625 case 0xa0: //MOV AL, Ob
2626 case 0xa1: //MOV eAX, Ov
2627 case 0xa2: //MOV Ob, AL
2628 case 0xa3: //MOV Ov, eAX
2630 case 0xa5: //MOVSW/D
2632 case 0xa7: //CMPSW/D
2634 case 0xab: //STOSW/D
2636 case 0xad: //LODSW/D
2638 case 0xaf: //SCASW/D
2640 case 0xb0: //MOV AL, Ib
2641 case 0xb1: //MOV CL, Ib
2642 case 0xb2: //MOV DL, Ib
2643 case 0xb3: //MOV BL, Ib
2644 case 0xb4: //MOV AH, Ib
2645 case 0xb5: //MOV CH, Ib
2646 case 0xb6: //MOV DH, Ib
2647 case 0xb7: //MOV BH, Ib
2648 case 0xb8: //MOV eAX, Iv
2649 case 0xb9: //MOV eCX, Iv
2650 case 0xba: //MOV eDX, Iv
2651 case 0xbb: //MOV eBX, Iv
2652 case 0xbc: //MOV eSP, Iv
2653 case 0xbd: //MOV eBP, Iv
2654 case 0xbe: //MOV eSI, Iv
2655 case 0xbf: //MOV eDI, Iv
2661 case 0xc6: //MOV GP11 Eb, Gb
2662 case 0xc7: //MOV GP11 Ev, Gv
2665 case 0xca: //RETF Iw
2680 case 0xe4: //IN AL, Ib
2681 case 0xe5: //IN eAX, Ib
2682 case 0xe6: //OUT Ib, AL
2683 case 0xe7: //OUT Ib, eAX
2684 case 0xe8: //CALL Jv
2686 case 0xea: //JMPF Ap
2688 case 0xec: //IN AL, DX
2689 case 0xed: //IN eAX, DX
2690 case 0xee: //OUT DX, AL
2691 case 0xef: //OUT DX, eAX
2702 case 0xf00: //Group 6
2703 case 0xf01: //Group 7
2704 case 0xf02: //LAR Gv, Ew
2705 case 0xf03: //LSL Gv, Ew
2707 case 0xf09: //WBINVD
2709 case 0xf20: //MOV Rd, Cd
2710 case 0xf21: //MOV Rd, Dd
2711 case 0xf22: //MOV Cd, Rd
2712 case 0xf23: //MOV Dd, Rd
2716 case 0xf34: //SYSENTER
2717 case 0xf35: //SYSEXIT
2719 case 0xf41: //CMOVNO
2721 case 0xf43: //CMOVNC
2723 case 0xf45: //CMOVNZ
2724 case 0xf46: //CMOVBE
2725 case 0xf47: //CMOVNBE
2727 case 0xf49: //CMOVNS
2729 case 0xf4b: //CMOVNP
2731 case 0xf4d: //CMOVNL
2732 case 0xf4e: //CMOVLE
2733 case 0xf4f: //CMOVNLE
2735 case 0xf81: //JNO Jv
2737 case 0xf83: //JNC Jv
2739 case 0xf85: //JNZ Jv
2740 case 0xf86: //JNA Jv
2743 case 0xf89: //JNS Jv
2745 case 0xf8b: //JNP Jv
2747 case 0xf8d: //JNL Jv
2748 case 0xf8e: //JNG Jv
2766 case 0xfa0: //PUSH FS
2768 case 0xfa8: //PUSH GS
2769 case 0xfaf: //IMUL Gv, Ev
2770 case 0xfa3: //BT Ev, Gv
2771 case 0xfab: //BTS Ev, Gv
2772 case 0xfb3: //BTR Ev, Gv
2773 case 0xfbb: //BTC Ev, Gv
2774 case 0xfb2: //LSS Mp
2775 case 0xfb4: //LFS Mp
2776 case 0xfb5: //LGS Mp
2777 case 0xfb6: //MOVZX Gv, Eb
2778 case 0xfb7: //MOVZX Gv, Ew
2779 case 0xfba: //Grp 8 Ev, Ib
2780 case 0xfbc: //BSF Gv, Ev
2781 case 0xfbd: //BSR Gv, Ev
2782 case 0xfbe: //MOVSX Gv, Eb
2783 case 0xfbf: //MOVSX Gv, Ew
2785 case 0xfc8: //BSWAP EAX
2786 case 0xfc9: //BSWAP ECX
2787 case 0xfca: //BSWAP EDX
2788 case 0xfcb: //BSWAP EBX
2789 case 0xfcc: //BSWAP ESP
2790 case 0xfcd: //BSWAP EBP
2791 case 0xfce: //BSWAP ESI
2792 case 0xfcf: //BSWAP EDI
2793 case 0xd800: // FPU OPS
2794 case 0xd900: // FPU OPS
2795 case 0xda00: // FPU OPS
2796 case 0xdb00: // FPU OPS
2797 case 0xdc00: // FPU OPS
2798 case 0xdd00: // FPU OPS
2799 case 0xde00: // FPU OPS
2800 case 0xdf00: // FPU OPS
2801 case 0x0fff: // Undefined instruction used by win 95
2805 throw new IllegalStateException("Missing Flags: 0x" + Integer
.toHexString(opcode
));
2809 private void writeInputOperands(int prefices
, int opcode
, int modrm
, int sib
, int displacement
, long immediate
)
2812 case 0x00: //ADD Eb, Gb
2813 case 0x08: //OR Eb, Gb
2814 case 0x10: //ADC Eb, Gb
2815 case 0x18: //SBB Eb, Gb
2816 case 0x20: //AND Eb, Gb
2817 case 0x28: //SUB Eb, Gb
2818 case 0x30: //XOR Eb, Gb
2819 case 0x38: //CMP Eb, Gb
2820 case 0x84: //TEST Eb, Gb
2821 case 0x86: //XCHG Eb, Gb
2822 load0_Eb(prefices
, modrm
, sib
, displacement
);
2826 case 0x88: //MOV Eb, Gb
2830 case 0x02: //ADD Gb, Eb
2831 case 0x0a: //OR Gb, Eb
2832 case 0x12: //ADC Gb, Eb
2833 case 0x1a: //SBB Gb, Eb
2834 case 0x22: //AND Gb, Eb
2835 case 0x2a: //SUB Gb, Eb
2836 case 0x32: //XOR Gb, Eb
2837 case 0x3a: //CMP Gb, Eb
2838 case 0xfc0: //XADD Eb, Gb
2840 load1_Eb(prefices
, modrm
, sib
, displacement
);
2843 case 0x8a: //MOV Gb, Eb
2844 case 0xfb6: //MOVZX Gv, Eb
2845 case 0xfbe: //MOVSX Gv, Eb
2846 load0_Eb(prefices
, modrm
, sib
, displacement
);
2849 case 0x01: //ADD Ev, Gv
2850 case 0x09: //OR Ev, Gv
2851 case 0x11: //ADC Ev, Gv
2852 case 0x19: //SBB Ev, Gv
2853 case 0x21: //AND Ev, Gv
2854 case 0x29: //SUB Ev, Gv
2855 case 0x31: //XOR Ev, Gv
2856 case 0x39: //CMP Ev, Gv
2857 case 0x85: //TEST Ev, Gv
2858 case 0x87: //XCHG Ev, Gv
2859 if ((prefices
& PREFICES_OPERAND
) != 0) {
2860 load0_Ed(prefices
, modrm
, sib
, displacement
);
2863 load0_Ew(prefices
, modrm
, sib
, displacement
);
2868 case 0x89: //MOV Ev, Gv
2869 if ((prefices
& PREFICES_OPERAND
) != 0) {
2876 case 0x03: //ADD Gv, Ev
2877 case 0x0b: //OR Gv, Ev
2878 case 0x13: //ADC Gv, Ev
2879 case 0x1b: //SBB Gv, Ev
2880 case 0x23: //AND Gv, Ev
2881 case 0x2b: //SUB Gv, Ev
2882 case 0x33: //XOR Gv, Ev
2883 case 0x3b: //CMP Gv, Ev
2884 case 0xfaf: //IMUL Gv, Ev
2885 case 0xfbc: //BSF Gv, Ev
2886 case 0xfbd: //BSR Gv, Ev
2887 case 0xfc1: //XADD Ev, Gv
2888 if ((prefices
& PREFICES_OPERAND
) != 0) {
2890 load1_Ed(prefices
, modrm
, sib
, displacement
);
2893 load1_Ew(prefices
, modrm
, sib
, displacement
);
2897 case 0x8b: //MOV Gv, Ev
2898 if ((prefices
& PREFICES_OPERAND
) != 0) {
2899 load0_Ed(prefices
, modrm
, sib
, displacement
);
2901 load0_Ew(prefices
, modrm
, sib
, displacement
);
2905 case 0xf02: //LAR Gv, Ew
2906 case 0xf03: //LSL Gv, Ew
2907 if ((prefices
& PREFICES_OPERAND
) != 0) {
2908 load0_Ew(prefices
, modrm
, sib
, displacement
);
2911 load0_Ew(prefices
, modrm
, sib
, displacement
);
2917 case 0xf41: //CMOVNO
2919 case 0xf43: //CMOVNC
2921 case 0xf45: //CMOVNZ
2922 case 0xf46: //CMOVBE
2923 case 0xf47: //CMOVNBE
2925 case 0xf49: //CMOVNS
2927 case 0xf4b: //CMOVNP
2929 case 0xf4d: //CMOVNL
2930 case 0xf4e: //CMOVLE
2931 case 0xf4f: //CMOVNLE
2932 if ((prefices
& PREFICES_OPERAND
) != 0) {
2934 load1_Ed(prefices
, modrm
, sib
, displacement
);
2937 load1_Ew(prefices
, modrm
, sib
, displacement
);
2941 case 0x8d: //LEA Gv, M
2942 load0_M(prefices
, modrm
, sib
, displacement
);
2946 case 0x80: //IMM G1 Eb, Ib
2947 case 0x82: //IMM G1 Eb, Ib
2948 case 0xc0: //SFT G2 Eb, Ib
2949 load0_Eb(prefices
, modrm
, sib
, displacement
);
2950 working
.write(LOAD1_IB
);
2951 working
.write((int)immediate
);
2954 case 0xc6: //MOV G11 Eb, Ib
2955 case 0xb0: //MOV AL, Ib
2956 case 0xb1: //MOV CL, Ib
2957 case 0xb2: //MOV DL, Ib
2958 case 0xb3: //MOV BL, Ib
2959 case 0xb4: //MOV AH, Ib
2960 case 0xb5: //MOV CH, Ib
2961 case 0xb6: //MOV DH, Ib
2962 case 0xb7: //MOV BH, Ib
2963 case 0xe4: //IN AL, Ib
2983 case 0xe0: //LOOPNZ Jb
2984 case 0xe1: //LOOPZ Jb
2985 case 0xe2: //LOOP Jb
2986 case 0xe3: //JCXZ Jb
2988 case 0xe5: //IN eAX, Ib
2989 working
.write(LOAD0_IB
);
2990 working
.write((int)immediate
);
2993 case 0x81: //IMM G1 Ev, Iv
2994 if ((prefices
& PREFICES_OPERAND
) != 0) {
2995 load0_Ed(prefices
, modrm
, sib
, displacement
);
2996 working
.write(LOAD1_ID
);
2997 working
.write((int)immediate
);
2999 load0_Ew(prefices
, modrm
, sib
, displacement
);
3000 working
.write(LOAD1_IW
);
3001 working
.write((int)immediate
);
3005 case 0xc7: //MOV G11 Ev, Iv
3006 case 0x68: //PUSH Iv
3007 case 0x6a: //PUSH Ib
3008 case 0xe8: //CALL Jv
3011 case 0xf81: //JNO Jv
3013 case 0xf83: //JNC Jv
3015 case 0xf85: //JNZ Jv
3016 case 0xf86: //JNA Jv
3019 case 0xf89: //JNS Jv
3021 case 0xf8b: //JNP Jv
3023 case 0xf8d: //JNL Jv
3024 case 0xf8e: //JNG Jv
3026 if ((prefices
& PREFICES_OPERAND
) != 0) {
3027 working
.write(LOAD0_ID
);
3028 working
.write((int)immediate
);
3030 working
.write(LOAD0_IW
);
3031 working
.write((int)immediate
);
3035 case 0xc1: //SFT G2 Ev, Ib
3036 if ((prefices
& PREFICES_OPERAND
) != 0) {
3037 load0_Ed(prefices
, modrm
, sib
, displacement
);
3038 working
.write(LOAD1_IB
);
3039 working
.write((int)immediate
);
3041 load0_Ew(prefices
, modrm
, sib
, displacement
);
3042 working
.write(LOAD1_IB
);
3043 working
.write((int)immediate
);
3047 case 0x83: //IMM G1 Ev, Ib sign extend the byte to 16/32 bits
3048 if ((prefices
& PREFICES_OPERAND
) != 0) {
3049 load0_Ed(prefices
, modrm
, sib
, displacement
);
3050 working
.write(LOAD1_ID
);
3051 working
.write((int)immediate
);
3053 load0_Ew(prefices
, modrm
, sib
, displacement
);
3054 working
.write(LOAD1_IW
);
3055 working
.write((int)immediate
);
3060 case 0x58: //POP eAX
3061 case 0x59: //POP eCX
3062 case 0x5a: //POP eDX
3063 case 0x5b: //POP eBX
3064 case 0x5c: //POP eSP
3065 case 0x5d: //POP eBP
3066 case 0x5e: //POP eSI
3067 case 0x5f: //POP eDI
3074 case 0xca: //RETF Iw
3075 working
.write(LOAD0_IW
);
3076 working
.write((int)immediate
);
3079 case 0x9a: //CALLF Ap
3080 case 0xea: //JMPF Ap
3081 if ((prefices
& PREFICES_OPERAND
) != 0) {
3082 working
.write(LOAD0_ID
);
3083 working
.write((int)immediate
);
3084 working
.write(LOAD1_IW
);
3085 working
.write((int)(immediate
>>> 32));
3087 working
.write(LOAD0_IW
);
3088 working
.write((int)(0xffff & immediate
));
3089 working
.write(LOAD1_IW
);
3090 working
.write((int)(immediate
>>> 16));
3095 switch (prefices
& PREFICES_OPERAND
) {
3097 working
.write(LOAD0_FLAGS
); break;
3098 case PREFICES_OPERAND
:
3099 working
.write(LOAD0_EFLAGS
); break;
3103 case 0xec: //IN AL, DX
3104 case 0xed: //IN eAX, DX
3105 working
.write(LOAD0_DX
);
3108 case 0xee: //OUT DX, AL
3109 working
.write(LOAD0_DX
);
3110 working
.write(LOAD1_AL
);
3113 case 0xef: //OUT DX, eAX
3114 if ((prefices
& PREFICES_OPERAND
) != 0) {
3115 working
.write(LOAD0_DX
);
3116 working
.write(LOAD1_EAX
);
3118 working
.write(LOAD0_DX
);
3119 working
.write(LOAD1_AX
);
3123 case 0x04: //ADD AL, Ib
3124 case 0x0c: //OR AL, Ib
3125 case 0x14: //ADC AL, Ib
3126 case 0x1c: //SBB AL, Ib
3127 case 0x24: //AND AL, Ib
3128 case 0x2c: //SUB AL, Ib
3129 case 0x34: //XOR AL, Ib
3130 case 0x3c: //CMP AL, Ib
3131 case 0xa8: //TEST AL, Ib
3132 working
.write(LOAD0_AL
);
3133 working
.write(LOAD1_IB
);
3134 working
.write((int)immediate
);
3137 case 0xc8: //ENTER Iw, Ib
3138 working
.write(LOAD0_IW
);
3139 working
.write((int)(0xffffl
& (immediate
>>> 16)));
3140 working
.write(LOAD1_IB
);
3141 working
.write((int)(0xffl
& immediate
));
3144 case 0x69: //IMUL Gv, Ev, Iv
3145 case 0x6b: //IMUL Gv, Ev, Ib
3146 if ((prefices
& PREFICES_OPERAND
) != 0) {
3147 load0_Ed(prefices
, modrm
, sib
, displacement
);
3148 working
.write(LOAD1_ID
);
3149 working
.write((int)immediate
);
3151 load0_Ew(prefices
, modrm
, sib
, displacement
);
3152 working
.write(LOAD1_IW
);
3153 working
.write((int)immediate
);
3157 case 0xe6: //OUT Ib, AL
3158 working
.write(LOAD0_IB
);
3159 working
.write((int)immediate
);
3160 working
.write(LOAD1_AL
);
3163 case 0x05: //ADD eAX, Iv
3164 case 0x0d: //OR eAX, Iv
3165 case 0x15: //ADC eAX, Iv
3166 case 0x1d: //SBB eAX, Iv
3167 case 0x25: //AND eAX, Iv
3168 case 0x2d: //SUB eAX, Iv
3169 case 0x35: //XOR eAX, Iv
3170 case 0x3d: //CMP eAX, Iv
3171 case 0xa9: //TEST eAX, Iv
3172 if ((prefices
& PREFICES_OPERAND
) != 0) {
3173 working
.write(LOAD0_EAX
);
3174 working
.write(LOAD1_ID
);
3175 working
.write((int)immediate
);
3177 working
.write(LOAD0_AX
);
3178 working
.write(LOAD1_IW
);
3179 working
.write((int)immediate
);
3183 case 0xb8: //MOV eAX, Iv
3184 case 0xb9: //MOV eCX, Iv
3185 case 0xba: //MOV eDX, Iv
3186 case 0xbb: //MOV eBX, Iv
3187 case 0xbc: //MOV eSP, Iv
3188 case 0xbd: //MOV eBP, Iv
3189 case 0xbe: //MOV eSI, Iv
3190 case 0xbf: //MOV eDI, Iv
3191 if ((prefices
& PREFICES_OPERAND
) != 0) {
3192 working
.write(LOAD0_ID
);
3193 working
.write((int)immediate
);
3195 working
.write(LOAD0_IW
);
3196 working
.write((int)immediate
);
3200 case 0xe7: //OUT Ib, eAX
3201 if ((prefices
& PREFICES_OPERAND
) != 0) {
3202 working
.write(LOAD0_IB
);
3203 working
.write((int)immediate
);
3204 working
.write(LOAD1_EAX
);
3206 working
.write(LOAD0_IB
);
3207 working
.write((int)immediate
);
3208 working
.write(LOAD1_AX
);
3212 case 0x40: //INC eAX
3213 case 0x48: //DEC eAX
3214 case 0x50: //PUSH eAX
3215 if ((prefices
& PREFICES_OPERAND
) != 0) {
3216 working
.write(LOAD0_EAX
);
3218 working
.write(LOAD0_AX
);
3222 case 0x41: //INC eCX
3223 case 0x49: //DEC eCX
3224 case 0x51: //PUSH eCX
3225 if ((prefices
& PREFICES_OPERAND
) != 0) {
3226 working
.write(LOAD0_ECX
);
3228 working
.write(LOAD0_CX
);
3232 case 0x42: //INC eDX
3233 case 0x4a: //DEC eDX
3234 case 0x52: //PUSH eDX
3235 if ((prefices
& PREFICES_OPERAND
) != 0) {
3236 working
.write(LOAD0_EDX
);
3238 working
.write(LOAD0_DX
);
3242 case 0x43: //INC eBX
3243 case 0x4b: //DEC eBX
3244 case 0x53: //PUSH eBX
3245 if ((prefices
& PREFICES_OPERAND
) != 0) {
3246 working
.write(LOAD0_EBX
);
3248 working
.write(LOAD0_BX
);
3252 case 0x44: //INC eSP
3253 case 0x4c: //DEC eSP
3254 case 0x54: //PUSH eSP
3255 if ((prefices
& PREFICES_OPERAND
) != 0) {
3256 working
.write(LOAD0_ESP
);
3258 working
.write(LOAD0_SP
);
3262 case 0x45: //INC eBP
3263 case 0x4d: //DEC eBP
3264 case 0x55: //PUSH eBP
3265 if ((prefices
& PREFICES_OPERAND
) != 0) {
3266 working
.write(LOAD0_EBP
);
3268 working
.write(LOAD0_BP
);
3272 case 0x46: //INC eSI
3273 case 0x4e: //DEC eSI
3274 case 0x56: //PUSH eSI
3275 if ((prefices
& PREFICES_OPERAND
) != 0) {
3276 working
.write(LOAD0_ESI
);
3278 working
.write(LOAD0_SI
);
3282 case 0x47: //INC eDI
3283 case 0x4f: //DEC eDI
3284 case 0x57: //PUSH eDI
3285 if ((prefices
& PREFICES_OPERAND
) != 0) {
3286 working
.write(LOAD0_EDI
);
3288 working
.write(LOAD0_DI
);
3292 case 0x91: //XCHG eAX, eCX
3293 if ((prefices
& PREFICES_OPERAND
) != 0) {
3294 working
.write(LOAD0_EAX
);
3295 working
.write(LOAD1_ECX
);
3297 working
.write(LOAD0_AX
);
3298 working
.write(LOAD1_CX
);
3302 case 0x92: //XCHG eAX, eDX
3303 if ((prefices
& PREFICES_OPERAND
) != 0) {
3304 working
.write(LOAD0_EAX
);
3305 working
.write(LOAD1_EDX
);
3307 working
.write(LOAD0_AX
);
3308 working
.write(LOAD1_DX
);
3312 case 0x93: //XCHG eAX, eBX
3313 if ((prefices
& PREFICES_OPERAND
) != 0) {
3314 working
.write(LOAD0_EAX
);
3315 working
.write(LOAD1_EBX
);
3317 working
.write(LOAD0_AX
);
3318 working
.write(LOAD1_BX
);
3322 case 0x94: //XCHG eAX, eSP
3323 if ((prefices
& PREFICES_OPERAND
) != 0) {
3324 working
.write(LOAD0_EAX
);
3325 working
.write(LOAD1_ESP
);
3327 working
.write(LOAD0_AX
);
3328 working
.write(LOAD1_SP
);
3332 case 0x95: //XCHG eAX, eBP
3333 if ((prefices
& PREFICES_OPERAND
) != 0) {
3334 working
.write(LOAD0_EAX
);
3335 working
.write(LOAD1_EBP
);
3337 working
.write(LOAD0_AX
);
3338 working
.write(LOAD1_BP
);
3342 case 0x96: //XCHG eAX, eSI
3343 if ((prefices
& PREFICES_OPERAND
) != 0) {
3344 working
.write(LOAD0_EAX
);
3345 working
.write(LOAD1_ESI
);
3347 working
.write(LOAD0_AX
);
3348 working
.write(LOAD1_SI
);
3352 case 0x97: //XCHG eAX, eDI
3353 if ((prefices
& PREFICES_OPERAND
) != 0) {
3354 working
.write(LOAD0_EAX
);
3355 working
.write(LOAD1_EDI
);
3357 working
.write(LOAD0_AX
);
3358 working
.write(LOAD1_DI
);
3362 case 0xd0: //SFT G2 Eb, 1
3363 load0_Eb(prefices
, modrm
, sib
, displacement
);
3364 working
.write(LOAD1_IB
);
3368 case 0xd2: //SFT G2 Eb, CL
3369 load0_Eb(prefices
, modrm
, sib
, displacement
);
3370 working
.write(LOAD1_CL
);
3373 case 0xd1: //SFT G2 Ev, 1
3374 if ((prefices
& PREFICES_OPERAND
) != 0) {
3375 load0_Ed(prefices
, modrm
, sib
, displacement
);
3376 working
.write(LOAD1_IB
);
3379 load0_Ew(prefices
, modrm
, sib
, displacement
);
3380 working
.write(LOAD1_IB
);
3385 case 0xd3: //SFT G2 Ev, CL
3386 if ((prefices
& PREFICES_OPERAND
) != 0) {
3387 load0_Ed(prefices
, modrm
, sib
, displacement
);
3388 working
.write(LOAD1_CL
);
3390 load0_Ew(prefices
, modrm
, sib
, displacement
);
3391 working
.write(LOAD1_CL
);
3395 case 0xf6: //UNA G3 Eb, ?
3396 switch (modrm
& 0x38) {
3397 case 0x00: //TEST Eb, Ib
3398 load0_Eb(prefices
, modrm
, sib
, displacement
);
3399 working
.write(LOAD1_IB
);
3400 working
.write((int)immediate
);
3404 load0_Eb(prefices
, modrm
, sib
, displacement
);
3408 load0_Eb(prefices
, modrm
, sib
, displacement
);
3412 load0_Eb(prefices
, modrm
, sib
, displacement
);
3417 case 0xf7: //UNA G3 Ev, ?
3418 if ((prefices
& PREFICES_OPERAND
) != 0) {
3419 switch (modrm
& 0x38) {
3420 case 0x00: //TEST Ed, Id
3421 load0_Ed(prefices
, modrm
, sib
, displacement
);
3422 working
.write(LOAD1_ID
);
3423 working
.write((int)immediate
);
3427 load0_Ed(prefices
, modrm
, sib
, displacement
);
3431 load0_Ed(prefices
, modrm
, sib
, displacement
);
3435 load0_Ed(prefices
, modrm
, sib
, displacement
);
3438 switch (modrm
& 0x38) {
3439 case 0x00: //TEST Ew, Iw
3440 load0_Ew(prefices
, modrm
, sib
, displacement
);
3441 working
.write(LOAD1_IW
);
3442 working
.write((int)immediate
);
3446 load0_Ew(prefices
, modrm
, sib
, displacement
);
3450 load0_Ew(prefices
, modrm
, sib
, displacement
);
3454 load0_Ew(prefices
, modrm
, sib
, displacement
);
3459 case 0xfe: //INC/DEC G4 Eb
3460 load0_Eb(prefices
, modrm
, sib
, displacement
);
3463 case 0x06: //PUSH ES
3464 working
.write(LOAD0_ES
);
3467 case 0x0e: //PUSH CS
3468 working
.write(LOAD0_CS
);
3471 case 0x16: //PUSH SS
3472 working
.write(LOAD0_SS
);
3475 case 0x1e: //PUSH DS
3476 working
.write(LOAD0_DS
);
3479 case 0x62: //BOUND Gv, Ma
3480 if ((prefices
& PREFICES_OPERAND
) != 0) {
3481 load0_Eq(prefices
, modrm
, sib
, displacement
);
3484 load0_Ed(prefices
, modrm
, sib
, displacement
);
3489 case 0x8c: //MOV Ew, Sw
3493 case 0x8e: //MOV Sw, Ew
3494 case 0xfb7: //MOV Gv, Ew
3495 case 0xfbf: //MOVSX Gv, Ew
3496 load0_Ew(prefices
, modrm
, sib
, displacement
);
3499 case 0xa0: //MOV AL, Ob
3500 load0_Ob(prefices
, displacement
);
3503 case 0xa2: //MOV Ob, AL
3504 working
.write(LOAD0_AL
);
3507 case 0xa1: //MOV eAX, Ov
3508 if ((prefices
& PREFICES_OPERAND
) != 0) {
3509 load0_Od(prefices
, displacement
);
3511 load0_Ow(prefices
, displacement
);
3515 case 0xa3: //MOV Ov, eAX
3516 if ((prefices
& PREFICES_OPERAND
) != 0) {
3517 working
.write(LOAD0_EAX
);
3519 working
.write(LOAD0_AX
);
3523 case 0x6c: //INS Yb, DX (prefices do not override segment)
3524 case 0x6d: //INS Yv, DX (prefices do not override segment)
3525 working
.write(LOAD0_DX
);
3528 case 0x6e: //OUTS DX, Xb
3529 case 0x6f: //OUTS DX, Xv
3530 working
.write(LOAD0_DX
);
3531 decodeSegmentPrefix(prefices
);
3534 case 0xa4: //MOVS Yb, Xb
3535 case 0xa5: //MOVS Yv, Xv
3536 case 0xa6: //CMPS Yb, Xb
3537 case 0xa7: //CMPS Xv, Yv
3538 case 0xac: //LODS AL, Xb
3539 case 0xad: //LODS eAX, Xv
3540 decodeSegmentPrefix(prefices
);
3543 case 0xaa: //STOS Yb, AL (prefices do not override segment)
3544 working
.write(LOAD0_AL
);
3547 case 0xab: //STOS Yv, eAX
3548 if ((prefices
& PREFICES_OPERAND
) != 0)
3549 working
.write(LOAD0_EAX
);
3551 working
.write(LOAD0_AX
);
3555 case 0xae: //SCAS AL, Yb (prefices do not override segment)
3556 working
.write(LOAD0_AL
);
3559 case 0xaf: //SCAS eAX, Yv
3560 if ((prefices
& PREFICES_OPERAND
) != 0)
3561 working
.write(LOAD0_EAX
);
3563 working
.write(LOAD0_AX
);
3566 case 0xff: //INC/DEC G5
3567 if ((prefices
& PREFICES_OPERAND
) != 0) {
3568 switch (modrm
& 0x38) {
3571 case 0x10: //CALLN Ed
3572 case 0x20: //JMPN Ed
3573 case 0x30: //PUSH Ed
3574 load0_Ed(prefices
, modrm
, sib
, displacement
);
3576 case 0x18: //CALLF Ep
3577 case 0x28: //JMPF Ep
3578 load0_Ed(prefices
, modrm
, sib
, displacement
);
3579 working
.write(ADDR_IB
);
3581 working
.write(LOAD1_MEM_WORD
);
3584 switch (modrm
& 0x38) {
3590 load0_Ew(prefices
, modrm
, sib
, displacement
);
3594 load0_Ew(prefices
, modrm
, sib
, displacement
);
3595 working
.write(ADDR_IB
);
3597 working
.write(LOAD1_MEM_WORD
);
3602 case 0xc4: //LES Gv, Mp
3603 case 0xc5: //LDS Gv, Mp
3604 case 0xfb2: //LSS Mp
3605 case 0xfb4: //LFS Mp
3606 case 0xfb5: //LGS Mp
3607 if ((prefices
& PREFICES_OPERAND
) != 0) {
3608 load0_Ed(prefices
, modrm
, sib
, displacement
);
3609 working
.write(ADDR_IB
);
3611 working
.write(LOAD1_MEM_WORD
);
3613 load0_Ew(prefices
, modrm
, sib
, displacement
);
3614 working
.write(ADDR_IB
);
3616 working
.write(LOAD1_MEM_WORD
);
3621 switch (prefices
& PREFICES_SG
) {
3622 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
3623 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
3624 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
3626 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
3627 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
3628 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
3631 if ((prefices
& PREFICES_ADDRESS
) != 0) {
3632 if (decodingAddressMode()) {
3633 working
.write(ADDR_EBX
);
3634 working
.write(ADDR_uAL
);
3637 if (decodingAddressMode()) {
3638 working
.write(ADDR_BX
);
3639 working
.write(ADDR_uAL
);
3640 working
.write(ADDR_MASK16
);
3643 working
.write(LOAD0_MEM_BYTE
);
3646 case 0xf00: // Group 6
3647 switch (modrm
& 0x38) {
3652 load0_Ew(prefices
, modrm
, sib
, displacement
); break;
3656 switch (modrm
& 0x38) {
3659 load0_Ew(prefices
, modrm
, sib
, displacement
);
3660 working
.write(ADDR_ID
);
3662 working
.write(LOAD1_MEM_DWORD
);
3664 case 0x30: load0_Ew(prefices
, modrm
, sib
, displacement
); break;
3665 case 0x38: decodeM(prefices
, modrm
, sib
, displacement
); break;
3668 case 0xfa0: //PUSH FS
3669 working
.write(LOAD0_FS
); break;
3670 case 0xfa8: //PUSH GS
3671 working
.write(LOAD0_GS
); break;
3673 case 0xf20: load0_Cd(modrm
); break; //MOV Rd, Cd
3675 case 0xf21: load0_Dd(modrm
); break; //MOV Rd, Dd
3677 case 0xf22: //MOV Cd, Rd
3678 case 0xf23: load0_Rd(modrm
); break; //MOV Dd, Rd
3681 working
.write(LOAD0_ECX
);
3682 working
.write(LOAD1_EDX
);
3683 working
.write(LOAD2_EAX
);
3687 working
.write(LOAD0_ECX
);
3690 case 0xf35: //SYSEXIT
3691 working
.write(LOAD0_ECX
);
3692 working
.write(LOAD1_EDX
);
3695 case 0xfa4: //SHLD Ev, Gv, Ib
3696 case 0xfac: //SHRD Ev, Gv, Ib
3697 if ((prefices
& PREFICES_OPERAND
) != 0) {
3698 load0_Ed(prefices
, modrm
, sib
, displacement
);
3700 working
.write(LOAD2_IB
);
3701 working
.write((int)immediate
);
3703 load0_Ew(prefices
, modrm
, sib
, displacement
);
3705 working
.write(LOAD2_IB
);
3706 working
.write((int)immediate
);
3709 case 0xfa5: //SHLD Ev, Gv, CL
3710 case 0xfad: //SHRD Ev, Gv, CL
3711 if ((prefices
& PREFICES_OPERAND
) != 0) {
3712 load0_Ed(prefices
, modrm
, sib
, displacement
);
3714 working
.write(LOAD2_CL
);
3716 load0_Ew(prefices
, modrm
, sib
, displacement
);
3718 working
.write(LOAD2_CL
);
3722 case 0xfb0: //CMPXCHG Eb, Gb
3723 load0_Eb(prefices
, modrm
, sib
, displacement
);
3725 working
.write(LOAD2_AL
);
3728 case 0xfb1: //CMPXCHG Ev, Gv
3729 if ((prefices
& PREFICES_OPERAND
) != 0) {
3730 load0_Ed(prefices
, modrm
, sib
, displacement
);
3732 working
.write(LOAD2_EAX
);
3734 load0_Ew(prefices
, modrm
, sib
, displacement
);
3736 working
.write(LOAD2_AX
);
3740 case 0xfa3: //BT Ev, Gv
3741 case 0xfab: //BTS Ev, Gv
3742 case 0xfb3: //BTR Ev, Gv
3743 case 0xfbb: //BTC Ev, Gv
3744 if ((prefices
& PREFICES_OPERAND
) != 0) {
3745 switch (modrm
& 0xc7) {
3746 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3748 case 0xc0: working
.write(LOAD0_EAX
); break;
3749 case 0xc1: working
.write(LOAD0_ECX
); break;
3750 case 0xc2: working
.write(LOAD0_EDX
); break;
3751 case 0xc3: working
.write(LOAD0_EBX
); break;
3752 case 0xc4: working
.write(LOAD0_ESP
); break;
3753 case 0xc5: working
.write(LOAD0_EBP
); break;
3754 case 0xc6: working
.write(LOAD0_ESI
); break;
3755 case 0xc7: working
.write(LOAD0_EDI
); break;
3759 switch (modrm
& 0xc7) {
3760 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3762 case 0xc0: working
.write(LOAD0_AX
); break;
3763 case 0xc1: working
.write(LOAD0_CX
); break;
3764 case 0xc2: working
.write(LOAD0_DX
); break;
3765 case 0xc3: working
.write(LOAD0_BX
); break;
3766 case 0xc4: working
.write(LOAD0_SP
); break;
3767 case 0xc5: working
.write(LOAD0_BP
); break;
3768 case 0xc6: working
.write(LOAD0_SI
); break;
3769 case 0xc7: working
.write(LOAD0_DI
); break;
3775 case 0xfba: //Grp 8 Ev, Ib
3776 if ((prefices
& PREFICES_OPERAND
) != 0) {
3777 switch (modrm
& 0xc7) {
3778 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3780 case 0xc0: working
.write(LOAD0_EAX
); break;
3781 case 0xc1: working
.write(LOAD0_ECX
); break;
3782 case 0xc2: working
.write(LOAD0_EDX
); break;
3783 case 0xc3: working
.write(LOAD0_EBX
); break;
3784 case 0xc4: working
.write(LOAD0_ESP
); break;
3785 case 0xc5: working
.write(LOAD0_EBP
); break;
3786 case 0xc6: working
.write(LOAD0_ESI
); break;
3787 case 0xc7: working
.write(LOAD0_EDI
); break;
3790 switch (modrm
& 0xc7) {
3791 default: decodeM(prefices
, modrm
, sib
, displacement
); break;
3793 case 0xc0: working
.write(LOAD0_AX
); break;
3794 case 0xc1: working
.write(LOAD0_CX
); break;
3795 case 0xc2: working
.write(LOAD0_DX
); break;
3796 case 0xc3: working
.write(LOAD0_BX
); break;
3797 case 0xc4: working
.write(LOAD0_SP
); break;
3798 case 0xc5: working
.write(LOAD0_BP
); break;
3799 case 0xc6: working
.write(LOAD0_SI
); break;
3800 case 0xc7: working
.write(LOAD0_DI
); break;
3803 working
.write(LOAD1_IB
);
3804 working
.write((int)immediate
& 0x1f);
3808 switch (modrm
& 0x38)
3811 decodeM(prefices
, modrm
, sib
, displacement
);
3812 working
.write(LOAD0_MEM_QWORD
);
3814 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm
& 0x38) >> 3) + "?");
3818 case 0xfc8: working
.write(LOAD0_EAX
); break; //BSWAP EAX
3819 case 0xfc9: working
.write(LOAD0_ECX
); break; //BSWAP ECX
3820 case 0xfca: working
.write(LOAD0_EDX
); break; //BSWAP EDX
3821 case 0xfcb: working
.write(LOAD0_EBX
); break; //BSWAP EBX
3822 case 0xfcc: working
.write(LOAD0_ESP
); break; //BSWAP ESP
3823 case 0xfcd: working
.write(LOAD0_EBP
); break; //BSWAP EBP
3824 case 0xfce: working
.write(LOAD0_ESI
); break; //BSWAP ESI
3825 case 0xfcf: working
.write(LOAD0_EDI
); break; //BSWAP EDI
3828 working
.write(FWAIT
);
3829 if ((modrm
& 0xc0) != 0xc0)
3831 switch (modrm
& 0x38)
3835 decodeM(prefices
, modrm
, sib
, displacement
);
3836 working
.write(FLOAD0_MEM_SINGLE
);
3837 working
.write(FLOAD1_ST0
);
3840 working
.write(FLOAD0_ST0
);
3841 decodeM(prefices
, modrm
, sib
, displacement
);
3842 working
.write(FLOAD1_MEM_SINGLE
);
3848 switch (modrm
& 0xf8)
3852 working
.write(FLOAD0_STN
);
3853 working
.write(modrm
& 0x07);
3854 working
.write(FLOAD1_ST0
);
3857 working
.write(FLOAD0_ST0
);
3858 working
.write(FLOAD1_STN
);
3859 working
.write(modrm
& 0x07);
3866 if ((modrm
& 0xc0) != 0xc0)
3868 switch (modrm
& 0x38)
3871 working
.write(FWAIT
);
3872 decodeM(prefices
, modrm
, sib
, displacement
);
3873 working
.write(FLOAD0_MEM_SINGLE
);
3877 working
.write(FWAIT
);
3878 working
.write(FLOAD0_ST0
); break;
3880 working
.write(FWAIT
);
3881 decodeM(prefices
, modrm
, sib
, displacement
);
3884 working
.write(FWAIT
);
3885 decodeM(prefices
, modrm
, sib
, displacement
);
3886 working
.write(LOAD0_MEM_WORD
);
3888 case 0x30: decodeM(prefices
, modrm
, sib
, displacement
); break;
3889 case 0x38: working
.write(LOAD0_FPUCW
); break;
3894 working
.write(FWAIT
);
3895 switch (modrm
& 0xf8)
3898 working
.write(FLOAD0_STN
);
3899 working
.write(modrm
& 0x07);
3902 working
.write(FLOAD0_ST0
);
3903 working
.write(FLOAD1_STN
);
3904 working
.write(modrm
& 0x07);
3922 case 0xff: working
.write(FLOAD0_ST0
); break;
3929 working
.write(FLOAD0_ST0
);
3930 working
.write(FLOAD1_STN
);
3934 working
.write(FLOAD0_ST0
);
3935 working
.write(FLOAD1_POS0
);
3937 case 0xe8: working
.write(FLOAD0_1
); break;
3938 case 0xe9: working
.write(FLOAD0_L2TEN
); break;
3939 case 0xea: working
.write(FLOAD0_L2E
); break;
3940 case 0xeb: working
.write(FLOAD0_PI
); break;
3941 case 0xec: working
.write(FLOAD0_LOG2
); break;
3942 case 0xed: working
.write(FLOAD0_LN2
); break;
3943 case 0xee: working
.write(FLOAD0_POS0
); break;
3949 working
.write(FWAIT
);
3950 if ((modrm
& 0xc0) != 0xc0)
3952 switch (modrm
& 0x38)
3956 decodeM(prefices
, modrm
, sib
, displacement
);
3957 working
.write(LOAD0_MEM_DWORD
);
3958 working
.write(FLOAD0_REG0
);
3959 working
.write(FLOAD1_ST0
);
3962 working
.write(FLOAD0_ST0
);
3963 decodeM(prefices
, modrm
, sib
, displacement
);
3964 working
.write(LOAD0_MEM_DWORD
);
3965 working
.write(FLOAD1_REG0
);
3971 switch (modrm
& 0xf8)
3977 working
.write(FLOAD0_STN
);
3978 working
.write(modrm
& 0x07);
3984 working
.write(FLOAD0_ST0
);
3985 working
.write(FLOAD1_STN
);
3993 if ((modrm
& 0xc0) != 0xc0)
3995 working
.write(FWAIT
);
3996 switch (modrm
& 0x38)
3999 decodeM(prefices
, modrm
, sib
, displacement
);
4000 working
.write(LOAD0_MEM_DWORD
);
4001 working
.write(FLOAD0_REG0
);
4006 case 0x38: working
.write(FLOAD0_ST0
); break;
4008 decodeM(prefices
, modrm
, sib
, displacement
);
4009 working
.write(FLOAD0_MEM_EXTENDED
);
4019 default: working
.write(FWAIT
); break;
4021 switch (modrm
& 0xf8)
4027 working
.write(FLOAD0_STN
);
4028 working
.write(modrm
& 0x07);
4032 working
.write(FLOAD0_ST0
);
4033 working
.write(FLOAD1_STN
);
4034 working
.write(modrm
& 0x07);
4041 working
.write(FWAIT
);
4042 if ((modrm
& 0xc0) != 0xc0)
4044 switch (modrm
& 0x38)
4048 decodeM(prefices
, modrm
, sib
, displacement
);
4049 working
.write(FLOAD0_MEM_DOUBLE
);
4050 working
.write(FLOAD1_ST0
);
4053 working
.write(FLOAD0_ST0
);
4054 decodeM(prefices
, modrm
, sib
, displacement
);
4055 working
.write(FLOAD1_MEM_DOUBLE
);
4061 switch (modrm
& 0xf8)
4065 working
.write(FLOAD0_STN
);
4066 working
.write(modrm
& 0x07);
4067 working
.write(FLOAD1_ST0
);
4070 working
.write(FLOAD0_ST0
);
4071 working
.write(FLOAD1_STN
);
4072 working
.write(modrm
& 0x07);
4079 if ((modrm
& 0xc0) != 0xc0)
4081 switch (modrm
& 0x38)
4084 working
.write(FWAIT
);
4085 decodeM(prefices
, modrm
, sib
, displacement
);
4086 working
.write(FLOAD0_MEM_DOUBLE
);
4091 working
.write(FWAIT
);
4092 working
.write(FLOAD0_ST0
);
4095 working
.write(FWAIT
);
4096 decodeM(prefices
, modrm
, sib
, displacement
);
4098 case 0x30: decodeM(prefices
, modrm
, sib
, displacement
); break;
4099 case 0x38: working
.write(LOAD0_FPUSW
); break;
4104 working
.write(FWAIT
);
4105 switch (modrm
& 0xf8)
4108 working
.write(LOAD0_ID
);
4109 working
.write(modrm
& 0x07);
4112 case 0xd8: working
.write(FLOAD0_ST0
); break;
4115 working
.write(FLOAD0_ST0
);
4116 working
.write(FLOAD1_STN
);
4117 working
.write(modrm
& 0x07);
4124 working
.write(FWAIT
);
4125 if ((modrm
& 0xc0) != 0xc0)
4127 switch (modrm
& 0x38)
4131 decodeM(prefices
, modrm
, sib
, displacement
);
4132 working
.write(LOAD0_MEM_WORD
);
4133 working
.write(FLOAD0_REG0
);
4134 working
.write(FLOAD1_ST0
);
4137 working
.write(FLOAD0_ST0
);
4138 decodeM(prefices
, modrm
, sib
, displacement
);
4139 working
.write(LOAD0_MEM_QWORD
);
4140 working
.write(FLOAD1_REG0L
);
4143 working
.write(FLOAD0_ST0
);
4144 decodeM(prefices
, modrm
, sib
, displacement
);
4145 working
.write(LOAD0_MEM_WORD
);
4146 working
.write(FLOAD1_REG0
);
4152 switch (modrm
& 0xf8) {
4157 working
.write(FLOAD0_ST0
);
4158 working
.write(FLOAD1_STN
);
4159 working
.write(modrm
& 0x07);
4163 working
.write(FLOAD1_ST0
);
4164 working
.write(FLOAD0_STN
);
4165 working
.write(modrm
& 0x07);
4171 working
.write(FLOAD0_ST0
);
4172 working
.write(FLOAD1_STN
);
4180 if ((modrm
& 0xc0) != 0xc0)
4182 working
.write(FWAIT
);
4183 switch (modrm
& 0x38)
4186 decodeM(prefices
, modrm
, sib
, displacement
);
4187 working
.write(LOAD0_MEM_WORD
);
4188 working
.write(FLOAD0_REG0
);
4191 decodeM(prefices
, modrm
, sib
, displacement
);
4192 working
.write(LOAD0_MEM_QWORD
);
4193 working
.write(FLOAD0_REG0L
);
4199 working
.write(FLOAD0_ST0
);
4202 working
.write(FLOAD0_ST0
);
4203 decodeM(prefices
, modrm
, sib
, displacement
);
4206 decodeM(prefices
, modrm
, sib
, displacement
);
4214 case 0xe0: working
.write(LOAD0_FPUSW
); break;
4215 default: working
.write(FWAIT
); break;
4217 switch (modrm
& 0xf8) {
4220 working
.write(FLOAD0_ST0
);
4221 working
.write(FLOAD1_STN
);
4222 working
.write(modrm
& 0x07);
4231 private void writeOutputOperands(int prefices
, int opcode
, int modrm
, int sib
, int displacement
)
4233 //Normal One Byte Operation
4235 case 0x00: //ADD Eb, Gb
4236 case 0x08: //OR Eb, Gb
4237 case 0x10: //ADC Eb, Gb
4238 case 0x18: //SBB Eb, Gb
4239 case 0x20: //AND Eb, Gb
4240 case 0x28: //SUB Eb, Gb
4241 case 0x30: //XOR Eb, Gb
4242 case 0x88: //MOV Eb, Gb
4243 case 0xc0: //SFT G2 Eb, Ib
4244 case 0xc6: //MOV G11 Eb, Ib
4245 case 0xfe: //INC/DEC G4 Eb
4253 case 0xf97: //SETNBE
4261 case 0xf9f: //SETNLE
4262 store0_Eb(prefices
, modrm
, sib
, displacement
);
4265 case 0xfb0: //CMPXCHG Eb, Gb
4266 working
.write(STORE1_AL
); //do store 1 first incase Eb is also AL/AX/EAX
4267 store0_Eb(prefices
, modrm
, sib
, displacement
);
4270 case 0x80: //IMM G1 Eb, Ib
4271 case 0x82: //IMM G1 Eb, Ib
4272 if ((modrm
& 0x38) == 0x38)
4274 store0_Eb(prefices
, modrm
, sib
, displacement
); break;
4276 case 0x86: //XCHG Eb, Gb
4278 store1_Eb(prefices
, modrm
, sib
, displacement
);
4281 case 0x02: //ADD Gb, Eb
4282 case 0x0a: //OR Gb, Eb
4283 case 0x12: //ADC Gb, Eb
4284 case 0x1a: //SBB Gb, Eb
4285 case 0x22: //AND Gb, Eb
4286 case 0x2a: //SUB Gb, Eb
4287 case 0x32: //XOR Gb, Eb
4288 case 0x8a: //MOV Gb, Eb
4292 case 0x01: //ADD Ev, Gv
4293 case 0x09: //OR Ev, Gv
4294 case 0x11: //ADC Ev, Gv
4295 case 0x19: //SBB Ev, Gv
4296 case 0x21: //AND Ev, Gv
4297 case 0x29: //SUB Ev, Gv
4298 case 0x31: //XOR Ev, Gv
4299 case 0x89: //MOV Ev, Gv
4300 case 0xc7: //MOV G11 Ev, Iv
4301 case 0xc1: //SFT G2 Ev, Ib
4303 case 0xd1: //SFT G2 Ev, 1
4304 case 0xd3: //SFT G2 Ev, CL
4305 if ((prefices
& PREFICES_OPERAND
) != 0) {
4306 store0_Ed(prefices
, modrm
, sib
, displacement
);
4308 store0_Ew(prefices
, modrm
, sib
, displacement
);
4312 case 0xfb1: //CMPXCHG Ev, Gv
4313 if ((prefices
& PREFICES_OPERAND
) != 0) {
4314 working
.write(STORE1_EAX
); //do store1 first incase Eb is same place
4315 store0_Ed(prefices
, modrm
, sib
, displacement
);
4317 working
.write(STORE1_AX
); //do store1 first incase Eb is same place
4318 store0_Ew(prefices
, modrm
, sib
, displacement
);
4322 case 0x81: //IMM G1 Ev, Iv
4323 case 0x83: //IMM G1 Ev, Ib
4324 if ((modrm
& 0x38) == 0x38)
4326 if ((prefices
& PREFICES_OPERAND
) != 0) {
4327 store0_Ed(prefices
, modrm
, sib
, displacement
);
4329 store0_Ew(prefices
, modrm
, sib
, displacement
);
4334 case 0x87: //XCHG Ev, Gv
4335 if ((prefices
& PREFICES_OPERAND
) != 0) {
4337 store1_Ed(prefices
, modrm
, sib
, displacement
);
4340 store1_Ew(prefices
, modrm
, sib
, displacement
);
4344 case 0x03: //ADD Gv, Ev
4345 case 0x0b: //OR Gv, Ev
4346 case 0x13: //ADC Gv, Ev
4347 case 0x1b: //SBB Gv, Ev
4348 case 0x23: //AND Gv, Ev
4349 case 0x2b: //SUB Gv, Ev
4350 case 0x33: //XOR Gv, Ev
4351 case 0x69: //IMUL Gv, Ev, Iv
4352 case 0x6b: //IMUL Gv, Ev, Ib
4353 case 0x8b: //MOV Gv, Ev
4354 case 0x8d: //LEA Gv, M
4355 case 0xf02: //LAR Gv, Ew
4356 case 0xf03: //LSL Gv, Ew
4358 case 0xf41: //CMOVNO
4360 case 0xf43: //CMOVNC
4362 case 0xf45: //CMOVNZ
4363 case 0xf46: //CMOVBE
4364 case 0xf47: //CMOVNBE
4366 case 0xf49: //CMOVNS
4368 case 0xf4b: //CMOVNP
4370 case 0xf4d: //CMOVNL
4371 case 0xf4e: //CMOVLE
4372 case 0xf4f: //CMOVNLE
4373 case 0xfaf: //IMUL Gv, Ev
4374 case 0xfb6: //MOVZX Gv, Eb
4375 case 0xfb7: //MOVZX Gv, Ew
4376 case 0xfbc: //BSF Gv, Ev
4377 case 0xfbd: //BSR Gv, Ev
4378 case 0xfbe: //MOVSX Gv, Eb
4379 case 0xfbf: //MOVSX Gv, Ew
4380 if ((prefices
& PREFICES_OPERAND
) != 0) {
4387 case 0xec: //IN AL, DX
4388 case 0x04: //ADD AL, Ib
4389 case 0x0c: //OR AL, Ib
4390 case 0x14: //ADC AL, Ib
4391 case 0x1c: //SBB AL, Ib
4392 case 0x24: //AND AL, Ib
4393 case 0x2c: //SUB AL, Ib
4394 case 0x34: //XOR AL, Ib
4395 case 0xe4: //IN AL, Ib
4396 case 0xb0: //MOV AL, Ib
4397 working
.write(STORE0_AL
);
4400 case 0xb1: //MOV CL, Ib
4401 working
.write(STORE0_CL
);
4404 case 0xb2: //MOV DL, Ib
4405 working
.write(STORE0_DL
);
4408 case 0xb3: //MOV BL, Ib
4409 working
.write(STORE0_BL
);
4412 case 0xb4: //MOV AH, Ib
4413 working
.write(STORE0_AH
);
4416 case 0xb5: //MOV CH, Ib
4417 working
.write(STORE0_CH
);
4420 case 0xb6: //MOV DH, Ib
4421 working
.write(STORE0_DH
);
4424 case 0xb7: //MOV BH, Ib
4425 working
.write(STORE0_BH
);
4430 case 0x05: //ADD eAX, Iv
4431 case 0x0d: //OR eAX, Iv
4432 case 0x15: //ADC eAX, Iv
4433 case 0x1d: //SBB eAX, Iv
4434 case 0x25: //AND eAX, Iv
4435 case 0x2d: //SUB eAX, Iv
4436 case 0x35: //XOR eAX, Iv
4437 case 0xb8: //MOV eAX, Iv
4438 case 0xe5: //IN eAX, Ib
4439 case 0x40: //INC eAX
4440 case 0x48: //DEC eAX
4441 case 0x58: //POP eAX
4442 case 0xed: //IN eAX, DX
4443 if ((prefices
& PREFICES_OPERAND
) != 0) {
4444 working
.write(STORE0_EAX
);
4446 working
.write(STORE0_AX
);
4450 case 0x41: //INC eCX
4451 case 0x49: //DEC eCX
4452 case 0x59: //POP eCX
4453 case 0xb9: //MOV eCX, Iv
4454 if ((prefices
& PREFICES_OPERAND
) != 0) {
4455 working
.write(STORE0_ECX
);
4457 working
.write(STORE0_CX
);
4461 case 0x42: //INC eDX
4462 case 0x4a: //DEC eDX
4463 case 0x5a: //POP eDX
4464 case 0xba: //MOV eDX, Iv
4465 if ((prefices
& PREFICES_OPERAND
) != 0) {
4466 working
.write(STORE0_EDX
);
4468 working
.write(STORE0_DX
);
4472 case 0x43: //INC eBX
4473 case 0x4b: //DEC eBX
4474 case 0x5b: //POP eBX
4475 case 0xbb: //MOV eBX, Iv
4476 if ((prefices
& PREFICES_OPERAND
) != 0) {
4477 working
.write(STORE0_EBX
);
4479 working
.write(STORE0_BX
);
4483 case 0x44: //INC eSP
4484 case 0x4c: //DEC eSP
4485 case 0x5c: //POP eSP
4486 case 0xbc: //MOV eSP, Iv
4487 if ((prefices
& PREFICES_OPERAND
) != 0) {
4488 working
.write(STORE0_ESP
);
4490 working
.write(STORE0_SP
);
4494 case 0x45: //INC eBP
4495 case 0x4d: //DEC eBP
4496 case 0x5d: //POP eBP
4497 case 0xbd: //MOV eBP, Iv
4498 if ((prefices
& PREFICES_OPERAND
) != 0) {
4499 working
.write(STORE0_EBP
);
4501 working
.write(STORE0_BP
);
4505 case 0x46: //INC eSI
4506 case 0x4e: //DEC eSI
4507 case 0x5e: //POP eSI
4508 case 0xbe: //MOV eSI, Iv
4509 if ((prefices
& PREFICES_OPERAND
) != 0) {
4510 working
.write(STORE0_ESI
);
4512 working
.write(STORE0_SI
);
4516 case 0x47: //INC eDI
4517 case 0x4f: //DEC eDI
4518 case 0x5f: //POP eDI
4519 case 0xbf: //MOV eDI, Iv
4520 if ((prefices
& PREFICES_OPERAND
) != 0) {
4521 working
.write(STORE0_EDI
);
4523 working
.write(STORE0_DI
);
4528 case 0x91: //XCHG eAX, eCX
4529 if ((prefices
& PREFICES_OPERAND
) != 0) {
4530 working
.write(STORE0_ECX
);
4531 working
.write(STORE1_EAX
);
4533 working
.write(STORE0_CX
);
4534 working
.write(STORE1_AX
);
4538 case 0x92: //XCHG eAX, eDX
4539 if ((prefices
& PREFICES_OPERAND
) != 0) {
4540 working
.write(STORE0_EDX
);
4541 working
.write(STORE1_EAX
);
4543 working
.write(STORE0_DX
);
4544 working
.write(STORE1_AX
);
4548 case 0x93: //XCHG eAX, eBX
4549 if ((prefices
& PREFICES_OPERAND
) != 0) {
4550 working
.write(STORE0_EBX
);
4551 working
.write(STORE1_EAX
);
4553 working
.write(STORE0_BX
);
4554 working
.write(STORE1_AX
);
4558 case 0x94: //XCHG eAX, eSP
4559 if ((prefices
& PREFICES_OPERAND
) != 0) {
4560 working
.write(STORE0_ESP
);
4561 working
.write(STORE1_EAX
);
4563 working
.write(STORE0_SP
);
4564 working
.write(STORE1_AX
);
4568 case 0x95: //XCHG eAX, eBP
4569 if ((prefices
& PREFICES_OPERAND
) != 0) {
4570 working
.write(STORE0_EBP
);
4571 working
.write(STORE1_EAX
);
4573 working
.write(STORE0_BP
);
4574 working
.write(STORE1_AX
);
4578 case 0x96: //XCHG eAX, eSI
4579 if ((prefices
& PREFICES_OPERAND
) != 0) {
4580 working
.write(STORE0_ESI
);
4581 working
.write(STORE1_EAX
);
4583 working
.write(STORE0_SI
);
4584 working
.write(STORE1_AX
);
4588 case 0x97: //XCHG eAX, eDI
4589 if ((prefices
& PREFICES_OPERAND
) != 0) {
4590 working
.write(STORE0_EDI
);
4591 working
.write(STORE1_EAX
);
4593 working
.write(STORE0_DI
);
4594 working
.write(STORE1_AX
);
4599 switch (prefices
& PREFICES_OPERAND
) {
4601 working
.write(STORE0_FLAGS
); break;
4602 case PREFICES_OPERAND
:
4603 working
.write(STORE0_EFLAGS
); break;
4607 case 0xd0: //SFT G2 Eb, 1
4608 case 0xd2: //SFT G2 Eb, CL
4609 store0_Eb(prefices
, modrm
, sib
, displacement
);
4614 case 0xf6: //UNA G3 Eb, ?
4615 switch (modrm
& 0x38) {
4618 store0_Eb(prefices
, modrm
, sib
, displacement
);
4623 case 0xf7: //UNA G3 Ev, ?
4624 if ((prefices
& PREFICES_OPERAND
) != 0) {
4625 switch (modrm
& 0x38) {
4628 store0_Ed(prefices
, modrm
, sib
, displacement
);
4632 switch (modrm
& 0x38) {
4635 store0_Ew(prefices
, modrm
, sib
, displacement
);
4643 working
.write(STORE0_ES
);
4647 working
.write(STORE0_SS
);
4651 working
.write(STORE0_DS
);
4654 case 0x8c: //MOV Ew, Sw
4655 if ((prefices
& PREFICES_OPERAND
) != 0) {
4656 store0_Ed(prefices
, modrm
, sib
, displacement
);
4658 store0_Ew(prefices
, modrm
, sib
, displacement
);
4662 case 0x8e: //MOV Sw, Ew
4666 case 0xa0: //MOV AL, Ob
4667 working
.write(STORE0_AL
);
4670 case 0xa2: //MOV Ob, AL
4671 store0_Ob(prefices
, displacement
);
4674 case 0xa1: //MOV eAX, Ov
4675 if ((prefices
& PREFICES_OPERAND
) != 0) {
4676 working
.write(STORE0_EAX
);
4678 working
.write(STORE0_AX
);
4682 case 0xa3: //MOV Ov, eAX
4683 if ((prefices
& PREFICES_OPERAND
) != 0) {
4684 store0_Od(prefices
, displacement
);
4686 store0_Ow(prefices
, displacement
);
4690 case 0xff: //INC/DEC G5
4691 if ((prefices
& PREFICES_OPERAND
) != 0) {
4692 switch (modrm
& 0x38) {
4695 store0_Ed(prefices
, modrm
, sib
, displacement
);
4698 switch (modrm
& 0x38) {
4701 store0_Ew(prefices
, modrm
, sib
, displacement
);
4706 case 0xc4: //LES Gv, Mp
4707 if ((prefices
& PREFICES_OPERAND
) != 0) {
4709 working
.write(STORE1_ES
);
4712 working
.write(STORE1_ES
);
4716 case 0xc5: //LDS Gv, Mp
4717 if ((prefices
& PREFICES_OPERAND
) != 0) {
4719 working
.write(STORE1_DS
);
4722 working
.write(STORE1_DS
);
4726 case 0xf00: // Group 6
4727 switch (modrm
& 0x38) {
4729 store0_Ew(prefices
, modrm
, sib
, displacement
); break;
4730 case 0x08: //STR (stores to a doubleword if a register, but a word if memory)
4731 if ((prefices
& PREFICES_OPERAND
) != 0) {
4732 switch (modrm
& 0xc7) {
4733 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_WORD
); break;
4735 case 0xc0: working
.write(STORE0_EAX
); break;
4736 case 0xc1: working
.write(STORE0_ECX
); break;
4737 case 0xc2: working
.write(STORE0_EDX
); break;
4738 case 0xc3: working
.write(STORE0_EBX
); break;
4739 case 0xc4: working
.write(STORE0_ESP
); break;
4740 case 0xc5: working
.write(STORE0_EBP
); break;
4741 case 0xc6: working
.write(STORE0_ESI
); break;
4742 case 0xc7: working
.write(STORE0_EDI
); break;
4746 store0_Ew(prefices
, modrm
, sib
, displacement
);
4751 switch (modrm
& 0x38) {
4754 store0_Ew(prefices
, modrm
, sib
, displacement
);
4755 working
.write(ADDR_ID
);
4757 working
.write(STORE1_MEM_DWORD
);
4759 case 0x20: store0_Ew(prefices
, modrm
, sib
, displacement
); break;
4762 case 0xf1f: break; //multi byte NOP (read latest manual)
4763 case 0xfa4: //SHLD Ev, Gv, Ib
4764 case 0xfa5: //SHLD Ev, Gv, CL
4765 case 0xfac: //SHRD Ev, Gv, Ib
4766 case 0xfad: //SHRD Ev, Gv, CL
4767 if ((prefices
& PREFICES_OPERAND
) != 0)
4768 store0_Ed(prefices
, modrm
, sib
, displacement
);
4770 store0_Ew(prefices
, modrm
, sib
, displacement
);
4773 case 0xfb2: //LSS Mp
4774 if ((prefices
& PREFICES_OPERAND
) != 0) {
4776 working
.write(STORE1_SS
);
4779 working
.write(STORE1_SS
);
4783 case 0xfb4: //LFS Mp
4784 if ((prefices
& PREFICES_OPERAND
) != 0) {
4786 working
.write(STORE1_FS
);
4789 working
.write(STORE1_FS
);
4793 case 0xfb5: //LGS Mp
4794 if ((prefices
& PREFICES_OPERAND
) != 0) {
4796 working
.write(STORE1_GS
);
4799 working
.write(STORE1_GS
);
4803 case 0xfc0: //XADD Eb, Gb
4804 store1_Gb(modrm
); //exchange first then add (so we write the result of the exchange first incase Eb and Gb are same reg)
4805 store0_Eb(prefices
, modrm
, sib
, displacement
);
4808 case 0xfc1: //XADD Eb, Gb
4809 if ((prefices
& PREFICES_OPERAND
) != 0) {
4810 store1_Gd(modrm
); //exchange first then add
4811 store0_Ed(prefices
, modrm
, sib
, displacement
);
4813 store1_Gw(modrm
); //exchange first then add
4814 store0_Ew(prefices
, modrm
, sib
, displacement
);
4820 working
.write(STORE0_AL
); break;
4822 case 0xf20: //MOV Rd, Cd
4823 case 0xf21: //MOV Rd, Dd
4824 store0_Rd(modrm
); break;
4826 case 0xf22: store0_Cd(modrm
); break; //MOV Cd, Rd
4827 case 0xf23: store0_Dd(modrm
); break; //MOV Dd, Rd
4831 working
.write(STORE0_EAX
);
4832 working
.write(STORE1_EDX
);
4836 case 0xfa1: //POP FS
4837 working
.write(STORE0_FS
); break;
4839 case 0xfa9: //POP GS
4840 working
.write(STORE0_GS
); break;
4842 case 0xfab: //BTS Ev, Gv
4843 case 0xfb3: //BTR Ev, Gv
4844 case 0xfbb: //BTC Ev, Gv
4845 if ((prefices
& PREFICES_OPERAND
) != 0) {
4846 if ((modrm
& 0xc0) == 0xc0)
4847 store0_Ed(prefices
, modrm
, sib
, displacement
);
4849 if ((modrm
& 0xc0) == 0xc0)
4850 store0_Ew(prefices
, modrm
, sib
, displacement
);
4854 case 0xfba: //Grp 8 Ev, Ib
4855 switch (modrm
& 0x38) {
4859 if ((prefices
& PREFICES_OPERAND
) != 0) {
4860 if ((modrm
& 0xc0) == 0xc0)
4861 store0_Ed(prefices
, modrm
, sib
, displacement
);
4863 if ((modrm
& 0xc0) == 0xc0)
4864 store0_Ew(prefices
, modrm
, sib
, displacement
);
4869 case 0xfc7: //CMPXCHG8B
4870 switch (modrm
& 0x38)
4873 decodeM(prefices
, modrm
, sib
, displacement
);
4874 working
.write(STORE0_MEM_QWORD
);
4876 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F C7 /" + ((modrm
& 0x38) >> 3) + "?");
4880 case 0xfc8: working
.write(STORE0_EAX
); break; //BSWAP EAX
4881 case 0xfc9: working
.write(STORE0_ECX
); break; //BSWAP ECX
4882 case 0xfca: working
.write(STORE0_EDX
); break; //BSWAP EDX
4883 case 0xfcb: working
.write(STORE0_EBX
); break; //BSWAP EBX
4884 case 0xfcc: working
.write(STORE0_ESP
); break; //BSWAP ESP
4885 case 0xfcd: working
.write(STORE0_EBP
); break; //BSWAP EBP
4886 case 0xfce: working
.write(STORE0_ESI
); break; //BSWAP ESI
4887 case 0xfcf: working
.write(STORE0_EDI
); break; //BSWAP EDI
4890 switch (modrm
& 0x38)
4898 working
.write(FSTORE0_ST0
);
4899 working
.write(FCHECK0
);
4902 case 0x18: working
.write(FPOP
); break;
4907 if ((modrm
& 0xc0) != 0xc0)
4909 switch (modrm
& 0x38)
4916 decodeM(prefices
, modrm
, sib
, displacement
);
4917 working
.write(FSTORE0_MEM_SINGLE
);
4920 decodeM(prefices
, modrm
, sib
, displacement
);
4921 working
.write(FSTORE0_MEM_SINGLE
);
4922 working
.write(FPOP
);
4924 case 0x28: working
.write(STORE0_FPUCW
); break;
4926 decodeM(prefices
, modrm
, sib
, displacement
);
4927 working
.write(STORE0_MEM_WORD
);
4933 switch (modrm
& 0xf8)
4937 working
.write(FSTORE0_STN
);
4938 working
.write(modrm
& 0x07);
4939 working
.write(FSTORE1_ST0
);
4959 case 0xff: working
.write(FSTORE0_ST0
); break;
4966 working
.write(FSTORE0_ST0
);
4967 working
.write(FCHECK0
);
4970 working
.write(FSTORE0_ST0
);
4971 working
.write(FLOAD0_1
);
4972 working
.write(FPUSH
);
4976 working
.write(FPOP
);
4977 working
.write(FSTORE0_ST0
);
4980 working
.write(FPOP
);
4981 working
.write(FSTORE0_ST0
);
4982 working
.write(FCHECK0
);
4985 working
.write(FSTORE1_ST0
);
4986 working
.write(FPUSH
);
4989 working
.write(FSTORE1_ST0
);
4990 working
.write(FPUSH
);
4991 working
.write(FCHECK0
);
4992 working
.write(FCHECK1
);
4999 if ((modrm
& 0xc0) != 0xc0)
5001 switch (modrm
& 0x38)
5009 working
.write(FSTORE0_ST0
);
5010 working
.write(FCHECK0
);
5013 case 0x18: working
.write(FPOP
); break;
5021 working
.write(FPOP
);
5022 working
.write(FPOP
);
5029 if ((modrm
& 0xc0) != 0xc0)
5031 switch (modrm
& 0x38)
5036 decodeM(prefices
, modrm
, sib
, displacement
);
5037 working
.write(STORE0_MEM_DWORD
);
5041 decodeM(prefices
, modrm
, sib
, displacement
);
5042 working
.write(STORE0_MEM_DWORD
);
5043 working
.write(FPOP
);
5046 decodeM(prefices
, modrm
, sib
, displacement
);
5047 working
.write(FSTORE0_MEM_EXTENDED
);
5048 working
.write(FPOP
);
5055 if ((modrm
& 0xc0) != 0xc0)
5057 switch (modrm
& 0x38)
5065 working
.write(FSTORE0_ST0
);
5066 working
.write(FCHECK0
);
5069 case 0x18: working
.write(FPOP
); break;
5074 switch (modrm
& 0xf8)
5082 working
.write(FSTORE0_STN
);
5083 working
.write(modrm
& 0x07);
5084 working
.write(FCHECK0
);
5091 if ((modrm
& 0xc0) != 0xc0)
5093 switch (modrm
& 0x38)
5099 decodeM(prefices
, modrm
, sib
, displacement
);
5100 working
.write(STORE0_MEM_QWORD
);
5101 working
.write(FPOP
);
5104 decodeM(prefices
, modrm
, sib
, displacement
);
5105 working
.write(FSTORE0_MEM_DOUBLE
);
5108 decodeM(prefices
, modrm
, sib
, displacement
);
5109 working
.write(FSTORE0_MEM_DOUBLE
);
5110 working
.write(FPOP
);
5113 decodeM(prefices
, modrm
, sib
, displacement
);
5114 working
.write(STORE0_MEM_WORD
);
5120 switch (modrm
& 0xf8)
5125 working
.write(FSTORE0_STN
);
5126 working
.write(modrm
& 0x07);
5129 working
.write(FSTORE0_STN
);
5130 working
.write(modrm
& 0x07);
5131 working
.write(FPOP
);
5133 case 0xe8: working
.write(FPOP
); break;
5139 if ((modrm
& 0xc0) != 0xc0)
5141 switch (modrm
& 0x38)
5149 working
.write(FSTORE0_ST0
);
5150 working
.write(FCHECK0
);
5153 case 0x18: working
.write(FPOP
); break;
5158 switch (modrm
& 0xf8)
5166 working
.write(FSTORE0_STN
);
5167 working
.write(modrm
& 0x07);
5168 working
.write(FPOP
);
5169 working
.write(FCHECK0
);
5177 working
.write(FPOP
);
5178 working
.write(FPOP
);
5185 if ((modrm
& 0xc0) != 0xc0)
5187 switch (modrm
& 0x38)
5195 decodeM(prefices
, modrm
, sib
, displacement
);
5196 working
.write(STORE0_MEM_WORD
);
5197 working
.write(FPOP
);
5200 decodeM(prefices
, modrm
, sib
, displacement
);
5201 working
.write(STORE0_MEM_WORD
);
5204 decodeM(prefices
, modrm
, sib
, displacement
);
5205 working
.write(STORE0_MEM_QWORD
);
5206 working
.write(FPOP
);
5212 switch (modrm
& 0xf8)
5215 case 0xf0: working
.write(FPOP
); break;
5219 case 0xe0: working
.write(STORE0_AX
); break;
5227 private static int operationHasImmediate(int prefices
, int opcode
, int modrm
)
5230 case 0x04: //ADD AL, Ib
5231 case 0x0c: //OR AL, Ib
5232 case 0x14: //ADC AL, Ib
5233 case 0x1c: //SBB AL, Ib
5234 case 0x24: //AND AL, Ib
5235 case 0x2c: //SUB AL, Ib
5236 case 0x34: //XOR AL, Ib
5237 case 0x3c: //CMP AL, Ib
5238 case 0x6a: //PUSH Ib
5239 case 0x6b: //IMUL Gv, Ev, Ib
5256 case 0x80: //IMM G1 Eb, Ib
5257 case 0x82: //IMM G1 Eb, Ib
5258 case 0x83: //IMM G1 Ev, Ib
5259 case 0xa8: //TEST AL, Ib
5260 case 0xb0: //MOV AL, Ib
5261 case 0xb1: //MOV CL, Ib
5262 case 0xb2: //MOV DL, Ib
5263 case 0xb3: //MOV BL, Ib
5264 case 0xb4: //MOV AH, Ib
5265 case 0xb5: //MOV CH, Ib
5266 case 0xb6: //MOV DH, Ib
5267 case 0xb7: //MOV BH, Ib
5268 case 0xc0: //SFT G2 Eb, Ib
5269 case 0xc1: //SFT G2 Ev, Ib
5270 case 0xc6: //MOV G11 Eb, Ib
5274 case 0xe0: //LOOPNZ Jb
5275 case 0xe1: //LOOPZ Jb
5276 case 0xe2: //LOOP Jb
5277 case 0xe3: //JCXZ Jb
5278 case 0xe4: //IN AL, Ib
5279 case 0xe5: //IN eAX, Ib
5280 case 0xe6: //OUT Ib, AL
5281 case 0xe7: //OUT Ib, eAX
5283 case 0xfa4: //SHLD Ev, Gv, Ib
5284 case 0xfac: //SHRD Ev, Gv, Ib
5285 case 0xfba: //Grp 8 Ev, Ib
5289 case 0xca: //RETF Iw
5292 case 0xc8: //ENTER Iw, Ib
5295 case 0x05: //ADD eAX, Iv
5296 case 0x0d: //OR eAX, Iv
5297 case 0x15: //ADC eAX, Iv
5298 case 0x1d: //SBB eAX, Iv
5299 case 0x25: //AND eAX, Iv
5300 case 0x2d: //SUB eAX, Iv
5301 case 0x35: //XOR eAX, Iv
5302 case 0x3d: //CMP eAX, Iv
5303 case 0x68: //PUSH Iv
5304 case 0x69: //IMUL Gv, Ev, Iv
5305 case 0x81: //IMM G1 Ev, Iv
5306 case 0xa9: //TEST eAX, Iv
5307 case 0xb8: //MOV eAX, Iv
5308 case 0xb9: //MOV eCX, Iv
5309 case 0xba: //MOV eDX, Iv
5310 case 0xbb: //MOV eBX, Iv
5311 case 0xbc: //MOV eSP, Iv
5312 case 0xbd: //MOV eBP, Iv
5313 case 0xbe: //MOV eSI, Iv
5314 case 0xbf: //MOV eDI, Iv
5315 case 0xc7: //MOV G11 Ev, Iv
5316 case 0xe8: //CALL Jv
5319 case 0xf81: //JNO Jv
5321 case 0xf83: //JNC Jv
5323 case 0xf85: //JNZ Jv
5324 case 0xf86: //JNA Jv
5327 case 0xf89: //JNS Jv
5329 case 0xf8b: //JNP Jv
5331 case 0xf8d: //JNL Jv
5332 case 0xf8e: //JNG Jv
5334 if ((prefices
& PREFICES_OPERAND
) != 0)
5339 case 0x9a: //CALLF Ap
5340 case 0xea: //JMPF Ap
5341 if ((prefices
& PREFICES_OPERAND
) != 0)
5346 case 0xf6: //UNA G3 Eb, ?
5347 switch (modrm
& 0x38) {
5348 case 0x00: //TEST Eb, Ib
5354 case 0xf7: //UNA G3 Ev, ?
5355 switch (modrm
& 0x38) {
5356 case 0x00: //TEST Ev, Iv
5357 if ((prefices
& PREFICES_OPERAND
) != 0)
5368 private static int operationHasDisplacement(int prefices
, int opcode
, int modrm
, int sib
)
5372 case 0x00: //ADD Eb, Gb
5373 case 0x01: //ADD Ev, Gv
5374 case 0x02: //ADD Gb, Eb
5375 case 0x03: //ADD Gv, Ev
5376 case 0x08: //OR Eb, Gb
5377 case 0x09: //OR Ev, Gv
5378 case 0x0a: //OR Gb, Eb
5379 case 0x0b: //OR Gv, Ev
5380 case 0x10: //ADC Eb, Gb
5381 case 0x11: //ADC Ev, Gv
5382 case 0x12: //ADC Gb, Eb
5383 case 0x13: //ADC Gv, Ev
5384 case 0x18: //SBB Eb, Gb
5385 case 0x19: //SBB Ev, Gv
5386 case 0x1a: //SBB Gb, Eb
5387 case 0x1b: //SBB Gv, Ev
5388 case 0x20: //AND Eb, Gb
5389 case 0x21: //AND Ev, Gv
5390 case 0x22: //AND Gb, Eb
5391 case 0x23: //AND Gv, Ev
5392 case 0x28: //SUB Eb, Gb
5393 case 0x29: //SUB Ev, Gv
5394 case 0x2a: //SUB Gb, Eb
5395 case 0x2b: //SUB Gv, Ev
5396 case 0x30: //XOR Eb, Gb
5397 case 0x31: //XOR Ev, Gv
5398 case 0x32: //XOR Gb, Eb
5399 case 0x33: //XOR Gv, Ev
5400 case 0x38: //CMP Eb, Gb
5401 case 0x39: //CMP Ev, Gv
5402 case 0x3a: //CMP Gb, Eb
5403 case 0x3b: //CMP Gv, Ev
5404 case 0x62: //BOUND Gv, Ma
5405 case 0x69: //IMUL Gv, Ev, Iv
5406 case 0x6b: //IMUL Gv, Ev, Ib
5407 case 0x80: //IMM G1 Eb, Ib
5408 case 0x81: //IMM G1 Ev, Iv
5409 case 0x82: //IMM G1 Eb, Ib
5410 case 0x83: //IMM G1 Ev, Ib
5411 case 0x84: //TEST Eb, Gb
5412 case 0x85: //TEST Ev, Gv
5413 case 0x86: //XCHG Eb, Gb
5414 case 0x87: //XCHG Ev, Gv
5415 case 0x88: //MOV Eb, Gb
5416 case 0x89: //MOV Ev, Gv
5417 case 0x8a: //MOV Gb, Eb
5418 case 0x8b: //MOV Gv, Ev
5419 case 0x8c: //MOV Ew, Sw
5420 case 0x8d: //LEA Gv, M
5421 case 0x8e: //MOV Sw, Ew
5423 case 0xc0: //SFT G2 Eb, Ib
5424 case 0xc1: //SFT G2 Ev, Ib
5425 case 0xc4: //LES Gv, Mp
5426 case 0xc5: //LDS Gv, Mp
5427 case 0xc6: //MOV G11 Eb, Ib
5428 case 0xc7: //MOV G11 Ev, Iv
5429 case 0xd0: //SFT G2 Eb, 1
5430 case 0xd1: //SFT G2 Ev, 1
5431 case 0xd2: //SFT G2 Eb, CL
5432 case 0xd3: //SFT G2 Ev, CL
5433 case 0xf6: //UNA G3 Eb, ?
5434 case 0xf7: //UNA G3 Ev, ?
5435 case 0xfe: //INC/DEC G4 Eb
5436 case 0xff: //INC/DEC G5
5440 case 0xf02: //LAR Gv, Ew
5441 case 0xf03: //LSL Gv, Ew
5443 case 0xf20: //MOV Rd, Cd
5444 case 0xf22: //MOV Cd, Rd
5447 case 0xf41: //CMOVNO
5449 case 0xf43: //CMOVNC
5451 case 0xf45: //CMOVNZ
5452 case 0xf46: //CMOVBE
5453 case 0xf47: //CMOVNBE
5455 case 0xf49: //CMOVNS
5457 case 0xf4b: //CMOVNP
5459 case 0xf4d: //CMOVNL
5460 case 0xf4e: //CMOVLE
5461 case 0xf4f: //CMOVNLE
5470 case 0xf97: //SETNBE
5478 case 0xf9f: //SETNLE
5480 case 0xfa3: //BT Ev, Gv
5481 case 0xfa4: //SHLD Ev, Gv, Ib
5482 case 0xfa5: //SHLD Ev, Gv, CL
5483 case 0xfab: //BTS Ev, Gv
5484 case 0xfac: //SHRD Ev, Gv, Ib
5485 case 0xfad: //SHRD Ev, Gv, CL
5487 case 0xfaf: //IMUL Gv, Ev
5489 case 0xfb0: //CMPXCHG Eb, Gb
5490 case 0xfb1: //CMPXCHG Ev, Gv
5491 case 0xfb2: //LSS Mp
5492 case 0xfb3: //BTR Ev, Gv
5493 case 0xfb4: //LFS Mp
5494 case 0xfb5: //LGS Mp
5495 case 0xfb6: //MOVZX Gv, Eb
5496 case 0xfb7: //MOVZX Gv, Ew
5498 case 0xfba: //Grp 8 Ev, Ib
5499 case 0xfbb: //BTC Ev, Gv
5500 case 0xfbc: //BSF Gv, Ev
5501 case 0xfbd: //BSR Gv, Ev
5502 case 0xfbe: //MOVSX Gv, Eb
5503 case 0xfbf: //MOVSX Gv, Ew
5504 case 0xfc0: //XADD Eb, Gb
5505 case 0xfc1: //XADD Ev, Gv
5507 case 0xfc7: //CMPXCHG8B
5508 return modrmHasDisplacement(prefices
, modrm
, sib
);
5519 if ((modrm
& 0xc0) != 0xc0)
5520 return modrmHasDisplacement(prefices
, modrm
, sib
);
5525 case 0xa0: //MOV AL, Ob
5526 case 0xa2: //MOV Ob, AL
5527 case 0xa1: //MOV eAX, Ov
5528 case 0xa3: //MOV Ov, eAX
5529 if ((prefices
& PREFICES_ADDRESS
) != 0)
5539 private static int modrmHasDisplacement(int prefices
, int modrm
, int sib
)
5541 if ((prefices
& PREFICES_ADDRESS
) != 0) {
5542 //32 bit address size
5543 switch(modrm
& 0xc0) {
5545 switch (modrm
& 0x7) {
5547 if ((sib
& 0x7) == 0x5)
5554 case 0x40: return 1; //IB
5555 case 0x80: return 4; //ID
5558 //16 bit address size
5559 switch(modrm
& 0xc0) {
5561 if ((modrm
& 0x7) == 0x6)
5565 case 0x40: return 1; //IB
5566 case 0x80: return 2; //IW
5573 public static boolean isFarJump(int opcode
, int modrm
)
5577 case 0x9a: //CALLF Ap
5578 case 0xca: //RETF Iw
5584 case 0xea: //JMPF Ap
5586 case 0xf34: //SYSENTER
5587 case 0xf35: //SYSEXIT
5591 switch (modrm
& 0x38) {
5592 case 0x18: //CALLF Ep
5593 case 0x28: //JMPF Ep
5595 default: return false;
5603 public static boolean isNearJump(int opcode
, int modrm
)
5625 case 0xe0: //LOOPNZ Jb
5626 case 0xe1: //LOOPZ Jb
5627 case 0xe2: //LOOP Jb
5628 case 0xe3: //JCXZ Jb
5629 case 0xe8: //CALL Jv
5635 switch (modrm
& 0x38) {
5636 case 0x10: //CALLN Ed
5637 case 0x20: //JMPN Ed
5639 default: return false;
5642 case 0x0f80: //Jcc Jv
5664 public static boolean isModeSwitch(int opcode
, int modrm
)
5667 case 0x0f22: //MOV Cd, Ed
5670 return ((modrm
& 0x38) == 0x30);
5676 public static boolean isBlockTerminating(int opcode
, int modrm
)
5687 public static boolean isJump(int opcode
, int modrm
)
5689 return isNearJump(opcode
, modrm
) || isFarJump(opcode
, modrm
) || isModeSwitch(opcode
, modrm
) || isBlockTerminating(opcode
, modrm
);
5692 private void store0_Cd(int modrm
)
5694 switch(modrm
& 0x38) {
5695 case 0x00: working
.write(STORE0_CR0
); break;
5696 case 0x10: working
.write(STORE0_CR2
); break;
5697 case 0x18: working
.write(STORE0_CR3
); break;
5698 case 0x20: working
.write(STORE0_CR4
); break;
5699 default: throw new IllegalStateException("Unknown Control Register Operand");
5703 private void load0_Cd(int modrm
)
5705 switch(modrm
& 0x38) {
5706 case 0x00: working
.write(LOAD0_CR0
); break;
5707 case 0x10: working
.write(LOAD0_CR2
); break;
5708 case 0x18: working
.write(LOAD0_CR3
); break;
5709 case 0x20: working
.write(LOAD0_CR4
); break;
5710 default: throw new IllegalStateException("Unknown Control Register Operand");
5714 private void store0_Dd(int modrm
)
5716 switch(modrm
& 0x38) {
5717 case 0x00: working
.write(STORE0_DR0
); break;
5718 case 0x08: working
.write(STORE0_DR1
); break;
5719 case 0x10: working
.write(STORE0_DR2
); break;
5720 case 0x18: working
.write(STORE0_DR3
); break;
5721 case 0x30: working
.write(STORE0_DR6
); break;
5722 case 0x38: working
.write(STORE0_DR7
); break;
5723 default: throw new IllegalStateException("Unknown Debug Register Operand");
5727 private void load0_Dd(int modrm
)
5729 switch(modrm
& 0x38) {
5730 case 0x00: working
.write(LOAD0_DR0
); break;
5731 case 0x08: working
.write(LOAD0_DR1
); break;
5732 case 0x10: working
.write(LOAD0_DR2
); break;
5733 case 0x18: working
.write(LOAD0_DR3
); break;
5734 case 0x30: working
.write(LOAD0_DR6
); break;
5735 case 0x38: working
.write(LOAD0_DR7
); break;
5736 default: throw new IllegalStateException("Unknown Debug Register Operand");
5740 private void load0_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5742 switch(modrm
& 0xc7) {
5743 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_BYTE
); break;
5745 case 0xc0: working
.write(LOAD0_AL
); break;
5746 case 0xc1: working
.write(LOAD0_CL
); break;
5747 case 0xc2: working
.write(LOAD0_DL
); break;
5748 case 0xc3: working
.write(LOAD0_BL
); break;
5749 case 0xc4: working
.write(LOAD0_AH
); break;
5750 case 0xc5: working
.write(LOAD0_CH
); break;
5751 case 0xc6: working
.write(LOAD0_DH
); break;
5752 case 0xc7: working
.write(LOAD0_BH
); break;
5755 private void load1_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5757 switch(modrm
& 0xc7) {
5758 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_BYTE
); break;
5760 case 0xc0: working
.write(LOAD1_AL
); break;
5761 case 0xc1: working
.write(LOAD1_CL
); break;
5762 case 0xc2: working
.write(LOAD1_DL
); break;
5763 case 0xc3: working
.write(LOAD1_BL
); break;
5764 case 0xc4: working
.write(LOAD1_AH
); break;
5765 case 0xc5: working
.write(LOAD1_CH
); break;
5766 case 0xc6: working
.write(LOAD1_DH
); break;
5767 case 0xc7: working
.write(LOAD1_BH
); break;
5770 private void store0_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5772 switch(modrm
& 0xc7) {
5773 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_BYTE
); break;
5775 case 0xc0: working
.write(STORE0_AL
); break;
5776 case 0xc1: working
.write(STORE0_CL
); break;
5777 case 0xc2: working
.write(STORE0_DL
); break;
5778 case 0xc3: working
.write(STORE0_BL
); break;
5779 case 0xc4: working
.write(STORE0_AH
); break;
5780 case 0xc5: working
.write(STORE0_CH
); break;
5781 case 0xc6: working
.write(STORE0_DH
); break;
5782 case 0xc7: working
.write(STORE0_BH
); break;
5785 private void store1_Eb(int prefices
, int modrm
, int sib
, int displacement
)
5787 switch(modrm
& 0xc7) {
5788 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_BYTE
); break;
5790 case 0xc0: working
.write(STORE1_AL
); break;
5791 case 0xc1: working
.write(STORE1_CL
); break;
5792 case 0xc2: working
.write(STORE1_DL
); break;
5793 case 0xc3: working
.write(STORE1_BL
); break;
5794 case 0xc4: working
.write(STORE1_AH
); break;
5795 case 0xc5: working
.write(STORE1_CH
); break;
5796 case 0xc6: working
.write(STORE1_DH
); break;
5797 case 0xc7: working
.write(STORE1_BH
); break;
5801 private void load0_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5803 switch (modrm
& 0xc7) {
5804 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_WORD
); break;
5806 case 0xc0: working
.write(LOAD0_AX
); break;
5807 case 0xc1: working
.write(LOAD0_CX
); break;
5808 case 0xc2: working
.write(LOAD0_DX
); break;
5809 case 0xc3: working
.write(LOAD0_BX
); break;
5810 case 0xc4: working
.write(LOAD0_SP
); break;
5811 case 0xc5: working
.write(LOAD0_BP
); break;
5812 case 0xc6: working
.write(LOAD0_SI
); break;
5813 case 0xc7: working
.write(LOAD0_DI
); break;
5816 private void store0_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5818 switch (modrm
& 0xc7) {
5819 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_WORD
); break;
5821 case 0xc0: working
.write(STORE0_AX
); break;
5822 case 0xc1: working
.write(STORE0_CX
); break;
5823 case 0xc2: working
.write(STORE0_DX
); break;
5824 case 0xc3: working
.write(STORE0_BX
); break;
5825 case 0xc4: working
.write(STORE0_SP
); break;
5826 case 0xc5: working
.write(STORE0_BP
); break;
5827 case 0xc6: working
.write(STORE0_SI
); break;
5828 case 0xc7: working
.write(STORE0_DI
); break;
5831 private void load1_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5833 switch (modrm
& 0xc7) {
5834 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_WORD
); break;
5836 case 0xc0: working
.write(LOAD1_AX
); break;
5837 case 0xc1: working
.write(LOAD1_CX
); break;
5838 case 0xc2: working
.write(LOAD1_DX
); break;
5839 case 0xc3: working
.write(LOAD1_BX
); break;
5840 case 0xc4: working
.write(LOAD1_SP
); break;
5841 case 0xc5: working
.write(LOAD1_BP
); break;
5842 case 0xc6: working
.write(LOAD1_SI
); break;
5843 case 0xc7: working
.write(LOAD1_DI
); break;
5846 private void store1_Ew(int prefices
, int modrm
, int sib
, int displacement
)
5848 switch (modrm
& 0xc7) {
5849 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_WORD
); break;
5851 case 0xc0: working
.write(STORE1_AX
); break;
5852 case 0xc1: working
.write(STORE1_CX
); break;
5853 case 0xc2: working
.write(STORE1_DX
); break;
5854 case 0xc3: working
.write(STORE1_BX
); break;
5855 case 0xc4: working
.write(STORE1_SP
); break;
5856 case 0xc5: working
.write(STORE1_BP
); break;
5857 case 0xc6: working
.write(STORE1_SI
); break;
5858 case 0xc7: working
.write(STORE1_DI
); break;
5862 private void load0_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5864 switch (modrm
& 0xc7) {
5865 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_DWORD
); break;
5867 case 0xc0: working
.write(LOAD0_EAX
); break;
5868 case 0xc1: working
.write(LOAD0_ECX
); break;
5869 case 0xc2: working
.write(LOAD0_EDX
); break;
5870 case 0xc3: working
.write(LOAD0_EBX
); break;
5871 case 0xc4: working
.write(LOAD0_ESP
); break;
5872 case 0xc5: working
.write(LOAD0_EBP
); break;
5873 case 0xc6: working
.write(LOAD0_ESI
); break;
5874 case 0xc7: working
.write(LOAD0_EDI
); break;
5878 private void store0_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5880 switch (modrm
& 0xc7) {
5881 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE0_MEM_DWORD
); break;
5883 case 0xc0: working
.write(STORE0_EAX
); break;
5884 case 0xc1: working
.write(STORE0_ECX
); break;
5885 case 0xc2: working
.write(STORE0_EDX
); break;
5886 case 0xc3: working
.write(STORE0_EBX
); break;
5887 case 0xc4: working
.write(STORE0_ESP
); break;
5888 case 0xc5: working
.write(STORE0_EBP
); break;
5889 case 0xc6: working
.write(STORE0_ESI
); break;
5890 case 0xc7: working
.write(STORE0_EDI
); break;
5893 private void load1_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5895 switch (modrm
& 0xc7) {
5896 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD1_MEM_DWORD
); break;
5898 case 0xc0: working
.write(LOAD1_EAX
); break;
5899 case 0xc1: working
.write(LOAD1_ECX
); break;
5900 case 0xc2: working
.write(LOAD1_EDX
); break;
5901 case 0xc3: working
.write(LOAD1_EBX
); break;
5902 case 0xc4: working
.write(LOAD1_ESP
); break;
5903 case 0xc5: working
.write(LOAD1_EBP
); break;
5904 case 0xc6: working
.write(LOAD1_ESI
); break;
5905 case 0xc7: working
.write(LOAD1_EDI
); break;
5909 private void store1_Ed(int prefices
, int modrm
, int sib
, int displacement
)
5911 switch (modrm
& 0xc7) {
5912 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(STORE1_MEM_DWORD
); break;
5914 case 0xc0: working
.write(STORE1_EAX
); break;
5915 case 0xc1: working
.write(STORE1_ECX
); break;
5916 case 0xc2: working
.write(STORE1_EDX
); break;
5917 case 0xc3: working
.write(STORE1_EBX
); break;
5918 case 0xc4: working
.write(STORE1_ESP
); break;
5919 case 0xc5: working
.write(STORE1_EBP
); break;
5920 case 0xc6: working
.write(STORE1_ESI
); break;
5921 case 0xc7: working
.write(STORE1_EDI
); break;
5925 private void load0_Eq(int prefices
, int modrm
, int sib
, int displacement
)
5927 switch (modrm
& 0xc7) {
5928 default: decodeM(prefices
, modrm
, sib
, displacement
); working
.write(LOAD0_MEM_QWORD
); break;
5937 throw new IllegalStateException("There are no 64bit GP Registers");
5941 private void load0_Gb(int modrm
)
5943 switch(modrm
& 0x38) {
5944 case 0x00: working
.write(LOAD0_AL
); break;
5945 case 0x08: working
.write(LOAD0_CL
); break;
5946 case 0x10: working
.write(LOAD0_DL
); break;
5947 case 0x18: working
.write(LOAD0_BL
); break;
5948 case 0x20: working
.write(LOAD0_AH
); break;
5949 case 0x28: working
.write(LOAD0_CH
); break;
5950 case 0x30: working
.write(LOAD0_DH
); break;
5951 case 0x38: working
.write(LOAD0_BH
); break;
5952 default: throw new IllegalStateException("Unknown Byte Register Operand");
5955 private void store0_Gb(int modrm
)
5957 switch(modrm
& 0x38) {
5958 case 0x00: working
.write(STORE0_AL
); break;
5959 case 0x08: working
.write(STORE0_CL
); break;
5960 case 0x10: working
.write(STORE0_DL
); break;
5961 case 0x18: working
.write(STORE0_BL
); break;
5962 case 0x20: working
.write(STORE0_AH
); break;
5963 case 0x28: working
.write(STORE0_CH
); break;
5964 case 0x30: working
.write(STORE0_DH
); break;
5965 case 0x38: working
.write(STORE0_BH
); break;
5966 default: throw new IllegalStateException("Unknown Byte Register Operand");
5969 private void load1_Gb(int modrm
)
5971 switch(modrm
& 0x38) {
5972 case 0x00: working
.write(LOAD1_AL
); break;
5973 case 0x08: working
.write(LOAD1_CL
); break;
5974 case 0x10: working
.write(LOAD1_DL
); break;
5975 case 0x18: working
.write(LOAD1_BL
); break;
5976 case 0x20: working
.write(LOAD1_AH
); break;
5977 case 0x28: working
.write(LOAD1_CH
); break;
5978 case 0x30: working
.write(LOAD1_DH
); break;
5979 case 0x38: working
.write(LOAD1_BH
); break;
5980 default: throw new IllegalStateException("Unknown Byte Register Operand");
5983 private void store1_Gb(int modrm
)
5985 switch(modrm
& 0x38) {
5986 case 0x00: working
.write(STORE1_AL
); break;
5987 case 0x08: working
.write(STORE1_CL
); break;
5988 case 0x10: working
.write(STORE1_DL
); break;
5989 case 0x18: working
.write(STORE1_BL
); break;
5990 case 0x20: working
.write(STORE1_AH
); break;
5991 case 0x28: working
.write(STORE1_CH
); break;
5992 case 0x30: working
.write(STORE1_DH
); break;
5993 case 0x38: working
.write(STORE1_BH
); break;
5994 default: throw new IllegalStateException("Unknown Byte Register Operand");
5998 private void load0_Gw(int modrm
)
6000 switch(modrm
& 0x38) {
6001 case 0x00: working
.write(LOAD0_AX
); break;
6002 case 0x08: working
.write(LOAD0_CX
); break;
6003 case 0x10: working
.write(LOAD0_DX
); break;
6004 case 0x18: working
.write(LOAD0_BX
); break;
6005 case 0x20: working
.write(LOAD0_SP
); break;
6006 case 0x28: working
.write(LOAD0_BP
); break;
6007 case 0x30: working
.write(LOAD0_SI
); break;
6008 case 0x38: working
.write(LOAD0_DI
); break;
6009 default: throw new IllegalStateException("Unknown Word Register Operand");
6012 private void store0_Gw(int modrm
)
6014 switch(modrm
& 0x38) {
6015 case 0x00: working
.write(STORE0_AX
); break;
6016 case 0x08: working
.write(STORE0_CX
); break;
6017 case 0x10: working
.write(STORE0_DX
); break;
6018 case 0x18: working
.write(STORE0_BX
); break;
6019 case 0x20: working
.write(STORE0_SP
); break;
6020 case 0x28: working
.write(STORE0_BP
); break;
6021 case 0x30: working
.write(STORE0_SI
); break;
6022 case 0x38: working
.write(STORE0_DI
); break;
6023 default: throw new IllegalStateException("Unknown Word Register Operand");
6026 private void load1_Gw(int modrm
)
6028 switch(modrm
& 0x38) {
6029 case 0x00: working
.write(LOAD1_AX
); break;
6030 case 0x08: working
.write(LOAD1_CX
); break;
6031 case 0x10: working
.write(LOAD1_DX
); break;
6032 case 0x18: working
.write(LOAD1_BX
); break;
6033 case 0x20: working
.write(LOAD1_SP
); break;
6034 case 0x28: working
.write(LOAD1_BP
); break;
6035 case 0x30: working
.write(LOAD1_SI
); break;
6036 case 0x38: working
.write(LOAD1_DI
); break;
6037 default: throw new IllegalStateException("Unknown Word Register Operand");
6040 private void store1_Gw(int modrm
)
6042 switch(modrm
& 0x38) {
6043 case 0x00: working
.write(STORE1_AX
); break;
6044 case 0x08: working
.write(STORE1_CX
); break;
6045 case 0x10: working
.write(STORE1_DX
); break;
6046 case 0x18: working
.write(STORE1_BX
); break;
6047 case 0x20: working
.write(STORE1_SP
); break;
6048 case 0x28: working
.write(STORE1_BP
); break;
6049 case 0x30: working
.write(STORE1_SI
); break;
6050 case 0x38: working
.write(STORE1_DI
); break;
6051 default: throw new IllegalStateException("Unknown Word Register Operand");
6055 private void load0_Gd(int modrm
)
6057 switch(modrm
& 0x38) {
6058 case 0x00: working
.write(LOAD0_EAX
); break;
6059 case 0x08: working
.write(LOAD0_ECX
); break;
6060 case 0x10: working
.write(LOAD0_EDX
); break;
6061 case 0x18: working
.write(LOAD0_EBX
); break;
6062 case 0x20: working
.write(LOAD0_ESP
); break;
6063 case 0x28: working
.write(LOAD0_EBP
); break;
6064 case 0x30: working
.write(LOAD0_ESI
); break;
6065 case 0x38: working
.write(LOAD0_EDI
); break;
6066 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6069 private void store0_Gd(int modrm
)
6071 switch(modrm
& 0x38) {
6072 case 0x00: working
.write(STORE0_EAX
); break;
6073 case 0x08: working
.write(STORE0_ECX
); break;
6074 case 0x10: working
.write(STORE0_EDX
); break;
6075 case 0x18: working
.write(STORE0_EBX
); break;
6076 case 0x20: working
.write(STORE0_ESP
); break;
6077 case 0x28: working
.write(STORE0_EBP
); break;
6078 case 0x30: working
.write(STORE0_ESI
); break;
6079 case 0x38: working
.write(STORE0_EDI
); break;
6080 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6083 private void load1_Gd(int modrm
)
6085 switch(modrm
& 0x38) {
6086 case 0x00: working
.write(LOAD1_EAX
); break;
6087 case 0x08: working
.write(LOAD1_ECX
); break;
6088 case 0x10: working
.write(LOAD1_EDX
); break;
6089 case 0x18: working
.write(LOAD1_EBX
); break;
6090 case 0x20: working
.write(LOAD1_ESP
); break;
6091 case 0x28: working
.write(LOAD1_EBP
); break;
6092 case 0x30: working
.write(LOAD1_ESI
); break;
6093 case 0x38: working
.write(LOAD1_EDI
); break;
6094 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6097 private void store1_Gd(int modrm
)
6099 switch(modrm
& 0x38) {
6100 case 0x00: working
.write(STORE1_EAX
); break;
6101 case 0x08: working
.write(STORE1_ECX
); break;
6102 case 0x10: working
.write(STORE1_EDX
); break;
6103 case 0x18: working
.write(STORE1_EBX
); break;
6104 case 0x20: working
.write(STORE1_ESP
); break;
6105 case 0x28: working
.write(STORE1_EBP
); break;
6106 case 0x30: working
.write(STORE1_ESI
); break;
6107 case 0x38: working
.write(STORE1_EDI
); break;
6108 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6112 private void load0_Sw(int modrm
)
6114 switch(modrm
& 0x38) {
6115 case 0x00: working
.write(LOAD0_ES
); break;
6116 case 0x08: working
.write(LOAD0_CS
); break;
6117 case 0x10: working
.write(LOAD0_SS
); break;
6118 case 0x18: working
.write(LOAD0_DS
); break;
6119 case 0x20: working
.write(LOAD0_FS
); break;
6120 case 0x28: working
.write(LOAD0_GS
); break;
6121 default: throw new IllegalStateException("Unknown Segment Register Operand");
6124 private void store0_Sw(int modrm
)
6126 switch(modrm
& 0x38) {
6127 case 0x00: working
.write(STORE0_ES
); break;
6128 case 0x08: working
.write(STORE0_CS
); break;
6129 case 0x10: working
.write(STORE0_SS
); break;
6130 case 0x18: working
.write(STORE0_DS
); break;
6131 case 0x20: working
.write(STORE0_FS
); break;
6132 case 0x28: working
.write(STORE0_GS
); break;
6133 default: throw new IllegalStateException("Unknown Segment Register Operand");
6137 private void decodeO(int prefices
, int displacement
)
6139 switch (prefices
& PREFICES_SG
) {
6141 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6142 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6143 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6144 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6145 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6146 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6149 if ((prefices
& PREFICES_ADDRESS
) != 0) {
6150 if (decodingAddressMode())
6151 working
.write(ADDR_ID
); working
.write(displacement
);
6153 if (decodingAddressMode()) {
6154 working
.write(ADDR_IW
); working
.write(displacement
);
6155 working
.write(ADDR_MASK16
);
6160 private void load0_Ob(int prefices
, int displacement
)
6162 decodeO(prefices
, displacement
);
6163 working
.write(LOAD0_MEM_BYTE
);
6165 private void store0_Ob(int prefices
, int displacement
)
6167 decodeO(prefices
, displacement
);
6168 working
.write(STORE0_MEM_BYTE
);
6171 private void load0_Ow(int prefices
, int displacement
)
6173 decodeO(prefices
, displacement
);
6174 working
.write(LOAD0_MEM_WORD
);
6176 private void store0_Ow(int prefices
, int displacement
)
6178 decodeO(prefices
, displacement
);
6179 working
.write(STORE0_MEM_WORD
);
6182 private void load0_Od(int prefices
, int displacement
)
6184 decodeO(prefices
, displacement
);
6185 working
.write(LOAD0_MEM_DWORD
);
6187 private void store0_Od(int prefices
, int displacement
)
6189 decodeO(prefices
, displacement
);
6190 working
.write(STORE0_MEM_DWORD
);
6193 private void load0_M(int prefices
, int modrm
, int sib
, int displacement
)
6195 decodeM(prefices
, modrm
, sib
, displacement
);
6196 working
.write(LOAD0_ADDR
);
6199 private void decodeM(int prefices
, int modrm
, int sib
, int displacement
)
6201 if (!decodingAddressMode()) return;
6203 if ((prefices
& PREFICES_ADDRESS
) != 0) {
6204 //32 bit address size
6207 switch (prefices
& PREFICES_SG
) {
6209 switch (modrm
& 0xc7) {
6210 default: working
.write(LOAD_SEG_DS
); break;
6213 case 0x84: break; //segment working.write will occur in decodeSIB
6215 case 0x85: working
.write(LOAD_SEG_SS
); break;
6218 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6219 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6220 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6221 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6222 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6223 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6227 switch(modrm
& 0x7) {
6228 case 0x0: working
.write(ADDR_EAX
); break;
6229 case 0x1: working
.write(ADDR_ECX
); break;
6230 case 0x2: working
.write(ADDR_EDX
); break;
6231 case 0x3: working
.write(ADDR_EBX
); break;
6232 case 0x4: decodeSIB(prefices
, modrm
, sib
, displacement
); break;
6234 if((modrm
& 0xc0) == 0x00) {
6235 working
.write(ADDR_ID
);
6236 working
.write(displacement
);
6238 working
.write(ADDR_EBP
);
6240 case 0x6: working
.write(ADDR_ESI
); break;
6241 case 0x7: working
.write(ADDR_EDI
); break;
6244 switch(modrm
& 0xc0) {
6245 case 0x40: working
.write(ADDR_IB
); working
.write(displacement
); break;
6246 case 0x80: working
.write(ADDR_ID
); working
.write(displacement
); break;
6249 //16 bit address size
6251 switch (prefices
& PREFICES_SG
) {
6253 switch (modrm
& 0xc7) {
6254 default: working
.write(LOAD_SEG_DS
); break;
6262 case 0x86: working
.write(LOAD_SEG_SS
); break;
6265 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6266 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6267 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6268 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6269 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6270 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6273 switch (modrm
& 0x7) {
6274 case 0x0: working
.write(ADDR_BX
); working
.write(ADDR_SI
); break;
6275 case 0x1: working
.write(ADDR_BX
); working
.write(ADDR_DI
); break;
6276 case 0x2: working
.write(ADDR_BP
); working
.write(ADDR_SI
); break;
6277 case 0x3: working
.write(ADDR_BP
); working
.write(ADDR_DI
); break;
6278 case 0x4: working
.write(ADDR_SI
); break;
6279 case 0x5: working
.write(ADDR_DI
); break;
6281 if ((modrm
& 0xc0) == 0x00) {
6282 working
.write(ADDR_IW
);
6283 working
.write(displacement
);
6285 working
.write(ADDR_BP
);
6288 case 0x7: working
.write(ADDR_BX
); break;
6291 switch (modrm
& 0xc0) {
6292 case 0x40: working
.write(ADDR_IB
); working
.write(displacement
); break;
6293 case 0x80: working
.write(ADDR_IW
); working
.write(displacement
); break;
6295 working
.write(ADDR_MASK16
);
6299 private void decodeSIB(int prefices
, int modrm
, int sib
, int displacement
)
6301 switch (prefices
& PREFICES_SG
) {
6303 switch (sib
& 0x7) {
6304 default: working
.write(LOAD_SEG_DS
); break;
6305 case 0x4: working
.write(LOAD_SEG_SS
); break;
6307 switch (modrm
& 0xc0) {
6308 default: working
.write(LOAD_SEG_SS
); break;
6309 case 0x00: working
.write(LOAD_SEG_DS
); break;
6312 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6313 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6314 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6315 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6316 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6317 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6321 switch (sib
& 0x7) {
6322 case 0x0: working
.write(ADDR_EAX
); break;
6323 case 0x1: working
.write(ADDR_ECX
); break;
6324 case 0x2: working
.write(ADDR_EDX
); break;
6325 case 0x3: working
.write(ADDR_EBX
); break;
6326 case 0x4: working
.write(ADDR_ESP
); break;
6328 switch (modrm
& 0xc0) {
6329 default: working
.write(ADDR_EBP
); break;
6330 case 0x00: working
.write(ADDR_ID
); working
.write(displacement
); break;
6332 case 0x6: working
.write(ADDR_ESI
); break;
6333 case 0x7: working
.write(ADDR_EDI
); break;
6337 switch (sib
& 0xf8) {
6338 case 0x00: working
.write(ADDR_EAX
); break;
6339 case 0x08: working
.write(ADDR_ECX
); break;
6340 case 0x10: working
.write(ADDR_EDX
); break;
6341 case 0x18: working
.write(ADDR_EBX
); break;
6342 case 0x20: break; //none
6343 case 0x28: working
.write(ADDR_EBP
); break;
6344 case 0x30: working
.write(ADDR_ESI
); break;
6345 case 0x38: working
.write(ADDR_EDI
); break;
6347 case 0x40: working
.write(ADDR_2EAX
); break;
6348 case 0x48: working
.write(ADDR_2ECX
); break;
6349 case 0x50: working
.write(ADDR_2EDX
); break;
6350 case 0x58: working
.write(ADDR_2EBX
); break;
6351 case 0x60: break; //none
6352 case 0x68: working
.write(ADDR_2EBP
); break;
6353 case 0x70: working
.write(ADDR_2ESI
); break;
6354 case 0x78: working
.write(ADDR_2EDI
); break;
6356 case 0x80: working
.write(ADDR_4EAX
); break;
6357 case 0x88: working
.write(ADDR_4ECX
); break;
6358 case 0x90: working
.write(ADDR_4EDX
); break;
6359 case 0x98: working
.write(ADDR_4EBX
); break;
6360 case 0xa0: break; //none
6361 case 0xa8: working
.write(ADDR_4EBP
); break;
6362 case 0xb0: working
.write(ADDR_4ESI
); break;
6363 case 0xb8: working
.write(ADDR_4EDI
); break;
6365 case 0xc0: working
.write(ADDR_8EAX
); break;
6366 case 0xc8: working
.write(ADDR_8ECX
); break;
6367 case 0xd0: working
.write(ADDR_8EDX
); break;
6368 case 0xd8: working
.write(ADDR_8EBX
); break;
6369 case 0xe0: break; //none
6370 case 0xe8: working
.write(ADDR_8EBP
); break;
6371 case 0xf0: working
.write(ADDR_8ESI
); break;
6372 case 0xf8: working
.write(ADDR_8EDI
); break;
6376 private void decodeSegmentPrefix(int prefices
)
6378 switch (prefices
& PREFICES_SG
) {
6380 case PREFICES_DS
: working
.write(LOAD_SEG_DS
); break;
6381 case PREFICES_ES
: working
.write(LOAD_SEG_ES
); break;
6382 case PREFICES_SS
: working
.write(LOAD_SEG_SS
); break;
6383 case PREFICES_CS
: working
.write(LOAD_SEG_CS
); break;
6384 case PREFICES_FS
: working
.write(LOAD_SEG_FS
); break;
6385 case PREFICES_GS
: working
.write(LOAD_SEG_GS
); break;
6389 private void store0_Rd(int modrm
)
6391 switch (modrm
& 0xc7) {
6392 case 0xc0: working
.write(STORE0_EAX
); break;
6393 case 0xc1: working
.write(STORE0_ECX
); break;
6394 case 0xc2: working
.write(STORE0_EDX
); break;
6395 case 0xc3: working
.write(STORE0_EBX
); break;
6396 case 0xc4: working
.write(STORE0_ESP
); break;
6397 case 0xc5: working
.write(STORE0_EBP
); break;
6398 case 0xc6: working
.write(STORE0_ESI
); break;
6399 case 0xc7: working
.write(STORE0_EDI
); break;
6400 default: throw new IllegalStateException("Rd cannot be a memory location");
6404 private void load0_Rd(int modrm
)
6406 switch (modrm
& 0xc7) {
6407 case 0xc0: working
.write(LOAD0_EAX
); break;
6408 case 0xc1: working
.write(LOAD0_ECX
); break;
6409 case 0xc2: working
.write(LOAD0_EDX
); break;
6410 case 0xc3: working
.write(LOAD0_EBX
); break;
6411 case 0xc4: working
.write(LOAD0_ESP
); break;
6412 case 0xc5: working
.write(LOAD0_EBP
); break;
6413 case 0xc6: working
.write(LOAD0_ESI
); break;
6414 case 0xc7: working
.write(LOAD0_EDI
); break;
6415 default: throw new IllegalStateException("Rd cannot be a memory location");
6419 private static class Operation
6421 private int[] microcodes
;
6422 private int microcodesLength
;
6423 private int x86Length
;
6424 private int readOffset
;
6425 private boolean decoded
;
6426 private boolean terminal
;
6430 microcodes
= new int[10];
6433 void write(int microcode
)
6436 microcodes
[microcodesLength
] = microcode
;
6438 } catch (ArrayIndexOutOfBoundsException e
) {
6439 int[] temp
= new int[2*microcodes
.length
];
6440 System
.arraycopy(microcodes
, 0, temp
, 0, microcodes
.length
);
6442 microcodes
[microcodesLength
++] = microcode
;
6446 void replace(int offset
, int microcode
)
6448 microcodes
[offset
] = microcode
;
6451 void finish(int x86Length
)
6453 this.x86Length
= x86Length
;
6475 microcodesLength
= 0;
6482 int getMicrocodeAt(int offset
)
6484 return microcodes
[offset
];
6489 if (readOffset
< microcodesLength
)
6490 return microcodes
[readOffset
++];
6492 System
.err
.println("Critical error: Attempted read outside microcode array.");
6493 throw new IllegalStateException("Attempted read outside microcode array");
6499 return microcodesLength
;