aboutsummaryrefslogtreecommitdiff
path: root/gdb/hppa-pinsn.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1992-12-22 03:18:46 +0000
committerStu Grossman <grossman@cygnus>1992-12-22 03:18:46 +0000
commit9f739abdacc530b319f71e627a766d030ab7268a (patch)
treee78193876b9ddabfad34ddf79e8dea7ca82e1f5c /gdb/hppa-pinsn.c
parentd9a30dc6c50d7ebadbea2b5cd0d2711e90c8c5cb (diff)
downloadgdb-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.c42
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);
}
}