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