/*++ 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