Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* RFC: implement typed DWARF stack
@ 2011-05-04 20:48 Tom Tromey
  2011-05-05 16:47 ` Tom Tromey
  2011-05-05 18:07 ` Ulrich Weigand
  0 siblings, 2 replies; 25+ messages in thread
From: Tom Tromey @ 2011-05-04 20:48 UTC (permalink / raw)
  To: gdb-patches

I would appreciate comments on this.  In the absence of comments I am
going to check it in.

Jakub recently implemented Cary Coutant's typed DWARF stack proposal in
GCC.

Cary's proposal:

    http://www.dwarfstd.org/doc/040408.1.html

The GCC thread:

    http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01730.html

This patch converts the DWARF expression evaluator to use GDB's value
types.  This approach made it easy to support floating point and also
decimal floating point; and also paves the way for any future
improvements.

There is some ugliness involving signed and unsigned types; this arises
because "old-style" untyped DWARF values don't have a consistent type.
Also I needed a little bit of special code to handle logical right
shifts.

The test case comes from Jakub.  I am checking in just the x86 variant.
I modified the .c file slightly (just comments) to XFAIL the cases known
not to work.

Built and regtested on our internal buildbot.  This tests on x86-64 F14
in 4 different configurations.

Tom

2011-05-04  Tom Tromey  <tromey@redhat.com>

	* dwarf2read.c (dwarf_stack_op_name): Add new values.
	(dwarf2_get_die_type): New function.
	* dwarf2loc.c (dwarf_expr_get_base_type): New function.
	(allocate_piece_closure): Acquire reference to values.
	(read_pieced_value): Update for value-based expressions.
	(write_pieced_value): Likewise.
	(free_pieced_value_closure): Call value_free as needed.
	(dwarf2_evaluate_loc_desc_full): Set get_base_type field.
	Update for value-based expressions.
	* dwarf2loc.h (dwarf2_get_die_type): Declare.
	* dwarf2expr.h (struct dwarf_stack_value) <value>: Change type.
	<get_base_type>: New field.
	(struct dwarf_expr_piece) <value>: Change type.
	(dwarf_expr_piece, dwarf_expr_fetch): Update.
	(dwarf_expr_pop): Remove.
	(dwarf_expr_address_type): Declare.
	* dwarf2expr.c (dwarf_arch_cookie): New global.
	(struct dwarf_gdbarch_types): New.
	(dwarf_gdbarch_types_init, dwarf_expr_address_type): New
	functions.
	(dwarf_expr_push): Change type of 'value' argument.  Update.
	(dwarf_expr_pop): Now static.
	(dwarf_expr_fetch): Change return type.
	(dwarf_require_integral): New function.
	(dwarf_expr_fetch): Simplify.
	(add_piece): Update.
	(base_types_equal_p, dwarf_get_base_type, get_unsigned_type): New
	functions.
	(execute_stack_op) <sign_ext>: Remove.
	Use values for DWARF stack.
	<DW_OP_GNU_const_type, DW_OP_GNU_deref_type,
	DW_OP_GNU_regval_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret>:
	New cases.
	(_initialize_dwarf2expr): New function.
	* dwarf2-frame.c (no_base_type): New function.
	(execute_stack_op): Set get_base_type field.  Update.

2011-05-04  Tom Tromey  <tromey@redhat.com>

	* gdb.dwarf2/typeddwarf.S: New file.
	* gdb.dwarf2/typeddwarf.c: New file.
	* gdb.dwarf2/typeddwarf.exp: New file.

diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index e78c328..f0d1d28 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -353,6 +353,14 @@ no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 		  _("Support for DW_OP_call* is invalid in CFI"));
 }
 
+/* Helper function for execute_stack_op.  */
+
+static struct type *
+no_base_type (struct dwarf_expr_context *ctx, size_t die)
+{
+  error (_("Support for typed DWARF is not supported in CFI"));
+}
+
 /* Execute the required actions for both the DW_CFA_restore and
 DW_CFA_restore_extended instructions.  */
 static void
@@ -406,14 +414,17 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
   ctx->get_frame_pc = no_get_frame_pc;
   ctx->get_tls_address = no_get_tls_address;
   ctx->dwarf_call = no_dwarf_call;
+  ctx->get_base_type = no_base_type;
 
-  dwarf_expr_push (ctx, initial, initial_in_stack_memory);
+  dwarf_expr_push (ctx, value_from_ulongest (dwarf_expr_address_type (ctx, 1),
+					     initial),
+		   initial_in_stack_memory);
   dwarf_expr_eval (ctx, exp, len);
 
   if (ctx->location == DWARF_VALUE_MEMORY)
     result = dwarf_expr_fetch_address (ctx, 0);
   else if (ctx->location == DWARF_VALUE_REGISTER)
-    result = read_reg (this_frame, dwarf_expr_fetch (ctx, 0));
+    result = read_reg (this_frame, value_as_long (dwarf_expr_fetch (ctx, 0)));
   else
     {
       /* This is actually invalid DWARF, but if we ever do run across
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 91fccf9..7b1b8af 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -34,6 +34,54 @@
 static void execute_stack_op (struct dwarf_expr_context *,
 			      const gdb_byte *, const gdb_byte *);
 
+/* Cookie for gdbarch data.  */
+
+static struct gdbarch_data *dwarf_arch_cookie;
+
+/* This holds two gdbarch-specific types used by the DWARF expression
+   evaluator.  */
+
+struct dwarf_gdbarch_types
+{
+  /* The signed "address" type.  */
+  struct type *signed_addr;
+  /* The unsigned "address" type.  */
+  struct type *unsigned_addr;
+};
+
+/* Allocate and fill in dwarf_gdbarch_types for an arch.  */
+
+static void *
+dwarf_gdbarch_types_init (struct gdbarch *gdbarch)
+{
+  struct dwarf_gdbarch_types *types
+    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf_gdbarch_types);
+
+  types->signed_addr
+    = arch_integer_type (gdbarch,
+			 8 * gdbarch_dwarf2_addr_size (gdbarch),
+			 0, "<signed DWARF address type>");
+  types->unsigned_addr
+    = arch_integer_type (gdbarch,
+			 8 * gdbarch_dwarf2_addr_size (gdbarch),
+			 1, "<unsigned DWARF address type>");
+
+  return types;
+}
+
+/* Return the type used for DWARF operations where the type is
+   unspecified in the DWARF spec.  SIGNED_P indicates whether the
+   returned type should be the signed or unsigned variant.  */
+
+struct type *
+dwarf_expr_address_type (struct dwarf_expr_context *ctx, int signed_p)
+{
+  struct dwarf_gdbarch_types *types = gdbarch_data (ctx->gdbarch,
+						    dwarf_arch_cookie);
+
+  return signed_p ? types->signed_addr : types->unsigned_addr;
+}
+
 /* Create a new context for the expression evaluator.  */
 
 struct dwarf_expr_context *
@@ -97,16 +145,11 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
 /* Push VALUE onto CTX's stack.  */
 
 void
-dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
+dwarf_expr_push (struct dwarf_expr_context *ctx, struct value *value,
 		 int in_stack_memory)
 {
   struct dwarf_stack_value *v;
 
-  /* We keep all stack elements within the range defined by the
-     DWARF address size.  */
-  if (ctx->addr_size < sizeof (ULONGEST))
-    value &= ((ULONGEST) 1 << (ctx->addr_size * HOST_CHAR_BIT)) - 1;
-
   dwarf_expr_grow_stack (ctx, 1);
   v = &ctx->stack[ctx->stack_len++];
   v->value = value;
@@ -115,7 +158,7 @@ dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
 
 /* Pop the top item off of CTX's stack.  */
 
-void
+static void
 dwarf_expr_pop (struct dwarf_expr_context *ctx)
 {
   if (ctx->stack_len <= 0)
@@ -125,7 +168,7 @@ dwarf_expr_pop (struct dwarf_expr_context *ctx)
 
 /* Retrieve the N'th item on CTX's stack.  */
 
-ULONGEST
+struct value *
 dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 {
   if (ctx->stack_len <= n)
@@ -133,7 +176,17 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].value;
+}
 
+/* Require that TYPE be an integral type; throw an exception if not.  */
+
+static void
+dwarf_require_integral (struct type *type)
+{
+  if (TYPE_CODE (type) != TYPE_CODE_INT
+      && TYPE_CODE (type) != TYPE_CODE_CHAR
+      && TYPE_CODE (type) != TYPE_CODE_BOOL)
+    error (_("integral type expected in DWARF expression"));
 }
 
 /* Retrieve the N'th item on CTX's stack, converted to an address.  */
@@ -141,41 +194,10 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 CORE_ADDR
 dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n)
 {
-  ULONGEST result = dwarf_expr_fetch (ctx, n);
-
-  /* For most architectures, calling extract_unsigned_integer() alone
-     is sufficient for extracting an address.  However, some
-     architectures (e.g. MIPS) use signed addresses and using
-     extract_unsigned_integer() will not produce a correct
-     result.  Make sure we invoke gdbarch_integer_to_address()
-     for those architectures which require it.  */
-  if (gdbarch_integer_to_address_p (ctx->gdbarch))
-    {
-      enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
-      gdb_byte *buf = alloca (ctx->addr_size);
-      struct type *int_type;
+  struct value *result_val = dwarf_expr_fetch (ctx, n);
 
-      switch (ctx->addr_size)
-	{
-	case 2:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint16;
-	  break;
-	case 4:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint32;
-	  break;
-	case 8:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint64;
-	  break;
-	default:
-	  internal_error (__FILE__, __LINE__,
-			  _("Unsupported address size.\n"));
-	}
-
-      store_unsigned_integer (buf, ctx->addr_size, byte_order, result);
-      return gdbarch_integer_to_address (ctx->gdbarch, int_type, buf);
-    }
-
-  return (CORE_ADDR) result;
+  dwarf_require_integral (value_type (result_val));
+  return value_as_address (result_val);
 }
 
 /* Retrieve the in_stack_memory flag of the N'th item on CTX's stack.  */
@@ -188,7 +210,6 @@ dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n)
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].in_stack_memory;
-
 }
 
 /* Return true if the expression stack is empty.  */
@@ -238,7 +259,7 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset)
   else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
     {
       p->v.ptr.die = ctx->len;
-      p->v.ptr.offset = (LONGEST) dwarf_expr_fetch (ctx, 0);
+      p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0));
     }
   else
     {
@@ -335,6 +356,65 @@ dwarf_expr_require_composition (const gdb_byte *op_ptr, const gdb_byte *op_end,
 	   op_name);
 }
 
+/* Return true iff the types T1 and T2 are "the same".  This only does
+   checks that might reasonably be needed to compare DWARF base
+   types.  */
+
+static int
+base_types_equal_p (struct type *t1, struct type *t2)
+{
+  if (TYPE_CODE (t1) != TYPE_CODE (t2))
+    return 0;
+  if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
+    return 0;
+  return TYPE_LENGTH (t1) == TYPE_LENGTH (t2);
+}
+
+/* A convenience function to call get_base_type on CTX and return the
+   result.  DIE is the DIE whose type we need.  SIZE is non-zero if
+   this function should verify that the resulting type has the correct
+   size.  */
+
+static struct type *
+dwarf_get_base_type (struct dwarf_expr_context *ctx, ULONGEST die, int size)
+{
+  struct type *result;
+
+  if (ctx->get_base_type)
+    {
+      result = ctx->get_base_type (ctx, die);
+      if (size != 0 && TYPE_LENGTH (result) != size)
+	error (_("DW_OP_GNU_const_type has different sizes for type and data"));
+    }
+  else
+    /* Anything will do.  */
+    result = builtin_type (ctx->gdbarch)->builtin_int;
+
+  return result;
+}
+
+/* Return the unsigned form of TYPE.  TYPE is necessarily an integral
+   type.  */
+
+static struct type *
+get_unsigned_type (struct gdbarch *gdbarch, struct type *type)
+{
+  switch (TYPE_LENGTH (type))
+    {
+    case 1:
+      return builtin_type (gdbarch)->builtin_uint8;
+    case 2:
+      return builtin_type (gdbarch)->builtin_uint16;
+    case 4:
+      return builtin_type (gdbarch)->builtin_uint32;
+    case 8:
+      return builtin_type (gdbarch)->builtin_uint64;
+    default:
+      error (_("no unsigned variant found for type, while evaluating "
+	       "DWARF expression"));
+    }
+}
+
 /* The engine for the expression evaluator.  Using the context in CTX,
    evaluate the expression between OP_PTR and OP_END.  */
 
@@ -342,10 +422,9 @@ static void
 execute_stack_op (struct dwarf_expr_context *ctx,
 		  const gdb_byte *op_ptr, const gdb_byte *op_end)
 {
-#define sign_ext(x) ((LONGEST) (((x) ^ sign_bit) - sign_bit))
-  ULONGEST sign_bit = (ctx->addr_size >= sizeof (ULONGEST) ? 0
-		       : ((ULONGEST) 1) << (ctx->addr_size * 8 - 1));
   enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+  struct type *address_type = dwarf_expr_address_type (ctx, 1);
+  struct type *uaddress_type = dwarf_expr_address_type (ctx, 0);
 
   ctx->location = DWARF_VALUE_MEMORY;
   ctx->initialized = 1;  /* Default is initialized.  */
@@ -368,6 +447,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
       int in_stack_memory = 0;
       ULONGEST uoffset, reg;
       LONGEST offset;
+      struct value *result_val = NULL;
 
       switch (op)
 	{
@@ -404,6 +484,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_lit30:
 	case DW_OP_lit31:
 	  result = op - DW_OP_lit0;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_addr:
@@ -416,47 +497,58 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
 	    result += ctx->offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_const1u:
 	  result = extract_unsigned_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const1s:
 	  result = extract_signed_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const2u:
 	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const2s:
 	  result = extract_signed_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const4u:
 	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const4s:
 	  result = extract_signed_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const8u:
 	  result = extract_unsigned_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_const8s:
 	  result = extract_signed_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_constu:
 	  op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = uoffset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 	case DW_OP_consts:
 	  op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	  result = offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	/* The DW_OP_reg operations are required to occur alone in
@@ -502,6 +594,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 		     "or DW_OP_bit_piece."));
 
 	  result = op - DW_OP_reg0;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -510,6 +603,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
 
 	  result = reg;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -547,6 +641,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    /* The byte offset into the data.  */
 	    op_ptr = read_sleb128 (op_ptr, op_end, &len);
 	    result = (ULONGEST) len;
+	    result_val = value_from_ulongest (address_type, result);
 
 	    ctx->location = DWARF_VALUE_IMPLICIT_POINTER;
 	    dwarf_expr_require_composition (op_ptr, op_end,
@@ -590,6 +685,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_bregx:
@@ -598,6 +694,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, reg);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_fbreg:
@@ -620,11 +717,14 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    if (ctx->location == DWARF_VALUE_MEMORY)
 	      result = dwarf_expr_fetch_address (ctx, 0);
 	    else if (ctx->location == DWARF_VALUE_REGISTER)
-	      result = (ctx->read_reg) (ctx->baton, dwarf_expr_fetch (ctx, 0));
+	      result
+		= (ctx->read_reg) (ctx->baton,
+				   value_as_long (dwarf_expr_fetch (ctx, 0)));
 	    else
 	      error (_("Not implemented: computing frame "
 		       "base using explicit value operator"));
 	    result = result + offset;
+	    result_val = value_from_ulongest (address_type, result);
 	    in_stack_memory = 1;
 	    ctx->stack_len = before_stack_len;
 	    ctx->location = DWARF_VALUE_MEMORY;
@@ -632,7 +732,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  break;
 
 	case DW_OP_dup:
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result_val = dwarf_expr_fetch (ctx, 0);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
 	  break;
 
@@ -642,7 +742,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_pick:
 	  offset = *op_ptr++;
-	  result = dwarf_expr_fetch (ctx, offset);
+	  result_val = dwarf_expr_fetch (ctx, offset);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset);
 	  break;
 	  
@@ -662,7 +762,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  }
 
 	case DW_OP_over:
-	  result = dwarf_expr_fetch (ctx, 1);
+	  result_val = dwarf_expr_fetch (ctx, 1);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1);
 	  break;
 
@@ -685,14 +785,27 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_deref:
 	case DW_OP_deref_size:
+	case DW_OP_GNU_deref_type:
 	  {
 	    int addr_size = (op == DW_OP_deref ? ctx->addr_size : *op_ptr++);
 	    gdb_byte *buf = alloca (addr_size);
 	    CORE_ADDR addr = dwarf_expr_fetch_address (ctx, 0);
+	    struct type *type;
+
 	    dwarf_expr_pop (ctx);
 
+	    if (op == DW_OP_GNU_deref_type)
+	      {
+		ULONGEST type_die;
+
+		op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+		type = dwarf_get_base_type (ctx, type_die, 0);
+	      }
+	    else
+	      type = address_type;
+
 	    (ctx->read_mem) (ctx->baton, buf, addr, addr_size);
-	    result = extract_unsigned_integer (buf, addr_size, byte_order);
+	    result_val = value_from_contents_and_address (type, buf, addr);
 	    break;
 	  }
 
@@ -700,27 +813,34 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_neg:
 	case DW_OP_not:
 	case DW_OP_plus_uconst:
-	  /* Unary operations.  */
-	  result = dwarf_expr_fetch (ctx, 0);
-	  dwarf_expr_pop (ctx);
+	  {
+	    /* Unary operations.  */
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
 
-	  switch (op)
-	    {
-	    case DW_OP_abs:
-	      if (sign_ext (result) < 0)
-		result = -result;
-	      break;
-	    case DW_OP_neg:
-	      result = -result;
-	      break;
-	    case DW_OP_not:
-	      result = ~result;
-	      break;
-	    case DW_OP_plus_uconst:
-	      op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-	      result += reg;
-	      break;
-	    }
+	    switch (op)
+	      {
+	      case DW_OP_abs:
+		if (value_less (result_val,
+				value_zero (value_type (result_val), not_lval)))
+		  result_val = value_neg (result_val);
+		break;
+	      case DW_OP_neg:
+		result_val = value_neg (result_val);
+		break;
+	      case DW_OP_not:
+		dwarf_require_integral (value_type (result_val));
+		result_val = value_complement (result_val);
+		break;
+	      case DW_OP_plus_uconst:
+		dwarf_require_integral (value_type (result_val));
+		result = value_as_long (result_val);
+		op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+		result += reg;
+		result_val = value_from_ulongest (address_type, result);
+		break;
+	      }
+	  }
 	  break;
 
 	case DW_OP_and:
@@ -742,7 +862,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_ne:
 	  {
 	    /* Binary operations.  */
-	    ULONGEST first, second;
+	    struct value *first, *second;
 
 	    second = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
@@ -750,62 +870,106 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    first = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
 
+	    if (! base_types_equal_p (value_type (first), value_type (second)))
+	      error (_("Incompatible types on DWARF stack"));
+
 	    switch (op)
 	      {
 	      case DW_OP_and:
-		result = first & second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_AND);
 		break;
 	      case DW_OP_div:
-		if (!second)
-		  error (_("Division by zero"));
-		result = sign_ext (first) / sign_ext (second);
+		result_val = value_binop (first, second, BINOP_DIV);
                 break;
 	      case DW_OP_minus:
-		result = first - second;
+		result_val = value_binop (first, second, BINOP_SUB);
 		break;
 	      case DW_OP_mod:
-		if (!second)
-		  error (_("Division by zero"));
-		result = first % second;
+		/* We have to special-case "old-style" untyped values
+		   -- these must have mod computed using unsigned
+		   math.  */
+		if (value_type (first) == address_type)
+		  {
+		    first = value_cast (uaddress_type, first);
+		    second = value_cast (uaddress_type, second);
+		  }
+		/* Note that value_binop doesn't handle float or
+		   decimal float here.  This seems unimportant.  */
+		result_val = value_binop (first, second, BINOP_MOD);
+		if (value_type (result_val) == uaddress_type)
+		  result_val = value_cast (address_type, result_val);
 		break;
 	      case DW_OP_mul:
-		result = first * second;
+		result_val = value_binop (first, second, BINOP_MUL);
 		break;
 	      case DW_OP_or:
-		result = first | second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_IOR);
 		break;
 	      case DW_OP_plus:
-		result = first + second;
+		result_val = value_binop (first, second, BINOP_ADD);
 		break;
 	      case DW_OP_shl:
-		result = first << second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_LSH);
 		break;
 	      case DW_OP_shr:
-		result = first >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		if (!TYPE_UNSIGNED (value_type (first)))
+		  {
+		    struct type *utype
+		      = get_unsigned_type (ctx->gdbarch, value_type (first));
+
+		    first = value_cast (utype, first);
+		  }
+
+		result_val = value_binop (first, second, BINOP_RSH);
+		/* Make sure we wind up with the same type we started
+		   with.  */
+		if (value_type (result_val) != value_type (second))
+		  result_val = value_cast (value_type (second), result_val);
                 break;
 	      case DW_OP_shra:
-		result = sign_ext (first) >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_RSH);
 		break;
 	      case DW_OP_xor:
-		result = first ^ second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_XOR);
 		break;
 	      case DW_OP_le:
-		result = sign_ext (first) <= sign_ext (second);
+		/* A <= B is !(B < A).  */
+		result = ! value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ge:
-		result = sign_ext (first) >= sign_ext (second);
+		/* A >= B is !(A < B).  */
+		result = ! value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_eq:
-		result = sign_ext (first) == sign_ext (second);
+		result = value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_lt:
-		result = sign_ext (first) < sign_ext (second);
+		result = value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_gt:
-		result = sign_ext (first) > sign_ext (second);
+		/* A > B is B < A.  */
+		result = value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ne:
-		result = sign_ext (first) != sign_ext (second);
+		result = ! value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      default:
 		internal_error (__FILE__, __LINE__,
@@ -816,6 +980,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_call_frame_cfa:
 	  result = (ctx->get_frame_cfa) (ctx->baton);
+	  result_val = value_from_ulongest (address_type, result);
 	  in_stack_memory = 1;
 	  break;
 
@@ -828,9 +993,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  control block at which the variable is located.  Nothing
 	  should follow this operator, so the top of stack would be
 	  returned.  */
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result = value_as_long (dwarf_expr_fetch (ctx, 0));
 	  dwarf_expr_pop (ctx);
 	  result = (ctx->get_tls_address) (ctx->baton, result);
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_skip:
@@ -840,11 +1006,17 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  goto no_push;
 
 	case DW_OP_bra:
-	  offset = extract_signed_integer (op_ptr, 2, byte_order);
-	  op_ptr += 2;
-	  if (dwarf_expr_fetch (ctx, 0) != 0)
-	    op_ptr += offset;
-	  dwarf_expr_pop (ctx);
+	  {
+	    struct value *val;
+
+	    offset = extract_signed_integer (op_ptr, 2, byte_order);
+	    op_ptr += 2;
+	    val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_require_integral (value_type (val));
+	    if (value_as_long (val) != 0)
+	      op_ptr += offset;
+	    dwarf_expr_pop (ctx);
+	  }
 	  goto no_push;
 
 	case DW_OP_nop:
@@ -912,12 +1084,81 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  ctx->num_pieces = 0;
 	  goto abort_expression;
 
+	case DW_OP_GNU_const_type:
+	  {
+	    ULONGEST type_die;
+	    int n;
+	    const gdb_byte *data;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    n = *op_ptr++;
+	    data = op_ptr;
+	    op_ptr += n;
+
+	    type = dwarf_get_base_type (ctx, type_die, n);
+
+	    /* Note that the address does not matter, since there is
+	       no way to fetch it.  */
+	    result_val = value_from_contents_and_address (type, data, 0);
+	  }
+	  break;
+
+	case DW_OP_GNU_regval_type:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+	    result = (ctx->read_reg) (ctx->baton, reg);
+	    result_val = value_from_ulongest (type, result);
+	  }
+	  break;
+
+	case DW_OP_GNU_convert:
+	case DW_OP_GNU_reinterpret:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
+
+	    if (op == DW_OP_GNU_convert)
+	      result_val = value_cast (type, result_val);
+	    else if (type == value_type (result_val))
+	      {
+		/* Nothing.  */
+	      }
+	    else if (TYPE_LENGTH (type)
+		     != TYPE_LENGTH (value_type (result_val)))
+	      error (_("DW_OP_GNU_reinterpret has wrong size"));
+	    else
+	      {
+		struct value *val = allocate_value (type);
+		gdb_byte *contents = value_contents_raw (val);
+
+		memcpy (contents, value_contents_all (result_val),
+			TYPE_LENGTH (type));
+		result_val = val;
+	      }
+	  }
+	  break;
+
 	default:
 	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
 	}
 
       /* Most things push a result value.  */
-      dwarf_expr_push (ctx, result, in_stack_memory);
+      gdb_assert (result_val != NULL);
+      dwarf_expr_push (ctx, result_val, in_stack_memory);
     no_push:
       ;
     }
@@ -931,5 +1172,11 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 abort_expression:
   ctx->recursion_depth--;
   gdb_assert (ctx->recursion_depth >= 0);
-#undef sign_ext
+}
+
+void
+_initialize_dwarf2expr (void)
+{
+  dwarf_arch_cookie
+    = gdbarch_data_register_post_init (dwarf_gdbarch_types_init);
 }
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index 78ff53f..7460e6a 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -51,7 +51,7 @@ enum dwarf_value_location
 
 struct dwarf_stack_value
 {
-  ULONGEST value;
+  struct value *value;
 
   /* Non-zero if the piece is in memory and is known to be
      on the program's stack.  It is always ok to set this to zero.
@@ -111,6 +111,13 @@ struct dwarf_expr_context
      being passed to and returned from the called DWARF subroutine.  */
   void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset);
 
+  /* Return the base type given by the indicated DIE.  This can throw
+     an exception if the DIE is invalid or does not represent a base
+     type.  If can also be NULL in the special case where the
+     callbacks are not performing evaluation, and thus it is
+     meaningful to substitute a stub type of the correct size.  */
+  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, size_t die);
+
 #if 0
   /* Not yet implemented.  */
 
@@ -182,7 +189,7 @@ struct dwarf_expr_piece
 
     /* The piece's register number or literal value, for
        DWARF_VALUE_REGISTER or DWARF_VALUE_STACK pieces.  */
-    ULONGEST value;
+    struct value *value;
 
     struct
     {
@@ -214,12 +221,11 @@ void free_dwarf_expr_context (struct dwarf_expr_context *ctx);
 struct cleanup *
     make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx);
 
-void dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
+void dwarf_expr_push (struct dwarf_expr_context *ctx, struct value *value,
 		      int in_stack_memory);
-void dwarf_expr_pop (struct dwarf_expr_context *ctx);
 void dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr,
 		      size_t len);
-ULONGEST dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
+struct value *dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
 CORE_ADDR dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n);
 int dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n);
 
@@ -234,4 +240,7 @@ const char *dwarf_stack_op_name (unsigned int);
 void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *,
 				     const char *);
 
+struct type *dwarf_expr_address_type (struct dwarf_expr_context *ctx,
+				      int signed_p);
+
 #endif /* dwarf2expr.h */
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 4c13307..7b43481 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -286,6 +286,16 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 		     ctx->get_frame_pc, ctx->baton);
 }
 
+/* Callback function for dwarf2_evaluate_loc_desc.  */
+
+static struct type *
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+  struct dwarf_expr_baton *debaton = ctx->baton;
+
+  return dwarf2_get_die_type (die_offset, debaton->per_cu);
+}
+
 struct piece_closure
 {
   /* Reference count.  */
@@ -313,6 +323,7 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
 			int addr_size)
 {
   struct piece_closure *c = XZALLOC (struct piece_closure);
+  int i;
 
   c->refc = 1;
   c->per_cu = per_cu;
@@ -321,6 +332,10 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
   c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
 
   memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
+  for (i = 0; i < n_pieces; ++i)
+    if (c->pieces[i].location == DWARF_VALUE_REGISTER
+	|| c->pieces[i].location == DWARF_VALUE_STACK)
+      value_incref (c->pieces[i].v.value);
 
   return c;
 }
@@ -576,7 +591,9 @@ read_pieced_value (struct value *v)
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum
+	      = gdbarch_dwarf2_reg_to_regnum (arch,
+					      value_as_long (p->v.value));
 	    int reg_offset = source_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -609,7 +626,7 @@ read_pieced_value (struct value *v)
 	    else
 	      {
 		error (_("Unable to access DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, value_as_long (p->v.value)));
 	      }
 	  }
 	  break;
@@ -623,7 +640,6 @@ read_pieced_value (struct value *v)
 
 	case DWARF_VALUE_STACK:
 	  {
-	    struct gdbarch *gdbarch = get_type_arch (value_type (v));
 	    size_t n = this_size;
 
 	    if (n > c->addr_size - source_offset)
@@ -634,18 +650,11 @@ read_pieced_value (struct value *v)
 	      {
 		/* Nothing.  */
 	      }
-	    else if (source_offset == 0)
-	      store_unsigned_integer (buffer, n,
-				      gdbarch_byte_order (gdbarch),
-				      p->v.value);
 	    else
 	      {
-		gdb_byte bytes[sizeof (ULONGEST)];
+		const gdb_byte *val_bytes = value_contents_all (p->v.value);
 
-		store_unsigned_integer (bytes, n + source_offset,
-					gdbarch_byte_order (gdbarch),
-					p->v.value);
-		memcpy (buffer, bytes + source_offset, n);
+		intermediate_buffer = val_bytes + source_offset;
 	      }
 	  }
 	  break;
@@ -776,7 +785,8 @@ write_pieced_value (struct value *to, struct value *from)
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum
+	      = gdbarch_dwarf2_reg_to_regnum (arch, value_as_long (p->v.value));
 	    int reg_offset = dest_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -816,7 +826,7 @@ write_pieced_value (struct value *to, struct value *from)
 	    else
 	      {
 		error (_("Unable to write to DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, value_as_long (p->v.value)));
 	      }
 	  }
 	  break;
@@ -1033,6 +1043,13 @@ free_pieced_value_closure (struct value *v)
   --c->refc;
   if (c->refc == 0)
     {
+      int i;
+
+      for (i = 0; i < c->n_pieces; ++i)
+	if (c->pieces[i].location == DWARF_VALUE_REGISTER
+	    || c->pieces[i].location == DWARF_VALUE_STACK)
+	  value_free (c->pieces[i].v.value);
+
       xfree (c->pieces);
       xfree (c);
     }
@@ -1106,6 +1123,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   ctx->get_frame_pc = dwarf_expr_frame_pc;
   ctx->get_tls_address = dwarf_expr_tls_address;
   ctx->dwarf_call = dwarf_expr_dwarf_call;
+  ctx->get_base_type = dwarf_expr_get_base_type;
 
   TRY_CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -1148,7 +1166,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0);
+	    ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
 	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
 
 	    if (byte_offset != 0)
@@ -1176,26 +1194,23 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
 	case DWARF_VALUE_STACK:
 	  {
-	    ULONGEST value = dwarf_expr_fetch (ctx, 0);
-	    bfd_byte *contents, *tem;
-	    size_t n = ctx->addr_size;
+	    struct value *value = dwarf_expr_fetch (ctx, 0);
+	    gdb_byte *contents;
+	    const gdb_byte *val_bytes;
+	    size_t n = TYPE_LENGTH (value_type (value));
 
 	    if (byte_offset + TYPE_LENGTH (type) > n)
 	      invalid_synthetic_pointer ();
 
-	    tem = alloca (n);
-	    store_unsigned_integer (tem, n,
-				    gdbarch_byte_order (ctx->gdbarch),
-				    value);
-
-	    tem += byte_offset;
+	    val_bytes = value_contents_all (value);
+	    val_bytes += byte_offset;
 	    n -= byte_offset;
 
 	    retval = allocate_value (type);
 	    contents = value_contents_raw (retval);
 	    if (n > TYPE_LENGTH (type))
 	      n = TYPE_LENGTH (type);
-	    memcpy (contents, tem, n);
+	    memcpy (contents, val_bytes, n);
 	  }
 	  break;
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 96a490e..08849ed 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -59,6 +59,9 @@ struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
+struct type *dwarf2_get_die_type (unsigned int die_offset,
+				  struct dwarf2_per_cu_data *per_cu);
+
 /* Evaluate a location description, starting at DATA and with length
    SIZE, to find the current location of variable of TYPE in the context
    of FRAME.  */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index fdab83d..790a873 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13017,6 +13017,18 @@ dwarf_stack_op_name (unsigned op)
       return "DW_OP_GNU_uninit";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
+    case DW_OP_GNU_entry_value:
+      return "DW_OP_GNU_entry_value";
+    case DW_OP_GNU_const_type:
+      return "DW_OP_GNU_const_type";
+    case DW_OP_GNU_regval_type:
+      return "DW_OP_GNU_regval_type";
+    case DW_OP_GNU_deref_type:
+      return "DW_OP_GNU_deref_type";
+    case DW_OP_GNU_convert:
+      return "DW_OP_GNU_convert";
+    case DW_OP_GNU_reinterpret:
+      return "DW_OP_GNU_reinterpret";
     default:
       return NULL;
     }
@@ -13575,6 +13587,31 @@ dwarf2_fetch_die_location_block (unsigned int offset,
   return retval;
 }
 
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+   PER_CU.  */
+
+struct type *
+dwarf2_get_die_type (unsigned int die_offset,
+		     struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf2_cu *cu = per_cu->cu;
+  struct die_info *die;
+  struct type *result;
+
+  dw2_setup (per_cu->objfile);
+
+  die = follow_die_offset (die_offset, &cu);
+  if (!die)
+    error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
+	   die_offset, per_cu->cu->objfile->name);
+
+  result = get_die_type (die, cu);
+  if (result == NULL)
+    result = read_type_die_1 (die, cu);
+
+  return result;
+}
+
 /* Follow the signature attribute ATTR in SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
    On exit *REF_CU is the CU of the result.  */
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.S b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
new file mode 100644
index 0000000..a46da14
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
@@ -0,0 +1,2225 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This source file was generated from typeddwarf.c using the following
+   command line:
+
+   gcc -m32 -dA -S -g -O2 typeddwarf.c -o typeddwarf.S
+
+*/
+
+
+	.file	"typeddwarf.c"
+	.text
+.Ltext0:
+	.p2align 4,,15
+	.globl	f1
+	.type	f1, @function
+f1:
+.LFB0:
+	# typeddwarf.c:10
+.LM1:
+.LVL0:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:29
+.LM2:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:30
+.LM3:
+	ret
+.LFE0:
+	.size	f1, .-f1
+	.p2align 4,,15
+	.globl	f2
+	.type	f2, @function
+f2:
+.LFB1:
+	# typeddwarf.c:34
+.LM4:
+.LVL1:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	subl	$12, %esp
+.LCFI0:
+	# typeddwarf.c:53
+.LM5:
+	movl	vv, %eax
+	# typeddwarf.c:54
+.LM6:
+	fnstcw	6(%esp)
+	# typeddwarf.c:34
+.LM7:
+	flds	40(%esp)
+.LVL2:
+	# typeddwarf.c:54
+.LM8:
+	fldl	16(%esp)
+	# typeddwarf.c:53
+.LM9:
+	addl	$1, %eax
+	movl	%eax, vv
+	# typeddwarf.c:54
+.LM10:
+	movzwl	6(%esp), %eax
+	movb	$12, %ah
+	movw	%ax, 4(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	# typeddwarf.c:55
+.LM11:
+	fldl	24(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:54
+.LM12:
+	movl	%eax, vv
+	# typeddwarf.c:55
+.LM13:
+	movl	(%esp), %eax
+	# typeddwarf.c:56
+.LM14:
+	fldl	32(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:55
+.LM15:
+	movl	%eax, vv
+	# typeddwarf.c:56
+.LM16:
+	movl	(%esp), %eax
+	# typeddwarf.c:57
+.LM17:
+	fldcw	4(%esp)
+	fistl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:56
+.LM18:
+	movl	%eax, vv
+	# typeddwarf.c:57
+.LM19:
+	movl	(%esp), %eax
+	# typeddwarf.c:58
+.LM20:
+	flds	44(%esp)
+	# typeddwarf.c:57
+.LM21:
+	movl	%eax, vv
+	# typeddwarf.c:58
+.LM22:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:59
+.LM23:
+	movl	48(%esp), %eax
+	# typeddwarf.c:63
+.LM24:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:59
+.LM25:
+	movl	%eax, vv
+	# typeddwarf.c:60
+.LM26:
+	movl	52(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:61
+.LM27:
+	movl	56(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:62
+.LM28:
+	movl	64(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:63
+.LM29:
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:64
+.LM30:
+	addl	$12, %esp
+.LCFI1:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE1:
+	.size	f2, .-f2
+	.p2align 4,,15
+	.globl	f3
+	.type	f3, @function
+f3:
+.LFB2:
+	# typeddwarf.c:68
+.LM31:
+.LVL3:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:73
+.LM32:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:74
+.LM33:
+	ret
+.LFE2:
+	.size	f3, .-f3
+	.p2align 4,,15
+	.globl	f4
+	.type	f4, @function
+f4:
+.LFB3:
+	# typeddwarf.c:78
+.LM34:
+.LVL4:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:82
+.LM35:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:83
+.LM36:
+	ret
+.LFE3:
+	.size	f4, .-f4
+	.section	.text.startup,"ax",@progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, @function
+main:
+.LFB4:
+	# typeddwarf.c:87
+.LM37:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	pushl	%esi
+.LCFI4:
+	# typeddwarf.c:88
+.LM38:
+	movl	$0x40a00000, %esi
+	# typeddwarf.c:87
+.LM39:
+	pushl	%ebx
+.LCFI5:
+	# typeddwarf.c:88
+.LM40:
+	movl	$0x40800000, %ebx
+	# typeddwarf.c:87
+.LM41:
+	andl	$-16, %esp
+	subl	$112, %esp
+.LCFI6:
+	# typeddwarf.c:88
+.LM42:
+	flds	.LC3
+	fstl	16(%esp)
+	movl	%esi, 28(%esp)
+	flds	.LC4
+	fstl	8(%esp)
+	movl	%ebx, 24(%esp)
+	fld1
+	fstl	(%esp)
+	movl	$9, 48(%esp)
+	fstps	64(%esp)
+	fstps	80(%esp)
+	movl	$0, 52(%esp)
+	fstps	96(%esp)
+	movl	$8, 40(%esp)
+	movl	$0, 44(%esp)
+	movl	$7, 36(%esp)
+	movl	$6, 32(%esp)
+	call	f1
+.LVL5:
+	# typeddwarf.c:89
+.LM43:
+	movl	%esi, 28(%esp)
+	movl	%ebx, 24(%esp)
+	movl	$9, 48(%esp)
+	movl	$0, 52(%esp)
+	movl	$8, 40(%esp)
+	flds	96(%esp)
+	fstpl	16(%esp)
+	movl	$0, 44(%esp)
+	flds	80(%esp)
+	fstpl	8(%esp)
+	movl	$7, 36(%esp)
+	flds	64(%esp)
+	fstpl	(%esp)
+	movl	$6, 32(%esp)
+	call	f2
+.LVL6:
+	# typeddwarf.c:90
+.LM44:
+	movl	$4, 20(%esp)
+	movl	$3, 12(%esp)
+	movl	$0, 16(%esp)
+	movl	$2, 8(%esp)
+	movl	$1, (%esp)
+	movl	$0, 4(%esp)
+	call	f3
+.LVL7:
+	# typeddwarf.c:91
+.LM45:
+	movl	$640, 16(%esp)
+	movl	$0, 20(%esp)
+	movl	$0, 24(%esp)
+	movl	$809369600, 28(%esp)
+	movl	$160, 4(%esp)
+	movl	$832569344, 8(%esp)
+	movl	$838860880, (%esp)
+	call	f4
+.LVL8:
+	# typeddwarf.c:93
+.LM46:
+	leal	-8(%ebp), %esp
+	xorl	%eax, %eax
+	popl	%ebx
+.LCFI7:
+	popl	%esi
+.LCFI8:
+	popl	%ebp
+.LCFI9:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE4:
+	.size	main, .-main
+	.comm	vv,4,4
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align 4
+.LC3:
+	.long	1077936128
+	.align 4
+.LC4:
+	.long	1073741824
+#APP
+	.section	.debug_frame,"",@progbits
+.Lframe0:
+	.long	.LECIE0-.LSCIE0	# Length of Common Information Entry
+.LSCIE0:
+	.long	0xffffffff	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE0:
+.LSFDE0:
+	.long	.LEFDE0-.LASFDE0	# FDE Length
+.LASFDE0:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE0:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE2:
+.LSFDE4:
+	.long	.LEFDE4-.LASFDE4	# FDE Length
+.LASFDE4:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE4:
+.LSFDE6:
+	.long	.LEFDE6-.LASFDE6	# FDE Length
+.LASFDE6:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE6:
+.LSFDE8:
+	.long	.LEFDE8-.LASFDE8	# FDE Length
+.LASFDE8:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE8:
+#NO_APP
+#APP
+	.section	.eh_frame,"aw",@progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.long	0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE1:
+.LSFDE11:
+	.long	.LEFDE11-.LASFDE11	# FDE Length
+.LASFDE11:
+	.long	.LASFDE11-.Lframe1	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE11:
+.LSFDE13:
+	.long	.LEFDE13-.LASFDE13	# FDE Length
+.LASFDE13:
+	.long	.LASFDE13-.Lframe1	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE13:
+.LSFDE15:
+	.long	.LEFDE15-.LASFDE15	# FDE Length
+.LASFDE15:
+	.long	.LASFDE15-.Lframe1	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE15:
+.LSFDE17:
+	.long	.LEFDE17-.LASFDE17	# FDE Length
+.LASFDE17:
+	.long	.LASFDE17-.Lframe1	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE17:
+.LSFDE19:
+	.long	.LEFDE19-.LASFDE19	# FDE Length
+.LASFDE19:
+	.long	.LASFDE19-.Lframe1	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE19:
+#NO_APP
+	.text
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x64e	# Length of Compilation Unit Info
+	.value	0x2	# DWARF version number
+	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+	.byte	0x4	# Pointer Size (in bytes)
+	.uleb128 0x1	# (DIE (0xb) DW_TAG_compile_unit)
+	.long	.LASF5	# DW_AT_producer: "GNU C 4.7.0 20110504 (experimental)"
+	.byte	0x1	# DW_AT_language
+	.long	.LASF6	# DW_AT_name: "typeddwarf.c"
+	.long	.LASF7	# DW_AT_comp_dir: "/usr/src/gcc/obj/gcc"
+	.long	.Ldebug_ranges0+0	# DW_AT_ranges
+	.long	0	# DW_AT_low_pc
+	.long	0	# DW_AT_entry_pc
+	.long	.Ldebug_line0	# DW_AT_stmt_list
+	.uleb128 0x2	# (DIE (0x29) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF0	# DW_AT_name: "double"
+	.uleb128 0x2	# (DIE (0x30) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF1	# DW_AT_name: "float"
+	.uleb128 0x2	# (DIE (0x37) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.long	.LASF2	# DW_AT_name: "long long int"
+	.uleb128 0x3	# (DIE (0x3e) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.ascii "int\0"	# DW_AT_name
+	.uleb128 0x2	# (DIE (0x45) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF3	# DW_AT_name: "unsigned int"
+	.uleb128 0x2	# (DIE (0x4c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF4	# DW_AT_name: "long long unsigned int"
+	.uleb128 0x4	# (DIE (0x53) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f1\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB0	# DW_AT_low_pc
+	.long	.LFE0	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x232	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x6b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x77) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x83) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x8f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x9b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0xa7) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0xb3) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0xbf) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0xcb) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0xd7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xb	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xe9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xc	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xfd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xe	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x6	# (DIE (0x109) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x10	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x11d) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x11	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x12f) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x12	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x141) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x13	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x153) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x14	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x167) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x15	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x179) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x16	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x18d) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x17	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x19f) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x18	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1b1) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x19	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1cf) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1a	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1f1) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x213) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1c	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x53
+	.uleb128 0x7	# (DIE (0x232) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f2\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB1	# DW_AT_low_pc
+	.long	.LFE1	# DW_AT_high_pc
+	.long	.LLST0	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x40a	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x24b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x257) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x263) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x26f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x27b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0x287) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0x293) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0x29f) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0x2ab) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0x2b7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x23	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2c9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x24	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2dd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x26	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x2e9) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x28	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x2f2) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x29	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.uleb128 0x6	# (DIE (0x2fb) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2a	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x30d) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x31f) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2c	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x333) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2d	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x345) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2e	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x359) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2f	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x36b) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x30	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x37d) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x31	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x39b) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x32	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x24	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.byte	0x1c	# DW_OP_minus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0x78b58c40	# fp or vector constant word 0
+	.long	0x4415af1d	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3c9) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x33	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x401c0000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3eb) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x34	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x232
+	.uleb128 0x4	# (DIE (0x40a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f3\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB2	# DW_AT_low_pc
+	.long	.LFE2	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x4fd	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x422) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x42e) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x43a) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.uleb128 0x5	# (DIE (0x446) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.uleb128 0x6	# (DIE (0x452) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x45	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x16	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x12	# DW_OP_dup
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x16	# DW_OP_swap
+	.byte	0x14	# DW_OP_over
+	.byte	0x2b	# DW_OP_gt
+	.byte	0x28	# DW_OP_bra
+	.value	0x1
+	.byte	0x16	# DW_OP_swap
+	.byte	0x13	# DW_OP_drop
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x472) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x46	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x496) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x47	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x4ba) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x48	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x38	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x40a
+	.uleb128 0x4	# (DIE (0x4fd) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f4\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB3	# DW_AT_low_pc
+	.long	.LFE3	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x555	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x515) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x521) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 4
+	.uleb128 0x5	# (DIE (0x52d) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x539) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4f	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x542) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x50	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x54b) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x51	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0	# end of children of DIE 0x4fd
+	.uleb128 0x2	# (DIE (0x555) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF8	# DW_AT_name: "_Decimal32"
+	.uleb128 0x2	# (DIE (0x55c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF9	# DW_AT_name: "_Decimal64"
+	.uleb128 0x2	# (DIE (0x563) DW_TAG_base_type)
+	.byte	0x10	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF10	# DW_AT_name: "_Decimal128"
+	.uleb128 0x9	# (DIE (0x56a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.long	.LASF11	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x56	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.long	.LFB4	# DW_AT_low_pc
+	.long	.LFE4	# DW_AT_high_pc
+	.long	.LLST1	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x62f	# DW_AT_sibling
+	.uleb128 0xa	# (DIE (0x587) DW_TAG_GNU_call_site)
+	.long	.LVL5	# DW_AT_low_pc
+	.long	0x53	# DW_AT_abstract_origin
+	.long	0x5e1	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x594) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 0
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5a4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5b4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5c4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5cc) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5d4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x5da) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x587
+	.uleb128 0xa	# (DIE (0x5e1) DW_TAG_GNU_call_site)
+	.long	.LVL6	# DW_AT_low_pc
+	.long	0x232	# DW_AT_abstract_origin
+	.long	0x60b	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x5ee) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5f6) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5fe) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x604) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x5e1
+	.uleb128 0xa	# (DIE (0x60b) DW_TAG_GNU_call_site)
+	.long	.LVL7	# DW_AT_low_pc
+	.long	0x40a	# DW_AT_abstract_origin
+	.long	0x625	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x618) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x32	# DW_OP_lit2
+	.uleb128 0xb	# (DIE (0x61e) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 20
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x34	# DW_OP_lit4
+	.byte	0	# end of children of DIE 0x60b
+	.uleb128 0xc	# (DIE (0x625) DW_TAG_GNU_call_site)
+	.long	.LVL8	# DW_AT_low_pc
+	.long	0x4fd	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x56a
+	.uleb128 0xd	# (DIE (0x62f) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x1	# DW_AT_declaration
+	.uleb128 0xe	# (DIE (0x63b) DW_TAG_volatile_type)
+	.long	0x3e	# DW_AT_type
+	.uleb128 0xf	# (DIE (0x640) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x5	# DW_AT_location
+	.byte	0x3	# DW_OP_addr
+	.long	vv
+	.byte	0	# end of children of DIE 0xb
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1	# (abbrev code)
+	.uleb128 0x11	# (TAG: DW_TAG_compile_unit)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x25	# (DW_AT_producer)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x13	# (DW_AT_language)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x1b	# (DW_AT_comp_dir)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x55	# (DW_AT_ranges)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x52	# (DW_AT_entry_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x10	# (DW_AT_stmt_list)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.byte	0
+	.byte	0
+	.uleb128 0x2	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.byte	0
+	.byte	0
+	.uleb128 0x3	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.byte	0
+	.byte	0
+	.uleb128 0x4	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x5	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x6	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x7	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x8	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x9	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xa	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xb	# (abbrev code)
+	.uleb128 0x410a	# (TAG: DW_TAG_GNU_call_site_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2111	# (DW_AT_GNU_call_site_value)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0xc	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xd	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3c	# (DW_AT_declaration)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.byte	0
+	.byte	0
+	.uleb128 0xe	# (abbrev code)
+	.uleb128 0x35	# (TAG: DW_TAG_volatile_type)
+	.byte	0	# DW_children_no
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xf	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.long	.LFB1	# Location list begin address (*.LLST0)
+	.long	.LCFI0	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI0	# Location list begin address (*.LLST0)
+	.long	.LCFI1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.long	.LCFI1	# Location list begin address (*.LLST0)
+	.long	.LFE1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST0)
+	.long	0	# Location list terminator end (*.LLST0)
+.LLST1:
+	.long	.LFB4	# Location list begin address (*.LLST1)
+	.long	.LCFI2	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI2	# Location list begin address (*.LLST1)
+	.long	.LCFI3	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.long	.LCFI3	# Location list begin address (*.LLST1)
+	.long	.LCFI9	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x75	# DW_OP_breg5
+	.sleb128 8
+	.long	.LCFI9	# Location list begin address (*.LLST1)
+	.long	.LFE4	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST1)
+	.long	0	# Location list terminator end (*.LLST1)
+	.section	.debug_aranges,"",@progbits
+	.long	0x24	# Length of Address Ranges Info
+	.value	0x2	# DWARF Version
+	.long	.Ldebug_info0	# Offset of Compilation Unit Info
+	.byte	0x4	# Size of Address
+	.byte	0	# Size of Segment Descriptor
+	.value	0	# Pad to 8 byte boundary
+	.value	0
+	.long	.Ltext0	# Address
+	.long	.Letext0-.Ltext0	# Length
+	.long	.LFB4	# Address
+	.long	.LFE4-.LFB4	# Length
+	.long	0
+	.long	0
+	.section	.debug_ranges,"",@progbits
+.Ldebug_ranges0:
+	.long	.Ltext0	# Offset 0
+	.long	.Letext0
+	.long	.LFB4	# Offset 0x8
+	.long	.LFE4
+	.long	0
+	.long	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.long	.LELT0-.LSLT0	# Length of Source Line Info
+.LSLT0:
+	.value	0x2	# DWARF Version
+	.long	.LELTP0-.LASLTP0	# Prolog Length
+.LASLTP0:
+	.byte	0x1	# Minimum Instruction Length
+	.byte	0x1	# Default is_stmt_start flag
+	.byte	0xf6	# Line Base Value (Special Opcodes)
+	.byte	0xf2	# Line Range Value (Special Opcodes)
+	.byte	0xd	# Special Opcode Base
+	.byte	0	# opcode: 0x1 has 0 args
+	.byte	0x1	# opcode: 0x2 has 1 args
+	.byte	0x1	# opcode: 0x3 has 1 args
+	.byte	0x1	# opcode: 0x4 has 1 args
+	.byte	0x1	# opcode: 0x5 has 1 args
+	.byte	0	# opcode: 0x6 has 0 args
+	.byte	0	# opcode: 0x7 has 0 args
+	.byte	0	# opcode: 0x8 has 0 args
+	.byte	0x1	# opcode: 0x9 has 1 args
+	.byte	0	# opcode: 0xa has 0 args
+	.byte	0	# opcode: 0xb has 0 args
+	.byte	0x1	# opcode: 0xc has 1 args
+	.byte	0	# End directory table
+	.ascii "typeddwarf.c\0"	# File Entry: 0x1
+	.uleb128 0
+	.uleb128 0
+	.uleb128 0
+	.byte	0	# End file name table
+.LELTP0:
+	.byte	0	# set address *.LM37
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM37
+	.byte	0x6d	# line 87
+	.byte	0	# set address *.LM38
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM38
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM39
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM39
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM40
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM40
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM41
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM41
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM42
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM42
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM43
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM43
+	.byte	0x18	# line 89
+	.byte	0	# set address *.LM44
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM44
+	.byte	0x18	# line 90
+	.byte	0	# set address *.LM45
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM45
+	.byte	0x18	# line 91
+	.byte	0	# set address *.LM46
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM46
+	.byte	0x19	# line 93
+	.byte	0	# set address *.LFE4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LFE4
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+	.byte	0	# set address *.LM1
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM1
+	.byte	0x20	# line 10
+	.byte	0	# set address *.LM2
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM2
+	.byte	0x2a	# line 29
+	.byte	0	# set address *.LM3
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM3
+	.byte	0x18	# line 30
+	.byte	0	# set address *.LM4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM4
+	.byte	0x1b	# line 34
+	.byte	0	# set address *.LM5
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM5
+	.byte	0x2a	# line 53
+	.byte	0	# set address *.LM6
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM6
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM7
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM7
+	.byte	0x3	# advance to line 34
+	.sleb128 -20
+	.byte	0x1
+	.byte	0	# set address *.LM8
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM8
+	.byte	0x2b	# line 54
+	.byte	0	# set address *.LM9
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM9
+	.byte	0x16	# line 53
+	.byte	0	# set address *.LM10
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM10
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM11
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM11
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM12
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM12
+	.byte	0x16	# line 54
+	.byte	0	# set address *.LM13
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM13
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM14
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM14
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM15
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM15
+	.byte	0x16	# line 55
+	.byte	0	# set address *.LM16
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM16
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM17
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM17
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM18
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM18
+	.byte	0x16	# line 56
+	.byte	0	# set address *.LM19
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM19
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM20
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM20
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM21
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM21
+	.byte	0x16	# line 57
+	.byte	0	# set address *.LM22
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM22
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM23
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM23
+	.byte	0x18	# line 59
+	.byte	0	# set address *.LM24
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM24
+	.byte	0x1b	# line 63
+	.byte	0	# set address *.LM25
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM25
+	.byte	0x13	# line 59
+	.byte	0	# set address *.LM26
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM26
+	.byte	0x18	# line 60
+	.byte	0	# set address *.LM27
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM27
+	.byte	0x18	# line 61
+	.byte	0	# set address *.LM28
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM28
+	.byte	0x18	# line 62
+	.byte	0	# set address *.LM29
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM29
+	.byte	0x18	# line 63
+	.byte	0	# set address *.LM30
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM30
+	.byte	0x18	# line 64
+	.byte	0	# set address *.LM31
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM31
+	.byte	0x1b	# line 68
+	.byte	0	# set address *.LM32
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM32
+	.byte	0x1c	# line 73
+	.byte	0	# set address *.LM33
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM33
+	.byte	0x18	# line 74
+	.byte	0	# set address *.LM34
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM34
+	.byte	0x1b	# line 78
+	.byte	0	# set address *.LM35
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM35
+	.byte	0x1b	# line 82
+	.byte	0	# set address *.LM36
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM36
+	.byte	0x18	# line 83
+	.byte	0	# set address *.Letext0
+	.uleb128 0x5
+	.byte	0x2
+	.long	.Letext0
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+.LELT0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF2:
+	.string	"long long int"
+.LASF3:
+	.string	"unsigned int"
+.LASF8:
+	.string	"_Decimal32"
+.LASF4:
+	.string	"long long unsigned int"
+.LASF11:
+	.string	"main"
+.LASF9:
+	.string	"_Decimal64"
+.LASF0:
+	.string	"double"
+.LASF10:
+	.string	"_Decimal128"
+.LASF7:
+	.string	"/usr/src/gcc/obj/gcc"
+.LASF1:
+	.string	"float"
+.LASF6:
+	.string	"typeddwarf.c"
+.LASF5:
+	.string	"GNU C 4.7.0 20110504 (experimental)"
+	.ident	"GCC: (GNU) 4.7.0 20110504 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.c b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
new file mode 100644
index 0000000..e5f7d67
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
@@ -0,0 +1,93 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-g" } */
+
+typedef __SIZE_TYPE__ size_t;
+volatile int vv;
+extern void *memcpy (void *, const void *, size_t);
+
+__attribute__((noinline, noclone)) void
+f1 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 29 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 29 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 29 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { gdb-test 29 "n" "9" } } */
+  double o = h;			/* { dg-final { gdb-test 29 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 29 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 29 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 29 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 29 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 29 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 29 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 29 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 29 "w" "1" } } */
+  double x = a + b + 1.0;	/* { dg-final { gdb-test 29 "x" "4" } } */
+  double y = b + c + 2.0;	/* { dg-final { gdb-test 29 "y" "7" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 29 "z" "12" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f2 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 53 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 53 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 53 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { xfail-gdb-test 53 "n" "9" } } */
+  double o = h;			/* { dg-final { xfail-gdb-test 53 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 53 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 53 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 53 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 53 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 53 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 53 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 53 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 53 "w" "1" } } */
+  double x = a + b - 3 + 1.0e20;/* { dg-final { gdb-test 53 "x" "1e\\+20" } } */
+  double y = b + c * 7.0;	/* { dg-final { gdb-test 53 "y" "23" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 53 "z" "12" } } */
+  vv++;
+  vv = a;
+  vv = b;
+  vv = c;
+  vv = d;
+  vv = e;
+  vv = f;
+  vv = g;
+  vv = h;
+  vv = i;
+  vv = j;
+}
+
+__attribute__((noinline, noclone)) void
+f3 (long long a, int b, long long c, unsigned d)
+{
+  long long w = (a > d) ? a : d;/* { dg-final { gdb-test 73 "w" "4" } } */
+  long long x = a + b + 7;	/* { dg-final { gdb-test 73 "x" "10" } } */
+  long long y = c + d + 0x912345678LL;/* { dg-final { gdb-test 73 "y" "38960125567" } } */
+  int z = (x + y);		/* { dg-final { gdb-test 73 "z" "305419913" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f4 (_Decimal32 a, _Decimal64 b, _Decimal128 c)
+{
+  _Decimal32 w = a * 8.0DF + 6.0DF;/* { dg-final { xfail-gdb-test 82 "(int)w" "70" } } */
+  _Decimal64 x = b / 8.0DD - 6.0DD;/* { dg-final { xfail-gdb-test 82 "(int)x" "-4" } } */
+  _Decimal128 y = -c / 8.0DL;	/* { dg-final { xfail-gdb-test 82 "(int)y" "-8" } } */
+  vv++;
+}
+
+int
+main ()
+{
+  f1 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f2 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f3 (1, 2, 3, 4);
+  f4 (8.0DF, 16.0DD, 64.0DL);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
new file mode 100644
index 0000000..bddcc18
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -0,0 +1,91 @@
+# Copyright 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib dwarf.exp
+
+set test "typeddwarf"
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if ![dwarf2_support] {
+    return 0  
+}
+
+# This test can only be run on x86 targets.
+if { ![istarget i?86-*] } {
+    return 0
+}
+
+if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+global tests
+set tests(_) -
+unset tests(_)
+
+proc gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 0]
+}
+
+proc xfail-gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 1]
+}
+
+proc scan_gdb_tests {} {
+    global srcdir subdir test
+
+    set file "$srcdir/$subdir/$test.c"
+
+    set fd [open "$file"]
+    while {![eof $fd]} {
+	set line [gets $fd]
+	if {! [regexp "\{ (gdb-test .+) \} \}" $line ignore test_cmd]} {
+	    continue
+	}
+
+	eval $test_cmd
+    }
+    close $fd
+}
+
+scan_gdb_tests
+
+foreach line [lsort [array names tests]] {
+    gdb_test "break typeddwarf.c:$line" "Breakpoint .*" \
+	"set breakpoint at typeddwarf.c:$line"
+    gdb_continue_to_breakpoint "continue to typeddwarf.c:$line"
+
+    foreach test $tests($line) {
+	set var [lindex $test 0]
+	set value [lindex $test 1]
+	set should_xfail [lindex $test 2]
+
+	if {$should_xfail} {
+	    setup_xfail *-*-*
+	}
+
+	gdb_test "print $var" \
+	    " = $value" \
+	    "check value of $var at typeddwarf.c:$line"
+    }
+}


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-04 20:48 RFC: implement typed DWARF stack Tom Tromey
@ 2011-05-05 16:47 ` Tom Tromey
  2011-05-05 18:07 ` Ulrich Weigand
  1 sibling, 0 replies; 25+ messages in thread
From: Tom Tromey @ 2011-05-05 16:47 UTC (permalink / raw)
  To: gdb-patches

>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> I would appreciate comments on this.  In the absence of comments I am
Tom> going to check it in.

Tom> Jakub recently implemented Cary Coutant's typed DWARF stack proposal in
Tom> GCC.

I had a couple notes I wanted to make that I forgot about when I was
actually writing the email.

First, look at the dwarf2_get_die_type addition in dwarf2read.c.
I am not extremely pleased with this code.  I think due to DIE cache
flushing it may create new types from time to time.

I am not sure what to do about this.  One idea I had was that perhaps
read_type_die_1 could intern base types (meaning we would have to
re-read the DIEs but we would not instantiate new types all the time).
Another idea was to permanently cache base types by DIE -- but this
seemed like too much overhead for a reasonably obscure feature.


The other issue is that you might be wondering why I didn't update the
DWARF->AX compiler in dwarf2loc.c.  The reason is simply that this
extension is, IIUC, mostly useful for floating point and decimal
floating point, and AX cannot express those.

Maybe this can also be used for wider-than-address-sized integral types.
I will look; maybe the AX compiler does need an update for this.

Tom


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-04 20:48 RFC: implement typed DWARF stack Tom Tromey
  2011-05-05 16:47 ` Tom Tromey
@ 2011-05-05 18:07 ` Ulrich Weigand
  2011-05-05 18:38   ` Tom Tromey
  1 sibling, 1 reply; 25+ messages in thread
From: Ulrich Weigand @ 2011-05-05 18:07 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey wrote:

> This patch converts the DWARF expression evaluator to use GDB's value
> types.  This approach made it easy to support floating point and also
> decimal floating point; and also paves the way for any future
> improvements.

Huh, so value_binop is back after I eliminated it :-)
http://sourceware.org/ml/gdb-patches/2010-06/msg00514.html
Due to the use of value_as_address in dwarf_expr_fetch_address, this
patch actually ought to still work on the SPU ... I'll do a test.

> There is some ugliness involving signed and unsigned types; this arises
> because "old-style" untyped DWARF values don't have a consistent type.
> Also I needed a little bit of special code to handle logical right
> shifts.

Yes, I'm wondering whether old-style values are handled correctly.  We
used to make sure all arithmetic is performed in ctx->addr_size bits
(which is taken from the DWARF section headers).  With your patch,
we now always use gdbarch_dwarf2_addr_size -- I'm not sure this is
always the same.

Also, what is the reason for handling the conversion to unsigned so
differently in the DW_OP_mod vs. DW_OP_shr cases?

+		/* We have to special-case "old-style" untyped values
+		   -- these must have mod computed using unsigned
+		   math.  */
+		if (value_type (first) == address_type)
+		  {
+		    first = value_cast (uaddress_type, first);
+		    second = value_cast (uaddress_type, second);
+		  }

vs.

+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		if (!TYPE_UNSIGNED (value_type (first)))
+		  {
+		    struct type *utype
+		      = get_unsigned_type (ctx->gdbarch, value_type (first));
+
+		    first = value_cast (utype, first);
+		  }

[ In fact, maybe we don't need the whole value_cast business and we could
just operate on ULONGEST without involving value_binop, since both cases
only support integers anyway ... ]

> -  dwarf_expr_push (ctx, initial, initial_in_stack_memory);
> +  dwarf_expr_push (ctx, value_from_ulongest (dwarf_expr_address_type (ctx, 1),
> +					     initial),
> +		   initial_in_stack_memory);

I'd rather see a dwarf_expr_push_address to keep the address-type abstraction
local to dwarf2expr.c ...

>  	case DW_OP_bra:
> -	  offset = extract_signed_integer (op_ptr, 2, byte_order);
> -	  op_ptr += 2;
> -	  if (dwarf_expr_fetch (ctx, 0) != 0)
> -	    op_ptr += offset;
> -	  dwarf_expr_pop (ctx);
> +	  {
> +	    struct value *val;
> +
> +	    offset = extract_signed_integer (op_ptr, 2, byte_order);
> +	    op_ptr += 2;
> +	    val = dwarf_expr_fetch (ctx, 0);
> +	    dwarf_require_integral (value_type (val));

Does DW_OP_bra really require an integral type on the stack?  The standard
wording isn't 100% clear to me here ...

> +	case DW_OP_GNU_const_type:
> +	  {
> +	    ULONGEST type_die;
> +	    int n;
> +	    const gdb_byte *data;
> +	    struct type *type;
> +
> +	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
> +	    n = *op_ptr++;
> +	    data = op_ptr;
> +	    op_ptr += n;
> +
> +	    type = dwarf_get_base_type (ctx, type_die, n);
> +
> +	    /* Note that the address does not matter, since there is
> +	       no way to fetch it.  */
> +	    result_val = value_from_contents_and_address (type, data, 0);

I guess a non_lval value would still seem cleaner here (just as done
below for DW_OP_GNU_reinterpret --- maybe this could be abstracted
into a new value_from_contents helper).

> @@ -182,7 +189,7 @@ struct dwarf_expr_piece
>  
>      /* The piece's register number or literal value, for
>         DWARF_VALUE_REGISTER or DWARF_VALUE_STACK pieces.  */
> -    ULONGEST value;
> +    struct value *value;

Maybe now it would be cleaner to split this into two union members,
a plain "int regnum" for DWARF_VALUE_REGISTER, and the struct value
for DWARF_VALUE_STACK ...

Otherwise this looks good to me.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-05 18:07 ` Ulrich Weigand
@ 2011-05-05 18:38   ` Tom Tromey
  2011-05-05 20:15     ` Tom Tromey
  0 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-05 18:38 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:

Tom> This patch converts the DWARF expression evaluator to use GDB's value
Tom> types.  This approach made it easy to support floating point and also
Tom> decimal floating point; and also paves the way for any future
Tom> improvements.

Ulrich> Huh, so value_binop is back after I eliminated it :-)
Ulrich> http://sourceware.org/ml/gdb-patches/2010-06/msg00514.html

Yeah, I actually referred back to this while writing the patch :)

Ulrich> Due to the use of value_as_address in dwarf_expr_fetch_address, this
Ulrich> patch actually ought to still work on the SPU ... I'll do a test.

Thank you.

Tom> There is some ugliness involving signed and unsigned types; this arises
Tom> because "old-style" untyped DWARF values don't have a consistent type.
Tom> Also I needed a little bit of special code to handle logical right
Tom> shifts.

Ulrich> Yes, I'm wondering whether old-style values are handled correctly.  We
Ulrich> used to make sure all arithmetic is performed in ctx->addr_size bits
Ulrich> (which is taken from the DWARF section headers).  With your patch,
Ulrich> we now always use gdbarch_dwarf2_addr_size -- I'm not sure this is
Ulrich> always the same.

Good point; I am not sure either.  Another option would be to use
ctx->addr_size to choose an arch type (e.g., builtin_uint32), and then
also carry along a flag indicating whether the value is "untyped".

I think this is needed because these untyped values must be treated
differently in a couple spots :-(

Yet another idea would be to lazily instantiate these special-to-DWARF
types and make struct dwarf_gdbarch_types a little bigger.  I think I
like this idea the best.  I think in practice we only need to support 3
such types (and if we run into more in the wild we can easily add them).

Ulrich> Also, what is the reason for handling the conversion to unsigned so
Ulrich> differently in the DW_OP_mod vs. DW_OP_shr cases?

There's no reason, I will clean this up.

Ulrich> [ In fact, maybe we don't need the whole value_cast business and
Ulrich> we could just operate on ULONGEST without involving value_binop,
Ulrich> since both cases only support integers anyway ... ]

I agree, for DW_OP_shr.  I will do that.  Unfortunately I think
DW_OP_mod still needs special magic.

Ulrich> I'd rather see a dwarf_expr_push_address to keep the
Ulrich> address-type abstraction local to dwarf2expr.c ...

Will do.

Ulrich> Does DW_OP_bra really require an integral type on the stack?
Ulrich> The standard wording isn't 100% clear to me here ...

A couple of oddities were clarified in this thread:

    http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00333.html

There, Cary said that DW_OP_bra should require an integral type and this
was just an oversight in the spec.

Ulrich> I guess a non_lval value would still seem cleaner here (just as done
Ulrich> below for DW_OP_GNU_reinterpret --- maybe this could be abstracted
Ulrich> into a new value_from_contents helper).

Will do.

Tom> @@ -182,7 +189,7 @@ struct dwarf_expr_piece
Tom> 
Tom> /* The piece's register number or literal value, for
Tom> DWARF_VALUE_REGISTER or DWARF_VALUE_STACK pieces.  */
Tom> -    ULONGEST value;
Tom> +    struct value *value;

Ulrich> Maybe now it would be cleaner to split this into two union members,
Ulrich> a plain "int regnum" for DWARF_VALUE_REGISTER, and the struct value
Ulrich> for DWARF_VALUE_STACK ...

That does seem better, I will do that too.

Ulrich> Otherwise this looks good to me.

Thanks very much for the review.  I'll post a new patch when I've made
the needed changes.

Tom


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-05 18:38   ` Tom Tromey
@ 2011-05-05 20:15     ` Tom Tromey
  2011-05-09 22:02       ` Ulrich Weigand
  0 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-05 20:15 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> Yet another idea would be to lazily instantiate these special-to-DWARF
Tom> types and make struct dwarf_gdbarch_types a little bigger.  I think I
Tom> like this idea the best.  I think in practice we only need to support 3
Tom> such types (and if we run into more in the wild we can easily add them).

This is what I did.

Ulrich> [ In fact, maybe we don't need the whole value_cast business and
Ulrich> we could just operate on ULONGEST without involving value_binop,
Ulrich> since both cases only support integers anyway ... ]

Tom> I agree, for DW_OP_shr.  I will do that.  Unfortunately I think
Tom> DW_OP_mod still needs special magic.

Actually in the end I thought it was perhaps better to keep DW_OP_shr
more or less as it was.  My reasoning is that by uniformly using the
value API, we make it simpler to handle new cases in the future.  E.g.,
consider if we want to support 128-bit integer types -- we could do this
via value changes, but this would leave an odd hole in DWARF that the
patch writer would have to discover.

Ulrich> Maybe now it would be cleaner to split this into two union members,
Ulrich> a plain "int regnum" for DWARF_VALUE_REGISTER, and the struct value
Ulrich> for DWARF_VALUE_STACK ...

I did this for pieced results, but not for the stack itself, as that
would entail much more code.

Tom> Thanks very much for the review.  I'll post a new patch when I've made
Tom> the needed changes.

Appended.

Tom

2011-05-05  Tom Tromey  <tromey@redhat.com>

	PR gdb/12617:
	* value.h (value_from_contents): Declare.
	* value.c (value_from_contents): New function.
	* dwarf2read.c (dwarf_stack_op_name): Add new values.
	(dwarf2_get_die_type): New function.
	* dwarf2loc.c (dwarf_expr_get_base_type): New function.
	(allocate_piece_closure): Acquire reference to values.
	(read_pieced_value): Update for value-based expressions.
	(write_pieced_value): Likewise.
	(free_pieced_value_closure): Call value_free as needed.
	(dwarf2_evaluate_loc_desc_full): Set get_base_type field.
	Update for value-based expressions.
	* dwarf2loc.h (dwarf2_get_die_type): Declare.
	* dwarf2expr.h (struct dwarf_stack_value) <value>: Change type.
	<get_base_type>: New field.
	(struct dwarf_expr_piece) <v.value>: Change type.
	<v.regno>: New field.
	(dwarf_expr_piece, dwarf_expr_fetch): Update.
	(dwarf_expr_pop, dwarf_expr_push): Remove.
	(dwarf_expr_push_address): Declare.
	* dwarf2expr.c (dwarf_arch_cookie): New global.
	(struct dwarf_gdbarch_types): New.
	(dwarf_gdbarch_types_init, dwarf_expr_address_type): New
	functions.
	(dwarf_expr_push): Change type of 'value' argument.  Update.  Now
	static.
	(dwarf_expr_push_address): New function.
	(dwarf_expr_pop): Now static.
	(dwarf_expr_fetch): Change return type.
	(dwarf_require_integral): New function.
	(dwarf_expr_fetch): Simplify.
	(add_piece): Update.
	(base_types_equal_p, dwarf_get_base_type, get_unsigned_type): New
	functions.
	(execute_stack_op) <sign_ext>: Remove.
	Use values for DWARF stack.
	<DW_OP_GNU_const_type, DW_OP_GNU_deref_type,
	DW_OP_GNU_regval_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret>:
	New cases.
	(_initialize_dwarf2expr): New function.
	(add_piece): Update.
	* dwarf2-frame.c (no_base_type): New function.
	(execute_stack_op): Set get_base_type field.  Update.

2011-05-05  Tom Tromey  <tromey@redhat.com>

	* gdb.dwarf2/typeddwarf.S: New file.
	* gdb.dwarf2/typeddwarf.c: New file.
	* gdb.dwarf2/typeddwarf.exp: New file.

diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index e78c328..4e4e6d9 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -353,6 +353,14 @@ no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 		  _("Support for DW_OP_call* is invalid in CFI"));
 }
 
+/* Helper function for execute_stack_op.  */
+
+static struct type *
+no_base_type (struct dwarf_expr_context *ctx, size_t die)
+{
+  error (_("Support for typed DWARF is not supported in CFI"));
+}
+
 /* Execute the required actions for both the DW_CFA_restore and
 DW_CFA_restore_extended instructions.  */
 static void
@@ -406,14 +414,15 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
   ctx->get_frame_pc = no_get_frame_pc;
   ctx->get_tls_address = no_get_tls_address;
   ctx->dwarf_call = no_dwarf_call;
+  ctx->get_base_type = no_base_type;
 
-  dwarf_expr_push (ctx, initial, initial_in_stack_memory);
+  dwarf_expr_push_address (ctx, initial, initial_in_stack_memory);
   dwarf_expr_eval (ctx, exp, len);
 
   if (ctx->location == DWARF_VALUE_MEMORY)
     result = dwarf_expr_fetch_address (ctx, 0);
   else if (ctx->location == DWARF_VALUE_REGISTER)
-    result = read_reg (this_frame, dwarf_expr_fetch (ctx, 0));
+    result = read_reg (this_frame, value_as_long (dwarf_expr_fetch (ctx, 0)));
   else
     {
       /* This is actually invalid DWARF, but if we ever do run across
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 91fccf9..3f6f277 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -34,6 +34,61 @@
 static void execute_stack_op (struct dwarf_expr_context *,
 			      const gdb_byte *, const gdb_byte *);
 
+/* Cookie for gdbarch data.  */
+
+static struct gdbarch_data *dwarf_arch_cookie;
+
+/* This holds gdbarch-specific types used by the DWARF expression
+   evaluator.  */
+
+struct dwarf_gdbarch_types
+{
+  struct type *dw_types[3];
+};
+
+/* Allocate and fill in dwarf_gdbarch_types for an arch.  */
+
+static void *
+dwarf_gdbarch_types_init (struct gdbarch *gdbarch)
+{
+  struct dwarf_gdbarch_types *types
+    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf_gdbarch_types);
+
+  /* The types themselves are lazily initialized.  */
+
+  return types;
+}
+
+/* Return the type used for DWARF operations where the type is
+   unspecified in the DWARF spec.  Only certain sizes are
+   supported.  */
+
+static struct type *
+dwarf_expr_address_type (struct dwarf_expr_context *ctx)
+{
+  struct dwarf_gdbarch_types *types = gdbarch_data (ctx->gdbarch,
+						    dwarf_arch_cookie);
+  int ndx;
+
+  if (ctx->addr_size == 2)
+    ndx = 0;
+  else if (ctx->addr_size == 4)
+    ndx = 1;
+  else if (ctx->addr_size == 8)
+    ndx = 2;
+  else
+    error (_("Unsupported address size in DWARF expressions: %d bits"),
+	   8 * ctx->addr_size);
+
+  if (types->dw_types[ndx] == NULL)
+    types->dw_types[ndx]
+      = arch_integer_type (ctx->gdbarch,
+			   8 * ctx->addr_size,
+			   0, "<signed DWARF address type>");
+
+  return types->dw_types[ndx];
+}
+
 /* Create a new context for the expression evaluator.  */
 
 struct dwarf_expr_context *
@@ -96,26 +151,32 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
 
 /* Push VALUE onto CTX's stack.  */
 
-void
-dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
+static void
+dwarf_expr_push (struct dwarf_expr_context *ctx, struct value *value,
 		 int in_stack_memory)
 {
   struct dwarf_stack_value *v;
 
-  /* We keep all stack elements within the range defined by the
-     DWARF address size.  */
-  if (ctx->addr_size < sizeof (ULONGEST))
-    value &= ((ULONGEST) 1 << (ctx->addr_size * HOST_CHAR_BIT)) - 1;
-
   dwarf_expr_grow_stack (ctx, 1);
   v = &ctx->stack[ctx->stack_len++];
   v->value = value;
   v->in_stack_memory = in_stack_memory;
 }
 
-/* Pop the top item off of CTX's stack.  */
+/* Push VALUE onto CTX's stack.  */
 
 void
+dwarf_expr_push_address (struct dwarf_expr_context *ctx, CORE_ADDR value,
+			 int in_stack_memory)
+{
+  dwarf_expr_push (ctx,
+		   value_from_ulongest (dwarf_expr_address_type (ctx), value),
+		   in_stack_memory);
+}
+
+/* Pop the top item off of CTX's stack.  */
+
+static void
 dwarf_expr_pop (struct dwarf_expr_context *ctx)
 {
   if (ctx->stack_len <= 0)
@@ -125,7 +186,7 @@ dwarf_expr_pop (struct dwarf_expr_context *ctx)
 
 /* Retrieve the N'th item on CTX's stack.  */
 
-ULONGEST
+struct value *
 dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 {
   if (ctx->stack_len <= n)
@@ -133,7 +194,17 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].value;
+}
+
+/* Require that TYPE be an integral type; throw an exception if not.  */
 
+static void
+dwarf_require_integral (struct type *type)
+{
+  if (TYPE_CODE (type) != TYPE_CODE_INT
+      && TYPE_CODE (type) != TYPE_CODE_CHAR
+      && TYPE_CODE (type) != TYPE_CODE_BOOL)
+    error (_("integral type expected in DWARF expression"));
 }
 
 /* Retrieve the N'th item on CTX's stack, converted to an address.  */
@@ -141,41 +212,10 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 CORE_ADDR
 dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n)
 {
-  ULONGEST result = dwarf_expr_fetch (ctx, n);
-
-  /* For most architectures, calling extract_unsigned_integer() alone
-     is sufficient for extracting an address.  However, some
-     architectures (e.g. MIPS) use signed addresses and using
-     extract_unsigned_integer() will not produce a correct
-     result.  Make sure we invoke gdbarch_integer_to_address()
-     for those architectures which require it.  */
-  if (gdbarch_integer_to_address_p (ctx->gdbarch))
-    {
-      enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
-      gdb_byte *buf = alloca (ctx->addr_size);
-      struct type *int_type;
+  struct value *result_val = dwarf_expr_fetch (ctx, n);
 
-      switch (ctx->addr_size)
-	{
-	case 2:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint16;
-	  break;
-	case 4:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint32;
-	  break;
-	case 8:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint64;
-	  break;
-	default:
-	  internal_error (__FILE__, __LINE__,
-			  _("Unsupported address size.\n"));
-	}
-
-      store_unsigned_integer (buf, ctx->addr_size, byte_order, result);
-      return gdbarch_integer_to_address (ctx->gdbarch, int_type, buf);
-    }
-
-  return (CORE_ADDR) result;
+  dwarf_require_integral (value_type (result_val));
+  return value_as_address (result_val);
 }
 
 /* Retrieve the in_stack_memory flag of the N'th item on CTX's stack.  */
@@ -188,7 +228,6 @@ dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n)
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].in_stack_memory;
-
 }
 
 /* Return true if the expression stack is empty.  */
@@ -238,8 +277,10 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset)
   else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
     {
       p->v.ptr.die = ctx->len;
-      p->v.ptr.offset = (LONGEST) dwarf_expr_fetch (ctx, 0);
+      p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0));
     }
+  else if (p->location == DWARF_VALUE_REGISTER)
+    p->v.regno = value_as_long (dwarf_expr_fetch (ctx, 0));
   else
     {
       p->v.value = dwarf_expr_fetch (ctx, 0);
@@ -335,6 +376,65 @@ dwarf_expr_require_composition (const gdb_byte *op_ptr, const gdb_byte *op_end,
 	   op_name);
 }
 
+/* Return true iff the types T1 and T2 are "the same".  This only does
+   checks that might reasonably be needed to compare DWARF base
+   types.  */
+
+static int
+base_types_equal_p (struct type *t1, struct type *t2)
+{
+  if (TYPE_CODE (t1) != TYPE_CODE (t2))
+    return 0;
+  if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
+    return 0;
+  return TYPE_LENGTH (t1) == TYPE_LENGTH (t2);
+}
+
+/* A convenience function to call get_base_type on CTX and return the
+   result.  DIE is the DIE whose type we need.  SIZE is non-zero if
+   this function should verify that the resulting type has the correct
+   size.  */
+
+static struct type *
+dwarf_get_base_type (struct dwarf_expr_context *ctx, ULONGEST die, int size)
+{
+  struct type *result;
+
+  if (ctx->get_base_type)
+    {
+      result = ctx->get_base_type (ctx, die);
+      if (size != 0 && TYPE_LENGTH (result) != size)
+	error (_("DW_OP_GNU_const_type has different sizes for type and data"));
+    }
+  else
+    /* Anything will do.  */
+    result = builtin_type (ctx->gdbarch)->builtin_int;
+
+  return result;
+}
+
+/* Return the unsigned form of TYPE.  TYPE is necessarily an integral
+   type.  */
+
+static struct type *
+get_unsigned_type (struct gdbarch *gdbarch, struct type *type)
+{
+  switch (TYPE_LENGTH (type))
+    {
+    case 1:
+      return builtin_type (gdbarch)->builtin_uint8;
+    case 2:
+      return builtin_type (gdbarch)->builtin_uint16;
+    case 4:
+      return builtin_type (gdbarch)->builtin_uint32;
+    case 8:
+      return builtin_type (gdbarch)->builtin_uint64;
+    default:
+      error (_("no unsigned variant found for type, while evaluating "
+	       "DWARF expression"));
+    }
+}
+
 /* The engine for the expression evaluator.  Using the context in CTX,
    evaluate the expression between OP_PTR and OP_END.  */
 
@@ -342,10 +442,8 @@ static void
 execute_stack_op (struct dwarf_expr_context *ctx,
 		  const gdb_byte *op_ptr, const gdb_byte *op_end)
 {
-#define sign_ext(x) ((LONGEST) (((x) ^ sign_bit) - sign_bit))
-  ULONGEST sign_bit = (ctx->addr_size >= sizeof (ULONGEST) ? 0
-		       : ((ULONGEST) 1) << (ctx->addr_size * 8 - 1));
   enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+  struct type *address_type = dwarf_expr_address_type (ctx);
 
   ctx->location = DWARF_VALUE_MEMORY;
   ctx->initialized = 1;  /* Default is initialized.  */
@@ -368,6 +466,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
       int in_stack_memory = 0;
       ULONGEST uoffset, reg;
       LONGEST offset;
+      struct value *result_val = NULL;
 
       switch (op)
 	{
@@ -404,6 +503,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_lit30:
 	case DW_OP_lit31:
 	  result = op - DW_OP_lit0;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_addr:
@@ -416,47 +516,58 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
 	    result += ctx->offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_const1u:
 	  result = extract_unsigned_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const1s:
 	  result = extract_signed_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const2u:
 	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const2s:
 	  result = extract_signed_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const4u:
 	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const4s:
 	  result = extract_signed_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const8u:
 	  result = extract_unsigned_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_const8s:
 	  result = extract_signed_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_constu:
 	  op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = uoffset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 	case DW_OP_consts:
 	  op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	  result = offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	/* The DW_OP_reg operations are required to occur alone in
@@ -502,6 +613,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 		     "or DW_OP_bit_piece."));
 
 	  result = op - DW_OP_reg0;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -510,6 +622,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
 
 	  result = reg;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -547,6 +660,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    /* The byte offset into the data.  */
 	    op_ptr = read_sleb128 (op_ptr, op_end, &len);
 	    result = (ULONGEST) len;
+	    result_val = value_from_ulongest (address_type, result);
 
 	    ctx->location = DWARF_VALUE_IMPLICIT_POINTER;
 	    dwarf_expr_require_composition (op_ptr, op_end,
@@ -590,6 +704,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_bregx:
@@ -598,6 +713,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, reg);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_fbreg:
@@ -620,11 +736,14 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    if (ctx->location == DWARF_VALUE_MEMORY)
 	      result = dwarf_expr_fetch_address (ctx, 0);
 	    else if (ctx->location == DWARF_VALUE_REGISTER)
-	      result = (ctx->read_reg) (ctx->baton, dwarf_expr_fetch (ctx, 0));
+	      result
+		= (ctx->read_reg) (ctx->baton,
+				   value_as_long (dwarf_expr_fetch (ctx, 0)));
 	    else
 	      error (_("Not implemented: computing frame "
 		       "base using explicit value operator"));
 	    result = result + offset;
+	    result_val = value_from_ulongest (address_type, result);
 	    in_stack_memory = 1;
 	    ctx->stack_len = before_stack_len;
 	    ctx->location = DWARF_VALUE_MEMORY;
@@ -632,7 +751,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  break;
 
 	case DW_OP_dup:
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result_val = dwarf_expr_fetch (ctx, 0);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
 	  break;
 
@@ -642,7 +761,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_pick:
 	  offset = *op_ptr++;
-	  result = dwarf_expr_fetch (ctx, offset);
+	  result_val = dwarf_expr_fetch (ctx, offset);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset);
 	  break;
 	  
@@ -662,7 +781,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  }
 
 	case DW_OP_over:
-	  result = dwarf_expr_fetch (ctx, 1);
+	  result_val = dwarf_expr_fetch (ctx, 1);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1);
 	  break;
 
@@ -685,14 +804,27 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_deref:
 	case DW_OP_deref_size:
+	case DW_OP_GNU_deref_type:
 	  {
 	    int addr_size = (op == DW_OP_deref ? ctx->addr_size : *op_ptr++);
 	    gdb_byte *buf = alloca (addr_size);
 	    CORE_ADDR addr = dwarf_expr_fetch_address (ctx, 0);
+	    struct type *type;
+
 	    dwarf_expr_pop (ctx);
 
+	    if (op == DW_OP_GNU_deref_type)
+	      {
+		ULONGEST type_die;
+
+		op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+		type = dwarf_get_base_type (ctx, type_die, 0);
+	      }
+	    else
+	      type = address_type;
+
 	    (ctx->read_mem) (ctx->baton, buf, addr, addr_size);
-	    result = extract_unsigned_integer (buf, addr_size, byte_order);
+	    result_val = value_from_contents_and_address (type, buf, addr);
 	    break;
 	  }
 
@@ -700,27 +832,34 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_neg:
 	case DW_OP_not:
 	case DW_OP_plus_uconst:
-	  /* Unary operations.  */
-	  result = dwarf_expr_fetch (ctx, 0);
-	  dwarf_expr_pop (ctx);
+	  {
+	    /* Unary operations.  */
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
 
-	  switch (op)
-	    {
-	    case DW_OP_abs:
-	      if (sign_ext (result) < 0)
-		result = -result;
-	      break;
-	    case DW_OP_neg:
-	      result = -result;
-	      break;
-	    case DW_OP_not:
-	      result = ~result;
-	      break;
-	    case DW_OP_plus_uconst:
-	      op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-	      result += reg;
-	      break;
-	    }
+	    switch (op)
+	      {
+	      case DW_OP_abs:
+		if (value_less (result_val,
+				value_zero (value_type (result_val), not_lval)))
+		  result_val = value_neg (result_val);
+		break;
+	      case DW_OP_neg:
+		result_val = value_neg (result_val);
+		break;
+	      case DW_OP_not:
+		dwarf_require_integral (value_type (result_val));
+		result_val = value_complement (result_val);
+		break;
+	      case DW_OP_plus_uconst:
+		dwarf_require_integral (value_type (result_val));
+		result = value_as_long (result_val);
+		op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+		result += reg;
+		result_val = value_from_ulongest (address_type, result);
+		break;
+	      }
+	  }
 	  break;
 
 	case DW_OP_and:
@@ -742,7 +881,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_ne:
 	  {
 	    /* Binary operations.  */
-	    ULONGEST first, second;
+	    struct value *first, *second;
 
 	    second = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
@@ -750,62 +889,115 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    first = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
 
+	    if (! base_types_equal_p (value_type (first), value_type (second)))
+	      error (_("Incompatible types on DWARF stack"));
+
 	    switch (op)
 	      {
 	      case DW_OP_and:
-		result = first & second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_AND);
 		break;
 	      case DW_OP_div:
-		if (!second)
-		  error (_("Division by zero"));
-		result = sign_ext (first) / sign_ext (second);
+		result_val = value_binop (first, second, BINOP_DIV);
                 break;
 	      case DW_OP_minus:
-		result = first - second;
+		result_val = value_binop (first, second, BINOP_SUB);
 		break;
 	      case DW_OP_mod:
-		if (!second)
-		  error (_("Division by zero"));
-		result = first % second;
+		{
+		  int cast_back = 0;
+		  struct type *orig_type = value_type (first);
+
+		  /* We have to special-case "old-style" untyped values
+		     -- these must have mod computed using unsigned
+		     math.  */
+		  if (orig_type == address_type)
+		    {
+		      struct type *utype
+			= get_unsigned_type (ctx->gdbarch, orig_type);
+
+		      cast_back = 1;
+		      first = value_cast (utype, first);
+		      second = value_cast (utype, second);
+		    }
+		  /* Note that value_binop doesn't handle float or
+		     decimal float here.  This seems unimportant.  */
+		  result_val = value_binop (first, second, BINOP_MOD);
+		  if (cast_back)
+		    result_val = value_cast (orig_type, result_val);
+		}
 		break;
 	      case DW_OP_mul:
-		result = first * second;
+		result_val = value_binop (first, second, BINOP_MUL);
 		break;
 	      case DW_OP_or:
-		result = first | second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_IOR);
 		break;
 	      case DW_OP_plus:
-		result = first + second;
+		result_val = value_binop (first, second, BINOP_ADD);
 		break;
 	      case DW_OP_shl:
-		result = first << second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_LSH);
 		break;
 	      case DW_OP_shr:
-		result = first >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		if (!TYPE_UNSIGNED (value_type (first)))
+		  {
+		    struct type *utype
+		      = get_unsigned_type (ctx->gdbarch, value_type (first));
+
+		    first = value_cast (utype, first);
+		  }
+
+		result_val = value_binop (first, second, BINOP_RSH);
+		/* Make sure we wind up with the same type we started
+		   with.  */
+		if (value_type (result_val) != value_type (second))
+		  result_val = value_cast (value_type (second), result_val);
                 break;
 	      case DW_OP_shra:
-		result = sign_ext (first) >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_RSH);
 		break;
 	      case DW_OP_xor:
-		result = first ^ second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_XOR);
 		break;
 	      case DW_OP_le:
-		result = sign_ext (first) <= sign_ext (second);
+		/* A <= B is !(B < A).  */
+		result = ! value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ge:
-		result = sign_ext (first) >= sign_ext (second);
+		/* A >= B is !(A < B).  */
+		result = ! value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_eq:
-		result = sign_ext (first) == sign_ext (second);
+		result = value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_lt:
-		result = sign_ext (first) < sign_ext (second);
+		result = value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_gt:
-		result = sign_ext (first) > sign_ext (second);
+		/* A > B is B < A.  */
+		result = value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ne:
-		result = sign_ext (first) != sign_ext (second);
+		result = ! value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      default:
 		internal_error (__FILE__, __LINE__,
@@ -816,6 +1008,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_call_frame_cfa:
 	  result = (ctx->get_frame_cfa) (ctx->baton);
+	  result_val = value_from_ulongest (address_type, result);
 	  in_stack_memory = 1;
 	  break;
 
@@ -828,9 +1021,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  control block at which the variable is located.  Nothing
 	  should follow this operator, so the top of stack would be
 	  returned.  */
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result = value_as_long (dwarf_expr_fetch (ctx, 0));
 	  dwarf_expr_pop (ctx);
 	  result = (ctx->get_tls_address) (ctx->baton, result);
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_skip:
@@ -840,11 +1034,17 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  goto no_push;
 
 	case DW_OP_bra:
-	  offset = extract_signed_integer (op_ptr, 2, byte_order);
-	  op_ptr += 2;
-	  if (dwarf_expr_fetch (ctx, 0) != 0)
-	    op_ptr += offset;
-	  dwarf_expr_pop (ctx);
+	  {
+	    struct value *val;
+
+	    offset = extract_signed_integer (op_ptr, 2, byte_order);
+	    op_ptr += 2;
+	    val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_require_integral (value_type (val));
+	    if (value_as_long (val) != 0)
+	      op_ptr += offset;
+	    dwarf_expr_pop (ctx);
+	  }
 	  goto no_push;
 
 	case DW_OP_nop:
@@ -912,12 +1112,73 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  ctx->num_pieces = 0;
 	  goto abort_expression;
 
+	case DW_OP_GNU_const_type:
+	  {
+	    ULONGEST type_die;
+	    int n;
+	    const gdb_byte *data;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    n = *op_ptr++;
+	    data = op_ptr;
+	    op_ptr += n;
+
+	    type = dwarf_get_base_type (ctx, type_die, n);
+	    result_val = value_from_contents (type, data);
+	  }
+	  break;
+
+	case DW_OP_GNU_regval_type:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+	    result = (ctx->read_reg) (ctx->baton, reg);
+	    result_val = value_from_ulongest (type, result);
+	  }
+	  break;
+
+	case DW_OP_GNU_convert:
+	case DW_OP_GNU_reinterpret:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
+
+	    if (op == DW_OP_GNU_convert)
+	      result_val = value_cast (type, result_val);
+	    else if (type == value_type (result_val))
+	      {
+		/* Nothing.  */
+	      }
+	    else if (TYPE_LENGTH (type)
+		     != TYPE_LENGTH (value_type (result_val)))
+	      error (_("DW_OP_GNU_reinterpret has wrong size"));
+	    else
+	      result_val
+		= value_from_contents (type,
+				       value_contents_all (result_val));
+	  }
+	  break;
+
 	default:
 	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
 	}
 
       /* Most things push a result value.  */
-      dwarf_expr_push (ctx, result, in_stack_memory);
+      gdb_assert (result_val != NULL);
+      dwarf_expr_push (ctx, result_val, in_stack_memory);
     no_push:
       ;
     }
@@ -931,5 +1192,11 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 abort_expression:
   ctx->recursion_depth--;
   gdb_assert (ctx->recursion_depth >= 0);
-#undef sign_ext
+}
+
+void
+_initialize_dwarf2expr (void)
+{
+  dwarf_arch_cookie
+    = gdbarch_data_register_post_init (dwarf_gdbarch_types_init);
 }
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index 78ff53f..676b54b 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -51,7 +51,7 @@ enum dwarf_value_location
 
 struct dwarf_stack_value
 {
-  ULONGEST value;
+  struct value *value;
 
   /* Non-zero if the piece is in memory and is known to be
      on the program's stack.  It is always ok to set this to zero.
@@ -111,6 +111,13 @@ struct dwarf_expr_context
      being passed to and returned from the called DWARF subroutine.  */
   void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset);
 
+  /* Return the base type given by the indicated DIE.  This can throw
+     an exception if the DIE is invalid or does not represent a base
+     type.  If can also be NULL in the special case where the
+     callbacks are not performing evaluation, and thus it is
+     meaningful to substitute a stub type of the correct size.  */
+  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, size_t die);
+
 #if 0
   /* Not yet implemented.  */
 
@@ -180,9 +187,11 @@ struct dwarf_expr_piece
       int in_stack_memory;
     } mem;
 
-    /* The piece's register number or literal value, for
-       DWARF_VALUE_REGISTER or DWARF_VALUE_STACK pieces.  */
-    ULONGEST value;
+    /* The piece's register number, for DWARF_VALUE_REGISTER pieces.  */
+    int regno;
+
+    /* The piece's literal value, for DWARF_VALUE_STACK pieces.  */
+    struct value *value;
 
     struct
     {
@@ -214,12 +223,12 @@ void free_dwarf_expr_context (struct dwarf_expr_context *ctx);
 struct cleanup *
     make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx);
 
-void dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
-		      int in_stack_memory);
-void dwarf_expr_pop (struct dwarf_expr_context *ctx);
+void dwarf_expr_push_address (struct dwarf_expr_context *ctx,
+			      CORE_ADDR value,
+			      int in_stack_memory);
 void dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr,
 		      size_t len);
-ULONGEST dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
+struct value *dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
 CORE_ADDR dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n);
 int dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n);
 
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 4c13307..01532d9 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -286,6 +286,16 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 		     ctx->get_frame_pc, ctx->baton);
 }
 
+/* Callback function for dwarf2_evaluate_loc_desc.  */
+
+static struct type *
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+  struct dwarf_expr_baton *debaton = ctx->baton;
+
+  return dwarf2_get_die_type (die_offset, debaton->per_cu);
+}
+
 struct piece_closure
 {
   /* Reference count.  */
@@ -313,6 +323,7 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
 			int addr_size)
 {
   struct piece_closure *c = XZALLOC (struct piece_closure);
+  int i;
 
   c->refc = 1;
   c->per_cu = per_cu;
@@ -321,6 +332,9 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
   c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
 
   memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
+  for (i = 0; i < n_pieces; ++i)
+    if (c->pieces[i].location == DWARF_VALUE_STACK)
+      value_incref (c->pieces[i].v.value);
 
   return c;
 }
@@ -576,7 +590,7 @@ read_pieced_value (struct value *v)
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = source_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -609,7 +623,7 @@ read_pieced_value (struct value *v)
 	    else
 	      {
 		error (_("Unable to access DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, value_as_long (p->v.value)));
 	      }
 	  }
 	  break;
@@ -623,7 +637,6 @@ read_pieced_value (struct value *v)
 
 	case DWARF_VALUE_STACK:
 	  {
-	    struct gdbarch *gdbarch = get_type_arch (value_type (v));
 	    size_t n = this_size;
 
 	    if (n > c->addr_size - source_offset)
@@ -634,18 +647,11 @@ read_pieced_value (struct value *v)
 	      {
 		/* Nothing.  */
 	      }
-	    else if (source_offset == 0)
-	      store_unsigned_integer (buffer, n,
-				      gdbarch_byte_order (gdbarch),
-				      p->v.value);
 	    else
 	      {
-		gdb_byte bytes[sizeof (ULONGEST)];
+		const gdb_byte *val_bytes = value_contents_all (p->v.value);
 
-		store_unsigned_integer (bytes, n + source_offset,
-					gdbarch_byte_order (gdbarch),
-					p->v.value);
-		memcpy (buffer, bytes + source_offset, n);
+		intermediate_buffer = val_bytes + source_offset;
 	      }
 	  }
 	  break;
@@ -776,7 +782,7 @@ write_pieced_value (struct value *to, struct value *from)
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = dest_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -816,7 +822,7 @@ write_pieced_value (struct value *to, struct value *from)
 	    else
 	      {
 		error (_("Unable to write to DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, value_as_long (p->v.value)));
 	      }
 	  }
 	  break;
@@ -1033,6 +1039,12 @@ free_pieced_value_closure (struct value *v)
   --c->refc;
   if (c->refc == 0)
     {
+      int i;
+
+      for (i = 0; i < c->n_pieces; ++i)
+	if (c->pieces[i].location == DWARF_VALUE_STACK)
+	  value_free (c->pieces[i].v.value);
+
       xfree (c->pieces);
       xfree (c);
     }
@@ -1106,6 +1118,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   ctx->get_frame_pc = dwarf_expr_frame_pc;
   ctx->get_tls_address = dwarf_expr_tls_address;
   ctx->dwarf_call = dwarf_expr_dwarf_call;
+  ctx->get_base_type = dwarf_expr_get_base_type;
 
   TRY_CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -1148,7 +1161,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0);
+	    ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
 	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
 
 	    if (byte_offset != 0)
@@ -1176,26 +1189,23 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
 	case DWARF_VALUE_STACK:
 	  {
-	    ULONGEST value = dwarf_expr_fetch (ctx, 0);
-	    bfd_byte *contents, *tem;
-	    size_t n = ctx->addr_size;
+	    struct value *value = dwarf_expr_fetch (ctx, 0);
+	    gdb_byte *contents;
+	    const gdb_byte *val_bytes;
+	    size_t n = TYPE_LENGTH (value_type (value));
 
 	    if (byte_offset + TYPE_LENGTH (type) > n)
 	      invalid_synthetic_pointer ();
 
-	    tem = alloca (n);
-	    store_unsigned_integer (tem, n,
-				    gdbarch_byte_order (ctx->gdbarch),
-				    value);
-
-	    tem += byte_offset;
+	    val_bytes = value_contents_all (value);
+	    val_bytes += byte_offset;
 	    n -= byte_offset;
 
 	    retval = allocate_value (type);
 	    contents = value_contents_raw (retval);
 	    if (n > TYPE_LENGTH (type))
 	      n = TYPE_LENGTH (type);
-	    memcpy (contents, tem, n);
+	    memcpy (contents, val_bytes, n);
 	  }
 	  break;
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 96a490e..08849ed 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -59,6 +59,9 @@ struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
+struct type *dwarf2_get_die_type (unsigned int die_offset,
+				  struct dwarf2_per_cu_data *per_cu);
+
 /* Evaluate a location description, starting at DATA and with length
    SIZE, to find the current location of variable of TYPE in the context
    of FRAME.  */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index fdab83d..790a873 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13017,6 +13017,18 @@ dwarf_stack_op_name (unsigned op)
       return "DW_OP_GNU_uninit";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
+    case DW_OP_GNU_entry_value:
+      return "DW_OP_GNU_entry_value";
+    case DW_OP_GNU_const_type:
+      return "DW_OP_GNU_const_type";
+    case DW_OP_GNU_regval_type:
+      return "DW_OP_GNU_regval_type";
+    case DW_OP_GNU_deref_type:
+      return "DW_OP_GNU_deref_type";
+    case DW_OP_GNU_convert:
+      return "DW_OP_GNU_convert";
+    case DW_OP_GNU_reinterpret:
+      return "DW_OP_GNU_reinterpret";
     default:
       return NULL;
     }
@@ -13575,6 +13587,31 @@ dwarf2_fetch_die_location_block (unsigned int offset,
   return retval;
 }
 
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+   PER_CU.  */
+
+struct type *
+dwarf2_get_die_type (unsigned int die_offset,
+		     struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf2_cu *cu = per_cu->cu;
+  struct die_info *die;
+  struct type *result;
+
+  dw2_setup (per_cu->objfile);
+
+  die = follow_die_offset (die_offset, &cu);
+  if (!die)
+    error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
+	   die_offset, per_cu->cu->objfile->name);
+
+  result = get_die_type (die, cu);
+  if (result == NULL)
+    result = read_type_die_1 (die, cu);
+
+  return result;
+}
+
 /* Follow the signature attribute ATTR in SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
    On exit *REF_CU is the CU of the result.  */
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.S b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
new file mode 100644
index 0000000..a46da14
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
@@ -0,0 +1,2225 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This source file was generated from typeddwarf.c using the following
+   command line:
+
+   gcc -m32 -dA -S -g -O2 typeddwarf.c -o typeddwarf.S
+
+*/
+
+
+	.file	"typeddwarf.c"
+	.text
+.Ltext0:
+	.p2align 4,,15
+	.globl	f1
+	.type	f1, @function
+f1:
+.LFB0:
+	# typeddwarf.c:10
+.LM1:
+.LVL0:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:29
+.LM2:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:30
+.LM3:
+	ret
+.LFE0:
+	.size	f1, .-f1
+	.p2align 4,,15
+	.globl	f2
+	.type	f2, @function
+f2:
+.LFB1:
+	# typeddwarf.c:34
+.LM4:
+.LVL1:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	subl	$12, %esp
+.LCFI0:
+	# typeddwarf.c:53
+.LM5:
+	movl	vv, %eax
+	# typeddwarf.c:54
+.LM6:
+	fnstcw	6(%esp)
+	# typeddwarf.c:34
+.LM7:
+	flds	40(%esp)
+.LVL2:
+	# typeddwarf.c:54
+.LM8:
+	fldl	16(%esp)
+	# typeddwarf.c:53
+.LM9:
+	addl	$1, %eax
+	movl	%eax, vv
+	# typeddwarf.c:54
+.LM10:
+	movzwl	6(%esp), %eax
+	movb	$12, %ah
+	movw	%ax, 4(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	# typeddwarf.c:55
+.LM11:
+	fldl	24(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:54
+.LM12:
+	movl	%eax, vv
+	# typeddwarf.c:55
+.LM13:
+	movl	(%esp), %eax
+	# typeddwarf.c:56
+.LM14:
+	fldl	32(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:55
+.LM15:
+	movl	%eax, vv
+	# typeddwarf.c:56
+.LM16:
+	movl	(%esp), %eax
+	# typeddwarf.c:57
+.LM17:
+	fldcw	4(%esp)
+	fistl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:56
+.LM18:
+	movl	%eax, vv
+	# typeddwarf.c:57
+.LM19:
+	movl	(%esp), %eax
+	# typeddwarf.c:58
+.LM20:
+	flds	44(%esp)
+	# typeddwarf.c:57
+.LM21:
+	movl	%eax, vv
+	# typeddwarf.c:58
+.LM22:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:59
+.LM23:
+	movl	48(%esp), %eax
+	# typeddwarf.c:63
+.LM24:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:59
+.LM25:
+	movl	%eax, vv
+	# typeddwarf.c:60
+.LM26:
+	movl	52(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:61
+.LM27:
+	movl	56(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:62
+.LM28:
+	movl	64(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:63
+.LM29:
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:64
+.LM30:
+	addl	$12, %esp
+.LCFI1:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE1:
+	.size	f2, .-f2
+	.p2align 4,,15
+	.globl	f3
+	.type	f3, @function
+f3:
+.LFB2:
+	# typeddwarf.c:68
+.LM31:
+.LVL3:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:73
+.LM32:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:74
+.LM33:
+	ret
+.LFE2:
+	.size	f3, .-f3
+	.p2align 4,,15
+	.globl	f4
+	.type	f4, @function
+f4:
+.LFB3:
+	# typeddwarf.c:78
+.LM34:
+.LVL4:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:82
+.LM35:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:83
+.LM36:
+	ret
+.LFE3:
+	.size	f4, .-f4
+	.section	.text.startup,"ax",@progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, @function
+main:
+.LFB4:
+	# typeddwarf.c:87
+.LM37:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	pushl	%esi
+.LCFI4:
+	# typeddwarf.c:88
+.LM38:
+	movl	$0x40a00000, %esi
+	# typeddwarf.c:87
+.LM39:
+	pushl	%ebx
+.LCFI5:
+	# typeddwarf.c:88
+.LM40:
+	movl	$0x40800000, %ebx
+	# typeddwarf.c:87
+.LM41:
+	andl	$-16, %esp
+	subl	$112, %esp
+.LCFI6:
+	# typeddwarf.c:88
+.LM42:
+	flds	.LC3
+	fstl	16(%esp)
+	movl	%esi, 28(%esp)
+	flds	.LC4
+	fstl	8(%esp)
+	movl	%ebx, 24(%esp)
+	fld1
+	fstl	(%esp)
+	movl	$9, 48(%esp)
+	fstps	64(%esp)
+	fstps	80(%esp)
+	movl	$0, 52(%esp)
+	fstps	96(%esp)
+	movl	$8, 40(%esp)
+	movl	$0, 44(%esp)
+	movl	$7, 36(%esp)
+	movl	$6, 32(%esp)
+	call	f1
+.LVL5:
+	# typeddwarf.c:89
+.LM43:
+	movl	%esi, 28(%esp)
+	movl	%ebx, 24(%esp)
+	movl	$9, 48(%esp)
+	movl	$0, 52(%esp)
+	movl	$8, 40(%esp)
+	flds	96(%esp)
+	fstpl	16(%esp)
+	movl	$0, 44(%esp)
+	flds	80(%esp)
+	fstpl	8(%esp)
+	movl	$7, 36(%esp)
+	flds	64(%esp)
+	fstpl	(%esp)
+	movl	$6, 32(%esp)
+	call	f2
+.LVL6:
+	# typeddwarf.c:90
+.LM44:
+	movl	$4, 20(%esp)
+	movl	$3, 12(%esp)
+	movl	$0, 16(%esp)
+	movl	$2, 8(%esp)
+	movl	$1, (%esp)
+	movl	$0, 4(%esp)
+	call	f3
+.LVL7:
+	# typeddwarf.c:91
+.LM45:
+	movl	$640, 16(%esp)
+	movl	$0, 20(%esp)
+	movl	$0, 24(%esp)
+	movl	$809369600, 28(%esp)
+	movl	$160, 4(%esp)
+	movl	$832569344, 8(%esp)
+	movl	$838860880, (%esp)
+	call	f4
+.LVL8:
+	# typeddwarf.c:93
+.LM46:
+	leal	-8(%ebp), %esp
+	xorl	%eax, %eax
+	popl	%ebx
+.LCFI7:
+	popl	%esi
+.LCFI8:
+	popl	%ebp
+.LCFI9:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE4:
+	.size	main, .-main
+	.comm	vv,4,4
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align 4
+.LC3:
+	.long	1077936128
+	.align 4
+.LC4:
+	.long	1073741824
+#APP
+	.section	.debug_frame,"",@progbits
+.Lframe0:
+	.long	.LECIE0-.LSCIE0	# Length of Common Information Entry
+.LSCIE0:
+	.long	0xffffffff	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE0:
+.LSFDE0:
+	.long	.LEFDE0-.LASFDE0	# FDE Length
+.LASFDE0:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE0:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE2:
+.LSFDE4:
+	.long	.LEFDE4-.LASFDE4	# FDE Length
+.LASFDE4:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE4:
+.LSFDE6:
+	.long	.LEFDE6-.LASFDE6	# FDE Length
+.LASFDE6:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE6:
+.LSFDE8:
+	.long	.LEFDE8-.LASFDE8	# FDE Length
+.LASFDE8:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE8:
+#NO_APP
+#APP
+	.section	.eh_frame,"aw",@progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.long	0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE1:
+.LSFDE11:
+	.long	.LEFDE11-.LASFDE11	# FDE Length
+.LASFDE11:
+	.long	.LASFDE11-.Lframe1	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE11:
+.LSFDE13:
+	.long	.LEFDE13-.LASFDE13	# FDE Length
+.LASFDE13:
+	.long	.LASFDE13-.Lframe1	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE13:
+.LSFDE15:
+	.long	.LEFDE15-.LASFDE15	# FDE Length
+.LASFDE15:
+	.long	.LASFDE15-.Lframe1	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE15:
+.LSFDE17:
+	.long	.LEFDE17-.LASFDE17	# FDE Length
+.LASFDE17:
+	.long	.LASFDE17-.Lframe1	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE17:
+.LSFDE19:
+	.long	.LEFDE19-.LASFDE19	# FDE Length
+.LASFDE19:
+	.long	.LASFDE19-.Lframe1	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE19:
+#NO_APP
+	.text
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x64e	# Length of Compilation Unit Info
+	.value	0x2	# DWARF version number
+	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+	.byte	0x4	# Pointer Size (in bytes)
+	.uleb128 0x1	# (DIE (0xb) DW_TAG_compile_unit)
+	.long	.LASF5	# DW_AT_producer: "GNU C 4.7.0 20110504 (experimental)"
+	.byte	0x1	# DW_AT_language
+	.long	.LASF6	# DW_AT_name: "typeddwarf.c"
+	.long	.LASF7	# DW_AT_comp_dir: "/usr/src/gcc/obj/gcc"
+	.long	.Ldebug_ranges0+0	# DW_AT_ranges
+	.long	0	# DW_AT_low_pc
+	.long	0	# DW_AT_entry_pc
+	.long	.Ldebug_line0	# DW_AT_stmt_list
+	.uleb128 0x2	# (DIE (0x29) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF0	# DW_AT_name: "double"
+	.uleb128 0x2	# (DIE (0x30) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF1	# DW_AT_name: "float"
+	.uleb128 0x2	# (DIE (0x37) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.long	.LASF2	# DW_AT_name: "long long int"
+	.uleb128 0x3	# (DIE (0x3e) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.ascii "int\0"	# DW_AT_name
+	.uleb128 0x2	# (DIE (0x45) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF3	# DW_AT_name: "unsigned int"
+	.uleb128 0x2	# (DIE (0x4c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF4	# DW_AT_name: "long long unsigned int"
+	.uleb128 0x4	# (DIE (0x53) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f1\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB0	# DW_AT_low_pc
+	.long	.LFE0	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x232	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x6b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x77) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x83) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x8f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x9b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0xa7) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0xb3) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0xbf) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0xcb) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0xd7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xb	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xe9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xc	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xfd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xe	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x6	# (DIE (0x109) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x10	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x11d) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x11	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x12f) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x12	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x141) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x13	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x153) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x14	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x167) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x15	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x179) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x16	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x18d) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x17	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x19f) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x18	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1b1) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x19	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1cf) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1a	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1f1) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x213) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1c	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x53
+	.uleb128 0x7	# (DIE (0x232) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f2\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB1	# DW_AT_low_pc
+	.long	.LFE1	# DW_AT_high_pc
+	.long	.LLST0	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x40a	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x24b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x257) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x263) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x26f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x27b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0x287) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0x293) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0x29f) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0x2ab) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0x2b7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x23	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2c9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x24	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2dd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x26	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x2e9) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x28	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x2f2) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x29	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.uleb128 0x6	# (DIE (0x2fb) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2a	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x30d) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x31f) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2c	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x333) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2d	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x345) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2e	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x359) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2f	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x36b) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x30	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x37d) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x31	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x39b) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x32	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x24	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.byte	0x1c	# DW_OP_minus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0x78b58c40	# fp or vector constant word 0
+	.long	0x4415af1d	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3c9) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x33	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x401c0000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3eb) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x34	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x232
+	.uleb128 0x4	# (DIE (0x40a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f3\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB2	# DW_AT_low_pc
+	.long	.LFE2	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x4fd	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x422) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x42e) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x43a) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.uleb128 0x5	# (DIE (0x446) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.uleb128 0x6	# (DIE (0x452) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x45	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x16	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x12	# DW_OP_dup
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x16	# DW_OP_swap
+	.byte	0x14	# DW_OP_over
+	.byte	0x2b	# DW_OP_gt
+	.byte	0x28	# DW_OP_bra
+	.value	0x1
+	.byte	0x16	# DW_OP_swap
+	.byte	0x13	# DW_OP_drop
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x472) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x46	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x496) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x47	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x4ba) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x48	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x38	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x40a
+	.uleb128 0x4	# (DIE (0x4fd) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f4\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB3	# DW_AT_low_pc
+	.long	.LFE3	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x555	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x515) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x521) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 4
+	.uleb128 0x5	# (DIE (0x52d) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x539) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4f	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x542) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x50	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x54b) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x51	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0	# end of children of DIE 0x4fd
+	.uleb128 0x2	# (DIE (0x555) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF8	# DW_AT_name: "_Decimal32"
+	.uleb128 0x2	# (DIE (0x55c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF9	# DW_AT_name: "_Decimal64"
+	.uleb128 0x2	# (DIE (0x563) DW_TAG_base_type)
+	.byte	0x10	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF10	# DW_AT_name: "_Decimal128"
+	.uleb128 0x9	# (DIE (0x56a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.long	.LASF11	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x56	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.long	.LFB4	# DW_AT_low_pc
+	.long	.LFE4	# DW_AT_high_pc
+	.long	.LLST1	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x62f	# DW_AT_sibling
+	.uleb128 0xa	# (DIE (0x587) DW_TAG_GNU_call_site)
+	.long	.LVL5	# DW_AT_low_pc
+	.long	0x53	# DW_AT_abstract_origin
+	.long	0x5e1	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x594) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 0
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5a4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5b4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5c4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5cc) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5d4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x5da) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x587
+	.uleb128 0xa	# (DIE (0x5e1) DW_TAG_GNU_call_site)
+	.long	.LVL6	# DW_AT_low_pc
+	.long	0x232	# DW_AT_abstract_origin
+	.long	0x60b	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x5ee) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5f6) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5fe) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x604) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x5e1
+	.uleb128 0xa	# (DIE (0x60b) DW_TAG_GNU_call_site)
+	.long	.LVL7	# DW_AT_low_pc
+	.long	0x40a	# DW_AT_abstract_origin
+	.long	0x625	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x618) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x32	# DW_OP_lit2
+	.uleb128 0xb	# (DIE (0x61e) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 20
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x34	# DW_OP_lit4
+	.byte	0	# end of children of DIE 0x60b
+	.uleb128 0xc	# (DIE (0x625) DW_TAG_GNU_call_site)
+	.long	.LVL8	# DW_AT_low_pc
+	.long	0x4fd	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x56a
+	.uleb128 0xd	# (DIE (0x62f) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x1	# DW_AT_declaration
+	.uleb128 0xe	# (DIE (0x63b) DW_TAG_volatile_type)
+	.long	0x3e	# DW_AT_type
+	.uleb128 0xf	# (DIE (0x640) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x5	# DW_AT_location
+	.byte	0x3	# DW_OP_addr
+	.long	vv
+	.byte	0	# end of children of DIE 0xb
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1	# (abbrev code)
+	.uleb128 0x11	# (TAG: DW_TAG_compile_unit)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x25	# (DW_AT_producer)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x13	# (DW_AT_language)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x1b	# (DW_AT_comp_dir)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x55	# (DW_AT_ranges)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x52	# (DW_AT_entry_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x10	# (DW_AT_stmt_list)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.byte	0
+	.byte	0
+	.uleb128 0x2	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.byte	0
+	.byte	0
+	.uleb128 0x3	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.byte	0
+	.byte	0
+	.uleb128 0x4	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x5	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x6	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x7	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x8	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x9	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xa	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xb	# (abbrev code)
+	.uleb128 0x410a	# (TAG: DW_TAG_GNU_call_site_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2111	# (DW_AT_GNU_call_site_value)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0xc	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xd	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3c	# (DW_AT_declaration)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.byte	0
+	.byte	0
+	.uleb128 0xe	# (abbrev code)
+	.uleb128 0x35	# (TAG: DW_TAG_volatile_type)
+	.byte	0	# DW_children_no
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xf	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.long	.LFB1	# Location list begin address (*.LLST0)
+	.long	.LCFI0	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI0	# Location list begin address (*.LLST0)
+	.long	.LCFI1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.long	.LCFI1	# Location list begin address (*.LLST0)
+	.long	.LFE1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST0)
+	.long	0	# Location list terminator end (*.LLST0)
+.LLST1:
+	.long	.LFB4	# Location list begin address (*.LLST1)
+	.long	.LCFI2	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI2	# Location list begin address (*.LLST1)
+	.long	.LCFI3	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.long	.LCFI3	# Location list begin address (*.LLST1)
+	.long	.LCFI9	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x75	# DW_OP_breg5
+	.sleb128 8
+	.long	.LCFI9	# Location list begin address (*.LLST1)
+	.long	.LFE4	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST1)
+	.long	0	# Location list terminator end (*.LLST1)
+	.section	.debug_aranges,"",@progbits
+	.long	0x24	# Length of Address Ranges Info
+	.value	0x2	# DWARF Version
+	.long	.Ldebug_info0	# Offset of Compilation Unit Info
+	.byte	0x4	# Size of Address
+	.byte	0	# Size of Segment Descriptor
+	.value	0	# Pad to 8 byte boundary
+	.value	0
+	.long	.Ltext0	# Address
+	.long	.Letext0-.Ltext0	# Length
+	.long	.LFB4	# Address
+	.long	.LFE4-.LFB4	# Length
+	.long	0
+	.long	0
+	.section	.debug_ranges,"",@progbits
+.Ldebug_ranges0:
+	.long	.Ltext0	# Offset 0
+	.long	.Letext0
+	.long	.LFB4	# Offset 0x8
+	.long	.LFE4
+	.long	0
+	.long	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.long	.LELT0-.LSLT0	# Length of Source Line Info
+.LSLT0:
+	.value	0x2	# DWARF Version
+	.long	.LELTP0-.LASLTP0	# Prolog Length
+.LASLTP0:
+	.byte	0x1	# Minimum Instruction Length
+	.byte	0x1	# Default is_stmt_start flag
+	.byte	0xf6	# Line Base Value (Special Opcodes)
+	.byte	0xf2	# Line Range Value (Special Opcodes)
+	.byte	0xd	# Special Opcode Base
+	.byte	0	# opcode: 0x1 has 0 args
+	.byte	0x1	# opcode: 0x2 has 1 args
+	.byte	0x1	# opcode: 0x3 has 1 args
+	.byte	0x1	# opcode: 0x4 has 1 args
+	.byte	0x1	# opcode: 0x5 has 1 args
+	.byte	0	# opcode: 0x6 has 0 args
+	.byte	0	# opcode: 0x7 has 0 args
+	.byte	0	# opcode: 0x8 has 0 args
+	.byte	0x1	# opcode: 0x9 has 1 args
+	.byte	0	# opcode: 0xa has 0 args
+	.byte	0	# opcode: 0xb has 0 args
+	.byte	0x1	# opcode: 0xc has 1 args
+	.byte	0	# End directory table
+	.ascii "typeddwarf.c\0"	# File Entry: 0x1
+	.uleb128 0
+	.uleb128 0
+	.uleb128 0
+	.byte	0	# End file name table
+.LELTP0:
+	.byte	0	# set address *.LM37
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM37
+	.byte	0x6d	# line 87
+	.byte	0	# set address *.LM38
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM38
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM39
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM39
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM40
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM40
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM41
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM41
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM42
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM42
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM43
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM43
+	.byte	0x18	# line 89
+	.byte	0	# set address *.LM44
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM44
+	.byte	0x18	# line 90
+	.byte	0	# set address *.LM45
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM45
+	.byte	0x18	# line 91
+	.byte	0	# set address *.LM46
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM46
+	.byte	0x19	# line 93
+	.byte	0	# set address *.LFE4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LFE4
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+	.byte	0	# set address *.LM1
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM1
+	.byte	0x20	# line 10
+	.byte	0	# set address *.LM2
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM2
+	.byte	0x2a	# line 29
+	.byte	0	# set address *.LM3
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM3
+	.byte	0x18	# line 30
+	.byte	0	# set address *.LM4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM4
+	.byte	0x1b	# line 34
+	.byte	0	# set address *.LM5
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM5
+	.byte	0x2a	# line 53
+	.byte	0	# set address *.LM6
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM6
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM7
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM7
+	.byte	0x3	# advance to line 34
+	.sleb128 -20
+	.byte	0x1
+	.byte	0	# set address *.LM8
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM8
+	.byte	0x2b	# line 54
+	.byte	0	# set address *.LM9
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM9
+	.byte	0x16	# line 53
+	.byte	0	# set address *.LM10
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM10
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM11
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM11
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM12
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM12
+	.byte	0x16	# line 54
+	.byte	0	# set address *.LM13
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM13
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM14
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM14
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM15
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM15
+	.byte	0x16	# line 55
+	.byte	0	# set address *.LM16
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM16
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM17
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM17
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM18
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM18
+	.byte	0x16	# line 56
+	.byte	0	# set address *.LM19
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM19
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM20
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM20
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM21
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM21
+	.byte	0x16	# line 57
+	.byte	0	# set address *.LM22
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM22
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM23
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM23
+	.byte	0x18	# line 59
+	.byte	0	# set address *.LM24
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM24
+	.byte	0x1b	# line 63
+	.byte	0	# set address *.LM25
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM25
+	.byte	0x13	# line 59
+	.byte	0	# set address *.LM26
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM26
+	.byte	0x18	# line 60
+	.byte	0	# set address *.LM27
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM27
+	.byte	0x18	# line 61
+	.byte	0	# set address *.LM28
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM28
+	.byte	0x18	# line 62
+	.byte	0	# set address *.LM29
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM29
+	.byte	0x18	# line 63
+	.byte	0	# set address *.LM30
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM30
+	.byte	0x18	# line 64
+	.byte	0	# set address *.LM31
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM31
+	.byte	0x1b	# line 68
+	.byte	0	# set address *.LM32
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM32
+	.byte	0x1c	# line 73
+	.byte	0	# set address *.LM33
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM33
+	.byte	0x18	# line 74
+	.byte	0	# set address *.LM34
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM34
+	.byte	0x1b	# line 78
+	.byte	0	# set address *.LM35
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM35
+	.byte	0x1b	# line 82
+	.byte	0	# set address *.LM36
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM36
+	.byte	0x18	# line 83
+	.byte	0	# set address *.Letext0
+	.uleb128 0x5
+	.byte	0x2
+	.long	.Letext0
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+.LELT0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF2:
+	.string	"long long int"
+.LASF3:
+	.string	"unsigned int"
+.LASF8:
+	.string	"_Decimal32"
+.LASF4:
+	.string	"long long unsigned int"
+.LASF11:
+	.string	"main"
+.LASF9:
+	.string	"_Decimal64"
+.LASF0:
+	.string	"double"
+.LASF10:
+	.string	"_Decimal128"
+.LASF7:
+	.string	"/usr/src/gcc/obj/gcc"
+.LASF1:
+	.string	"float"
+.LASF6:
+	.string	"typeddwarf.c"
+.LASF5:
+	.string	"GNU C 4.7.0 20110504 (experimental)"
+	.ident	"GCC: (GNU) 4.7.0 20110504 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.c b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
new file mode 100644
index 0000000..e5f7d67
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
@@ -0,0 +1,93 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-g" } */
+
+typedef __SIZE_TYPE__ size_t;
+volatile int vv;
+extern void *memcpy (void *, const void *, size_t);
+
+__attribute__((noinline, noclone)) void
+f1 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 29 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 29 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 29 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { gdb-test 29 "n" "9" } } */
+  double o = h;			/* { dg-final { gdb-test 29 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 29 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 29 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 29 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 29 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 29 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 29 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 29 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 29 "w" "1" } } */
+  double x = a + b + 1.0;	/* { dg-final { gdb-test 29 "x" "4" } } */
+  double y = b + c + 2.0;	/* { dg-final { gdb-test 29 "y" "7" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 29 "z" "12" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f2 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 53 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 53 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 53 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { xfail-gdb-test 53 "n" "9" } } */
+  double o = h;			/* { dg-final { xfail-gdb-test 53 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 53 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 53 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 53 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 53 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 53 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 53 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 53 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 53 "w" "1" } } */
+  double x = a + b - 3 + 1.0e20;/* { dg-final { gdb-test 53 "x" "1e\\+20" } } */
+  double y = b + c * 7.0;	/* { dg-final { gdb-test 53 "y" "23" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 53 "z" "12" } } */
+  vv++;
+  vv = a;
+  vv = b;
+  vv = c;
+  vv = d;
+  vv = e;
+  vv = f;
+  vv = g;
+  vv = h;
+  vv = i;
+  vv = j;
+}
+
+__attribute__((noinline, noclone)) void
+f3 (long long a, int b, long long c, unsigned d)
+{
+  long long w = (a > d) ? a : d;/* { dg-final { gdb-test 73 "w" "4" } } */
+  long long x = a + b + 7;	/* { dg-final { gdb-test 73 "x" "10" } } */
+  long long y = c + d + 0x912345678LL;/* { dg-final { gdb-test 73 "y" "38960125567" } } */
+  int z = (x + y);		/* { dg-final { gdb-test 73 "z" "305419913" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f4 (_Decimal32 a, _Decimal64 b, _Decimal128 c)
+{
+  _Decimal32 w = a * 8.0DF + 6.0DF;/* { dg-final { xfail-gdb-test 82 "(int)w" "70" } } */
+  _Decimal64 x = b / 8.0DD - 6.0DD;/* { dg-final { xfail-gdb-test 82 "(int)x" "-4" } } */
+  _Decimal128 y = -c / 8.0DL;	/* { dg-final { xfail-gdb-test 82 "(int)y" "-8" } } */
+  vv++;
+}
+
+int
+main ()
+{
+  f1 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f2 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f3 (1, 2, 3, 4);
+  f4 (8.0DF, 16.0DD, 64.0DL);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
new file mode 100644
index 0000000..bddcc18
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -0,0 +1,91 @@
+# Copyright 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib dwarf.exp
+
+set test "typeddwarf"
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if ![dwarf2_support] {
+    return 0  
+}
+
+# This test can only be run on x86 targets.
+if { ![istarget i?86-*] } {
+    return 0
+}
+
+if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+global tests
+set tests(_) -
+unset tests(_)
+
+proc gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 0]
+}
+
+proc xfail-gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 1]
+}
+
+proc scan_gdb_tests {} {
+    global srcdir subdir test
+
+    set file "$srcdir/$subdir/$test.c"
+
+    set fd [open "$file"]
+    while {![eof $fd]} {
+	set line [gets $fd]
+	if {! [regexp "\{ (gdb-test .+) \} \}" $line ignore test_cmd]} {
+	    continue
+	}
+
+	eval $test_cmd
+    }
+    close $fd
+}
+
+scan_gdb_tests
+
+foreach line [lsort [array names tests]] {
+    gdb_test "break typeddwarf.c:$line" "Breakpoint .*" \
+	"set breakpoint at typeddwarf.c:$line"
+    gdb_continue_to_breakpoint "continue to typeddwarf.c:$line"
+
+    foreach test $tests($line) {
+	set var [lindex $test 0]
+	set value [lindex $test 1]
+	set should_xfail [lindex $test 2]
+
+	if {$should_xfail} {
+	    setup_xfail *-*-*
+	}
+
+	gdb_test "print $var" \
+	    " = $value" \
+	    "check value of $var at typeddwarf.c:$line"
+    }
+}
diff --git a/gdb/value.c b/gdb/value.c
index 2acb1df..cb7cae5 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -2965,6 +2965,19 @@ value_from_contents_and_address (struct type *type,
   return v;
 }
 
+/* Create a value of type TYPE holding the contents CONTENTS.
+   The new value is `not_lval'.  */
+
+struct value *
+value_from_contents (struct type *type, const gdb_byte *contents)
+{
+  struct value *result;
+
+  result = allocate_value (type);
+  memcpy (value_contents_raw (result), contents, TYPE_LENGTH (type));
+  return result;
+}
+
 struct value *
 value_from_double (struct type *type, DOUBLEST num)
 {
diff --git a/gdb/value.h b/gdb/value.h
index 0889cef..1e8b670 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -479,6 +479,7 @@ extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
 extern struct value *value_from_contents_and_address (struct type *,
 						      const gdb_byte *,
 						      CORE_ADDR);
+extern struct value *value_from_contents (struct type *, const gdb_byte *);
 
 extern struct value *default_value_from_register (struct type *type,
 						  int regnum,


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-05 20:15     ` Tom Tromey
@ 2011-05-09 22:02       ` Ulrich Weigand
  2011-05-10 14:15         ` Tom Tromey
  2011-05-10 16:39         ` Tom Tromey
  0 siblings, 2 replies; 25+ messages in thread
From: Ulrich Weigand @ 2011-05-09 22:02 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey wrote:

> Ulrich> [ In fact, maybe we don't need the whole value_cast business and
> Ulrich> we could just operate on ULONGEST without involving value_binop,
> Ulrich> since both cases only support integers anyway ... ]
> 
> Tom> I agree, for DW_OP_shr.  I will do that.  Unfortunately I think
> Tom> DW_OP_mod still needs special magic.
> 
> Actually in the end I thought it was perhaps better to keep DW_OP_shr
> more or less as it was.  My reasoning is that by uniformly using the
> value API, we make it simpler to handle new cases in the future.  E.g.,
> consider if we want to support 128-bit integer types -- we could do this
> via value changes, but this would leave an odd hole in DWARF that the
> patch writer would have to discover.

OK, fine with me.  I guess I still find it a bit odd why we need those
DWARF-specific types in the first place (apparently solely for DW_OP_mod),
but if we really want to be completely compatible with the prior behaviour,
it seems we have to.  (Unless DW_OP_mod is defined to always be an unsigned
operation, just like DW_OP_shr ...)

B.t.w. your patch always performs an unsigned shift for DW_OP_shr, even
on signed operands.  However, for DW_OP_shra, your patch respects the sign
of the operands and might actually perform an unsigned shift (even though
the opcode explicitly says "arithmetic right shift" ...)  This looks like
another of those signed/unsigned inconsistencies with the proposal to me.

> Tom> Thanks very much for the review.  I'll post a new patch when I've made
> Tom> the needed changes.
> 
> Appended.

I ran a test on Cell, and interestingly it turns out that while Cell
mixed-architecture debugging appears to be OK, just plain ppc32 debugging
on a ppc64 host is now broken.  When the (32-bit) address of a stack
variable has its high bit set, dwarf2_evaluate_loc_desc_full now returns
a value with a sign-extended 64-bit CORE_ADDR address (0xffffffff....).
This address later on causes a memory_error when accessed.

Looking into that, your code does run through value_as_address, but
since the platform does not define gdbarch_integer_to_address, this
falls through to unpack_long, and since the underlying type is a
TYPE_CODE_INT and not a pointer type, this in turn now respects
the TYPE_UNSIGNED flag and does a signed conversion ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-09 22:02       ` Ulrich Weigand
@ 2011-05-10 14:15         ` Tom Tromey
  2011-05-11  0:15           ` Ulrich Weigand
  2011-05-10 16:39         ` Tom Tromey
  1 sibling, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-10 14:15 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:

Ulrich> I guess I still find it a bit odd why we need those
Ulrich> DWARF-specific types in the first place (apparently solely for
Ulrich> DW_OP_mod), but if we really want to be completely compatible
Ulrich> with the prior behaviour, it seems we have to.

Yes, the reason is DW_OP_mod.

"Old-style" DWARF values are untyped.  We normally represent them as
signed ints of the appropriate size (DWARF says unsigned, but it is
simpler to use signed and gets the same results as long as the
arithmetic respects word size).  For DW_OP_mod, we must convert the
values to unsigned -- but we must not do this for values on the stack
that have an explicit type.  So, we need a special type we can
recognize, one that cannot be the same as any base type from the CU.

I will add a comment about this to the code.

Ulrich> B.t.w. your patch always performs an unsigned shift for
Ulrich> DW_OP_shr, even on signed operands.  However, for DW_OP_shra,
Ulrich> your patch respects the sign of the operands and might actually
Ulrich> perform an unsigned shift (even though the opcode explicitly
Ulrich> says "arithmetic right shift" ...)  This looks like another of
Ulrich> those signed/unsigned inconsistencies with the proposal to me.

Yes.  My understanding is that for new-style typed values, DW_OP_shr and
DW_OP_shra are actually the same -- the type indicates the operation to
perform.  But, for old-style values, we must cast to unsigned for
DW_OP_shr.

Ulrich> Looking into that, your code does run through value_as_address, but
Ulrich> since the platform does not define gdbarch_integer_to_address, this
Ulrich> falls through to unpack_long, and since the underlying type is a
Ulrich> TYPE_CODE_INT and not a pointer type, this in turn now respects
Ulrich> the TYPE_UNSIGNED flag and does a signed conversion ...

What if we add a cast to dwarf_expr_fetch_address, like the appended?
I am not really sure whether this is ok.

I will try to find a suitable PPC machine for testing.

Tom

diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 3f6f277..bd3d4d7 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -215,6 +215,8 @@ dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n)
   struct value *result_val = dwarf_expr_fetch (ctx, n);
 
   dwarf_require_integral (value_type (result_val));
+  result_val = value_cast (builtin_type (ctx->gdbarch)->builtin_data_ptr,
+			   result_val);
   return value_as_address (result_val);
 }
 


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-09 22:02       ` Ulrich Weigand
  2011-05-10 14:15         ` Tom Tromey
@ 2011-05-10 16:39         ` Tom Tromey
  1 sibling, 0 replies; 25+ messages in thread
From: Tom Tromey @ 2011-05-10 16:39 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:

Ulrich> I ran a test on Cell, and interestingly it turns out that while
Ulrich> Cell mixed-architecture debugging appears to be OK, just plain
Ulrich> ppc32 debugging on a ppc64 host is now broken.  When the
Ulrich> (32-bit) address of a stack variable has its high bit set,
Ulrich> dwarf2_evaluate_loc_desc_full now returns a value with a
Ulrich> sign-extended 64-bit CORE_ADDR address (0xffffffff....).  This
Ulrich> address later on causes a memory_error when accessed.

Can you send me your test case?
I have a PPC64 gdb now; I built one on gcc40, on the GCC compile farm.

Tom


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-10 14:15         ` Tom Tromey
@ 2011-05-11  0:15           ` Ulrich Weigand
  2011-05-11 14:59             ` Tom Tromey
  2011-05-12 19:32             ` Tom Tromey
  0 siblings, 2 replies; 25+ messages in thread
From: Ulrich Weigand @ 2011-05-11  0:15 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey wrote:

> Ulrich> I ran a test on Cell, and interestingly it turns out that while
> Ulrich> Cell mixed-architecture debugging appears to be OK, just plain
> Ulrich> ppc32 debugging on a ppc64 host is now broken.  When the
> Ulrich> (32-bit) address of a stack variable has its high bit set,
> Ulrich> dwarf2_evaluate_loc_desc_full now returns a value with a
> Ulrich> sign-extended 64-bit CORE_ADDR address (0xffffffff....).  This
> Ulrich> address later on causes a memory_error when accessed.
> 
> Can you send me your test case?
> I have a PPC64 gdb now; I built one on gcc40, on the GCC compile farm.

The specific test case I was looking at was one of the Cell test cases
(gdb.cell/bt.exp), which failed already in a PowerPC-only part.

However, you don't really need to look specifically into Cell tests;
with your patch applied, I'm seeing a whole bunch of test suite
regressions in an -m32 test on ppc64.

Typical errors look like:

#0  0x0fd65e40 in raise () from /home/uweigand/fsf/gdb-head-build-rhel5/gdb/testsuite/gdb.base/break-interp-BINprelinkNOdebugNOpieNO.d/libc.so.6^M
#1  0x0ffd16f4 in libfunc (action=Cannot access memory at address 0xfffae1c8^M
) at ../../../gdb-head/gdb/testsuite/gdb.base/break-interp-lib.c:33^M
#2  0x100016ac in main ()^M
(gdb) FAIL: gdb.base/break-interp.exp: LDprelinkNOdebugNO: BINprelinkNOdebugNOpieNO: core: core main bt

Note the "Cannot access memory ..." because the address (internally,
not visible in the output) is sign-extended to 64-bit.

Likewise, a bunch of tests fail with

Could not insert hardware watchpoint 11.^M
Could not insert hardware breakpoints:^M
You may have requested too many hardware breakpoints/watchpoints.^M

which seems to be caused by attempting to set a hardware watchpoint
at an address that is sign-extended to 64-bit.

> Ulrich> B.t.w. your patch always performs an unsigned shift for
> Ulrich> DW_OP_shr, even on signed operands.  However, for DW_OP_shra,
> Ulrich> your patch respects the sign of the operands and might actually
> Ulrich> perform an unsigned shift (even though the opcode explicitly
> Ulrich> says "arithmetic right shift" ...)  This looks like another of
> Ulrich> those signed/unsigned inconsistencies with the proposal to me.
> 
> Yes.  My understanding is that for new-style typed values, DW_OP_shr and
> DW_OP_shra are actually the same -- the type indicates the operation to
> perform.  But, for old-style values, we must cast to unsigned for
> DW_OP_shr.

I see.  However, the code as implemented casts *all* signed values to
unsigned for DW_OP_shr, not just old-style values.  That's what got
me confused ...

> Ulrich> Looking into that, your code does run through value_as_address, but
> Ulrich> since the platform does not define gdbarch_integer_to_address, this
> Ulrich> falls through to unpack_long, and since the underlying type is a
> Ulrich> TYPE_CODE_INT and not a pointer type, this in turn now respects
> Ulrich> the TYPE_UNSIGNED flag and does a signed conversion ...
> 
> What if we add a cast to dwarf_expr_fetch_address, like the appended?
> I am not really sure whether this is ok.

Huh, interesting approach.  In a sense, that might be OK, since it mirrors
what we're doing in dwarf_expr_read_reg by calling address_from_register.
On the other hand, I'm not sure value_cast always does the right thing if
the size of a pointer type differs from the size of the DWARF address type ...

In any case, that patch does fix the regressions I'm seeing on PowerPC.


Another issue that just occurred to me: your patch creates possibly many
temporary struct value objects.  I'm wondering whether those ought to be
released from the value chain at some point ...


Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-11  0:15           ` Ulrich Weigand
@ 2011-05-11 14:59             ` Tom Tromey
  2011-05-11 19:44               ` Tom Tromey
  2011-05-12  0:03               ` Ulrich Weigand
  2011-05-12 19:32             ` Tom Tromey
  1 sibling, 2 replies; 25+ messages in thread
From: Tom Tromey @ 2011-05-11 14:59 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:

Ulrich> However, you don't really need to look specifically into Cell tests;
Ulrich> with your patch applied, I'm seeing a whole bunch of test suite
Ulrich> regressions in an -m32 test on ppc64.

Thanks, I will look into this.

Ulrich> I see.  However, the code as implemented casts *all* signed values to
Ulrich> unsigned for DW_OP_shr, not just old-style values.  That's what got
Ulrich> me confused ...

Oops, thanks for noticing that.  I fixed it locally.

Tom> What if we add a cast to dwarf_expr_fetch_address, like the appended?
Tom> I am not really sure whether this is ok.

Ulrich> Huh, interesting approach.  In a sense, that might be OK, since
Ulrich> it mirrors what we're doing in dwarf_expr_read_reg by calling
Ulrich> address_from_register.  On the other hand, I'm not sure
Ulrich> value_cast always does the right thing if the size of a pointer
Ulrich> type differs from the size of the DWARF address type ...

I had not considered that as a possibility.  I think the most obviously
safe thing to do is just revert dwarf_expr_fetch_address to (mostly)
resemble its pre-patch state.  I will do that and test it.

Ulrich> Another issue that just occurred to me: your patch creates
Ulrich> possibly many temporary struct value objects.  I'm wondering
Ulrich> whether those ought to be released from the value chain at some
Ulrich> point ...

I considered this but talked myself out of it using the following
reasoning:

1. Most DWARF expressions are simple, so in practice not many values
   will be released;
2. The unwinder code is value based but does not seem to call
   value_free_to_mark, so it must not be significant there;
3. In other (expression-evaluation) contexts, some caller is going to
   free the values anyway;
4. The watchpoint code looks at the value stack to determine what
   intermediate values to watch, and perhaps the values from the DWARF
   expression are relevant (though ... it occurs to me just now that
   this approach must be pretty broken in the presence of location
   lists).

I am actually not sure if #4 is an argument for or against.  Maybe those
intermediate values confuse things; there is a comment in
value_fetch_lazy indicating that this may be the case.

Tom


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-11 14:59             ` Tom Tromey
@ 2011-05-11 19:44               ` Tom Tromey
  2011-05-12  0:03               ` Ulrich Weigand
  1 sibling, 0 replies; 25+ messages in thread
From: Tom Tromey @ 2011-05-11 19:44 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

Tom> I had not considered that as a possibility.  I think the most obviously
Tom> safe thing to do is just revert dwarf_expr_fetch_address to (mostly)
Tom> resemble its pre-patch state.  I will do that and test it.

I regression-tested the appended on PPC64, running the test suite with
-m32.

Let me know what you think.

Tom

2011-05-05  Tom Tromey  <tromey@redhat.com>

	PR gdb/12617:
	* value.h (value_from_contents): Declare.
	* value.c (value_from_contents): New function.
	* dwarf2read.c (dwarf_stack_op_name): Add new values.
	(dwarf2_get_die_type): New function.
	* dwarf2loc.c (dwarf_expr_get_base_type): New function.
	(allocate_piece_closure): Acquire reference to values.
	(read_pieced_value): Update for value-based expressions.
	(write_pieced_value): Likewise.
	(free_pieced_value_closure): Call value_free as needed.
	(dwarf2_evaluate_loc_desc_full): Set get_base_type field.
	Update for value-based expressions.
	* dwarf2loc.h (dwarf2_get_die_type): Declare.
	* dwarf2expr.h (struct dwarf_stack_value) <value>: Change type.
	<get_base_type>: New field.
	(struct dwarf_expr_piece) <v.value>: Change type.
	<v.regno>: New field.
	(dwarf_expr_piece, dwarf_expr_fetch): Update.
	(dwarf_expr_pop, dwarf_expr_push): Remove.
	(dwarf_expr_push_address): Declare.
	* dwarf2expr.c (dwarf_arch_cookie): New global.
	(struct dwarf_gdbarch_types): New.
	(dwarf_gdbarch_types_init, dwarf_expr_address_type): New
	functions.
	(dwarf_expr_push): Change type of 'value' argument.  Update.  Now
	static.
	(dwarf_expr_push_address): New function.
	(dwarf_expr_pop): Now static.
	(dwarf_expr_fetch): Change return type.
	(dwarf_require_integral): New function.
	(dwarf_expr_fetch): Simplify.
	(add_piece): Update.
	(base_types_equal_p, dwarf_get_base_type, get_unsigned_type): New
	functions.
	(execute_stack_op) <sign_ext>: Remove.
	Use values for DWARF stack.
	<DW_OP_GNU_const_type, DW_OP_GNU_deref_type,
	DW_OP_GNU_regval_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret>:
	New cases.
	(_initialize_dwarf2expr): New function.
	(add_piece): Update.
	* dwarf2-frame.c (no_base_type): New function.
	(execute_stack_op): Set get_base_type field.  Update.

2011-05-05  Tom Tromey  <tromey@redhat.com>

	* gdb.dwarf2/typeddwarf.S: New file.
	* gdb.dwarf2/typeddwarf.c: New file.
	* gdb.dwarf2/typeddwarf.exp: New file.

diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index e78c328..4e4e6d9 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -353,6 +353,14 @@ no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 		  _("Support for DW_OP_call* is invalid in CFI"));
 }
 
+/* Helper function for execute_stack_op.  */
+
+static struct type *
+no_base_type (struct dwarf_expr_context *ctx, size_t die)
+{
+  error (_("Support for typed DWARF is not supported in CFI"));
+}
+
 /* Execute the required actions for both the DW_CFA_restore and
 DW_CFA_restore_extended instructions.  */
 static void
@@ -406,14 +414,15 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
   ctx->get_frame_pc = no_get_frame_pc;
   ctx->get_tls_address = no_get_tls_address;
   ctx->dwarf_call = no_dwarf_call;
+  ctx->get_base_type = no_base_type;
 
-  dwarf_expr_push (ctx, initial, initial_in_stack_memory);
+  dwarf_expr_push_address (ctx, initial, initial_in_stack_memory);
   dwarf_expr_eval (ctx, exp, len);
 
   if (ctx->location == DWARF_VALUE_MEMORY)
     result = dwarf_expr_fetch_address (ctx, 0);
   else if (ctx->location == DWARF_VALUE_REGISTER)
-    result = read_reg (this_frame, dwarf_expr_fetch (ctx, 0));
+    result = read_reg (this_frame, value_as_long (dwarf_expr_fetch (ctx, 0)));
   else
     {
       /* This is actually invalid DWARF, but if we ever do run across
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 91fccf9..4b7a77c 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -34,6 +34,61 @@
 static void execute_stack_op (struct dwarf_expr_context *,
 			      const gdb_byte *, const gdb_byte *);
 
+/* Cookie for gdbarch data.  */
+
+static struct gdbarch_data *dwarf_arch_cookie;
+
+/* This holds gdbarch-specific types used by the DWARF expression
+   evaluator.  See comments in execute_stack_op.  */
+
+struct dwarf_gdbarch_types
+{
+  struct type *dw_types[3];
+};
+
+/* Allocate and fill in dwarf_gdbarch_types for an arch.  */
+
+static void *
+dwarf_gdbarch_types_init (struct gdbarch *gdbarch)
+{
+  struct dwarf_gdbarch_types *types
+    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf_gdbarch_types);
+
+  /* The types themselves are lazily initialized.  */
+
+  return types;
+}
+
+/* Return the type used for DWARF operations where the type is
+   unspecified in the DWARF spec.  Only certain sizes are
+   supported.  */
+
+static struct type *
+dwarf_expr_address_type (struct dwarf_expr_context *ctx)
+{
+  struct dwarf_gdbarch_types *types = gdbarch_data (ctx->gdbarch,
+						    dwarf_arch_cookie);
+  int ndx;
+
+  if (ctx->addr_size == 2)
+    ndx = 0;
+  else if (ctx->addr_size == 4)
+    ndx = 1;
+  else if (ctx->addr_size == 8)
+    ndx = 2;
+  else
+    error (_("Unsupported address size in DWARF expressions: %d bits"),
+	   8 * ctx->addr_size);
+
+  if (types->dw_types[ndx] == NULL)
+    types->dw_types[ndx]
+      = arch_integer_type (ctx->gdbarch,
+			   8 * ctx->addr_size,
+			   0, "<signed DWARF address type>");
+
+  return types->dw_types[ndx];
+}
+
 /* Create a new context for the expression evaluator.  */
 
 struct dwarf_expr_context *
@@ -96,26 +151,32 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
 
 /* Push VALUE onto CTX's stack.  */
 
-void
-dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
+static void
+dwarf_expr_push (struct dwarf_expr_context *ctx, struct value *value,
 		 int in_stack_memory)
 {
   struct dwarf_stack_value *v;
 
-  /* We keep all stack elements within the range defined by the
-     DWARF address size.  */
-  if (ctx->addr_size < sizeof (ULONGEST))
-    value &= ((ULONGEST) 1 << (ctx->addr_size * HOST_CHAR_BIT)) - 1;
-
   dwarf_expr_grow_stack (ctx, 1);
   v = &ctx->stack[ctx->stack_len++];
   v->value = value;
   v->in_stack_memory = in_stack_memory;
 }
 
-/* Pop the top item off of CTX's stack.  */
+/* Push VALUE onto CTX's stack.  */
 
 void
+dwarf_expr_push_address (struct dwarf_expr_context *ctx, CORE_ADDR value,
+			 int in_stack_memory)
+{
+  dwarf_expr_push (ctx,
+		   value_from_ulongest (dwarf_expr_address_type (ctx), value),
+		   in_stack_memory);
+}
+
+/* Pop the top item off of CTX's stack.  */
+
+static void
 dwarf_expr_pop (struct dwarf_expr_context *ctx)
 {
   if (ctx->stack_len <= 0)
@@ -125,7 +186,7 @@ dwarf_expr_pop (struct dwarf_expr_context *ctx)
 
 /* Retrieve the N'th item on CTX's stack.  */
 
-ULONGEST
+struct value *
 dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 {
   if (ctx->stack_len <= n)
@@ -133,7 +194,39 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].value;
+}
+
+/* Require that TYPE be an integral type; throw an exception if not.  */
 
+static void
+dwarf_require_integral (struct type *type)
+{
+  if (TYPE_CODE (type) != TYPE_CODE_INT
+      && TYPE_CODE (type) != TYPE_CODE_CHAR
+      && TYPE_CODE (type) != TYPE_CODE_BOOL)
+    error (_("integral type expected in DWARF expression"));
+}
+
+/* Return the unsigned form of TYPE.  TYPE is necessarily an integral
+   type.  */
+
+static struct type *
+get_unsigned_type (struct gdbarch *gdbarch, struct type *type)
+{
+  switch (TYPE_LENGTH (type))
+    {
+    case 1:
+      return builtin_type (gdbarch)->builtin_uint8;
+    case 2:
+      return builtin_type (gdbarch)->builtin_uint16;
+    case 4:
+      return builtin_type (gdbarch)->builtin_uint32;
+    case 8:
+      return builtin_type (gdbarch)->builtin_uint64;
+    default:
+      error (_("no unsigned variant found for type, while evaluating "
+	       "DWARF expression"));
+    }
 }
 
 /* Retrieve the N'th item on CTX's stack, converted to an address.  */
@@ -141,7 +234,14 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 CORE_ADDR
 dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n)
 {
-  ULONGEST result = dwarf_expr_fetch (ctx, n);
+  struct value *result_val = dwarf_expr_fetch (ctx, n);
+  enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+  ULONGEST result;
+
+  dwarf_require_integral (value_type (result_val));
+  result = extract_unsigned_integer (value_contents (result_val),
+				     TYPE_LENGTH (value_type (result_val)),
+				     byte_order);
 
   /* For most architectures, calling extract_unsigned_integer() alone
      is sufficient for extracting an address.  However, some
@@ -151,25 +251,9 @@ dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n)
      for those architectures which require it.  */
   if (gdbarch_integer_to_address_p (ctx->gdbarch))
     {
-      enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
       gdb_byte *buf = alloca (ctx->addr_size);
-      struct type *int_type;
-
-      switch (ctx->addr_size)
-	{
-	case 2:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint16;
-	  break;
-	case 4:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint32;
-	  break;
-	case 8:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint64;
-	  break;
-	default:
-	  internal_error (__FILE__, __LINE__,
-			  _("Unsupported address size.\n"));
-	}
+      struct type *int_type = get_unsigned_type (ctx->gdbarch,
+						 value_type (result_val));
 
       store_unsigned_integer (buf, ctx->addr_size, byte_order, result);
       return gdbarch_integer_to_address (ctx->gdbarch, int_type, buf);
@@ -188,7 +272,6 @@ dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n)
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].in_stack_memory;
-
 }
 
 /* Return true if the expression stack is empty.  */
@@ -238,8 +321,10 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset)
   else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
     {
       p->v.ptr.die = ctx->len;
-      p->v.ptr.offset = (LONGEST) dwarf_expr_fetch (ctx, 0);
+      p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0));
     }
+  else if (p->location == DWARF_VALUE_REGISTER)
+    p->v.regno = value_as_long (dwarf_expr_fetch (ctx, 0));
   else
     {
       p->v.value = dwarf_expr_fetch (ctx, 0);
@@ -335,6 +420,43 @@ dwarf_expr_require_composition (const gdb_byte *op_ptr, const gdb_byte *op_end,
 	   op_name);
 }
 
+/* Return true iff the types T1 and T2 are "the same".  This only does
+   checks that might reasonably be needed to compare DWARF base
+   types.  */
+
+static int
+base_types_equal_p (struct type *t1, struct type *t2)
+{
+  if (TYPE_CODE (t1) != TYPE_CODE (t2))
+    return 0;
+  if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
+    return 0;
+  return TYPE_LENGTH (t1) == TYPE_LENGTH (t2);
+}
+
+/* A convenience function to call get_base_type on CTX and return the
+   result.  DIE is the DIE whose type we need.  SIZE is non-zero if
+   this function should verify that the resulting type has the correct
+   size.  */
+
+static struct type *
+dwarf_get_base_type (struct dwarf_expr_context *ctx, ULONGEST die, int size)
+{
+  struct type *result;
+
+  if (ctx->get_base_type)
+    {
+      result = ctx->get_base_type (ctx, die);
+      if (size != 0 && TYPE_LENGTH (result) != size)
+	error (_("DW_OP_GNU_const_type has different sizes for type and data"));
+    }
+  else
+    /* Anything will do.  */
+    result = builtin_type (ctx->gdbarch)->builtin_int;
+
+  return result;
+}
+
 /* The engine for the expression evaluator.  Using the context in CTX,
    evaluate the expression between OP_PTR and OP_END.  */
 
@@ -342,10 +464,15 @@ static void
 execute_stack_op (struct dwarf_expr_context *ctx,
 		  const gdb_byte *op_ptr, const gdb_byte *op_end)
 {
-#define sign_ext(x) ((LONGEST) (((x) ^ sign_bit) - sign_bit))
-  ULONGEST sign_bit = (ctx->addr_size >= sizeof (ULONGEST) ? 0
-		       : ((ULONGEST) 1) << (ctx->addr_size * 8 - 1));
   enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+  /* Old-style "untyped" DWARF values need special treatment in a
+     couple of places, specifically DW_OP_mod and DW_OP_shr.  We need
+     a special type for these values so we can distinguish them from
+     values that have an explicit type, because explicitly-typed
+     values do not need special treatment.  This special type must be
+     different (in the `==' sense) from any base type coming from the
+     CU.  */
+  struct type *address_type = dwarf_expr_address_type (ctx);
 
   ctx->location = DWARF_VALUE_MEMORY;
   ctx->initialized = 1;  /* Default is initialized.  */
@@ -368,6 +495,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
       int in_stack_memory = 0;
       ULONGEST uoffset, reg;
       LONGEST offset;
+      struct value *result_val = NULL;
 
       switch (op)
 	{
@@ -404,6 +532,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_lit30:
 	case DW_OP_lit31:
 	  result = op - DW_OP_lit0;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_addr:
@@ -416,47 +545,58 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
 	    result += ctx->offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_const1u:
 	  result = extract_unsigned_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const1s:
 	  result = extract_signed_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const2u:
 	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const2s:
 	  result = extract_signed_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const4u:
 	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const4s:
 	  result = extract_signed_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const8u:
 	  result = extract_unsigned_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_const8s:
 	  result = extract_signed_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_constu:
 	  op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = uoffset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 	case DW_OP_consts:
 	  op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	  result = offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	/* The DW_OP_reg operations are required to occur alone in
@@ -502,6 +642,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 		     "or DW_OP_bit_piece."));
 
 	  result = op - DW_OP_reg0;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -510,6 +651,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
 
 	  result = reg;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -547,6 +689,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    /* The byte offset into the data.  */
 	    op_ptr = read_sleb128 (op_ptr, op_end, &len);
 	    result = (ULONGEST) len;
+	    result_val = value_from_ulongest (address_type, result);
 
 	    ctx->location = DWARF_VALUE_IMPLICIT_POINTER;
 	    dwarf_expr_require_composition (op_ptr, op_end,
@@ -590,6 +733,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_bregx:
@@ -598,6 +742,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, reg);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_fbreg:
@@ -620,11 +765,14 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    if (ctx->location == DWARF_VALUE_MEMORY)
 	      result = dwarf_expr_fetch_address (ctx, 0);
 	    else if (ctx->location == DWARF_VALUE_REGISTER)
-	      result = (ctx->read_reg) (ctx->baton, dwarf_expr_fetch (ctx, 0));
+	      result
+		= (ctx->read_reg) (ctx->baton,
+				   value_as_long (dwarf_expr_fetch (ctx, 0)));
 	    else
 	      error (_("Not implemented: computing frame "
 		       "base using explicit value operator"));
 	    result = result + offset;
+	    result_val = value_from_ulongest (address_type, result);
 	    in_stack_memory = 1;
 	    ctx->stack_len = before_stack_len;
 	    ctx->location = DWARF_VALUE_MEMORY;
@@ -632,7 +780,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  break;
 
 	case DW_OP_dup:
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result_val = dwarf_expr_fetch (ctx, 0);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
 	  break;
 
@@ -642,7 +790,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_pick:
 	  offset = *op_ptr++;
-	  result = dwarf_expr_fetch (ctx, offset);
+	  result_val = dwarf_expr_fetch (ctx, offset);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset);
 	  break;
 	  
@@ -662,7 +810,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  }
 
 	case DW_OP_over:
-	  result = dwarf_expr_fetch (ctx, 1);
+	  result_val = dwarf_expr_fetch (ctx, 1);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1);
 	  break;
 
@@ -685,14 +833,27 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_deref:
 	case DW_OP_deref_size:
+	case DW_OP_GNU_deref_type:
 	  {
 	    int addr_size = (op == DW_OP_deref ? ctx->addr_size : *op_ptr++);
 	    gdb_byte *buf = alloca (addr_size);
 	    CORE_ADDR addr = dwarf_expr_fetch_address (ctx, 0);
+	    struct type *type;
+
 	    dwarf_expr_pop (ctx);
 
+	    if (op == DW_OP_GNU_deref_type)
+	      {
+		ULONGEST type_die;
+
+		op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+		type = dwarf_get_base_type (ctx, type_die, 0);
+	      }
+	    else
+	      type = address_type;
+
 	    (ctx->read_mem) (ctx->baton, buf, addr, addr_size);
-	    result = extract_unsigned_integer (buf, addr_size, byte_order);
+	    result_val = value_from_contents_and_address (type, buf, addr);
 	    break;
 	  }
 
@@ -700,27 +861,34 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_neg:
 	case DW_OP_not:
 	case DW_OP_plus_uconst:
-	  /* Unary operations.  */
-	  result = dwarf_expr_fetch (ctx, 0);
-	  dwarf_expr_pop (ctx);
+	  {
+	    /* Unary operations.  */
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
 
-	  switch (op)
-	    {
-	    case DW_OP_abs:
-	      if (sign_ext (result) < 0)
-		result = -result;
-	      break;
-	    case DW_OP_neg:
-	      result = -result;
-	      break;
-	    case DW_OP_not:
-	      result = ~result;
-	      break;
-	    case DW_OP_plus_uconst:
-	      op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-	      result += reg;
-	      break;
-	    }
+	    switch (op)
+	      {
+	      case DW_OP_abs:
+		if (value_less (result_val,
+				value_zero (value_type (result_val), not_lval)))
+		  result_val = value_neg (result_val);
+		break;
+	      case DW_OP_neg:
+		result_val = value_neg (result_val);
+		break;
+	      case DW_OP_not:
+		dwarf_require_integral (value_type (result_val));
+		result_val = value_complement (result_val);
+		break;
+	      case DW_OP_plus_uconst:
+		dwarf_require_integral (value_type (result_val));
+		result = value_as_long (result_val);
+		op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+		result += reg;
+		result_val = value_from_ulongest (address_type, result);
+		break;
+	      }
+	  }
 	  break;
 
 	case DW_OP_and:
@@ -742,7 +910,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_ne:
 	  {
 	    /* Binary operations.  */
-	    ULONGEST first, second;
+	    struct value *first, *second;
 
 	    second = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
@@ -750,62 +918,115 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	    first = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
 
+	    if (! base_types_equal_p (value_type (first), value_type (second)))
+	      error (_("Incompatible types on DWARF stack"));
+
 	    switch (op)
 	      {
 	      case DW_OP_and:
-		result = first & second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_AND);
 		break;
 	      case DW_OP_div:
-		if (!second)
-		  error (_("Division by zero"));
-		result = sign_ext (first) / sign_ext (second);
+		result_val = value_binop (first, second, BINOP_DIV);
                 break;
 	      case DW_OP_minus:
-		result = first - second;
+		result_val = value_binop (first, second, BINOP_SUB);
 		break;
 	      case DW_OP_mod:
-		if (!second)
-		  error (_("Division by zero"));
-		result = first % second;
+		{
+		  int cast_back = 0;
+		  struct type *orig_type = value_type (first);
+
+		  /* We have to special-case "old-style" untyped values
+		     -- these must have mod computed using unsigned
+		     math.  */
+		  if (orig_type == address_type)
+		    {
+		      struct type *utype
+			= get_unsigned_type (ctx->gdbarch, orig_type);
+
+		      cast_back = 1;
+		      first = value_cast (utype, first);
+		      second = value_cast (utype, second);
+		    }
+		  /* Note that value_binop doesn't handle float or
+		     decimal float here.  This seems unimportant.  */
+		  result_val = value_binop (first, second, BINOP_MOD);
+		  if (cast_back)
+		    result_val = value_cast (orig_type, result_val);
+		}
 		break;
 	      case DW_OP_mul:
-		result = first * second;
+		result_val = value_binop (first, second, BINOP_MUL);
 		break;
 	      case DW_OP_or:
-		result = first | second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_IOR);
 		break;
 	      case DW_OP_plus:
-		result = first + second;
+		result_val = value_binop (first, second, BINOP_ADD);
 		break;
 	      case DW_OP_shl:
-		result = first << second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_LSH);
 		break;
 	      case DW_OP_shr:
-		result = first >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		if (value_type (first) == address_type)
+		  {
+		    struct type *utype
+		      = get_unsigned_type (ctx->gdbarch, value_type (first));
+
+		    first = value_cast (utype, first);
+		  }
+
+		result_val = value_binop (first, second, BINOP_RSH);
+		/* Make sure we wind up with the same type we started
+		   with.  */
+		if (value_type (result_val) != value_type (second))
+		  result_val = value_cast (value_type (second), result_val);
                 break;
 	      case DW_OP_shra:
-		result = sign_ext (first) >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_RSH);
 		break;
 	      case DW_OP_xor:
-		result = first ^ second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_XOR);
 		break;
 	      case DW_OP_le:
-		result = sign_ext (first) <= sign_ext (second);
+		/* A <= B is !(B < A).  */
+		result = ! value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ge:
-		result = sign_ext (first) >= sign_ext (second);
+		/* A >= B is !(A < B).  */
+		result = ! value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_eq:
-		result = sign_ext (first) == sign_ext (second);
+		result = value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_lt:
-		result = sign_ext (first) < sign_ext (second);
+		result = value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_gt:
-		result = sign_ext (first) > sign_ext (second);
+		/* A > B is B < A.  */
+		result = value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ne:
-		result = sign_ext (first) != sign_ext (second);
+		result = ! value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      default:
 		internal_error (__FILE__, __LINE__,
@@ -816,6 +1037,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_call_frame_cfa:
 	  result = (ctx->get_frame_cfa) (ctx->baton);
+	  result_val = value_from_ulongest (address_type, result);
 	  in_stack_memory = 1;
 	  break;
 
@@ -828,9 +1050,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  control block at which the variable is located.  Nothing
 	  should follow this operator, so the top of stack would be
 	  returned.  */
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result = value_as_long (dwarf_expr_fetch (ctx, 0));
 	  dwarf_expr_pop (ctx);
 	  result = (ctx->get_tls_address) (ctx->baton, result);
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_skip:
@@ -840,11 +1063,17 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  goto no_push;
 
 	case DW_OP_bra:
-	  offset = extract_signed_integer (op_ptr, 2, byte_order);
-	  op_ptr += 2;
-	  if (dwarf_expr_fetch (ctx, 0) != 0)
-	    op_ptr += offset;
-	  dwarf_expr_pop (ctx);
+	  {
+	    struct value *val;
+
+	    offset = extract_signed_integer (op_ptr, 2, byte_order);
+	    op_ptr += 2;
+	    val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_require_integral (value_type (val));
+	    if (value_as_long (val) != 0)
+	      op_ptr += offset;
+	    dwarf_expr_pop (ctx);
+	  }
 	  goto no_push;
 
 	case DW_OP_nop:
@@ -912,12 +1141,73 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  ctx->num_pieces = 0;
 	  goto abort_expression;
 
+	case DW_OP_GNU_const_type:
+	  {
+	    ULONGEST type_die;
+	    int n;
+	    const gdb_byte *data;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    n = *op_ptr++;
+	    data = op_ptr;
+	    op_ptr += n;
+
+	    type = dwarf_get_base_type (ctx, type_die, n);
+	    result_val = value_from_contents (type, data);
+	  }
+	  break;
+
+	case DW_OP_GNU_regval_type:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+	    result = (ctx->read_reg) (ctx->baton, reg);
+	    result_val = value_from_ulongest (type, result);
+	  }
+	  break;
+
+	case DW_OP_GNU_convert:
+	case DW_OP_GNU_reinterpret:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
+
+	    if (op == DW_OP_GNU_convert)
+	      result_val = value_cast (type, result_val);
+	    else if (type == value_type (result_val))
+	      {
+		/* Nothing.  */
+	      }
+	    else if (TYPE_LENGTH (type)
+		     != TYPE_LENGTH (value_type (result_val)))
+	      error (_("DW_OP_GNU_reinterpret has wrong size"));
+	    else
+	      result_val
+		= value_from_contents (type,
+				       value_contents_all (result_val));
+	  }
+	  break;
+
 	default:
 	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
 	}
 
       /* Most things push a result value.  */
-      dwarf_expr_push (ctx, result, in_stack_memory);
+      gdb_assert (result_val != NULL);
+      dwarf_expr_push (ctx, result_val, in_stack_memory);
     no_push:
       ;
     }
@@ -931,5 +1221,11 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 abort_expression:
   ctx->recursion_depth--;
   gdb_assert (ctx->recursion_depth >= 0);
-#undef sign_ext
+}
+
+void
+_initialize_dwarf2expr (void)
+{
+  dwarf_arch_cookie
+    = gdbarch_data_register_post_init (dwarf_gdbarch_types_init);
 }
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index 78ff53f..676b54b 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -51,7 +51,7 @@ enum dwarf_value_location
 
 struct dwarf_stack_value
 {
-  ULONGEST value;
+  struct value *value;
 
   /* Non-zero if the piece is in memory and is known to be
      on the program's stack.  It is always ok to set this to zero.
@@ -111,6 +111,13 @@ struct dwarf_expr_context
      being passed to and returned from the called DWARF subroutine.  */
   void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset);
 
+  /* Return the base type given by the indicated DIE.  This can throw
+     an exception if the DIE is invalid or does not represent a base
+     type.  If can also be NULL in the special case where the
+     callbacks are not performing evaluation, and thus it is
+     meaningful to substitute a stub type of the correct size.  */
+  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, size_t die);
+
 #if 0
   /* Not yet implemented.  */
 
@@ -180,9 +187,11 @@ struct dwarf_expr_piece
       int in_stack_memory;
     } mem;
 
-    /* The piece's register number or literal value, for
-       DWARF_VALUE_REGISTER or DWARF_VALUE_STACK pieces.  */
-    ULONGEST value;
+    /* The piece's register number, for DWARF_VALUE_REGISTER pieces.  */
+    int regno;
+
+    /* The piece's literal value, for DWARF_VALUE_STACK pieces.  */
+    struct value *value;
 
     struct
     {
@@ -214,12 +223,12 @@ void free_dwarf_expr_context (struct dwarf_expr_context *ctx);
 struct cleanup *
     make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx);
 
-void dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
-		      int in_stack_memory);
-void dwarf_expr_pop (struct dwarf_expr_context *ctx);
+void dwarf_expr_push_address (struct dwarf_expr_context *ctx,
+			      CORE_ADDR value,
+			      int in_stack_memory);
 void dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr,
 		      size_t len);
-ULONGEST dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
+struct value *dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
 CORE_ADDR dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n);
 int dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n);
 
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 4c13307..01532d9 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -286,6 +286,16 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 		     ctx->get_frame_pc, ctx->baton);
 }
 
+/* Callback function for dwarf2_evaluate_loc_desc.  */
+
+static struct type *
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+  struct dwarf_expr_baton *debaton = ctx->baton;
+
+  return dwarf2_get_die_type (die_offset, debaton->per_cu);
+}
+
 struct piece_closure
 {
   /* Reference count.  */
@@ -313,6 +323,7 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
 			int addr_size)
 {
   struct piece_closure *c = XZALLOC (struct piece_closure);
+  int i;
 
   c->refc = 1;
   c->per_cu = per_cu;
@@ -321,6 +332,9 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
   c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
 
   memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
+  for (i = 0; i < n_pieces; ++i)
+    if (c->pieces[i].location == DWARF_VALUE_STACK)
+      value_incref (c->pieces[i].v.value);
 
   return c;
 }
@@ -576,7 +590,7 @@ read_pieced_value (struct value *v)
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = source_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -609,7 +623,7 @@ read_pieced_value (struct value *v)
 	    else
 	      {
 		error (_("Unable to access DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, value_as_long (p->v.value)));
 	      }
 	  }
 	  break;
@@ -623,7 +637,6 @@ read_pieced_value (struct value *v)
 
 	case DWARF_VALUE_STACK:
 	  {
-	    struct gdbarch *gdbarch = get_type_arch (value_type (v));
 	    size_t n = this_size;
 
 	    if (n > c->addr_size - source_offset)
@@ -634,18 +647,11 @@ read_pieced_value (struct value *v)
 	      {
 		/* Nothing.  */
 	      }
-	    else if (source_offset == 0)
-	      store_unsigned_integer (buffer, n,
-				      gdbarch_byte_order (gdbarch),
-				      p->v.value);
 	    else
 	      {
-		gdb_byte bytes[sizeof (ULONGEST)];
+		const gdb_byte *val_bytes = value_contents_all (p->v.value);
 
-		store_unsigned_integer (bytes, n + source_offset,
-					gdbarch_byte_order (gdbarch),
-					p->v.value);
-		memcpy (buffer, bytes + source_offset, n);
+		intermediate_buffer = val_bytes + source_offset;
 	      }
 	  }
 	  break;
@@ -776,7 +782,7 @@ write_pieced_value (struct value *to, struct value *from)
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = dest_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -816,7 +822,7 @@ write_pieced_value (struct value *to, struct value *from)
 	    else
 	      {
 		error (_("Unable to write to DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, value_as_long (p->v.value)));
 	      }
 	  }
 	  break;
@@ -1033,6 +1039,12 @@ free_pieced_value_closure (struct value *v)
   --c->refc;
   if (c->refc == 0)
     {
+      int i;
+
+      for (i = 0; i < c->n_pieces; ++i)
+	if (c->pieces[i].location == DWARF_VALUE_STACK)
+	  value_free (c->pieces[i].v.value);
+
       xfree (c->pieces);
       xfree (c);
     }
@@ -1106,6 +1118,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   ctx->get_frame_pc = dwarf_expr_frame_pc;
   ctx->get_tls_address = dwarf_expr_tls_address;
   ctx->dwarf_call = dwarf_expr_dwarf_call;
+  ctx->get_base_type = dwarf_expr_get_base_type;
 
   TRY_CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -1148,7 +1161,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0);
+	    ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
 	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
 
 	    if (byte_offset != 0)
@@ -1176,26 +1189,23 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
 	case DWARF_VALUE_STACK:
 	  {
-	    ULONGEST value = dwarf_expr_fetch (ctx, 0);
-	    bfd_byte *contents, *tem;
-	    size_t n = ctx->addr_size;
+	    struct value *value = dwarf_expr_fetch (ctx, 0);
+	    gdb_byte *contents;
+	    const gdb_byte *val_bytes;
+	    size_t n = TYPE_LENGTH (value_type (value));
 
 	    if (byte_offset + TYPE_LENGTH (type) > n)
 	      invalid_synthetic_pointer ();
 
-	    tem = alloca (n);
-	    store_unsigned_integer (tem, n,
-				    gdbarch_byte_order (ctx->gdbarch),
-				    value);
-
-	    tem += byte_offset;
+	    val_bytes = value_contents_all (value);
+	    val_bytes += byte_offset;
 	    n -= byte_offset;
 
 	    retval = allocate_value (type);
 	    contents = value_contents_raw (retval);
 	    if (n > TYPE_LENGTH (type))
 	      n = TYPE_LENGTH (type);
-	    memcpy (contents, tem, n);
+	    memcpy (contents, val_bytes, n);
 	  }
 	  break;
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 96a490e..08849ed 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -59,6 +59,9 @@ struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
+struct type *dwarf2_get_die_type (unsigned int die_offset,
+				  struct dwarf2_per_cu_data *per_cu);
+
 /* Evaluate a location description, starting at DATA and with length
    SIZE, to find the current location of variable of TYPE in the context
    of FRAME.  */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 81b20c7..507f525 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13092,6 +13092,18 @@ dwarf_stack_op_name (unsigned op)
       return "DW_OP_GNU_uninit";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
+    case DW_OP_GNU_entry_value:
+      return "DW_OP_GNU_entry_value";
+    case DW_OP_GNU_const_type:
+      return "DW_OP_GNU_const_type";
+    case DW_OP_GNU_regval_type:
+      return "DW_OP_GNU_regval_type";
+    case DW_OP_GNU_deref_type:
+      return "DW_OP_GNU_deref_type";
+    case DW_OP_GNU_convert:
+      return "DW_OP_GNU_convert";
+    case DW_OP_GNU_reinterpret:
+      return "DW_OP_GNU_reinterpret";
     default:
       return NULL;
     }
@@ -13650,6 +13662,31 @@ dwarf2_fetch_die_location_block (unsigned int offset,
   return retval;
 }
 
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+   PER_CU.  */
+
+struct type *
+dwarf2_get_die_type (unsigned int die_offset,
+		     struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf2_cu *cu = per_cu->cu;
+  struct die_info *die;
+  struct type *result;
+
+  dw2_setup (per_cu->objfile);
+
+  die = follow_die_offset (die_offset, &cu);
+  if (!die)
+    error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
+	   die_offset, per_cu->cu->objfile->name);
+
+  result = get_die_type (die, cu);
+  if (result == NULL)
+    result = read_type_die_1 (die, cu);
+
+  return result;
+}
+
 /* Follow the signature attribute ATTR in SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
    On exit *REF_CU is the CU of the result.  */
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.S b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
new file mode 100644
index 0000000..a46da14
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
@@ -0,0 +1,2225 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This source file was generated from typeddwarf.c using the following
+   command line:
+
+   gcc -m32 -dA -S -g -O2 typeddwarf.c -o typeddwarf.S
+
+*/
+
+
+	.file	"typeddwarf.c"
+	.text
+.Ltext0:
+	.p2align 4,,15
+	.globl	f1
+	.type	f1, @function
+f1:
+.LFB0:
+	# typeddwarf.c:10
+.LM1:
+.LVL0:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:29
+.LM2:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:30
+.LM3:
+	ret
+.LFE0:
+	.size	f1, .-f1
+	.p2align 4,,15
+	.globl	f2
+	.type	f2, @function
+f2:
+.LFB1:
+	# typeddwarf.c:34
+.LM4:
+.LVL1:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	subl	$12, %esp
+.LCFI0:
+	# typeddwarf.c:53
+.LM5:
+	movl	vv, %eax
+	# typeddwarf.c:54
+.LM6:
+	fnstcw	6(%esp)
+	# typeddwarf.c:34
+.LM7:
+	flds	40(%esp)
+.LVL2:
+	# typeddwarf.c:54
+.LM8:
+	fldl	16(%esp)
+	# typeddwarf.c:53
+.LM9:
+	addl	$1, %eax
+	movl	%eax, vv
+	# typeddwarf.c:54
+.LM10:
+	movzwl	6(%esp), %eax
+	movb	$12, %ah
+	movw	%ax, 4(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	# typeddwarf.c:55
+.LM11:
+	fldl	24(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:54
+.LM12:
+	movl	%eax, vv
+	# typeddwarf.c:55
+.LM13:
+	movl	(%esp), %eax
+	# typeddwarf.c:56
+.LM14:
+	fldl	32(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:55
+.LM15:
+	movl	%eax, vv
+	# typeddwarf.c:56
+.LM16:
+	movl	(%esp), %eax
+	# typeddwarf.c:57
+.LM17:
+	fldcw	4(%esp)
+	fistl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:56
+.LM18:
+	movl	%eax, vv
+	# typeddwarf.c:57
+.LM19:
+	movl	(%esp), %eax
+	# typeddwarf.c:58
+.LM20:
+	flds	44(%esp)
+	# typeddwarf.c:57
+.LM21:
+	movl	%eax, vv
+	# typeddwarf.c:58
+.LM22:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:59
+.LM23:
+	movl	48(%esp), %eax
+	# typeddwarf.c:63
+.LM24:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:59
+.LM25:
+	movl	%eax, vv
+	# typeddwarf.c:60
+.LM26:
+	movl	52(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:61
+.LM27:
+	movl	56(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:62
+.LM28:
+	movl	64(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:63
+.LM29:
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:64
+.LM30:
+	addl	$12, %esp
+.LCFI1:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE1:
+	.size	f2, .-f2
+	.p2align 4,,15
+	.globl	f3
+	.type	f3, @function
+f3:
+.LFB2:
+	# typeddwarf.c:68
+.LM31:
+.LVL3:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:73
+.LM32:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:74
+.LM33:
+	ret
+.LFE2:
+	.size	f3, .-f3
+	.p2align 4,,15
+	.globl	f4
+	.type	f4, @function
+f4:
+.LFB3:
+	# typeddwarf.c:78
+.LM34:
+.LVL4:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:82
+.LM35:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:83
+.LM36:
+	ret
+.LFE3:
+	.size	f4, .-f4
+	.section	.text.startup,"ax",@progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, @function
+main:
+.LFB4:
+	# typeddwarf.c:87
+.LM37:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	pushl	%esi
+.LCFI4:
+	# typeddwarf.c:88
+.LM38:
+	movl	$0x40a00000, %esi
+	# typeddwarf.c:87
+.LM39:
+	pushl	%ebx
+.LCFI5:
+	# typeddwarf.c:88
+.LM40:
+	movl	$0x40800000, %ebx
+	# typeddwarf.c:87
+.LM41:
+	andl	$-16, %esp
+	subl	$112, %esp
+.LCFI6:
+	# typeddwarf.c:88
+.LM42:
+	flds	.LC3
+	fstl	16(%esp)
+	movl	%esi, 28(%esp)
+	flds	.LC4
+	fstl	8(%esp)
+	movl	%ebx, 24(%esp)
+	fld1
+	fstl	(%esp)
+	movl	$9, 48(%esp)
+	fstps	64(%esp)
+	fstps	80(%esp)
+	movl	$0, 52(%esp)
+	fstps	96(%esp)
+	movl	$8, 40(%esp)
+	movl	$0, 44(%esp)
+	movl	$7, 36(%esp)
+	movl	$6, 32(%esp)
+	call	f1
+.LVL5:
+	# typeddwarf.c:89
+.LM43:
+	movl	%esi, 28(%esp)
+	movl	%ebx, 24(%esp)
+	movl	$9, 48(%esp)
+	movl	$0, 52(%esp)
+	movl	$8, 40(%esp)
+	flds	96(%esp)
+	fstpl	16(%esp)
+	movl	$0, 44(%esp)
+	flds	80(%esp)
+	fstpl	8(%esp)
+	movl	$7, 36(%esp)
+	flds	64(%esp)
+	fstpl	(%esp)
+	movl	$6, 32(%esp)
+	call	f2
+.LVL6:
+	# typeddwarf.c:90
+.LM44:
+	movl	$4, 20(%esp)
+	movl	$3, 12(%esp)
+	movl	$0, 16(%esp)
+	movl	$2, 8(%esp)
+	movl	$1, (%esp)
+	movl	$0, 4(%esp)
+	call	f3
+.LVL7:
+	# typeddwarf.c:91
+.LM45:
+	movl	$640, 16(%esp)
+	movl	$0, 20(%esp)
+	movl	$0, 24(%esp)
+	movl	$809369600, 28(%esp)
+	movl	$160, 4(%esp)
+	movl	$832569344, 8(%esp)
+	movl	$838860880, (%esp)
+	call	f4
+.LVL8:
+	# typeddwarf.c:93
+.LM46:
+	leal	-8(%ebp), %esp
+	xorl	%eax, %eax
+	popl	%ebx
+.LCFI7:
+	popl	%esi
+.LCFI8:
+	popl	%ebp
+.LCFI9:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE4:
+	.size	main, .-main
+	.comm	vv,4,4
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align 4
+.LC3:
+	.long	1077936128
+	.align 4
+.LC4:
+	.long	1073741824
+#APP
+	.section	.debug_frame,"",@progbits
+.Lframe0:
+	.long	.LECIE0-.LSCIE0	# Length of Common Information Entry
+.LSCIE0:
+	.long	0xffffffff	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE0:
+.LSFDE0:
+	.long	.LEFDE0-.LASFDE0	# FDE Length
+.LASFDE0:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE0:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE2:
+.LSFDE4:
+	.long	.LEFDE4-.LASFDE4	# FDE Length
+.LASFDE4:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE4:
+.LSFDE6:
+	.long	.LEFDE6-.LASFDE6	# FDE Length
+.LASFDE6:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE6:
+.LSFDE8:
+	.long	.LEFDE8-.LASFDE8	# FDE Length
+.LASFDE8:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE8:
+#NO_APP
+#APP
+	.section	.eh_frame,"aw",@progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.long	0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE1:
+.LSFDE11:
+	.long	.LEFDE11-.LASFDE11	# FDE Length
+.LASFDE11:
+	.long	.LASFDE11-.Lframe1	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE11:
+.LSFDE13:
+	.long	.LEFDE13-.LASFDE13	# FDE Length
+.LASFDE13:
+	.long	.LASFDE13-.Lframe1	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE13:
+.LSFDE15:
+	.long	.LEFDE15-.LASFDE15	# FDE Length
+.LASFDE15:
+	.long	.LASFDE15-.Lframe1	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE15:
+.LSFDE17:
+	.long	.LEFDE17-.LASFDE17	# FDE Length
+.LASFDE17:
+	.long	.LASFDE17-.Lframe1	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE17:
+.LSFDE19:
+	.long	.LEFDE19-.LASFDE19	# FDE Length
+.LASFDE19:
+	.long	.LASFDE19-.Lframe1	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE19:
+#NO_APP
+	.text
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x64e	# Length of Compilation Unit Info
+	.value	0x2	# DWARF version number
+	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+	.byte	0x4	# Pointer Size (in bytes)
+	.uleb128 0x1	# (DIE (0xb) DW_TAG_compile_unit)
+	.long	.LASF5	# DW_AT_producer: "GNU C 4.7.0 20110504 (experimental)"
+	.byte	0x1	# DW_AT_language
+	.long	.LASF6	# DW_AT_name: "typeddwarf.c"
+	.long	.LASF7	# DW_AT_comp_dir: "/usr/src/gcc/obj/gcc"
+	.long	.Ldebug_ranges0+0	# DW_AT_ranges
+	.long	0	# DW_AT_low_pc
+	.long	0	# DW_AT_entry_pc
+	.long	.Ldebug_line0	# DW_AT_stmt_list
+	.uleb128 0x2	# (DIE (0x29) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF0	# DW_AT_name: "double"
+	.uleb128 0x2	# (DIE (0x30) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF1	# DW_AT_name: "float"
+	.uleb128 0x2	# (DIE (0x37) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.long	.LASF2	# DW_AT_name: "long long int"
+	.uleb128 0x3	# (DIE (0x3e) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.ascii "int\0"	# DW_AT_name
+	.uleb128 0x2	# (DIE (0x45) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF3	# DW_AT_name: "unsigned int"
+	.uleb128 0x2	# (DIE (0x4c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF4	# DW_AT_name: "long long unsigned int"
+	.uleb128 0x4	# (DIE (0x53) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f1\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB0	# DW_AT_low_pc
+	.long	.LFE0	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x232	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x6b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x77) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x83) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x8f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x9b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0xa7) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0xb3) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0xbf) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0xcb) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0xd7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xb	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xe9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xc	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xfd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xe	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x6	# (DIE (0x109) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x10	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x11d) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x11	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x12f) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x12	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x141) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x13	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x153) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x14	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x167) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x15	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x179) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x16	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x18d) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x17	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x19f) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x18	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1b1) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x19	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1cf) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1a	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1f1) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x213) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1c	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x53
+	.uleb128 0x7	# (DIE (0x232) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f2\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB1	# DW_AT_low_pc
+	.long	.LFE1	# DW_AT_high_pc
+	.long	.LLST0	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x40a	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x24b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x257) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x263) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x26f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x27b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0x287) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0x293) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0x29f) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0x2ab) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0x2b7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x23	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2c9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x24	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2dd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x26	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x2e9) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x28	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x2f2) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x29	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.uleb128 0x6	# (DIE (0x2fb) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2a	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x30d) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x31f) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2c	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x333) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2d	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x345) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2e	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x359) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2f	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x36b) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x30	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x37d) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x31	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x39b) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x32	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x24	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.byte	0x1c	# DW_OP_minus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0x78b58c40	# fp or vector constant word 0
+	.long	0x4415af1d	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3c9) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x33	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x401c0000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3eb) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x34	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x232
+	.uleb128 0x4	# (DIE (0x40a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f3\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB2	# DW_AT_low_pc
+	.long	.LFE2	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x4fd	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x422) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x42e) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x43a) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.uleb128 0x5	# (DIE (0x446) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.uleb128 0x6	# (DIE (0x452) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x45	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x16	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x12	# DW_OP_dup
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x16	# DW_OP_swap
+	.byte	0x14	# DW_OP_over
+	.byte	0x2b	# DW_OP_gt
+	.byte	0x28	# DW_OP_bra
+	.value	0x1
+	.byte	0x16	# DW_OP_swap
+	.byte	0x13	# DW_OP_drop
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x472) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x46	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x496) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x47	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x4ba) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x48	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x38	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x40a
+	.uleb128 0x4	# (DIE (0x4fd) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f4\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB3	# DW_AT_low_pc
+	.long	.LFE3	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x555	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x515) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x521) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 4
+	.uleb128 0x5	# (DIE (0x52d) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x539) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4f	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x542) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x50	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x54b) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x51	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0	# end of children of DIE 0x4fd
+	.uleb128 0x2	# (DIE (0x555) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF8	# DW_AT_name: "_Decimal32"
+	.uleb128 0x2	# (DIE (0x55c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF9	# DW_AT_name: "_Decimal64"
+	.uleb128 0x2	# (DIE (0x563) DW_TAG_base_type)
+	.byte	0x10	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF10	# DW_AT_name: "_Decimal128"
+	.uleb128 0x9	# (DIE (0x56a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.long	.LASF11	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x56	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.long	.LFB4	# DW_AT_low_pc
+	.long	.LFE4	# DW_AT_high_pc
+	.long	.LLST1	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x62f	# DW_AT_sibling
+	.uleb128 0xa	# (DIE (0x587) DW_TAG_GNU_call_site)
+	.long	.LVL5	# DW_AT_low_pc
+	.long	0x53	# DW_AT_abstract_origin
+	.long	0x5e1	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x594) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 0
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5a4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5b4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5c4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5cc) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5d4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x5da) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x587
+	.uleb128 0xa	# (DIE (0x5e1) DW_TAG_GNU_call_site)
+	.long	.LVL6	# DW_AT_low_pc
+	.long	0x232	# DW_AT_abstract_origin
+	.long	0x60b	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x5ee) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5f6) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5fe) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x604) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x5e1
+	.uleb128 0xa	# (DIE (0x60b) DW_TAG_GNU_call_site)
+	.long	.LVL7	# DW_AT_low_pc
+	.long	0x40a	# DW_AT_abstract_origin
+	.long	0x625	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x618) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x32	# DW_OP_lit2
+	.uleb128 0xb	# (DIE (0x61e) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 20
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x34	# DW_OP_lit4
+	.byte	0	# end of children of DIE 0x60b
+	.uleb128 0xc	# (DIE (0x625) DW_TAG_GNU_call_site)
+	.long	.LVL8	# DW_AT_low_pc
+	.long	0x4fd	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x56a
+	.uleb128 0xd	# (DIE (0x62f) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x1	# DW_AT_declaration
+	.uleb128 0xe	# (DIE (0x63b) DW_TAG_volatile_type)
+	.long	0x3e	# DW_AT_type
+	.uleb128 0xf	# (DIE (0x640) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x5	# DW_AT_location
+	.byte	0x3	# DW_OP_addr
+	.long	vv
+	.byte	0	# end of children of DIE 0xb
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1	# (abbrev code)
+	.uleb128 0x11	# (TAG: DW_TAG_compile_unit)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x25	# (DW_AT_producer)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x13	# (DW_AT_language)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x1b	# (DW_AT_comp_dir)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x55	# (DW_AT_ranges)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x52	# (DW_AT_entry_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x10	# (DW_AT_stmt_list)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.byte	0
+	.byte	0
+	.uleb128 0x2	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.byte	0
+	.byte	0
+	.uleb128 0x3	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.byte	0
+	.byte	0
+	.uleb128 0x4	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x5	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x6	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x7	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x8	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x9	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xa	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xb	# (abbrev code)
+	.uleb128 0x410a	# (TAG: DW_TAG_GNU_call_site_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2111	# (DW_AT_GNU_call_site_value)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0xc	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xd	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3c	# (DW_AT_declaration)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.byte	0
+	.byte	0
+	.uleb128 0xe	# (abbrev code)
+	.uleb128 0x35	# (TAG: DW_TAG_volatile_type)
+	.byte	0	# DW_children_no
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xf	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.long	.LFB1	# Location list begin address (*.LLST0)
+	.long	.LCFI0	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI0	# Location list begin address (*.LLST0)
+	.long	.LCFI1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.long	.LCFI1	# Location list begin address (*.LLST0)
+	.long	.LFE1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST0)
+	.long	0	# Location list terminator end (*.LLST0)
+.LLST1:
+	.long	.LFB4	# Location list begin address (*.LLST1)
+	.long	.LCFI2	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI2	# Location list begin address (*.LLST1)
+	.long	.LCFI3	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.long	.LCFI3	# Location list begin address (*.LLST1)
+	.long	.LCFI9	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x75	# DW_OP_breg5
+	.sleb128 8
+	.long	.LCFI9	# Location list begin address (*.LLST1)
+	.long	.LFE4	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST1)
+	.long	0	# Location list terminator end (*.LLST1)
+	.section	.debug_aranges,"",@progbits
+	.long	0x24	# Length of Address Ranges Info
+	.value	0x2	# DWARF Version
+	.long	.Ldebug_info0	# Offset of Compilation Unit Info
+	.byte	0x4	# Size of Address
+	.byte	0	# Size of Segment Descriptor
+	.value	0	# Pad to 8 byte boundary
+	.value	0
+	.long	.Ltext0	# Address
+	.long	.Letext0-.Ltext0	# Length
+	.long	.LFB4	# Address
+	.long	.LFE4-.LFB4	# Length
+	.long	0
+	.long	0
+	.section	.debug_ranges,"",@progbits
+.Ldebug_ranges0:
+	.long	.Ltext0	# Offset 0
+	.long	.Letext0
+	.long	.LFB4	# Offset 0x8
+	.long	.LFE4
+	.long	0
+	.long	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.long	.LELT0-.LSLT0	# Length of Source Line Info
+.LSLT0:
+	.value	0x2	# DWARF Version
+	.long	.LELTP0-.LASLTP0	# Prolog Length
+.LASLTP0:
+	.byte	0x1	# Minimum Instruction Length
+	.byte	0x1	# Default is_stmt_start flag
+	.byte	0xf6	# Line Base Value (Special Opcodes)
+	.byte	0xf2	# Line Range Value (Special Opcodes)
+	.byte	0xd	# Special Opcode Base
+	.byte	0	# opcode: 0x1 has 0 args
+	.byte	0x1	# opcode: 0x2 has 1 args
+	.byte	0x1	# opcode: 0x3 has 1 args
+	.byte	0x1	# opcode: 0x4 has 1 args
+	.byte	0x1	# opcode: 0x5 has 1 args
+	.byte	0	# opcode: 0x6 has 0 args
+	.byte	0	# opcode: 0x7 has 0 args
+	.byte	0	# opcode: 0x8 has 0 args
+	.byte	0x1	# opcode: 0x9 has 1 args
+	.byte	0	# opcode: 0xa has 0 args
+	.byte	0	# opcode: 0xb has 0 args
+	.byte	0x1	# opcode: 0xc has 1 args
+	.byte	0	# End directory table
+	.ascii "typeddwarf.c\0"	# File Entry: 0x1
+	.uleb128 0
+	.uleb128 0
+	.uleb128 0
+	.byte	0	# End file name table
+.LELTP0:
+	.byte	0	# set address *.LM37
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM37
+	.byte	0x6d	# line 87
+	.byte	0	# set address *.LM38
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM38
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM39
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM39
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM40
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM40
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM41
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM41
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM42
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM42
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM43
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM43
+	.byte	0x18	# line 89
+	.byte	0	# set address *.LM44
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM44
+	.byte	0x18	# line 90
+	.byte	0	# set address *.LM45
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM45
+	.byte	0x18	# line 91
+	.byte	0	# set address *.LM46
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM46
+	.byte	0x19	# line 93
+	.byte	0	# set address *.LFE4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LFE4
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+	.byte	0	# set address *.LM1
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM1
+	.byte	0x20	# line 10
+	.byte	0	# set address *.LM2
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM2
+	.byte	0x2a	# line 29
+	.byte	0	# set address *.LM3
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM3
+	.byte	0x18	# line 30
+	.byte	0	# set address *.LM4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM4
+	.byte	0x1b	# line 34
+	.byte	0	# set address *.LM5
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM5
+	.byte	0x2a	# line 53
+	.byte	0	# set address *.LM6
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM6
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM7
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM7
+	.byte	0x3	# advance to line 34
+	.sleb128 -20
+	.byte	0x1
+	.byte	0	# set address *.LM8
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM8
+	.byte	0x2b	# line 54
+	.byte	0	# set address *.LM9
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM9
+	.byte	0x16	# line 53
+	.byte	0	# set address *.LM10
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM10
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM11
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM11
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM12
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM12
+	.byte	0x16	# line 54
+	.byte	0	# set address *.LM13
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM13
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM14
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM14
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM15
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM15
+	.byte	0x16	# line 55
+	.byte	0	# set address *.LM16
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM16
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM17
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM17
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM18
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM18
+	.byte	0x16	# line 56
+	.byte	0	# set address *.LM19
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM19
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM20
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM20
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM21
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM21
+	.byte	0x16	# line 57
+	.byte	0	# set address *.LM22
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM22
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM23
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM23
+	.byte	0x18	# line 59
+	.byte	0	# set address *.LM24
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM24
+	.byte	0x1b	# line 63
+	.byte	0	# set address *.LM25
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM25
+	.byte	0x13	# line 59
+	.byte	0	# set address *.LM26
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM26
+	.byte	0x18	# line 60
+	.byte	0	# set address *.LM27
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM27
+	.byte	0x18	# line 61
+	.byte	0	# set address *.LM28
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM28
+	.byte	0x18	# line 62
+	.byte	0	# set address *.LM29
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM29
+	.byte	0x18	# line 63
+	.byte	0	# set address *.LM30
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM30
+	.byte	0x18	# line 64
+	.byte	0	# set address *.LM31
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM31
+	.byte	0x1b	# line 68
+	.byte	0	# set address *.LM32
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM32
+	.byte	0x1c	# line 73
+	.byte	0	# set address *.LM33
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM33
+	.byte	0x18	# line 74
+	.byte	0	# set address *.LM34
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM34
+	.byte	0x1b	# line 78
+	.byte	0	# set address *.LM35
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM35
+	.byte	0x1b	# line 82
+	.byte	0	# set address *.LM36
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM36
+	.byte	0x18	# line 83
+	.byte	0	# set address *.Letext0
+	.uleb128 0x5
+	.byte	0x2
+	.long	.Letext0
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+.LELT0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF2:
+	.string	"long long int"
+.LASF3:
+	.string	"unsigned int"
+.LASF8:
+	.string	"_Decimal32"
+.LASF4:
+	.string	"long long unsigned int"
+.LASF11:
+	.string	"main"
+.LASF9:
+	.string	"_Decimal64"
+.LASF0:
+	.string	"double"
+.LASF10:
+	.string	"_Decimal128"
+.LASF7:
+	.string	"/usr/src/gcc/obj/gcc"
+.LASF1:
+	.string	"float"
+.LASF6:
+	.string	"typeddwarf.c"
+.LASF5:
+	.string	"GNU C 4.7.0 20110504 (experimental)"
+	.ident	"GCC: (GNU) 4.7.0 20110504 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.c b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
new file mode 100644
index 0000000..e5f7d67
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.c
@@ -0,0 +1,93 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-g" } */
+
+typedef __SIZE_TYPE__ size_t;
+volatile int vv;
+extern void *memcpy (void *, const void *, size_t);
+
+__attribute__((noinline, noclone)) void
+f1 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 29 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 29 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 29 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { gdb-test 29 "n" "9" } } */
+  double o = h;			/* { dg-final { gdb-test 29 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 29 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 29 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 29 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 29 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 29 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 29 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 29 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 29 "w" "1" } } */
+  double x = a + b + 1.0;	/* { dg-final { gdb-test 29 "x" "4" } } */
+  double y = b + c + 2.0;	/* { dg-final { gdb-test 29 "y" "7" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 29 "z" "12" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f2 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 53 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 53 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 53 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { xfail-gdb-test 53 "n" "9" } } */
+  double o = h;			/* { dg-final { xfail-gdb-test 53 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 53 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 53 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 53 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 53 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 53 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 53 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 53 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 53 "w" "1" } } */
+  double x = a + b - 3 + 1.0e20;/* { dg-final { gdb-test 53 "x" "1e\\+20" } } */
+  double y = b + c * 7.0;	/* { dg-final { gdb-test 53 "y" "23" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 53 "z" "12" } } */
+  vv++;
+  vv = a;
+  vv = b;
+  vv = c;
+  vv = d;
+  vv = e;
+  vv = f;
+  vv = g;
+  vv = h;
+  vv = i;
+  vv = j;
+}
+
+__attribute__((noinline, noclone)) void
+f3 (long long a, int b, long long c, unsigned d)
+{
+  long long w = (a > d) ? a : d;/* { dg-final { gdb-test 73 "w" "4" } } */
+  long long x = a + b + 7;	/* { dg-final { gdb-test 73 "x" "10" } } */
+  long long y = c + d + 0x912345678LL;/* { dg-final { gdb-test 73 "y" "38960125567" } } */
+  int z = (x + y);		/* { dg-final { gdb-test 73 "z" "305419913" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f4 (_Decimal32 a, _Decimal64 b, _Decimal128 c)
+{
+  _Decimal32 w = a * 8.0DF + 6.0DF;/* { dg-final { xfail-gdb-test 82 "(int)w" "70" } } */
+  _Decimal64 x = b / 8.0DD - 6.0DD;/* { dg-final { xfail-gdb-test 82 "(int)x" "-4" } } */
+  _Decimal128 y = -c / 8.0DL;	/* { dg-final { xfail-gdb-test 82 "(int)y" "-8" } } */
+  vv++;
+}
+
+int
+main ()
+{
+  f1 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f2 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f3 (1, 2, 3, 4);
+  f4 (8.0DF, 16.0DD, 64.0DL);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
new file mode 100644
index 0000000..bddcc18
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -0,0 +1,91 @@
+# Copyright 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib dwarf.exp
+
+set test "typeddwarf"
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if ![dwarf2_support] {
+    return 0  
+}
+
+# This test can only be run on x86 targets.
+if { ![istarget i?86-*] } {
+    return 0
+}
+
+if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+global tests
+set tests(_) -
+unset tests(_)
+
+proc gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 0]
+}
+
+proc xfail-gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 1]
+}
+
+proc scan_gdb_tests {} {
+    global srcdir subdir test
+
+    set file "$srcdir/$subdir/$test.c"
+
+    set fd [open "$file"]
+    while {![eof $fd]} {
+	set line [gets $fd]
+	if {! [regexp "\{ (gdb-test .+) \} \}" $line ignore test_cmd]} {
+	    continue
+	}
+
+	eval $test_cmd
+    }
+    close $fd
+}
+
+scan_gdb_tests
+
+foreach line [lsort [array names tests]] {
+    gdb_test "break typeddwarf.c:$line" "Breakpoint .*" \
+	"set breakpoint at typeddwarf.c:$line"
+    gdb_continue_to_breakpoint "continue to typeddwarf.c:$line"
+
+    foreach test $tests($line) {
+	set var [lindex $test 0]
+	set value [lindex $test 1]
+	set should_xfail [lindex $test 2]
+
+	if {$should_xfail} {
+	    setup_xfail *-*-*
+	}
+
+	gdb_test "print $var" \
+	    " = $value" \
+	    "check value of $var at typeddwarf.c:$line"
+    }
+}
diff --git a/gdb/value.c b/gdb/value.c
index 2acb1df..cb7cae5 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -2965,6 +2965,19 @@ value_from_contents_and_address (struct type *type,
   return v;
 }
 
+/* Create a value of type TYPE holding the contents CONTENTS.
+   The new value is `not_lval'.  */
+
+struct value *
+value_from_contents (struct type *type, const gdb_byte *contents)
+{
+  struct value *result;
+
+  result = allocate_value (type);
+  memcpy (value_contents_raw (result), contents, TYPE_LENGTH (type));
+  return result;
+}
+
 struct value *
 value_from_double (struct type *type, DOUBLEST num)
 {
diff --git a/gdb/value.h b/gdb/value.h
index 4c42633..65d0a02 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -479,6 +479,7 @@ extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
 extern struct value *value_from_contents_and_address (struct type *,
 						      const gdb_byte *,
 						      CORE_ADDR);
+extern struct value *value_from_contents (struct type *, const gdb_byte *);
 
 extern struct value *default_value_from_register (struct type *type,
 						  int regnum,


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-11 14:59             ` Tom Tromey
  2011-05-11 19:44               ` Tom Tromey
@ 2011-05-12  0:03               ` Ulrich Weigand
  2011-05-12 16:33                 ` Tom Tromey
  1 sibling, 1 reply; 25+ messages in thread
From: Ulrich Weigand @ 2011-05-12  0:03 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey wrote:
> >>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:
> Ulrich> Huh, interesting approach.  In a sense, that might be OK, since
> Ulrich> it mirrors what we're doing in dwarf_expr_read_reg by calling
> Ulrich> address_from_register.  On the other hand, I'm not sure
> Ulrich> value_cast always does the right thing if the size of a pointer
> Ulrich> type differs from the size of the DWARF address type ...
> 
> I had not considered that as a possibility.  I think the most obviously
> safe thing to do is just revert dwarf_expr_fetch_address to (mostly)
> resemble its pre-patch state.  I will do that and test it.

Yes, I agree your latest version of dwarf_expr_fetch_address should
be obviously safe, that is, getting the same result as prior to the
change.  I've tested your patch on Cell/B.E. with no regressions
(using both -m32 and -m64 for the PowerPC side).

Another option that occurred to me in the meantime would be to ensure
that untyped "old-style" DWARF values are represented by an *unsigned*
type (either always, and converted to signed for operations that need
it, or else just converted to unsigned in dwarf_expr_fetch_address),
so that calling value_as_address will then do the right thing ...

> Ulrich> Another issue that just occurred to me: your patch creates
> Ulrich> possibly many temporary struct value objects.  I'm wondering
> Ulrich> whether those ought to be released from the value chain at some
> Ulrich> point ...
> 
> I considered this but talked myself out of it using the following
> reasoning:
> 
> 1. Most DWARF expressions are simple, so in practice not many values
>    will be released;
> 2. The unwinder code is value based but does not seem to call
>    value_free_to_mark, so it must not be significant there;

But it does call release_value; see frame.c:frame_register_unwind:

  /* Dispose of the new value.  This prevents watchpoints from
     trying to watch the saved frame pointer.  */
  release_value (value);
  value_free (value);

> 3. In other (expression-evaluation) contexts, some caller is going to
>    free the values anyway;
> 4. The watchpoint code looks at the value stack to determine what
>    intermediate values to watch, and perhaps the values from the DWARF
>    expression are relevant (though ... it occurs to me just now that
>    this approach must be pretty broken in the presence of location
>    lists).
> 
> I am actually not sure if #4 is an argument for or against.  Maybe those
> intermediate values confuse things; there is a comment in
> value_fetch_lazy indicating that this may be the case.

Yes, that is my concern -- that there could be intermediate values that
are *not* actually appropriate to watch ...


I noticed one more minor buglet in the latest patch:

@@ -576,7 +590,7 @@ read_pieced_value (struct value *v)
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = source_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -609,7 +623,7 @@ read_pieced_value (struct value *v)
 	    else
 	      {
 		error (_("Unable to access DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, value_as_long (p->v.value)));

That should be p->v.regno here (and at another place a bit farther down).

Otherwise this looks good to me.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-12  0:03               ` Ulrich Weigand
@ 2011-05-12 16:33                 ` Tom Tromey
  2011-05-13  7:52                   ` Regression: " Jan Kratochvil
  0 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-12 16:33 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

Tom> I had not considered that as a possibility.  I think the most obviously
Tom> safe thing to do is just revert dwarf_expr_fetch_address to (mostly)
Tom> resemble its pre-patch state.  I will do that and test it.

Ulrich> Yes, I agree your latest version of dwarf_expr_fetch_address should
Ulrich> be obviously safe, that is, getting the same result as prior to the
Ulrich> change.  I've tested your patch on Cell/B.E. with no regressions
Ulrich> (using both -m32 and -m64 for the PowerPC side).

Ulrich> Another option that occurred to me in the meantime would be to ensure
Ulrich> that untyped "old-style" DWARF values are represented by an *unsigned*
Ulrich> type (either always, and converted to signed for operations that need
Ulrich> it, or else just converted to unsigned in dwarf_expr_fetch_address),
Ulrich> so that calling value_as_address will then do the right thing ...

I looked at that earlier, but decided on the current course instead.
My reasoning was that using unsigned would result in more casts, as
there are more must-be-signed operations than must-be-unsigned ones.

Ulrich> But it does call release_value; see frame.c:frame_register_unwind:

Thanks, I missed that.

I've added value freeing to the patch.

Ulrich> I noticed one more minor buglet in the latest patch:

Thanks.

Ulrich> Otherwise this looks good to me.

Thank you very much for your reviews.

Here is what I am checking in.

Tom

2011-05-12  Tom Tromey  <tromey@redhat.com>

	PR gdb/12617:
	* value.h (value_from_contents): Declare.
	* value.c (value_from_contents): New function.
	* dwarf2read.c (dwarf_stack_op_name): Add new values.
	(dwarf2_get_die_type): New function.
	* dwarf2loc.c (dwarf_expr_get_base_type): New function.
	(allocate_piece_closure): Acquire reference to values.
	(read_pieced_value): Update for value-based expressions.
	(write_pieced_value): Likewise.
	(free_pieced_value_closure): Call value_free as needed.
	(dwarf2_evaluate_loc_desc_full): Set get_base_type field.
	Update for value-based expressions.
	* dwarf2loc.h (dwarf2_get_die_type): Declare.
	* dwarf2expr.h (struct dwarf_stack_value) <value>: Change type.
	<get_base_type>: New field.
	(struct dwarf_expr_piece) <v.value>: Change type.
	<v.regno>: New field.
	(struct dwarf_expr_context) <mark>: New field.
	(dwarf_expr_piece, dwarf_expr_fetch): Update.
	(dwarf_expr_pop, dwarf_expr_push): Remove.
	(dwarf_expr_push_address): Declare.
	* dwarf2expr.c (dwarf_arch_cookie): New global.
	(struct dwarf_gdbarch_types): New.
	(dwarf_gdbarch_types_init, dwarf_expr_address_type): New
	functions.
	(dwarf_expr_push): Change type of 'value' argument.  Update.  Now
	static.
	(dwarf_expr_push_address): New function.
	(dwarf_expr_pop): Now static.
	(dwarf_expr_fetch): Change return type.
	(dwarf_require_integral): New function.
	(dwarf_expr_fetch): Simplify.
	(add_piece): Update.
	(base_types_equal_p, dwarf_get_base_type, get_unsigned_type): New
	functions.
	(execute_stack_op) <sign_ext>: Remove.
	Use values for DWARF stack.
	<DW_OP_GNU_const_type, DW_OP_GNU_deref_type,
	DW_OP_GNU_regval_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret>:
	New cases.
	(_initialize_dwarf2expr): New function.
	(add_piece): Update.
	(new_dwarf_expr_context): Set new field.
	(free_dwarf_expr_context): Call value_free_to_mark.
	* dwarf2-frame.c (no_base_type): New function.
	(execute_stack_op): Set get_base_type field.  Update.

2011-05-12  Tom Tromey  <tromey@redhat.com>

	* gdb.dwarf2/typeddwarf.S: New file.
	* gdb.dwarf2/typeddwarf.c: New file.
	* gdb.dwarf2/typeddwarf.exp: New file.

Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.121
diff -u -r1.121 dwarf2-frame.c
--- dwarf2-frame.c	18 Mar 2011 18:52:30 -0000	1.121
+++ dwarf2-frame.c	12 May 2011 16:25:10 -0000
@@ -353,6 +353,14 @@
 		  _("Support for DW_OP_call* is invalid in CFI"));
 }
 
+/* Helper function for execute_stack_op.  */
+
+static struct type *
+no_base_type (struct dwarf_expr_context *ctx, size_t die)
+{
+  error (_("Support for typed DWARF is not supported in CFI"));
+}
+
 /* Execute the required actions for both the DW_CFA_restore and
 DW_CFA_restore_extended instructions.  */
 static void
@@ -406,14 +414,15 @@
   ctx->get_frame_pc = no_get_frame_pc;
   ctx->get_tls_address = no_get_tls_address;
   ctx->dwarf_call = no_dwarf_call;
+  ctx->get_base_type = no_base_type;
 
-  dwarf_expr_push (ctx, initial, initial_in_stack_memory);
+  dwarf_expr_push_address (ctx, initial, initial_in_stack_memory);
   dwarf_expr_eval (ctx, exp, len);
 
   if (ctx->location == DWARF_VALUE_MEMORY)
     result = dwarf_expr_fetch_address (ctx, 0);
   else if (ctx->location == DWARF_VALUE_REGISTER)
-    result = read_reg (this_frame, dwarf_expr_fetch (ctx, 0));
+    result = read_reg (this_frame, value_as_long (dwarf_expr_fetch (ctx, 0)));
   else
     {
       /* This is actually invalid DWARF, but if we ever do run across
Index: dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.57
diff -u -r1.57 dwarf2expr.c
--- dwarf2expr.c	22 Mar 2011 21:06:32 -0000	1.57
+++ dwarf2expr.c	12 May 2011 16:25:10 -0000
@@ -34,6 +34,61 @@
 static void execute_stack_op (struct dwarf_expr_context *,
 			      const gdb_byte *, const gdb_byte *);
 
+/* Cookie for gdbarch data.  */
+
+static struct gdbarch_data *dwarf_arch_cookie;
+
+/* This holds gdbarch-specific types used by the DWARF expression
+   evaluator.  See comments in execute_stack_op.  */
+
+struct dwarf_gdbarch_types
+{
+  struct type *dw_types[3];
+};
+
+/* Allocate and fill in dwarf_gdbarch_types for an arch.  */
+
+static void *
+dwarf_gdbarch_types_init (struct gdbarch *gdbarch)
+{
+  struct dwarf_gdbarch_types *types
+    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf_gdbarch_types);
+
+  /* The types themselves are lazily initialized.  */
+
+  return types;
+}
+
+/* Return the type used for DWARF operations where the type is
+   unspecified in the DWARF spec.  Only certain sizes are
+   supported.  */
+
+static struct type *
+dwarf_expr_address_type (struct dwarf_expr_context *ctx)
+{
+  struct dwarf_gdbarch_types *types = gdbarch_data (ctx->gdbarch,
+						    dwarf_arch_cookie);
+  int ndx;
+
+  if (ctx->addr_size == 2)
+    ndx = 0;
+  else if (ctx->addr_size == 4)
+    ndx = 1;
+  else if (ctx->addr_size == 8)
+    ndx = 2;
+  else
+    error (_("Unsupported address size in DWARF expressions: %d bits"),
+	   8 * ctx->addr_size);
+
+  if (types->dw_types[ndx] == NULL)
+    types->dw_types[ndx]
+      = arch_integer_type (ctx->gdbarch,
+			   8 * ctx->addr_size,
+			   0, "<signed DWARF address type>");
+
+  return types->dw_types[ndx];
+}
+
 /* Create a new context for the expression evaluator.  */
 
 struct dwarf_expr_context *
@@ -49,6 +104,7 @@
   retval->num_pieces = 0;
   retval->pieces = 0;
   retval->max_recursion_depth = 0x100;
+  retval->mark = value_mark ();
   return retval;
 }
 
@@ -57,6 +113,7 @@
 void
 free_dwarf_expr_context (struct dwarf_expr_context *ctx)
 {
+  value_free_to_mark (ctx->mark);
   xfree (ctx->stack);
   xfree (ctx->pieces);
   xfree (ctx);
@@ -96,26 +153,32 @@
 
 /* Push VALUE onto CTX's stack.  */
 
-void
-dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
+static void
+dwarf_expr_push (struct dwarf_expr_context *ctx, struct value *value,
 		 int in_stack_memory)
 {
   struct dwarf_stack_value *v;
 
-  /* We keep all stack elements within the range defined by the
-     DWARF address size.  */
-  if (ctx->addr_size < sizeof (ULONGEST))
-    value &= ((ULONGEST) 1 << (ctx->addr_size * HOST_CHAR_BIT)) - 1;
-
   dwarf_expr_grow_stack (ctx, 1);
   v = &ctx->stack[ctx->stack_len++];
   v->value = value;
   v->in_stack_memory = in_stack_memory;
 }
 
-/* Pop the top item off of CTX's stack.  */
+/* Push VALUE onto CTX's stack.  */
 
 void
+dwarf_expr_push_address (struct dwarf_expr_context *ctx, CORE_ADDR value,
+			 int in_stack_memory)
+{
+  dwarf_expr_push (ctx,
+		   value_from_ulongest (dwarf_expr_address_type (ctx), value),
+		   in_stack_memory);
+}
+
+/* Pop the top item off of CTX's stack.  */
+
+static void
 dwarf_expr_pop (struct dwarf_expr_context *ctx)
 {
   if (ctx->stack_len <= 0)
@@ -125,7 +188,7 @@
 
 /* Retrieve the N'th item on CTX's stack.  */
 
-ULONGEST
+struct value *
 dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 {
   if (ctx->stack_len <= n)
@@ -133,7 +196,39 @@
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].value;
+}
 
+/* Require that TYPE be an integral type; throw an exception if not.  */
+
+static void
+dwarf_require_integral (struct type *type)
+{
+  if (TYPE_CODE (type) != TYPE_CODE_INT
+      && TYPE_CODE (type) != TYPE_CODE_CHAR
+      && TYPE_CODE (type) != TYPE_CODE_BOOL)
+    error (_("integral type expected in DWARF expression"));
+}
+
+/* Return the unsigned form of TYPE.  TYPE is necessarily an integral
+   type.  */
+
+static struct type *
+get_unsigned_type (struct gdbarch *gdbarch, struct type *type)
+{
+  switch (TYPE_LENGTH (type))
+    {
+    case 1:
+      return builtin_type (gdbarch)->builtin_uint8;
+    case 2:
+      return builtin_type (gdbarch)->builtin_uint16;
+    case 4:
+      return builtin_type (gdbarch)->builtin_uint32;
+    case 8:
+      return builtin_type (gdbarch)->builtin_uint64;
+    default:
+      error (_("no unsigned variant found for type, while evaluating "
+	       "DWARF expression"));
+    }
 }
 
 /* Retrieve the N'th item on CTX's stack, converted to an address.  */
@@ -141,7 +236,14 @@
 CORE_ADDR
 dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n)
 {
-  ULONGEST result = dwarf_expr_fetch (ctx, n);
+  struct value *result_val = dwarf_expr_fetch (ctx, n);
+  enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+  ULONGEST result;
+
+  dwarf_require_integral (value_type (result_val));
+  result = extract_unsigned_integer (value_contents (result_val),
+				     TYPE_LENGTH (value_type (result_val)),
+				     byte_order);
 
   /* For most architectures, calling extract_unsigned_integer() alone
      is sufficient for extracting an address.  However, some
@@ -151,25 +253,9 @@
      for those architectures which require it.  */
   if (gdbarch_integer_to_address_p (ctx->gdbarch))
     {
-      enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
       gdb_byte *buf = alloca (ctx->addr_size);
-      struct type *int_type;
-
-      switch (ctx->addr_size)
-	{
-	case 2:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint16;
-	  break;
-	case 4:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint32;
-	  break;
-	case 8:
-	  int_type = builtin_type (ctx->gdbarch)->builtin_uint64;
-	  break;
-	default:
-	  internal_error (__FILE__, __LINE__,
-			  _("Unsupported address size.\n"));
-	}
+      struct type *int_type = get_unsigned_type (ctx->gdbarch,
+						 value_type (result_val));
 
       store_unsigned_integer (buf, ctx->addr_size, byte_order, result);
       return gdbarch_integer_to_address (ctx->gdbarch, int_type, buf);
@@ -188,7 +274,6 @@
 	      "stack only has %d elements on it."),
 	    n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)].in_stack_memory;
-
 }
 
 /* Return true if the expression stack is empty.  */
@@ -238,8 +323,10 @@
   else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
     {
       p->v.ptr.die = ctx->len;
-      p->v.ptr.offset = (LONGEST) dwarf_expr_fetch (ctx, 0);
+      p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0));
     }
+  else if (p->location == DWARF_VALUE_REGISTER)
+    p->v.regno = value_as_long (dwarf_expr_fetch (ctx, 0));
   else
     {
       p->v.value = dwarf_expr_fetch (ctx, 0);
@@ -335,6 +422,43 @@
 	   op_name);
 }
 
+/* Return true iff the types T1 and T2 are "the same".  This only does
+   checks that might reasonably be needed to compare DWARF base
+   types.  */
+
+static int
+base_types_equal_p (struct type *t1, struct type *t2)
+{
+  if (TYPE_CODE (t1) != TYPE_CODE (t2))
+    return 0;
+  if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
+    return 0;
+  return TYPE_LENGTH (t1) == TYPE_LENGTH (t2);
+}
+
+/* A convenience function to call get_base_type on CTX and return the
+   result.  DIE is the DIE whose type we need.  SIZE is non-zero if
+   this function should verify that the resulting type has the correct
+   size.  */
+
+static struct type *
+dwarf_get_base_type (struct dwarf_expr_context *ctx, ULONGEST die, int size)
+{
+  struct type *result;
+
+  if (ctx->get_base_type)
+    {
+      result = ctx->get_base_type (ctx, die);
+      if (size != 0 && TYPE_LENGTH (result) != size)
+	error (_("DW_OP_GNU_const_type has different sizes for type and data"));
+    }
+  else
+    /* Anything will do.  */
+    result = builtin_type (ctx->gdbarch)->builtin_int;
+
+  return result;
+}
+
 /* The engine for the expression evaluator.  Using the context in CTX,
    evaluate the expression between OP_PTR and OP_END.  */
 
@@ -342,10 +466,15 @@
 execute_stack_op (struct dwarf_expr_context *ctx,
 		  const gdb_byte *op_ptr, const gdb_byte *op_end)
 {
-#define sign_ext(x) ((LONGEST) (((x) ^ sign_bit) - sign_bit))
-  ULONGEST sign_bit = (ctx->addr_size >= sizeof (ULONGEST) ? 0
-		       : ((ULONGEST) 1) << (ctx->addr_size * 8 - 1));
   enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+  /* Old-style "untyped" DWARF values need special treatment in a
+     couple of places, specifically DW_OP_mod and DW_OP_shr.  We need
+     a special type for these values so we can distinguish them from
+     values that have an explicit type, because explicitly-typed
+     values do not need special treatment.  This special type must be
+     different (in the `==' sense) from any base type coming from the
+     CU.  */
+  struct type *address_type = dwarf_expr_address_type (ctx);
 
   ctx->location = DWARF_VALUE_MEMORY;
   ctx->initialized = 1;  /* Default is initialized.  */
@@ -368,6 +497,7 @@
       int in_stack_memory = 0;
       ULONGEST uoffset, reg;
       LONGEST offset;
+      struct value *result_val = NULL;
 
       switch (op)
 	{
@@ -404,6 +534,7 @@
 	case DW_OP_lit30:
 	case DW_OP_lit31:
 	  result = op - DW_OP_lit0;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_addr:
@@ -416,47 +547,58 @@
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
 	    result += ctx->offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_const1u:
 	  result = extract_unsigned_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const1s:
 	  result = extract_signed_integer (op_ptr, 1, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const2u:
 	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const2s:
 	  result = extract_signed_integer (op_ptr, 2, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const4u:
 	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const4s:
 	  result = extract_signed_integer (op_ptr, 4, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const8u:
 	  result = extract_unsigned_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_const8s:
 	  result = extract_signed_integer (op_ptr, 8, byte_order);
+	  result_val = value_from_ulongest (address_type, result);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_constu:
 	  op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = uoffset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 	case DW_OP_consts:
 	  op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	  result = offset;
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	/* The DW_OP_reg operations are required to occur alone in
@@ -502,6 +644,7 @@
 		     "or DW_OP_bit_piece."));
 
 	  result = op - DW_OP_reg0;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -510,6 +653,7 @@
 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
 
 	  result = reg;
+	  result_val = value_from_ulongest (address_type, result);
 	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
@@ -547,6 +691,7 @@
 	    /* The byte offset into the data.  */
 	    op_ptr = read_sleb128 (op_ptr, op_end, &len);
 	    result = (ULONGEST) len;
+	    result_val = value_from_ulongest (address_type, result);
 
 	    ctx->location = DWARF_VALUE_IMPLICIT_POINTER;
 	    dwarf_expr_require_composition (op_ptr, op_end,
@@ -590,6 +735,7 @@
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_bregx:
@@ -598,6 +744,7 @@
 	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
 	    result = (ctx->read_reg) (ctx->baton, reg);
 	    result += offset;
+	    result_val = value_from_ulongest (address_type, result);
 	  }
 	  break;
 	case DW_OP_fbreg:
@@ -620,11 +767,14 @@
 	    if (ctx->location == DWARF_VALUE_MEMORY)
 	      result = dwarf_expr_fetch_address (ctx, 0);
 	    else if (ctx->location == DWARF_VALUE_REGISTER)
-	      result = (ctx->read_reg) (ctx->baton, dwarf_expr_fetch (ctx, 0));
+	      result
+		= (ctx->read_reg) (ctx->baton,
+				   value_as_long (dwarf_expr_fetch (ctx, 0)));
 	    else
 	      error (_("Not implemented: computing frame "
 		       "base using explicit value operator"));
 	    result = result + offset;
+	    result_val = value_from_ulongest (address_type, result);
 	    in_stack_memory = 1;
 	    ctx->stack_len = before_stack_len;
 	    ctx->location = DWARF_VALUE_MEMORY;
@@ -632,7 +782,7 @@
 	  break;
 
 	case DW_OP_dup:
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result_val = dwarf_expr_fetch (ctx, 0);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
 	  break;
 
@@ -642,7 +792,7 @@
 
 	case DW_OP_pick:
 	  offset = *op_ptr++;
-	  result = dwarf_expr_fetch (ctx, offset);
+	  result_val = dwarf_expr_fetch (ctx, offset);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset);
 	  break;
 	  
@@ -662,7 +812,7 @@
 	  }
 
 	case DW_OP_over:
-	  result = dwarf_expr_fetch (ctx, 1);
+	  result_val = dwarf_expr_fetch (ctx, 1);
 	  in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1);
 	  break;
 
@@ -685,14 +835,27 @@
 
 	case DW_OP_deref:
 	case DW_OP_deref_size:
+	case DW_OP_GNU_deref_type:
 	  {
 	    int addr_size = (op == DW_OP_deref ? ctx->addr_size : *op_ptr++);
 	    gdb_byte *buf = alloca (addr_size);
 	    CORE_ADDR addr = dwarf_expr_fetch_address (ctx, 0);
+	    struct type *type;
+
 	    dwarf_expr_pop (ctx);
 
+	    if (op == DW_OP_GNU_deref_type)
+	      {
+		ULONGEST type_die;
+
+		op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+		type = dwarf_get_base_type (ctx, type_die, 0);
+	      }
+	    else
+	      type = address_type;
+
 	    (ctx->read_mem) (ctx->baton, buf, addr, addr_size);
-	    result = extract_unsigned_integer (buf, addr_size, byte_order);
+	    result_val = value_from_contents_and_address (type, buf, addr);
 	    break;
 	  }
 
@@ -700,27 +863,34 @@
 	case DW_OP_neg:
 	case DW_OP_not:
 	case DW_OP_plus_uconst:
-	  /* Unary operations.  */
-	  result = dwarf_expr_fetch (ctx, 0);
-	  dwarf_expr_pop (ctx);
+	  {
+	    /* Unary operations.  */
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
 
-	  switch (op)
-	    {
-	    case DW_OP_abs:
-	      if (sign_ext (result) < 0)
-		result = -result;
-	      break;
-	    case DW_OP_neg:
-	      result = -result;
-	      break;
-	    case DW_OP_not:
-	      result = ~result;
-	      break;
-	    case DW_OP_plus_uconst:
-	      op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-	      result += reg;
-	      break;
-	    }
+	    switch (op)
+	      {
+	      case DW_OP_abs:
+		if (value_less (result_val,
+				value_zero (value_type (result_val), not_lval)))
+		  result_val = value_neg (result_val);
+		break;
+	      case DW_OP_neg:
+		result_val = value_neg (result_val);
+		break;
+	      case DW_OP_not:
+		dwarf_require_integral (value_type (result_val));
+		result_val = value_complement (result_val);
+		break;
+	      case DW_OP_plus_uconst:
+		dwarf_require_integral (value_type (result_val));
+		result = value_as_long (result_val);
+		op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+		result += reg;
+		result_val = value_from_ulongest (address_type, result);
+		break;
+	      }
+	  }
 	  break;
 
 	case DW_OP_and:
@@ -742,7 +912,7 @@
 	case DW_OP_ne:
 	  {
 	    /* Binary operations.  */
-	    ULONGEST first, second;
+	    struct value *first, *second;
 
 	    second = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
@@ -750,62 +920,115 @@
 	    first = dwarf_expr_fetch (ctx, 0);
 	    dwarf_expr_pop (ctx);
 
+	    if (! base_types_equal_p (value_type (first), value_type (second)))
+	      error (_("Incompatible types on DWARF stack"));
+
 	    switch (op)
 	      {
 	      case DW_OP_and:
-		result = first & second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_AND);
 		break;
 	      case DW_OP_div:
-		if (!second)
-		  error (_("Division by zero"));
-		result = sign_ext (first) / sign_ext (second);
+		result_val = value_binop (first, second, BINOP_DIV);
                 break;
 	      case DW_OP_minus:
-		result = first - second;
+		result_val = value_binop (first, second, BINOP_SUB);
 		break;
 	      case DW_OP_mod:
-		if (!second)
-		  error (_("Division by zero"));
-		result = first % second;
+		{
+		  int cast_back = 0;
+		  struct type *orig_type = value_type (first);
+
+		  /* We have to special-case "old-style" untyped values
+		     -- these must have mod computed using unsigned
+		     math.  */
+		  if (orig_type == address_type)
+		    {
+		      struct type *utype
+			= get_unsigned_type (ctx->gdbarch, orig_type);
+
+		      cast_back = 1;
+		      first = value_cast (utype, first);
+		      second = value_cast (utype, second);
+		    }
+		  /* Note that value_binop doesn't handle float or
+		     decimal float here.  This seems unimportant.  */
+		  result_val = value_binop (first, second, BINOP_MOD);
+		  if (cast_back)
+		    result_val = value_cast (orig_type, result_val);
+		}
 		break;
 	      case DW_OP_mul:
-		result = first * second;
+		result_val = value_binop (first, second, BINOP_MUL);
 		break;
 	      case DW_OP_or:
-		result = first | second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_IOR);
 		break;
 	      case DW_OP_plus:
-		result = first + second;
+		result_val = value_binop (first, second, BINOP_ADD);
 		break;
 	      case DW_OP_shl:
-		result = first << second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_LSH);
 		break;
 	      case DW_OP_shr:
-		result = first >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		if (value_type (first) == address_type)
+		  {
+		    struct type *utype
+		      = get_unsigned_type (ctx->gdbarch, value_type (first));
+
+		    first = value_cast (utype, first);
+		  }
+
+		result_val = value_binop (first, second, BINOP_RSH);
+		/* Make sure we wind up with the same type we started
+		   with.  */
+		if (value_type (result_val) != value_type (second))
+		  result_val = value_cast (value_type (second), result_val);
                 break;
 	      case DW_OP_shra:
-		result = sign_ext (first) >> second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_RSH);
 		break;
 	      case DW_OP_xor:
-		result = first ^ second;
+		dwarf_require_integral (value_type (first));
+		dwarf_require_integral (value_type (second));
+		result_val = value_binop (first, second, BINOP_BITWISE_XOR);
 		break;
 	      case DW_OP_le:
-		result = sign_ext (first) <= sign_ext (second);
+		/* A <= B is !(B < A).  */
+		result = ! value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ge:
-		result = sign_ext (first) >= sign_ext (second);
+		/* A >= B is !(A < B).  */
+		result = ! value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_eq:
-		result = sign_ext (first) == sign_ext (second);
+		result = value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_lt:
-		result = sign_ext (first) < sign_ext (second);
+		result = value_less (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_gt:
-		result = sign_ext (first) > sign_ext (second);
+		/* A > B is B < A.  */
+		result = value_less (second, first);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      case DW_OP_ne:
-		result = sign_ext (first) != sign_ext (second);
+		result = ! value_equal (first, second);
+		result_val = value_from_ulongest (address_type, result);
 		break;
 	      default:
 		internal_error (__FILE__, __LINE__,
@@ -816,6 +1039,7 @@
 
 	case DW_OP_call_frame_cfa:
 	  result = (ctx->get_frame_cfa) (ctx->baton);
+	  result_val = value_from_ulongest (address_type, result);
 	  in_stack_memory = 1;
 	  break;
 
@@ -828,9 +1052,10 @@
 	  control block at which the variable is located.  Nothing
 	  should follow this operator, so the top of stack would be
 	  returned.  */
-	  result = dwarf_expr_fetch (ctx, 0);
+	  result = value_as_long (dwarf_expr_fetch (ctx, 0));
 	  dwarf_expr_pop (ctx);
 	  result = (ctx->get_tls_address) (ctx->baton, result);
+	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
 	case DW_OP_skip:
@@ -840,11 +1065,17 @@
 	  goto no_push;
 
 	case DW_OP_bra:
-	  offset = extract_signed_integer (op_ptr, 2, byte_order);
-	  op_ptr += 2;
-	  if (dwarf_expr_fetch (ctx, 0) != 0)
-	    op_ptr += offset;
-	  dwarf_expr_pop (ctx);
+	  {
+	    struct value *val;
+
+	    offset = extract_signed_integer (op_ptr, 2, byte_order);
+	    op_ptr += 2;
+	    val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_require_integral (value_type (val));
+	    if (value_as_long (val) != 0)
+	      op_ptr += offset;
+	    dwarf_expr_pop (ctx);
+	  }
 	  goto no_push;
 
 	case DW_OP_nop:
@@ -912,12 +1143,73 @@
 	  ctx->num_pieces = 0;
 	  goto abort_expression;
 
+	case DW_OP_GNU_const_type:
+	  {
+	    ULONGEST type_die;
+	    int n;
+	    const gdb_byte *data;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    n = *op_ptr++;
+	    data = op_ptr;
+	    op_ptr += n;
+
+	    type = dwarf_get_base_type (ctx, type_die, n);
+	    result_val = value_from_contents (type, data);
+	  }
+	  break;
+
+	case DW_OP_GNU_regval_type:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+	    result = (ctx->read_reg) (ctx->baton, reg);
+	    result_val = value_from_ulongest (type, result);
+	  }
+	  break;
+
+	case DW_OP_GNU_convert:
+	case DW_OP_GNU_reinterpret:
+	  {
+	    ULONGEST type_die;
+	    struct type *type;
+
+	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+
+	    type = dwarf_get_base_type (ctx, type_die, 0);
+
+	    result_val = dwarf_expr_fetch (ctx, 0);
+	    dwarf_expr_pop (ctx);
+
+	    if (op == DW_OP_GNU_convert)
+	      result_val = value_cast (type, result_val);
+	    else if (type == value_type (result_val))
+	      {
+		/* Nothing.  */
+	      }
+	    else if (TYPE_LENGTH (type)
+		     != TYPE_LENGTH (value_type (result_val)))
+	      error (_("DW_OP_GNU_reinterpret has wrong size"));
+	    else
+	      result_val
+		= value_from_contents (type,
+				       value_contents_all (result_val));
+	  }
+	  break;
+
 	default:
 	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
 	}
 
       /* Most things push a result value.  */
-      dwarf_expr_push (ctx, result, in_stack_memory);
+      gdb_assert (result_val != NULL);
+      dwarf_expr_push (ctx, result_val, in_stack_memory);
     no_push:
       ;
     }
@@ -931,5 +1223,11 @@
 abort_expression:
   ctx->recursion_depth--;
   gdb_assert (ctx->recursion_depth >= 0);
-#undef sign_ext
+}
+
+void
+_initialize_dwarf2expr (void)
+{
+  dwarf_arch_cookie
+    = gdbarch_data_register_post_init (dwarf_gdbarch_types_init);
 }
Index: dwarf2expr.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.h,v
retrieving revision 1.32
diff -u -r1.32 dwarf2expr.h
--- dwarf2expr.h	27 Feb 2011 16:25:37 -0000	1.32
+++ dwarf2expr.h	12 May 2011 16:25:10 -0000
@@ -51,7 +51,7 @@
 
 struct dwarf_stack_value
 {
-  ULONGEST value;
+  struct value *value;
 
   /* Non-zero if the piece is in memory and is known to be
      on the program's stack.  It is always ok to set this to zero.
@@ -81,6 +81,10 @@
   /* Offset used to relocate DW_OP_addr argument.  */
   CORE_ADDR offset;
 
+  /* The evaluator is value-based, and frees values up to this point
+     when the expression context is destroyed.  */
+  struct value *mark;
+
   /* An opaque argument provided by the caller, which will be passed
      to all of the callback functions.  */
   void *baton;
@@ -111,6 +115,13 @@
      being passed to and returned from the called DWARF subroutine.  */
   void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset);
 
+  /* Return the base type given by the indicated DIE.  This can throw
+     an exception if the DIE is invalid or does not represent a base
+     type.  If can also be NULL in the special case where the
+     callbacks are not performing evaluation, and thus it is
+     meaningful to substitute a stub type of the correct size.  */
+  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, size_t die);
+
 #if 0
   /* Not yet implemented.  */
 
@@ -180,9 +191,11 @@
       int in_stack_memory;
     } mem;
 
-    /* The piece's register number or literal value, for
-       DWARF_VALUE_REGISTER or DWARF_VALUE_STACK pieces.  */
-    ULONGEST value;
+    /* The piece's register number, for DWARF_VALUE_REGISTER pieces.  */
+    int regno;
+
+    /* The piece's literal value, for DWARF_VALUE_STACK pieces.  */
+    struct value *value;
 
     struct
     {
@@ -214,12 +227,12 @@
 struct cleanup *
     make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx);
 
-void dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value,
-		      int in_stack_memory);
-void dwarf_expr_pop (struct dwarf_expr_context *ctx);
+void dwarf_expr_push_address (struct dwarf_expr_context *ctx,
+			      CORE_ADDR value,
+			      int in_stack_memory);
 void dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr,
 		      size_t len);
-ULONGEST dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
+struct value *dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
 CORE_ADDR dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n);
 int dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n);
 
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.115
diff -u -r1.115 dwarf2loc.c
--- dwarf2loc.c	22 Mar 2011 21:06:33 -0000	1.115
+++ dwarf2loc.c	12 May 2011 16:25:10 -0000
@@ -286,6 +286,16 @@
 		     ctx->get_frame_pc, ctx->baton);
 }
 
+/* Callback function for dwarf2_evaluate_loc_desc.  */
+
+static struct type *
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+  struct dwarf_expr_baton *debaton = ctx->baton;
+
+  return dwarf2_get_die_type (die_offset, debaton->per_cu);
+}
+
 struct piece_closure
 {
   /* Reference count.  */
@@ -313,6 +323,7 @@
 			int addr_size)
 {
   struct piece_closure *c = XZALLOC (struct piece_closure);
+  int i;
 
   c->refc = 1;
   c->per_cu = per_cu;
@@ -321,6 +332,9 @@
   c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
 
   memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
+  for (i = 0; i < n_pieces; ++i)
+    if (c->pieces[i].location == DWARF_VALUE_STACK)
+      value_incref (c->pieces[i].v.value);
 
   return c;
 }
@@ -576,7 +590,7 @@
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = source_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -609,7 +623,7 @@
 	    else
 	      {
 		error (_("Unable to access DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, p->v.regno));
 	      }
 	  }
 	  break;
@@ -623,7 +637,6 @@
 
 	case DWARF_VALUE_STACK:
 	  {
-	    struct gdbarch *gdbarch = get_type_arch (value_type (v));
 	    size_t n = this_size;
 
 	    if (n > c->addr_size - source_offset)
@@ -634,18 +647,11 @@
 	      {
 		/* Nothing.  */
 	      }
-	    else if (source_offset == 0)
-	      store_unsigned_integer (buffer, n,
-				      gdbarch_byte_order (gdbarch),
-				      p->v.value);
 	    else
 	      {
-		gdb_byte bytes[sizeof (ULONGEST)];
+		const gdb_byte *val_bytes = value_contents_all (p->v.value);
 
-		store_unsigned_integer (bytes, n + source_offset,
-					gdbarch_byte_order (gdbarch),
-					p->v.value);
-		memcpy (buffer, bytes + source_offset, n);
+		intermediate_buffer = val_bytes + source_offset;
 	      }
 	  }
 	  break;
@@ -776,7 +782,7 @@
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
 	    int reg_offset = dest_offset;
 
 	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -816,7 +822,7 @@
 	    else
 	      {
 		error (_("Unable to write to DWARF register number %s"),
-		       paddress (arch, p->v.value));
+		       paddress (arch, p->v.regno));
 	      }
 	  }
 	  break;
@@ -1033,6 +1039,12 @@
   --c->refc;
   if (c->refc == 0)
     {
+      int i;
+
+      for (i = 0; i < c->n_pieces; ++i)
+	if (c->pieces[i].location == DWARF_VALUE_STACK)
+	  value_free (c->pieces[i].v.value);
+
       xfree (c->pieces);
       xfree (c);
     }
@@ -1106,6 +1118,7 @@
   ctx->get_frame_pc = dwarf_expr_frame_pc;
   ctx->get_tls_address = dwarf_expr_tls_address;
   ctx->dwarf_call = dwarf_expr_dwarf_call;
+  ctx->get_base_type = dwarf_expr_get_base_type;
 
   TRY_CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -1148,7 +1161,7 @@
 	case DWARF_VALUE_REGISTER:
 	  {
 	    struct gdbarch *arch = get_frame_arch (frame);
-	    ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0);
+	    ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
 	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
 
 	    if (byte_offset != 0)
@@ -1176,26 +1189,23 @@
 
 	case DWARF_VALUE_STACK:
 	  {
-	    ULONGEST value = dwarf_expr_fetch (ctx, 0);
-	    bfd_byte *contents, *tem;
-	    size_t n = ctx->addr_size;
+	    struct value *value = dwarf_expr_fetch (ctx, 0);
+	    gdb_byte *contents;
+	    const gdb_byte *val_bytes;
+	    size_t n = TYPE_LENGTH (value_type (value));
 
 	    if (byte_offset + TYPE_LENGTH (type) > n)
 	      invalid_synthetic_pointer ();
 
-	    tem = alloca (n);
-	    store_unsigned_integer (tem, n,
-				    gdbarch_byte_order (ctx->gdbarch),
-				    value);
-
-	    tem += byte_offset;
+	    val_bytes = value_contents_all (value);
+	    val_bytes += byte_offset;
 	    n -= byte_offset;
 
 	    retval = allocate_value (type);
 	    contents = value_contents_raw (retval);
 	    if (n > TYPE_LENGTH (type))
 	      n = TYPE_LENGTH (type);
-	    memcpy (contents, tem, n);
+	    memcpy (contents, val_bytes, n);
 	  }
 	  break;
 
Index: dwarf2loc.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.h,v
retrieving revision 1.22
diff -u -r1.22 dwarf2loc.h
--- dwarf2loc.h	17 Feb 2011 16:20:44 -0000	1.22
+++ dwarf2loc.h	12 May 2011 16:25:10 -0000
@@ -59,6 +59,9 @@
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
+struct type *dwarf2_get_die_type (unsigned int die_offset,
+				  struct dwarf2_per_cu_data *per_cu);
+
 /* Evaluate a location description, starting at DATA and with length
    SIZE, to find the current location of variable of TYPE in the context
    of FRAME.  */
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.532
diff -u -r1.532 dwarf2read.c
--- dwarf2read.c	12 May 2011 15:59:46 -0000	1.532
+++ dwarf2read.c	12 May 2011 16:25:11 -0000
@@ -13094,6 +13094,18 @@
       return "DW_OP_GNU_uninit";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
+    case DW_OP_GNU_entry_value:
+      return "DW_OP_GNU_entry_value";
+    case DW_OP_GNU_const_type:
+      return "DW_OP_GNU_const_type";
+    case DW_OP_GNU_regval_type:
+      return "DW_OP_GNU_regval_type";
+    case DW_OP_GNU_deref_type:
+      return "DW_OP_GNU_deref_type";
+    case DW_OP_GNU_convert:
+      return "DW_OP_GNU_convert";
+    case DW_OP_GNU_reinterpret:
+      return "DW_OP_GNU_reinterpret";
     default:
       return NULL;
     }
@@ -13652,6 +13664,31 @@
   return retval;
 }
 
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+   PER_CU.  */
+
+struct type *
+dwarf2_get_die_type (unsigned int die_offset,
+		     struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf2_cu *cu = per_cu->cu;
+  struct die_info *die;
+  struct type *result;
+
+  dw2_setup (per_cu->objfile);
+
+  die = follow_die_offset (die_offset, &cu);
+  if (!die)
+    error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
+	   die_offset, per_cu->cu->objfile->name);
+
+  result = get_die_type (die, cu);
+  if (result == NULL)
+    result = read_type_die_1 (die, cu);
+
+  return result;
+}
+
 /* Follow the signature attribute ATTR in SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
    On exit *REF_CU is the CU of the result.  */
Index: value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.139
diff -u -r1.139 value.c
--- value.c	27 Feb 2011 20:57:15 -0000	1.139
+++ value.c	12 May 2011 16:25:12 -0000
@@ -2965,6 +2965,19 @@
   return v;
 }
 
+/* Create a value of type TYPE holding the contents CONTENTS.
+   The new value is `not_lval'.  */
+
+struct value *
+value_from_contents (struct type *type, const gdb_byte *contents)
+{
+  struct value *result;
+
+  result = allocate_value (type);
+  memcpy (value_contents_raw (result), contents, TYPE_LENGTH (type));
+  return result;
+}
+
 struct value *
 value_from_double (struct type *type, DOUBLEST num)
 {
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.179
diff -u -r1.179 value.h
--- value.h	6 May 2011 14:12:18 -0000	1.179
+++ value.h	12 May 2011 16:25:12 -0000
@@ -479,6 +479,7 @@
 extern struct value *value_from_contents_and_address (struct type *,
 						      const gdb_byte *,
 						      CORE_ADDR);
+extern struct value *value_from_contents (struct type *, const gdb_byte *);
 
 extern struct value *default_value_from_register (struct type *type,
 						  int regnum,
Index: testsuite/gdb.dwarf2/typeddwarf.S
===================================================================
RCS file: testsuite/gdb.dwarf2/typeddwarf.S
diff -N testsuite/gdb.dwarf2/typeddwarf.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/typeddwarf.S	12 May 2011 16:25:14 -0000
@@ -0,0 +1,2225 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This source file was generated from typeddwarf.c using the following
+   command line:
+
+   gcc -m32 -dA -S -g -O2 typeddwarf.c -o typeddwarf.S
+
+*/
+
+
+	.file	"typeddwarf.c"
+	.text
+.Ltext0:
+	.p2align 4,,15
+	.globl	f1
+	.type	f1, @function
+f1:
+.LFB0:
+	# typeddwarf.c:10
+.LM1:
+.LVL0:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:29
+.LM2:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:30
+.LM3:
+	ret
+.LFE0:
+	.size	f1, .-f1
+	.p2align 4,,15
+	.globl	f2
+	.type	f2, @function
+f2:
+.LFB1:
+	# typeddwarf.c:34
+.LM4:
+.LVL1:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	subl	$12, %esp
+.LCFI0:
+	# typeddwarf.c:53
+.LM5:
+	movl	vv, %eax
+	# typeddwarf.c:54
+.LM6:
+	fnstcw	6(%esp)
+	# typeddwarf.c:34
+.LM7:
+	flds	40(%esp)
+.LVL2:
+	# typeddwarf.c:54
+.LM8:
+	fldl	16(%esp)
+	# typeddwarf.c:53
+.LM9:
+	addl	$1, %eax
+	movl	%eax, vv
+	# typeddwarf.c:54
+.LM10:
+	movzwl	6(%esp), %eax
+	movb	$12, %ah
+	movw	%ax, 4(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	# typeddwarf.c:55
+.LM11:
+	fldl	24(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:54
+.LM12:
+	movl	%eax, vv
+	# typeddwarf.c:55
+.LM13:
+	movl	(%esp), %eax
+	# typeddwarf.c:56
+.LM14:
+	fldl	32(%esp)
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:55
+.LM15:
+	movl	%eax, vv
+	# typeddwarf.c:56
+.LM16:
+	movl	(%esp), %eax
+	# typeddwarf.c:57
+.LM17:
+	fldcw	4(%esp)
+	fistl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:56
+.LM18:
+	movl	%eax, vv
+	# typeddwarf.c:57
+.LM19:
+	movl	(%esp), %eax
+	# typeddwarf.c:58
+.LM20:
+	flds	44(%esp)
+	# typeddwarf.c:57
+.LM21:
+	movl	%eax, vv
+	# typeddwarf.c:58
+.LM22:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:59
+.LM23:
+	movl	48(%esp), %eax
+	# typeddwarf.c:63
+.LM24:
+	fldcw	4(%esp)
+	fistpl	(%esp)
+	fldcw	6(%esp)
+	# typeddwarf.c:59
+.LM25:
+	movl	%eax, vv
+	# typeddwarf.c:60
+.LM26:
+	movl	52(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:61
+.LM27:
+	movl	56(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:62
+.LM28:
+	movl	64(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:63
+.LM29:
+	movl	(%esp), %eax
+	movl	%eax, vv
+	# typeddwarf.c:64
+.LM30:
+	addl	$12, %esp
+.LCFI1:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE1:
+	.size	f2, .-f2
+	.p2align 4,,15
+	.globl	f3
+	.type	f3, @function
+f3:
+.LFB2:
+	# typeddwarf.c:68
+.LM31:
+.LVL3:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:73
+.LM32:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:74
+.LM33:
+	ret
+.LFE2:
+	.size	f3, .-f3
+	.p2align 4,,15
+	.globl	f4
+	.type	f4, @function
+f4:
+.LFB3:
+	# typeddwarf.c:78
+.LM34:
+.LVL4:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	# typeddwarf.c:82
+.LM35:
+	movl	vv, %eax
+	addl	$1, %eax
+	movl	%eax, vv
+# SUCC: EXIT [100.0%] 
+	# typeddwarf.c:83
+.LM36:
+	ret
+.LFE3:
+	.size	f4, .-f4
+	.section	.text.startup,"ax",@progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, @function
+main:
+.LFB4:
+	# typeddwarf.c:87
+.LM37:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (fallthru)
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	pushl	%esi
+.LCFI4:
+	# typeddwarf.c:88
+.LM38:
+	movl	$0x40a00000, %esi
+	# typeddwarf.c:87
+.LM39:
+	pushl	%ebx
+.LCFI5:
+	# typeddwarf.c:88
+.LM40:
+	movl	$0x40800000, %ebx
+	# typeddwarf.c:87
+.LM41:
+	andl	$-16, %esp
+	subl	$112, %esp
+.LCFI6:
+	# typeddwarf.c:88
+.LM42:
+	flds	.LC3
+	fstl	16(%esp)
+	movl	%esi, 28(%esp)
+	flds	.LC4
+	fstl	8(%esp)
+	movl	%ebx, 24(%esp)
+	fld1
+	fstl	(%esp)
+	movl	$9, 48(%esp)
+	fstps	64(%esp)
+	fstps	80(%esp)
+	movl	$0, 52(%esp)
+	fstps	96(%esp)
+	movl	$8, 40(%esp)
+	movl	$0, 44(%esp)
+	movl	$7, 36(%esp)
+	movl	$6, 32(%esp)
+	call	f1
+.LVL5:
+	# typeddwarf.c:89
+.LM43:
+	movl	%esi, 28(%esp)
+	movl	%ebx, 24(%esp)
+	movl	$9, 48(%esp)
+	movl	$0, 52(%esp)
+	movl	$8, 40(%esp)
+	flds	96(%esp)
+	fstpl	16(%esp)
+	movl	$0, 44(%esp)
+	flds	80(%esp)
+	fstpl	8(%esp)
+	movl	$7, 36(%esp)
+	flds	64(%esp)
+	fstpl	(%esp)
+	movl	$6, 32(%esp)
+	call	f2
+.LVL6:
+	# typeddwarf.c:90
+.LM44:
+	movl	$4, 20(%esp)
+	movl	$3, 12(%esp)
+	movl	$0, 16(%esp)
+	movl	$2, 8(%esp)
+	movl	$1, (%esp)
+	movl	$0, 4(%esp)
+	call	f3
+.LVL7:
+	# typeddwarf.c:91
+.LM45:
+	movl	$640, 16(%esp)
+	movl	$0, 20(%esp)
+	movl	$0, 24(%esp)
+	movl	$809369600, 28(%esp)
+	movl	$160, 4(%esp)
+	movl	$832569344, 8(%esp)
+	movl	$838860880, (%esp)
+	call	f4
+.LVL8:
+	# typeddwarf.c:93
+.LM46:
+	leal	-8(%ebp), %esp
+	xorl	%eax, %eax
+	popl	%ebx
+.LCFI7:
+	popl	%esi
+.LCFI8:
+	popl	%ebp
+.LCFI9:
+# SUCC: EXIT [100.0%] 
+	ret
+.LFE4:
+	.size	main, .-main
+	.comm	vv,4,4
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align 4
+.LC3:
+	.long	1077936128
+	.align 4
+.LC4:
+	.long	1073741824
+#APP
+	.section	.debug_frame,"",@progbits
+.Lframe0:
+	.long	.LECIE0-.LSCIE0	# Length of Common Information Entry
+.LSCIE0:
+	.long	0xffffffff	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE0:
+.LSFDE0:
+	.long	.LEFDE0-.LASFDE0	# FDE Length
+.LASFDE0:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE0:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE2:
+.LSFDE4:
+	.long	.LEFDE4-.LASFDE4	# FDE Length
+.LASFDE4:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE4:
+.LSFDE6:
+	.long	.LEFDE6-.LASFDE6	# FDE Length
+.LASFDE6:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE6:
+.LSFDE8:
+	.long	.LEFDE8-.LASFDE8	# FDE Length
+.LASFDE8:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE8:
+#NO_APP
+#APP
+	.section	.eh_frame,"aw",@progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.long	0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0x8	# CIE RA Column
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x1
+	.align 4
+.LECIE1:
+.LSFDE11:
+	.long	.LEFDE11-.LASFDE11	# FDE Length
+.LASFDE11:
+	.long	.LASFDE11-.Lframe1	# FDE CIE offset
+	.long	.LFB0	# FDE initial location
+	.long	.LFE0-.LFB0	# FDE address range
+	.align 4
+.LEFDE11:
+.LSFDE13:
+	.long	.LEFDE13-.LASFDE13	# FDE Length
+.LASFDE13:
+	.long	.LASFDE13-.Lframe1	# FDE CIE offset
+	.long	.LFB1	# FDE initial location
+	.long	.LFE1-.LFB1	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI0-.LFB1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x10
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI1-.LCFI0
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE13:
+.LSFDE15:
+	.long	.LEFDE15-.LASFDE15	# FDE Length
+.LASFDE15:
+	.long	.LASFDE15-.Lframe1	# FDE CIE offset
+	.long	.LFB2	# FDE initial location
+	.long	.LFE2-.LFB2	# FDE address range
+	.align 4
+.LEFDE15:
+.LSFDE17:
+	.long	.LEFDE17-.LASFDE17	# FDE Length
+.LASFDE17:
+	.long	.LASFDE17-.Lframe1	# FDE CIE offset
+	.long	.LFB3	# FDE initial location
+	.long	.LFE3-.LFB3	# FDE address range
+	.align 4
+.LEFDE17:
+.LSFDE19:
+	.long	.LEFDE19-.LASFDE19	# FDE Length
+.LASFDE19:
+	.long	.LASFDE19-.Lframe1	# FDE CIE offset
+	.long	.LFB4	# FDE initial location
+	.long	.LFE4-.LFB4	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI2-.LFB4
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI4-.LCFI3
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI5-.LCFI4
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI7-.LCFI5
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI9-.LCFI8
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0x4
+	.uleb128 0x4
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.align 4
+.LEFDE19:
+#NO_APP
+	.text
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x64e	# Length of Compilation Unit Info
+	.value	0x2	# DWARF version number
+	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+	.byte	0x4	# Pointer Size (in bytes)
+	.uleb128 0x1	# (DIE (0xb) DW_TAG_compile_unit)
+	.long	.LASF5	# DW_AT_producer: "GNU C 4.7.0 20110504 (experimental)"
+	.byte	0x1	# DW_AT_language
+	.long	.LASF6	# DW_AT_name: "typeddwarf.c"
+	.long	.LASF7	# DW_AT_comp_dir: "/usr/src/gcc/obj/gcc"
+	.long	.Ldebug_ranges0+0	# DW_AT_ranges
+	.long	0	# DW_AT_low_pc
+	.long	0	# DW_AT_entry_pc
+	.long	.Ldebug_line0	# DW_AT_stmt_list
+	.uleb128 0x2	# (DIE (0x29) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF0	# DW_AT_name: "double"
+	.uleb128 0x2	# (DIE (0x30) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x4	# DW_AT_encoding
+	.long	.LASF1	# DW_AT_name: "float"
+	.uleb128 0x2	# (DIE (0x37) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.long	.LASF2	# DW_AT_name: "long long int"
+	.uleb128 0x3	# (DIE (0x3e) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.ascii "int\0"	# DW_AT_name
+	.uleb128 0x2	# (DIE (0x45) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF3	# DW_AT_name: "unsigned int"
+	.uleb128 0x2	# (DIE (0x4c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0x7	# DW_AT_encoding
+	.long	.LASF4	# DW_AT_name: "long long unsigned int"
+	.uleb128 0x4	# (DIE (0x53) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f1\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB0	# DW_AT_low_pc
+	.long	.LFE0	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x232	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x6b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x77) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x83) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x8f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x9b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0xa7) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0xb3) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0xbf) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0xcb) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x9	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0xd7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xb	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xe9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xc	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0xfd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0xe	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x6	# (DIE (0x109) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x10	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x11d) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x11	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x12f) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x12	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x141) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x13	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x153) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x14	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x167) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x15	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x179) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x16	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x18d) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x17	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x19f) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x18	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1b1) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x19	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1cf) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1a	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x1f1) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x213) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x1c	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x53
+	.uleb128 0x7	# (DIE (0x232) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f2\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB1	# DW_AT_low_pc
+	.long	.LFE1	# DW_AT_high_pc
+	.long	.LLST0	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x40a	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x24b) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x257) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x263) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x5	# (DIE (0x26f) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.uleb128 0x5	# (DIE (0x27b) DW_TAG_formal_parameter)
+	.ascii "e\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.uleb128 0x5	# (DIE (0x287) DW_TAG_formal_parameter)
+	.ascii "f\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.uleb128 0x5	# (DIE (0x293) DW_TAG_formal_parameter)
+	.ascii "g\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.uleb128 0x5	# (DIE (0x29f) DW_TAG_formal_parameter)
+	.ascii "h\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 40
+	.uleb128 0x5	# (DIE (0x2ab) DW_TAG_formal_parameter)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x21	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 48
+	.uleb128 0x6	# (DIE (0x2b7) DW_TAG_variable)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x23	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2c9) DW_TAG_variable)
+	.ascii "l\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x24	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf9	# DW_OP_GNU_reinterpret
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x2dd) DW_TAG_variable)
+	.ascii "m\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x26	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x2e9) DW_TAG_variable)
+	.ascii "n\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x28	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x2f2) DW_TAG_variable)
+	.ascii "o\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x29	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.uleb128 0x6	# (DIE (0x2fb) DW_TAG_variable)
+	.ascii "p\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2a	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 36
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x30d) DW_TAG_variable)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2b	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 32
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x31f) DW_TAG_variable)
+	.ascii "r\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2c	# DW_AT_decl_line
+	.long	0x4c	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x4c
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x333) DW_TAG_variable)
+	.ascii "s\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2d	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x345) DW_TAG_variable)
+	.ascii "t\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2e	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0xa	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x359) DW_TAG_variable)
+	.ascii "u\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x2f	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x36b) DW_TAG_variable)
+	.ascii "v\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x30	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x8	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x30
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x37d) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x31	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3fd00000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x39b) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x32	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x24	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.byte	0x1c	# DW_OP_minus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0x78b58c40	# fp or vector constant word 0
+	.long	0x4415af1d	# fp or vector constant word 1
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3c9) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x33	# DW_AT_decl_line
+	.long	0x29	# DW_AT_type
+	.byte	0x18	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x401c0000	# fp or vector constant word 1
+	.byte	0x1e	# DW_OP_mul
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x29
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x3eb) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x34	# DW_AT_decl_line
+	.long	0x30	# DW_AT_type
+	.byte	0x14	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 24
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 28
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x4
+	.uleb128 0x30
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x30
+	.byte	0x4
+	.long	0x40400000	# fp or vector constant word 0
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x232
+	.uleb128 0x4	# (DIE (0x40a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f3\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB2	# DW_AT_low_pc
+	.long	.LFE2	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x4fd	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x422) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x42e) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.uleb128 0x5	# (DIE (0x43a) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.uleb128 0x5	# (DIE (0x446) DW_TAG_formal_parameter)
+	.ascii "d\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x43	# DW_AT_decl_line
+	.long	0x45	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.uleb128 0x6	# (DIE (0x452) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x45	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x16	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x12	# DW_OP_dup
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x16	# DW_OP_swap
+	.byte	0x14	# DW_OP_over
+	.byte	0x2b	# DW_OP_gt
+	.byte	0x28	# DW_OP_bra
+	.value	0x1
+	.byte	0x16	# DW_OP_swap
+	.byte	0x13	# DW_OP_drop
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x472) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x46	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x496) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x47	# DW_AT_decl_line
+	.long	0x37	# DW_AT_type
+	.byte	0x1a	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.uleb128 0x6	# (DIE (0x4ba) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x48	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.byte	0x38	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 8
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x7
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 20
+	.byte	0x6	# DW_OP_deref
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x45
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x37
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 12
+	.byte	0xf6	# DW_OP_GNU_deref_type
+	.byte	0x8
+	.uleb128 0x37
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x37
+	.byte	0x8
+	.quad	0x912345678
+	.byte	0x22	# DW_OP_plus
+	.byte	0xf7	# DW_OP_GNU_convert
+	.uleb128 0x3e
+	.byte	0x22	# DW_OP_plus
+	.byte	0x9f	# DW_OP_stack_value
+	.byte	0	# end of children of DIE 0x40a
+	.uleb128 0x4	# (DIE (0x4fd) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.ascii "f4\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	.LFB3	# DW_AT_low_pc
+	.long	.LFE3	# DW_AT_high_pc
+	.byte	0x2	# DW_AT_frame_base
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x555	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x515) DW_TAG_formal_parameter)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0x5	# (DIE (0x521) DW_TAG_formal_parameter)
+	.ascii "b\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 4
+	.uleb128 0x5	# (DIE (0x52d) DW_TAG_formal_parameter)
+	.ascii "c\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4d	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 16
+	.uleb128 0x8	# (DIE (0x539) DW_TAG_variable)
+	.ascii "w\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x4f	# DW_AT_decl_line
+	.long	0x555	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x542) DW_TAG_variable)
+	.ascii "x\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x50	# DW_AT_decl_line
+	.long	0x55c	# DW_AT_type
+	.uleb128 0x8	# (DIE (0x54b) DW_TAG_variable)
+	.ascii "y\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x51	# DW_AT_decl_line
+	.long	0x563	# DW_AT_type
+	.byte	0	# end of children of DIE 0x4fd
+	.uleb128 0x2	# (DIE (0x555) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF8	# DW_AT_name: "_Decimal32"
+	.uleb128 0x2	# (DIE (0x55c) DW_TAG_base_type)
+	.byte	0x8	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF9	# DW_AT_name: "_Decimal64"
+	.uleb128 0x2	# (DIE (0x563) DW_TAG_base_type)
+	.byte	0x10	# DW_AT_byte_size
+	.byte	0xf	# DW_AT_encoding
+	.long	.LASF10	# DW_AT_name: "_Decimal128"
+	.uleb128 0x9	# (DIE (0x56a) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.long	.LASF11	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x56	# DW_AT_decl_line
+	.long	0x3e	# DW_AT_type
+	.long	.LFB4	# DW_AT_low_pc
+	.long	.LFE4	# DW_AT_high_pc
+	.long	.LLST1	# DW_AT_frame_base
+	.byte	0x1	# DW_AT_GNU_all_call_sites
+	.long	0x62f	# DW_AT_sibling
+	.uleb128 0xa	# (DIE (0x587) DW_TAG_GNU_call_site)
+	.long	.LVL5	# DW_AT_low_pc
+	.long	0x53	# DW_AT_abstract_origin
+	.long	0x5e1	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x594) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 0
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x3ff00000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5a4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40000000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5b4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.byte	0xb	# DW_AT_GNU_call_site_value
+	.byte	0xf4	# DW_OP_GNU_const_type
+	.uleb128 0x29
+	.byte	0x8
+	.long	0	# fp or vector constant word 0
+	.long	0x40080000	# fp or vector constant word 1
+	.uleb128 0xb	# (DIE (0x5c4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5cc) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5d4) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x5da) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x587
+	.uleb128 0xa	# (DIE (0x5e1) DW_TAG_GNU_call_site)
+	.long	.LVL6	# DW_AT_low_pc
+	.long	0x232	# DW_AT_abstract_origin
+	.long	0x60b	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x5ee) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 24
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x3
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5f6) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 28
+	.byte	0x3	# DW_AT_GNU_call_site_value
+	.byte	0xf5	# DW_OP_GNU_regval_type
+	.uleb128 0x6
+	.uleb128 0x30
+	.uleb128 0xb	# (DIE (0x5fe) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 32
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x36	# DW_OP_lit6
+	.uleb128 0xb	# (DIE (0x604) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 36
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x37	# DW_OP_lit7
+	.byte	0	# end of children of DIE 0x5e1
+	.uleb128 0xa	# (DIE (0x60b) DW_TAG_GNU_call_site)
+	.long	.LVL7	# DW_AT_low_pc
+	.long	0x40a	# DW_AT_abstract_origin
+	.long	0x625	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x618) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x32	# DW_OP_lit2
+	.uleb128 0xb	# (DIE (0x61e) DW_TAG_GNU_call_site_parameter)
+	.byte	0x2	# DW_AT_location
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 20
+	.byte	0x1	# DW_AT_GNU_call_site_value
+	.byte	0x34	# DW_OP_lit4
+	.byte	0	# end of children of DIE 0x60b
+	.uleb128 0xc	# (DIE (0x625) DW_TAG_GNU_call_site)
+	.long	.LVL8	# DW_AT_low_pc
+	.long	0x4fd	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x56a
+	.uleb128 0xd	# (DIE (0x62f) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x1	# DW_AT_declaration
+	.uleb128 0xe	# (DIE (0x63b) DW_TAG_volatile_type)
+	.long	0x3e	# DW_AT_type
+	.uleb128 0xf	# (DIE (0x640) DW_TAG_variable)
+	.ascii "vv\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (typeddwarf.c)
+	.byte	0x5	# DW_AT_decl_line
+	.long	0x63b	# DW_AT_type
+	.byte	0x1	# DW_AT_external
+	.byte	0x5	# DW_AT_location
+	.byte	0x3	# DW_OP_addr
+	.long	vv
+	.byte	0	# end of children of DIE 0xb
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1	# (abbrev code)
+	.uleb128 0x11	# (TAG: DW_TAG_compile_unit)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x25	# (DW_AT_producer)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x13	# (DW_AT_language)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x1b	# (DW_AT_comp_dir)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x55	# (DW_AT_ranges)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x52	# (DW_AT_entry_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x10	# (DW_AT_stmt_list)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.byte	0
+	.byte	0
+	.uleb128 0x2	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.byte	0
+	.byte	0
+	.uleb128 0x3	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.byte	0
+	.byte	0
+	.uleb128 0x4	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x5	# (abbrev code)
+	.uleb128 0x5	# (TAG: DW_TAG_formal_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x6	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0x7	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x8	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x9	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xa	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xb	# (abbrev code)
+	.uleb128 0x410a	# (TAG: DW_TAG_GNU_call_site_parameter)
+	.byte	0	# DW_children_no
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.uleb128 0x2111	# (DW_AT_GNU_call_site_value)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.uleb128 0xc	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xd	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x3c	# (DW_AT_declaration)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.byte	0
+	.byte	0
+	.uleb128 0xe	# (abbrev code)
+	.uleb128 0x35	# (TAG: DW_TAG_volatile_type)
+	.byte	0	# DW_children_no
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0xf	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0xc	# (DW_FORM_flag)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0xa	# (DW_FORM_block1)
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.long	.LFB1	# Location list begin address (*.LLST0)
+	.long	.LCFI0	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI0	# Location list begin address (*.LLST0)
+	.long	.LCFI1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 16
+	.long	.LCFI1	# Location list begin address (*.LLST0)
+	.long	.LFE1	# Location list end address (*.LLST0)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST0)
+	.long	0	# Location list terminator end (*.LLST0)
+.LLST1:
+	.long	.LFB4	# Location list begin address (*.LLST1)
+	.long	.LCFI2	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI2	# Location list begin address (*.LLST1)
+	.long	.LCFI3	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.long	.LCFI3	# Location list begin address (*.LLST1)
+	.long	.LCFI9	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x75	# DW_OP_breg5
+	.sleb128 8
+	.long	.LCFI9	# Location list begin address (*.LLST1)
+	.long	.LFE4	# Location list end address (*.LLST1)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST1)
+	.long	0	# Location list terminator end (*.LLST1)
+	.section	.debug_aranges,"",@progbits
+	.long	0x24	# Length of Address Ranges Info
+	.value	0x2	# DWARF Version
+	.long	.Ldebug_info0	# Offset of Compilation Unit Info
+	.byte	0x4	# Size of Address
+	.byte	0	# Size of Segment Descriptor
+	.value	0	# Pad to 8 byte boundary
+	.value	0
+	.long	.Ltext0	# Address
+	.long	.Letext0-.Ltext0	# Length
+	.long	.LFB4	# Address
+	.long	.LFE4-.LFB4	# Length
+	.long	0
+	.long	0
+	.section	.debug_ranges,"",@progbits
+.Ldebug_ranges0:
+	.long	.Ltext0	# Offset 0
+	.long	.Letext0
+	.long	.LFB4	# Offset 0x8
+	.long	.LFE4
+	.long	0
+	.long	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.long	.LELT0-.LSLT0	# Length of Source Line Info
+.LSLT0:
+	.value	0x2	# DWARF Version
+	.long	.LELTP0-.LASLTP0	# Prolog Length
+.LASLTP0:
+	.byte	0x1	# Minimum Instruction Length
+	.byte	0x1	# Default is_stmt_start flag
+	.byte	0xf6	# Line Base Value (Special Opcodes)
+	.byte	0xf2	# Line Range Value (Special Opcodes)
+	.byte	0xd	# Special Opcode Base
+	.byte	0	# opcode: 0x1 has 0 args
+	.byte	0x1	# opcode: 0x2 has 1 args
+	.byte	0x1	# opcode: 0x3 has 1 args
+	.byte	0x1	# opcode: 0x4 has 1 args
+	.byte	0x1	# opcode: 0x5 has 1 args
+	.byte	0	# opcode: 0x6 has 0 args
+	.byte	0	# opcode: 0x7 has 0 args
+	.byte	0	# opcode: 0x8 has 0 args
+	.byte	0x1	# opcode: 0x9 has 1 args
+	.byte	0	# opcode: 0xa has 0 args
+	.byte	0	# opcode: 0xb has 0 args
+	.byte	0x1	# opcode: 0xc has 1 args
+	.byte	0	# End directory table
+	.ascii "typeddwarf.c\0"	# File Entry: 0x1
+	.uleb128 0
+	.uleb128 0
+	.uleb128 0
+	.byte	0	# End file name table
+.LELTP0:
+	.byte	0	# set address *.LM37
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM37
+	.byte	0x6d	# line 87
+	.byte	0	# set address *.LM38
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM38
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM39
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM39
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM40
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM40
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM41
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM41
+	.byte	0x16	# line 87
+	.byte	0	# set address *.LM42
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM42
+	.byte	0x18	# line 88
+	.byte	0	# set address *.LM43
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM43
+	.byte	0x18	# line 89
+	.byte	0	# set address *.LM44
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM44
+	.byte	0x18	# line 90
+	.byte	0	# set address *.LM45
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM45
+	.byte	0x18	# line 91
+	.byte	0	# set address *.LM46
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM46
+	.byte	0x19	# line 93
+	.byte	0	# set address *.LFE4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LFE4
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+	.byte	0	# set address *.LM1
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM1
+	.byte	0x20	# line 10
+	.byte	0	# set address *.LM2
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM2
+	.byte	0x2a	# line 29
+	.byte	0	# set address *.LM3
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM3
+	.byte	0x18	# line 30
+	.byte	0	# set address *.LM4
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM4
+	.byte	0x1b	# line 34
+	.byte	0	# set address *.LM5
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM5
+	.byte	0x2a	# line 53
+	.byte	0	# set address *.LM6
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM6
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM7
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM7
+	.byte	0x3	# advance to line 34
+	.sleb128 -20
+	.byte	0x1
+	.byte	0	# set address *.LM8
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM8
+	.byte	0x2b	# line 54
+	.byte	0	# set address *.LM9
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM9
+	.byte	0x16	# line 53
+	.byte	0	# set address *.LM10
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM10
+	.byte	0x18	# line 54
+	.byte	0	# set address *.LM11
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM11
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM12
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM12
+	.byte	0x16	# line 54
+	.byte	0	# set address *.LM13
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM13
+	.byte	0x18	# line 55
+	.byte	0	# set address *.LM14
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM14
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM15
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM15
+	.byte	0x16	# line 55
+	.byte	0	# set address *.LM16
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM16
+	.byte	0x18	# line 56
+	.byte	0	# set address *.LM17
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM17
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM18
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM18
+	.byte	0x16	# line 56
+	.byte	0	# set address *.LM19
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM19
+	.byte	0x18	# line 57
+	.byte	0	# set address *.LM20
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM20
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM21
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM21
+	.byte	0x16	# line 57
+	.byte	0	# set address *.LM22
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM22
+	.byte	0x18	# line 58
+	.byte	0	# set address *.LM23
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM23
+	.byte	0x18	# line 59
+	.byte	0	# set address *.LM24
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM24
+	.byte	0x1b	# line 63
+	.byte	0	# set address *.LM25
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM25
+	.byte	0x13	# line 59
+	.byte	0	# set address *.LM26
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM26
+	.byte	0x18	# line 60
+	.byte	0	# set address *.LM27
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM27
+	.byte	0x18	# line 61
+	.byte	0	# set address *.LM28
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM28
+	.byte	0x18	# line 62
+	.byte	0	# set address *.LM29
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM29
+	.byte	0x18	# line 63
+	.byte	0	# set address *.LM30
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM30
+	.byte	0x18	# line 64
+	.byte	0	# set address *.LM31
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM31
+	.byte	0x1b	# line 68
+	.byte	0	# set address *.LM32
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM32
+	.byte	0x1c	# line 73
+	.byte	0	# set address *.LM33
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM33
+	.byte	0x18	# line 74
+	.byte	0	# set address *.LM34
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM34
+	.byte	0x1b	# line 78
+	.byte	0	# set address *.LM35
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM35
+	.byte	0x1b	# line 82
+	.byte	0	# set address *.LM36
+	.uleb128 0x5
+	.byte	0x2
+	.long	.LM36
+	.byte	0x18	# line 83
+	.byte	0	# set address *.Letext0
+	.uleb128 0x5
+	.byte	0x2
+	.long	.Letext0
+	.byte	0	# end sequence
+	.uleb128 0x1
+	.byte	0x1
+.LELT0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF2:
+	.string	"long long int"
+.LASF3:
+	.string	"unsigned int"
+.LASF8:
+	.string	"_Decimal32"
+.LASF4:
+	.string	"long long unsigned int"
+.LASF11:
+	.string	"main"
+.LASF9:
+	.string	"_Decimal64"
+.LASF0:
+	.string	"double"
+.LASF10:
+	.string	"_Decimal128"
+.LASF7:
+	.string	"/usr/src/gcc/obj/gcc"
+.LASF1:
+	.string	"float"
+.LASF6:
+	.string	"typeddwarf.c"
+.LASF5:
+	.string	"GNU C 4.7.0 20110504 (experimental)"
+	.ident	"GCC: (GNU) 4.7.0 20110504 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
Index: testsuite/gdb.dwarf2/typeddwarf.c
===================================================================
RCS file: testsuite/gdb.dwarf2/typeddwarf.c
diff -N testsuite/gdb.dwarf2/typeddwarf.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/typeddwarf.c	12 May 2011 16:25:14 -0000
@@ -0,0 +1,93 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-g" } */
+
+typedef __SIZE_TYPE__ size_t;
+volatile int vv;
+extern void *memcpy (void *, const void *, size_t);
+
+__attribute__((noinline, noclone)) void
+f1 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 29 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 29 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 29 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { gdb-test 29 "n" "9" } } */
+  double o = h;			/* { dg-final { gdb-test 29 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 29 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 29 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 29 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 29 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 29 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 29 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 29 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 29 "w" "1" } } */
+  double x = a + b + 1.0;	/* { dg-final { gdb-test 29 "x" "4" } } */
+  double y = b + c + 2.0;	/* { dg-final { gdb-test 29 "y" "7" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 29 "z" "12" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f2 (double a, double b, double c, float d, float e, int f, unsigned int g, long long h, unsigned long long i)
+{
+  double j = d;			/* { dg-final { gdb-test 53 "j" "4" } } */
+  long long l;			/* { dg-final { gdb-test 53 "l" "4616189618054758400" } } */
+  memcpy (&l, &j, sizeof (l));
+  long long m;			/* { dg-final { gdb-test 53 "m" "4613937818241073152" } } */
+  memcpy (&m, &c, sizeof (l));
+  float n = i;			/* { dg-final { xfail-gdb-test 53 "n" "9" } } */
+  double o = h;			/* { dg-final { xfail-gdb-test 53 "o" "8" } } */
+  float p = g;			/* { dg-final { gdb-test 53 "p" "7" } } */
+  double q = f;			/* { dg-final { gdb-test 53 "q" "6" } } */
+  unsigned long long r = a;	/* { dg-final { gdb-test 53 "r" "1" } } */
+  long long s = c;		/* { dg-final { gdb-test 53 "s" "3" } } */
+  unsigned t = d;		/* { dg-final { gdb-test 53 "t" "4" } } */
+  int u = b;			/* { dg-final { gdb-test 53 "u" "2" } } */
+  float v = a;			/* { dg-final { gdb-test 53 "v" "1" } } */
+  double w = d / 4.0;		/* { dg-final { gdb-test 53 "w" "1" } } */
+  double x = a + b - 3 + 1.0e20;/* { dg-final { gdb-test 53 "x" "1e\\+20" } } */
+  double y = b + c * 7.0;	/* { dg-final { gdb-test 53 "y" "23" } } */
+  float z = d + e + 3.0f;	/* { dg-final { gdb-test 53 "z" "12" } } */
+  vv++;
+  vv = a;
+  vv = b;
+  vv = c;
+  vv = d;
+  vv = e;
+  vv = f;
+  vv = g;
+  vv = h;
+  vv = i;
+  vv = j;
+}
+
+__attribute__((noinline, noclone)) void
+f3 (long long a, int b, long long c, unsigned d)
+{
+  long long w = (a > d) ? a : d;/* { dg-final { gdb-test 73 "w" "4" } } */
+  long long x = a + b + 7;	/* { dg-final { gdb-test 73 "x" "10" } } */
+  long long y = c + d + 0x912345678LL;/* { dg-final { gdb-test 73 "y" "38960125567" } } */
+  int z = (x + y);		/* { dg-final { gdb-test 73 "z" "305419913" } } */
+  vv++;
+}
+
+__attribute__((noinline, noclone)) void
+f4 (_Decimal32 a, _Decimal64 b, _Decimal128 c)
+{
+  _Decimal32 w = a * 8.0DF + 6.0DF;/* { dg-final { xfail-gdb-test 82 "(int)w" "70" } } */
+  _Decimal64 x = b / 8.0DD - 6.0DD;/* { dg-final { xfail-gdb-test 82 "(int)x" "-4" } } */
+  _Decimal128 y = -c / 8.0DL;	/* { dg-final { xfail-gdb-test 82 "(int)y" "-8" } } */
+  vv++;
+}
+
+int
+main ()
+{
+  f1 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f2 (1.0, 2.0, 3.0, 4.0f, 5.0f, 6, 7, 8, 9);
+  f3 (1, 2, 3, 4);
+  f4 (8.0DF, 16.0DD, 64.0DL);
+  return 0;
+}
Index: testsuite/gdb.dwarf2/typeddwarf.exp
===================================================================
RCS file: testsuite/gdb.dwarf2/typeddwarf.exp
diff -N testsuite/gdb.dwarf2/typeddwarf.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/typeddwarf.exp	12 May 2011 16:25:14 -0000
@@ -0,0 +1,91 @@
+# Copyright 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib dwarf.exp
+
+set test "typeddwarf"
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if ![dwarf2_support] {
+    return 0  
+}
+
+# This test can only be run on x86 targets.
+if { ![istarget i?86-*] } {
+    return 0
+}
+
+if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+global tests
+set tests(_) -
+unset tests(_)
+
+proc gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 0]
+}
+
+proc xfail-gdb-test {line var value} {
+    global tests
+
+    lappend tests($line) [list $var $value 1]
+}
+
+proc scan_gdb_tests {} {
+    global srcdir subdir test
+
+    set file "$srcdir/$subdir/$test.c"
+
+    set fd [open "$file"]
+    while {![eof $fd]} {
+	set line [gets $fd]
+	if {! [regexp "\{ (gdb-test .+) \} \}" $line ignore test_cmd]} {
+	    continue
+	}
+
+	eval $test_cmd
+    }
+    close $fd
+}
+
+scan_gdb_tests
+
+foreach line [lsort [array names tests]] {
+    gdb_test "break typeddwarf.c:$line" "Breakpoint .*" \
+	"set breakpoint at typeddwarf.c:$line"
+    gdb_continue_to_breakpoint "continue to typeddwarf.c:$line"
+
+    foreach test $tests($line) {
+	set var [lindex $test 0]
+	set value [lindex $test 1]
+	set should_xfail [lindex $test 2]
+
+	if {$should_xfail} {
+	    setup_xfail *-*-*
+	}
+
+	gdb_test "print $var" \
+	    " = $value" \
+	    "check value of $var at typeddwarf.c:$line"
+    }
+}


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-11  0:15           ` Ulrich Weigand
  2011-05-11 14:59             ` Tom Tromey
@ 2011-05-12 19:32             ` Tom Tromey
  2011-05-16 15:50               ` Ulrich Weigand
  1 sibling, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-12 19:32 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:

Tom> Yes.  My understanding is that for new-style typed values, DW_OP_shr and
Tom> DW_OP_shra are actually the same -- the type indicates the operation to
Tom> perform.  But, for old-style values, we must cast to unsigned for
Tom> DW_OP_shr.

Ulrich> I see.  However, the code as implemented casts *all* signed values to
Ulrich> unsigned for DW_OP_shr, not just old-style values.  That's what got
Ulrich> me confused ...

I mentioned this on the GCC list and Jakub said that GCC actually emits
code assuming that the operation will always be unsigned.

So, I am reverting my change here.  Patch appended.

Tom

2011-05-12  Tom Tromey  <tromey@redhat.com>

	* dwarf2expr.c (execute_stack_op) <DW_OP_shr>: Unconditionally
	cast left-hand-side to unsigned.

Index: dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.58
diff -u -r1.58 dwarf2expr.c
--- dwarf2expr.c	12 May 2011 17:40:54 -0000	1.58
+++ dwarf2expr.c	12 May 2011 19:28:28 -0000
@@ -979,7 +979,7 @@
 	      case DW_OP_shr:
 		dwarf_require_integral (value_type (first));
 		dwarf_require_integral (value_type (second));
-		if (value_type (first) == address_type)
+		if (!TYPE_UNSIGNED (value_type (first)))
 		  {
 		    struct type *utype
 		      = get_unsigned_type (ctx->gdbarch, value_type (first));


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Regression: Re: RFC: implement typed DWARF stack
  2011-05-12 16:33                 ` Tom Tromey
@ 2011-05-13  7:52                   ` Jan Kratochvil
  2011-05-13 15:44                     ` Tom Tromey
  2011-05-13 17:17                     ` Tom Tromey
  0 siblings, 2 replies; 25+ messages in thread
From: Jan Kratochvil @ 2011-05-13  7:52 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Ulrich Weigand, gdb-patches

On Thu, 12 May 2011 18:32:19 +0200, Tom Tromey wrote:
> Here is what I am checking in.

This is 15MB .sum diff of regressions, nothing works now.

ff577da70c2f9064dce1abb1742fabe4d93edabb is the first bad commit
commit ff577da70c2f9064dce1abb1742fabe4d93edabb
Author: Tom Tromey <tromey@redhat.com>
Date:   Thu May 12 17:40:52 2011 +0000

    gdb
    	PR gdb/12617:
[...]


+# This test can only be run on x86 targets.
+if { ![istarget i?86-*] } {
+    return 0
+}

It will not run on x86_64 box with -m32 while it could, I would prefer there
also x86_64 target with is_ilp32_target conditional.


Everything incl. gdb.dwarf2/typeddwarf.exp crashes also on fedora-15-i386, at
least when built with:
	http://git.jankratochvil.net/?p=nethome.git;a=blob_plain;f=bin/errs12;hb=HEAD


Regards,
Jan


Invalid read of size 4
   at: value_type (value.c:742)
   by: print_frame_args (stack.c:363)
   by: print_args_stub (stack.c:434)
   by: catch_errors (exceptions.c:506)
   by: print_frame (stack.c:828)
   by: print_frame_info (stack.c:599)
   by: print_stack_frame_stub (stack.c:101)
   by: catch_errors (exceptions.c:506)
   by: print_stack_frame (stack.c:149)
   by: normal_stop (infrun.c:5807)
   by: proceed (infrun.c:2209)
   by: continue_1 (infcmd.c:701)
   by: continue_command (infcmd.c:793)
   by: do_cfunc (cli-decode.c:67)
   by: cmd_func (cli-decode.c:1777)
   by: execute_command (top.c:435)
   by: command_handler (event-top.c:499)
   by: command_line_handler (event-top.c:704)
   by: rl_callback_read_char (callback.c:220)
   by: rl_callback_read_char_wrapper (event-top.c:177)
   by: stdin_event_handler (event-top.c:434)
   by: handle_file_event (event-loop.c:831)
   by: process_event (event-loop.c:402)
   by: gdb_do_one_event (event-loop.c:455)
   by: catch_errors (exceptions.c:506)
   by: tui_command_loop (tui-interp.c:172)
   by: current_interp_command_loop (interps.c:291)
   by: captured_command_loop (main.c:230)
   by: catch_errors (exceptions.c:506)
   by: captured_main (main.c:937)
   by: catch_errors (exceptions.c:506)
   by: gdb_main (main.c:946)
   by: main (gdb.c:35)
 Address 0xc6c0b18 is 64 bytes inside a block of size 108 free'd
   at: free (vg_replace_malloc.c:366)
   by: xfree (utils.c:1549)
   by: value_free (value.c:1175)
   by: value_free_to_mark (value.c:1189)
   by: free_dwarf_expr_context (dwarf2expr.c:116)
   by: free_dwarf_expr_context_cleanup (dwarf2expr.c:127)
   by: do_my_cleanups (utils.c:499)
   by: do_cleanups (utils.c:481)
   by: dwarf2_evaluate_loc_desc_full (dwarf2loc.c:1251)
   by: dwarf2_evaluate_loc_desc (dwarf2loc.c:1264)
   by: locexpr_read_variable (dwarf2loc.c:2146)
   by: read_var_value (findvar.c:555)
   by: print_frame_args (stack.c:361)
   by: print_args_stub (stack.c:434)
   by: catch_errors (exceptions.c:506)
   by: print_frame (stack.c:828)
   by: print_frame_info (stack.c:599)
   by: print_stack_frame_stub (stack.c:101)
   by: catch_errors (exceptions.c:506)
   by: print_stack_frame (stack.c:149)
   by: normal_stop (infrun.c:5807)
   by: proceed (infrun.c:2209)
   by: continue_1 (infcmd.c:701)
   by: continue_command (infcmd.c:793)
   by: do_cfunc (cli-decode.c:67)
   by: cmd_func (cli-decode.c:1777)
   by: execute_command (top.c:435)
   by: command_handler (event-top.c:499)
   by: command_line_handler (event-top.c:704)
   by: rl_callback_read_char (callback.c:220)
   by: rl_callback_read_char_wrapper (event-top.c:177)
   by: stdin_event_handler (event-top.c:434)
   by: handle_file_event (event-loop.c:831)
   by: process_event (event-loop.c:402)
   by: gdb_do_one_event (event-loop.c:455)
   by: catch_errors (exceptions.c:506)
   by: tui_command_loop (tui-interp.c:172)
   by: current_interp_command_loop (interps.c:291)
   by: captured_command_loop (main.c:230)
   by: catch_errors (exceptions.c:506)
   by: captured_main (main.c:937)
   by: catch_errors (exceptions.c:506)
   by: gdb_main (main.c:946)
   by: main (gdb.c:35)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Regression: Re: RFC: implement typed DWARF stack
  2011-05-13  7:52                   ` Regression: " Jan Kratochvil
@ 2011-05-13 15:44                     ` Tom Tromey
  2011-05-15  8:26                       ` gdbindex crash: " Jan Kratochvil
  2011-05-13 17:17                     ` Tom Tromey
  1 sibling, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-13 15:44 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Ulrich Weigand, gdb-patches

Jan> This is 15MB .sum diff of regressions, nothing works now.

Yeah, I apologize for that.  I didn't run the final version through the
tester, neglecting that I had made a major change.

Here is the fix I am checking in.  The bug was that we were calling
value_free_to_mark but then using values from the value list.  The fix
is to be more careful about ordering cleanups.

Built and regtested on the buildbot.

Jan> +# This test can only be run on x86 targets.
Jan> +if { ![istarget i?86-*] } {
Jan> +    return 0
Jan> +}

Jan> It will not run on x86_64 box with -m32 while it could, I would
Jan> prefer there also x86_64 target with is_ilp32_target conditional.

I will make this change separately.

Tom

2011-05-13  Tom Tromey  <tromey@redhat.com>

	* utils.c (do_value_free): New function.
	(make_cleanup_value_free): Likewise.
	* dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Handle value
	freeing correctly.
	(dwarf2_loc_desc_needs_frame): Call
	make_cleanup_value_free_to_mark.
	* dwarf2expr.h (struct dwarf_expr_context) <mark>: Remove field.
	* dwarf2expr.c (free_dwarf_expr_context): Don't call
	value_free_to_mark.
	(new_dwarf_expr_context): Don't call value_mark.
	* dwarf2-frame.c (execute_stack_op): Call
	make_cleanup_value_free_to_mark.
	* defs.h (make_cleanup_value_free): Declare.

diff --git a/gdb/defs.h b/gdb/defs.h
index 771d3ad..38a2fcf 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -362,6 +362,7 @@ extern struct cleanup *
   make_cleanup_restore_ui_file (struct ui_file **variable);
 
 extern struct cleanup *make_cleanup_value_free_to_mark (struct value *);
+extern struct cleanup *make_cleanup_value_free (struct value *);
 
 extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
 
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 4e4e6d9..fe48713 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -402,6 +402,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
 
   ctx = new_dwarf_expr_context ();
   old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+  make_cleanup_value_free_to_mark (value_mark ());
 
   ctx->gdbarch = get_frame_arch (this_frame);
   ctx->addr_size = addr_size;
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 0c0760b..b42f289 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -104,7 +104,6 @@ new_dwarf_expr_context (void)
   retval->num_pieces = 0;
   retval->pieces = 0;
   retval->max_recursion_depth = 0x100;
-  retval->mark = value_mark ();
   return retval;
 }
 
@@ -113,7 +112,6 @@ new_dwarf_expr_context (void)
 void
 free_dwarf_expr_context (struct dwarf_expr_context *ctx)
 {
-  value_free_to_mark (ctx->mark);
   xfree (ctx->stack);
   xfree (ctx->pieces);
   xfree (ctx);
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index 281c65b..676b54b 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -81,10 +81,6 @@ struct dwarf_expr_context
   /* Offset used to relocate DW_OP_addr argument.  */
   CORE_ADDR offset;
 
-  /* The evaluator is value-based, and frees values up to this point
-     when the expression context is destroyed.  */
-  struct value *mark;
-
   /* An opaque argument provided by the caller, which will be passed
      to all of the callback functions.  */
   void *baton;
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 04f16e9..64cc5e5 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1086,7 +1086,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   struct value *retval;
   struct dwarf_expr_baton baton;
   struct dwarf_expr_context *ctx;
-  struct cleanup *old_chain;
+  struct cleanup *old_chain, *value_chain;
   struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
   volatile struct gdb_exception ex;
 
@@ -1106,6 +1106,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
   ctx = new_dwarf_expr_context ();
   old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+  value_chain = make_cleanup_value_free_to_mark (value_mark ());
 
   ctx->gdbarch = get_objfile_arch (objfile);
   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
@@ -1128,6 +1129,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
     {
       if (ex.error == NOT_AVAILABLE_ERROR)
 	{
+	  do_cleanups (old_chain);
 	  retval = allocate_value (type);
 	  mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type));
 	  return retval;
@@ -1150,6 +1152,9 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
       c = allocate_piece_closure (per_cu, ctx->num_pieces, ctx->pieces,
 				  ctx->addr_size);
+      /* We must clean up the value chain after creating the piece
+	 closure but before allocating the result.  */
+      do_cleanups (value_chain);
       retval = allocate_computed_value (type, &pieced_value_funcs, c);
       VALUE_FRAME_ID (retval) = frame_id;
       set_value_offset (retval, byte_offset);
@@ -1166,6 +1171,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
 	    if (byte_offset != 0)
 	      error (_("cannot use offset on synthetic pointer to register"));
+	    do_cleanups (value_chain);
 	    if (gdb_regnum != -1)
 	      retval = value_from_register (type, gdb_regnum, frame);
 	    else
@@ -1179,6 +1185,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	    CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
 	    int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
 
+	    do_cleanups (value_chain);
 	    retval = allocate_value_lazy (type);
 	    VALUE_LVAL (retval) = lval_memory;
 	    if (in_stack_memory)
@@ -1201,6 +1208,13 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	    val_bytes += byte_offset;
 	    n -= byte_offset;
 
+	    /* Preserve VALUE because we are going to free values back
+	       to the mark, but we still need the value contents
+	       below.  */
+	    value_incref (value);
+	    do_cleanups (value_chain);
+	    make_cleanup_value_free (value);
+
 	    retval = allocate_value (type);
 	    contents = value_contents_raw (retval);
 	    if (n > TYPE_LENGTH (type))
@@ -1218,6 +1232,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	    if (byte_offset + TYPE_LENGTH (type) > n)
 	      invalid_synthetic_pointer ();
 
+	    do_cleanups (value_chain);
 	    retval = allocate_value (type);
 	    contents = value_contents_raw (retval);
 
@@ -1231,6 +1246,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	  break;
 
 	case DWARF_VALUE_OPTIMIZED_OUT:
+	  do_cleanups (value_chain);
 	  retval = allocate_value (type);
 	  VALUE_LVAL (retval) = not_lval;
 	  set_value_optimized_out (retval, 1);
@@ -1353,6 +1369,7 @@ dwarf2_loc_desc_needs_frame (const gdb_byte *data, unsigned short size,
 
   ctx = new_dwarf_expr_context ();
   old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+  make_cleanup_value_free_to_mark (value_mark ());
 
   ctx->gdbarch = get_objfile_arch (objfile);
   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
diff --git a/gdb/utils.c b/gdb/utils.c
index 3e4a54d..6fd220a 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -448,6 +448,22 @@ make_cleanup_value_free_to_mark (struct value *mark)
   return make_my_cleanup (&cleanup_chain, do_value_free_to_mark, mark);
 }
 
+/* Helper for make_cleanup_value_free.  */
+
+static void
+do_value_free (void *value)
+{
+  value_free (value);
+}
+
+/* Free VALUE.  */
+
+struct cleanup *
+make_cleanup_value_free (struct value *value)
+{
+  return make_my_cleanup (&cleanup_chain, do_value_free, value);
+}
+
 struct cleanup *
 make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
 		  void *arg,  void (*free_arg) (void *))


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Regression: Re: RFC: implement typed DWARF stack
  2011-05-13  7:52                   ` Regression: " Jan Kratochvil
  2011-05-13 15:44                     ` Tom Tromey
@ 2011-05-13 17:17                     ` Tom Tromey
  2011-05-13 17:34                       ` Jan Kratochvil
  1 sibling, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-13 17:17 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Ulrich Weigand, gdb-patches

Jan> +# This test can only be run on x86 targets.
Jan> +if { ![istarget i?86-*] } {
Jan> +    return 0
Jan> +}

Jan> It will not run on x86_64 box with -m32 while it could, I would
Jan> prefer there also x86_64 target with is_ilp32_target conditional.

Here is what I am checking in for this.

This adds a new proc, 'is_x86_like_target', to do this check.  Then it
updates gdb.dwarf2 to use it.  This also fixes a bug in dw2-restore.exp,
which needs LP64.

I tested this by running --directory=gdb.dwarf2 with and without -m32 on
x86-64, and natively on x86.

Tom

b/gdb/testsuite/ChangeLog:
2011-05-13  Tom Tromey  <tromey@redhat.com>

	* lib/gdb.exp (is_x86_like_target): New proc.
	* gdb.dwarf2/watch-notconst.exp: Use is_x86_like_target.
	* gdb.dwarf2/valop.exp: Use is_x86_like_target.
	* gdb.dwarf2/typeddwarf.exp: Use is_x86_like_target.  Pass
	-nostdlib to compiler.
	* gdb.dwarf2/typeddwarf.S (_start): Rename from 'main'.
	* gdb.dwarf2/pieces.exp: Use is_x86_like_target.
	* gdb.dwarf2/implptr.exp: Use is_x86_like_target.
	* gdb.dwarf2/dw2-restore.exp: Check for LP64.
	* gdb.dwarf2/callframecfa.exp: Use is_x86_like_target.

diff --git a/gdb/testsuite/gdb.dwarf2/callframecfa.exp b/gdb/testsuite/gdb.dwarf2/callframecfa.exp
index 42c02b0..f88348a 100644
--- a/gdb/testsuite/gdb.dwarf2/callframecfa.exp
+++ b/gdb/testsuite/gdb.dwarf2/callframecfa.exp
@@ -21,7 +21,7 @@ if {![dwarf2_support]} {
     return 0  
 }
 # This test can only be run on x86 targets.
-if {![istarget i?86-*]} {
+if {![is_x86_like_target]} {
     return 0  
 }
 
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-restore.exp b/gdb/testsuite/gdb.dwarf2/dw2-restore.exp
index a04b029..e64c5e5 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-restore.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-restore.exp
@@ -16,7 +16,7 @@
 # Test handling of DW_CFA_restore_state.
 
 # This test can only be run on x86_64 targets.
-if {![istarget x86_64-*]} {
+if {![istarget x86_64-*] || ![is_lp64_target]} {
     return 0  
 }
 set testfile "dw2-restore"
diff --git a/gdb/testsuite/gdb.dwarf2/implptr.exp b/gdb/testsuite/gdb.dwarf2/implptr.exp
index 5bf894b..e9348e40 100644
--- a/gdb/testsuite/gdb.dwarf2/implptr.exp
+++ b/gdb/testsuite/gdb.dwarf2/implptr.exp
@@ -21,7 +21,7 @@ if {![dwarf2_support]} {
     return 0  
 }
 # This test can only be run on x86 targets.
-if {![istarget i?86-*]} {
+if {![is_x86_like_target]} {
     return 0  
 }
 
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.exp b/gdb/testsuite/gdb.dwarf2/pieces.exp
index 73780d8..a2e6c04 100644
--- a/gdb/testsuite/gdb.dwarf2/pieces.exp
+++ b/gdb/testsuite/gdb.dwarf2/pieces.exp
@@ -20,7 +20,7 @@ if {![dwarf2_support]} {
     return 0  
 }
 # This test can only be run on x86 targets.
-if {![istarget i?86-*]} {
+if {![is_x86_like_target]} {
     return 0  
 }
 
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.S b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
index a46da14..2ab7444 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.S
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.S
@@ -212,9 +212,9 @@ f4:
 	.size	f4, .-f4
 	.section	.text.startup,"ax",@progbits
 	.p2align 4,,15
-	.globl	main
-	.type	main, @function
-main:
+	.globl	_start
+	.type	_start, @function
+_start:
 .LFB4:
 	# typeddwarf.c:87
 .LM37:
@@ -314,7 +314,7 @@ main:
 # SUCC: EXIT [100.0%] 
 	ret
 .LFE4:
-	.size	main, .-main
+	.size	_start, .-_start
 	.comm	vv,4,4
 	.section	.rodata.cst4,"aM",@progbits,4
 	.align 4
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
index bddcc18..e6a420a 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -23,11 +23,11 @@ if ![dwarf2_support] {
 }
 
 # This test can only be run on x86 targets.
-if { ![istarget i?86-*] } {
+if { ![is_x86_like_target] } {
     return 0
 }
 
-if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug}] } {
+if { [prepare_for_testing "${test}.exp" "${test}" ${test}.S {nodebug additional_flags=-nostdlib}] } {
     return -1
 }
 
diff --git a/gdb/testsuite/gdb.dwarf2/valop.exp b/gdb/testsuite/gdb.dwarf2/valop.exp
index f7343ef..4dc7434 100644
--- a/gdb/testsuite/gdb.dwarf2/valop.exp
+++ b/gdb/testsuite/gdb.dwarf2/valop.exp
@@ -21,7 +21,7 @@ if {![dwarf2_support]} {
     return 0  
 }
 # This test can only be run on x86 targets.
-if {![istarget i?86-*]} {
+if {![is_x86_like_target]} {
     return 0  
 }
 
diff --git a/gdb/testsuite/gdb.dwarf2/watch-notconst.exp b/gdb/testsuite/gdb.dwarf2/watch-notconst.exp
index f4e2d52..da13868 100644
--- a/gdb/testsuite/gdb.dwarf2/watch-notconst.exp
+++ b/gdb/testsuite/gdb.dwarf2/watch-notconst.exp
@@ -22,7 +22,7 @@ if ![dwarf2_support] {
 }
 
 # This test can only be run on x86 targets.
-if { ![istarget i?86-*] } {
+if { ![is_x86_like_target] } {
     return 0
 }
 
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 17ea0b7..531120c 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1563,6 +1563,17 @@ proc is_lp64_target {} {
     return [set is_lp64_target_saved($board) 1]
 }
 
+# Return 1 if this target is an x86 or x86-64 with -m32.
+proc is_x86_like_target {} {
+    if {[istarget i?86-*]} {
+	return 1
+    }
+    if {![istarget "x86_64-*-*"]} {
+	return 0
+    }
+    return [is_ilp32_target]
+}
+
 # Run a test on the target to see if it supports vmx hardware.  Return 0 if so, 
 # 1 if it does not.  Based on 'check_vmx_hw_available' from the GCC testsuite.
 


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Regression: Re: RFC: implement typed DWARF stack
  2011-05-13 17:17                     ` Tom Tromey
@ 2011-05-13 17:34                       ` Jan Kratochvil
  0 siblings, 0 replies; 25+ messages in thread
From: Jan Kratochvil @ 2011-05-13 17:34 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Ulrich Weigand, gdb-patches

On Fri, 13 May 2011 19:16:38 +0200, Tom Tromey wrote:
> Here is what I am checking in for this.
> 
> This adds a new proc, 'is_x86_like_target', to do this check.  Then it
> updates gdb.dwarf2 to use it.  This also fixes a bug in dw2-restore.exp,
> which needs LP64.

It works great, thanks for doing it, it fixes both a compilation error and
extends a single-arch testsuite run coverage.


Thanks,
Jan


^ permalink raw reply	[flat|nested] 25+ messages in thread

* gdbindex crash: Re: Regression: Re: RFC: implement typed DWARF stack
  2011-05-13 15:44                     ` Tom Tromey
@ 2011-05-15  8:26                       ` Jan Kratochvil
  2011-05-16 17:37                         ` Tom Tromey
  0 siblings, 1 reply; 25+ messages in thread
From: Jan Kratochvil @ 2011-05-15  8:26 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Ulrich Weigand, gdb-patches

On Fri, 13 May 2011 17:43:43 +0200, Tom Tromey wrote:
> I didn't run the final version through the
> tester, neglecting that I had made a major change.
> 
> Here is the fix I am checking in.

The new testcase crashes with .gdb_index:
	print j
	ERROR: Process no longer exists
	UNRESOLVED: gdb.dwarf2/typeddwarf.exp: check value of j at typeddwarf.c:29


Thanks,
Jan


#0  0x08365f0f in follow_die_offset (offset=48, ref_cu=0xffdec0a4) at dwarf2read.c:13555
13555	  gdb_assert (cu->per_cu != NULL);
(gdb) p cu
$1 = (struct dwarf2_cu *) 0x0
(gdb) bt
#0  in follow_die_offset (offset=48, ref_cu=0xffdec0a4) at dwarf2read.c:13555
#1  in dwarf2_get_die_type (die_offset=48, per_cu=0xb566398) at dwarf2read.c:13680
#2  in dwarf_expr_get_base_type (ctx=0xb811838, die_offset=48) at dwarf2loc.c:296
#3  in dwarf_get_base_type (ctx=0xb811838, die=48, size=0) at dwarf2expr.c:449
#4  in execute_stack_op (ctx=0xb811838, op_ptr=0xb5675a2 "\367)\237\006l", op_end=0xb5675a5 "\006l") at dwarf2expr.c:850
#5  in dwarf_expr_eval (ctx=0xb811838, addr=0xb56759d "\221\030\366\004\060\367)\237\006l", len=8) at dwarf2expr.c:343
#6  in dwarf2_evaluate_loc_desc_full (type=0xb567e84, frame=0xb56646c, data=0xb56759d "\221\030\366\004\060\367)\237\006l", size=8, per_cu=0xb566398, 
#7  in dwarf2_evaluate_loc_desc (type=0xb567e84, frame=0xb56646c, data=0xb56759d "\221\030\366\004\060\367)\237\006l", size=8, per_cu=0xb566398)
#8  in locexpr_read_variable (symbol=0xb569f1c, frame=0xb56646c) at dwarf2loc.c:2163
#9  in read_var_value (var=0xb569f1c, frame=0xb56646c) at findvar.c:555
#10 in value_of_variable (var=0xb569f1c, b=0x0) at valops.c:1510
#11 in evaluate_subexp_standard (expect_type=0x0, exp=0xb54ed08, pos=0xffdec7dc, noside=EVAL_NORMAL) at eval.c:847
#12 in evaluate_subexp_c (expect_type=0x0, exp=0xb54ed08, pos=0xffdec7dc, noside=EVAL_NORMAL) at c-lang.c:1076
#13 in evaluate_subexp (expect_type=0x0, exp=0xb54ed08, pos=0xffdec7dc, noside=EVAL_NORMAL) at eval.c:76
#14 in evaluate_expression (exp=0xb54ed08) at eval.c:151
#15 in print_command_1 (exp=0xb2f624e "j", inspect=0, voidprint=1) at ./printcmd.c:973
#16 in print_command (exp=0xb2f624e "j", from_tty=1) at ./printcmd.c:1021


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-12 19:32             ` Tom Tromey
@ 2011-05-16 15:50               ` Ulrich Weigand
  2011-05-16 18:09                 ` Tom Tromey
  0 siblings, 1 reply; 25+ messages in thread
From: Ulrich Weigand @ 2011-05-16 15:50 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom Tromey wrote:
> >>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:
> 
> Tom> Yes.  My understanding is that for new-style typed values, DW_OP_shr and
> Tom> DW_OP_shra are actually the same -- the type indicates the operation to
> Tom> perform.  But, for old-style values, we must cast to unsigned for
> Tom> DW_OP_shr.
> 
> Ulrich> I see.  However, the code as implemented casts *all* signed values to
> Ulrich> unsigned for DW_OP_shr, not just old-style values.  That's what got
> Ulrich> me confused ...
> 
> I mentioned this on the GCC list and Jakub said that GCC actually emits
> code assuming that the operation will always be unsigned.
> 
> So, I am reverting my change here.  Patch appended.

So just to clarify: in the discussion a while back, you said:

> Ulrich> B.t.w. your patch always performs an unsigned shift for
> Ulrich> DW_OP_shr, even on signed operands.  However, for DW_OP_shra,
> Ulrich> your patch respects the sign of the operands and might actually
> Ulrich> perform an unsigned shift (even though the opcode explicitly
> Ulrich> says "arithmetic right shift" ...)  This looks like another of
> Ulrich> those signed/unsigned inconsistencies with the proposal to me.
> 
> Yes.  My understanding is that for new-style typed values, DW_OP_shr and
> DW_OP_shra are actually the same -- the type indicates the operation to
> perform.  But, for old-style values, we must cast to unsigned for
> DW_OP_shr.

With this latest patch, it is now definitely *not* the case that DW_OP_shr
and DW_OP_shra behave the same on new-style typed values.  Instead, as I
pointed out originally, DW_OP_shr now always performs an unsigned operation,
while DW_OP_shra respects the value's type ...

Is that really what was intended?  Or should rather DW_OP_shra now also
be changed (to always perform a signed operation as its name suggests)?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: gdbindex crash: Re: Regression: Re: RFC: implement typed DWARF stack
  2011-05-15  8:26                       ` gdbindex crash: " Jan Kratochvil
@ 2011-05-16 17:37                         ` Tom Tromey
  2011-05-17 17:01                           ` Tom Tromey
  0 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-16 17:37 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Ulrich Weigand, gdb-patches

>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:

Jan> The new testcase crashes with .gdb_index:
Jan> 	print j
Jan> 	ERROR: Process no longer exists
Jan> 	UNRESOLVED: gdb.dwarf2/typeddwarf.exp: check value of j at typeddwarf.c:29

Thanks.

I have a patch for this which I'm going to test, 
but first I have to look into why the buildbot did not detect this.
My guess is that the index-based tester is not working properly.

Tom


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-16 15:50               ` Ulrich Weigand
@ 2011-05-16 18:09                 ` Tom Tromey
  2011-05-17  8:35                   ` Jakub Jelinek
  0 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2011-05-16 18:09 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches, Jakub Jelinek

CCing Jakub.

Ulrich> So just to clarify: in the discussion a while back, you said:

Sorry for any confusion.  I hope this email will clear it up.

During our discussion I was convinced that DW_OP_shr should generally
use the sign of any explicit type to decide what to do (with a special
case for implicit type).  However, Jakub informed me that GCC relied on
'shr' always zero-filling, even for explicit types.  So, I changed the
code back.  What is now in the tree implements the same semantics that
GCC assumes.

Ulrich> With this latest patch, it is now definitely *not* the case that
Ulrich> DW_OP_shr and DW_OP_shra behave the same on new-style typed
Ulrich> values.  Instead, as I pointed out originally, DW_OP_shr now
Ulrich> always performs an unsigned operation, while DW_OP_shra respects
Ulrich> the value's type ...

Ulrich> Is that really what was intended?

At least the shr part is intended.  I did not consider the shra case.

Ulrich> Or should rather DW_OP_shra now also be changed (to always
Ulrich> perform a signed operation as its name suggests)?

In other words, mirror the shr special case for shra.
This makes sense to me.  Jakub, what do you think?

Tom


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-16 18:09                 ` Tom Tromey
@ 2011-05-17  8:35                   ` Jakub Jelinek
  2011-06-03 13:52                     ` Tom Tromey
  0 siblings, 1 reply; 25+ messages in thread
From: Jakub Jelinek @ 2011-05-17  8:35 UTC (permalink / raw)
  To: Tom Tromey, Cary Coutant; +Cc: Ulrich Weigand, gdb-patches

On Mon, May 16, 2011 at 12:09:28PM -0600, Tom Tromey wrote:
> CCing Jakub.
> 
> Ulrich> So just to clarify: in the discussion a while back, you said:
> 
> Sorry for any confusion.  I hope this email will clear it up.
> 
> During our discussion I was convinced that DW_OP_shr should generally
> use the sign of any explicit type to decide what to do (with a special
> case for implicit type).  However, Jakub informed me that GCC relied on
> 'shr' always zero-filling, even for explicit types.  So, I changed the
> code back.  What is now in the tree implements the same semantics that
> GCC assumes.

My point is that we have two right shift operations, DW_OP_shr{,a}, so
it is IMHO better to just keep them as two operations even for typed
stack.  The type in that case is used only for the size of the shift,
whether the upper bits are filled with 0s or msb is determined by the
operation.  DW_OP_mod or DW_OP_div are different, there is just one
operation, so it has some default for untyped arguments (unsigned for
mod, signed for div) and for typed operands both type's size and signedness
matter.
If DW_OP_shr{,a} was the same, the producer would often need to add
additional DW_OP_convert ops.

OT, DW_OP_mod should be documented as:
"This operation operates only on integral values."
and DW_OP_const_type description uses "The second operand" twice, where
"The third operand" should be used in the second occurrence.

	Jakub


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: gdbindex crash: Re: Regression: Re: RFC: implement typed DWARF stack
  2011-05-16 17:37                         ` Tom Tromey
@ 2011-05-17 17:01                           ` Tom Tromey
  0 siblings, 0 replies; 25+ messages in thread
From: Tom Tromey @ 2011-05-17 17:01 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Ulrich Weigand, gdb-patches

Jan> The new testcase crashes with .gdb_index:
Jan> print j
Jan> ERROR: Process no longer exists
Jan> UNRESOLVED: gdb.dwarf2/typeddwarf.exp: check value of j at typeddwarf.c:29

Tom> I have a patch for this which I'm going to test, 

Appended.  I am checking this in.

Earlier I did not realize that the types from the CU are cached, and so
we can simply look them up using get_die_type_at_offset.

Tom> but first I have to look into why the buildbot did not detect this.
Tom> My guess is that the index-based tester is not working properly.

I tracked this down to a bad 'make' invocation.
It wasn't properly passing the options to set the compiler.
I verified that it works now by examining the .log files and checking
that dejagnu is invoking cc-with-index.sh.

Tom

2011-05-17  Tom Tromey  <tromey@redhat.com>

	* dwarf2read.c (dwarf2_get_die_type): Call
	get_die_type_at_offset.
	* dwarf2expr.c (dwarf_get_base_type): Handle NULL return from
	get_base_type function.

diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 1fe8b79..5cd33a6 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -447,6 +447,8 @@ dwarf_get_base_type (struct dwarf_expr_context *ctx, ULONGEST die, int size)
   if (ctx->get_base_type)
     {
       result = ctx->get_base_type (ctx, die);
+      if (result == NULL)
+	error (_("Could not find type for DW_OP_GNU_const_type"));
       if (size != 0 && TYPE_LENGTH (result) != size)
 	error (_("DW_OP_GNU_const_type has different sizes for type and data"));
     }
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 22643c5..6558bfe 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13671,22 +13671,8 @@ struct type *
 dwarf2_get_die_type (unsigned int die_offset,
 		     struct dwarf2_per_cu_data *per_cu)
 {
-  struct dwarf2_cu *cu = per_cu->cu;
-  struct die_info *die;
-  struct type *result;
-
   dw2_setup (per_cu->objfile);
-
-  die = follow_die_offset (die_offset, &cu);
-  if (!die)
-    error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
-	   die_offset, per_cu->cu->objfile->name);
-
-  result = get_die_type (die, cu);
-  if (result == NULL)
-    result = read_type_die_1 (die, cu);
-
-  return result;
+  return get_die_type_at_offset (die_offset, per_cu);
 }
 
 /* Follow the signature attribute ATTR in SRC_DIE.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: RFC: implement typed DWARF stack
  2011-05-17  8:35                   ` Jakub Jelinek
@ 2011-06-03 13:52                     ` Tom Tromey
  0 siblings, 0 replies; 25+ messages in thread
From: Tom Tromey @ 2011-06-03 13:52 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Cary Coutant, Ulrich Weigand, gdb-patches

>>>>> "Jakub" == Jakub Jelinek <jakub@redhat.com> writes:

Jakub> My point is that we have two right shift operations, DW_OP_shr{,a}, so
Jakub> it is IMHO better to just keep them as two operations even for typed
Jakub> stack.

Ok, no problem.  I am checking this in on the trunk; it changes
DW_OP_shra to always be a signed operation.

Tom

2011-06-03  Tom Tromey  <tromey@redhat.com>

	* dwarf2expr.c (get_signed_type): New function.
	(execute_stack_op) <DW_OP_shra>: Always perform a signed shift.

diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 5cd33a6..3c60b6a 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -229,6 +229,28 @@ get_unsigned_type (struct gdbarch *gdbarch, struct type *type)
     }
 }
 
+/* Return the signed form of TYPE.  TYPE is necessarily an integral
+   type.  */
+
+static struct type *
+get_signed_type (struct gdbarch *gdbarch, struct type *type)
+{
+  switch (TYPE_LENGTH (type))
+    {
+    case 1:
+      return builtin_type (gdbarch)->builtin_int8;
+    case 2:
+      return builtin_type (gdbarch)->builtin_int16;
+    case 4:
+      return builtin_type (gdbarch)->builtin_int32;
+    case 8:
+      return builtin_type (gdbarch)->builtin_int64;
+    default:
+      error (_("no signed variant found for type, while evaluating "
+	       "DWARF expression"));
+    }
+}
+
 /* Retrieve the N'th item on CTX's stack, converted to an address.  */
 
 CORE_ADDR
@@ -996,7 +1018,19 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	      case DW_OP_shra:
 		dwarf_require_integral (value_type (first));
 		dwarf_require_integral (value_type (second));
+		if (TYPE_UNSIGNED (value_type (first)))
+		  {
+		    struct type *stype
+		      = get_signed_type (ctx->gdbarch, value_type (first));
+
+		    first = value_cast (stype, first);
+		  }
+
 		result_val = value_binop (first, second, BINOP_RSH);
+		/* Make sure we wind up with the same type we started
+		   with.  */
+		if (value_type (result_val) != value_type (second))
+		  result_val = value_cast (value_type (second), result_val);
 		break;
 	      case DW_OP_xor:
 		dwarf_require_integral (value_type (first));


^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2011-06-03 13:52 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-04 20:48 RFC: implement typed DWARF stack Tom Tromey
2011-05-05 16:47 ` Tom Tromey
2011-05-05 18:07 ` Ulrich Weigand
2011-05-05 18:38   ` Tom Tromey
2011-05-05 20:15     ` Tom Tromey
2011-05-09 22:02       ` Ulrich Weigand
2011-05-10 14:15         ` Tom Tromey
2011-05-11  0:15           ` Ulrich Weigand
2011-05-11 14:59             ` Tom Tromey
2011-05-11 19:44               ` Tom Tromey
2011-05-12  0:03               ` Ulrich Weigand
2011-05-12 16:33                 ` Tom Tromey
2011-05-13  7:52                   ` Regression: " Jan Kratochvil
2011-05-13 15:44                     ` Tom Tromey
2011-05-15  8:26                       ` gdbindex crash: " Jan Kratochvil
2011-05-16 17:37                         ` Tom Tromey
2011-05-17 17:01                           ` Tom Tromey
2011-05-13 17:17                     ` Tom Tromey
2011-05-13 17:34                       ` Jan Kratochvil
2011-05-12 19:32             ` Tom Tromey
2011-05-16 15:50               ` Ulrich Weigand
2011-05-16 18:09                 ` Tom Tromey
2011-05-17  8:35                   ` Jakub Jelinek
2011-06-03 13:52                     ` Tom Tromey
2011-05-10 16:39         ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox