diff options
author | Fred Fish <fnf@specifix.com> | 1992-05-03 23:05:07 +0000 |
---|---|---|
committer | Fred Fish <fnf@specifix.com> | 1992-05-03 23:05:07 +0000 |
commit | 4db8e515c4db19f91a671c81fcc87bbc2b48c242 (patch) | |
tree | 6f5baa70bf3b92aa0ce5e19d909165c549b88b93 /gdb/values.c | |
parent | d752f749c86c0b43e54d2da9f5963e27f5baa3e3 (diff) | |
download | gdb-4db8e515c4db19f91a671c81fcc87bbc2b48c242.zip gdb-4db8e515c4db19f91a671c81fcc87bbc2b48c242.tar.gz gdb-4db8e515c4db19f91a671c81fcc87bbc2b48c242.tar.bz2 |
* Makefile.in (VERSION): Bump to 4.5.2.
* Makefile.in (DEMANGLE_OPTS): Add, default to -Dnounderscore.
* configure.in: Simplify ncr3000 gdb_host logic, add gdb_target.
* dwarfread.c (struct_type): Apply fix from Peggy Fieland for
proper handling of bit fields.
* gdbtypes.h (struct type): Clarify use of field.bitpos.
* symtab.h: Fix couple of misspellings in comments.
* value.h (struct value): Clarify use of bitpos.
* value.h (unpack_field_as_long): Change prototype, returns
LONGEST.
* values.c (unpack_field_as_long): Change return type to LONGEST,
sign extend unpacked fields that are signed, other rewriting.
* config/ncr3000.mt: New target config file.
Diffstat (limited to 'gdb/values.c')
-rw-r--r-- | gdb/values.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/gdb/values.c b/gdb/values.c index 895df77..c7ab7b7 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -1190,29 +1190,60 @@ baseclass_addr (type, index, valaddr, valuep, errp) return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8; } -long +/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at + VALADDR. + + Extracting bits depends on endianness of the machine. Compute the + number of least significant bits to discard. For big endian machines, + we compute the total number of bits in the anonymous object, subtract + off the bit count from the MSB of the object to the MSB of the + bitfield, then the size of the bitfield, which leaves the LSB discard + count. For little endian machines, the discard count is simply the + number of bits from the LSB of the anonymous object to the LSB of the + bitfield. + + If the field is signed, we also do sign extension. */ + +LONGEST unpack_field_as_long (type, valaddr, fieldno) struct type *type; char *valaddr; int fieldno; { - unsigned long val; + unsigned LONGEST val; + unsigned LONGEST valmask; int bitpos = TYPE_FIELD_BITPOS (type, fieldno); int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); + int lsbcount; - bcopy (valaddr + bitpos / 8, &val, sizeof val); - SWAP_TARGET_AND_HOST (&val, sizeof val); + bcopy (valaddr + bitpos / 8, &val, sizeof (val)); + SWAP_TARGET_AND_HOST (&val, sizeof (val)); + + /* Extract bits. See comment above. */ - /* Extracting bits depends on endianness of the machine. */ #if BITS_BIG_ENDIAN - val = val >> (sizeof val * 8 - bitpos % 8 - bitsize); + lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize); #else - val = val >> (bitpos % 8); + lsbcount = (bitpos % 8); #endif + val >>= lsbcount; - if (bitsize < 8 * sizeof (val)) - val &= (((unsigned long)1) << bitsize) - 1; - return val; + /* If the field does not entirely fill a LONGEST, then zero the sign bits. + If the field is signed, and is negative, then sign extend. */ + + if ((bitsize > 0) && (bitsize < 8 * sizeof (val))) + { + valmask = (((unsigned LONGEST) 1) << bitsize) - 1; + val &= valmask; + if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno))) + { + if (val & (valmask ^ (valmask >> 1))) + { + val |= ~valmask; + } + } + } + return (val); } /* Modify the value of a bitfield. ADDR points to a block of memory in |