* mips-tdep.c (mips32_bc1_pc): New function.
(mips32_next_pc): Handle BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T, BPOSGE32 and BPOSGE64 instructions. (deal_with_atomic_sequence): Likewise. (mips32_instruction_has_delay_slot): Likewise.
This commit is contained in:
parent
1faeff088b
commit
a385295e2c
|
@ -1,3 +1,11 @@
|
||||||
|
2012-03-01 Maciej W. Rozycki <macro@codesourcery.com>
|
||||||
|
|
||||||
|
* mips-tdep.c (mips32_bc1_pc): New function.
|
||||||
|
(mips32_next_pc): Handle BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T,
|
||||||
|
BPOSGE32 and BPOSGE64 instructions.
|
||||||
|
(deal_with_atomic_sequence): Likewise.
|
||||||
|
(mips32_instruction_has_delay_slot): Likewise.
|
||||||
|
|
||||||
2012-03-01 Maciej W. Rozycki <macro@mips.com>
|
2012-03-01 Maciej W. Rozycki <macro@mips.com>
|
||||||
Chris Dearman <chris@mips.com>
|
Chris Dearman <chris@mips.com>
|
||||||
Maciej W. Rozycki <macro@codesourcery.com>
|
Maciej W. Rozycki <macro@codesourcery.com>
|
||||||
|
|
105
gdb/mips-tdep.c
105
gdb/mips-tdep.c
|
@ -1132,6 +1132,36 @@ mips32_relative_offset (ULONGEST inst)
|
||||||
return ((itype_immediate (inst) ^ 0x8000) - 0x8000) << 2;
|
return ((itype_immediate (inst) ^ 0x8000) - 0x8000) << 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine the address of the next instruction executed after the INST
|
||||||
|
floating condition branch instruction at PC. COUNT specifies the
|
||||||
|
number of the floating condition bits tested by the branch. */
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
|
||||||
|
ULONGEST inst, CORE_ADDR pc, int count)
|
||||||
|
{
|
||||||
|
int fcsr = mips_regnum (gdbarch)->fp_control_status;
|
||||||
|
int cnum = (itype_rt (inst) >> 2) & (count - 1);
|
||||||
|
int tf = itype_rt (inst) & 1;
|
||||||
|
int mask = (1 << count) - 1;
|
||||||
|
ULONGEST fcs;
|
||||||
|
int cond;
|
||||||
|
|
||||||
|
if (fcsr == -1)
|
||||||
|
/* No way to handle; it'll most likely trap anyway. */
|
||||||
|
return pc;
|
||||||
|
|
||||||
|
fcs = get_frame_register_unsigned (frame, fcsr);
|
||||||
|
cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
|
||||||
|
|
||||||
|
if (((cond >> cnum) & mask) != mask * !tf)
|
||||||
|
pc += mips32_relative_offset (inst);
|
||||||
|
else
|
||||||
|
pc += 4;
|
||||||
|
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine where to set a single step breakpoint while considering
|
/* Determine where to set a single step breakpoint while considering
|
||||||
branch prediction. */
|
branch prediction. */
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
|
@ -1164,20 +1194,15 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
|
||||||
}
|
}
|
||||||
else if (itype_op (inst) == 17 && itype_rs (inst) == 8)
|
else if (itype_op (inst) == 17 && itype_rs (inst) == 8)
|
||||||
/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
|
/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
|
||||||
{
|
pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 1);
|
||||||
int tf = itype_rt (inst) & 0x01;
|
else if (itype_op (inst) == 17 && itype_rs (inst) == 9
|
||||||
int cnum = itype_rt (inst) >> 2;
|
&& (itype_rt (inst) & 2) == 0)
|
||||||
int fcrcs =
|
/* BC1ANY2F, BC1ANY2T: 010001 01001 xxx0x */
|
||||||
get_frame_register_signed (frame,
|
pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 2);
|
||||||
mips_regnum (get_frame_arch (frame))->
|
else if (itype_op (inst) == 17 && itype_rs (inst) == 10
|
||||||
fp_control_status);
|
&& (itype_rt (inst) & 2) == 0)
|
||||||
int cond = ((fcrcs >> 24) & 0xfe) | ((fcrcs >> 23) & 0x01);
|
/* BC1ANY4F, BC1ANY4T: 010001 01010 xxx0x */
|
||||||
|
pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 4);
|
||||||
if (((cond >> cnum) & 0x01) == tf)
|
|
||||||
pc += mips32_relative_offset (inst) + 4;
|
|
||||||
else
|
|
||||||
pc += 8;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
pc += 4; /* Not a branch, next instruction is easy. */
|
pc += 4; /* Not a branch, next instruction is easy. */
|
||||||
}
|
}
|
||||||
|
@ -1236,6 +1261,25 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
|
||||||
else
|
else
|
||||||
pc += 8; /* after the delay slot */
|
pc += 8; /* after the delay slot */
|
||||||
break;
|
break;
|
||||||
|
case 0x1c: /* BPOSGE32 */
|
||||||
|
case 0x1e: /* BPOSGE64 */
|
||||||
|
pc += 4;
|
||||||
|
if (itype_rs (inst) == 0)
|
||||||
|
{
|
||||||
|
unsigned int pos = (op & 2) ? 64 : 32;
|
||||||
|
int dspctl = mips_regnum (gdbarch)->dspctl;
|
||||||
|
|
||||||
|
if (dspctl == -1)
|
||||||
|
/* No way to handle; it'll most likely trap anyway. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((get_frame_register_unsigned (frame,
|
||||||
|
dspctl) & 0x7f) >= pos)
|
||||||
|
pc += mips32_relative_offset (inst);
|
||||||
|
else
|
||||||
|
pc += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
/* All of the other instructions in the REGIMM category */
|
/* All of the other instructions in the REGIMM category */
|
||||||
default:
|
default:
|
||||||
pc += 4;
|
pc += 4;
|
||||||
|
@ -2618,7 +2662,9 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
|
||||||
return 0; /* fallback to the standard single-step code. */
|
return 0; /* fallback to the standard single-step code. */
|
||||||
break;
|
break;
|
||||||
case 1: /* REGIMM */
|
case 1: /* REGIMM */
|
||||||
is_branch = ((itype_rt (insn) & 0xc) == 0); /* B{LT,GE}Z* */
|
is_branch = ((itype_rt (insn) & 0xc) == 0 /* B{LT,GE}Z* */
|
||||||
|
|| ((itype_rt (insn) & 0x1e) == 0
|
||||||
|
&& itype_rs (insn) == 0)); /* BPOSGE* */
|
||||||
break;
|
break;
|
||||||
case 2: /* J */
|
case 2: /* J */
|
||||||
case 3: /* JAL */
|
case 3: /* JAL */
|
||||||
|
@ -2634,6 +2680,11 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
|
||||||
is_branch = 1;
|
is_branch = 1;
|
||||||
break;
|
break;
|
||||||
case 17: /* COP1 */
|
case 17: /* COP1 */
|
||||||
|
is_branch = ((itype_rs (insn) == 9 || itype_rs (insn) == 10)
|
||||||
|
&& (itype_rt (insn) & 0x2) == 0);
|
||||||
|
if (is_branch) /* BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T */
|
||||||
|
break;
|
||||||
|
/* Fall through. */
|
||||||
case 18: /* COP2 */
|
case 18: /* COP2 */
|
||||||
case 19: /* COP3 */
|
case 19: /* COP3 */
|
||||||
is_branch = (itype_rs (insn) == 8); /* BCzF, BCzFL, BCzT, BCzTL */
|
is_branch = (itype_rs (insn) == 8); /* BCzF, BCzFL, BCzT, BCzTL */
|
||||||
|
@ -5333,6 +5384,8 @@ mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
|
||||||
unsigned long inst;
|
unsigned long inst;
|
||||||
int status;
|
int status;
|
||||||
int op;
|
int op;
|
||||||
|
int rs;
|
||||||
|
int rt;
|
||||||
|
|
||||||
status = target_read_memory (addr, buf, MIPS_INSN32_SIZE);
|
status = target_read_memory (addr, buf, MIPS_INSN32_SIZE);
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -5341,10 +5394,19 @@ mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
|
||||||
inst = mips_fetch_instruction (gdbarch, addr);
|
inst = mips_fetch_instruction (gdbarch, addr);
|
||||||
op = itype_op (inst);
|
op = itype_op (inst);
|
||||||
if ((inst & 0xe0000000) != 0)
|
if ((inst & 0xe0000000) != 0)
|
||||||
return (op >> 2 == 5 /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
|
{
|
||||||
|| op == 29 /* JALX: bits 011101 */
|
rs = itype_rs (inst);
|
||||||
|| (op == 17 && itype_rs (inst) == 8));
|
rt = itype_rt (inst);
|
||||||
|
return (op >> 2 == 5 /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
|
||||||
|
|| op == 29 /* JALX: bits 011101 */
|
||||||
|
|| (op == 17
|
||||||
|
&& (rs == 8
|
||||||
/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
|
/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
|
||||||
|
|| (rs == 9 && (rt & 0x2) == 0)
|
||||||
|
/* BC1ANY2F, BC1ANY2T: bits 010001 01001 */
|
||||||
|
|| (rs == 10 && (rt & 0x2) == 0))));
|
||||||
|
/* BC1ANY4F, BC1ANY4T: bits 010001 01010 */
|
||||||
|
}
|
||||||
else
|
else
|
||||||
switch (op & 0x07) /* extract bits 28,27,26 */
|
switch (op & 0x07) /* extract bits 28,27,26 */
|
||||||
{
|
{
|
||||||
|
@ -5354,10 +5416,13 @@ mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
|
||||||
|| op == 9); /* JALR */
|
|| op == 9); /* JALR */
|
||||||
break; /* end SPECIAL */
|
break; /* end SPECIAL */
|
||||||
case 1: /* REGIMM */
|
case 1: /* REGIMM */
|
||||||
op = itype_rt (inst); /* branch condition */
|
rs = itype_rs (inst);
|
||||||
return (op & 0xc) == 0;
|
rt = itype_rt (inst); /* branch condition */
|
||||||
|
return ((rt & 0xc) == 0
|
||||||
/* BLTZ, BLTZL, BGEZ, BGEZL: bits 000xx */
|
/* BLTZ, BLTZL, BGEZ, BGEZL: bits 000xx */
|
||||||
/* BLTZAL, BLTZALL, BGEZAL, BGEZALL: 100xx */
|
/* BLTZAL, BLTZALL, BGEZAL, BGEZALL: 100xx */
|
||||||
|
|| ((rt & 0x1e) == 0x1c && rs == 0));
|
||||||
|
/* BPOSGE32, BPOSGE64: bits 1110x */
|
||||||
break; /* end REGIMM */
|
break; /* end REGIMM */
|
||||||
default: /* J, JAL, BEQ, BNE, BLEZ, BGTZ */
|
default: /* J, JAL, BEQ, BNE, BLEZ, BGTZ */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in New Issue