From 80c35b40e481737a452e96a4a9f89cae6c2b2e68 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 20 Jan 2010 09:13:50 +0100 Subject: [PATCH] dwarf2out.c (mem_loc_descriptor): Use DW_OP_mod for UMOD instead of MOD... * 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. * gcc.dg/cleanup-13.c: Expect DW_OP_mod to do unsigned modulo instead of signed, add a few new tests. From-SVN: r156063 --- gcc/ChangeLog | 9 +++++++ gcc/dwarf2out.c | 44 ++++++++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/cleanup-13.c | 15 ++++++++++- gcc/unwind-dw2.c | 4 +-- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 82f70614a2c..44495403a51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-01-20 Jakub Jelinek + + * 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 * config/h8300/h8300.c (F): Add "in_epilogue" flag. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b78c2cc0a33..0a6045a4a87 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 33e9cc84bf7..226f13668d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 Jakub Jelinek + + * 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 PR fortran/42804 diff --git a/gcc/testsuite/gcc.dg/cleanup-13.c b/gcc/testsuite/gcc.dg/cleanup-13.c index 0a5a9e9153e..5a0d4c69f5a 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 28373c20bd8..3cf3189bb4f 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; -- 2.30.2