2002-03-27 Elena Zannoni <ezannoni@redhat.com>
* rs6000-tdep.c (struct rs6000_framedata): Add fields for AltiVec vector registers handling. (skip_prologue): Handle new AltiVec instructions. Fill in new fields of frame data. (frame_get_saved_regs): Fill in information for AltiVec registers.
This commit is contained in:
parent
96b0714f37
commit
6be8bc0c92
@ -1,3 +1,11 @@
|
|||||||
|
2002-03-27 Elena Zannoni <ezannoni@redhat.com>
|
||||||
|
|
||||||
|
* rs6000-tdep.c (struct rs6000_framedata): Add fields for AltiVec
|
||||||
|
vector registers handling.
|
||||||
|
(skip_prologue): Handle new AltiVec instructions. Fill in new
|
||||||
|
fields of frame data.
|
||||||
|
(frame_get_saved_regs): Fill in information for AltiVec registers.
|
||||||
|
|
||||||
2002-03-27 Jim Blandy <jimb@redhat.com>
|
2002-03-27 Jim Blandy <jimb@redhat.com>
|
||||||
|
|
||||||
* symtab.h (SYMBOL_INIT_MANGLED_NAME): Turn this macro's body into
|
* symtab.h (SYMBOL_INIT_MANGLED_NAME): Turn this macro's body into
|
||||||
|
@ -64,13 +64,16 @@ struct rs6000_framedata
|
|||||||
the frame */
|
the frame */
|
||||||
int saved_gpr; /* smallest # of saved gpr */
|
int saved_gpr; /* smallest # of saved gpr */
|
||||||
int saved_fpr; /* smallest # of saved fpr */
|
int saved_fpr; /* smallest # of saved fpr */
|
||||||
|
int saved_vr; /* smallest # of saved vr */
|
||||||
int alloca_reg; /* alloca register number (frame ptr) */
|
int alloca_reg; /* alloca register number (frame ptr) */
|
||||||
char frameless; /* true if frameless functions. */
|
char frameless; /* true if frameless functions. */
|
||||||
char nosavedpc; /* true if pc not saved. */
|
char nosavedpc; /* true if pc not saved. */
|
||||||
int gpr_offset; /* offset of saved gprs from prev sp */
|
int gpr_offset; /* offset of saved gprs from prev sp */
|
||||||
int fpr_offset; /* offset of saved fprs from prev sp */
|
int fpr_offset; /* offset of saved fprs from prev sp */
|
||||||
|
int vr_offset; /* offset of saved vrs from prev sp */
|
||||||
int lr_offset; /* offset of saved lr */
|
int lr_offset; /* offset of saved lr */
|
||||||
int cr_offset; /* offset of saved cr */
|
int cr_offset; /* offset of saved cr */
|
||||||
|
int vrsave_offset; /* offset of saved vrsave register */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Description of a single register. */
|
/* Description of a single register. */
|
||||||
@ -362,12 +365,15 @@ rs6000_software_single_step (enum target_signal signal,
|
|||||||
which we decrement the sp to allocate the frame.
|
which we decrement the sp to allocate the frame.
|
||||||
- saved_gpr is the number of the first saved gpr.
|
- saved_gpr is the number of the first saved gpr.
|
||||||
- saved_fpr is the number of the first saved fpr.
|
- saved_fpr is the number of the first saved fpr.
|
||||||
|
- saved_vr is the number of the first saved vr.
|
||||||
- alloca_reg is the number of the register used for alloca() handling.
|
- alloca_reg is the number of the register used for alloca() handling.
|
||||||
Otherwise -1.
|
Otherwise -1.
|
||||||
- gpr_offset is the offset of the first saved gpr from the previous frame.
|
- gpr_offset is the offset of the first saved gpr from the previous frame.
|
||||||
- fpr_offset is the offset of the first saved fpr from the previous frame.
|
- fpr_offset is the offset of the first saved fpr from the previous frame.
|
||||||
|
- vr_offset is the offset of the first saved vr from the previous frame.
|
||||||
- lr_offset is the offset of the saved lr
|
- lr_offset is the offset of the saved lr
|
||||||
- cr_offset is the offset of the saved cr
|
- cr_offset is the offset of the saved cr
|
||||||
|
- vrsave_offset is the offset of the saved vrsave register
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SIGNED_SHORT(x) \
|
#define SIGNED_SHORT(x) \
|
||||||
@ -434,11 +440,15 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
|
|||||||
{
|
{
|
||||||
CORE_ADDR orig_pc = pc;
|
CORE_ADDR orig_pc = pc;
|
||||||
CORE_ADDR last_prologue_pc = pc;
|
CORE_ADDR last_prologue_pc = pc;
|
||||||
|
CORE_ADDR li_found_pc = 0;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
unsigned long op;
|
unsigned long op;
|
||||||
long offset = 0;
|
long offset = 0;
|
||||||
|
long vr_saved_offset = 0;
|
||||||
int lr_reg = -1;
|
int lr_reg = -1;
|
||||||
int cr_reg = -1;
|
int cr_reg = -1;
|
||||||
|
int vr_reg = -1;
|
||||||
|
int vrsave_reg = -1;
|
||||||
int reg;
|
int reg;
|
||||||
int framep = 0;
|
int framep = 0;
|
||||||
int minimal_toc_loaded = 0;
|
int minimal_toc_loaded = 0;
|
||||||
@ -463,6 +473,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
|
|||||||
memset (fdata, 0, sizeof (struct rs6000_framedata));
|
memset (fdata, 0, sizeof (struct rs6000_framedata));
|
||||||
fdata->saved_gpr = -1;
|
fdata->saved_gpr = -1;
|
||||||
fdata->saved_fpr = -1;
|
fdata->saved_fpr = -1;
|
||||||
|
fdata->saved_vr = -1;
|
||||||
fdata->alloca_reg = -1;
|
fdata->alloca_reg = -1;
|
||||||
fdata->frameless = 1;
|
fdata->frameless = 1;
|
||||||
fdata->nosavedpc = 1;
|
fdata->nosavedpc = 1;
|
||||||
@ -581,8 +592,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (((op & 0xffff0000) == 0x801e0000 || /* lwz 0,NUM(r30), used
|
else if (((op & 0xffff0000) == 0x801e0000 || /* lwz 0,NUM(r30), used
|
||||||
in V.4 -mrelocatable */
|
in V.4 -mrelocatable */
|
||||||
op == 0x7fc0f214) && /* add r30,r0,r30, used
|
op == 0x7fc0f214) && /* add r30,r0,r30, used
|
||||||
in V.4 -mrelocatable */
|
in V.4 -mrelocatable */
|
||||||
lr_reg == 0x901e0000)
|
lr_reg == 0x901e0000)
|
||||||
@ -590,8 +601,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ((op & 0xffff0000) == 0x3fc00000 || /* addis 30,0,foo@ha, used
|
else if ((op & 0xffff0000) == 0x3fc00000 || /* addis 30,0,foo@ha, used
|
||||||
in V.4 -mminimal-toc */
|
in V.4 -mminimal-toc */
|
||||||
(op & 0xffff0000) == 0x3bde0000)
|
(op & 0xffff0000) == 0x3bde0000)
|
||||||
{ /* addi 30,30,foo@l */
|
{ /* addi 30,30,foo@l */
|
||||||
continue;
|
continue;
|
||||||
@ -602,17 +613,17 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
|
|||||||
to save fprs??? */
|
to save fprs??? */
|
||||||
|
|
||||||
fdata->frameless = 0;
|
fdata->frameless = 0;
|
||||||
/* Don't skip over the subroutine call if it is not within the first
|
/* Don't skip over the subroutine call if it is not within
|
||||||
three instructions of the prologue. */
|
the first three instructions of the prologue. */
|
||||||
if ((pc - orig_pc) > 8)
|
if ((pc - orig_pc) > 8)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
op = read_memory_integer (pc + 4, 4);
|
op = read_memory_integer (pc + 4, 4);
|
||||||
|
|
||||||
/* At this point, make sure this is not a trampoline function
|
/* At this point, make sure this is not a trampoline
|
||||||
(a function that simply calls another functions, and nothing else).
|
function (a function that simply calls another functions,
|
||||||
If the next is not a nop, this branch was part of the function
|
and nothing else). If the next is not a nop, this branch
|
||||||
prologue. */
|
was part of the function prologue. */
|
||||||
|
|
||||||
if (op == 0x4def7b82 || op == 0) /* crorc 15, 15, 15 */
|
if (op == 0x4def7b82 || op == 0) /* crorc 15, 15, 15 */
|
||||||
break; /* don't skip over
|
break; /* don't skip over
|
||||||
@ -658,8 +669,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
|
|||||||
|
|
||||||
/* store parameters in stack */
|
/* store parameters in stack */
|
||||||
}
|
}
|
||||||
else if ((op & 0xfc1f0000) == 0x90010000 || /* st rx,NUM(r1) */
|
else if ((op & 0xfc1f0003) == 0xf8010000 || /* std rx,NUM(r1) */
|
||||||
(op & 0xfc1f0003) == 0xf8010000 || /* std rx,NUM(r1) */
|
|
||||||
(op & 0xfc1f0000) == 0xd8010000 || /* stfd Rx,NUM(r1) */
|
(op & 0xfc1f0000) == 0xd8010000 || /* stfd Rx,NUM(r1) */
|
||||||
(op & 0xfc1f0000) == 0xfc010000) /* frsp, fp?,NUM(r1) */
|
(op & 0xfc1f0000) == 0xfc010000) /* frsp, fp?,NUM(r1) */
|
||||||
{
|
{
|
||||||
@ -692,8 +702,74 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
|
|||||||
framep = 1;
|
framep = 1;
|
||||||
fdata->alloca_reg = (op & ~0x38010000) >> 21;
|
fdata->alloca_reg = (op & ~0x38010000) >> 21;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/* AltiVec related instructions. */
|
||||||
|
/* Store the vrsave register (spr 256) in another register for
|
||||||
|
later manipulation, or load a register into the vrsave
|
||||||
|
register. 2 instructions are used: mfvrsave and
|
||||||
|
mtvrsave. They are shorthand notation for mfspr Rn, SPR256
|
||||||
|
and mtspr SPR256, Rn. */
|
||||||
|
/* mfspr Rn SPR256 == 011111 nnnnn 0000001000 01010100110
|
||||||
|
mtspr SPR256 Rn == 011111 nnnnn 0000001000 01110100110 */
|
||||||
|
else if ((op & 0xfc1fffff) == 0x7c0042a6) /* mfvrsave Rn */
|
||||||
|
{
|
||||||
|
vrsave_reg = GET_SRC_REG (op);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ((op & 0xfc1fffff) == 0x7c0043a6) /* mtvrsave Rn */
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Store the register where vrsave was saved to onto the stack:
|
||||||
|
rS is the register where vrsave was stored in a previous
|
||||||
|
instruction. */
|
||||||
|
/* 100100 sssss 00001 dddddddd dddddddd */
|
||||||
|
else if ((op & 0xfc1f0000) == 0x90010000) /* stw rS, d(r1) */
|
||||||
|
{
|
||||||
|
if (vrsave_reg == GET_SRC_REG (op))
|
||||||
|
{
|
||||||
|
fdata->vrsave_offset = SIGNED_SHORT (op) + offset;
|
||||||
|
vrsave_reg = -1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Compute the new value of vrsave, by modifying the register
|
||||||
|
where vrsave was saved to. */
|
||||||
|
else if (((op & 0xfc000000) == 0x64000000) /* oris Ra, Rs, UIMM */
|
||||||
|
|| ((op & 0xfc000000) == 0x60000000))/* ori Ra, Rs, UIMM */
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* li r0, SIMM (short for addi r0, 0, SIMM). This is the first
|
||||||
|
in a pair of insns to save the vector registers on the
|
||||||
|
stack. */
|
||||||
|
/* 001110 00000 00000 iiii iiii iiii iiii */
|
||||||
|
else if ((op & 0xffff0000) == 0x38000000) /* li r0, SIMM */
|
||||||
|
{
|
||||||
|
li_found_pc = pc;
|
||||||
|
vr_saved_offset = SIGNED_SHORT (op);
|
||||||
|
}
|
||||||
|
/* Store vector register S at (r31+r0) aligned to 16 bytes. */
|
||||||
|
/* 011111 sssss 11111 00000 00111001110 */
|
||||||
|
else if ((op & 0xfc1fffff) == 0x7c1f01ce) /* stvx Vs, R31, R0 */
|
||||||
|
{
|
||||||
|
if (pc == (li_found_pc + 4))
|
||||||
|
{
|
||||||
|
vr_reg = GET_SRC_REG (op);
|
||||||
|
/* If this is the first vector reg to be saved, or if
|
||||||
|
it has a lower number than others previously seen,
|
||||||
|
reupdate the frame info. */
|
||||||
|
if (fdata->saved_vr == -1 || fdata->saved_vr > vr_reg)
|
||||||
|
{
|
||||||
|
fdata->saved_vr = vr_reg;
|
||||||
|
fdata->vr_offset = vr_saved_offset + offset;
|
||||||
|
}
|
||||||
|
vr_saved_offset = -1;
|
||||||
|
vr_reg = -1;
|
||||||
|
li_found_pc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* End AltiVec related instructions. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Not a recognized prologue instruction.
|
/* Not a recognized prologue instruction.
|
||||||
@ -1304,7 +1380,8 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
|
|||||||
{
|
{
|
||||||
CORE_ADDR frame_addr;
|
CORE_ADDR frame_addr;
|
||||||
struct rs6000_framedata work_fdata;
|
struct rs6000_framedata work_fdata;
|
||||||
int wordsize = TDEP->wordsize;
|
struct gdbarch_tdep * tdep = gdbarch_tdep (current_gdbarch);
|
||||||
|
int wordsize = tdep->wordsize;
|
||||||
|
|
||||||
if (fi->saved_regs)
|
if (fi->saved_regs)
|
||||||
return;
|
return;
|
||||||
@ -1322,8 +1399,12 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
|
|||||||
/* The following is true only if the frame doesn't have a call to
|
/* The following is true only if the frame doesn't have a call to
|
||||||
alloca(), FIXME. */
|
alloca(), FIXME. */
|
||||||
|
|
||||||
if (fdatap->saved_fpr == 0 && fdatap->saved_gpr == 0
|
if (fdatap->saved_fpr == 0
|
||||||
&& fdatap->lr_offset == 0 && fdatap->cr_offset == 0)
|
&& fdatap->saved_gpr == 0
|
||||||
|
&& fdatap->saved_vr == 0
|
||||||
|
&& fdatap->lr_offset == 0
|
||||||
|
&& fdatap->cr_offset == 0
|
||||||
|
&& fdatap->vr_offset == 0)
|
||||||
frame_addr = 0;
|
frame_addr = 0;
|
||||||
else if (fi->prev && fi->prev->frame)
|
else if (fi->prev && fi->prev->frame)
|
||||||
frame_addr = fi->prev->frame;
|
frame_addr = fi->prev->frame;
|
||||||
@ -1358,17 +1439,36 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if != -1, fdatap->saved_vr is the smallest number of saved_vr.
|
||||||
|
All vr's from saved_vr to vr31 are saved. */
|
||||||
|
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
|
||||||
|
{
|
||||||
|
if (fdatap->saved_vr >= 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
CORE_ADDR vr_addr = frame_addr + fdatap->vr_offset;
|
||||||
|
for (i = fdatap->saved_vr; i < 32; i++)
|
||||||
|
{
|
||||||
|
fi->saved_regs[tdep->ppc_vr0_regnum + i] = vr_addr;
|
||||||
|
vr_addr += REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If != 0, fdatap->cr_offset is the offset from the frame that holds
|
/* If != 0, fdatap->cr_offset is the offset from the frame that holds
|
||||||
the CR. */
|
the CR. */
|
||||||
if (fdatap->cr_offset != 0)
|
if (fdatap->cr_offset != 0)
|
||||||
fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_cr_regnum] =
|
fi->saved_regs[tdep->ppc_cr_regnum] = frame_addr + fdatap->cr_offset;
|
||||||
frame_addr + fdatap->cr_offset;
|
|
||||||
|
|
||||||
/* If != 0, fdatap->lr_offset is the offset from the frame that holds
|
/* If != 0, fdatap->lr_offset is the offset from the frame that holds
|
||||||
the LR. */
|
the LR. */
|
||||||
if (fdatap->lr_offset != 0)
|
if (fdatap->lr_offset != 0)
|
||||||
fi->saved_regs[gdbarch_tdep (current_gdbarch)->ppc_lr_regnum] =
|
fi->saved_regs[tdep->ppc_lr_regnum] = frame_addr + fdatap->lr_offset;
|
||||||
frame_addr + fdatap->lr_offset;
|
|
||||||
|
/* If != 0, fdatap->vrsave_offset is the offset from the frame that holds
|
||||||
|
the VRSAVE. */
|
||||||
|
if (fdatap->vrsave_offset != 0)
|
||||||
|
fi->saved_regs[tdep->ppc_vrsave_regnum] = frame_addr + fdatap->vrsave_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the address of a frame. This is the inital %sp value when the frame
|
/* Return the address of a frame. This is the inital %sp value when the frame
|
||||||
|
Loading…
Reference in New Issue
Block a user