]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2007-10-25 Wu Zhou <woodzltc@cn.ibm.com>
authorThiago Jung Bauermann <bauerman@br.ibm.com>
Thu, 25 Oct 2007 18:01:58 +0000 (18:01 +0000)
committerThiago Jung Bauermann <bauerman@br.ibm.com>
Thu, 25 Oct 2007 18:01:58 +0000 (18:01 +0000)
    Thiago Jung Bauermann  <bauerman@br.ibm.com>

* c-exp.y (YYSTYPE): Add typed_val_decfloat for decimal
floating point in YYSTYPE union.
(DECFLOAT) Add token and expression element handling code.
(parse_number): Parse DFP constants, which end with suffix 'df',
'dd' or 'dl'.  Return DECFLOAT.
* eval.c (evaluate_subexp_standard): Call value_from_decfloat to
handle OP_DECFLOAT.
* expression.h (enum exp_opcode): Add an opcode (OP_DECFLOAT)
for DFP constants.
(union exp_element): Add decfloatconst to represent DFP
elements, which is 16 bytes by default.
* parse.c (write_exp_elt_decfloatcst): New function to write a
decimal float const into the expression.
(operator_length_standard): Set operator length for OP_DECFLOAT
to 4.
* parser-defs.h (write_exp_elt_decfloatcst): Prototype.
* valarith.c (value_neg): Add code to handle the negation
operation of DFP values.
* value.c (value_from_decfloat): New function to get the value
from a decimal floating point.
* value.h (value_from_decfloat): Prototype.

gdb/ChangeLog
gdb/c-exp.y
gdb/eval.c
gdb/expression.h
gdb/parse.c
gdb/parser-defs.h
gdb/valarith.c
gdb/value.c
gdb/value.h

index be6eab8d00e8ba148d58eeee675c9a26daf25e2e..f86576c61e88f8199064d633ef61644a0687a499 100644 (file)
@@ -1,3 +1,28 @@
+2007-10-25  Wu Zhou  <woodzltc@cn.ibm.com> 
+           Thiago Jung Bauermann  <bauerman@br.ibm.com>
+
+       * c-exp.y (YYSTYPE): Add typed_val_decfloat for decimal
+       floating point in YYSTYPE union.
+       (DECFLOAT) Add token and expression element handling code.
+       (parse_number): Parse DFP constants, which end with suffix 'df',
+       'dd' or 'dl'.  Return DECFLOAT.
+       * eval.c (evaluate_subexp_standard): Call value_from_decfloat to
+       handle OP_DECFLOAT.
+       * expression.h (enum exp_opcode): Add an opcode (OP_DECFLOAT)
+       for DFP constants.
+       (union exp_element): Add decfloatconst to represent DFP
+       elements, which is 16 bytes by default.
+       * parse.c (write_exp_elt_decfloatcst): New function to write a
+       decimal float const into the expression.
+       (operator_length_standard): Set operator length for OP_DECFLOAT
+       to 4.
+       * parser-defs.h (write_exp_elt_decfloatcst): Prototype.
+       * valarith.c (value_neg): Add code to handle the negation
+       operation of DFP values.
+       * value.c (value_from_decfloat): New function to get the value
+       from a decimal floating point.
+       * value.h (value_from_decfloat): Prototype.
+
 2007-10-25  Wu Zhou  <woodzltc@cn.ibm.com> 
            Thiago Jung Bauermann  <bauerman@br.ibm.com>
 
index 6318955b038a88ef8de90b7a944541130ce9d37f..40dbc93efb099111ff3e856c70ae81786be3593d 100644 (file)
@@ -52,6 +52,7 @@ Boston, MA 02110-1301, USA.  */
 #include "charset.h"
 #include "block.h"
 #include "cp-support.h"
+#include "dfp.h"
 
 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
    as well as gratuitiously global symbol names, so we can have multiple
@@ -130,6 +131,10 @@ void yyerror (char *);
       DOUBLEST dval;
       struct type *type;
     } typed_val_float;
+    struct {
+      gdb_byte val[16];
+      struct type *type;
+    } typed_val_decfloat;
     struct symbol *sym;
     struct type *tval;
     struct stoken sval;
@@ -162,6 +167,7 @@ static int parse_number (char *, int, int, YYSTYPE *);
 
 %token <typed_val_int> INT
 %token <typed_val_float> FLOAT
+%token <typed_val_decfloat> DECFLOAT
 
 /* Both NAME and TYPENAME tokens represent symbols in the input,
    and both convey their data as strings.
@@ -496,6 +502,13 @@ exp        :       FLOAT
                          write_exp_elt_opcode (OP_DOUBLE); }
        ;
 
+exp    :       DECFLOAT
+                       { write_exp_elt_opcode (OP_DECFLOAT);
+                         write_exp_elt_type ($1.type);
+                         write_exp_elt_decfloatcst ($1.val);
+                         write_exp_elt_opcode (OP_DECFLOAT); }
+       ;
+
 exp    :       variable
        ;
 
@@ -1077,6 +1090,40 @@ parse_number (p, len, parsed_float, putithere)
       char saved_char = p[len];
 
       p[len] = 0;      /* null-terminate the token */
+
+      /* If it ends at "df", "dd" or "dl", take it as type of decimal floating
+         point.  Return DECFLOAT.  */
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'f')
+       {
+         p[len - 2] = '\0';
+         putithere->typed_val_decfloat.type
+           = builtin_type (current_gdbarch)->builtin_decfloat;
+         decimal_from_string (putithere->typed_val_decfloat.val, 4, p);
+         p[len] = saved_char;
+         return (DECFLOAT);
+       }
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'd')
+       {
+         p[len - 2] = '\0';
+         putithere->typed_val_decfloat.type
+           = builtin_type (current_gdbarch)->builtin_decdouble;
+         decimal_from_string (putithere->typed_val_decfloat.val, 8, p);
+         p[len] = saved_char;
+         return (DECFLOAT);
+       }
+
+      if (p[len - 2] == 'd' && p[len - 1] == 'l')
+       {
+         p[len - 2] = '\0';
+         putithere->typed_val_decfloat.type
+           = builtin_type (current_gdbarch)->builtin_declong;
+         decimal_from_string (putithere->typed_val_decfloat.val, 16, p);
+         p[len] = saved_char;
+         return (DECFLOAT);
+       }
+
       num = sscanf (p, DOUBLEST_SCAN_FORMAT "%s",
                    &putithere->typed_val_float.dval, s);
       p[len] = saved_char;     /* restore the input stream */
index ee1ac589ee2d0d07b47ce030678b2e20a24b95b3..2e6a8325ad51146ed38588dd866ca8d475712b8c 100644 (file)
@@ -456,6 +456,11 @@ evaluate_subexp_standard (struct type *expect_type,
       return value_from_double (exp->elts[pc + 1].type,
                                exp->elts[pc + 2].doubleconst);
 
+    case OP_DECFLOAT:
+      (*pos) += 3;
+      return value_from_decfloat (expect_type, exp->elts[pc + 1].type,
+                               exp->elts[pc + 2].decfloatconst);
+
     case OP_VAR_VALUE:
       (*pos) += 3;
       if (noside == EVAL_SKIP)
index fb4ecac547421ba0e0a2dbc4b64abccc8c647d89..01ddc05dec11c27d70c9d0516812e20b4dd3dca2 100644 (file)
@@ -328,6 +328,11 @@ enum exp_opcode
     /* A F90 array range operator (for "exp:exp", "exp:", ":exp" and ":").  */
     OP_F90_RANGE,
 
+    /* OP_DECFLOAT is followed by a type pointer in the next exp_element
+       and a dec long constant value in the following exp_element.
+       Then comes another OP_DECFLOAT.  */
+    OP_DECFLOAT,
+
      /* First extension operator.  Individual language modules define
         extra operators they need as constants with values 
         OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate 
@@ -355,6 +360,7 @@ union exp_element
     struct symbol *symbol;
     LONGEST longconst;
     DOUBLEST doubleconst;
+    gdb_byte decfloatconst[16];
     /* Really sizeof (union exp_element) characters (or less for the last
        element of a string).  */
     char string;
index 9303dfd7df7c72f7926f995e52d7a2224f7dacad..8841e598a0e3b20474737b791f4e2224aef82005 100644 (file)
@@ -247,6 +247,18 @@ write_exp_elt_dblcst (DOUBLEST expelt)
   write_exp_elt (tmp);
 }
 
+void
+write_exp_elt_decfloatcst (gdb_byte expelt[16])
+{
+  union exp_element tmp;
+  int index;
+
+  for (index = 0; index < 16; index++)
+    tmp.decfloatconst[index] = expelt[index];
+
+  write_exp_elt (tmp);
+}
+
 void
 write_exp_elt_type (struct type *expelt)
 {
@@ -718,6 +730,7 @@ operator_length_standard (struct expression *expr, int endpos,
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_DECFLOAT:
     case OP_VAR_VALUE:
       oplen = 4;
       break;
index 417bc5bae2603e6e44ebe7382c0f489bbcc36dba..7928537276e5fa25d182a623afeddaf094fce8ba 100644 (file)
@@ -119,6 +119,8 @@ extern void write_exp_elt_longcst (LONGEST);
 
 extern void write_exp_elt_dblcst (DOUBLEST);
 
+extern void write_exp_elt_decfloatcst (gdb_byte *);
+
 extern void write_exp_elt_type (struct type *);
 
 extern void write_exp_elt_intern (struct internalvar *);
index ed65d6679c6a110e369d8c665a847e496322f5fe..9771ac83c0b7908e9a7da3c2dde622256a07b4b6 100644 (file)
@@ -1376,6 +1376,23 @@ value_neg (struct value *arg1)
 
   type = check_typedef (value_type (arg1));
 
+  if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
+    {
+      struct value *val = allocate_value (result_type);
+      int len = TYPE_LENGTH (type);
+      gdb_byte decbytes[16];  /* a decfloat is at most 128 bits long */
+
+      memcpy(decbytes, value_contents(arg1), len);
+
+      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
+       decbytes[len-1] = decbytes[len - 1] | 0x80;
+      else
+       decbytes[0] = decbytes[0] | 0x80;
+
+      memcpy (value_contents_raw (val), decbytes, len);
+      return val;
+    }
+
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     return value_from_double (result_type, -value_as_double (arg1));
   else if (is_integral_type (type))
index 7085ec11f75690f3fb4218085119eac9582b3384..89759b8f00ab30b2a45cf786d65201f3384d4801 100644 (file)
@@ -34,6 +34,7 @@
 #include "gdb_assert.h"
 #include "regcache.h"
 #include "block.h"
+#include "dfp.h"
 
 /* Prototypes for exported functions. */
 
@@ -1641,6 +1642,27 @@ value_from_double (struct type *type, DOUBLEST num)
   return val;
 }
 
+struct value *
+value_from_decfloat (struct type *expect_type, struct type *type,
+                     gdb_byte decbytes[16])
+{
+  struct value *val = allocate_value (type);
+  int len = TYPE_LENGTH (type);
+
+  if (expect_type)
+    {
+      int expect_len = TYPE_LENGTH (expect_type);
+      char decstr[128];
+      int real_len;
+
+      decimal_to_string (decbytes, len, decstr);
+      decimal_from_string (decbytes, expect_len, decstr);
+    }
+
+  memcpy (value_contents_raw (val), decbytes, len);
+  return val;
+}
+
 struct value *
 coerce_ref (struct value *arg)
 {
index 7026466222843cc4d6612bfbd049e3ea8be3c78e..ada7fc7dd6be5ddf21fed021fe70475b4239fb26 100644 (file)
@@ -280,6 +280,9 @@ extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num);
 extern struct value *value_from_longest (struct type *type, LONGEST num);
 extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr);
 extern struct value *value_from_double (struct type *type, DOUBLEST num);
+extern struct value *value_from_decfloat (struct type *expect_type,
+                                         struct type *type,
+                                         gdb_byte decbytes[16]);
 extern struct value *value_from_string (char *string);
 
 extern struct value *value_at (struct type *type, CORE_ADDR addr);