[RFA] V850 patch

Martin M. Hunt
2003-02-20T05:16:15Z

I'm submitting this for Jim Wilson. It is a revised patch
of the one submitted by Miles Bader for GDB PR #870.

I have verified it applies cleanly to the current CVS head and
seems to fix the problems it claims. There are no testsuite regressions.

2003-01-08 Miles Bader <miles@gnu.org>
Jim Wilson <wilson@redhat.com>

* v850-tdep.c (v850_scan_prologue): Handle six byte instructions.
Correctly sign-extend insn2. Use insn2 as well as insn to recognize
insns where appropriate (some insns only differ in the second 16-bit
word). Handle mov imm5,r12 and mov imm32,r12.

Index: v850-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/v850-tdep.c,v
retrieving revision 2.33.6.1
diff -p -r2.33.6.1 v850-tdep.c
*** v850-tdep.c 2002/08/08 07:56:41 2.33.6.1
--- v850-tdep.c 2003/01/08 20:06:06
*************** v850_scan_prologue (CORE_ADDR pc, struct
*** 627,643 ****

insn = read_memory_unsigned_integer (current_pc, 2);
current_pc += 2;
! if ((insn & 0x0780) >= 0x0600) /* Four byte instruction? */
{
insn2 = read_memory_unsigned_integer (current_pc, 2);
current_pc += 2;
}

! if ((insn & 0xffc0) == ((10 << 11) | 0x0780) && !regsave_func_p)
{ /* jarl <func>,10 */
! long low_disp = insn2 & ~(long) 1;
! long disp = (((((insn & 0x3f) << 16) + low_disp)
! & ~(long) 1) ^ 0x00200000) - 0x00200000;

save_pc = current_pc;
save_end = prologue_end;
--- 627,654 ----

insn = read_memory_unsigned_integer (current_pc, 2);
current_pc += 2;
! if ((insn & 0xffe0) == 0x0620) /* Six byte instruction? */
{
+ insn2 = read_memory_unsigned_integer (current_pc, 4);
+ current_pc += 4;
+ }
+ else if ((insn & 0x0780) >= 0x0600) /* Four byte instruction? */
+ {
insn2 = read_memory_unsigned_integer (current_pc, 2);
current_pc += 2;
+
+ /* Most uses of insn2 below interpret it as a sign-extended
+ 16-bit field, so sign-extend it here. */
+ insn2 = (insn2 ^ 0x8000) - 0x8000;
}

! if ((insn & 0xffc0) == ((10 << 11) | 0x0780)
! && (insn2 & 1) == 0
! && !regsave_func_p)
{ /* jarl <func>,10 */
! long low_disp = insn2 & 0xfffe;
! long disp = (((((insn & 0x3f) << 16) | low_disp) ^ 0x00200000)
! - 0x00200000);

save_pc = current_pc;
save_end = prologue_end;
*************** v850_scan_prologue (CORE_ADDR pc, struct
*** 676,683 ****
#endif
continue;
}
! else if ((insn & 0xffc0) == 0x0780) /* prepare list2,imm5 */
! {
handle_prepare (insn, insn2, &current_pc, pi, &pifsr);
continue;
}
--- 687,695 ----
#endif
continue;
}
! else if ((insn & 0xffc0) == 0x0780
! && ((insn2 & 0x1f) == 0x01 || (insn2 & 0x03) == 0x03))
! { /* prepare list2,imm5 */
handle_prepare (insn, insn2, &current_pc, pi, &pifsr);
continue;
}
*************** v850_scan_prologue (CORE_ADDR pc, struct
*** 706,712 ****
#endif
continue;
}
! else if ((insn & 0x07c0) == 0x0780 /* jarl or jr */
|| (insn & 0xffe0) == 0x0060 /* jmp */
|| (insn & 0x0780) == 0x0580) /* branch */
{
--- 718,725 ----
#endif
continue;
}
! else if (((insn & 0x07c0) == 0x0780 /* jarl or jr */
! && (insn2 & 1) == 0)
|| (insn & 0xffe0) == 0x0060 /* jmp */
|| (insn & 0x0780) == 0x0580) /* branch */
{
*************** v850_scan_prologue (CORE_ADDR pc, struct
*** 726,731 ****
--- 739,748 ----
pi->framereg = E_FP_RAW_REGNUM;
}

+ else if ((insn & 0xffe0) == ((E_R12_REGNUM << 11) | 0x0200)) /* mov imm5,r12 */
+ r12_tmp = ((insn & 0x1f) ^ 0x10) - 0x10;
+ else if (insn == (0x0620 | E_R12_REGNUM)) /* mov imm32,r12 */
+ r12_tmp = insn2;
else if (insn == ((E_R12_REGNUM << 11) | 0x0640 | E_R0_REGNUM)) /* movhi hi(const),r0,r12 */
r12_tmp = insn2 << 16;
else if (insn == ((E_R12_REGNUM << 11) | 0x0620 | E_R12_REGNUM)) /* movea lo(const),r12,r12 */