|
|
/*++
Copyright (c) 1995-2000 Microsoft Corporation
Module Name:
fragp.h
Abstract: Private exports, defines for shared code fragments.
Author:
12-Jun-1995 BarryBo, Created
Revision History:
--*/
#include "cpumain.h"
#ifndef FRAGP_H
#define FRAGP_H
#include "fraglib.h"
#include "eflags.h"
//
// This function patches a call to pass the mips address corresponding to
// intelAddr directly to the call fragments.
//
PULONG patchCallRoutine( IN PULONG intelAddr, IN PULONG patchAddr );
//
// Table mapping a byte to a 0 or 1, corresponding to the parity bit for
// that byte.
//
extern const BYTE ParityBit[256];
#if _ALPHA_
// defined in fraginit.c, used in the Alpha code generator
extern DWORD fByteInstructionsOK; #endif
#ifdef MSCCPU
#define eax cpu->GpRegs[GP_EAX].i4
#define ebx cpu->GpRegs[GP_EBX].i4
#define ecx cpu->GpRegs[GP_ECX].i4
#define edx cpu->GpRegs[GP_EDX].i4
#define esp cpu->GpRegs[GP_ESP].i4
#define ebp cpu->GpRegs[GP_EBP].i4
#define esi cpu->GpRegs[GP_ESI].i4
#define edi cpu->GpRegs[GP_EDI].i4
#define eip cpu->eipReg.i4
#define eipTemp cpu->eipTempReg.i4
#define ax cpu->GpRegs[GP_EAX].i2
#define bx cpu->GpRegs[GP_EBX].i2
#define cx cpu->GpRegs[GP_ECX].i2
#define dx cpu->GpRegs[GP_EDX].i2
#define sp cpu->GpRegs[GP_ESP].i2
#define bp cpu->GpRegs[GP_EBP].i2
#define si cpu->GpRegs[GP_ESI].i2
#define di cpu->GpRegs[GP_EDI].i2
#define al cpu->GpRegs[GP_EAX].i1
#define bl cpu->GpRegs[GP_EBX].i1
#define cl cpu->GpRegs[GP_ECX].i1
#define dl cpu->GpRegs[GP_EDX].i1
#define ah cpu->GpRegs[GP_EAX].hb
#define bh cpu->GpRegs[GP_EBX].hb
#define ch cpu->GpRegs[GP_ECX].hb
#define dh cpu->GpRegs[GP_EDX].hb
#define CS cpu->cs
#define DS cpu->ds
#define ES cpu->es
#define SS cpu->ss
#define FS cpu->fs
#define GS cpu->gs
#define CPUDATA CPUCONTEXT
#define PCPUDATA PCPUCONTEXT
#else //!MSCCPU
#define eax cpu->GpRegs[GP_EAX].i4
#define ebx cpu->GpRegs[GP_EBX].i4
#define ecx cpu->GpRegs[GP_ECX].i4
#define edx cpu->GpRegs[GP_EDX].i4
#define esp cpu->GpRegs[GP_ESP].i4
#define ebp cpu->GpRegs[GP_EBP].i4
#define esi cpu->GpRegs[GP_ESI].i4
#define edi cpu->GpRegs[GP_EDI].i4
#define eip cpu->eipReg.i4
#define eipTemp cpu->eipTempReg.i4
#define ax cpu->GpRegs[GP_EAX].i2
#define bx cpu->GpRegs[GP_EBX].i2
#define cx cpu->GpRegs[GP_ECX].i2
#define dx cpu->GpRegs[GP_EDX].i2
#define sp cpu->GpRegs[GP_ESP].i2
#define bp cpu->GpRegs[GP_EBP].i2
#define si cpu->GpRegs[GP_ESI].i2
#define di cpu->GpRegs[GP_EDI].i2
#define al cpu->GpRegs[GP_EAX].i1
#define bl cpu->GpRegs[GP_EBX].i1
#define cl cpu->GpRegs[GP_ECX].i1
#define dl cpu->GpRegs[GP_EDX].i1
#define ah cpu->GpRegs[GP_EAX].hb
#define bh cpu->GpRegs[GP_EBX].hb
#define ch cpu->GpRegs[GP_ECX].hb
#define dh cpu->GpRegs[GP_EDX].hb
#define CS cpu->GpRegs[REG_CS].i2
#define DS cpu->GpRegs[REG_DS].i2
#define ES cpu->GpRegs[REG_ES].i2
#define SS cpu->GpRegs[REG_SS].i2
#define FS cpu->GpRegs[REG_FS].i2
#define GS cpu->GpRegs[REG_GS].i2
#define CPUDATA THREADSTATE
#define PCPUDATA PTHREADSTATE
#endif //!MSCCPU
#define MSB32 0x80000000
#define SET_FLAG(flag, b) flag = (DWORD)b
#define SET_CFLAG(b) SET_FLAG(cpu->flag_cf, (b))
#define SET_PFLAG(b) SET_FLAG(cpu->flag_pf, (b))
#define SET_AUXFLAG(b) SET_FLAG(cpu->flag_aux,(b))
#define SET_ZFLAG(b) SET_FLAG(cpu->flag_zf, (b))
#define SET_SFLAG(b) SET_FLAG(cpu->flag_sf, (b))
// SET_DFLAG is special
#define SET_OFLAG(b) SET_FLAG(cpu->flag_of, (b))
#define SET_TFLAG(b) SET_FLAG(cpu->flag_tf, (b))
#define SET_RFLAG(b) //UNDONE: not used until 386 debug registers implemented
#define AUX_VAL 0x10
#define GET_AUXFLAG (cpu->flag_aux & AUX_VAL)
#define SET_AUXFLAG_ON SET_AUXFLAG(AUX_VAL)
#define SET_AUXFLAG_OFF SET_AUXFLAG(0x0)
#define GET_OFLAG (cpu->flag_of & MSB32)
#define GET_OFLAGZO (cpu->flag_of >> 31)
#define SET_OFLAG_ON SET_OFLAG(MSB32)
#define SET_OFLAG_OFF SET_OFLAG(0)
#define SET_OFLAG_IND(b) SET_OFLAG(b ? MSB32 : 0)
#define GET_CFLAG (cpu->flag_cf & MSB32)
#define GET_CFLAGZO (cpu->flag_cf >> 31)
#define SET_CFLAG_ON SET_CFLAG(MSB32)
#define SET_CFLAG_OFF SET_CFLAG(0)
#define SET_CFLAG_IND(b) SET_CFLAG(b ? MSB32 : 0)
#define GET_SFLAG (cpu->flag_sf & MSB32)
#define GET_SFLAGZO (cpu->flag_sf >> 31)
#define SET_SFLAG_ON SET_SFLAG(MSB32)
#define SET_SFLAG_OFF SET_SFLAG(0)
#define SET_SFLAG_IND(b) SET_SFLAG(b ? MSB32 : 0)
#define GET_PFLAG (ParityBit[cpu->flag_pf & 0xff])
#define GET_BYTE(addr) (*(UNALIGNED unsigned char *)(addr))
#define GET_SHORT(addr) (*(UNALIGNED unsigned short *)(addr))
#define GET_LONG(addr) (*(UNALIGNED unsigned long *)(addr))
#define PUT_BYTE(addr,dw) {GET_BYTE(addr)=dw;}
#define PUT_SHORT(addr,dw) {GET_SHORT(addr)=dw;}
#define PUT_LONG(addr,dw) {GET_LONG(addr)=dw;}
typedef void (*pfnFrag0)(PCPUDATA); typedef void (*pfnFrag18)(PCPUDATA, BYTE *); typedef void (*pfnFrag116)(PCPUDATA, USHORT *); typedef void (*pfnFrag132)(PCPUDATA, DWORD *); typedef void (*pfnFrag28)(PCPUDATA, BYTE *, BYTE); typedef void (*pfnFrag216)(PCPUDATA, USHORT *, USHORT); typedef void (*pfnFrag232)(PCPUDATA, DWORD *, DWORD); typedef void (*pfnFrag38)(PCPUDATA, BYTE *, BYTE, BYTE); typedef void (*pfnFrag316)(PCPUDATA, USHORT *, USHORT, USHORT); typedef void (*pfnFrag332)(PCPUDATA, DWORD *, DWORD, DWORD);
/*---------------------------------------------------------------------*/ extern void CpupUnlockTCAndDoInterrupt(PTHREADSTATE cpu, int Interrupt);
#define Int0() CpupUnlockTCAndDoInterrupt(cpu, 0) // Divide error
#define Int3() CpupUnlockTCAndDoInterrupt(cpu, 3) // Breakpoint
#define Int4() CpupUnlockTCAndDoInterrupt(cpu, 4) // Overflow
#define Int5() CpupUnlockTCAndDoInterrupt(cpu, 5) // Bound check
#define Int6() CpupUnlockTCAndDoInterrupt(cpu, 6) // Invalid opcode
#define Int8() CpupUnlockTCAndDoInterrupt(cpu, 8) // Double fault
#define Int13(sel) CpupUnlockTCAndDoInterrupt(cpu, 13) // General protection
#define PRIVILEGED_INSTR Int13(0)
#define BREAKPOINT_INSTR Int3()
#define OVERFLOW_INSTR Int4()
/*---------------------------------------------------------------------*/
#define PUSH_LONG(dw) { \
DWORD NewEsp = esp-4; \ *(DWORD *)(NewEsp) = (DWORD)(dw); \ esp=NewEsp; \ }
#define POP_LONG(dw) { \
DWORD espTemp = esp; \ (dw)=*(DWORD *)espTemp; \ esp=espTemp+4; \ }
#define PUSH_SHORT(s) { \
DWORD NewEsp = esp-2; \ *(USHORT *)(NewEsp)=(USHORT)(s); \ esp=NewEsp; \ }
#define POP_SHORT(s) { \
DWORD espTemp = esp; \ (s)=*(USHORT *)espTemp; \ esp=espTemp+2; \ }
#define XCHG(t, r1, r2) { \
t temp; \ temp = r1; \ r1=r2; \ r2=temp; \ }
#define XCHG_MEM(t, m1, m2) { \
t temp; \ temp = *m1; \ *m1 = *m2; \ *m2 = temp; \ }
#define do_j_b(f) { \
if (cpu->AdrPrefix) { \ if (f) { \ cpu->eipTempReg.i2+=(char)GET_BYTE(eipTemp+1)+2; \ } else { \ cpu->eipTempReg.i2+=2; \ } \ cpu->AdrPrefix = PREFIX_NONE; \ } else { \ if (f) { \ eipTemp+=(char)GET_BYTE(eipTemp+1)+2; \ } else { \ eipTemp+=2; \ } \ } \ }
#define DO_J(f) { \
if (cpu->AdrPrefix) { \ if (f) { \ cpu->eipTempReg.i2+=(STYPE)GET_VAL(eipTemp+1)+1+sizeof(UTYPE); \ } else { \ cpu->eipTempReg.i2+=1+sizeof(UTYPE); \ } \ cpu->AdrPrefix = PREFIX_NONE; \ } else { \ if (f) { \ eipTemp+=(STYPE)GET_VAL(eipTemp+1)+1+sizeof(UTYPE); \ } else { \ eipTemp+=1+sizeof(UTYPE); \ } \ } \ }
#define SET_FLAGS_ADD32(r, op1, op2, msb) { \
DWORD carry = (op1) ^ (op2) ^ (r); \ /* next line is different for ADD/SUB */ \ SET_OFLAG(~((op1) ^ (op2)) & ((op2) ^ (r))); \ SET_CFLAG(carry ^ cpu->flag_of); \ SET_ZFLAG((r)); \ SET_SFLAG((r)); \ SET_PFLAG((r)); \ SET_AUXFLAG(carry); \ }
#define SET_FLAGS_ADD16(r, op1, op2, msb) { \
DWORD carry = (op1) ^ (op2) ^ (r); \ /* next line is different for ADD/SUB */ \ SET_OFLAG((~((op1) ^ (op2)) & ((op2) ^ (r))) << 16); \ SET_CFLAG((carry<<16) ^ cpu->flag_of); \ SET_ZFLAG((r)); \ SET_PFLAG((r)); \ SET_SFLAG((r) << 16); \ SET_AUXFLAG(carry); \ }
#define SET_FLAGS_ADD8(r, op1, op2, msb) { \
DWORD carry = (op1) ^ (op2) ^ (r); \ /* next line is different for ADD/SUB */ \ SET_OFLAG((~((op1) ^ (op2)) & ((op2) ^ (r))) << 24); \ SET_CFLAG((carry<<24) ^ cpu->flag_of); \ SET_ZFLAG((r)); \ SET_SFLAG((r) << 24); \ SET_AUXFLAG(carry); \ SET_PFLAG((r)); \ }
#define SET_FLAGS_SUB32(r, op1, op2, msb) { \
DWORD carry = (op1) ^ (op2) ^ (r); \ /* next line is different for ADD/SUB */ \ SET_OFLAG(((op1) ^ (op2)) & ((op1) ^ (r))); \ SET_CFLAG(carry ^ cpu->flag_of); \ SET_ZFLAG((r)); \ SET_SFLAG((r)); \ SET_AUXFLAG(carry); \ SET_PFLAG((r)); \ }
#define SET_FLAGS_SUB16(r, op1, op2, msb) { \
DWORD carry = (op1) ^ (op2) ^ (r); \ /* next line is different for ADD/SUB */ \ SET_OFLAG((((op1) ^ (op2)) & ((op1) ^ (r))) << 16); \ SET_CFLAG((carry<<16) ^ cpu->flag_of); \ SET_ZFLAG((r)); \ SET_SFLAG((r) << 16); \ SET_AUXFLAG(carry); \ SET_PFLAG((r)); \ }
#define SET_FLAGS_SUB8(r, op1, op2, msb) { \
DWORD carry = (op1) ^ (op2) ^ (r); \ /* next line is different for ADD/SUB */ \ SET_OFLAG((((op1) ^ (op2)) & ((op1) ^ (r))) << 24); \ SET_CFLAG((carry<<24) ^ cpu->flag_of); \ SET_ZFLAG((r)); \ SET_SFLAG((r) << 24); \ SET_AUXFLAG(carry); \ SET_PFLAG((r)); \ }
#define SET_FLAGS_INC32(r, op1) { \
DWORD carry = (op1) ^ 1 ^ (r); \ /* next line is different for INC/DEC */ \ SET_OFLAG(~((op1) ^ 1) & (1 ^ (r))); \ SET_ZFLAG((r)); \ SET_SFLAG((r)); \ SET_PFLAG((r)); \ SET_AUXFLAG(carry); \ }
#define SET_FLAGS_INC16(r, op1) { \
DWORD carry = (op1) ^ 1 ^ (r); \ /* next line is different for INC/DEC */ \ SET_OFLAG((~((op1) ^ 1) & (1 ^ (r))) << 16); \ SET_ZFLAG((r)); \ SET_PFLAG((r)); \ SET_SFLAG((r) << 16); \ SET_AUXFLAG(carry); \ }
#define SET_FLAGS_INC8(r, op1) { \
DWORD carry = (op1) ^ 1 ^ (r); \ /* next line is different for INC/DEC */ \ SET_OFLAG((~((op1) ^ 1) & (1 ^ (r))) << 24); \ SET_ZFLAG((r)); \ SET_SFLAG((r) << 24); \ SET_PFLAG((r)); \ SET_AUXFLAG(carry); \ }
#define SET_FLAGS_DEC32(r, op1) { \
DWORD carry = (op1) ^ 1 ^ (r); \ /* next line is different for INC/DEC */ \ SET_OFLAG(((op1) ^ 1) & ((op1) ^ (r))); \ SET_ZFLAG((r)); \ SET_SFLAG((r)); \ SET_PFLAG((r)); \ SET_AUXFLAG(carry); \ }
#define SET_FLAGS_DEC16(r, op1) { \
DWORD carry = (op1) ^ 1 ^ (r); \ /* next line is different for INC/DEC */ \ SET_OFLAG((((op1) ^ 1) & ((op1) ^ (r))) << 16); \ SET_ZFLAG((r)); \ SET_SFLAG((r) << 16); \ SET_PFLAG((r)); \ SET_AUXFLAG(carry); \ }
#define SET_FLAGS_DEC8(r, op1) { \
DWORD carry = (op1) ^ 1 ^ (r); \ /* next line is different for INC/DEC */ \ SET_OFLAG((((op1) ^ 1) & ((op1) ^ (r))) << 24); \ SET_ZFLAG((r)); \ SET_SFLAG((r) << 24); \ SET_PFLAG((r)); \ SET_AUXFLAG(carry); \ }
VOID CpuRaiseStatus( NTSTATUS Status );
#endif //FRAGP_H
|