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.
This commit is contained in:
parent
7678ef8fb0
commit
27bc4d809e
@ -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>
|
2007-10-25 Wu Zhou <woodzltc@cn.ibm.com>
|
||||||
Thiago Jung Bauermann <bauerman@br.ibm.com>
|
Thiago Jung Bauermann <bauerman@br.ibm.com>
|
||||||
|
|
||||||
|
47
gdb/c-exp.y
47
gdb/c-exp.y
@ -52,6 +52,7 @@ Boston, MA 02110-1301, USA. */
|
|||||||
#include "charset.h"
|
#include "charset.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
#include "cp-support.h"
|
#include "cp-support.h"
|
||||||
|
#include "dfp.h"
|
||||||
|
|
||||||
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
|
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
|
||||||
as well as gratuitiously global symbol names, so we can have multiple
|
as well as gratuitiously global symbol names, so we can have multiple
|
||||||
@ -130,6 +131,10 @@ void yyerror (char *);
|
|||||||
DOUBLEST dval;
|
DOUBLEST dval;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
} typed_val_float;
|
} typed_val_float;
|
||||||
|
struct {
|
||||||
|
gdb_byte val[16];
|
||||||
|
struct type *type;
|
||||||
|
} typed_val_decfloat;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct type *tval;
|
struct type *tval;
|
||||||
struct stoken sval;
|
struct stoken sval;
|
||||||
@ -162,6 +167,7 @@ static int parse_number (char *, int, int, YYSTYPE *);
|
|||||||
|
|
||||||
%token <typed_val_int> INT
|
%token <typed_val_int> INT
|
||||||
%token <typed_val_float> FLOAT
|
%token <typed_val_float> FLOAT
|
||||||
|
%token <typed_val_decfloat> DECFLOAT
|
||||||
|
|
||||||
/* Both NAME and TYPENAME tokens represent symbols in the input,
|
/* Both NAME and TYPENAME tokens represent symbols in the input,
|
||||||
and both convey their data as strings.
|
and both convey their data as strings.
|
||||||
@ -496,6 +502,13 @@ exp : FLOAT
|
|||||||
write_exp_elt_opcode (OP_DOUBLE); }
|
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
|
exp : variable
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -1077,6 +1090,40 @@ parse_number (p, len, parsed_float, putithere)
|
|||||||
char saved_char = p[len];
|
char saved_char = p[len];
|
||||||
|
|
||||||
p[len] = 0; /* null-terminate the token */
|
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",
|
num = sscanf (p, DOUBLEST_SCAN_FORMAT "%s",
|
||||||
&putithere->typed_val_float.dval, s);
|
&putithere->typed_val_float.dval, s);
|
||||||
p[len] = saved_char; /* restore the input stream */
|
p[len] = saved_char; /* restore the input stream */
|
||||||
|
@ -456,6 +456,11 @@ evaluate_subexp_standard (struct type *expect_type,
|
|||||||
return value_from_double (exp->elts[pc + 1].type,
|
return value_from_double (exp->elts[pc + 1].type,
|
||||||
exp->elts[pc + 2].doubleconst);
|
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:
|
case OP_VAR_VALUE:
|
||||||
(*pos) += 3;
|
(*pos) += 3;
|
||||||
if (noside == EVAL_SKIP)
|
if (noside == EVAL_SKIP)
|
||||||
|
@ -328,6 +328,11 @@ enum exp_opcode
|
|||||||
/* A F90 array range operator (for "exp:exp", "exp:", ":exp" and ":"). */
|
/* A F90 array range operator (for "exp:exp", "exp:", ":exp" and ":"). */
|
||||||
OP_F90_RANGE,
|
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
|
/* First extension operator. Individual language modules define
|
||||||
extra operators they need as constants with values
|
extra operators they need as constants with values
|
||||||
OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate
|
OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate
|
||||||
@ -355,6 +360,7 @@ union exp_element
|
|||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
LONGEST longconst;
|
LONGEST longconst;
|
||||||
DOUBLEST doubleconst;
|
DOUBLEST doubleconst;
|
||||||
|
gdb_byte decfloatconst[16];
|
||||||
/* Really sizeof (union exp_element) characters (or less for the last
|
/* Really sizeof (union exp_element) characters (or less for the last
|
||||||
element of a string). */
|
element of a string). */
|
||||||
char string;
|
char string;
|
||||||
|
13
gdb/parse.c
13
gdb/parse.c
@ -247,6 +247,18 @@ write_exp_elt_dblcst (DOUBLEST expelt)
|
|||||||
write_exp_elt (tmp);
|
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
|
void
|
||||||
write_exp_elt_type (struct type *expelt)
|
write_exp_elt_type (struct type *expelt)
|
||||||
{
|
{
|
||||||
@ -718,6 +730,7 @@ operator_length_standard (struct expression *expr, int endpos,
|
|||||||
|
|
||||||
case OP_LONG:
|
case OP_LONG:
|
||||||
case OP_DOUBLE:
|
case OP_DOUBLE:
|
||||||
|
case OP_DECFLOAT:
|
||||||
case OP_VAR_VALUE:
|
case OP_VAR_VALUE:
|
||||||
oplen = 4;
|
oplen = 4;
|
||||||
break;
|
break;
|
||||||
|
@ -119,6 +119,8 @@ extern void write_exp_elt_longcst (LONGEST);
|
|||||||
|
|
||||||
extern void write_exp_elt_dblcst (DOUBLEST);
|
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_type (struct type *);
|
||||||
|
|
||||||
extern void write_exp_elt_intern (struct internalvar *);
|
extern void write_exp_elt_intern (struct internalvar *);
|
||||||
|
@ -1376,6 +1376,23 @@ value_neg (struct value *arg1)
|
|||||||
|
|
||||||
type = check_typedef (value_type (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)
|
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
||||||
return value_from_double (result_type, -value_as_double (arg1));
|
return value_from_double (result_type, -value_as_double (arg1));
|
||||||
else if (is_integral_type (type))
|
else if (is_integral_type (type))
|
||||||
|
22
gdb/value.c
22
gdb/value.c
@ -34,6 +34,7 @@
|
|||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
#include "dfp.h"
|
||||||
|
|
||||||
/* Prototypes for exported functions. */
|
/* Prototypes for exported functions. */
|
||||||
|
|
||||||
@ -1641,6 +1642,27 @@ value_from_double (struct type *type, DOUBLEST num)
|
|||||||
return val;
|
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 *
|
struct value *
|
||||||
coerce_ref (struct value *arg)
|
coerce_ref (struct value *arg)
|
||||||
{
|
{
|
||||||
|
@ -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_longest (struct type *type, LONGEST num);
|
||||||
extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr);
|
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_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_from_string (char *string);
|
||||||
|
|
||||||
extern struct value *value_at (struct type *type, CORE_ADDR addr);
|
extern struct value *value_at (struct type *type, CORE_ADDR addr);
|
||||||
|
Loading…
Reference in New Issue
Block a user