windows-nt/Source/XPSP1/NT/base/wow64/mscpu/fraglib/shared.c
2020-09-26 16:20:57 +08:00

418 lines
8.8 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
shared.c
Abstract:
Instruction fragments with common (shared) BYTE, WORD, and DWORD flavors.
Author:
12-Jun-1995 BarryBo
Revision History:
--*/
// THIS FILE IS #include'd INTO FILES WHICH DEFINE THE FOLLOWING MACROS:
// MSB - most significant bit
// UTYPE - UNSIGNED type which defines registers (BYTE/USHORT/DWORD)
// STYPE - SIGNED type which defines registers (char/short/long)
// GET_VAL - dereference a pointer of the right type (GET_BYTE/...)
// PUT_VAL - writes a value into memory
// FRAGCOMMON{0,1,2} - mangles the function name and declares parameters
// AREG - al/ax/eax
// BREG - ...
// CREG - ...
// DREG - ...
FRAGCOMMON1IMM(OPT_FastTestFrag)
{
SET_ZFLAG(op1);
SET_PFLAG(op1);
SET_SFLAG(op1 << (31-LMB));
SET_CFLAG_OFF;
SET_OFLAG_OFF;
}
FRAGCOMMON2IMM(CmpFrag)
{
UTYPE result;
result = op1 - op2;
SET_FLAGS_SUB(result, op1, op2, MSB);
}
FRAGCOMMON2IMM(TestFrag)
{
UTYPE result;
result = op1 & op2;
SET_ZFLAG(result);
SET_PFLAG(result);
SET_SFLAG(result << (31-LMB));
SET_CFLAG_OFF;
SET_OFLAG_OFF;
}
FRAGCOMMON0(RepMovsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
while (ecx) {
PUT_VAL(edi, GET_VAL(esi));
esi += LoopIncr;
edi += LoopIncr;
ecx--;
}
}
FRAGCOMMON0(FsRepMovsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
while (ecx) {
PUT_VAL(edi, GET_VAL(esi + Base));
esi += LoopIncr;
edi += LoopIncr;
ecx--;
}
}
FRAGCOMMON0(MovsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
PUT_VAL(edi, GET_VAL(esi));
esi += LoopIncr;
edi += LoopIncr;
}
FRAGCOMMON0(FsMovsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
PUT_VAL(edi, GET_VAL(esi + (DWORD)(ULONGLONG)NtCurrentTeb()));
esi += LoopIncr;
edi += LoopIncr;
}
FRAGCOMMON0(RepnzCmpsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op1, op2;
while (ecx) {
op1 = GET_VAL(esi);
op2 = GET_VAL(edi);
result = op1 - op2;
SET_FLAGS_SUB(result, op1, op2, MSB);
esi += LoopIncr;
edi += LoopIncr;
ecx--;
if (cpu->flag_zf == 0) { // inverse logic
break;
}
}
}
FRAGCOMMON0(FsRepnzCmpsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
UTYPE result, op1, op2;
while (ecx) {
op1 = GET_VAL(esi + Base);
op2 = GET_VAL(edi);
result = op1 - op2;
SET_FLAGS_SUB(result, op1, op2, MSB);
esi += LoopIncr;
edi += LoopIncr;
ecx--;
if (cpu->flag_zf == 0) { // inverse logic
break;
}
}
}
FRAGCOMMON0(RepzCmpsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op1, op2;
while (ecx) {
op1 = GET_VAL(esi);
op2 = GET_VAL(edi);
result = op1 - op2;
SET_FLAGS_SUB(result, op1, op2, MSB);
esi += LoopIncr;
edi += LoopIncr;
ecx--;
if (cpu->flag_zf) { // inverse logic
break;
}
}
}
FRAGCOMMON0(FsRepzCmpsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
UTYPE result, op1, op2;
while (ecx) {
op1 = GET_VAL(esi + Base);
op2 = GET_VAL(edi);
result = op1 - op2;
SET_FLAGS_SUB(result, op1, op2, MSB);
esi += LoopIncr;
edi += LoopIncr;
ecx--;
if (cpu->flag_zf) { // inverse logic
break;
}
}
}
FRAGCOMMON0(CmpsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op1, op2;
op1 = GET_VAL(esi);
op2 = GET_VAL(edi);
result = op1 - op2;
SET_FLAGS_SUB(result, op1, op2, MSB);
esi += LoopIncr;
edi += LoopIncr;
}
FRAGCOMMON0(FsCmpsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op1, op2;
op1 = GET_VAL(esi + (DWORD)(ULONGLONG)NtCurrentTeb());
op2 = GET_VAL(edi);
result = op1 - op2;
SET_FLAGS_SUB(result, op1, op2, MSB);
esi += LoopIncr;
edi += LoopIncr;
}
FRAGCOMMON0(RepStosFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE Value = AREG;
while (ecx) {
PUT_VAL(edi, Value);
edi += LoopIncr;
ecx--;
}
}
FRAGCOMMON0(StosFrag)
{
PUT_VAL(edi, AREG);
edi += sizeof(UTYPE)*cpu->flag_df;
}
FRAGCOMMON0(RepnzScasFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi);
result = Value - op2;
SET_FLAGS_SUB(result, Value, op2, MSB);
edi += LoopIncr;
ecx--;
if (cpu->flag_zf == 0) { // inverse logic
break;
}
}
}
FRAGCOMMON0(RepnzScasNoFlagsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi);
result = Value - op2;
edi += LoopIncr;
ecx--;
if (result == 0) { // inverse logic
break;
}
}
}
FRAGCOMMON0(FsRepnzScasFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi + Base);
result = Value - op2;
SET_FLAGS_SUB(result, Value, op2, MSB);
edi += LoopIncr;
ecx--;
if (cpu->flag_zf == 0) { // inverse logic
break;
}
}
}
FRAGCOMMON0(FsRepnzScasNoFlagsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi + Base);
result = Value - op2;
edi += LoopIncr;
ecx--;
if (result == 0) { // inverse logic
break;
}
}
}
FRAGCOMMON0(RepzScasFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi);
result = Value - op2;
SET_FLAGS_SUB(result, Value, op2, MSB);
edi += LoopIncr;
ecx--;
if (cpu->flag_zf) { // inverse logic
break;
}
}
}
FRAGCOMMON0(RepzScasNoFlagsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi);
result = Value - op2;
edi += LoopIncr;
ecx--;
if (result) { // inverse logic
break;
}
}
}
FRAGCOMMON0(FsRepzScasFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi + Base);
result = Value - op2;
SET_FLAGS_SUB(result, Value, op2, MSB);
edi += LoopIncr;
ecx--;
if (cpu->flag_zf) { // inverse logic
break;
}
}
}
FRAGCOMMON0(FsRepzScasNoFlagsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
UTYPE result, op2;
UTYPE Value = AREG;
while (ecx) {
op2 = GET_VAL(edi + Base);
result = Value - op2;
edi += LoopIncr;
ecx--;
if (result) { // inverse logic
break;
}
}
}
FRAGCOMMON0(ScasFrag)
{
UTYPE result, op2;
op2 = GET_VAL(edi);
result = AREG - op2;
SET_FLAGS_SUB(result, AREG, op2, MSB);
edi += sizeof(UTYPE)*cpu->flag_df;
}
FRAGCOMMON0(ScasNoFlagsFrag)
{
UTYPE result, op2;
op2 = GET_VAL(edi);
result = AREG - op2;
edi += sizeof(UTYPE)*cpu->flag_df;
}
FRAGCOMMON0(FsScasFrag)
{
UTYPE result, op2;
op2 = GET_VAL(edi + (DWORD)(ULONGLONG)NtCurrentTeb());
result = AREG - op2;
SET_FLAGS_SUB(result, AREG, op2, MSB);
edi += sizeof(UTYPE)*cpu->flag_df;
}
FRAGCOMMON0(FsScasNoFlagsFrag)
{
UTYPE result, op2;
op2 = GET_VAL(edi + (DWORD)(ULONGLONG)NtCurrentTeb());
result = AREG - op2;
edi += sizeof(UTYPE)*cpu->flag_df;
}
FRAGCOMMON0(LodsFrag)
{
AREG = GET_VAL(esi);
esi += sizeof(UTYPE)*cpu->flag_df;
}
FRAGCOMMON0(FsLodsFrag)
{
AREG = GET_VAL(esi + (DWORD)(ULONGLONG)NtCurrentTeb());
esi += sizeof(UTYPE)*cpu->flag_df;
}
FRAGCOMMON0(RepLodsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
while (ecx) {
AREG = GET_VAL(esi);
esi += LoopIncr;
ecx--;
}
}
FRAGCOMMON0(FsRepLodsFrag)
{
DWORD LoopIncr = sizeof(UTYPE)*cpu->flag_df;
DWORD Base = (DWORD)(ULONGLONG)NtCurrentTeb();
while (ecx) {
AREG = GET_VAL(esi + Base);
esi += LoopIncr;
ecx--;
}
}