From 7a096a16ea88c1cd0c191f289538257b2e323409 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 17 Oct 2004 15:33:52 +0000 Subject: [PATCH] Change flag handling of rotate instructions Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2028 --- src/cpu/flags.cpp | 116 +------------------ src/cpu/instructions.h | 254 +++++++++++++++++++++-------------------- 2 files changed, 134 insertions(+), 236 deletions(-) diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 1ac9000f..fabc39a9 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -42,9 +42,6 @@ Bitu get_CF(void) { case t_DECw: case t_DECd: case t_MUL: - case t_RCLb: - case t_RCLw: - case t_RCLd: return GETFLAG(CF); break; case t_ADDb: @@ -107,18 +104,6 @@ Bitu get_CF(void) { return lf_var1w; case t_NEGd: return lf_var1d; - case t_ROLb: - return lf_resb & 1; - case t_ROLw: - return lf_resw & 1; - case t_ROLd: - return lf_resd & 1; - case t_RORb: - return (lf_resb & 0x80); - case t_RORw: - return (lf_resw & 0x8000); - case t_RORd: - return (lf_resd & 0x80000000); case t_ORb: case t_ORw: case t_ORd: @@ -148,18 +133,6 @@ Bitu get_AF(void) { Bitu type=lflags.type; switch (type) { case t_UNKNOWN: - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: return GETFLAG(AF); case t_ADDb: case t_ADCb: @@ -238,18 +211,6 @@ Bitu get_ZF(void) { Bitu type=lflags.type; switch (type) { case t_UNKNOWN: - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: return GETFLAG(ZF); case t_ADDb: case t_ORb: @@ -318,18 +279,6 @@ Bitu get_SF(void) { Bitu type=lflags.type; switch (type) { case t_UNKNOWN: - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: return GETFLAG(SF); case t_ADDb: case t_ORb: @@ -437,26 +386,14 @@ Bitu get_OF(void) { return (lf_var1w == 0x8000); case t_NEGd: return (lf_var1d == 0x80000000); - case t_ROLb: - case t_RORb: - case t_RCLb: - case t_RCRb: case t_SHLb: case t_SHRb: return (lf_resb ^ lf_var1b) & 0x80; - case t_ROLw: - case t_RORw: - case t_RCLw: - case t_RCRw: case t_SHLw: case t_SHRw: case t_DSHRw: case t_DSHLw: return (lf_resw ^ lf_var1w) & 0x8000; - case t_ROLd: - case t_RORd: - case t_RCLd: - case t_RCRd: case t_SHLd: case t_SHRd: case t_DSHRd: @@ -507,7 +444,7 @@ Bit16u parity_lookup[256] = { Bitu get_PF(void) { switch (lflags.type) { - case t_UNKNOWN: + case t_UNKNOWN: return GETFLAG(PF); default: return (parity_lookup[lf_resb]);; @@ -832,57 +769,6 @@ Bitu FillFlags(void) { DOFLAG_PF; break; - - case t_ROLb: - SET_FLAG(CF,lf_resb & 1); - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_ROLw: - SET_FLAG(CF,lf_resw & 1); - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_ROLd: - SET_FLAG(CF,lf_resd & 1); - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - - - case t_RORb: - SET_FLAG(CF,(lf_resb & 0x80)); - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_RORw: - SET_FLAG(CF,(lf_resw & 0x8000)); - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_RORd: - SET_FLAG(CF,(lf_resd & 0x80000000)); - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - - case t_RCLb: - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_RCLw: - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_RCLd: - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - - case t_RCRb: - SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - break; - case t_RCRw: - SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - break; - case t_RCRd: - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - break; - case t_INCb: SET_FLAG(AF,(lf_resb & 0x0f) == 0); DOFLAG_ZFb; diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index a53ae3e6..a69324ff 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -225,150 +225,162 @@ save(op1,lf_resd); \ lflags.type=t_DECd; -#define ROLB(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (lf_var1b >> (8-lf_var2b)); \ - save(op1,lf_resb); \ - lflags.type=t_ROLb; \ -#define ROLW(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1w=load(op1); \ - lf_var2b=op2&0x0F; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (lf_var1w >> (16-lf_var2b)); \ - save(op1,lf_resw); \ - lflags.type=t_ROLw; \ +#define ROLB(op1,op2,load,save) \ + if (!(op2&0x7)) break; \ + FillFlags(); \ + lf_var1b=load(op1); \ + lf_var2b=op2&0x07; \ + lf_resb=(lf_var1b << lf_var2b) | \ + (lf_var1b >> (8-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,lf_resb & 1); \ + SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); + +#define ROLW(op1,op2,load,save) \ + if (!(op2&0xf)) break; \ + FillFlags(); \ + lf_var1w=load(op1); \ + lf_var2b=op2&0xf; \ + lf_resw=(lf_var1w << lf_var2b) | \ + (lf_var1w >> (16-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,lf_resw & 1); \ + SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); + +#define ROLD(op1,op2,load,save) \ + if (!op2) break; \ + FillFlags(); \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lf_resd=(lf_var1d << lf_var2b) | \ + (lf_var1d >> (32-lf_var2b)); \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,lf_resd & 1); \ + SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31)); -#define ROLD(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d << lf_var2b) | \ - (lf_var1d >> (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_ROLd; \ +#define RORB(op1,op2,load,save) \ + if (!(op2&0x7)) break; \ + FillFlags(); \ + lf_var1b=load(op1); \ + lf_var2b=op2&0x07; \ + lf_resb=(lf_var1b >> lf_var2b) | \ + (lf_var1b << (8-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,lf_resb & 1); \ + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); + +#define RORW(op1,op2,load,save) \ + if (!(op2&0xf)) break; \ + FillFlags(); \ + lf_var1w=load(op1); \ + lf_var2b=op2&0xf; \ + lf_resw=(lf_var1w >> lf_var2b) | \ + (lf_var1w << (16-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,lf_resw & 1); \ + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); + +#define RORD(op1,op2,load,save) \ + if (!op2) break; \ + FillFlags(); \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + lf_resd=(lf_var1d >> lf_var2b) | \ + (lf_var1d << (32-lf_var2b)); \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,lf_resd & 1); \ + if (lf_var2b == 1) SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); -#define RORB(op1,op2,load,save) \ - LoadZF;LoadSF;LoadAF; \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (lf_var1b << (8-lf_var2b)); \ - save(op1,lf_resb); \ - lflags.type=t_RORb; \ - - -#define RORW(op1,op2,load,save) \ - if (op2&0x0F) { \ - LoadZF;LoadSF;LoadAF; \ - lf_var1w=load(op1); \ - lf_var2b=op2&0x0F; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (lf_var1w << (16-lf_var2b)); \ - save(op1,lf_resw); \ - lflags.type=t_RORw; \ - } - -#define RORD(op1,op2,load,save) \ - if (op2) { \ - LoadZF;LoadSF;LoadAF; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (lf_var1d << (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_RORd; \ - } - - -#define RCLB(op1,op2,load,save) \ - if (op2%9) { \ - Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lflags.type=t_RCLb; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1b >> (9-lf_var2b)); \ - SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ - save(op1,lf_resb); \ - } - -#define RCLW(op1,op2,load,save) \ - if (op2%17) { \ - Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lflags.type=t_RCLw; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1w >> (17-lf_var2b)); \ - SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ - save(op1,lf_resw); \ - } - -#define RCLD(op1,op2,load,save) \ - if (op2) { \ - Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lflags.type=t_RCLd; \ - if (lf_var2b==1) { \ - lf_resd=(lf_var1d << 1) | cf; \ - } else { \ - lf_resd=(lf_var1d << lf_var2b) | \ +#define RCLB(op1,op2,load,save) \ + if (!(op2%9)) break; \ +{ Bit8u cf=(Bit8u)FillFlags()&0x1; \ + lf_var1b=load(op1); \ + lf_var2b=op2%9; \ + lf_resb=(lf_var1b << lf_var2b) | \ (cf << (lf_var2b-1)) | \ - (lf_var1d >> (33-lf_var2b)); \ - } \ - SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ - save(op1,lf_resd); \ - } + (lf_var1b >> (9-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7)); \ +} + +#define RCLW(op1,op2,load,save) \ + if (!(op2%17)) break; \ +{ Bit16u cf=(Bit16u)FillFlags()&0x1; \ + lf_var1w=load(op1); \ + lf_var2b=op2%17; \ + lf_resw=(lf_var1w << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1w >> (17-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15)); \ +} + +#define RCLD(op1,op2,load,save) \ + if (!op2) break; \ +{ Bit32u cf=(Bit32u)FillFlags()&0x1; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + if (lf_var2b==1) { \ + lf_resd=(lf_var1d << 1) | cf; \ + } else { \ + lf_resd=(lf_var1d << lf_var2b) | \ + (cf << (lf_var2b-1)) | \ + (lf_var1d >> (33-lf_var2b)); \ + } \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ + SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); \ +} + + #define RCRB(op1,op2,load,save) \ if (op2%9) { \ Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lflags.type=t_RCRb; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (cf << (8-lf_var2b)) | \ - (lf_var1b << (9-lf_var2b)); \ - save(op1,lf_resb); \ + lf_var1b=load(op1); \ + lf_var2b=op2%9; \ + lf_resb=(lf_var1b >> lf_var2b) | \ + (cf << (8-lf_var2b)) | \ + (lf_var1b << (9-lf_var2b)); \ + save(op1,lf_resb); \ + SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); \ + SETFLAGBIT(OF,(lf_resb ^ lf_var1b) & 0x80); \ } #define RCRW(op1,op2,load,save) \ if (op2%17) { \ Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lflags.type=t_RCRw; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (cf << (16-lf_var2b)) | \ - (lf_var1w << (17-lf_var2b)); \ - save(op1,lf_resw); \ + lf_var1w=load(op1); \ + lf_var2b=op2%17; \ + lf_resw=(lf_var1w >> lf_var2b) | \ + (cf << (16-lf_var2b)) | \ + (lf_var1w << (17-lf_var2b)); \ + save(op1,lf_resw); \ + SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); \ + SETFLAGBIT(OF,(lf_resw ^ lf_var1w) & 0x8000); \ } #define RCRD(op1,op2,load,save) \ if (op2) { \ Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lflags.type=t_RCRd; \ - if (lf_var2b==1) { \ - lf_resd=lf_var1d >> 1 | cf << 31; \ + lf_var1d=load(op1); \ + lf_var2b=op2; \ + if (lf_var2b==1) { \ + lf_resd=lf_var1d >> 1 | cf << 31; \ } else { \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (cf << (32-lf_var2b)) | \ - (lf_var1d << (33-lf_var2b)); \ + lf_resd=(lf_var1d >> lf_var2b) | \ + (cf << (32-lf_var2b)) | \ + (lf_var1d << (33-lf_var2b)); \ } \ - save(op1,lf_resd); \ + save(op1,lf_resd); \ + SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); \ + SETFLAGBIT(OF,(lf_resd ^ lf_var1d) & 0x80000000); \ }