]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
(merge from 20020320)
authorJulian Seward <jseward@acm.org>
Sun, 24 Mar 2002 10:00:09 +0000 (10:00 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 24 Mar 2002 10:00:09 +0000 (10:00 +0000)
Implement x86 das instruction.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12

coregrind/vg_helpers.S
coregrind/vg_include.h
coregrind/vg_main.c
coregrind/vg_to_ucode.c
vg_helpers.S
vg_include.h
vg_main.c
vg_to_ucode.c

index 781175d49b6aaaceb7d65e8bdfeaa8930209d5a1..f86f6f96a1d2247574633d29790f5f9955abb24a 100644 (file)
@@ -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):
index 83d6eae01b3e00abae6168c9b0b6429ac7e485f0..73befe245c639dbd29abb392adebf910891f8b6a 100644 (file)
@@ -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);
index 798d43b0c86b9b3978e8d72c2d3d4572515c9164..a80a79fd389549f52401f3c7d08cec40592de7de 100644 (file)
@@ -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) );
index f31214889a5dc5c014dbe9be9eeeb9b38fdffa67..5cef0b843412e3b2c08a5e5a037e1e6fe9acd2a1 100644 (file)
@@ -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 */
index 781175d49b6aaaceb7d65e8bdfeaa8930209d5a1..f86f6f96a1d2247574633d29790f5f9955abb24a 100644 (file)
@@ -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):
index 83d6eae01b3e00abae6168c9b0b6429ac7e485f0..73befe245c639dbd29abb392adebf910891f8b6a 100644 (file)
@@ -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);
index 798d43b0c86b9b3978e8d72c2d3d4572515c9164..a80a79fd389549f52401f3c7d08cec40592de7de 100644 (file)
--- 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) );
index f31214889a5dc5c014dbe9be9eeeb9b38fdffa67..5cef0b843412e3b2c08a5e5a037e1e6fe9acd2a1 100644 (file)
@@ -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 */