aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-01-20 09:13:50 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2010-01-20 09:13:50 +0100
commit80c35b40e481737a452e96a4a9f89cae6c2b2e68 (patch)
tree3b76f6fe9d8dc678e83b02a7245e921fce8c9690 /gcc/dwarf2out.c
parent204803dc83d90012ceae0b33a7c469098754da33 (diff)
downloadgcc-80c35b40e481737a452e96a4a9f89cae6c2b2e68.zip
gcc-80c35b40e481737a452e96a4a9f89cae6c2b2e68.tar.gz
gcc-80c35b40e481737a452e96a4a9f89cae6c2b2e68.tar.bz2
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
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c44
1 files changed, 40 insertions, 4 deletions
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;