1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2025-02-02 12:52:53 +01:00

(compile_reg): Take extra ia64_reg_info-pointer argument.

(build_script): Adjust for extra argument to compile_reg().
	Fix the primary-NaT compilation such that it always
	updates IA64_REGPRI_UNAT_MEM.
(run_script): For IA64_INSN_SETNET_MEMSTK, set the location based on
	IA64_REG_PRI_UNAT_MEM and don't forget to turn on the
	MEMSTK_NAT bit.

(Logical change 1.178)
This commit is contained in:
hp.com!davidm 2004-02-27 00:54:27 +00:00
parent c4d1b80bfe
commit d83276cb80

View file

@ -294,9 +294,9 @@ emit_nat_info (struct ia64_state_record *sr, int i, struct ia64_script *script)
}
static void
compile_reg (struct ia64_state_record *sr, int i, struct ia64_script *script)
compile_reg (struct ia64_state_record *sr, int i, struct ia64_reg_info *r,
struct ia64_script *script)
{
struct ia64_reg_info *r = sr->curr.reg + i;
enum ia64_script_insn_opcode opc;
unsigned long val, rval;
struct ia64_script_insn insn;
@ -439,6 +439,7 @@ static inline int
build_script (struct cursor *c, struct ia64_script *script)
{
int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3];
struct ia64_reg_info *pri_unat;
struct ia64_state_record sr;
struct ia64_script_insn insn;
@ -461,26 +462,36 @@ build_script (struct cursor *c, struct ia64_script *script)
script_emit (script, insn);
}
else
compile_reg (&sr, IA64_REG_PSP, script);
compile_reg (&sr, IA64_REG_PSP, sr.curr.reg + IA64_REG_PSP, script);
/* Second, compile the update for the primary UNaT: */
/* Second, compile the update for the primary UNaT, if any: */
if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
i = IA64_REG_PRI_UNAT_MEM;
else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
i = IA64_REG_PRI_UNAT_GR;
else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when >
sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
i = IA64_REG_PRI_UNAT_MEM;
else
i = IA64_REG_PRI_UNAT_GR;
compile_reg (&sr, i, script);
if (sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_GR].when
|| sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
{
if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
/* (primary) NaT bits were saved to memory only */
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
/* (primary) NaT bits were saved to a register only */
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when >
sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
/* (primary) NaT bits were last saved to memory */
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
else
/* (primary) NaT bits were last saved to a register */
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR;
/* Note: we always store the final primary-UNaT location in UNAT_MEM. */
compile_reg (&sr, IA64_REG_PRI_UNAT_MEM, pri_unat, script);
}
/* Third, compile the other register in decreasing order of WHEN values. */
num_regs = sort_regs (&sr, regorder);
for (i = 0; i < num_regs; ++i)
compile_reg (&sr, regorder[i], script);
compile_reg (&sr, regorder[i], sr.curr.reg + regorder[i], script);
script->abi_marker = sr.abi_marker;
script_finalize (script, c, &sr);
@ -497,9 +508,9 @@ static inline int
run_script (struct ia64_script *script, struct cursor *c)
{
struct ia64_script_insn *ip, *limit, next_insn;
unw_word_t val, unat_addr;
unsigned long opc, dst;
ia64_loc_t loc;
unw_word_t val;
int ret;
c->pi = script->pi;
@ -550,10 +561,15 @@ run_script (struct ia64_script *script, struct cursor *c)
break;
case IA64_INSN_SETNAT_MEMSTK:
if ((ret = ia64_get (c, c->loc[IA64_REG_PRI_UNAT_MEM],
&unat_addr)) < 0)
return ret;
loc = IA64_LOC_ADDR (unat_addr, IA64_LOC_TYPE_MEMSTK_NAT);
loc = c->loc[IA64_REG_PRI_UNAT_MEM];
/* This is a fast and clean, if somewhat verbose way of
turning on bit 1 in the first word. */
if (IA64_IS_REG_LOC (loc))
loc = IA64_LOC_REG (IA64_GET_REG (loc),
IA64_LOC_TYPE_MEMSTK_NAT);
else
loc = IA64_LOC_ADDR (IA64_GET_ADDR (loc),
IA64_LOC_TYPE_MEMSTK_NAT);
break;
case IA64_INSN_INC_PSP: