aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/dwarf2out.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/cleanup-13.c15
-rw-r--r--gcc/unwind-dw2.c4
5 files changed, 70 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 82f7061..4449540 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b78c2cc..0a6045a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 33e9cc8..226f136 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/cleanup-13.c b/gcc/testsuite/gcc.dg/cleanup-13.c
index 0a5a9e9..5a0d4c6 100644
--- a/gcc/testsuite/gcc.dg/cleanup-13.c
+++ b/gcc/testsuite/gcc.dg/cleanup-13.c
@@ -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 \
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 28373c2..3cf3189 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -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;