ReactOS  0.4.15-dev-3017-g1d9542d
opgroups.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

 FAST486_OPCODE_HANDLER (Fast486OpcodeGroup8082)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroup81)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroup83)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroup8F)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupC0)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupC1)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupC6)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupC7)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupD0)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupD1)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupD2)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupD3)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupF6)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupF7)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupFE)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeGroupFF)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeGroup0F00)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeGroup0F01)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeGroup0FB9)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeGroup0FBA)
 

Function Documentation

◆ FAST486_OPCODE_HANDLER() [1/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroup8082  )

Definition at line 299 of file opgroups.c.

300 {
301  UCHAR Immediate, Value;
302  FAST486_MOD_REG_RM ModRegRm;
303  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
304 
305  TOGGLE_ADSIZE(AddressSize);
306 
307  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
308  {
309  /* Exception occurred */
310  return;
311  }
312 
313  /* Fetch the immediate operand */
314  if (!Fast486FetchByte(State, &Immediate))
315  {
316  /* Exception occurred */
317  return;
318  }
319 
320  /* Read the operands */
321  if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
322  {
323  /* Exception occurred */
324  return;
325  }
326 
327  /* Calculate the result */
328  Value = Fast486ArithmeticOperation(State, ModRegRm.Register, Value, Immediate, 8);
329 
330  /* Unless this is CMP, write back the result */
331  if (ModRegRm.Register != 7)
332  {
333  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
334  }
335 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
static ULONG Fast486ArithmeticOperation(PFAST486_STATE State, INT Operation, ULONG FirstValue, ULONG SecondValue, UCHAR Bits)
Definition: opgroups.c:38
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181
#define NULL
Definition: types.h:112

◆ FAST486_OPCODE_HANDLER() [2/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroup81  )

Definition at line 337 of file opgroups.c.

338 {
339  FAST486_MOD_REG_RM ModRegRm;
340  BOOLEAN OperandSize, AddressSize;
341 
342  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
343 
344  TOGGLE_OPSIZE(OperandSize);
345  TOGGLE_ADSIZE(AddressSize);
346 
347  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
348  {
349  /* Exception occurred */
350  return;
351  }
352 
353  if (OperandSize)
354  {
355  ULONG Immediate, Value;
356 
357  /* Fetch the immediate operand */
358  if (!Fast486FetchDword(State, &Immediate))
359  {
360  /* Exception occurred */
361  return;
362  }
363 
364  /* Read the operands */
365  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
366  {
367  /* Exception occurred */
368  return;
369  }
370 
371  /* Calculate the result */
372  Value = Fast486ArithmeticOperation(State, ModRegRm.Register, Value, Immediate, 32);
373 
374  /* Unless this is CMP, write back the result */
375  if (ModRegRm.Register != 7)
376  {
377  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
378  }
379  }
380  else
381  {
382  USHORT Immediate, Value;
383 
384  /* Fetch the immediate operand */
385  if (!Fast486FetchWord(State, &Immediate))
386  {
387  /* Exception occurred */
388  return;
389  }
390 
391  /* Read the operands */
392  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
393  {
394  /* Exception occurred */
395  return;
396  }
397 
398  /* Calculate the result */
399  Value = Fast486ArithmeticOperation(State, ModRegRm.Register, Value, Immediate, 16);
400 
401  /* Unless this is CMP, write back the result */
402  if (ModRegRm.Register != 7)
403  {
404  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
405  }
406  }
407 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
static ULONG Fast486ArithmeticOperation(PFAST486_STATE State, INT Operation, ULONG FirstValue, ULONG SecondValue, UCHAR Bits)
Definition: opgroups.c:38
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

◆ FAST486_OPCODE_HANDLER() [3/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroup83  )

Definition at line 409 of file opgroups.c.

410 {
411  CHAR ImmByte;
412  FAST486_MOD_REG_RM ModRegRm;
413  BOOLEAN OperandSize, AddressSize;
414 
415  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
416 
417  TOGGLE_OPSIZE(OperandSize);
418  TOGGLE_ADSIZE(AddressSize);
419 
420  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
421  {
422  /* Exception occurred */
423  return;
424  }
425 
426  /* Fetch the immediate operand */
427  if (!Fast486FetchByte(State, (PUCHAR)&ImmByte))
428  {
429  /* Exception occurred */
430  return;
431  }
432 
433  if (OperandSize)
434  {
435  ULONG Immediate = (ULONG)((LONG)ImmByte); // Sign extend
436  ULONG Value;
437 
438  /* Read the operands */
439  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
440  {
441  /* Exception occurred */
442  return;
443  }
444 
445  /* Calculate the result */
446  Value = Fast486ArithmeticOperation(State, ModRegRm.Register, Value, Immediate, 32);
447 
448  /* Unless this is CMP, write back the result */
449  if (ModRegRm.Register != 7)
450  {
451  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
452  }
453  }
454  else
455  {
456  USHORT Immediate = (USHORT)((SHORT)ImmByte); // Sign extend
457  USHORT Value;
458 
459  /* Read the operands */
460  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
461  {
462  /* Exception occurred */
463  return;
464  }
465 
466  /* Calculate the result */
467  Value = Fast486ArithmeticOperation(State, ModRegRm.Register, Value, Immediate, 16);
468 
469  /* Unless this is CMP, write back the result */
470  if (ModRegRm.Register != 7)
471  {
472  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
473  }
474  }
475 }
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
short SHORT
Definition: pedump.c:59
unsigned char BOOLEAN
static ULONG Fast486ArithmeticOperation(PFAST486_STATE State, INT Operation, ULONG FirstValue, ULONG SecondValue, UCHAR Bits)
Definition: opgroups.c:38
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

◆ FAST486_OPCODE_HANDLER() [4/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroup8F  )

Definition at line 477 of file opgroups.c.

478 {
479  ULONG Value;
480  FAST486_MOD_REG_RM ModRegRm;
481  BOOLEAN OperandSize, AddressSize;
482 
483  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
484 
485  TOGGLE_OPSIZE(OperandSize);
486  TOGGLE_ADSIZE(AddressSize);
487 
488  /* Pop a value from the stack - this must be done first */
489  if (!Fast486StackPop(State, &Value))
490  {
491  /* Exception occurred */
492  return;
493  }
494 
495  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
496  {
497  /* Exception occurred */
498  return;
499  }
500 
501  if (ModRegRm.Register != 0)
502  {
503  /* Invalid */
504  Fast486Exception(State, FAST486_EXCEPTION_UD);
505  return;
506  }
507 
508  if (OperandSize) Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
509  else Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(Value));
510 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned int ULONG
Definition: retypes.h:1
#define LOWORD(l)
Definition: pedump.c:82

◆ FAST486_OPCODE_HANDLER() [5/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupC0  )

Definition at line 512 of file opgroups.c.

513 {
514  UCHAR Value, Count;
515  FAST486_MOD_REG_RM ModRegRm;
516  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
517 
518  TOGGLE_ADSIZE(AddressSize);
519 
520  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
521  {
522  /* Exception occurred */
523  return;
524  }
525 
526  /* Fetch the count */
527  if (!Fast486FetchByte(State, &Count))
528  {
529  /* Exception occurred */
530  return;
531  }
532 
533  /* Read the operands */
534  if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
535  {
536  /* Exception occurred */
537  return;
538  }
539 
540  /* Calculate the result */
542  ModRegRm.Register,
543  Value,
544  8,
545  Count));
546 
547  /* Write back the result */
548  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
549 }
#define LOBYTE(W)
Definition: jmemdos.c:487
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
int Count
Definition: noreturn.cpp:7
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181
static ULONG Fast486RotateOperation(PFAST486_STATE State, INT Operation, ULONG Value, UCHAR Bits, UCHAR Count)
Definition: opgroups.c:162
#define NULL
Definition: types.h:112

◆ FAST486_OPCODE_HANDLER() [6/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupC1  )

Definition at line 551 of file opgroups.c.

552 {
553  UCHAR Count;
554  FAST486_MOD_REG_RM ModRegRm;
555  BOOLEAN OperandSize, AddressSize;
556 
557  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
558 
559  TOGGLE_OPSIZE(OperandSize);
560  TOGGLE_ADSIZE(AddressSize);
561 
562  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
563  {
564  /* Exception occurred */
565  return;
566  }
567 
568  /* Fetch the count */
569  if (!Fast486FetchByte(State, &Count))
570  {
571  /* Exception occurred */
572  return;
573  }
574 
575  if (OperandSize)
576  {
577  ULONG Value;
578 
579  /* Read the operands */
580  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
581  {
582  /* Exception occurred */
583  return;
584  }
585 
586  /* Calculate the result */
588  ModRegRm.Register,
589  Value,
590  32,
591  Count);
592 
593  /* Write back the result */
594  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
595  }
596  else
597  {
598  USHORT Value;
599 
600  /* Read the operands */
601  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
602  {
603  /* Exception occurred */
604  return;
605  }
606 
607  /* Calculate the result */
609  ModRegRm.Register,
610  Value,
611  16,
612  Count));
613 
614  /* Write back the result */
615  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
616  }
617 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
int Count
Definition: noreturn.cpp:7
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181
static ULONG Fast486RotateOperation(PFAST486_STATE State, INT Operation, ULONG Value, UCHAR Bits, UCHAR Count)
Definition: opgroups.c:162
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define LOWORD(l)
Definition: pedump.c:82

◆ FAST486_OPCODE_HANDLER() [7/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupC6  )

Definition at line 619 of file opgroups.c.

620 {
621  UCHAR Immediate;
622  FAST486_MOD_REG_RM ModRegRm;
623  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
624 
625  TOGGLE_ADSIZE(AddressSize);
626 
627  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
628  {
629  /* Exception occurred */
630  return;
631  }
632 
633  if (ModRegRm.Register != 0)
634  {
635  /* Invalid */
636  Fast486Exception(State, FAST486_EXCEPTION_UD);
637  return;
638  }
639 
640  /* Get the immediate operand */
641  if (!Fast486FetchByte(State, &Immediate))
642  {
643  /* Exception occurred */
644  return;
645  }
646 
647  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Immediate);
648 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ FAST486_OPCODE_HANDLER() [8/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupC7  )

Definition at line 650 of file opgroups.c.

651 {
652  FAST486_MOD_REG_RM ModRegRm;
653  BOOLEAN OperandSize, AddressSize;
654 
655  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
656 
657  TOGGLE_OPSIZE(OperandSize);
658  TOGGLE_ADSIZE(AddressSize);
659 
660  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
661  {
662  /* Exception occurred */
663  return;
664  }
665 
666  if (ModRegRm.Register != 0)
667  {
668  /* Invalid */
669  Fast486Exception(State, FAST486_EXCEPTION_UD);
670  return;
671  }
672 
673  if (OperandSize)
674  {
675  ULONG Immediate;
676 
677  /* Get the immediate operand */
678  if (!Fast486FetchDword(State, &Immediate))
679  {
680  /* Exception occurred */
681  return;
682  }
683 
684  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Immediate);
685  }
686  else
687  {
688  USHORT Immediate;
689 
690  /* Get the immediate operand */
691  if (!Fast486FetchWord(State, &Immediate))
692  {
693  /* Exception occurred */
694  return;
695  }
696 
697  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Immediate);
698  }
699 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1

◆ FAST486_OPCODE_HANDLER() [9/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupD0  )

Definition at line 701 of file opgroups.c.

702 {
703  UCHAR Value;
704  FAST486_MOD_REG_RM ModRegRm;
705  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
706 
707  TOGGLE_ADSIZE(AddressSize);
708 
709  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
710  {
711  /* Exception occurred */
712  return;
713  }
714 
715  /* Read the operands */
716  if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
717  {
718  /* Exception occurred */
719  return;
720  }
721 
722  /* Calculate the result */
723  Value = LOBYTE(Fast486RotateOperation(State, ModRegRm.Register, Value, 8, 1));
724 
725  /* Write back the result */
726  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
727 
728 }
#define LOBYTE(W)
Definition: jmemdos.c:487
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181
static ULONG Fast486RotateOperation(PFAST486_STATE State, INT Operation, ULONG Value, UCHAR Bits, UCHAR Count)
Definition: opgroups.c:162
#define NULL
Definition: types.h:112

◆ FAST486_OPCODE_HANDLER() [10/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupD1  )

Definition at line 730 of file opgroups.c.

731 {
732  FAST486_MOD_REG_RM ModRegRm;
733  BOOLEAN OperandSize, AddressSize;
734 
735  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
736 
737  TOGGLE_OPSIZE(OperandSize);
738  TOGGLE_ADSIZE(AddressSize);
739 
740  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
741  {
742  /* Exception occurred */
743  return;
744  }
745 
746  if (OperandSize)
747  {
748  ULONG Value;
749 
750  /* Read the operands */
751  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
752  {
753  /* Exception occurred */
754  return;
755  }
756 
757  /* Calculate the result */
758  Value = Fast486RotateOperation(State, ModRegRm.Register, Value, 32, 1);
759 
760  /* Write back the result */
761  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
762  }
763  else
764  {
765  USHORT Value;
766 
767  /* Read the operands */
768  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
769  {
770  /* Exception occurred */
771  return;
772  }
773 
774  /* Calculate the result */
775  Value = LOWORD(Fast486RotateOperation(State, ModRegRm.Register, Value, 16, 1));
776 
777  /* Write back the result */
778  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
779  }
780 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
static ULONG Fast486RotateOperation(PFAST486_STATE State, INT Operation, ULONG Value, UCHAR Bits, UCHAR Count)
Definition: opgroups.c:162
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define LOWORD(l)
Definition: pedump.c:82

◆ FAST486_OPCODE_HANDLER() [11/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupD2  )

Definition at line 782 of file opgroups.c.

783 {
784  UCHAR Value;
785  FAST486_MOD_REG_RM ModRegRm;
786  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
787 
788  TOGGLE_ADSIZE(AddressSize);
789 
790  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
791  {
792  /* Exception occurred */
793  return;
794  }
795 
796  /* Read the operands */
797  if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
798  {
799  /* Exception occurred */
800  return;
801  }
802 
803  /* Calculate the result */
805  ModRegRm.Register,
806  Value,
807  8,
808  State->GeneralRegs[FAST486_REG_ECX].LowByte));
809 
810  /* Write back the result */
811  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
812 }
#define LOBYTE(W)
Definition: jmemdos.c:487
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181
static ULONG Fast486RotateOperation(PFAST486_STATE State, INT Operation, ULONG Value, UCHAR Bits, UCHAR Count)
Definition: opgroups.c:162
#define NULL
Definition: types.h:112

◆ FAST486_OPCODE_HANDLER() [12/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupD3  )

Definition at line 814 of file opgroups.c.

815 {
816  FAST486_MOD_REG_RM ModRegRm;
817  BOOLEAN OperandSize, AddressSize;
818 
819  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
820 
821  TOGGLE_OPSIZE(OperandSize);
822  TOGGLE_ADSIZE(AddressSize);
823 
824  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
825  {
826  /* Exception occurred */
827  return;
828  }
829 
830  if (OperandSize)
831  {
832  ULONG Value;
833 
834  /* Read the operands */
835  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
836  {
837  /* Exception occurred */
838  return;
839  }
840 
841  /* Calculate the result */
843  ModRegRm.Register,
844  Value,
845  32,
846  State->GeneralRegs[FAST486_REG_ECX].LowByte);
847 
848  /* Write back the result */
849  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
850  }
851  else
852  {
853  USHORT Value;
854 
855  /* Read the operands */
856  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
857  {
858  /* Exception occurred */
859  return;
860  }
861 
862  /* Calculate the result */
864  ModRegRm.Register,
865  Value,
866  16,
867  State->GeneralRegs[FAST486_REG_ECX].LowByte));
868 
869  /* Write back the result */
870  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
871  }
872 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
static ULONG Fast486RotateOperation(PFAST486_STATE State, INT Operation, ULONG Value, UCHAR Bits, UCHAR Count)
Definition: opgroups.c:162
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define LOWORD(l)
Definition: pedump.c:82

◆ FAST486_OPCODE_HANDLER() [13/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupF6  )

Definition at line 874 of file opgroups.c.

875 {
876  UCHAR Value = 0;
877  FAST486_MOD_REG_RM ModRegRm;
878  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
879 
880  TOGGLE_ADSIZE(AddressSize);
881 
882  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
883  {
884  /* Exception occurred */
885  return;
886  }
887 
888  /* Read the operands */
889  if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
890  {
891  /* Exception occurred */
892  return;
893  }
894 
895  switch (ModRegRm.Register)
896  {
897  /* TEST */
898  case 0:
899  case 1:
900  {
901  UCHAR Immediate, Result;
902 
903  /* Fetch the immediate byte */
904  if (!Fast486FetchByte(State, &Immediate))
905  {
906  /* Exception occurred */
907  return;
908  }
909 
910  /* Calculate the result */
911  Result = Value & Immediate;
912 
913  /* Update the flags */
914  State->Flags.Cf = FALSE;
915  State->Flags.Of = FALSE;
916  State->Flags.Zf = (Result == 0);
917  State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
918  State->Flags.Pf = Fast486CalculateParity(Result);
919 
920  break;
921  }
922 
923  /* NOT */
924  case 2:
925  {
926  /* Write back the result */
927  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, ~Value);
928 
929  break;
930  }
931 
932  /* NEG */
933  case 3:
934  {
935  /* Calculate the result */
936  UCHAR Result = -Value;
937 
938  /* Update the flags */
939  State->Flags.Cf = (Value != 0);
940  State->Flags.Of = (Value & SIGN_FLAG_BYTE) && (Result & SIGN_FLAG_BYTE);
941  State->Flags.Af = ((Value & 0x0F) != 0);
942  State->Flags.Zf = (Result == 0);
943  State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
944  State->Flags.Pf = Fast486CalculateParity(Result);
945 
946  /* Write back the result */
947  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Result);
948 
949  break;
950  }
951 
952  /* MUL */
953  case 4:
954  {
955  USHORT Result = (USHORT)Value * (USHORT)State->GeneralRegs[FAST486_REG_EAX].LowByte;
956 
957  /* Update the flags */
958  State->Flags.Cf = State->Flags.Of = (HIBYTE(Result) != 0);
959 
960  /* Write back the result */
961  State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
962 
963  break;
964  }
965 
966  /* IMUL */
967  case 5:
968  {
969  SHORT Result = (SHORT)((CHAR)Value) * (SHORT)((CHAR)State->GeneralRegs[FAST486_REG_EAX].LowByte);
970 
971  /* Update the flags */
972  State->Flags.Cf = State->Flags.Of = ((Result < FAST486_CHAR_MIN) || (Result > FAST486_CHAR_MAX));
973 
974  /* Write back the result */
975  State->GeneralRegs[FAST486_REG_EAX].LowWord = (USHORT)Result;
976 
977  break;
978  }
979 
980  /* DIV */
981  case 6:
982  {
983  USHORT Quotient;
985 
986  if (Value == 0)
987  {
988  /* Divide error */
989  Fast486Exception(State, FAST486_EXCEPTION_DE);
990  return;
991  }
992 
993  Quotient = State->GeneralRegs[FAST486_REG_EAX].LowWord / Value;
994  Remainder = State->GeneralRegs[FAST486_REG_EAX].LowWord % Value;
995 
996  if (Quotient > 0xFF)
997  {
998  /* Divide error */
999  Fast486Exception(State, FAST486_EXCEPTION_DE);
1000  return;
1001  }
1002 
1003  /* Write back the results */
1004  State->GeneralRegs[FAST486_REG_EAX].LowByte = (UCHAR)Quotient;
1005  State->GeneralRegs[FAST486_REG_EAX].HighByte = Remainder;
1006 
1007  break;
1008  }
1009 
1010  /* IDIV */
1011  case 7:
1012  {
1013  SHORT Quotient;
1014  CHAR Remainder;
1015 
1016  if (Value == 0)
1017  {
1018  /* Divide error */
1019  Fast486Exception(State, FAST486_EXCEPTION_DE);
1020  return;
1021  }
1022 
1023  Quotient = (SHORT)State->GeneralRegs[FAST486_REG_EAX].LowWord / (CHAR)Value;
1024  Remainder = (SHORT)State->GeneralRegs[FAST486_REG_EAX].LowWord % (CHAR)Value;
1025 
1026  if (Quotient > FAST486_CHAR_MAX || Quotient < FAST486_CHAR_MIN)
1027  {
1028  /* Divide error */
1029  Fast486Exception(State, FAST486_EXCEPTION_DE);
1030  return;
1031  }
1032 
1033  /* Write back the results */
1034  State->GeneralRegs[FAST486_REG_EAX].LowByte = (UCHAR)((CHAR)Quotient);
1035  State->GeneralRegs[FAST486_REG_EAX].HighByte = (UCHAR)Remainder;
1036 
1037  break;
1038  }
1039  }
1040 }
char CHAR
Definition: xmlstorage.h:175
#define FAST486_CHAR_MIN
Definition: fast486.h:33
#define HIBYTE(W)
Definition: jmemdos.c:486
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
short SHORT
Definition: pedump.c:59
#define SIGN_FLAG_BYTE
Definition: common.h:29
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
#define FAST486_CHAR_MAX
Definition: fast486.h:34
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
#define CHAR(Char)
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3044

◆ FAST486_OPCODE_HANDLER() [14/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupF7  )

Definition at line 1042 of file opgroups.c.

1043 {
1044  ULONG Value = 0, SignFlag;
1045  FAST486_MOD_REG_RM ModRegRm;
1046  BOOLEAN OperandSize, AddressSize;
1047 
1048  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1049 
1050  TOGGLE_OPSIZE(OperandSize);
1051  TOGGLE_ADSIZE(AddressSize);
1052 
1053  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1054  {
1055  /* Exception occurred */
1056  return;
1057  }
1058 
1059  /* Set the sign flag */
1060  if (OperandSize) SignFlag = SIGN_FLAG_LONG;
1061  else SignFlag = SIGN_FLAG_WORD;
1062 
1063  /* Read the operand */
1064  if (OperandSize)
1065  {
1066  /* 32-bit */
1067  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
1068  {
1069  /* Exception occurred */
1070  return;
1071  }
1072  }
1073  else
1074  {
1075  /* 16-bit */
1076  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, (PUSHORT)&Value))
1077  {
1078  /* Exception occurred */
1079  return;
1080  }
1081  }
1082 
1083  switch (ModRegRm.Register)
1084  {
1085  /* TEST */
1086  case 0:
1087  case 1:
1088  {
1089  ULONG Immediate = 0, Result = 0;
1090 
1091  if (OperandSize)
1092  {
1093  /* Fetch the immediate dword */
1094  if (!Fast486FetchDword(State, &Immediate))
1095  {
1096  /* Exception occurred */
1097  return;
1098  }
1099  }
1100  else
1101  {
1102  /* Fetch the immediate word */
1103  if (!Fast486FetchWord(State, (PUSHORT)&Immediate))
1104  {
1105  /* Exception occurred */
1106  return;
1107  }
1108  }
1109 
1110  /* Calculate the result */
1111  Result = Value & Immediate;
1112 
1113  /* Update the flags */
1114  State->Flags.Cf = FALSE;
1115  State->Flags.Of = FALSE;
1116  State->Flags.Zf = (Result == 0);
1117  State->Flags.Sf = ((Result & SignFlag) != 0);
1118  State->Flags.Pf = Fast486CalculateParity(Result);
1119 
1120  break;
1121  }
1122 
1123  /* NOT */
1124  case 2:
1125  {
1126  /* Write back the result */
1127  if (OperandSize)
1128  {
1129  /* 32-bit */
1130  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, ~Value);
1131  }
1132  else
1133  {
1134  /* 16-bit */
1135  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(~Value));
1136  }
1137 
1138  break;
1139  }
1140 
1141  /* NEG */
1142  case 3:
1143  {
1144  /* Calculate the result */
1145  ULONG Result = -(LONG)Value;
1146  if (!OperandSize) Result &= 0xFFFF;
1147 
1148  /* Update the flags */
1149  State->Flags.Cf = (Value != 0);
1150  State->Flags.Of = (Value & SignFlag) && (Result & SignFlag);
1151  State->Flags.Af = ((Value & 0x0F) != 0);
1152  State->Flags.Zf = (Result == 0);
1153  State->Flags.Sf = ((Result & SignFlag) != 0);
1154  State->Flags.Pf = Fast486CalculateParity(Result);
1155 
1156  /* Write back the result */
1157  if (OperandSize)
1158  {
1159  /* 32-bit */
1160  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
1161  }
1162  else
1163  {
1164  /* 16-bit */
1165  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(Result));
1166  }
1167 
1168  break;
1169  }
1170 
1171  /* MUL */
1172  case 4:
1173  {
1174  if (OperandSize)
1175  {
1176  ULONGLONG Result = (ULONGLONG)Value * (ULONGLONG)State->GeneralRegs[FAST486_REG_EAX].Long;
1177 
1178  /* Update the flags */
1179  State->Flags.Cf = State->Flags.Of = ((Result & 0xFFFFFFFF00000000ULL) != 0);
1180 
1181  /* Write back the result */
1182  State->GeneralRegs[FAST486_REG_EAX].Long = Result & 0xFFFFFFFFULL;
1183  State->GeneralRegs[FAST486_REG_EDX].Long = Result >> 32;
1184  }
1185  else
1186  {
1187  ULONG Result = (ULONG)Value * (ULONG)State->GeneralRegs[FAST486_REG_EAX].LowWord;
1188 
1189  /* Update the flags */
1190  State->Flags.Cf = State->Flags.Of = (HIWORD(Result) != 0);
1191 
1192  /* Write back the result */
1193  State->GeneralRegs[FAST486_REG_EAX].LowWord = LOWORD(Result);
1194  State->GeneralRegs[FAST486_REG_EDX].LowWord = HIWORD(Result);
1195  }
1196 
1197  break;
1198  }
1199 
1200  /* IMUL */
1201  case 5:
1202  {
1203  if (OperandSize)
1204  {
1205  LONGLONG Result = (LONGLONG)((LONG)Value) * (LONGLONG)((LONG)State->GeneralRegs[FAST486_REG_EAX].Long);
1206 
1207  /* Update the flags */
1208  State->Flags.Cf = State->Flags.Of = ((Result < FAST486_LONG_MIN) || (Result > FAST486_LONG_MAX));
1209 
1210  /* Write back the result */
1211  State->GeneralRegs[FAST486_REG_EAX].Long = Result & 0xFFFFFFFFULL;
1212  State->GeneralRegs[FAST486_REG_EDX].Long = Result >> 32;
1213  }
1214  else
1215  {
1216  LONG Result = (LONG)((SHORT)Value) * (LONG)((SHORT)State->GeneralRegs[FAST486_REG_EAX].LowWord);
1217 
1218  /* Update the flags */
1219  State->Flags.Cf = State->Flags.Of = ((Result < FAST486_SHORT_MIN) || (Result > FAST486_SHORT_MAX));
1220 
1221  /* Write back the result */
1222  State->GeneralRegs[FAST486_REG_EAX].LowWord = LOWORD(Result);
1223  State->GeneralRegs[FAST486_REG_EDX].LowWord = HIWORD(Result);
1224  }
1225 
1226  break;
1227  }
1228 
1229  /* DIV */
1230  case 6:
1231  {
1232  if (Value == 0)
1233  {
1234  /* Divide error */
1235  Fast486Exception(State, FAST486_EXCEPTION_DE);
1236  return;
1237  }
1238 
1239  if (OperandSize)
1240  {
1241  ULONGLONG Dividend = (ULONGLONG)State->GeneralRegs[FAST486_REG_EAX].Long
1242  | ((ULONGLONG)State->GeneralRegs[FAST486_REG_EDX].Long << 32);
1243  ULONGLONG Quotient = Dividend / Value;
1244  ULONG Remainder = Dividend % Value;
1245 
1246  if (Quotient > 0xFFFFFFFFULL)
1247  {
1248  /* Divide error */
1249  Fast486Exception(State, FAST486_EXCEPTION_DE);
1250  return;
1251  }
1252 
1253  /* Write back the results */
1254  State->GeneralRegs[FAST486_REG_EAX].Long = (ULONG)Quotient;
1255  State->GeneralRegs[FAST486_REG_EDX].Long = Remainder;
1256  }
1257  else
1258  {
1259  ULONG Dividend = (ULONG)State->GeneralRegs[FAST486_REG_EAX].LowWord
1260  | ((ULONG)State->GeneralRegs[FAST486_REG_EDX].LowWord << 16);
1261  ULONG Quotient = Dividend / Value;
1262  USHORT Remainder = Dividend % Value;
1263 
1264  if (Quotient > 0xFFFF)
1265  {
1266  /* Divide error */
1267  Fast486Exception(State, FAST486_EXCEPTION_DE);
1268  return;
1269  }
1270 
1271  /* Write back the results */
1272  State->GeneralRegs[FAST486_REG_EAX].LowWord = (USHORT)Quotient;
1273  State->GeneralRegs[FAST486_REG_EDX].LowWord = Remainder;
1274  }
1275 
1276  break;
1277  }
1278 
1279  /* IDIV */
1280  case 7:
1281  {
1282  if (Value == 0)
1283  {
1284  /* Divide error */
1285  Fast486Exception(State, FAST486_EXCEPTION_DE);
1286  return;
1287  }
1288 
1289  if (OperandSize)
1290  {
1291  LONGLONG Dividend = (LONGLONG)State->GeneralRegs[FAST486_REG_EAX].Long
1292  | ((LONGLONG)State->GeneralRegs[FAST486_REG_EDX].Long << 32);
1293  LONGLONG Quotient = Dividend / (LONG)Value;
1294  LONG Remainder = Dividend % (LONG)Value;
1295 
1296  if (Quotient > FAST486_LONG_MAX || Quotient < FAST486_LONG_MIN)
1297  {
1298  /* Divide error */
1299  Fast486Exception(State, FAST486_EXCEPTION_DE);
1300  return;
1301  }
1302 
1303  /* Write back the results */
1304  State->GeneralRegs[FAST486_REG_EAX].Long = (ULONG)((LONG)Quotient);
1305  State->GeneralRegs[FAST486_REG_EDX].Long = (ULONG)Remainder;
1306  }
1307  else
1308  {
1309  LONG Dividend = (LONG)State->GeneralRegs[FAST486_REG_EAX].LowWord
1310  | ((LONG)State->GeneralRegs[FAST486_REG_EDX].LowWord << 16);
1311  LONG Quotient = Dividend / (SHORT)LOWORD(Value);
1312  SHORT Remainder = Dividend % (SHORT)LOWORD(Value);
1313 
1314  if (Quotient > FAST486_SHORT_MAX || Quotient < FAST486_SHORT_MIN)
1315  {
1316  /* Divide error */
1317  Fast486Exception(State, FAST486_EXCEPTION_DE);
1318  return;
1319  }
1320 
1321  /* Write back the results */
1322  State->GeneralRegs[FAST486_REG_EAX].LowWord = (USHORT)((SHORT)Quotient);
1323  State->GeneralRegs[FAST486_REG_EDX].LowWord = (USHORT)Remainder;
1324  }
1325 
1326  break;
1327  }
1328  }
1329 }
#define FAST486_SHORT_MIN
Definition: fast486.h:35
#define FAST486_LONG_MAX
Definition: fast486.h:38
FAST486_GEN_REGS Register
Definition: common.h:76
#define SIGN_FLAG_LONG
Definition: common.h:31
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
short SHORT
Definition: pedump.c:59
#define SIGN_FLAG_WORD
Definition: common.h:30
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define ULL(a, b)
Definition: format_msg.c:27
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
int64_t LONGLONG
Definition: typedefs.h:68
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
uint64_t ULONGLONG
Definition: typedefs.h:67
#define FAST486_SHORT_MAX
Definition: fast486.h:36
#define FAST486_LONG_MIN
Definition: fast486.h:37
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
#define HIWORD(l)
Definition: typedefs.h:247
unsigned int ULONG
Definition: retypes.h:1
#define LOWORD(l)
Definition: pedump.c:82
unsigned short * PUSHORT
Definition: retypes.h:2
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3044

◆ FAST486_OPCODE_HANDLER() [15/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupFE  )

Definition at line 1331 of file opgroups.c.

1332 {
1333  UCHAR Value;
1334  FAST486_MOD_REG_RM ModRegRm;
1335  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1336 
1337  TOGGLE_ADSIZE(AddressSize);
1338 
1339  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1340  {
1341  /* Exception occurred */
1342  return;
1343  }
1344 
1345  if (ModRegRm.Register > 1)
1346  {
1347  /* Invalid */
1348  Fast486Exception(State, FAST486_EXCEPTION_UD);
1349  return;
1350  }
1351 
1352  /* Read the operands */
1353  if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
1354  {
1355  /* Exception occurred */
1356  return;
1357  }
1358 
1359  if (ModRegRm.Register == 0)
1360  {
1361  /* Increment and update OF and AF */
1362  Value++;
1363  State->Flags.Of = (Value == SIGN_FLAG_BYTE);
1364  State->Flags.Af = ((Value & 0x0F) == 0);
1365  }
1366  else
1367  {
1368  /* Decrement and update OF and AF */
1369  State->Flags.Of = (Value == SIGN_FLAG_BYTE);
1370  Value--;
1371  State->Flags.Af = ((Value & 0x0F) == 0x0F);
1372  }
1373 
1374  /* Update flags */
1375  State->Flags.Zf = (Value == 0);
1376  State->Flags.Sf = ((Value & SIGN_FLAG_BYTE) != 0);
1377  State->Flags.Pf = Fast486CalculateParity(Value);
1378 
1379  /* Write back the result */
1380  Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
1381 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
#define SIGN_FLAG_BYTE
Definition: common.h:29
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181
#define NULL
Definition: types.h:112

◆ FAST486_OPCODE_HANDLER() [16/20]

FAST486_OPCODE_HANDLER ( Fast486OpcodeGroupFF  )

Definition at line 1383 of file opgroups.c.

1384 {
1385  FAST486_MOD_REG_RM ModRegRm;
1386  BOOLEAN OperandSize, AddressSize;
1387 
1388  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1389 
1390  TOGGLE_OPSIZE(OperandSize);
1391  TOGGLE_ADSIZE(AddressSize);
1392 
1393  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1394  {
1395  /* Exception occurred */
1396  return;
1397  }
1398 
1399  if (ModRegRm.Register == 7)
1400  {
1401  /* Invalid */
1402  Fast486Exception(State, FAST486_EXCEPTION_UD);
1403  return;
1404  }
1405 
1406  /* Read the operands */
1407  if (OperandSize)
1408  {
1409  ULONG Value;
1410 
1411  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
1412  {
1413  /* Exception occurred */
1414  return;
1415  }
1416 
1417  if (ModRegRm.Register == 0)
1418  {
1419  /* Increment and update OF and AF */
1420  Value++;
1421  State->Flags.Of = (Value == SIGN_FLAG_LONG);
1422  State->Flags.Af = ((Value & 0x0F) == 0);
1423  }
1424  else if (ModRegRm.Register == 1)
1425  {
1426  /* Decrement and update OF and AF */
1427  State->Flags.Of = (Value == SIGN_FLAG_LONG);
1428  Value--;
1429  State->Flags.Af = ((Value & 0x0F) == 0x0F);
1430  }
1431  else if (ModRegRm.Register == 2)
1432  {
1433  /* Push the current value of EIP */
1434  if (!Fast486StackPush(State, State->InstPtr.Long))
1435  {
1436  /* Exception occurred */
1437  return;
1438  }
1439 
1440  /* Set the EIP to the address */
1441  State->InstPtr.Long = Value;
1442  }
1443  else if (ModRegRm.Register == 3)
1444  {
1445  USHORT Selector;
1446  FAST486_SEG_REGS Segment = FAST486_REG_DS;
1447 
1448  /* Check for the segment override */
1449  if (State->PrefixFlags & FAST486_PREFIX_SEG)
1450  {
1451  /* Use the override segment instead */
1452  Segment = State->SegmentOverride;
1453  }
1454 
1455  /* Read the selector */
1456  if (!Fast486ReadMemory(State,
1457  Segment,
1458  ModRegRm.MemoryAddress + sizeof(ULONG),
1459  FALSE,
1460  &Selector,
1461  sizeof(USHORT)))
1462  {
1463  /* Exception occurred */
1464  return;
1465  }
1466 
1467  if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1468  && !State->Flags.Vm)
1469  {
1470  if (!Fast486ProcessGate(State, Selector, Value, TRUE))
1471  {
1472  /* Gate processed or exception occurred */
1473  return;
1474  }
1475  }
1476 
1477  /* Push the current value of CS */
1478  if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector))
1479  {
1480  /* Exception occurred */
1481  return;
1482  }
1483 
1484  /* Push the current value of EIP */
1485  if (!Fast486StackPush(State, State->InstPtr.Long))
1486  {
1487  /* Exception occurred */
1488  return;
1489  }
1490 
1491  /* Load the new code segment */
1492  if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
1493  {
1494  /* Exception occurred */
1495  return;
1496  }
1497 
1498  /* Set the EIP to the address */
1499  State->InstPtr.Long = Value;
1500  }
1501  else if (ModRegRm.Register == 4)
1502  {
1503  /* Set the EIP to the address */
1504  State->InstPtr.Long = Value;
1505  }
1506  else if (ModRegRm.Register == 5)
1507  {
1508  USHORT Selector;
1509  FAST486_SEG_REGS Segment = FAST486_REG_DS;
1510 
1511  /* Check for the segment override */
1512  if (State->PrefixFlags & FAST486_PREFIX_SEG)
1513  {
1514  /* Use the override segment instead */
1515  Segment = State->SegmentOverride;
1516  }
1517 
1518  /* Read the selector */
1519  if (!Fast486ReadMemory(State,
1520  Segment,
1521  ModRegRm.MemoryAddress + sizeof(ULONG),
1522  FALSE,
1523  &Selector,
1524  sizeof(USHORT)))
1525  {
1526  /* Exception occurred */
1527  return;
1528  }
1529 
1530  if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1531  && !State->Flags.Vm)
1532  {
1533  if (!Fast486ProcessGate(State, Selector, Value, FALSE))
1534  {
1535  /* Gate processed or exception occurred */
1536  return;
1537  }
1538  }
1539 
1540  /* Load the new code segment */
1541  if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
1542  {
1543  /* Exception occurred */
1544  return;
1545  }
1546 
1547  /* Set the EIP to the address */
1548  State->InstPtr.Long = Value;
1549  }
1550  else if (ModRegRm.Register == 6)
1551  {
1552  /* Push the value on to the stack */
1553  Fast486StackPush(State, Value);
1554  return;
1555  }
1556 
1557  if (ModRegRm.Register <= 1)
1558  {
1559  /* Update flags */
1560  State->Flags.Sf = ((Value & SIGN_FLAG_LONG) != 0);
1561  State->Flags.Zf = (Value == 0);
1562  State->Flags.Pf = Fast486CalculateParity(Value);
1563 
1564  /* Write back the result */
1565  Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
1566  }
1567  }
1568  else
1569  {
1570  USHORT Value;
1571 
1572  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
1573  {
1574  /* Exception occurred */
1575  return;
1576  }
1577 
1578  if (ModRegRm.Register == 0)
1579  {
1580  /* Increment and update OF */
1581  Value++;
1582  State->Flags.Of = (Value == SIGN_FLAG_WORD);
1583  State->Flags.Af = ((Value & 0x0F) == 0);
1584  }
1585  else if (ModRegRm.Register == 1)
1586  {
1587  /* Decrement and update OF */
1588  State->Flags.Of = (Value == SIGN_FLAG_WORD);
1589  Value--;
1590  State->Flags.Af = ((Value & 0x0F) == 0x0F);
1591  }
1592  else if (ModRegRm.Register == 2)
1593  {
1594  /* Push the current value of IP */
1595  if (!Fast486StackPush(State, State->InstPtr.LowWord))
1596  {
1597  /* Exception occurred */
1598  return;
1599  }
1600 
1601  /* Set the IP to the address */
1602  State->InstPtr.LowWord = Value;
1603 
1604  /* Clear the top half of EIP */
1605  State->InstPtr.Long &= 0xFFFF;
1606  }
1607  else if (ModRegRm.Register == 3)
1608  {
1609  USHORT Selector;
1610  FAST486_SEG_REGS Segment = FAST486_REG_DS;
1611 
1612  /* Check for the segment override */
1613  if (State->PrefixFlags & FAST486_PREFIX_SEG)
1614  {
1615  /* Use the override segment instead */
1616  Segment = State->SegmentOverride;
1617  }
1618 
1619  /* Read the selector */
1620  if (!Fast486ReadMemory(State,
1621  Segment,
1622  ModRegRm.MemoryAddress + sizeof(USHORT),
1623  FALSE,
1624  &Selector,
1625  sizeof(USHORT)))
1626  {
1627  /* Exception occurred */
1628  return;
1629  }
1630 
1631  if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1632  && !State->Flags.Vm)
1633  {
1634  if (!Fast486ProcessGate(State, Selector, Value, TRUE))
1635  {
1636  /* Gate processed or exception occurred */
1637  return;
1638  }
1639  }
1640 
1641  /* Push the current value of CS */
1642  if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector))
1643  {
1644  /* Exception occurred */
1645  return;
1646  }
1647 
1648  /* Push the current value of IP */
1649  if (!Fast486StackPush(State, State->InstPtr.LowWord))
1650  {
1651  /* Exception occurred */
1652  return;
1653  }
1654 
1655  /* Load the new code segment */
1656  if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
1657  {
1658  /* Exception occurred */
1659  return;
1660  }
1661 
1662  /* Set the IP to the address */
1663  State->InstPtr.LowWord = Value;
1664 
1665  /* Clear the top half of EIP */
1666  State->InstPtr.Long &= 0xFFFF;
1667  }
1668  else if (ModRegRm.Register == 4)
1669  {
1670  /* Set the IP to the address */
1671  State->InstPtr.LowWord = Value;
1672 
1673  /* Clear the top half of EIP */
1674  State->InstPtr.Long &= 0xFFFF;
1675  }
1676  else if (ModRegRm.Register == 5)
1677  {
1678  USHORT Selector;
1679  FAST486_SEG_REGS Segment = FAST486_REG_DS;
1680 
1681  /* Check for the segment override */
1682  if (State->PrefixFlags & FAST486_PREFIX_SEG)
1683  {
1684  /* Use the override segment instead */
1685  Segment = State->SegmentOverride;
1686  }
1687 
1688  /* Read the selector */
1689  if (!Fast486ReadMemory(State,
1690  Segment,
1691  ModRegRm.MemoryAddress + sizeof(USHORT),
1692  FALSE,
1693  &Selector,
1694  sizeof(USHORT)))
1695  {
1696  /* Exception occurred */
1697  return;
1698  }
1699 
1700  if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1701  && !State->Flags.Vm)
1702  {
1703  if (!Fast486ProcessGate(State, Selector, Value, FALSE))
1704  {
1705  /* Gate processed or exception occurred */
1706  return;
1707  }
1708  }
1709 
1710  /* Load the new code segment */
1711  if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
1712  {
1713  /* Exception occurred */
1714  return;
1715  }
1716 
1717  /* Set the IP to the address */
1718  State->InstPtr.LowWord = Value;
1719 
1720  /* Clear the top half of EIP */
1721  State->InstPtr.Long &= 0xFFFF;
1722  }
1723  else if (ModRegRm.Register == 6)
1724  {
1725  /* Push the value on to the stack */
1726  Fast486StackPush(State, Value);
1727  return;
1728  }
1729  else
1730  {
1731  /* Invalid */
1732  Fast486Exception(State, FAST486_EXCEPTION_UD);
1733  return;
1734  }
1735 
1736  if (ModRegRm.Register <= 1)
1737  {
1738  /* Update flags */
1739  State->Flags.Sf = ((Value & SIGN_FLAG_WORD) != 0);
1740  State->Flags.Zf = (Value == 0);
1741  State->Flags.Pf = Fast486CalculateParity(Value);
1742 
1743  /* Write back the result */
1744  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
1745  }
1746  }
1747 }
#define TRUE
Definition: types.h:120
#define FAST486_CR0_PE
Definition: fast486.h:46
FAST486_GEN_REGS Register
Definition: common.h:76
#define SIGN_FLAG_LONG
Definition: common.h:31
#define FALSE
Definition: types.h:117
#define SIGN_FLAG_WORD
Definition: common.h:30
unsigned char BOOLEAN
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
BOOLEAN FASTCALL Fast486ReadMemory(PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, BOOLEAN InstFetch, PVOID Buffer, ULONG Size)
Definition: common.c:36
#define FAST486_PREFIX_SEG
Definition: fast486.h:98
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
ULONG MemoryAddress
Definition: common.h:81

◆ FAST486_OPCODE_HANDLER() [17/20]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeGroup0F00  )

Definition at line 1749 of file opgroups.c.

1750 {
1751  FAST486_MOD_REG_RM ModRegRm;
1752  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1753 
1754  NO_LOCK_PREFIX();
1755  TOGGLE_ADSIZE(AddressSize);
1756 
1757  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1758  {
1759  /* Exception occurred */
1760  return;
1761  }
1762 
1763  /* Check which operation this is */
1764  switch (ModRegRm.Register)
1765  {
1766  /* SLDT */
1767  case 0:
1768  {
1769  /* Not recognized in real mode or virtual 8086 mode */
1770  if (!(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1771  || State->Flags.Vm)
1772  {
1773  Fast486Exception(State, FAST486_EXCEPTION_UD);
1774  return;
1775  }
1776 
1777  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, State->Ldtr.Selector);
1778  break;
1779  }
1780 
1781  /* STR */
1782  case 1:
1783  {
1784  /* Not recognized in real mode or virtual 8086 mode */
1785  if (!(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1786  || State->Flags.Vm)
1787  {
1788  Fast486Exception(State, FAST486_EXCEPTION_UD);
1789  return;
1790  }
1791 
1792  Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, State->TaskReg.Selector);
1793  break;
1794  }
1795 
1796  /* LLDT */
1797  case 2:
1798  {
1799  BOOLEAN Valid;
1800  USHORT Selector;
1801  FAST486_SYSTEM_DESCRIPTOR GdtEntry;
1802 
1803  /* Not recognized in real mode or virtual 8086 mode */
1804  if (!(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1805  || State->Flags.Vm)
1806  {
1807  Fast486Exception(State, FAST486_EXCEPTION_UD);
1808  return;
1809  }
1810 
1811  /* This is a privileged instruction */
1812  if (Fast486GetCurrentPrivLevel(State) != 0)
1813  {
1814  Fast486Exception(State, FAST486_EXCEPTION_GP);
1815  return;
1816  }
1817 
1818  if (!Fast486ReadModrmWordOperands(State,
1819  &ModRegRm,
1820  NULL,
1821  &Selector))
1822  {
1823  /* Exception occurred */
1824  return;
1825  }
1826 
1827  if (Selector & SEGMENT_TABLE_INDICATOR)
1828  {
1829  /* This selector doesn't point to the GDT */
1830  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
1831  return;
1832  }
1833 
1834  if (!Fast486ReadDescriptorEntry(State,
1835  Selector,
1836  &Valid,
1837  (PFAST486_GDT_ENTRY)&GdtEntry))
1838  {
1839  /* Exception occurred */
1840  return;
1841  }
1842 
1843  if (!Valid)
1844  {
1845  /* Invalid selector */
1846  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
1847  return;
1848  }
1849 
1850  if (GET_SEGMENT_INDEX(Selector) == 0)
1851  {
1852  RtlZeroMemory(&State->Ldtr, sizeof(State->Ldtr));
1853  return;
1854  }
1855 
1856  if (!GdtEntry.Present)
1857  {
1858  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
1859  return;
1860  }
1861 
1862  if (GdtEntry.Signature != FAST486_LDT_SIGNATURE)
1863  {
1864  /* This is not a LDT descriptor */
1865  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
1866  return;
1867  }
1868 
1869  /* Update the LDTR */
1870  State->Ldtr.Selector = Selector;
1871  State->Ldtr.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
1872  State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
1873 
1874  if (GdtEntry.Granularity)
1875  {
1876  State->Ldtr.Limit <<= 12;
1877  State->Ldtr.Limit |= 0x00000FFF;
1878  }
1879 
1880  break;
1881  }
1882 
1883  /* LTR */
1884  case 3:
1885  {
1886  BOOLEAN Valid;
1887  USHORT Selector;
1888  FAST486_SYSTEM_DESCRIPTOR GdtEntry;
1889 
1890  /* Not recognized in real mode or virtual 8086 mode */
1891  if (!(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1892  || State->Flags.Vm)
1893  {
1894  Fast486Exception(State, FAST486_EXCEPTION_UD);
1895  return;
1896  }
1897 
1898  /* This is a privileged instruction */
1899  if (Fast486GetCurrentPrivLevel(State) != 0)
1900  {
1901  Fast486Exception(State, FAST486_EXCEPTION_GP);
1902  return;
1903  }
1904 
1905  if (!Fast486ReadModrmWordOperands(State,
1906  &ModRegRm,
1907  NULL,
1908  &Selector))
1909  {
1910  /* Exception occurred */
1911  return;
1912  }
1913 
1914  if (Selector & SEGMENT_TABLE_INDICATOR)
1915  {
1916  /* This selector doesn't point to the GDT */
1917  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
1918  return;
1919  }
1920 
1921  if (!Fast486ReadDescriptorEntry(State,
1922  Selector,
1923  &Valid,
1924  (PFAST486_GDT_ENTRY)&GdtEntry))
1925  {
1926  /* Exception occurred */
1927  return;
1928  }
1929 
1930  if (!Valid)
1931  {
1932  /* Invalid selector */
1933  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
1934  return;
1935  }
1936 
1937  if (GET_SEGMENT_INDEX(Selector) == 0)
1938  {
1939  Fast486Exception(State, FAST486_EXCEPTION_GP);
1940  return;
1941  }
1942 
1943  if (!GdtEntry.Present)
1944  {
1945  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
1946  return;
1947  }
1948 
1949  if (GdtEntry.Signature != FAST486_TSS_SIGNATURE
1950  && GdtEntry.Signature != FAST486_BUSY_TSS_SIGNATURE
1951  && GdtEntry.Signature != FAST486_TSS_16_SIGNATURE
1952  && GdtEntry.Signature != FAST486_BUSY_TSS_16_SIGNATURE)
1953  {
1954  /* This is not a TSS descriptor */
1955  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
1956  return;
1957  }
1958 
1959  /* Update the TR */
1960  State->TaskReg.Selector = Selector;
1961  State->TaskReg.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
1962  State->TaskReg.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
1963  State->TaskReg.Modern = GdtEntry.Signature == FAST486_TSS_SIGNATURE
1964  || GdtEntry.Signature == FAST486_BUSY_TSS_SIGNATURE;
1965 
1966  if (GdtEntry.Granularity)
1967  {
1968  State->TaskReg.Limit <<= 12;
1969  State->TaskReg.Limit |= 0x00000FFF;
1970  }
1971 
1972  if (GdtEntry.Signature != FAST486_BUSY_TSS_SIGNATURE
1973  && GdtEntry.Signature != FAST486_BUSY_TSS_16_SIGNATURE)
1974  {
1975  /* Set the busy bit of this TSS descriptor and write it back */
1976  GdtEntry.Signature |= 2;
1977 
1978  Fast486WriteLinearMemory(State,
1979  State->Gdtr.Address + GET_SEGMENT_INDEX(Selector),
1980  &GdtEntry,
1981  sizeof(GdtEntry),
1982  FALSE /* We already made sure CPL is 0 */);
1983  }
1984 
1985  break;
1986  }
1987 
1988  /* VERR/VERW */
1989  case 4:
1990  case 5:
1991  {
1992  USHORT Selector;
1993  BOOLEAN Valid;
1994  FAST486_GDT_ENTRY GdtEntry;
1995 
1996  /* Not recognized in real mode or virtual 8086 mode */
1997  if (!(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
1998  || State->Flags.Vm)
1999  {
2000  Fast486Exception(State, FAST486_EXCEPTION_UD);
2001  return;
2002  }
2003 
2004  if (!Fast486ReadModrmWordOperands(State,
2005  &ModRegRm,
2006  NULL,
2007  &Selector))
2008  {
2009  /* Exception occurred */
2010  return;
2011  }
2012 
2013  if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry))
2014  {
2015  /* Exception occurred */
2016  return;
2017  }
2018 
2019  if (!Valid)
2020  {
2021  /* Clear ZF */
2022  State->Flags.Zf = FALSE;
2023  return;
2024  }
2025 
2026  /* Set ZF if it is valid and accessible */
2027  State->Flags.Zf = GdtEntry.Present // must be present
2028  && GdtEntry.SystemType // must be a segment
2029  && (((ModRegRm.Register == 4)
2030  /* code segments are only readable if the RW bit is set */
2031  && (!GdtEntry.Executable || GdtEntry.ReadWrite))
2032  || ((ModRegRm.Register == 5)
2033  /* code segments are never writable, data segments are writable when RW is set */
2034  && (!GdtEntry.Executable && GdtEntry.ReadWrite)))
2035  /*
2036  * for segments other than conforming code segments,
2037  * both RPL and CPL must be less than or equal to DPL
2038  */
2039  && (((!GdtEntry.Executable || !GdtEntry.DirConf)
2040  && (GET_SEGMENT_RPL(Selector) <= GdtEntry.Dpl)
2041  && (Fast486GetCurrentPrivLevel(State) <= GdtEntry.Dpl))
2042  /* for conforming code segments, DPL must be less than or equal to CPL */
2043  || ((GdtEntry.Executable && GdtEntry.DirConf)
2044  && (GdtEntry.Dpl <= Fast486GetCurrentPrivLevel(State))));
2045 
2046 
2047  break;
2048  }
2049 
2050  /* Invalid */
2051  default:
2052  {
2053  Fast486Exception(State, FAST486_EXCEPTION_UD);
2054  }
2055  }
2056 }
#define NO_LOCK_PREFIX()
Definition: common.h:43
#define FAST486_CR0_PE
Definition: fast486.h:46
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
#define GET_SEGMENT_INDEX(s)
Definition: common.h:39
unsigned char BOOLEAN
#define FAST486_BUSY_TSS_SIGNATURE
Definition: fast486.h:93
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
#define FAST486_BUSY_TSS_16_SIGNATURE
Definition: fast486.h:87
#define FAST486_TSS_16_SIGNATURE
Definition: fast486.h:85
#define SEGMENT_TABLE_INDICATOR
Definition: common.h:40
unsigned short USHORT
Definition: pedump.c:61
#define GET_SEGMENT_RPL(s)
Definition: common.h:38
#define NULL
Definition: types.h:112
VOID FASTCALL Fast486ExceptionWithErrorCode(PFAST486_STATE State, FAST486_EXCEPTIONS ExceptionCode, ULONG ErrorCode)
Definition: common.c:557
#define FAST486_TSS_SIGNATURE
Definition: fast486.h:92
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define FAST486_LDT_SIGNATURE
Definition: fast486.h:86

◆ FAST486_OPCODE_HANDLER() [18/20]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeGroup0F01  )

Definition at line 2058 of file opgroups.c.

2059 {
2060  // FAST486_TABLE_REG TableReg;
2061  UCHAR TableReg[6];
2062  FAST486_MOD_REG_RM ModRegRm;
2063  BOOLEAN OperandSize, AddressSize;
2064  FAST486_SEG_REGS Segment = FAST486_REG_DS;
2065 
2066  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
2067 
2068  NO_LOCK_PREFIX();
2069  TOGGLE_OPSIZE(OperandSize);
2070  TOGGLE_ADSIZE(AddressSize);
2071 
2072  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
2073  {
2074  /* Exception occurred */
2075  return;
2076  }
2077 
2078  /* Check for the segment override */
2079  if (State->PrefixFlags & FAST486_PREFIX_SEG)
2080  {
2081  /* Use the override segment instead */
2082  Segment = State->SegmentOverride;
2083  }
2084 
2085  /* Check which operation this is */
2086  switch (ModRegRm.Register)
2087  {
2088  /* SGDT */
2089  case 0:
2090  {
2091  if (!ModRegRm.Memory)
2092  {
2093  /* The second operand must be a memory location */
2094  Fast486Exception(State, FAST486_EXCEPTION_UD);
2095  return;
2096  }
2097 
2098  /* Fill the 6-byte table register */
2099  // TableReg = State->Gdtr;
2100  *((PUSHORT)&TableReg) = State->Gdtr.Size;
2101  *((PULONG)&TableReg[sizeof(USHORT)]) = State->Gdtr.Address;
2102 
2103  /* Store the GDTR */
2105  Segment,
2106  ModRegRm.MemoryAddress,
2107  TableReg,
2108  sizeof(TableReg));
2109 
2110  break;
2111  }
2112 
2113  /* SIDT */
2114  case 1:
2115  {
2116  if (!ModRegRm.Memory)
2117  {
2118  /* The second operand must be a memory location */
2119  Fast486Exception(State, FAST486_EXCEPTION_UD);
2120  return;
2121  }
2122 
2123  /* Fill the 6-byte table register */
2124  // TableReg = State->Idtr;
2125  *((PUSHORT)&TableReg) = State->Idtr.Size;
2126  *((PULONG)&TableReg[sizeof(USHORT)]) = State->Idtr.Address;
2127 
2128  /* Store the IDTR */
2130  Segment,
2131  ModRegRm.MemoryAddress,
2132  TableReg,
2133  sizeof(TableReg));
2134 
2135  break;
2136  }
2137 
2138  /* LGDT */
2139  case 2:
2140  {
2141  /* This is a privileged instruction */
2142  if (Fast486GetCurrentPrivLevel(State) != 0)
2143  {
2144  Fast486Exception(State, FAST486_EXCEPTION_GP);
2145  return;
2146  }
2147 
2148  if (!ModRegRm.Memory)
2149  {
2150  /* The second operand must be a memory location */
2151  Fast486Exception(State, FAST486_EXCEPTION_UD);
2152  return;
2153  }
2154 
2155  /* Read the new GDTR */
2156  if (!Fast486ReadMemory(State,
2157  Segment,
2158  ModRegRm.MemoryAddress,
2159  FALSE,
2160  TableReg,
2161  sizeof(TableReg)))
2162  {
2163  /* Exception occurred */
2164  return;
2165  }
2166 
2167  /* Load the new GDT */
2168  // State->Gdtr = TableReg;
2169  State->Gdtr.Size = *((PUSHORT)&TableReg);
2170  State->Gdtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
2171 
2172  /* In 16-bit mode the highest byte is masked out */
2173  if (!OperandSize) State->Gdtr.Address &= 0x00FFFFFF;
2174 
2175  break;
2176  }
2177 
2178  /* LIDT */
2179  case 3:
2180  {
2181  /* This is a privileged instruction */
2182  if (Fast486GetCurrentPrivLevel(State) != 0)
2183  {
2184  Fast486Exception(State, FAST486_EXCEPTION_GP);
2185  return;
2186  }
2187 
2188  if (!ModRegRm.Memory)
2189  {
2190  /* The second operand must be a memory location */
2191  Fast486Exception(State, FAST486_EXCEPTION_UD);
2192  return;
2193  }
2194 
2195  /* Read the new IDTR */
2196  if (!Fast486ReadMemory(State,
2197  Segment,
2198  ModRegRm.MemoryAddress,
2199  FALSE,
2200  TableReg,
2201  sizeof(TableReg)))
2202  {
2203  /* Exception occurred */
2204  return;
2205  }
2206 
2207  /* Load the new IDT */
2208  // State->Idtr = TableReg;
2209  State->Idtr.Size = *((PUSHORT)&TableReg);
2210  State->Idtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
2211 
2212  /* In 16-bit mode the highest byte is masked out */
2213  if (!OperandSize) State->Idtr.Address &= 0x00FFFFFF;
2214 
2215  break;
2216  }
2217 
2218  /* SMSW */
2219  case 4:
2220  {
2221  /* Store the lower 16 bits (Machine Status Word) of CR0 */
2222  Fast486WriteModrmWordOperands(State,
2223  &ModRegRm,
2224  FALSE,
2225  LOWORD(State->ControlRegisters[FAST486_REG_CR0]));
2226 
2227  break;
2228  }
2229 
2230  /* LMSW */
2231  case 6:
2232  {
2233  USHORT MachineStatusWord;
2234 
2235  if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
2236  {
2237  /* This is a privileged instruction */
2238  if (Fast486GetCurrentPrivLevel(State) != 0)
2239  {
2240  Fast486Exception(State, FAST486_EXCEPTION_GP);
2241  return;
2242  }
2243  }
2244 
2245  /* Read the new Machine Status Word */
2246  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &MachineStatusWord))
2247  {
2248  /* Exception occurred */
2249  return;
2250  }
2251 
2252  /* Set the lowest 4 bits, but never clear bit 0 */
2253  State->ControlRegisters[FAST486_REG_CR0] &= 0xFFFFFFF1;
2254  State->ControlRegisters[FAST486_REG_CR0] |= MachineStatusWord & 0x0F;
2255 
2256  break;
2257  }
2258 
2259  /* INVLPG */
2260  case 7:
2261  {
2262 #ifndef FAST486_NO_PREFETCH
2263  /* Invalidate the prefetch */
2264  State->PrefetchValid = FALSE;
2265 #endif
2266 
2267  /* This is a privileged instruction */
2268  if (Fast486GetCurrentPrivLevel(State) != 0)
2269  {
2270  Fast486Exception(State, FAST486_EXCEPTION_GP);
2271  return;
2272  }
2273 
2274  if (!ModRegRm.Memory)
2275  {
2276  /* The second operand must be a memory location */
2277  Fast486Exception(State, FAST486_EXCEPTION_UD);
2278  return;
2279  }
2280 
2281  if (State->Tlb != NULL)
2282  {
2283  /* Clear the TLB entry */
2284  State->Tlb[ModRegRm.MemoryAddress >> 12] = INVALID_TLB_FIELD;
2285  }
2286 
2287  break;
2288  }
2289 
2290  /* Invalid */
2291  default:
2292  {
2293  Fast486Exception(State, FAST486_EXCEPTION_UD);
2294  }
2295  }
2296 }
#define NO_LOCK_PREFIX()
Definition: common.h:43
#define FAST486_CR0_PE
Definition: fast486.h:46
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
BOOLEAN FASTCALL Fast486WriteMemory(PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, PVOID Buffer, ULONG Size)
Definition: common.c:163
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN FASTCALL Fast486ReadMemory(PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, BOOLEAN InstFetch, PVOID Buffer, ULONG Size)
Definition: common.c:36
#define FAST486_PREFIX_SEG
Definition: fast486.h:98
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
#define INVALID_TLB_FIELD
Definition: common.h:71
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
ULONG MemoryAddress
Definition: common.h:81
#define LOWORD(l)
Definition: pedump.c:82
unsigned short * PUSHORT
Definition: retypes.h:2
BOOLEAN Memory
Definition: common.h:77

◆ FAST486_OPCODE_HANDLER() [19/20]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeGroup0FB9  )

Definition at line 2298 of file opgroups.c.

2299 {
2300  FAST486_MOD_REG_RM ModRegRm;
2301  BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
2302 
2303  TOGGLE_ADSIZE(AddressSize);
2304 
2305  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
2306  {
2307  /* Exception occurred */
2308  return;
2309  }
2310 
2311  /* All of them are reserved (UD2) */
2312  Fast486Exception(State, FAST486_EXCEPTION_UD);
2313  return;
2314 }
unsigned char BOOLEAN
#define TOGGLE_ADSIZE(x)
Definition: common.h:53

◆ FAST486_OPCODE_HANDLER() [20/20]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeGroup0FBA  )

Definition at line 2316 of file opgroups.c.

2317 {
2318  FAST486_MOD_REG_RM ModRegRm;
2319  BOOLEAN OperandSize, AddressSize;
2320  UINT DataSize;
2321  UCHAR BitNumber;
2322 
2323  OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
2324 
2325  TOGGLE_OPSIZE(OperandSize);
2326  TOGGLE_ADSIZE(AddressSize);
2327 
2328  /* Get the number of bits */
2329  if (OperandSize) DataSize = 32;
2330  else DataSize = 16;
2331 
2332  if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
2333  {
2334  /* Exception occurred */
2335  return;
2336  }
2337 
2338  if (ModRegRm.Register < 4)
2339  {
2340  /* Invalid */
2341  Fast486Exception(State, FAST486_EXCEPTION_UD);
2342  return;
2343  }
2344 
2345  /* Get the bit number */
2346  if (!Fast486FetchByte(State, &BitNumber))
2347  {
2348  /* Exception occurred */
2349  return;
2350  }
2351 
2352  if (ModRegRm.Memory)
2353  {
2354  /*
2355  * For memory operands, add the bit offset divided by
2356  * the data size to the address
2357  */
2358  ModRegRm.MemoryAddress += BitNumber / DataSize;
2359  }
2360 
2361  /* Normalize the bit number */
2362  BitNumber %= DataSize;
2363 
2364  if (OperandSize)
2365  {
2366  ULONG Value;
2367 
2368  /* Read the value */
2369  if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
2370  {
2371  /* Exception occurred */
2372  return;
2373  }
2374 
2375  /* Set CF to the bit value */
2376  State->Flags.Cf = (Value >> BitNumber) & 1;
2377 
2378  if (ModRegRm.Register == 5)
2379  {
2380  /* BTS */
2381  Value |= 1 << BitNumber;
2382  }
2383  else if (ModRegRm.Register == 6)
2384  {
2385  /* BTR */
2386  Value &= ~(1 << BitNumber);
2387  }
2388  else if (ModRegRm.Register == 7)
2389  {
2390  /* BTC */
2391  Value ^= 1 << BitNumber;
2392  }
2393 
2394  if (ModRegRm.Register >= 5)
2395  {
2396  /* Write back the result */
2397  if (!Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value))
2398  {
2399  /* Exception occurred */
2400  return;
2401  }
2402  }
2403  }
2404  else
2405  {
2406  USHORT Value;
2407 
2408  /* Read the value */
2409  if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
2410  {
2411  /* Exception occurred */
2412  return;
2413  }
2414 
2415  /* Set CF to the bit value */
2416  State->Flags.Cf = (Value >> BitNumber) & 1;
2417 
2418  if (ModRegRm.Register == 5)
2419  {
2420  /* BTS */
2421  Value |= 1 << BitNumber;
2422  }
2423  else if (ModRegRm.Register == 6)
2424  {
2425  /* BTR */
2426  Value &= ~(1 << BitNumber);
2427  }
2428  else if (ModRegRm.Register == 7)
2429  {
2430  /* BTC */
2431  Value ^= 1 << BitNumber;
2432  }
2433 
2434  if (ModRegRm.Register >= 5)
2435  {
2436  /* Write back the result */
2437  if (!Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value))
2438  {
2439  /* Exception occurred */
2440  return;
2441  }
2442  }
2443  }
2444 }
FAST486_GEN_REGS Register
Definition: common.h:76
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
unsigned short USHORT
Definition: pedump.c:61
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
ULONG MemoryAddress
Definition: common.h:81
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
BOOLEAN Memory
Definition: common.h:77