1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2025-03-11 19:00:07 +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 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; enum ia64_script_insn_opcode opc;
unsigned long val, rval; unsigned long val, rval;
struct ia64_script_insn insn; struct ia64_script_insn insn;
@ -439,6 +439,7 @@ static inline int
build_script (struct cursor *c, struct ia64_script *script) build_script (struct cursor *c, struct ia64_script *script)
{ {
int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3]; int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3];
struct ia64_reg_info *pri_unat;
struct ia64_state_record sr; struct ia64_state_record sr;
struct ia64_script_insn insn; struct ia64_script_insn insn;
@ -461,26 +462,36 @@ build_script (struct cursor *c, struct ia64_script *script)
script_emit (script, insn); script_emit (script, insn);
} }
else 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) if (sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_GR].when
i = IA64_REG_PRI_UNAT_MEM; || sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when) {
i = IA64_REG_PRI_UNAT_GR; if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when > /* (primary) NaT bits were saved to memory only */
sr.curr.reg[IA64_REG_PRI_UNAT_GR].when) pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
i = IA64_REG_PRI_UNAT_MEM; else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
else /* (primary) NaT bits were saved to a register only */
i = IA64_REG_PRI_UNAT_GR; pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
compile_reg (&sr, i, script); 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. */ /* Third, compile the other register in decreasing order of WHEN values. */
num_regs = sort_regs (&sr, regorder); num_regs = sort_regs (&sr, regorder);
for (i = 0; i < num_regs; ++i) 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->abi_marker = sr.abi_marker;
script_finalize (script, c, &sr); script_finalize (script, c, &sr);
@ -497,9 +508,9 @@ static inline int
run_script (struct ia64_script *script, struct cursor *c) run_script (struct ia64_script *script, struct cursor *c)
{ {
struct ia64_script_insn *ip, *limit, next_insn; struct ia64_script_insn *ip, *limit, next_insn;
unw_word_t val, unat_addr;
unsigned long opc, dst; unsigned long opc, dst;
ia64_loc_t loc; ia64_loc_t loc;
unw_word_t val;
int ret; int ret;
c->pi = script->pi; c->pi = script->pi;
@ -550,10 +561,15 @@ run_script (struct ia64_script *script, struct cursor *c)
break; break;
case IA64_INSN_SETNAT_MEMSTK: case IA64_INSN_SETNAT_MEMSTK:
if ((ret = ia64_get (c, c->loc[IA64_REG_PRI_UNAT_MEM], loc = c->loc[IA64_REG_PRI_UNAT_MEM];
&unat_addr)) < 0) /* This is a fast and clean, if somewhat verbose way of
return ret; turning on bit 1 in the first word. */
loc = IA64_LOC_ADDR (unat_addr, IA64_LOC_TYPE_MEMSTK_NAT); 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; break;
case IA64_INSN_INC_PSP: case IA64_INSN_INC_PSP: