From 01772f27ae4db05a36a2a8c8ffd3d3f5049ec23c Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Sun, 24 Mar 2002 10:00:09 +0000 Subject: [PATCH] (merge from 20020320) Implement x86 das instruction. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12 --- coregrind/vg_helpers.S | 32 ++++++++++++++++++++++++++++++++ coregrind/vg_include.h | 3 +++ coregrind/vg_main.c | 3 +++ coregrind/vg_to_ucode.c | 18 ++++++++++++++++++ vg_helpers.S | 32 ++++++++++++++++++++++++++++++++ vg_include.h | 3 +++ vg_main.c | 3 +++ vg_to_ucode.c | 18 ++++++++++++++++++ 8 files changed, 112 insertions(+) diff --git a/coregrind/vg_helpers.S b/coregrind/vg_helpers.S index 781175d49b..f86f6f96a1 100644 --- a/coregrind/vg_helpers.S +++ b/coregrind/vg_helpers.S @@ -289,6 +289,27 @@ VG_(helper_SAHF): ret +/* Do %al = DAS(%al). Note that the passed param has %AL as the least + significant 8 bits, since it was generated with GETB %AL, + some-temp. Fortunately %al is the least significant 8 bits of + %eax anyway, which is why it's safe to work with %eax as a + whole. + + On entry: + value of %eax + RA <- %esp +*/ +.global VG_(helper_DAS) +VG_(helper_DAS): + pushl %eax + movl 8(%esp), %eax + das + movl %eax, 8(%esp) + popl %eax + ret + + + /* Bit scan forwards/reverse. Sets flags (??). On entry: value, replaced by result @@ -316,6 +337,17 @@ VG_(helper_bsf): src dst RA <- %esp + + NOTE all these are basically misimplemented, since for memory + operands it appears the index value can be arbitrary, and the + address should be calculated accordingly. Here, we assume (by + forcing the register- and memory- versions to be handled by + the same helper) that the offset is always in the range + 0 .. word-size-1, or to be more precise by implementing the + client's memory- version of this using the register- version, + we impose the condition that the offset is used + modulo-wordsize. This is just plain wrong and should be + fixed. */ .global VG_(helper_bt) VG_(helper_bt): diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 83d6eae01b..73befe245c 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -617,6 +617,7 @@ typedef UChar FlagSet; #define FlagsSZACP ( FlagS | FlagZ | FlagA | FlagC | FlagP) #define FlagsSZAP ( FlagS | FlagZ | FlagA | FlagP) #define FlagsOC (FlagO | FlagC ) +#define FlagsAC ( FlagA | FlagC ) #define FlagsALL (FlagsOSZACP | FlagD) #define FlagsEmpty (FlagSet)0 @@ -1292,6 +1293,7 @@ extern void VG_(helper_bsr); extern void VG_(helper_fstsw_AX); extern void VG_(helper_SAHF); +extern void VG_(helper_DAS); extern void VG_(helper_value_check4_fail); extern void VG_(helper_value_check2_fail); @@ -1420,6 +1422,7 @@ extern Int VGOFF_(helper_bsr); extern Int VGOFF_(helper_fstsw_AX); extern Int VGOFF_(helper_SAHF); +extern Int VGOFF_(helper_DAS); extern Int VGOFF_(helper_value_check4_fail); extern Int VGOFF_(helper_value_check2_fail); diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index 798d43b0c8..a80a79fd38 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -94,6 +94,7 @@ Int VGOFF_(helper_bsf) = INVALID_OFFSET; Int VGOFF_(helper_bsr) = INVALID_OFFSET; Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET; Int VGOFF_(helper_SAHF) = INVALID_OFFSET; +Int VGOFF_(helper_DAS) = INVALID_OFFSET; Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET; Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET; Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET; @@ -300,6 +301,8 @@ static void vg_init_baseBlock ( void ) = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) ); VGOFF_(helper_SAHF) = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) ); + VGOFF_(helper_DAS) + = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) ); VGOFF_(helper_request_normal_exit) = alloc_BaB_1_set( (Addr) & VG_(helper_request_normal_exit) ); diff --git a/coregrind/vg_to_ucode.c b/coregrind/vg_to_ucode.c index f31214889a..5cef0b8434 100644 --- a/coregrind/vg_to_ucode.c +++ b/coregrind/vg_to_ucode.c @@ -3018,6 +3018,24 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd ) if (dis) VG_(printf)("leave"); break; + /* ---------------- Misc wierd-ass insns --------------- */ + + case 0x2F: /* DAS */ + t1 = newTemp(cb); + uInstr2(cb, GET, 1, ArchReg, R_AL, TempReg, t1); + /* Widen %AL to 32 bits, so it's all defined when we push it. */ + uInstr1(cb, WIDEN, 4, TempReg, t1); + LAST_UINSTR(cb).extra4b = 1; + LAST_UINSTR(cb).signed_widen = False; + uInstr0(cb, CALLM_S, 0); + uInstr1(cb, PUSH, 4, TempReg, t1); + uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_DAS) ); + uFlagsRWU(cb, FlagsAC, FlagsOSZACP, FlagsEmpty); + uInstr1(cb, POP, 4, TempReg, t1); + uInstr0(cb, CALLM_E, 0); + uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, R_AL); + if (dis) VG_(printf)("das\n"); + /* ------------------------ CWD/CDQ -------------------- */ case 0x98: /* CBW */ diff --git a/vg_helpers.S b/vg_helpers.S index 781175d49b..f86f6f96a1 100644 --- a/vg_helpers.S +++ b/vg_helpers.S @@ -289,6 +289,27 @@ VG_(helper_SAHF): ret +/* Do %al = DAS(%al). Note that the passed param has %AL as the least + significant 8 bits, since it was generated with GETB %AL, + some-temp. Fortunately %al is the least significant 8 bits of + %eax anyway, which is why it's safe to work with %eax as a + whole. + + On entry: + value of %eax + RA <- %esp +*/ +.global VG_(helper_DAS) +VG_(helper_DAS): + pushl %eax + movl 8(%esp), %eax + das + movl %eax, 8(%esp) + popl %eax + ret + + + /* Bit scan forwards/reverse. Sets flags (??). On entry: value, replaced by result @@ -316,6 +337,17 @@ VG_(helper_bsf): src dst RA <- %esp + + NOTE all these are basically misimplemented, since for memory + operands it appears the index value can be arbitrary, and the + address should be calculated accordingly. Here, we assume (by + forcing the register- and memory- versions to be handled by + the same helper) that the offset is always in the range + 0 .. word-size-1, or to be more precise by implementing the + client's memory- version of this using the register- version, + we impose the condition that the offset is used + modulo-wordsize. This is just plain wrong and should be + fixed. */ .global VG_(helper_bt) VG_(helper_bt): diff --git a/vg_include.h b/vg_include.h index 83d6eae01b..73befe245c 100644 --- a/vg_include.h +++ b/vg_include.h @@ -617,6 +617,7 @@ typedef UChar FlagSet; #define FlagsSZACP ( FlagS | FlagZ | FlagA | FlagC | FlagP) #define FlagsSZAP ( FlagS | FlagZ | FlagA | FlagP) #define FlagsOC (FlagO | FlagC ) +#define FlagsAC ( FlagA | FlagC ) #define FlagsALL (FlagsOSZACP | FlagD) #define FlagsEmpty (FlagSet)0 @@ -1292,6 +1293,7 @@ extern void VG_(helper_bsr); extern void VG_(helper_fstsw_AX); extern void VG_(helper_SAHF); +extern void VG_(helper_DAS); extern void VG_(helper_value_check4_fail); extern void VG_(helper_value_check2_fail); @@ -1420,6 +1422,7 @@ extern Int VGOFF_(helper_bsr); extern Int VGOFF_(helper_fstsw_AX); extern Int VGOFF_(helper_SAHF); +extern Int VGOFF_(helper_DAS); extern Int VGOFF_(helper_value_check4_fail); extern Int VGOFF_(helper_value_check2_fail); diff --git a/vg_main.c b/vg_main.c index 798d43b0c8..a80a79fd38 100644 --- a/vg_main.c +++ b/vg_main.c @@ -94,6 +94,7 @@ Int VGOFF_(helper_bsf) = INVALID_OFFSET; Int VGOFF_(helper_bsr) = INVALID_OFFSET; Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET; Int VGOFF_(helper_SAHF) = INVALID_OFFSET; +Int VGOFF_(helper_DAS) = INVALID_OFFSET; Int VGOFF_(helper_value_check4_fail) = INVALID_OFFSET; Int VGOFF_(helper_value_check2_fail) = INVALID_OFFSET; Int VGOFF_(helper_value_check1_fail) = INVALID_OFFSET; @@ -300,6 +301,8 @@ static void vg_init_baseBlock ( void ) = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) ); VGOFF_(helper_SAHF) = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) ); + VGOFF_(helper_DAS) + = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) ); VGOFF_(helper_request_normal_exit) = alloc_BaB_1_set( (Addr) & VG_(helper_request_normal_exit) ); diff --git a/vg_to_ucode.c b/vg_to_ucode.c index f31214889a..5cef0b8434 100644 --- a/vg_to_ucode.c +++ b/vg_to_ucode.c @@ -3018,6 +3018,24 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd ) if (dis) VG_(printf)("leave"); break; + /* ---------------- Misc wierd-ass insns --------------- */ + + case 0x2F: /* DAS */ + t1 = newTemp(cb); + uInstr2(cb, GET, 1, ArchReg, R_AL, TempReg, t1); + /* Widen %AL to 32 bits, so it's all defined when we push it. */ + uInstr1(cb, WIDEN, 4, TempReg, t1); + LAST_UINSTR(cb).extra4b = 1; + LAST_UINSTR(cb).signed_widen = False; + uInstr0(cb, CALLM_S, 0); + uInstr1(cb, PUSH, 4, TempReg, t1); + uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_DAS) ); + uFlagsRWU(cb, FlagsAC, FlagsOSZACP, FlagsEmpty); + uInstr1(cb, POP, 4, TempReg, t1); + uInstr0(cb, CALLM_E, 0); + uInstr2(cb, PUT, 1, TempReg, t1, ArchReg, R_AL); + if (dis) VG_(printf)("das\n"); + /* ------------------------ CWD/CDQ -------------------- */ case 0x98: /* CBW */ -- 2.47.2