+/* Attempt to emulate an ARMv6 instruction.
+ Stores t_branch into PVALUE upon success or t_undefined otherwise. */
+
+static void
+handle_v6_thumb_insn (ARMul_State * state,
+ ARMword tinstr,
+ tdstate * pvalid)
+{
+ ARMword Rd;
+ ARMword Rm;
+
+ if (! state->is_v6)
+ {
+ * pvalid = t_undefined;
+ return;
+ }
+
+ switch (tinstr & 0xFFC0)
+ {
+ case 0xb660: /* cpsie */
+ case 0xb670: /* cpsid */
+ case 0x4600: /* cpy */
+ case 0xba00: /* rev */
+ case 0xba40: /* rev16 */
+ case 0xbac0: /* revsh */
+ case 0xb650: /* setend */
+ default:
+ printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
+ * pvalid = t_undefined;
+ return;
+
+ case 0xb200: /* sxth */
+ Rm = state->Reg [(tinstr & 0x38) >> 3];
+ if (Rm & 0x8000)
+ state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
+ else
+ state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
+ break;
+ case 0xb240: /* sxtb */
+ Rm = state->Reg [(tinstr & 0x38) >> 3];
+ if (Rm & 0x80)
+ state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
+ else
+ state->Reg [(tinstr & 0x7)] = Rm & 0xff;
+ break;
+ case 0xb280: /* uxth */
+ Rm = state->Reg [(tinstr & 0x38) >> 3];
+ state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
+ break;
+ case 0xb2c0: /* uxtb */
+ Rm = state->Reg [(tinstr & 0x38) >> 3];
+ state->Reg [(tinstr & 0x7)] = Rm & 0xff;
+ break;
+ }
+ /* Indicate that the instruction has been processed. */
+ * pvalid = t_branch;
+}
+