From: Michal Ludvig Date: Fri, 7 Jun 2002 16:11:10 +0000 (+0000) Subject: 2002-06-07 Michal Ludvig X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8dda97708fa5c4537d670a063d4a1b9a2690f3b5;p=binutils-gdb.git 2002-06-07 Michal Ludvig * x86-64-linux-nat.c (x86_64_fxsave_offset): New. (supply_fpregset, fill_fpregset): Don't call i387_*_fxsave, better do the things actually here. * x86-64-tdep.c (x86_64_register_name2nr): New. (x86_64_register_name): Renamed to x86_64_register_nr2name. (x86_64_gdbarch_init): Respect the above change. * x86-64-tdep.h (x86_64_register_name2nr) (x86_64_register_nr2name): Add prototypes. * config/i386/x86-64linux.mt (TDEPFILES): Remove i387-tdep.o. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1285ec1ac5a..82d60b30822 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2002-06-07 Michal Ludvig + + * x86-64-linux-nat.c (x86_64_fxsave_offset): New. + (supply_fpregset, fill_fpregset): Don't call i387_*_fxsave, + better do the things actually here. + * x86-64-tdep.c (x86_64_register_name2nr): New. + (x86_64_register_name): Renamed to x86_64_register_nr2name. + (x86_64_gdbarch_init): Respect the above change. + * x86-64-tdep.h (x86_64_register_name2nr) + (x86_64_register_nr2name): Add prototypes. + * config/i386/x86-64linux.mt (TDEPFILES): Remove i387-tdep.o. + 2002-06-06 Michael Snyder * d10v-tdep.c (d10v_push_arguments): Handle struct_return. diff --git a/gdb/config/i386/x86-64linux.mt b/gdb/config/i386/x86-64linux.mt index 85f1972531d..58a9cee1889 100644 --- a/gdb/config/i386/x86-64linux.mt +++ b/gdb/config/i386/x86-64linux.mt @@ -1,3 +1,3 @@ # Target: AMD x86-64 running GNU/Linux -TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o i387-tdep.o dwarf2cfi.o \ +TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o dwarf2cfi.o \ solib.o solib-svr4.o solib-legacy.o diff --git a/gdb/x86-64-linux-nat.c b/gdb/x86-64-linux-nat.c index f57a5f27675..4c4f64382c4 100644 --- a/gdb/x86-64-linux-nat.c +++ b/gdb/x86-64-linux-nat.c @@ -25,7 +25,6 @@ #include "inferior.h" #include "gdbcore.h" #include "regcache.h" -#include "i387-tdep.h" #include "gdb_assert.h" #include "x86-64-tdep.h" @@ -195,23 +194,73 @@ store_regs (int tid, int regno) /* Transfering floating-point registers between GDB, inferiors and cores. */ -/* Fill GDB's register array with the floating-point register values in - *FPREGSETP. */ +static void * +x86_64_fxsave_offset (elf_fpregset_t * fxsave, int regnum) +{ + char *reg_name; + int reg_index; + + gdb_assert (x86_64_num_gregs - 1 < regnum && regnum < x86_64_num_regs); + + reg_name = x86_64_register_nr2name (regnum); + + if (reg_name[0] == 's' && reg_name[1] == 't') + { + reg_index = reg_name[2] - '0'; + return &fxsave->st_space[reg_index * 2]; + } + + if (reg_name[0] == 'x' && reg_name[1] == 'm' && reg_name[2] == 'm') + { + reg_index = reg_name[3] - '0'; + return &fxsave->xmm_space[reg_index * 4]; + } + + if (strcmp (reg_name, "mxcsr") == 0) + return &fxsave->mxcsr; + + return NULL; +} + +/* Fill GDB's register array with the floating-point and SSE register + values in *FXSAVE. This function masks off any of the reserved + bits in *FXSAVE. */ void -supply_fpregset (elf_fpregset_t * fpregsetp) +supply_fpregset (elf_fpregset_t * fxsave) { - i387_supply_fxsave ((char *) fpregsetp); + int i, reg_st0, reg_mxcsr; + + reg_st0 = x86_64_register_name2nr ("st0"); + reg_mxcsr = x86_64_register_name2nr ("mxcsr"); + + gdb_assert (reg_st0 > 0 && reg_mxcsr > reg_st0); + + for (i = reg_st0; i <= reg_mxcsr; i++) + supply_register (i, x86_64_fxsave_offset (fxsave, i)); } -/* Fill register REGNO (if it is a floating-point register) in - *FPREGSETP with the value in GDB's register array. If REGNO is -1, - do this for all registers. */ +/* Fill register REGNUM (if it is a floating-point or SSE register) in + *FXSAVE with the value in GDB's register array. If REGNUM is -1, do + this for all registers. This function doesn't touch any of the + reserved bits in *FXSAVE. */ void -fill_fpregset (elf_fpregset_t * fpregsetp, int regno) +fill_fpregset (elf_fpregset_t * fxsave, int regnum) { - i387_fill_fxsave ((char *) fpregsetp, regno); + int i, last_regnum = MXCSR_REGNUM; + void *ptr; + + if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0) + last_regnum = FOP_REGNUM; + + for (i = FP0_REGNUM; i <= last_regnum; i++) + if (regnum == -1 || regnum == i) + { + ptr = x86_64_fxsave_offset (fxsave, i); + if (ptr) + regcache_collect (i, ptr); + } } /* Fetch all floating-point registers from process/thread TID and store diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c index a3f8bee1682..6391e756c9b 100644 --- a/gdb/x86-64-tdep.c +++ b/gdb/x86-64-tdep.c @@ -376,14 +376,15 @@ classify_argument (struct type *type, { int num = classify_argument (TYPE_FIELDS (type)[j].type, subclasses, - (TYPE_FIELDS (type)[j].loc.bitpos - + bit_offset) % 256); + (TYPE_FIELDS (type)[j].loc. + bitpos + bit_offset) % 256); if (!num) return 0; for (i = 0; i < num; i++) { int pos = - (TYPE_FIELDS (type)[j].loc.bitpos + bit_offset) / 8 / 8; + (TYPE_FIELDS (type)[j].loc.bitpos + + bit_offset) / 8 / 8; classes[i + pos] = merge_classes (subclasses[i], classes[i + pos]); } @@ -490,7 +491,7 @@ classify_argument (struct type *type, } case TYPE_CODE_VOID: return 0; - default: /* Avoid warning. */ + default: /* Avoid warning. */ break; } internal_error (__FILE__, __LINE__, @@ -797,13 +798,24 @@ x86_64_store_return_value (struct type *type, char *valbuf) } -static char * -x86_64_register_name (int reg_nr) +char * +x86_64_register_nr2name (int reg_nr) { if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS) return NULL; return x86_64_register_info_table[reg_nr].name; } + +int +x86_64_register_name2nr (const char *name) +{ + int reg_nr; + + for (reg_nr = 0; reg_nr < X86_64_NUM_REGS; reg_nr++) + if (strcmp (name, x86_64_register_info_table[reg_nr].name) == 0) + return reg_nr; + return -1; +} @@ -862,7 +874,7 @@ x86_64_skip_prologue (CORE_ADDR pc) /* First check, whether pc points to pushq %rbp, movq %rsp,%rbp. */ for (i = 0; i < PROLOG_BUFSIZE; i++) if (prolog_expect[i] != prolog_buf[i]) - return pc; /* ... no, it doesn't. Nothing to skip. */ + return pc; /* ... no, it doesn't. Nothing to skip. */ /* OK, we have found the prologue and want PC of the first non-prologue instruction. */ @@ -982,7 +994,7 @@ x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext); set_gdbarch_num_regs (gdbarch, X86_64_NUM_REGS); - set_gdbarch_register_name (gdbarch, x86_64_register_name); + set_gdbarch_register_name (gdbarch, x86_64_register_nr2name); set_gdbarch_register_size (gdbarch, 8); set_gdbarch_register_raw_size (gdbarch, x86_64_register_raw_size); set_gdbarch_max_register_raw_size (gdbarch, 16); diff --git a/gdb/x86-64-tdep.h b/gdb/x86-64-tdep.h index d15b8e71e7f..dda94bc5eb8 100644 --- a/gdb/x86-64-tdep.h +++ b/gdb/x86-64-tdep.h @@ -28,6 +28,9 @@ extern int x86_64_num_regs; extern int x86_64_num_gregs; +int x86_64_register_name2nr (const char *name); +char *x86_64_register_nr2name (int reg_nr); + gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc; gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;