* utils.c (perror_with_name): Is a NORETURN function.
(error): Is NORETURN independently of ANSI_PROTOTYPES.
* symtab.c (fixup_symbol_section): Remove prototype.
* symtab.h: (fixup_symbol_section): Add prototype.
* m32r-rom.c (report_transfer_performance): Add prototype.
* sparclet-rom.c: Ditto.
* dsrec.c: Ditto.
* c-exp.y (parse_number): Cast args to float* or double* as
appropriate for conversion format.
* java-exp.y (parse_number): Ditto.
* Makefile.in (c-exp.tab.c): Remove #line lines that refer
to nonexistant y.tab.c file.
(java-exp.tab.c): Ditto.
(f-exp.tab.c): Ditto.
(m2-exp.tab.c): Ditto.
start-sanitize-gdbtk
* gdbtk.c (gdbtk_init): Make truth value test explicit.
Remove unused static variable "Gdbtk_Library".
end-sanitize-gdbtk
+Fri Jun 13 07:30:48 1997 Fred Fish <fnf@cygnus.com>
+
+ * defs.h (perror_with_name): Is a NORETURN function.
+ * utils.c (perror_with_name): Is a NORETURN function.
+ (error): Is NORETURN independently of ANSI_PROTOTYPES.
+
+ * symtab.c (fixup_symbol_section): Remove prototype.
+ * symtab.h: (fixup_symbol_section): Add prototype.
+ * m32r-rom.c (report_transfer_performance): Add prototype.
+ * sparclet-rom.c: Ditto.
+ * dsrec.c: Ditto.
+
+ * c-exp.y (parse_number): Cast args to float* or double* as
+ appropriate for conversion format.
+ * java-exp.y (parse_number): Ditto.
+
+ * Makefile.in (c-exp.tab.c): Remove #line lines that refer
+ to nonexistant y.tab.c file.
+ (java-exp.tab.c): Ditto.
+ (f-exp.tab.c): Ditto.
+ (m2-exp.tab.c): Ditto.
+start-sanitize-gdbtk
+
+ * gdbtk.c (gdbtk_init): Make truth value test explicit.
+ Remove unused static variable "Gdbtk_Library".
+end-sanitize-gdbtk
+
Sat Jun 7 02:34:19 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
start-sanitize-gdbtk
#start-sanitize-gdbtk
# Where is the TCL library? Typically in ../tcl.
LIB_INSTALL_DIR = $(libdir)
+# This variable is needed when doing dynamic linking.
+LIB_RUNTIME_DIR = $(libdir)
TCL = @TCL_LD_SEARCH_FLAGS@ @TCL_BUILD_LIB_SPEC@
TCL_CFLAGS = @TCLHDIR@
-e '/include.*malloc.h/d' \
-e 's/malloc/xmalloc/g' \
-e 's/realloc/xrealloc/g' \
+ -e '/^#line.*y.tab.c/d' \
< y.tab.c > c-exp.new
-rm y.tab.c
mv c-exp.new ./c-exp.tab.c
-e '/include.*malloc.h/d' \
-e 's/malloc/xmalloc/g' \
-e 's/realloc/xrealloc/g' \
+ -e '/^#line.*y.tab.c/d' \
< y.tab.c > java-exp.new
-rm y.tab.c
mv java-exp.new ./java-exp.tab.c
-e '/include.*malloc.h/d' \
-e 's/malloc/xmalloc/g' \
-e 's/realloc/xrealloc/g' \
+ -e '/^#line.*y.tab.c/d' \
< y.tab.c > f-exp.new
-rm y.tab.c
mv f-exp.new ./f-exp.tab.c
-e '/include.*malloc.h/d' \
-e 's/malloc/xmalloc/g' \
-e 's/realloc/xrealloc/g' \
+ -e '/^#line.*y.tab.c/d' \
< y.tab.c > m2-exp.new
-rm y.tab.c
mv m2-exp.new ./m2-exp.tab.c
$(gdbtypes_h) language.h objfiles.h symfile.h $(symtab_h) target.h \
$(value_h) gdb_string.h
+gnu-nat.o: process_reply_S.h exc_request_S.h notify_S.h msg_reply_S.h \
+ exc_request_U.h msg_U.h gnu-nat.h
+
go32-xdep.o: go32-xdep.c
gould-tdep.o: gould-tdep.c $(OP_INCLUDE)/np1.h $(defs_h) $(frame_h) \
hppab-nat.o: hppab-nat.c $(bfd_h) $(defs_h) $(inferior_h) target.h
hppah-nat.o: hppah-nat.c $(bfd_h) $(defs_h) $(inferior_h) target.h
+i386gnu-nat.o: gnu-nat.h
+
i386-tdep.o: i386-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
gdb_string.h
p[len] = 0; /* null-terminate the token */
if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
- num = sscanf (p, "%g%c", &putithere->typed_val_float.dval,&c);
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
- num = sscanf (p, "%lg%c", &putithere->typed_val_float.dval,&c);
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
else
{
#ifdef PRINTF_HAS_LONG_DOUBLE
extern void fprintf_symbol_filtered PARAMS ((GDB_FILE *, char *,
enum language, int));
-extern void perror_with_name PARAMS ((char *));
+extern NORETURN void perror_with_name PARAMS ((char *)) ATTR_NORETURN;
extern void print_sys_errmsg PARAMS ((char *, int));
extern char *warning_pre_print;
-extern NORETURN void error PARAMS((char *, ...)) ATTR_NORETURN;
+extern NORETURN void error PARAMS((const char *, ...)) ATTR_NORETURN;
extern void error_begin PARAMS ((void));
extern void warning_begin PARAMS ((void));
-extern void warning PARAMS ((char *, ...))
+extern void warning PARAMS ((const char *, ...))
ATTR_FORMAT(printf, 1, 2);
/* Global functions from other, non-gdb GNU thingies.
--- /dev/null
+/* S-record download support for GDB, the GNU debugger.
+ Copyright 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "serial.h"
+#include "srec.h"
+#include <time.h>
+
+extern void report_transfer_performance PARAMS ((unsigned long, time_t, time_t));
+
+extern int remote_debug;
+
+static int make_srec PARAMS ((char *srec, CORE_ADDR targ_addr, bfd *abfd,
+ asection *sect, int sectoff, int *maxrecsize,
+ int flags));
+
+/* Download an executable by converting it to S records. DESC is a serial_t
+ to send the data to. FILE is the name of the file to be loaded.
+ LOAD_OFFSET is the offset into memory to load data into. It is usually
+ specified by the user and is useful with the a.out file format.
+ MAXRECSIZE is the length in chars of the largest S-record the host can
+ accomodate. This is measured from the starting `S' to the last char of the
+ checksum. FLAGS is various random flags, and HASHMARK is non-zero to cause
+ a `#' to be printed out for each record loaded. WAITACK, if non-NULL, is
+ a function that waits for an acknowledgement after each S-record, and
+ returns non-zero if the ack is read correctly. */
+
+void
+load_srec (desc, file, load_offset, maxrecsize, flags, hashmark, waitack)
+ serial_t desc;
+ const char *file;
+ bfd_vma load_offset;
+ int maxrecsize;
+ int flags;
+ int hashmark;
+ int (*waitack) PARAMS ((void));
+{
+ bfd *abfd;
+ asection *s;
+ char *srec;
+ int i;
+ int reclen;
+ time_t start_time, end_time;
+ unsigned long data_count = 0;
+
+ srec = (char *)alloca (maxrecsize + 1);
+
+ abfd = bfd_openr (file, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", file);
+ return;
+ }
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
+ return;
+ }
+
+ start_time = time (NULL);
+
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ int numbytes;
+ bfd_vma addr = bfd_get_section_vma (abfd, s) + load_offset;
+ bfd_size_type size = bfd_get_section_size_before_reloc (s);
+
+ printf_filtered ("%s\t: 0x%08x .. 0x%08x ",
+ bfd_get_section_name (abfd, s),
+ (int) addr, (int) addr + size);
+ gdb_flush (gdb_stdout);
+
+ data_count += size;
+
+ for (i = 0; i < size; i += numbytes)
+ {
+ reclen = maxrecsize;
+ numbytes = make_srec (srec, (CORE_ADDR) (addr + i), abfd, s,
+ i, &reclen, flags);
+
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stderr, "%.*s\\r\n", reclen-1, srec);
+
+ /* Repeatedly send the S-record until a good acknowledgement
+ is sent back. */
+ do
+ {
+ SERIAL_WRITE (desc, srec, reclen);
+ }
+ while (waitack != NULL && !waitack());
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+ } /* Per-packet (or S-record) loop */
+
+ putchar_unfiltered ('\n');
+ } /* Loadable sections */
+
+ if (hashmark)
+ putchar_unfiltered ('\n');
+
+ end_time = time (NULL);
+
+ /* Write a type 7 terminator record. no data for a type 7, and there
+ is no data, so len is 0. */
+
+ reclen = maxrecsize;
+ make_srec (srec, abfd->start_address, NULL, NULL, 0, &reclen, flags);
+
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stderr, "%.*s\\r\n", reclen-1, srec);
+ SERIAL_WRITE (desc, srec, reclen);
+
+ SERIAL_WRITE (desc, "\r\r", 2); /* Some monitors need these to wake up */
+
+ SERIAL_FLUSH_INPUT (desc);
+
+ report_transfer_performance (data_count, start_time, end_time);
+}
+
+/*
+ * make_srec -- make an srecord. This writes each line, one at a
+ * time, each with it's own header and trailer line.
+ * An srecord looks like this:
+ *
+ * byte count-+ address
+ * start ---+ | | data +- checksum
+ * | | | |
+ * S01000006F6B692D746573742E73726563E4
+ * S315000448600000000000000000FC00005900000000E9
+ * S31A0004000023C1400037DE00F023604000377B009020825000348D
+ * S30B0004485A0000000000004E
+ * S70500040000F6
+ *
+ * S<type><length><address><data><checksum>
+ *
+ * Where
+ * - length
+ * is the number of bytes following upto the checksum. Note that
+ * this is not the number of chars following, since it takes two
+ * chars to represent a byte.
+ * - type
+ * is one of:
+ * 0) header record
+ * 1) two byte address data record
+ * 2) three byte address data record
+ * 3) four byte address data record
+ * 7) four byte address termination record
+ * 8) three byte address termination record
+ * 9) two byte address termination record
+ *
+ * - address
+ * is the start address of the data following, or in the case of
+ * a termination record, the start address of the image
+ * - data
+ * is the data.
+ * - checksum
+ * is the sum of all the raw byte data in the record, from the length
+ * upwards, modulo 256 and subtracted from 255.
+ *
+ * This routine returns the length of the S-record.
+ *
+ */
+
+static int
+make_srec (srec, targ_addr, abfd, sect, sectoff, maxrecsize, flags)
+ char *srec;
+ CORE_ADDR targ_addr;
+ bfd *abfd;
+ asection *sect;
+ int sectoff;
+ int *maxrecsize;
+ int flags;
+{
+ unsigned char checksum;
+ int tmp;
+ const static char hextab[] = "0123456789ABCDEF";
+ const static char data_code_table[] = "xx123";
+ const static char term_code_table[] = "xx987";
+ const static char *formats[] = {NULL, NULL, "S%c%02X%04X", "S%c%02X%06X",
+ "S%c%02X%08X"};
+ char const *code_table;
+ int addr_size;
+ int payload_size;
+ int type_code;
+ char *binbuf;
+ char *p;
+
+ if (sect)
+ {
+ tmp = flags; /* Data record */
+ code_table = data_code_table;
+ binbuf = alloca (*maxrecsize/2);
+ }
+ else
+ {
+ tmp = flags >> SREC_TERM_SHIFT; /* Term record */
+ code_table = term_code_table;
+ }
+
+ if ((tmp & SREC_2_BYTE_ADDR) && (targ_addr <= 0xffff))
+ addr_size = 2;
+ else if ((tmp & SREC_3_BYTE_ADDR) && (targ_addr <= 0xffffff))
+ addr_size = 3;
+ else if (tmp & SREC_4_BYTE_ADDR)
+ addr_size = 4;
+ else
+ fatal ("make_srec: Bad address (0x%x), or bad flags (0x%x).", targ_addr,
+ flags);
+
+/* Now that we know the address size, we can figure out how much data this
+ record can hold. */
+
+ if (sect)
+ {
+ payload_size = (*maxrecsize - (1 + 1 + 2 + addr_size * 2 + 2)) / 2;
+ payload_size = min (payload_size, sect->_raw_size - sectoff);
+
+ bfd_get_section_contents (abfd, sect, binbuf, sectoff, payload_size);
+ }
+ else
+ payload_size = 0; /* Term packets have no payload */
+
+/* Output the header. */
+
+ sprintf (srec, formats[addr_size], code_table[addr_size],
+ addr_size + payload_size + 1, targ_addr);
+
+/* Note that the checksum is calculated on the raw data, not the hexified
+ data. It includes the length, address and the data portions of the
+ packet. */
+
+ checksum = 0;
+
+ checksum += (payload_size + addr_size + 1 /* Packet length */
+ + (targ_addr & 0xff) /* Address... */
+ + ((targ_addr >> 8) & 0xff)
+ + ((targ_addr >> 16) & 0xff)
+ + ((targ_addr >> 24) & 0xff));
+
+ p = srec + 1 + 1 + 2 + addr_size * 2;
+
+ /* build the srecord */
+ for (tmp = 0; tmp < payload_size; tmp++)
+ {
+ unsigned char k;
+
+ k = binbuf[tmp];
+ *p++ = hextab [k >> 4];
+ *p++ = hextab [k & 0xf];
+ checksum += k;
+ }
+
+ checksum = ~checksum;
+
+ *p++ = hextab[checksum >> 4];
+ *p++ = hextab[checksum & 0xf];
+ *p++ = '\r';
+
+ *maxrecsize = p - srec;
+ return payload_size;
+}
static int disassemble_from_exec = -1;
-static char *Gdbtk_Library;
-
/* Supply malloc calls for tcl/tk. */
char *
}
}
}
- while (lib = strtok (NULL, ":"));
+ while ((lib = strtok (NULL, ":")) != NULL);
if (!found_main)
{
p[len] = 0; /* null-terminate the token */
if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
- num = sscanf (p, "%g%c", &putithere->typed_val_float.dval, &c);
+ num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
- num = sscanf (p, "%lg%c", &putithere->typed_val_float.dval, &c);
+ num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
else
{
#ifdef PRINTF_HAS_LONG_DOUBLE
#include "symfile.h" /* for generic_load */
#include <time.h>
+extern void report_transfer_performance PARAMS ((unsigned long, time_t, time_t));
+
static struct target_ops sparclet_ops;
static void sparclet_open PARAMS ((char *args, int from_tty));
\f
-struct symbol * fixup_symbol_section PARAMS ((struct symbol *,
- struct objfile *));
struct partial_symbol * fixup_psymbol_section PARAMS ((struct partial_symbol *,
struct objfile *));
also tries to set it correctly). */
short section;
+
+ /* The bfd section associated with this symbol. */
+
+ asection *bfd_section;
};
+extern CORE_ADDR symbol_overlayed_address PARAMS((CORE_ADDR, asection *));
+
#define SYMBOL_NAME(symbol) (symbol)->ginfo.name
#define SYMBOL_VALUE(symbol) (symbol)->ginfo.value.ivalue
#define SYMBOL_VALUE_ADDRESS(symbol) (symbol)->ginfo.value.address
#define SYMBOL_VALUE_CHAIN(symbol) (symbol)->ginfo.value.chain
#define SYMBOL_LANGUAGE(symbol) (symbol)->ginfo.language
#define SYMBOL_SECTION(symbol) (symbol)->ginfo.section
+#define SYMBOL_BFD_SECTION(symbol) (symbol)->ginfo.bfd_section
#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol) \
(symbol)->ginfo.language_specific.cplus_specific.demangled_name
mst_file_data, /* Static version of mst_data */
mst_file_bss /* Static version of mst_bss */
} type BYTE_BITFIELD;
-
};
#define MSYMBOL_INFO(msymbol) (msymbol)->info
/* Name space code. */
+#ifdef __MFC4__
+ /* FIXME: don't conflict with C++'s namespace */
+ /* would be safer to do a global change for all namespace identifiers. */
+ #define namespace _namespace
+#endif
namespace_enum namespace BYTE_BITFIELD;
/* Address class */
extern int demangle;
extern int asm_demangle;
+/* symtab.c lookup functions */
+
+/* lookup a symbol table by source file name */
+
extern struct symtab *
lookup_symtab PARAMS ((char *));
+/* lookup a symbol by name (optional block, optional symtab) */
+
extern struct symbol *
lookup_symbol PARAMS ((const char *, const struct block *,
const namespace_enum, int *, struct symtab **));
+/* lookup a symbol by name, within a specified block */
+
extern struct symbol *
lookup_block_symbol PARAMS ((const struct block *, const char *,
const namespace_enum));
+/* lookup a [struct, union, enum] by name, within a specified block */
+
extern struct type *
lookup_struct PARAMS ((char *, struct block *));
extern struct type *
lookup_enum PARAMS ((char *, struct block *));
+/* lookup the function corresponding to the block */
+
extern struct symbol *
block_function PARAMS ((struct block *));
+/* from blockframe.c: */
+
+/* lookup the function symbol corresponding to the address */
+
extern struct symbol *
find_pc_function PARAMS ((CORE_ADDR));
-extern int find_pc_partial_function
- PARAMS ((CORE_ADDR, char **, CORE_ADDR *, CORE_ADDR *));
+/* lookup the function corresponding to the address and section */
+
+extern struct symbol *
+find_pc_sect_function PARAMS ((CORE_ADDR, asection *));
+
+/* lookup function from address, return name, start addr and end addr */
+
+extern int find_pc_partial_function PARAMS ((CORE_ADDR, char **,
+ CORE_ADDR *, CORE_ADDR *));
extern void
clear_pc_function_cache PARAMS ((void));
+/* from symtab.c: */
+
+/* lookup partial symbol table by filename */
+
extern struct partial_symtab *
lookup_partial_symtab PARAMS ((char *));
+/* lookup partial symbol table by address */
+
extern struct partial_symtab *
find_pc_psymtab PARAMS ((CORE_ADDR));
+/* lookup partial symbol table by address and section */
+
+extern struct partial_symtab *
+find_pc_sect_psymtab PARAMS ((CORE_ADDR, asection *));
+
+/* lookup full symbol table by address */
+
extern struct symtab *
find_pc_symtab PARAMS ((CORE_ADDR));
+/* lookup full symbol table by address and section */
+
+extern struct symtab *
+find_pc_sect_symtab PARAMS ((CORE_ADDR, asection *));
+
+/* lookup partial symbol by address */
+
extern struct partial_symbol *
find_pc_psymbol PARAMS ((struct partial_symtab *, CORE_ADDR));
+/* lookup partial symbol by address and section */
+
+extern struct partial_symbol *
+find_pc_sect_psymbol PARAMS ((struct partial_symtab *, CORE_ADDR, asection *));
+
extern int
find_pc_line_pc_range PARAMS ((CORE_ADDR, CORE_ADDR *, CORE_ADDR *));
PARAMS ((const char *, CORE_ADDR,
enum minimal_symbol_type,
char *info, int section,
+ asection *bfd_section,
struct objfile *));
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
extern struct minimal_symbol *
lookup_minimal_symbol_by_pc PARAMS ((CORE_ADDR));
+extern struct minimal_symbol *
+lookup_minimal_symbol_by_pc_section PARAMS ((CORE_ADDR, asection *));
+
extern struct minimal_symbol *
lookup_solib_trampoline_symbol_by_pc PARAMS ((CORE_ADDR));
struct symtab_and_line
{
struct symtab *symtab;
-
+ asection *section;
/* Line number. Line numbers start at 1 and proceed through symtab->nlines.
0 is never a valid line number; it is used to indicate that line number
information is not available. */
CORE_ADDR end;
};
+#define INIT_SAL(sal) { \
+ (sal)->symtab = 0; \
+ (sal)->section = 0; \
+ (sal)->line = 0; \
+ (sal)->pc = 0; \
+ (sal)->end = 0; \
+}
+
struct symtabs_and_lines
{
struct symtab_and_line *sals;
extern struct symtab_and_line
find_pc_line PARAMS ((CORE_ADDR, int));
+/* Same function, but specify a section as well as an address */
+
+extern struct symtab_and_line
+find_pc_sect_line PARAMS ((CORE_ADDR, asection *, int));
+
/* Given an address, return the nearest symbol at or below it in memory.
Optionally return the symtab it's from through 2nd arg, and the
address in inferior memory of the symbol through 3rd arg. */
extern struct symtabs_and_lines
decode_line_1 PARAMS ((char **, int, struct symtab *, int, char ***));
-/* Symmisc.c */
-
#if MAINTENANCE_CMDS
+/* Symmisc.c */
+
void
maintenance_print_symbols PARAMS ((char *, int));
void
maintenance_check_symtabs PARAMS ((char *, int));
+/* maint.c */
+
+void
+maintenance_print_statistics PARAMS ((char *, int));
+
#endif
extern void
extern struct blockvector *
blockvector_for_pc PARAMS ((CORE_ADDR, int *));
+
+extern struct blockvector *
+blockvector_for_pc_sect PARAMS ((CORE_ADDR, asection *, int *,
+ struct symtab *));
/* symfile.c */
extern void
extern int
in_prologue PARAMS ((CORE_ADDR pc, CORE_ADDR func_start));
+extern struct symbol *
+fixup_symbol_section PARAMS ((struct symbol *, struct objfile *));
+
#endif /* !defined(SYMTAB_H) */
The first argument STRING is the error message, used as a fprintf string,
and the remaining args are passed as arguments to it. */
-#ifdef ANSI_PROTOTYPES
+/* VARARGS */
NORETURN void
+#ifdef ANSI_PROTOTYPES
error (const char *string, ...)
#else
void
as the file name for which the error was encountered.
Then return to command level. */
-void
+NORETURN void
perror_with_name (string)
char *string;
{
/* Start at the least significant part of the field. */
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
cur_bitshift =
((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
result = *(data + cur_byte) >> (-cur_bitshift);
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
else
result |= *(data + cur_byte) << cur_bitshift;
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
int mant_bits_left;
int special_exponent; /* It's a NaN, denorm or zero */
+ /* If the mantissa bits are not contiguous from one end of the
+ mantissa to the other, we need to make a private copy of the
+ source bytes that is in the right order since the unpacking
+ algorithm assumes that the bits are contiguous.
+
+ Swap the bytes individually rather than accessing them through
+ "long *" since we have no guarantee that they start on a long
+ alignment, and also sizeof(long) for the host could be different
+ than sizeof(long) for the target. FIXME: Assumes sizeof(long)
+ for the target is 4. */
+
+ if (fmt -> byteorder == floatformat_littlebyte_bigword)
+ {
+ static unsigned char *newfrom;
+ unsigned char *swapin, *swapout;
+ int longswaps;
+
+ longswaps = fmt -> totalsize / FLOATFORMAT_CHAR_BIT;
+ longswaps >>= 3;
+
+ if (newfrom == NULL)
+ {
+ newfrom = xmalloc (fmt -> totalsize);
+ }
+ swapout = newfrom;
+ swapin = ufrom;
+ ufrom = newfrom;
+ while (longswaps-- > 0)
+ {
+ /* This is ugly, but efficient */
+ *swapout++ = swapin[4];
+ *swapout++ = swapin[5];
+ *swapout++ = swapin[6];
+ *swapout++ = swapin[7];
+ *swapout++ = swapin[0];
+ *swapout++ = swapin[1];
+ *swapout++ = swapin[2];
+ *swapout++ = swapin[3];
+ swapin += 8;
+ }
+ }
+
exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
fmt->exp_start, fmt->exp_len);
/* Note that if exponent indicates a NaN, we can't really do anything useful
/* Start at the least significant part of the field. */
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
cur_bitshift =
((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
*(data + cur_byte) |=
(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
& ((1 << FLOATFORMAT_CHAR_BIT) - 1));
cur_bitshift += FLOATFORMAT_CHAR_BIT;
- if (order == floatformat_little)
+ if (order == floatformat_little || order == floatformat_littlebyte_bigword)
++cur_byte;
else
--cur_byte;
memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
if (dfrom == 0)
return; /* Result is zero */
- if (dfrom != dfrom)
+ if (dfrom != dfrom) /* Result is NaN */
{
/* From is NaN */
put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
dfrom = -dfrom;
}
- /* How to tell an infinity from an ordinary number? FIXME-someday */
+ if (dfrom + 1 == dfrom) /* Result is Infinity */
+ {
+ /* Infinity exponent is same as NaN's. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Infinity mantissa is all zeroes. */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ fmt->man_len, 0);
+ return;
+ }
#ifdef HAVE_LONG_DOUBLE
mant = ldfrexp (dfrom, &exponent);
mant_off += mant_bits;
mant_bits_left -= mant_bits;
}
+ if (fmt -> byteorder == floatformat_littlebyte_bigword)
+ {
+ int count;
+ unsigned char *swaplow = uto;
+ unsigned char *swaphigh = uto + 4;
+ unsigned char tmp;
+
+ for (count = 0; count < 4; count++)
+ {
+ tmp = *swaplow;
+ *swaplow++ = *swaphigh;
+ *swaphigh++ = tmp;
+ }
+ }
}
/* temporary storage using circular buffer */