This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[committed] Use prologue-value.c in s390-tdep.c
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Sun, 9 Apr 2006 02:29:27 +0200 (CEST)
- Subject: [committed] Use prologue-value.c in s390-tdep.c
Hello,
this removes the prologue_value infrastructure from s390-tdep.c
and uses the new generic code instead. Due to the changed data
type name and the switch from call-by-reference to call-by-value
calling convention, this requires some cosmetic changes.
I've also taken the opportunity to tighten the big conditional
in s390_analyze_prologue.
Tested on s390-ibm-linux and s390x-ibm-linux, both as-is and with
the DWARF-2 unwinder disabled. No regressions.
Committed to mainline.
Bye,
Ulrich
ChangeLog:
* Makefile.in (s390-tdep.o): Add dependency on $(prologue_value_h).
* s390-tdep.c: Include "prologue-value.h".
(struct prologue_value): Remove.
(pv_set_to_unknown, pv_set_to_constant, pv_set_to_register,
pv_constant_last, pv_add, pv_add_constant, pv_subtract,
pv_logical_and, pv_is_identical, pv_is_register): Remove.
(compute_x_addr): Remove, replace by ...
(s390_addr): ... this new function.
(struct s390_prologue_data): Use pv_t instead of prologue_value.
(s390_store, s390_load): Likewise.
(s390_prologue_frame_unwind_cache): Likewise.
(s390_analyze_prologue): Likewise. Also, simplify and combine
several conditional statements.
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.804
diff -c -p -r1.804 Makefile.in
*** gdb/Makefile.in 5 Apr 2006 21:51:11 -0000 1.804
--- gdb/Makefile.in 7 Apr 2006 19:22:18 -0000
*************** s390-tdep.o: s390-tdep.c $(defs_h) $(arc
*** 2515,2521 ****
$(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(objfiles_h) \
$(floatformat_h) $(regcache_h) $(trad_frame_h) $(frame_base_h) \
$(frame_unwind_h) $(dwarf2_frame_h) $(reggroups_h) $(regset_h) \
! $(value_h) $(gdb_assert_h) $(dis_asm_h) $(solib_svr4_h) $(s390_tdep_h)
scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
$(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
$(scm_tags_h)
--- 2516,2523 ----
$(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(objfiles_h) \
$(floatformat_h) $(regcache_h) $(trad_frame_h) $(frame_base_h) \
$(frame_unwind_h) $(dwarf2_frame_h) $(reggroups_h) $(regset_h) \
! $(value_h) $(gdb_assert_h) $(dis_asm_h) $(solib_svr4_h) \
! $(prologue_value_h) $(s390_tdep_h)
scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
$(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
$(scm_tags_h)
Index: gdb/s390-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/s390-tdep.c,v
retrieving revision 1.151
diff -c -p -r1.151 s390-tdep.c
*** gdb/s390-tdep.c 5 Apr 2006 20:01:19 -0000 1.151
--- gdb/s390-tdep.c 7 Apr 2006 19:22:18 -0000
***************
*** 44,49 ****
--- 44,50 ----
#include "gdb_assert.h"
#include "dis-asm.h"
#include "solib-svr4.h"
+ #include "prologue-value.h"
#include "s390-tdep.h"
*************** s390_regset_from_core_section (struct gd
*** 476,805 ****
}
- /* Prologue analysis. */
-
- /* When we analyze a prologue, we're really doing 'abstract
- interpretation' or 'pseudo-evaluation': running the function's code
- in simulation, but using conservative approximations of the values
- it would have when it actually runs. For example, if our function
- starts with the instruction:
-
- ahi r1, 42 # add halfword immediate 42 to r1
-
- we don't know exactly what value will be in r1 after executing this
- instruction, but we do know it'll be 42 greater than its original
- value.
-
- If we then see an instruction like:
-
- ahi r1, 22 # add halfword immediate 22 to r1
-
- we still don't know what r1's value is, but again, we can say it is
- now 64 greater than its original value.
-
- If the next instruction were:
-
- lr r2, r1 # set r2 to r1's value
-
- then we can say that r2's value is now the original value of r1
- plus 64. And so on.
-
- Of course, this can only go so far before it gets unreasonable. If
- we wanted to be able to say anything about the value of r1 after
- the instruction:
-
- xr r1, r3 # exclusive-or r1 and r3, place result in r1
-
- then things would get pretty complex. But remember, we're just
- doing a conservative approximation; if exclusive-or instructions
- aren't relevant to prologues, we can just say r1's value is now
- 'unknown'. We can ignore things that are too complex, if that loss
- of information is acceptable for our application.
-
- Once you've reached an instruction that you don't know how to
- simulate, you stop. Now you examine the state of the registers and
- stack slots you've kept track of. For example:
-
- - To see how large your stack frame is, just check the value of sp;
- if it's the original value of sp minus a constant, then that
- constant is the stack frame's size. If the sp's value has been
- marked as 'unknown', then that means the prologue has done
- something too complex for us to track, and we don't know the
- frame size.
-
- - To see whether we've saved the SP in the current frame's back
- chain slot, we just check whether the current value of the back
- chain stack slot is the original value of the sp.
-
- Sure, this takes some work. But prologue analyzers aren't
- quick-and-simple pattern patching to recognize a few fixed prologue
- forms any more; they're big, hairy functions. Along with inferior
- function calls, prologue analysis accounts for a substantial
- portion of the time needed to stabilize a GDB port. So I think
- it's worthwhile to look for an approach that will be easier to
- understand and maintain. In the approach used here:
-
- - It's easier to see that the analyzer is correct: you just see
- whether the analyzer properly (albiet conservatively) simulates
- the effect of each instruction.
-
- - It's easier to extend the analyzer: you can add support for new
- instructions, and know that you haven't broken anything that
- wasn't already broken before.
-
- - It's orthogonal: to gather new information, you don't need to
- complicate the code for each instruction. As long as your domain
- of conservative values is already detailed enough to tell you
- what you need, then all the existing instruction simulations are
- already gathering the right data for you.
-
- A 'struct prologue_value' is a conservative approximation of the
- real value the register or stack slot will have. */
-
- struct prologue_value {
-
- /* What sort of value is this? This determines the interpretation
- of subsequent fields. */
- enum {
-
- /* We don't know anything about the value. This is also used for
- values we could have kept track of, when doing so would have
- been too complex and we don't want to bother. The bottom of
- our lattice. */
- pv_unknown,
-
- /* A known constant. K is its value. */
- pv_constant,
-
- /* The value that register REG originally had *UPON ENTRY TO THE
- FUNCTION*, plus K. If K is zero, this means, obviously, just
- the value REG had upon entry to the function. REG is a GDB
- register number. Before we start interpreting, we initialize
- every register R to { pv_register, R, 0 }. */
- pv_register,
-
- } kind;
-
- /* The meanings of the following fields depend on 'kind'; see the
- comments for the specific 'kind' values. */
- int reg;
- CORE_ADDR k;
- };
-
-
- /* Set V to be unknown. */
- static void
- pv_set_to_unknown (struct prologue_value *v)
- {
- v->kind = pv_unknown;
- }
-
-
- /* Set V to the constant K. */
- static void
- pv_set_to_constant (struct prologue_value *v, CORE_ADDR k)
- {
- v->kind = pv_constant;
- v->k = k;
- }
-
-
- /* Set V to the original value of register REG, plus K. */
- static void
- pv_set_to_register (struct prologue_value *v, int reg, CORE_ADDR k)
- {
- v->kind = pv_register;
- v->reg = reg;
- v->k = k;
- }
-
-
- /* If one of *A and *B is a constant, and the other isn't, swap the
- pointers as necessary to ensure that *B points to the constant.
- This can reduce the number of cases we need to analyze in the
- functions below. */
- static void
- pv_constant_last (struct prologue_value **a,
- struct prologue_value **b)
- {
- if ((*a)->kind == pv_constant
- && (*b)->kind != pv_constant)
- {
- struct prologue_value *temp = *a;
- *a = *b;
- *b = temp;
- }
- }
-
-
- /* Set SUM to the sum of A and B. SUM, A, and B may point to the same
- 'struct prologue_value' object. */
- static void
- pv_add (struct prologue_value *sum,
- struct prologue_value *a,
- struct prologue_value *b)
- {
- pv_constant_last (&a, &b);
-
- /* We can handle adding constants to registers, and other constants. */
- if (b->kind == pv_constant
- && (a->kind == pv_register
- || a->kind == pv_constant))
- {
- sum->kind = a->kind;
- sum->reg = a->reg; /* not meaningful if a is pv_constant, but
- harmless */
- sum->k = a->k + b->k;
- }
-
- /* Anything else we don't know how to add. We don't have a
- representation for, say, the sum of two registers, or a multiple
- of a register's value (adding a register to itself). */
- else
- sum->kind = pv_unknown;
- }
-
-
- /* Add the constant K to V. */
- static void
- pv_add_constant (struct prologue_value *v, CORE_ADDR k)
- {
- struct prologue_value pv_k;
-
- /* Rather than thinking of all the cases we can and can't handle,
- we'll just let pv_add take care of that for us. */
- pv_set_to_constant (&pv_k, k);
- pv_add (v, v, &pv_k);
- }
-
-
- /* Subtract B from A, and put the result in DIFF.
-
- This isn't quite the same as negating B and adding it to A, since
- we don't have a representation for the negation of anything but a
- constant. For example, we can't negate { pv_register, R1, 10 },
- but we do know that { pv_register, R1, 10 } minus { pv_register,
- R1, 5 } is { pv_constant, <ignored>, 5 }.
-
- This means, for example, that we can subtract two stack addresses;
- they're both relative to the original SP. Since the frame pointer
- is set based on the SP, its value will be the original SP plus some
- constant (probably zero), so we can use its value just fine. */
- static void
- pv_subtract (struct prologue_value *diff,
- struct prologue_value *a,
- struct prologue_value *b)
- {
- pv_constant_last (&a, &b);
-
- /* We can subtract a constant from another constant, or from a
- register. */
- if (b->kind == pv_constant
- && (a->kind == pv_register
- || a->kind == pv_constant))
- {
- diff->kind = a->kind;
- diff->reg = a->reg; /* not always meaningful, but harmless */
- diff->k = a->k - b->k;
- }
-
- /* We can subtract a register from itself, yielding a constant. */
- else if (a->kind == pv_register
- && b->kind == pv_register
- && a->reg == b->reg)
- {
- diff->kind = pv_constant;
- diff->k = a->k - b->k;
- }
-
- /* We don't know how to subtract anything else. */
- else
- diff->kind = pv_unknown;
- }
-
-
- /* Set AND to the logical and of A and B. */
- static void
- pv_logical_and (struct prologue_value *and,
- struct prologue_value *a,
- struct prologue_value *b)
- {
- pv_constant_last (&a, &b);
-
- /* We can 'and' two constants. */
- if (a->kind == pv_constant
- && b->kind == pv_constant)
- {
- and->kind = pv_constant;
- and->k = a->k & b->k;
- }
-
- /* We can 'and' anything with the constant zero. */
- else if (b->kind == pv_constant
- && b->k == 0)
- {
- and->kind = pv_constant;
- and->k = 0;
- }
-
- /* We can 'and' anything with ~0. */
- else if (b->kind == pv_constant
- && b->k == ~ (CORE_ADDR) 0)
- *and = *a;
-
- /* We can 'and' a register with itself. */
- else if (a->kind == pv_register
- && b->kind == pv_register
- && a->reg == b->reg
- && a->k == b->k)
- *and = *a;
-
- /* Otherwise, we don't know. */
- else
- pv_set_to_unknown (and);
- }
-
-
- /* Return non-zero iff A and B are identical expressions.
-
- This is not the same as asking if the two values are equal; the
- result of such a comparison would have to be a pv_boolean, and
- asking whether two 'unknown' values were equal would give you
- pv_maybe. Same for comparing, say, { pv_register, R1, 0 } and {
- pv_register, R2, 0}. Instead, this is asking whether the two
- representations are the same. */
- static int
- pv_is_identical (struct prologue_value *a,
- struct prologue_value *b)
- {
- if (a->kind != b->kind)
- return 0;
-
- switch (a->kind)
- {
- case pv_unknown:
- return 1;
- case pv_constant:
- return (a->k == b->k);
- case pv_register:
- return (a->reg == b->reg && a->k == b->k);
- default:
- gdb_assert (0);
- }
- }
-
-
- /* Return non-zero if A is the original value of register number R
- plus K, zero otherwise. */
- static int
- pv_is_register (struct prologue_value *a, int r, CORE_ADDR k)
- {
- return (a->kind == pv_register
- && a->reg == r
- && a->k == k);
- }
-
-
/* Decoding S/390 instructions. */
/* Named opcode values for the S/390 instructions we recognize. Some
--- 477,482 ----
*************** is_rxy (bfd_byte *insn, int op1, int op2
*** 1032,1066 ****
}
! /* Set ADDR to the effective address for an X-style instruction, like:
!
! L R1, D2(X2, B2)
!
! Here, X2 and B2 are registers, and D2 is a signed 20-bit
! constant; the effective address is the sum of all three. If either
! X2 or B2 are zero, then it doesn't contribute to the sum --- this
! means that r0 can't be used as either X2 or B2.
!
! GPR is an array of general register values, indexed by GPR number,
! not GDB register number. */
! static void
! compute_x_addr (struct prologue_value *addr,
! struct prologue_value *gpr,
! int d2, unsigned int x2, unsigned int b2)
! {
! /* We can't just add stuff directly in addr; it might alias some of
! the registers we need to read. */
! struct prologue_value result;
!
! pv_set_to_constant (&result, d2);
! if (x2)
! pv_add (&result, &result, &gpr[x2]);
! if (b2)
! pv_add (&result, &result, &gpr[b2]);
!
! *addr = result;
! }
!
#define S390_NUM_GPRS 16
#define S390_NUM_FPRS 16
--- 709,715 ----
}
! /* Prologue analysis. */
#define S390_NUM_GPRS 16
#define S390_NUM_FPRS 16
*************** struct s390_prologue_data {
*** 1072,1081 ****
int fpr_size;
/* The general-purpose registers. */
! struct prologue_value gpr[S390_NUM_GPRS];
/* The floating-point registers. */
! struct prologue_value fpr[S390_NUM_FPRS];
/* The offset relative to the CFA where the incoming GPR N was saved
by the function prologue. 0 if not saved or unknown. */
--- 721,730 ----
int fpr_size;
/* The general-purpose registers. */
! pv_t gpr[S390_NUM_GPRS];
/* The floating-point registers. */
! pv_t fpr[S390_NUM_FPRS];
/* The offset relative to the CFA where the incoming GPR N was saved
by the function prologue. 0 if not saved or unknown. */
*************** struct s390_prologue_data {
*** 1089,1110 ****
int back_chain_saved_p;
};
! /* Do a SIZE-byte store of VALUE to ADDR. */
static void
! s390_store (struct prologue_value *addr,
! CORE_ADDR size,
! struct prologue_value *value,
! struct s390_prologue_data *data)
{
! struct prologue_value cfa, offset;
int i;
/* Check whether we are storing the backchain. */
! pv_subtract (&offset, &data->gpr[S390_SP_REGNUM - S390_R0_REGNUM], addr);
! if (offset.kind == pv_constant && offset.k == 0)
if (size == data->gpr_size
! && pv_is_register (value, S390_SP_REGNUM, 0))
{
data->back_chain_saved_p = 1;
return;
--- 738,782 ----
int back_chain_saved_p;
};
! /* Return the effective address for an X-style instruction, like:
!
! L R1, D2(X2, B2)
!
! Here, X2 and B2 are registers, and D2 is a signed 20-bit
! constant; the effective address is the sum of all three. If either
! X2 or B2 are zero, then it doesn't contribute to the sum --- this
! means that r0 can't be used as either X2 or B2. */
! static pv_t
! s390_addr (struct s390_prologue_data *data,
! int d2, unsigned int x2, unsigned int b2)
! {
! pv_t result;
!
! result = pv_constant (d2);
! if (x2)
! result = pv_add (result, data->gpr[x2]);
! if (b2)
! result = pv_add (result, data->gpr[b2]);
!
! return result;
! }
!
! /* Do a SIZE-byte store of VALUE to D2(X2,B2). */
static void
! s390_store (struct s390_prologue_data *data,
! int d2, unsigned int x2, unsigned int b2, CORE_ADDR size,
! pv_t value)
{
! pv_t addr = s390_addr (data, d2, x2, b2);
! pv_t cfa, offset;
int i;
/* Check whether we are storing the backchain. */
! offset = pv_subtract (data->gpr[S390_SP_REGNUM - S390_R0_REGNUM], addr);
! if (pv_is_constant (offset) && offset.k == 0)
if (size == data->gpr_size
! && pv_is_register_k (value, S390_SP_REGNUM, 0))
{
data->back_chain_saved_p = 1;
return;
*************** s390_store (struct prologue_value *addr,
*** 1112,1121 ****
/* Check whether we are storing a register into the stack. */
! pv_set_to_register (&cfa, S390_SP_REGNUM, 16 * data->gpr_size + 32);
! pv_subtract (&offset, &cfa, addr);
! if (offset.kind == pv_constant
&& offset.k < INT_MAX && offset.k > 0
&& offset.k % data->gpr_size == 0)
{
--- 784,793 ----
/* Check whether we are storing a register into the stack. */
! cfa = pv_register (S390_SP_REGNUM, 16 * data->gpr_size + 32);
! offset = pv_subtract (cfa, addr);
! if (pv_is_constant (offset)
&& offset.k < INT_MAX && offset.k > 0
&& offset.k % data->gpr_size == 0)
{
*************** s390_store (struct prologue_value *addr,
*** 1125,1131 ****
for (i = 0; i < S390_NUM_GPRS; i++)
if (size == data->gpr_size
! && pv_is_register (value, S390_R0_REGNUM + i, 0))
if (data->gpr_slot[i] == 0
|| data->gpr_slot[i] > offset.k)
{
--- 797,803 ----
for (i = 0; i < S390_NUM_GPRS; i++)
if (size == data->gpr_size
! && pv_is_register_k (value, S390_R0_REGNUM + i, 0))
if (data->gpr_slot[i] == 0
|| data->gpr_slot[i] > offset.k)
{
*************** s390_store (struct prologue_value *addr,
*** 1135,1141 ****
for (i = 0; i < S390_NUM_FPRS; i++)
if (size == data->fpr_size
! && pv_is_register (value, S390_F0_REGNUM + i, 0))
if (data->fpr_slot[i] == 0
|| data->fpr_slot[i] > offset.k)
{
--- 807,813 ----
for (i = 0; i < S390_NUM_FPRS; i++)
if (size == data->fpr_size
! && pv_is_register_k (value, S390_F0_REGNUM + i, 0))
if (data->fpr_slot[i] == 0
|| data->fpr_slot[i] > offset.k)
{
*************** s390_store (struct prologue_value *addr,
*** 1153,1166 ****
stores. Thus every store we cannot recognize does not hit our data. */
}
! /* Do a SIZE-byte load from ADDR into VALUE. */
! static void
! s390_load (struct prologue_value *addr,
! CORE_ADDR size,
! struct prologue_value *value,
! struct s390_prologue_data *data)
{
! struct prologue_value cfa, offset;
int i;
/* If it's a load from an in-line constant pool, then we can
--- 825,838 ----
stores. Thus every store we cannot recognize does not hit our data. */
}
! /* Do a SIZE-byte load from D2(X2,B2). */
! static pv_t
! s390_load (struct s390_prologue_data *data,
! int d2, unsigned int x2, unsigned int b2, CORE_ADDR size)
!
{
! pv_t addr = s390_addr (data, d2, x2, b2);
! pv_t cfa, offset;
int i;
/* If it's a load from an in-line constant pool, then we can
*************** s390_load (struct prologue_value *addr,
*** 1168,1210 ****
going to change between the time the processor actually
executed it creating the current frame, and the time when
we're analyzing the code to unwind past that frame. */
! if (addr->kind == pv_constant)
{
struct section_table *secp;
! secp = target_section_by_addr (¤t_target, addr->k);
if (secp != NULL
&& (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
& SEC_READONLY))
! {
! pv_set_to_constant (value, read_memory_integer (addr->k, size));
! return;
! }
}
/* Check whether we are accessing one of our save slots. */
! pv_set_to_register (&cfa, S390_SP_REGNUM, 16 * data->gpr_size + 32);
! pv_subtract (&offset, &cfa, addr);
! if (offset.kind == pv_constant
&& offset.k < INT_MAX && offset.k > 0)
{
for (i = 0; i < S390_NUM_GPRS; i++)
if (offset.k == data->gpr_slot[i])
! {
! pv_set_to_register (value, S390_R0_REGNUM + i, 0);
! return;
! }
for (i = 0; i < S390_NUM_FPRS; i++)
if (offset.k == data->fpr_slot[i])
! {
! pv_set_to_register (value, S390_F0_REGNUM + i, 0);
! return;
! }
}
/* Otherwise, we don't know the value. */
! pv_set_to_unknown (value);
}
--- 840,873 ----
going to change between the time the processor actually
executed it creating the current frame, and the time when
we're analyzing the code to unwind past that frame. */
! if (pv_is_constant (addr))
{
struct section_table *secp;
! secp = target_section_by_addr (¤t_target, addr.k);
if (secp != NULL
&& (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
& SEC_READONLY))
! return pv_constant (read_memory_integer (addr.k, size));
}
/* Check whether we are accessing one of our save slots. */
! cfa = pv_register (S390_SP_REGNUM, 16 * data->gpr_size + 32);
! offset = pv_subtract (cfa, addr);
! if (pv_is_constant (offset)
&& offset.k < INT_MAX && offset.k > 0)
{
for (i = 0; i < S390_NUM_GPRS; i++)
if (offset.k == data->gpr_slot[i])
! return pv_register (S390_R0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_FPRS; i++)
if (offset.k == data->fpr_slot[i])
! return pv_register (S390_F0_REGNUM + i, 0);
}
/* Otherwise, we don't know the value. */
! return pv_unknown ();
}
*************** s390_analyze_prologue (struct gdbarch *g
*** 1245,1254 ****
data->fpr_size = 8;
for (i = 0; i < S390_NUM_GPRS; i++)
! pv_set_to_register (&data->gpr[i], S390_R0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_FPRS; i++)
! pv_set_to_register (&data->fpr[i], S390_F0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_GPRS; i++)
data->gpr_slot[i] = 0;
--- 908,917 ----
data->fpr_size = 8;
for (i = 0; i < S390_NUM_GPRS; i++)
! data->gpr[i] = pv_register (S390_R0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_FPRS; i++)
! data->fpr[i] = pv_register (S390_F0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_GPRS; i++)
data->gpr_slot[i] = 0;
*************** s390_analyze_prologue (struct gdbarch *g
*** 1266,1278 ****
bfd_byte insn[S390_MAX_INSTR_SIZE];
int insn_len = s390_readinstruction (insn, pc);
/* Fields for various kinds of instructions. */
unsigned int b2, r1, r2, x2, r3;
int i2, d2;
/* The values of SP and FP before this instruction,
for detecting instructions that change them. */
! struct prologue_value pre_insn_sp, pre_insn_fp;
/* Likewise for the flag whether the back chain was saved. */
int pre_insn_back_chain_saved_p;
--- 929,945 ----
bfd_byte insn[S390_MAX_INSTR_SIZE];
int insn_len = s390_readinstruction (insn, pc);
+ bfd_byte dummy[S390_MAX_INSTR_SIZE] = { 0 };
+ bfd_byte *insn32 = word_size == 4 ? insn : dummy;
+ bfd_byte *insn64 = word_size == 8 ? insn : dummy;
+
/* Fields for various kinds of instructions. */
unsigned int b2, r1, r2, x2, r3;
int i2, d2;
/* The values of SP and FP before this instruction,
for detecting instructions that change them. */
! pv_t pre_insn_sp, pre_insn_fp;
/* Likewise for the flag whether the back chain was saved. */
int pre_insn_back_chain_saved_p;
*************** s390_analyze_prologue (struct gdbarch *g
*** 1289,1608 ****
pre_insn_fp = data->gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
pre_insn_back_chain_saved_p = data->back_chain_saved_p;
- /* LHI r1, i2 --- load halfword immediate */
- if (word_size == 4
- && is_ri (insn, op1_lhi, op2_lhi, &r1, &i2))
- pv_set_to_constant (&data->gpr[r1], i2);
-
- /* LGHI r1, i2 --- load halfword immediate (64-bit version) */
- else if (word_size == 8
- && is_ri (insn, op1_lghi, op2_lghi, &r1, &i2))
- pv_set_to_constant (&data->gpr[r1], i2);
-
- /* LGFI r1, i2 --- load fullword immediate */
- else if (is_ril (insn, op1_lgfi, op2_lgfi, &r1, &i2))
- pv_set_to_constant (&data->gpr[r1], i2);
-
- /* LR r1, r2 --- load from register */
- else if (word_size == 4
- && is_rr (insn, op_lr, &r1, &r2))
- data->gpr[r1] = data->gpr[r2];
-
- /* LGR r1, r2 --- load from register (64-bit version) */
- else if (word_size == 8
- && is_rre (insn, op_lgr, &r1, &r2))
- data->gpr[r1] = data->gpr[r2];
-
- /* L r1, d2(x2, b2) --- load */
- else if (word_size == 4
- && is_rx (insn, op_l, &r1, &d2, &x2, &b2))
- {
- struct prologue_value addr;
-
- compute_x_addr (&addr, data->gpr, d2, x2, b2);
- s390_load (&addr, 4, &data->gpr[r1], data);
- }
-
- /* LY r1, d2(x2, b2) --- load (long-displacement version) */
- else if (word_size == 4
- && is_rxy (insn, op1_ly, op2_ly, &r1, &d2, &x2, &b2))
- {
- struct prologue_value addr;
-
- compute_x_addr (&addr, data->gpr, d2, x2, b2);
- s390_load (&addr, 4, &data->gpr[r1], data);
- }
-
- /* LG r1, d2(x2, b2) --- load (64-bit version) */
- else if (word_size == 8
- && is_rxy (insn, op1_lg, op2_lg, &r1, &d2, &x2, &b2))
- {
- struct prologue_value addr;
-
- compute_x_addr (&addr, data->gpr, d2, x2, b2);
- s390_load (&addr, 8, &data->gpr[r1], data);
- }
-
- /* ST r1, d2(x2, b2) --- store */
- else if (word_size == 4
- && is_rx (insn, op_st, &r1, &d2, &x2, &b2))
- {
- struct prologue_value addr;
-
- compute_x_addr (&addr, data->gpr, d2, x2, b2);
- s390_store (&addr, 4, &data->gpr[r1], data);
- }
-
- /* STY r1, d2(x2, b2) --- store (long-displacement version) */
- else if (word_size == 4
- && is_rxy (insn, op1_sty, op2_sty, &r1, &d2, &x2, &b2))
- {
- struct prologue_value addr;
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_store (&addr, 4, &data->gpr[r1], data);
! }
!
! /* STG r1, d2(x2, b2) --- store (64-bit version) */
! else if (word_size == 8
! && is_rxy (insn, op1_stg, op2_stg, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_store (&addr, 8, &data->gpr[r1], data);
! }
! /* STD r1, d2(x2,b2) --- store floating-point register */
else if (is_rx (insn, op_std, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_store (&addr, 8, &data->fpr[r1], data);
! }
!
! /* STM r1, r3, d2(b2) --- store multiple */
! else if (word_size == 4
! && is_rs (insn, op_stm, &r1, &r3, &d2, &b2))
! {
! int regnum;
! int offset;
! struct prologue_value addr;
!
! for (regnum = r1, offset = 0;
! regnum <= r3;
! regnum++, offset += 4)
! {
! compute_x_addr (&addr, data->gpr, d2 + offset, 0, b2);
! s390_store (&addr, 4, &data->gpr[regnum], data);
! }
! }
! /* STMY r1, r3, d2(b2) --- store multiple (long-displacement version) */
! else if (word_size == 4
! && is_rsy (insn, op1_stmy, op2_stmy, &r1, &r3, &d2, &b2))
{
! int regnum;
! int offset;
! struct prologue_value addr;
!
! for (regnum = r1, offset = 0;
! regnum <= r3;
! regnum++, offset += 4)
! {
! compute_x_addr (&addr, data->gpr, d2 + offset, 0, b2);
! s390_store (&addr, 4, &data->gpr[regnum], data);
! }
}
! /* STMG r1, r3, d2(b2) --- store multiple (64-bit version) */
! else if (word_size == 8
! && is_rsy (insn, op1_stmg, op2_stmg, &r1, &r3, &d2, &b2))
! {
! int regnum;
! int offset;
! struct prologue_value addr;
!
! for (regnum = r1, offset = 0;
! regnum <= r3;
! regnum++, offset += 8)
! {
! compute_x_addr (&addr, data->gpr, d2 + offset, 0, b2);
! s390_store (&addr, 8, &data->gpr[regnum], data);
! }
! }
!
! /* AHI r1, i2 --- add halfword immediate */
! else if (word_size == 4
! && is_ri (insn, op1_ahi, op2_ahi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], i2);
!
! /* AGHI r1, i2 --- add halfword immediate (64-bit version) */
! else if (word_size == 8
! && is_ri (insn, op1_aghi, op2_aghi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], i2);
!
! /* AFI r1, i2 --- add fullword immediate */
! else if (word_size == 4
! && is_ril (insn, op1_afi, op2_afi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], i2);
!
! /* AGFI r1, i2 --- add fullword immediate (64-bit version) */
! else if (word_size == 8
! && is_ril (insn, op1_agfi, op2_agfi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], i2);
!
! /* ALFI r1, i2 --- add logical immediate */
! else if (word_size == 4
! && is_ril (insn, op1_alfi, op2_alfi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], (CORE_ADDR)i2 & 0xffffffff);
!
! /* ALGFI r1, i2 --- add logical immediate (64-bit version) */
! else if (word_size == 8
! && is_ril (insn, op1_algfi, op2_algfi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], (CORE_ADDR)i2 & 0xffffffff);
!
! /* AR r1, r2 -- add register */
! else if (word_size == 4
! && is_rr (insn, op_ar, &r1, &r2))
! pv_add (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]);
!
! /* AGR r1, r2 -- add register (64-bit version) */
! else if (word_size == 8
! && is_rre (insn, op_agr, &r1, &r2))
! pv_add (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]);
!
! /* A r1, d2(x2, b2) -- add */
! else if (word_size == 4
! && is_rx (insn, op_a, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
! struct prologue_value value;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_load (&addr, 4, &value, data);
!
! pv_add (&data->gpr[r1], &data->gpr[r1], &value);
! }
!
! /* AY r1, d2(x2, b2) -- add (long-displacement version) */
! else if (word_size == 4
! && is_rxy (insn, op1_ay, op2_ay, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
! struct prologue_value value;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_load (&addr, 4, &value, data);
!
! pv_add (&data->gpr[r1], &data->gpr[r1], &value);
! }
!
! /* AG r1, d2(x2, b2) -- add (64-bit version) */
! else if (word_size == 8
! && is_rxy (insn, op1_ag, op2_ag, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
! struct prologue_value value;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_load (&addr, 8, &value, data);
!
! pv_add (&data->gpr[r1], &data->gpr[r1], &value);
! }
!
! /* SLFI r1, i2 --- subtract logical immediate */
! else if (word_size == 4
! && is_ril (insn, op1_slfi, op2_slfi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], -((CORE_ADDR)i2 & 0xffffffff));
!
! /* SLGFI r1, i2 --- subtract logical immediate (64-bit version) */
! else if (word_size == 8
! && is_ril (insn, op1_slgfi, op2_slgfi, &r1, &i2))
! pv_add_constant (&data->gpr[r1], -((CORE_ADDR)i2 & 0xffffffff));
!
! /* SR r1, r2 -- subtract register */
! else if (word_size == 4
! && is_rr (insn, op_sr, &r1, &r2))
! pv_subtract (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]);
!
! /* SGR r1, r2 -- subtract register (64-bit version) */
! else if (word_size == 8
! && is_rre (insn, op_sgr, &r1, &r2))
! pv_subtract (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]);
!
! /* S r1, d2(x2, b2) -- subtract */
! else if (word_size == 4
! && is_rx (insn, op_s, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
! struct prologue_value value;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_load (&addr, 4, &value, data);
!
! pv_subtract (&data->gpr[r1], &data->gpr[r1], &value);
! }
!
! /* SY r1, d2(x2, b2) -- subtract (long-displacement version) */
! else if (word_size == 4
! && is_rxy (insn, op1_sy, op2_sy, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
! struct prologue_value value;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_load (&addr, 4, &value, data);
!
! pv_subtract (&data->gpr[r1], &data->gpr[r1], &value);
! }
!
! /* SG r1, d2(x2, b2) -- subtract (64-bit version) */
! else if (word_size == 8
! && is_rxy (insn, op1_sg, op2_sg, &r1, &d2, &x2, &b2))
! {
! struct prologue_value addr;
! struct prologue_value value;
!
! compute_x_addr (&addr, data->gpr, d2, x2, b2);
! s390_load (&addr, 8, &value, data);
!
! pv_subtract (&data->gpr[r1], &data->gpr[r1], &value);
! }
!
! /* NR r1, r2 --- logical and */
! else if (word_size == 4
! && is_rr (insn, op_nr, &r1, &r2))
! pv_logical_and (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]);
!
! /* NGR r1, r2 >--- logical and (64-bit version) */
! else if (word_size == 8
! && is_rre (insn, op_ngr, &r1, &r2))
! pv_logical_and (&data->gpr[r1], &data->gpr[r1], &data->gpr[r2]);
!
! /* LA r1, d2(x2, b2) --- load address */
! else if (is_rx (insn, op_la, &r1, &d2, &x2, &b2))
! compute_x_addr (&data->gpr[r1], data->gpr, d2, x2, b2);
!
! /* LAY r1, d2(x2, b2) --- load address (long-displacement version) */
! else if (is_rxy (insn, op1_lay, op2_lay, &r1, &d2, &x2, &b2))
! compute_x_addr (&data->gpr[r1], data->gpr, d2, x2, b2);
! /* LARL r1, i2 --- load address relative long */
else if (is_ril (insn, op1_larl, op2_larl, &r1, &i2))
! pv_set_to_constant (&data->gpr[r1], pc + i2 * 2);
! /* BASR r1, 0 --- branch and save
Since r2 is zero, this saves the PC in r1, but doesn't branch. */
else if (is_rr (insn, op_basr, &r1, &r2)
&& r2 == 0)
! pv_set_to_constant (&data->gpr[r1], next_pc);
! /* BRAS r1, i2 --- branch relative and save */
else if (is_ri (insn, op1_bras, op2_bras, &r1, &i2))
{
! pv_set_to_constant (&data->gpr[r1], next_pc);
next_pc = pc + i2 * 2;
/* We'd better not interpret any backward branches. We'll
--- 956,1081 ----
pre_insn_fp = data->gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
pre_insn_back_chain_saved_p = data->back_chain_saved_p;
! /* LHI r1, i2 --- load halfword immediate. */
! /* LGHI r1, i2 --- load halfword immediate (64-bit version). */
! /* LGFI r1, i2 --- load fullword immediate. */
! if (is_ri (insn32, op1_lhi, op2_lhi, &r1, &i2)
! || is_ri (insn64, op1_lghi, op2_lghi, &r1, &i2)
! || is_ril (insn, op1_lgfi, op2_lgfi, &r1, &i2))
! data->gpr[r1] = pv_constant (i2);
!
! /* LR r1, r2 --- load from register. */
! /* LGR r1, r2 --- load from register (64-bit version). */
! else if (is_rr (insn32, op_lr, &r1, &r2)
! || is_rre (insn64, op_lgr, &r1, &r2))
! data->gpr[r1] = data->gpr[r2];
!
! /* L r1, d2(x2, b2) --- load. */
! /* LY r1, d2(x2, b2) --- load (long-displacement version). */
! /* LG r1, d2(x2, b2) --- load (64-bit version). */
! else if (is_rx (insn32, op_l, &r1, &d2, &x2, &b2)
! || is_rxy (insn32, op1_ly, op2_ly, &r1, &d2, &x2, &b2)
! || is_rxy (insn64, op1_lg, op2_lg, &r1, &d2, &x2, &b2))
! data->gpr[r1] = s390_load (data, d2, x2, b2, data->gpr_size);
!
! /* ST r1, d2(x2, b2) --- store. */
! /* STY r1, d2(x2, b2) --- store (long-displacement version). */
! /* STG r1, d2(x2, b2) --- store (64-bit version). */
! else if (is_rx (insn32, op_st, &r1, &d2, &x2, &b2)
! || is_rxy (insn32, op1_sty, op2_sty, &r1, &d2, &x2, &b2)
! || is_rxy (insn64, op1_stg, op2_stg, &r1, &d2, &x2, &b2))
! s390_store (data, d2, x2, b2, data->gpr_size, data->gpr[r1]);
! /* STD r1, d2(x2,b2) --- store floating-point register. */
else if (is_rx (insn, op_std, &r1, &d2, &x2, &b2))
! s390_store (data, d2, x2, b2, data->fpr_size, data->fpr[r1]);
! /* STM r1, r3, d2(b2) --- store multiple. */
! /* STMY r1, r3, d2(b2) --- store multiple (long-displacement version). */
! /* STMG r1, r3, d2(b2) --- store multiple (64-bit version). */
! else if (is_rs (insn32, op_stm, &r1, &r3, &d2, &b2)
! || is_rsy (insn32, op1_stmy, op2_stmy, &r1, &r3, &d2, &b2)
! || is_rsy (insn64, op1_stmg, op2_stmg, &r1, &r3, &d2, &b2))
{
! for (; r1 <= r3; r1++, d2 += data->gpr_size)
! s390_store (data, d2, 0, b2, data->gpr_size, data->gpr[r1]);
}
! /* AHI r1, i2 --- add halfword immediate. */
! /* AGHI r1, i2 --- add halfword immediate (64-bit version). */
! /* AFI r1, i2 --- add fullword immediate. */
! /* AGFI r1, i2 --- add fullword immediate (64-bit version). */
! else if (is_ri (insn32, op1_ahi, op2_ahi, &r1, &i2)
! || is_ri (insn64, op1_aghi, op2_aghi, &r1, &i2)
! || is_ril (insn32, op1_afi, op2_afi, &r1, &i2)
! || is_ril (insn64, op1_agfi, op2_agfi, &r1, &i2))
! data->gpr[r1] = pv_add_constant (data->gpr[r1], i2);
!
! /* ALFI r1, i2 --- add logical immediate. */
! /* ALGFI r1, i2 --- add logical immediate (64-bit version). */
! else if (is_ril (insn32, op1_alfi, op2_alfi, &r1, &i2)
! || is_ril (insn64, op1_algfi, op2_algfi, &r1, &i2))
! data->gpr[r1] = pv_add_constant (data->gpr[r1],
! (CORE_ADDR)i2 & 0xffffffff);
!
! /* AR r1, r2 -- add register. */
! /* AGR r1, r2 -- add register (64-bit version). */
! else if (is_rr (insn32, op_ar, &r1, &r2)
! || is_rre (insn64, op_agr, &r1, &r2))
! data->gpr[r1] = pv_add (data->gpr[r1], data->gpr[r2]);
!
! /* A r1, d2(x2, b2) -- add. */
! /* AY r1, d2(x2, b2) -- add (long-displacement version). */
! /* AG r1, d2(x2, b2) -- add (64-bit version). */
! else if (is_rx (insn32, op_a, &r1, &d2, &x2, &b2)
! || is_rxy (insn32, op1_ay, op2_ay, &r1, &d2, &x2, &b2)
! || is_rxy (insn64, op1_ag, op2_ag, &r1, &d2, &x2, &b2))
! data->gpr[r1] = pv_add (data->gpr[r1],
! s390_load (data, d2, x2, b2, data->gpr_size));
!
! /* SLFI r1, i2 --- subtract logical immediate. */
! /* SLGFI r1, i2 --- subtract logical immediate (64-bit version). */
! else if (is_ril (insn32, op1_slfi, op2_slfi, &r1, &i2)
! || is_ril (insn64, op1_slgfi, op2_slgfi, &r1, &i2))
! data->gpr[r1] = pv_add_constant (data->gpr[r1],
! -((CORE_ADDR)i2 & 0xffffffff));
!
! /* SR r1, r2 -- subtract register. */
! /* SGR r1, r2 -- subtract register (64-bit version). */
! else if (is_rr (insn32, op_sr, &r1, &r2)
! || is_rre (insn64, op_sgr, &r1, &r2))
! data->gpr[r1] = pv_subtract (data->gpr[r1], data->gpr[r2]);
!
! /* S r1, d2(x2, b2) -- subtract. */
! /* SY r1, d2(x2, b2) -- subtract (long-displacement version). */
! /* SG r1, d2(x2, b2) -- subtract (64-bit version). */
! else if (is_rx (insn32, op_s, &r1, &d2, &x2, &b2)
! || is_rxy (insn32, op1_sy, op2_sy, &r1, &d2, &x2, &b2)
! || is_rxy (insn64, op1_sg, op2_sg, &r1, &d2, &x2, &b2))
! data->gpr[r1] = pv_subtract (data->gpr[r1],
! s390_load (data, d2, x2, b2, data->gpr_size));
!
! /* LA r1, d2(x2, b2) --- load address. */
! /* LAY r1, d2(x2, b2) --- load address (long-displacement version). */
! else if (is_rx (insn, op_la, &r1, &d2, &x2, &b2)
! || is_rxy (insn, op1_lay, op2_lay, &r1, &d2, &x2, &b2))
! data->gpr[r1] = s390_addr (data, d2, x2, b2);
! /* LARL r1, i2 --- load address relative long. */
else if (is_ril (insn, op1_larl, op2_larl, &r1, &i2))
! data->gpr[r1] = pv_constant (pc + i2 * 2);
! /* BASR r1, 0 --- branch and save.
Since r2 is zero, this saves the PC in r1, but doesn't branch. */
else if (is_rr (insn, op_basr, &r1, &r2)
&& r2 == 0)
! data->gpr[r1] = pv_constant (next_pc);
! /* BRAS r1, i2 --- branch relative and save. */
else if (is_ri (insn, op1_bras, op2_bras, &r1, &i2))
{
! data->gpr[r1] = pv_constant (next_pc);
next_pc = pc + i2 * 2;
/* We'd better not interpret any backward branches. We'll
*************** s390_analyze_prologue (struct gdbarch *g
*** 1636,1648 ****
restore instructions. (The back chain is never restored,
just popped.) */
{
! struct prologue_value *sp = &data->gpr[S390_SP_REGNUM - S390_R0_REGNUM];
! struct prologue_value *fp = &data->gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
! if ((! pv_is_identical (&pre_insn_sp, sp)
! && ! pv_is_register (sp, S390_SP_REGNUM, 0))
! || (! pv_is_identical (&pre_insn_fp, fp)
! && ! pv_is_register (fp, S390_FRAME_REGNUM, 0))
|| pre_insn_back_chain_saved_p != data->back_chain_saved_p)
result = next_pc;
}
--- 1109,1123 ----
restore instructions. (The back chain is never restored,
just popped.) */
{
! pv_t sp = data->gpr[S390_SP_REGNUM - S390_R0_REGNUM];
! pv_t fp = data->gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
! if ((! pv_is_identical (pre_insn_sp, sp)
! && ! pv_is_register_k (sp, S390_SP_REGNUM, 0)
! && sp.kind != pvk_unknown)
! || (! pv_is_identical (pre_insn_fp, fp)
! && ! pv_is_register_k (fp, S390_FRAME_REGNUM, 0)
! && fp.kind != pvk_unknown)
|| pre_insn_back_chain_saved_p != data->back_chain_saved_p)
result = next_pc;
}
*************** s390_prologue_frame_unwind_cache (struct
*** 1733,1740 ****
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int word_size = gdbarch_ptr_bit (gdbarch) / 8;
struct s390_prologue_data data;
! struct prologue_value *fp = &data.gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
! struct prologue_value *sp = &data.gpr[S390_SP_REGNUM - S390_R0_REGNUM];
int i;
CORE_ADDR cfa;
CORE_ADDR func;
--- 1208,1215 ----
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int word_size = gdbarch_ptr_bit (gdbarch) / 8;
struct s390_prologue_data data;
! pv_t *fp = &data.gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
! pv_t *sp = &data.gpr[S390_SP_REGNUM - S390_R0_REGNUM];
int i;
CORE_ADDR cfa;
CORE_ADDR func;
*************** s390_prologue_frame_unwind_cache (struct
*** 1761,1767 ****
/* If this was successful, we should have found the instruction that
sets the stack pointer register to the previous value of the stack
pointer minus the frame size. */
! if (sp->kind != pv_register || sp->reg != S390_SP_REGNUM)
return 0;
/* A frame size of zero at this point can mean either a real
--- 1236,1242 ----
/* If this was successful, we should have found the instruction that
sets the stack pointer register to the previous value of the stack
pointer minus the frame size. */
! if (!pv_is_register (*sp, S390_SP_REGNUM))
return 0;
/* A frame size of zero at this point can mean either a real
*************** s390_prologue_frame_unwind_cache (struct
*** 1793,1803 ****
Recognize this case by looking ahead a bit ... */
struct s390_prologue_data data2;
! struct prologue_value *sp = &data2.gpr[S390_SP_REGNUM - S390_R0_REGNUM];
if (!(s390_analyze_prologue (gdbarch, func, (CORE_ADDR)-1, &data2)
! && sp->kind == pv_register
! && sp->reg == S390_SP_REGNUM
&& sp->k != 0))
return 0;
}
--- 1268,1277 ----
Recognize this case by looking ahead a bit ... */
struct s390_prologue_data data2;
! pv_t *sp = &data2.gpr[S390_SP_REGNUM - S390_R0_REGNUM];
if (!(s390_analyze_prologue (gdbarch, func, (CORE_ADDR)-1, &data2)
! && pv_is_register (*sp, S390_SP_REGNUM)
&& sp->k != 0))
return 0;
}
*************** s390_prologue_frame_unwind_cache (struct
*** 1811,1817 ****
as the stack pointer, we're probably using it. If it holds
some other value -- even a constant offset -- it is most
likely used as temp register. */
! if (pv_is_identical (sp, fp))
frame_pointer = S390_FRAME_REGNUM;
else
frame_pointer = S390_SP_REGNUM;
--- 1285,1291 ----
as the stack pointer, we're probably using it. If it holds
some other value -- even a constant offset -- it is most
likely used as temp register. */
! if (pv_is_identical (*sp, *fp))
frame_pointer = S390_FRAME_REGNUM;
else
frame_pointer = S390_SP_REGNUM;
--
Dr. Ulrich Weigand
Linux on zSeries Development
Ulrich.Weigand@de.ibm.com