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:
Thiago Jung Bauermann 2007-10-25 18:01:58 +00:00
parent 7678ef8fb0
commit 27bc4d809e
9 changed files with 140 additions and 0 deletions

View 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> 2007-10-25 Wu Zhou <woodzltc@cn.ibm.com>
Thiago Jung Bauermann <bauerman@br.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com>

View File

@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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 *);

View File

@ -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))

View File

@ -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)
{ {

View 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_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);