Index: gdb/c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.54 diff -a -u -r1.54 c-valprint.c --- gdb/c-valprint.c 28 Oct 2008 17:19:56 -0000 1.54 +++ gdb/c-valprint.c 30 Dec 2008 00:16:27 -0000 @@ -492,6 +492,13 @@ print_decimal_floating (valaddr + embedded_offset, type, stream); break; + case TYPE_CODE_FIXED: + /* convert to double and print that */ + return c_value_print (value_cast (builtin_type_ieee_double, + value_from_contents_and_address + (type, valaddr + embedded_offset, 0)), + stream, options); + case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; Index: gdb/dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.291 diff -a -u -r1.291 dwarf2read.c --- gdb/dwarf2read.c 15 Nov 2008 18:49:50 -0000 1.291 +++ gdb/dwarf2read.c 30 Dec 2008 00:16:35 -0000 @@ -5088,6 +5088,12 @@ code = TYPE_CODE_CHAR; type_flags |= TYPE_FLAG_UNSIGNED; break; + case DW_ATE_unsigned_fixed: + type_flags |= TYPE_FLAG_UNSIGNED; + + case DW_ATE_signed_fixed: + code = TYPE_CODE_FIXED; + break; default: complaint (&symfile_complaints, _("unsupported DW_AT_encoding: '%s'"), dwarf_type_encoding_name (encoding)); @@ -5098,6 +5104,12 @@ TYPE_NAME (type) = name; TYPE_TARGET_TYPE (type) = target_type; + if (code == TYPE_CODE_FIXED) { + attr = dwarf2_attr (die, DW_AT_binary_scale, cu); + if (attr) + TYPE_BINARYSCALE (type) = DW_SND (attr); + } + if (name && strcmp (name, "char") == 0) TYPE_NOSIGN (type) = 1; Index: gdb/eval.c =================================================================== RCS file: /cvs/src/src/gdb/eval.c,v retrieving revision 1.103 diff -a -u -r1.103 eval.c --- gdb/eval.c 28 Dec 2008 14:14:19 -0000 1.103 +++ gdb/eval.c 30 Dec 2008 00:16:37 -0000 @@ -703,7 +703,10 @@ (*pos) += 3; return value_from_decfloat (exp->elts[pc + 1].type, exp->elts[pc + 2].decfloatconst); - + case OP_FIXED: + (*pos) += 3; + return value_from_fixed (exp->elts[pc + 1].type, + exp->elts[pc + 2].fixedconst); case OP_VAR_VALUE: (*pos) += 3; if (noside == EVAL_SKIP) Index: gdb/expression.h =================================================================== RCS file: /cvs/src/src/gdb/expression.h,v retrieving revision 1.29 diff -a -u -r1.29 expression.h --- gdb/expression.h 11 Sep 2008 14:12:15 -0000 1.29 +++ gdb/expression.h 30 Dec 2008 00:16:37 -0000 @@ -334,15 +334,20 @@ 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 - enumerated type definition: - enum foo_extension_operator { - BINOP_MOGRIFY = OP_EXTENDED0, - BINOP_FROB, - ... - }; */ + /* OP_FIXED is followed by by a type pointer in the next exp_element + and a fixed constant value in the following exp_element, + Then comes the binaryscale */ + OP_FIXED, + + /* 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 + enumerated type definition: + enum foo_extension_operator { + BINOP_MOGRIFY = OP_EXTENDED0, + BINOP_FROB, + ... + }; */ OP_EXTENDED0, /* Last possible extension operator. Defined to provide an @@ -362,6 +367,7 @@ LONGEST longconst; DOUBLEST doubleconst; gdb_byte decfloatconst[16]; + gdb_byte fixedconst[16]; /* Really sizeof (union exp_element) characters (or less for the last element of a string). */ char string; Index: gdb/gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.96 diff -a -u -r1.96 gdbtypes.h --- gdb/gdbtypes.h 28 Dec 2008 14:14:19 -0000 1.96 +++ gdb/gdbtypes.h 30 Dec 2008 00:16:39 -0000 @@ -134,7 +134,8 @@ TYPE_CODE_NAMESPACE, /* C++ namespace. */ - TYPE_CODE_DECFLOAT /* Decimal floating point. */ + TYPE_CODE_DECFLOAT, /* Decimal floating point. */ + TYPE_CODE_FIXED /* Fixed point type */ }; /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an @@ -517,6 +518,9 @@ const struct floatformat **floatformat; + /* BINARYSCALE is for TYPE_CODE_FIXED. */ + int binaryscale; + /* For TYPE_CODE_FUNC types, the calling convention for targets supporting multiple ABIs. Right now this is only fetched from the Dwarf-2 DW_AT_calling_convention attribute. */ @@ -838,6 +842,7 @@ #define TYPE_TYPE_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific #define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff #define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat +#define TYPE_BINARYSCALE(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.binaryscale #define TYPE_CALLING_CONVENTION(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.calling_convention #define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses Index: gdb/valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.68 diff -a -u -r1.68 valarith.c --- gdb/valarith.c 28 Dec 2008 14:14:19 -0000 1.68 +++ gdb/valarith.c 30 Dec 2008 00:16:40 -0000 @@ -881,9 +881,11 @@ if ((TYPE_CODE (type1) != TYPE_CODE_FLT && TYPE_CODE (type1) != TYPE_CODE_DECFLOAT + && TYPE_CODE (type1) != TYPE_CODE_FIXED && !is_integral_type (type1)) || (TYPE_CODE (type2) != TYPE_CODE_FLT && TYPE_CODE (type2) != TYPE_CODE_DECFLOAT + && TYPE_CODE (type2) != TYPE_CODE_FIXED && !is_integral_type (type2))) error (_("Argument to arithmetic operation not a number or boolean.")); @@ -924,6 +926,21 @@ val = value_from_decfloat (result_type, v); } + else if (TYPE_CODE (type1) == TYPE_CODE_FIXED + || TYPE_CODE (type2) == TYPE_CODE_FIXED) + { + struct value *result; + + /* convert fixed to double */ + if(TYPE_CODE (type1) == TYPE_CODE_FIXED) + arg1 = value_cast(builtin_type_ieee_double, arg1); + if(TYPE_CODE (type2) == TYPE_CODE_FIXED) + arg2 = value_cast(builtin_type_ieee_double, arg2); + + /* use largest type for result */ + result_type = (TYPE_LENGTH (type1) > TYPE_LENGTH (type2)) ? type1 : type2; + return value_cast (result_type, value_binop (arg1, arg2, op)); + } else if (TYPE_CODE (type1) == TYPE_CODE_FLT || TYPE_CODE (type2) == TYPE_CODE_FLT) { @@ -1485,6 +1502,8 @@ return value_from_double (type, value_as_double (arg1)); else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT) return value_from_decfloat (type, value_contents (arg1)); + else if (TYPE_CODE (type) == TYPE_CODE_FIXED) + return value_from_fixed (type, value_contents (arg1)); else if (is_integral_type (type)) { return value_from_longest (type, value_as_long (arg1)); @@ -1520,6 +1539,12 @@ memcpy (value_contents_raw (val), decbytes, len); return val; } + else if (TYPE_CODE (type) == TYPE_CODE_FIXED) + { + LONGEST unshiftedval = -extract_signed_integer (value_contents (arg1), + TYPE_LENGTH (type)); + return value_from_fixed (type, (gdb_byte*)&unshiftedval); + } else if (TYPE_CODE (type) == TYPE_CODE_FLT) return value_from_double (type, -value_as_double (arg1)); else if (is_integral_type (type)) Index: gdb/valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.204 diff -a -u -r1.204 valops.c --- gdb/valops.c 29 Dec 2008 06:02:06 -0000 1.204 +++ gdb/valops.c 30 Dec 2008 00:16:42 -0000 @@ -409,7 +409,7 @@ scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM - || code2 == TYPE_CODE_RANGE); + || code2 == TYPE_CODE_RANGE || code2 == TYPE_CODE_FIXED); if ((code1 == TYPE_CODE_STRUCT || code1 == TYPE_CODE_UNION) && (code2 == TYPE_CODE_STRUCT || code2 == TYPE_CODE_UNION) @@ -438,6 +438,32 @@ return value_from_decfloat (type, dec); } + else if (code1 == TYPE_CODE_FIXED && scalar) + { + /* first convert to double */ + struct value *ieee_double = value_cast (builtin_type_ieee_double, arg2); + + if(ieee_double) { + LONGEST lvalue; + DOUBLEST value = value_as_double (ieee_double); + int binaryscale = TYPE_BINARYSCALE(type); + + /* shift by the binary scale value */ + while(binaryscale < 0) { + binaryscale++; + value *= 2; + } + while(binaryscale > 0) { + binaryscale--; + value /= 2; + } + lvalue = value; + + return value_from_fixed (type, (gdb_byte*)&lvalue); + } + error (_("Failed to convert to fixed-point.")); + return 0; + } else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM || code1 == TYPE_CODE_RANGE) && (scalar || code2 == TYPE_CODE_PTR @@ -539,26 +565,14 @@ struct value * value_one (struct type *type, enum lval_type lv) { - struct type *type1 = check_typedef (type); + CHECK_TYPEDEF(type); struct value *val = NULL; /* avoid -Wall warning */ - if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT) - { - struct value *int_one = value_from_longest (builtin_type_int32, 1); - struct value *val; - gdb_byte v[16]; - - decimal_from_integral (int_one, v, TYPE_LENGTH (builtin_type_int32)); - val = value_from_decfloat (type, v); - } - else if (TYPE_CODE (type1) == TYPE_CODE_FLT) - { - val = value_from_double (type, (DOUBLEST) 1); - } - else if (is_integral_type (type1)) - { - val = value_from_longest (type, (LONGEST) 1); - } + if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT + || TYPE_CODE (type) == TYPE_CODE_FLT + || TYPE_CODE (type) == TYPE_CODE_FIXED + || is_integral_type (type)) + val = value_cast (type, value_from_longest (builtin_type_int32, 1)); else { error (_("Not a numeric type.")); Index: gdb/value.c =================================================================== RCS file: /cvs/src/src/gdb/value.c,v retrieving revision 1.72 diff -a -u -r1.72 value.c --- gdb/value.c 26 Nov 2008 16:27:27 -0000 1.72 +++ gdb/value.c 30 Dec 2008 00:16:44 -0000 @@ -1196,6 +1196,9 @@ it doesn't work when the decimal number has a fractional part. */ return decimal_to_doublest (valaddr, len); + case TYPE_CODE_FIXED: + return unpack_double (type, valaddr, 0); + case TYPE_CODE_PTR: case TYPE_CODE_REF: /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure @@ -1221,7 +1224,8 @@ int len; int nosign; - *invp = 0; /* Assume valid. */ + if(invp) + *invp = 0; CHECK_TYPEDEF (type); code = TYPE_CODE (type); len = TYPE_LENGTH (type); @@ -1247,7 +1251,8 @@ if (!floatformat_is_valid (floatformat_from_type (type), valaddr)) { - *invp = 1; + if(invp) + *invp = 1; return 0.0; } @@ -1255,6 +1260,26 @@ } else if (code == TYPE_CODE_DECFLOAT) return decimal_to_doublest (valaddr, len); + else if (code == TYPE_CODE_FIXED) + { + DOUBLEST value; + int binaryscale = TYPE_BINARYSCALE(type); + if (nosign) + value = extract_unsigned_integer (valaddr, len); + else + value = extract_signed_integer (valaddr, len); + + /* shift by the binary scale value */ + while(binaryscale < 0) { + binaryscale++; + value /= 2; + } + while(binaryscale > 0) { + binaryscale--; + value *= 2; + } + return value; + } else if (nosign) { /* Unsigned -- be sure we compensate for signed LONGEST. */ @@ -1738,6 +1763,16 @@ } struct value * +value_from_fixed (struct type *type, const gdb_byte *value) +{ + struct value *val = allocate_value (type); + + memcpy (value_contents_raw (val), value, TYPE_LENGTH (type)); + + return val; +} + +struct value * coerce_ref (struct value *arg) { struct type *value_type_arg_tmp = check_typedef (value_type (arg)); Index: gdb/value.h =================================================================== RCS file: /cvs/src/src/gdb/value.h,v retrieving revision 1.126 diff -a -u -r1.126 value.h --- gdb/value.h 22 Dec 2008 23:11:56 -0000 1.126 +++ gdb/value.h 30 Dec 2008 00:16:44 -0000 @@ -284,6 +284,9 @@ extern struct value *value_from_double (struct type *type, DOUBLEST num); extern struct value *value_from_decfloat (struct type *type, const gdb_byte *decbytes); +extern struct value *value_from_fixed (struct type *type, + const gdb_byte *value); + extern struct value *value_from_string (char *string); extern struct value *value_at (struct type *type, CORE_ADDR addr);