+static inline unsigned int
+os_context_register(os_context_t *context, int offset)
+{
+ return (unsigned int)(*os_context_register_addr(context, offset));
+}
+
+static inline unsigned int
+os_context_pc(os_context_t *context)
+{
+ return (unsigned int)(*os_context_pc_addr(context));
+}
+
+static inline unsigned int
+os_context_insn(os_context_t *context)
+{
+ if (os_context_bd_cause(context))
+ return *(unsigned int *)(os_context_pc(context) + INSN_LEN);
+ else
+ return *(unsigned int *)(os_context_pc(context));
+}
+
+boolean
+arch_insn_with_bdelay_p(unsigned int insn)
+{
+ switch (insn >> 26) {
+ case 0x0:
+ switch (insn & 0x3f) {
+ /* register jumps */
+ case 0x08:
+ case 0x09:
+ return 1;
+ }
+ break;
+ /* branches and immediate jumps */
+ case 0x1:
+ switch ((insn >> 16) & 0x1f) {
+ case 0x00:
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ return 1;
+ }
+ break;
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ return 1;
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ switch ((insn >> 21) & 0x1f) {
+ /* CP0/CP1/CP2 branches */
+ case 0x08:
+ return 1;
+ }
+ break;
+ /* branch likely (MIPS II) */
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ return 1;
+ }
+ return 0;
+}
+
+/* Find the next instruction in the control flow. For a instruction
+ with branch delay slot, this is the branch/jump target if the branch
+ is taken, and PC + 8 if it is not taken. For other instructions it
+ is PC + 4. */