Implement setting the direction flag

This commit is contained in:
Theodore Dubois 2018-06-01 12:12:33 -07:00
parent cd310198c6
commit c09571fad3
4 changed files with 15 additions and 4 deletions

View File

@ -76,6 +76,8 @@ struct cpu_state {
#define ZF_FLAG (1 << 6)
#define DF_FLAG (1 << 10)
};
// please pretend this doesn't exist
dword_t df_offset;
// for maximum efficiency these are stored in bytes
byte_t cf;
byte_t of;

View File

@ -6,6 +6,10 @@
andl $~DF_FLAG, CPU_eflags(%_cpu)
gret
.gadget std
orl $DF_FLAG, CPU_eflags(%_cpu)
gret
.macro do_strop op, size, rep, s, ss, a
# repnz is only a thing for cmps and scas
.ifc \rep,repnz
@ -20,11 +24,15 @@
jz 2f
1:
.endif
movl $-(\size/8), CPU_df_offset(%_cpu)
testl $DF_FLAG, CPU_eflags(%_cpu)
jnz 3f
negl CPU_df_offset(%_cpu)
3:
.ifc \op,stos
movl %edi, %_addr
write_prep
mov\ss %\a, (%_addrq)
.else; .ifc \op,movs
movl %esi, %_addr
read_prep
@ -34,10 +42,10 @@
mov\ss %tmp\s, (%_addrq)
.endif; .endif
.ifin(\op, lods,movs,cmps,scas)
addl $(\size/8), %esi
addl CPU_df_offset(%_cpu), %esi
.endifin
.ifin(\op, movs,stos,cmps)
addl $(\size/8), %edi
addl CPU_df_offset(%_cpu), %edi
.endifin
.ifc \rep,rep
decl %ecx

View File

@ -249,7 +249,7 @@ static inline bool gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
#define POPF() UNDEFINED
#define SAHF UNDEFINED
#define CLD g(cld)
#define STD UNDEFINED
#define STD g(std)
#define MUL18(val,z) MUL1(val,z)
#define MUL1(val,z) load(val, z); gz(mul, z)

View File

@ -29,6 +29,7 @@ void cpu() {
OFFSET(CPU, cpu_state, op1);
OFFSET(CPU, cpu_state, op2);
OFFSET(CPU, cpu_state, flags_res);
OFFSET(CPU, cpu_state, df_offset);
MACRO(PF_RES);
MACRO(ZF_RES);
MACRO(SF_RES);