OSDN Git Service

* dwarf2out.c (mem_loc_descriptor): Use DW_OP_mod for UMOD instead
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2010 08:13:50 +0000 (08:13 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2010 08:13:50 +0000 (08:13 +0000)
of MOD, handle MOD using DW_OP_{over,over,div,mul,minus}.
(loc_list_from_tree): Don't handle unsigned division.  Handle
signed modulo using DW_OP_{over,over,div,mul,minus}.
* unwind-dw2.c (execute_stack_op): Handle DW_OP_mod using unsigned
modulo instead of signed.

* gcc.dg/cleanup-13.c: Expect DW_OP_mod to do unsigned modulo instead
of signed, add a few new tests.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156063 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cleanup-13.c
gcc/unwind-dw2.c

index 82f7061..4449540 100644 (file)
@@ -1,3 +1,12 @@
+2010-01-20  Jakub Jelinek  <jakub@redhat.com>
+
+       * dwarf2out.c (mem_loc_descriptor): Use DW_OP_mod for UMOD instead
+       of MOD, handle MOD using DW_OP_{over,over,div,mul,minus}.
+       (loc_list_from_tree): Don't handle unsigned division.  Handle
+       signed modulo using DW_OP_{over,over,div,mul,minus}.
+       * unwind-dw2.c (execute_stack_op): Handle DW_OP_mod using unsigned
+       modulo instead of signed.
+
 2010-01-20  DJ Delorie  <dj@redhat.com>
 
        * config/h8300/h8300.c (F): Add "in_epilogue" flag.
index b78c2cc..0a6045a 100644 (file)
@@ -13129,7 +13129,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
       op = DW_OP_div;
       goto do_binop;
 
-    case MOD:
+    case UMOD:
       op = DW_OP_mod;
       goto do_binop;
 
@@ -13171,6 +13171,24 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
       add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
       break;
 
+    case MOD:
+      op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
+                               VAR_INIT_STATUS_INITIALIZED);
+      op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
+                               VAR_INIT_STATUS_INITIALIZED);
+
+      if (op0 == 0 || op1 == 0)
+       break;
+
+      mem_loc_result = op0;
+      add_loc_descr (&mem_loc_result, op1);
+      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_over, 0, 0));
+      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_over, 0, 0));
+      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_div, 0, 0));
+      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
+      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_minus, 0, 0));
+      break;
+
     case NOT:
       op = DW_OP_not;
       goto do_unop;
@@ -13454,7 +13472,6 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
     case SS_TRUNCATE:
     case US_TRUNCATE:
     case UDIV:
-    case UMOD:
     case UNORDERED:
     case ORDERED:
     case UNEQ:
@@ -14508,6 +14525,8 @@ loc_list_from_tree (tree loc, int want_address)
     case CEIL_DIV_EXPR:
     case ROUND_DIV_EXPR:
     case TRUNC_DIV_EXPR:
+      if (TYPE_UNSIGNED (TREE_TYPE (loc)))
+       return 0;
       op = DW_OP_div;
       goto do_binop;
 
@@ -14519,8 +14538,25 @@ loc_list_from_tree (tree loc, int want_address)
     case CEIL_MOD_EXPR:
     case ROUND_MOD_EXPR:
     case TRUNC_MOD_EXPR:
-      op = DW_OP_mod;
-      goto do_binop;
+      if (TYPE_UNSIGNED (TREE_TYPE (loc)))
+       {
+         op = DW_OP_mod;
+         goto do_binop;
+       }
+      list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
+      list_ret1 = loc_list_from_tree (TREE_OPERAND (loc, 1), 0);
+      if (list_ret == 0 || list_ret1 == 0)
+       return 0;
+
+      add_loc_list (&list_ret, list_ret1);
+      if (list_ret == 0)
+       return 0;
+      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_over, 0, 0));
+      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_over, 0, 0));
+      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_div, 0, 0));
+      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_mul, 0, 0));
+      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_minus, 0, 0));
+      break;
 
     case MULT_EXPR:
       op = DW_OP_mul;
index 33e9cc8..226f136 100644 (file)
@@ -1,3 +1,8 @@
+2010-01-20  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.dg/cleanup-13.c: Expect DW_OP_mod to do unsigned modulo instead
+       of signed, add a few new tests.
+
 2010-01-19  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/42804
index 0a5a9e9..5a0d4c6 100644 (file)
@@ -210,9 +210,22 @@ OP_const1s(-123) OP_abs OP_const1u(123) OP_eq ASSERT_TOS_NON0              \
 OP_lit3 OP_lit6 OP_and OP_lit2 OP_eq ASSERT_TOS_NON0                   \
 OP_lit3 OP_lit6 OP_or OP_lit7 OP_eq ASSERT_TOS_NON0                    \
 OP_lit17 OP_lit2 OP_minus OP_lit15 OP_eq ASSERT_TOS_NON0               \
+/* Divide is signed truncating toward zero.  */                                \
 OP_const1s(-6) OP_const1s(-2) OP_div OP_lit3 OP_eq ASSERT_TOS_NON0     \
-OP_const1s(-6) OP_const1s(-4) OP_mod OP_const1s(-2)                    \
+OP_const1s(-7) OP_const1s(3) OP_div OP_const1s(-2)                     \
   OP_eq ASSERT_TOS_NON0                                                        \
+/* Modulo is unsigned.  */                                             \
+OP_const1s(-6) OP_const1s(-4) OP_mod OP_const1s(-6)                    \
+  OP_eq ASSERT_TOS_NON0                                                        \
+OP_const1s(-6) OP_lit4 OP_mod OP_lit2 OP_eq ASSERT_TOS_NON0            \
+OP_lit6 OP_const1s(-4) OP_mod OP_lit6 OP_eq ASSERT_TOS_NON0            \
+/* Signed modulo can be implemented using "over over div mul minus".  */\
+OP_const1s(-6) OP_const1s(-4) OP_over OP_over OP_div OP_mul OP_minus   \
+  OP_const1s(-2) OP_eq ASSERT_TOS_NON0                                 \
+OP_const1s(-7) OP_lit3 OP_over OP_over OP_div OP_mul OP_minus          \
+  OP_const1s(-1) OP_eq ASSERT_TOS_NON0                                 \
+OP_lit7 OP_const1s(-3) OP_over OP_over OP_div OP_mul OP_minus          \
+  OP_lit1 OP_eq ASSERT_TOS_NON0                                                \
 OP_lit16 OP_lit31 OP_plus_uconst(1) OP_mul OP_const2u(512)             \
   OP_eq ASSERT_TOS_NON0                                                        \
 OP_lit5 OP_not OP_lit31 OP_and OP_lit26 OP_eq ASSERT_TOS_NON0          \
index 28373c2..3cf3189 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF2 exception handling and frame unwind runtime interface routines.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2008, 2009  Free Software Foundation, Inc.
+   2008, 2009, 2010  Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -765,7 +765,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
                result = second - first;
                break;
              case DW_OP_mod:
-               result = (_Unwind_Sword) second % (_Unwind_Sword) first;
+               result = second % first;
                break;
              case DW_OP_mul:
                result = second * first;