From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10982 invoked by alias); 9 Jun 2011 17:42:06 -0000 Received: (qmail 10972 invoked by uid 22791); 9 Jun 2011 17:42:03 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 09 Jun 2011 17:41:42 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p59Hfg3H029640 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 9 Jun 2011 13:41:42 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p59Hfd45003318 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 9 Jun 2011 13:41:40 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost.localdomain [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id p59HfdH6028109; Thu, 9 Jun 2011 19:41:39 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id p59HfcpX028107; Thu, 9 Jun 2011 19:41:38 +0200 Date: Thu, 09 Jun 2011 18:34:00 -0000 From: Jakub Jelinek To: Richard Henderson , Jason Merrill , Cary Coutant Cc: gcc-patches@gcc.gnu.org, Roland McGrath , Jan Kratochvil , Tom Tromey , Mark Wielaard Subject: Re: Typed DWARF stack and convert to untyped Message-ID: <20110609174137.GQ17079@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek References: <20110325113237.GY18914@tyan-ft48-01.lab.bos.redhat.com> <20110609145319.GO17079@tyan-ft48-01.lab.bos.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110609145319.GO17079@tyan-ft48-01.lab.bos.redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-06/txt/msg00753.txt.bz2 On Thu, Jun 09, 2011 at 04:53:19PM +0200, Jakub Jelinek wrote: > I'd like to propose convert to untyped operation, e.g. > DW_OP_GNU_convert <0> could do it (and maybe DW_OP_GNU_reinterpret <0>), > these would convert to an integral value of the same size as DWARF > address and make it untyped. As DW_OP_GNU_convert operand is > uleb128 DIE offset within current CU, offset 0 certainly won't > contain any DIEs, because it is the first byte of the CU header. And here is a rough patch that implements it, in case you agree with that (and also switches from defaulting to signed types to defaulting to unsigned types, as those have defined overflow for say addition/subtraction etc.). Untested so far. Testcase where the convert to untyped is used is e.g.: void foo (unsigned long long a, unsigned long long b) { unsigned long long c = a / b; long long d = c; long long e = d % 17; } Although long is <= DWARF2_ADDR_SIZE here, for unsigned division we have to change the arguments to typed unsigned 64-bit, then DW_OP_div, and then we just used to convert to typed signed 64-bit and mod was performed with the other argument DW_OP_lit17 instead of DW_OP_const_type <17>. With the patch the result of DW_OP_div is converted to untyped and the rest is performed in untyped. 2011-06-09 Jakub Jelinek * dwarf2out.c (size_of_loc_descr, output_loc_operands, mark_base_types, hash_loc_operands, compare_loc_operands): Allow DW_OP_GNU_convert and DW_OP_GNU_reinterpret to use constant instead of base type reference as argument. (resolve_addr_in_expr): Likewise. Fix keep computation. (convert_descriptor_to_signed): Renamed to... (convert_descriptor_to_mode): ... this. For wider types convert to unsigned instead of signed, for <= DWARF2_ADDR_SIZE convert to untyped. (typed_binop): New function. (scompare_loc_descriptor, ucompare_loc_descriptor, minmax_loc_descriptor, mem_loc_descriptor): For wider integer modes default to unsigned type instead of signed. --- gcc/dwarf2out.c.jj 2011-06-09 16:56:50.000000000 +0200 +++ gcc/dwarf2out.c 2011-06-09 19:15:26.000000000 +0200 @@ -5076,11 +5076,15 @@ size_of_loc_descr (dw_loc_descr_ref loc) break; case DW_OP_GNU_convert: case DW_OP_GNU_reinterpret: - { - unsigned long o - = get_base_type_offset (loc->dw_loc_oprnd1.v.val_die_ref.die); - size += size_of_uleb128 (o); - } + if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const) + size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); + else + { + unsigned long o + = get_base_type_offset (loc->dw_loc_oprnd1.v.val_die_ref.die); + size += size_of_uleb128 (o); + } + break; default: break; } @@ -5456,11 +5460,14 @@ output_loc_operands (dw_loc_descr_ref lo break; case DW_OP_GNU_convert: case DW_OP_GNU_reinterpret: - { - unsigned long o = get_base_type_offset (val1->v.val_die_ref.die); - gcc_assert (o); - dw2_asm_output_data_uleb128 (o, NULL); - } + if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const) + dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); + else + { + unsigned long o = get_base_type_offset (val1->v.val_die_ref.die); + gcc_assert (o); + dw2_asm_output_data_uleb128 (o, NULL); + } break; default: @@ -13824,27 +13831,24 @@ base_type_for_mode (enum machine_mode mo return type_die; } -/* For OP descriptor assumed to be in unsigned MODE, convert it to a signed - type matching MODE, or, if MODE is narrower than DWARF2_ADDR_SIZE, signed - type matching DWARF2_ADDR_SIZE. Return NULL if the conversion is not +/* For OP descriptor assumed to be in unsigned MODE, convert it to a unsigned + type matching MODE, or, if MODE is narrower than or as wide as + DWARF2_ADDR_SIZE, untyped. Return NULL if the conversion is not possible. */ static dw_loc_descr_ref -convert_descriptor_to_signed (enum machine_mode mode, dw_loc_descr_ref op) +convert_descriptor_to_mode (enum machine_mode mode, dw_loc_descr_ref op) { enum machine_mode outer_mode = mode; dw_die_ref type_die; dw_loc_descr_ref cvt; - if (GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE) + if (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE) { - outer_mode = mode_for_size (DWARF2_ADDR_SIZE * BITS_PER_UNIT, - MODE_INT, 0); - if (outer_mode == BLKmode - || GET_MODE_SIZE (outer_mode) != DWARF2_ADDR_SIZE) - return NULL; + add_loc_descr (&op, new_loc_descr (DW_OP_GNU_convert, 0, 0)); + return op; } - type_die = base_type_for_mode (outer_mode, 0); + type_die = base_type_for_mode (outer_mode, 1); if (type_die == NULL) return NULL; cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); @@ -13901,9 +13905,29 @@ scompare_loc_descriptor (enum dwarf_loca return NULL; if (GET_MODE_CLASS (op_mode) != MODE_INT - || GET_MODE_SIZE (op_mode) >= DWARF2_ADDR_SIZE) + || GET_MODE_SIZE (op_mode) == DWARF2_ADDR_SIZE) return compare_loc_descriptor (op, op0, op1); + if (GET_MODE_SIZE (op_mode) > DWARF2_ADDR_SIZE) + { + dw_die_ref type_die = base_type_for_mode (op_mode, 0); + dw_loc_descr_ref cvt; + + if (type_die == NULL) + return NULL; + cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); + cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; + cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; + add_loc_descr (&op0, cvt); + cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); + cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; + cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; + add_loc_descr (&op1, cvt); + return compare_loc_descriptor (op, op0, op1); + } + shift = (DWARF2_ADDR_SIZE - GET_MODE_SIZE (op_mode)) * BITS_PER_UNIT; /* For eq/ne, if the operands are known to be zero-extended, there is no need to do the fancy shifting up. */ @@ -13959,9 +13983,6 @@ ucompare_loc_descriptor (enum dwarf_loca if (dwarf_strict && GET_MODE_SIZE (op_mode) > DWARF2_ADDR_SIZE) return NULL; - if (op_mode != VOIDmode && GET_MODE_CLASS (op_mode) != MODE_INT) - return NULL; - op0 = mem_loc_descriptor (XEXP (rtl, 0), op_mode, mem_mode, VAR_INIT_STATUS_INITIALIZED); op1 = mem_loc_descriptor (XEXP (rtl, 1), op_mode, mem_mode, @@ -14009,24 +14030,6 @@ ucompare_loc_descriptor (enum dwarf_loca add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst, bias, 0)); } - else - { - dw_die_ref type_die = base_type_for_mode (op_mode, 1); - dw_loc_descr_ref cvt; - - if (type_die == NULL) - return NULL; - cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); - cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; - cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; - cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; - add_loc_descr (&op0, cvt); - cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); - cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; - cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; - cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; - add_loc_descr (&op1, cvt); - } return compare_loc_descriptor (op, op0, op1); } @@ -14073,23 +14076,6 @@ minmax_loc_descriptor (rtx rtl, enum mac add_loc_descr (&op0, new_loc_descr (DW_OP_plus_uconst, bias, 0)); add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst, bias, 0)); } - else - { - dw_die_ref type_die = base_type_for_mode (mode, 1); - dw_loc_descr_ref cvt; - if (type_die == NULL) - return NULL; - cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); - cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; - cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; - cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; - add_loc_descr (&op0, cvt); - cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); - cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; - cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; - cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; - add_loc_descr (&op1, cvt); - } } else if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE) @@ -14100,6 +14086,24 @@ minmax_loc_descriptor (rtx rtl, enum mac add_loc_descr (&op1, int_loc_descriptor (shift)); add_loc_descr (&op1, new_loc_descr (DW_OP_shl, 0, 0)); } + else if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE) + { + dw_die_ref type_die = base_type_for_mode (mode, 0); + dw_loc_descr_ref cvt; + if (type_die == NULL) + return NULL; + cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); + cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; + cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; + add_loc_descr (&op0, cvt); + cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); + cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; + cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; + add_loc_descr (&op1, cvt); + } if (GET_CODE (rtl) == SMIN || GET_CODE (rtl) == UMIN) op = DW_OP_lt; @@ -14115,9 +14119,46 @@ minmax_loc_descriptor (rtx rtl, enum mac add_loc_descr (&ret, drop_node); bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc; bra_node->dw_loc_oprnd1.v.val_loc = drop_node; + if ((GET_CODE (rtl) == SMIN || GET_CODE (rtl) == SMAX) + && GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE) + ret = convert_descriptor_to_mode (mode, ret); return ret; } +/* Helper function for mem_loc_descriptor. Perform OP binary op, + but after converting arguments to type_die, afterwards + convert back to unsigned. */ + +static dw_loc_descr_ref +typed_binop (enum dwarf_location_atom op, rtx rtl, dw_die_ref type_die, + enum machine_mode mode, enum machine_mode mem_mode) +{ + dw_loc_descr_ref cvt, op0, op1; + + if (type_die == NULL) + return NULL; + op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode, + VAR_INIT_STATUS_INITIALIZED); + op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode, + VAR_INIT_STATUS_INITIALIZED); + if (op0 == NULL || op1 == NULL) + return NULL; + cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); + cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; + cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; + add_loc_descr (&op0, cvt); + cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); + cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; + cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; + add_loc_descr (&op1, cvt); + add_loc_descr (&op0, op1); + add_loc_descr (&op0, new_loc_descr (op, 0, 0)); + return convert_descriptor_to_mode (mode, op0); +} + /* CLZ (where constV is CLZ_DEFINED_VALUE_AT_ZERO computed value, const0 is DW_OP_lit0 or corresponding typed constant, const1 is DW_OP_lit1 or corresponding typed constant @@ -14562,7 +14603,8 @@ mem_loc_descriptor (rtx rtl, enum machin mem_mode, initialized); if (mem_loc_result == NULL) break; - type_die = base_type_for_mode (mode, 0); + type_die = base_type_for_mode (mode, + GET_MODE_CLASS (mode) == MODE_INT); if (type_die == NULL) { mem_loc_result = NULL; @@ -14594,7 +14636,8 @@ mem_loc_descriptor (rtx rtl, enum machin break; if (REGNO (rtl) > FIRST_PSEUDO_REGISTER) break; - type_die = base_type_for_mode (mode, 0); + type_die = base_type_for_mode (mode, + GET_MODE_CLASS (mode) == MODE_INT); if (type_die == NULL) break; mem_loc_result = new_loc_descr (DW_OP_GNU_regval_type, @@ -14677,7 +14720,7 @@ mem_loc_descriptor (rtx rtl, enum machin GET_CODE (rtl) == ZERO_EXTEND); if (type_die1 == NULL) break; - type_die2 = base_type_for_mode (mode, 0); + type_die2 = base_type_for_mode (mode, 1); if (type_die2 == NULL) break; mem_loc_result = op0; @@ -14710,7 +14753,8 @@ mem_loc_descriptor (rtx rtl, enum machin if (dwarf_strict) return NULL; - type_die = base_type_for_mode (mode, 0); + type_die + = base_type_for_mode (mode, GET_MODE_CLASS (mode) == MODE_INT); if (type_die == NULL) return NULL; deref = new_loc_descr (DW_OP_GNU_deref_type, @@ -14861,12 +14905,11 @@ mem_loc_descriptor (rtx rtl, enum machin loc_descr_plus_const (&mem_loc_result, INTVAL (XEXP (rtl, 1))); else { - dw_loc_descr_ref mem_loc_result2 - = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode, - VAR_INIT_STATUS_INITIALIZED); - if (mem_loc_result2 == 0) + op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode, + VAR_INIT_STATUS_INITIALIZED); + if (op1 == 0) break; - add_loc_descr (&mem_loc_result, mem_loc_result2); + add_loc_descr (&mem_loc_result, op1); add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_plus, 0, 0)); } @@ -14884,6 +14927,15 @@ mem_loc_descriptor (rtx rtl, enum machin goto do_binop; case DIV: + if (!dwarf_strict + && GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE) + { + mem_loc_result = typed_binop (DW_OP_div, rtl, + base_type_for_mode (mode, 0), + mode, mem_mode); + break; + } op = DW_OP_div; goto do_binop; @@ -14955,12 +15007,10 @@ mem_loc_descriptor (rtx rtl, enum machin case MOD: if (GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE && !dwarf_strict) { - /* If MODE is wider than DWARF2_ADDR_SIZE, mem_loc_descriptor - should return signed typed values and therefore DW_OP_mod - won't be unsigned as it defaults for untyped stack values, - but signed. */ - op = DW_OP_mod; - goto do_binop; + mem_loc_result = typed_binop (DW_OP_mod, rtl, + base_type_for_mode (mode, 0), + mode, mem_mode); + break; } op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode, @@ -14983,32 +15033,14 @@ mem_loc_descriptor (rtx rtl, enum machin case UDIV: if (!dwarf_strict && GET_MODE_CLASS (mode) == MODE_INT) { - dw_die_ref type_die; - dw_loc_descr_ref cvt; - - type_die = base_type_for_mode (mode, 1); - if (type_die == NULL) - break; - op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode, - VAR_INIT_STATUS_INITIALIZED); - op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode, - VAR_INIT_STATUS_INITIALIZED); - if (op0 == 0 || op1 == 0) - break; - cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); - cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; - cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; - cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; - add_loc_descr (&op0, cvt); - cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); - cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref; - cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; - cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; - add_loc_descr (&op1, cvt); - mem_loc_result = op0; - add_loc_descr (&mem_loc_result, op1); - add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_div, 0, 0)); - mem_loc_result = convert_descriptor_to_signed (mode, mem_loc_result); + if (GET_MODE_CLASS (mode) > DWARF2_ADDR_SIZE) + { + op = DW_OP_div; + goto do_binop; + } + mem_loc_result = typed_binop (DW_OP_div, rtl, + base_type_for_mode (mode, 1), + mode, mem_mode); } break; @@ -15051,7 +15083,7 @@ mem_loc_descriptor (rtx rtl, enum machin && (GET_MODE_BITSIZE (mode) == HOST_BITS_PER_WIDE_INT || GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT)) { - dw_die_ref type_die = base_type_for_mode (mode, 0); + dw_die_ref type_die = base_type_for_mode (mode, 1); if (type_die == NULL) return NULL; mem_loc_result = new_loc_descr (DW_OP_GNU_const_type, 0, @@ -15084,7 +15116,8 @@ mem_loc_descriptor (rtx rtl, enum machin || (GET_MODE (rtl) == VOIDmode && GET_MODE_BITSIZE (mode) != 2 * HOST_BITS_PER_WIDE_INT)) break; - type_die = base_type_for_mode (mode, 0); + type_die = base_type_for_mode (mode, + GET_MODE_CLASS (mode) == MODE_INT); if (type_die == NULL) return NULL; mem_loc_result = new_loc_descr (DW_OP_GNU_const_type, 0, 0); @@ -15248,7 +15281,7 @@ mem_loc_descriptor (rtx rtl, enum machin if (op0 == NULL) break; if (GET_MODE_CLASS (GET_MODE (XEXP (rtl, 0))) == MODE_INT - && (GET_CODE (rtl) == UNSIGNED_FLOAT + && (GET_CODE (rtl) == FLOAT || GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0))) <= DWARF2_ADDR_SIZE)) { @@ -15271,10 +15304,10 @@ mem_loc_descriptor (rtx rtl, enum machin cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; add_loc_descr (&op0, cvt); if (GET_MODE_CLASS (mode) == MODE_INT - && (GET_CODE (rtl) == UNSIGNED_FIX + && (GET_CODE (rtl) == FIX || GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE)) { - op0 = convert_descriptor_to_signed (mode, op0); + op0 = convert_descriptor_to_mode (mode, op0); if (op0 == NULL) break; } @@ -23999,9 +24032,12 @@ mark_base_types (dw_loc_descr_ref loc) case DW_OP_GNU_deref_type: base_type = loc->dw_loc_oprnd2.v.val_die_ref.die; break; - case DW_OP_GNU_const_type: case DW_OP_GNU_convert: case DW_OP_GNU_reinterpret: + if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const) + continue; + /* FALLTHRU */ + case DW_OP_GNU_const_type: base_type = loc->dw_loc_oprnd1.v.val_die_ref.die; break; case DW_OP_GNU_entry_value: @@ -24189,8 +24225,14 @@ resolve_addr_in_expr (dw_loc_descr_ref l if (loc->dw_loc_opc == DW_OP_GNU_regval_type || loc->dw_loc_opc == DW_OP_GNU_deref_type) base1 = loc->dw_loc_oprnd2.v.val_die_ref.die; + else if (loc->dw_loc_oprnd1.val_class + == dw_val_class_unsigned_const) + break; else base1 = loc->dw_loc_oprnd1.v.val_die_ref.die; + if (loc->dw_loc_next->dw_loc_oprnd1.val_class + == dw_val_class_unsigned_const) + break; base2 = loc->dw_loc_next->dw_loc_oprnd1.v.val_die_ref.die; gcc_assert (base1->die_tag == DW_TAG_base_type && base2->die_tag == DW_TAG_base_type); @@ -24217,7 +24259,7 @@ resolve_addr_in_expr (dw_loc_descr_ref l /* Don't change integer DW_OP_GNU_convert after e.g. floating point typed stack entry. */ else if (enc1 != DW_ATE_unsigned && enc1 != DW_ATE_signed) - keep = loc; + keep = loc->dw_loc_next; break; } break; @@ -24483,6 +24525,12 @@ hash_loc_operands (dw_loc_descr_ref loc, break; case DW_OP_GNU_convert: case DW_OP_GNU_reinterpret: + if (val1->val_class == dw_val_class_unsigned_const) + { + hash = iterative_hash_object (val1->v.val_unsigned, hash); + break; + } + /* FALLTHRU */ case DW_OP_GNU_const_type: { unsigned int byte_size @@ -24704,6 +24752,10 @@ compare_loc_operands (dw_loc_descr_ref x && valx2->v.val_die_ref.die == valy2->v.val_die_ref.die; case DW_OP_GNU_convert: case DW_OP_GNU_reinterpret: + if (valx1->val_class != valy1->val_class) + return false; + if (valx1->val_class == dw_val_class_unsigned_const) + return valx1->v.val_unsigned == valy1->v.val_unsigned; return valx1->v.val_die_ref.die == valy1->v.val_die_ref.die; default: /* Other codes have no operands. */ Jakub