diff options
author | Stu Grossman <grossman@cygnus> | 1992-12-22 03:18:46 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1992-12-22 03:18:46 +0000 |
commit | 9f739abdacc530b319f71e627a766d030ab7268a (patch) | |
tree | e78193876b9ddabfad34ddf79e8dea7ca82e1f5c /gdb/hppa-pinsn.c | |
parent | d9a30dc6c50d7ebadbea2b5cd0d2711e90c8c5cb (diff) | |
download | gdb-9f739abdacc530b319f71e627a766d030ab7268a.zip gdb-9f739abdacc530b319f71e627a766d030ab7268a.tar.gz gdb-9f739abdacc530b319f71e627a766d030ab7268a.tar.bz2 |
* hppa-pinsn.c (print_insn): Improve handling of be and ble
branch targets to compute target address using const from previous
instruction if necessary.
* Add `Q' operator to print out bit position field various
instructions.
* hppah-nat.c: #include sys/param.h, and sys/user.h. General
cleanups, use new code from Utah.
* (store_inferior_registers): Update to new code from Utah.
* (initialize_kernel_u_addr): Re-enable decl of struct user u.
* (fetch_register): Clear out priv level when reading PCs.
* hppah-tdep.c: Get rid of gobs of KERNELDEBUG stuff.
* Remove decl of errno, #include wait.h and target.h.
* (frame_saved_pc): Check `flags' pseudo-register to see if we
were inside of a kernel call. If so, then PC is in a different
register. Also, mask out bottom two bits of all PCs so as not to
confuse higher level code.
* (push_dummy_frame): Create from #define in tm-hppa.h.
* (find_dummy_frame_regs): Update from Utah.
* (hp_pop_frame): Create from #define in tm-hppa.h.
* (hp_restore_pc_queue): New, from Utah.
* (hp_push_arguments): Big fixes from Utah.
* (pa_do_registers_info, pa_print_registers): Only print out fp
regs upon request.
* (skip_trampoline_code): New routine to deal with stubs that
live in nowhereland between callers and callees.
* i860-tdep.c: Remove decl of attach_flag.
* infrun.c (wait_for_inferior): Add new macro
INSTRUCTION_NULLIFIED, which can tell if the instruction pointed
at by PC will be nullified. If so, then step the target once more
so as to avoid confusing the user.
* (just before step_over_function:): Use stop_func_start, not
stop_pc when checking for the existance of line number info.
stop_func_start will reflect the proper address of the target
routine, not of the stub that we may be traversing to get there.
* tm-hppa.h: define SKIP_TRAMPOLINE_CODE and IN_SOLIB_TRAMPOLINE
to deal with the stubs that PA compilers sometimes stick between
callers and callees. Also, define FLAGS_REGNUM for access to the
`flags' pseudo-reg.
* (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW): Use
memcpy, not bcopy.
* (CANNOT_STORE_REGISTER): New from Utah. Says that we can't
write gr0, PC regs, and PSW!
* (FRAME_FIND_SAVED_REGS): Bug fixes from Utah.
* (PUSH_DUMMY_FRAME, POP_FRAME): Make into real routines in
hppah-nat.c.
* (CALL_DUMMY, FIX_CALL_DUMMY): Fixes from Utah.
* Define struct unwind_table_entry.
* valops.c (call_function_by_hand): Add another arg to
FIX_CALL_DUMMY (under #ifdef GDB_TARGET_IS_HPPA). Why is this
necessary?
Diffstat (limited to 'gdb/hppa-pinsn.c')
-rw-r--r-- | gdb/hppa-pinsn.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/gdb/hppa-pinsn.c b/gdb/hppa-pinsn.c index 12df5f3..0f0fec1 100644 --- a/gdb/hppa-pinsn.c +++ b/gdb/hppa-pinsn.c @@ -233,13 +233,13 @@ print_insn (memaddr, stream) print_address (memaddr + 8 + extract_12 (insn), stream); break; case 'W': - /* don't interpret an address if it's an external branch - instruction. */ op = GET_FIELD (insn, 0, 5); - if (op != 0x38 /* be */ && op != 0x39 /* ble */) - print_address (memaddr + 8 + extract_17 (insn), stream); - else + + if (op == 0x38 /* be */ || op == 0x39 /* ble */) fput_const (extract_17 (insn), stream); + else + print_address (memaddr + 8 + extract_17 (insn), stream); + break; case 'B': { @@ -257,6 +257,10 @@ print_insn (memaddr, stream) fprintf_filtered (stream, "%d", GET_FIELD (insn, 22, 26)); break; + case 'Q': + fprintf_filtered (stream, "%d", + GET_FIELD (insn, 11, 15)); + break; case 'T': fprintf_filtered (stream, "%d", 32 - GET_FIELD (insn, 27, 31)); @@ -340,6 +344,34 @@ print_insn (memaddr, stream) break; } } + +/* If this is an external branch, examine the previous instruction and see if + it was an ldil that loaded something into the same base reg. If so, then + calculate the branch target from the constants in both instructions, and + print it out. */ + + op = GET_FIELD (insn, 0, 5); + if (op == 0x38 /* be */ || op == 0x39 /* ble */) + { + CORE_ADDR target_address; + unsigned int prev_insn; + int basereg, basereg_prev; + + target_address = extract_17 (insn); + basereg = GET_FIELD (insn, 6, 10); + if (basereg != 0) + { + read_memory (memaddr - 4, &prev_insn, sizeof(prev_insn)); + basereg_prev = GET_FIELD (prev_insn, 6, 10); + + if ((prev_insn & 0xfc000000) == 0x20000000 /* ldil */ + && basereg == basereg_prev) + target_address += extract_21 (prev_insn); + } + fprintf_filtered (stream, "\t! "); + print_address (target_address, stream); + } + return sizeof(insn); } } |