+ int status;
+ gdb_byte instr[2];
+
+ /* Instructions can be as small as one byte; however, we usually
+ need at least two bytes to do the decoding, so fetch that many
+ to begin with. */
+ status = target_read_memory (pc, instr, 2);
+ if (status != 0)
+ break;
+
+ /* movm [regs], sp */
+ if (instr[0] == 0xcf)
+ {
+ gdb_byte save_mask;
+
+ save_mask = instr[1];
+
+ if ((save_mask & movm_exreg0_bit) && am33_mode)
+ {
+ push_reg (regs, stack, E_E2_REGNUM);
+ push_reg (regs, stack, E_E3_REGNUM);
+ }
+ if ((save_mask & movm_exreg1_bit) && am33_mode)
+ {
+ push_reg (regs, stack, E_E4_REGNUM);
+ push_reg (regs, stack, E_E5_REGNUM);
+ push_reg (regs, stack, E_E6_REGNUM);
+ push_reg (regs, stack, E_E7_REGNUM);
+ }
+ if ((save_mask & movm_exother_bit) && am33_mode)
+ {
+ push_reg (regs, stack, E_E0_REGNUM);
+ push_reg (regs, stack, E_E1_REGNUM);
+ push_reg (regs, stack, E_MDRQ_REGNUM);
+ push_reg (regs, stack, E_MCRH_REGNUM);
+ push_reg (regs, stack, E_MCRL_REGNUM);
+ push_reg (regs, stack, E_MCVF_REGNUM);
+ }
+ if (save_mask & movm_d2_bit)
+ push_reg (regs, stack, E_D2_REGNUM);
+ if (save_mask & movm_d3_bit)
+ push_reg (regs, stack, E_D3_REGNUM);
+ if (save_mask & movm_a2_bit)
+ push_reg (regs, stack, E_A2_REGNUM);
+ if (save_mask & movm_a3_bit)
+ push_reg (regs, stack, E_A3_REGNUM);
+ if (save_mask & movm_other_bit)
+ {
+ push_reg (regs, stack, E_D0_REGNUM);
+ push_reg (regs, stack, E_D1_REGNUM);
+ push_reg (regs, stack, E_A0_REGNUM);
+ push_reg (regs, stack, E_A1_REGNUM);
+ push_reg (regs, stack, E_MDR_REGNUM);
+ push_reg (regs, stack, E_LIR_REGNUM);
+ push_reg (regs, stack, E_LAR_REGNUM);
+ /* The `other' bit leaves a blank area of four bytes at
+ the beginning of its block of saved registers, making
+ it 32 bytes long in total. */
+ regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], -4);
+ }
+
+ pc += 2;
+ after_last_frame_setup_insn = pc;
+ }
+ /* mov sp, aN */
+ else if ((instr[0] & 0xfc) == 0x3c)
+ {
+ int aN = instr[0] & 0x03;
+
+ regs[E_A0_REGNUM + aN] = regs[E_SP_REGNUM];
+
+ pc += 1;
+ if (aN == 3)
+ after_last_frame_setup_insn = pc;
+ }
+ /* mov aM, aN */
+ else if ((instr[0] & 0xf0) == 0x90
+ && (instr[0] & 0x03) != ((instr[0] & 0x0c) >> 2))
+ {
+ int aN = instr[0] & 0x03;
+ int aM = (instr[0] & 0x0c) >> 2;
+
+ regs[E_A0_REGNUM + aN] = regs[E_A0_REGNUM + aM];
+
+ pc += 1;
+ }
+ /* mov dM, dN */
+ else if ((instr[0] & 0xf0) == 0x80
+ && (instr[0] & 0x03) != ((instr[0] & 0x0c) >> 2))
+ {
+ int dN = instr[0] & 0x03;
+ int dM = (instr[0] & 0x0c) >> 2;
+
+ regs[E_D0_REGNUM + dN] = regs[E_D0_REGNUM + dM];
+
+ pc += 1;
+ }
+ /* mov aM, dN */
+ else if (instr[0] == 0xf1 && (instr[1] & 0xf0) == 0xd0)
+ {
+ int dN = instr[1] & 0x03;
+ int aM = (instr[1] & 0x0c) >> 2;
+
+ regs[E_D0_REGNUM + dN] = regs[E_A0_REGNUM + aM];
+
+ pc += 2;
+ }
+ /* mov dM, aN */
+ else if (instr[0] == 0xf1 && (instr[1] & 0xf0) == 0xe0)
+ {
+ int aN = instr[1] & 0x03;
+ int dM = (instr[1] & 0x0c) >> 2;
+
+ regs[E_A0_REGNUM + aN] = regs[E_D0_REGNUM + dM];
+
+ pc += 2;
+ }
+ /* add imm8, SP */
+ else if (instr[0] == 0xf8 && instr[1] == 0xfe)
+ {
+ gdb_byte buf[1];
+ LONGEST imm8;
+
+
+ status = target_read_memory (pc + 2, buf, 1);
+ if (status != 0)
+ break;
+
+ imm8 = extract_signed_integer (buf, 1, byte_order);
+ regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm8);
+
+ pc += 3;
+ /* Stack pointer adjustments are frame related. */
+ after_last_frame_setup_insn = pc;
+ }
+ /* add imm16, SP */
+ else if (instr[0] == 0xfa && instr[1] == 0xfe)
+ {
+ gdb_byte buf[2];
+ LONGEST imm16;
+
+ status = target_read_memory (pc + 2, buf, 2);
+ if (status != 0)
+ break;
+
+ imm16 = extract_signed_integer (buf, 2, byte_order);
+ regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm16);
+
+ pc += 4;
+ /* Stack pointer adjustments are frame related. */
+ after_last_frame_setup_insn = pc;
+ }
+ /* add imm32, SP */
+ else if (instr[0] == 0xfc && instr[1] == 0xfe)
+ {
+ gdb_byte buf[4];
+ LONGEST imm32;
+
+ status = target_read_memory (pc + 2, buf, 4);
+ if (status != 0)
+ break;
+
+
+ imm32 = extract_signed_integer (buf, 4, byte_order);
+ regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm32);
+
+ pc += 6;
+ /* Stack pointer adjustments are frame related. */
+ after_last_frame_setup_insn = pc;
+ }
+ /* add imm8, aN */
+ else if ((instr[0] & 0xfc) == 0x20)
+ {
+ int aN;
+ LONGEST imm8;
+
+ aN = instr[0] & 0x03;
+ imm8 = extract_signed_integer (&instr[1], 1, byte_order);
+
+ regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN],
+ imm8);
+
+ pc += 2;
+ }
+ /* add imm16, aN */
+ else if (instr[0] == 0xfa && (instr[1] & 0xfc) == 0xd0)
+ {
+ int aN;
+ LONGEST imm16;
+ gdb_byte buf[2];
+
+ aN = instr[1] & 0x03;
+
+ status = target_read_memory (pc + 2, buf, 2);
+ if (status != 0)
+ break;
+
+
+ imm16 = extract_signed_integer (buf, 2, byte_order);
+
+ regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN],
+ imm16);
+
+ pc += 4;
+ }
+ /* add imm32, aN */
+ else if (instr[0] == 0xfc && (instr[1] & 0xfc) == 0xd0)
+ {
+ int aN;
+ LONGEST imm32;
+ gdb_byte buf[4];
+
+ aN = instr[1] & 0x03;
+
+ status = target_read_memory (pc + 2, buf, 4);
+ if (status != 0)
+ break;
+
+ imm32 = extract_signed_integer (buf, 2, byte_order);
+
+ regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN],
+ imm32);
+ pc += 6;
+ }
+ /* fmov fsM, (rN) */
+ else if (instr[0] == 0xf9 && (instr[1] & 0xfd) == 0x30)
+ {
+ int fsM, sM, Y, rN;
+ gdb_byte buf[1];
+
+ Y = (instr[1] & 0x02) >> 1;
+
+ status = target_read_memory (pc + 2, buf, 1);
+ if (status != 0)
+ break;
+
+ sM = (buf[0] & 0xf0) >> 4;
+ rN = buf[0] & 0x0f;
+ fsM = (Y << 4) | sM;
+
+ pv_area_store (stack, regs[translate_rreg (rN)], 4,
+ regs[E_FS0_REGNUM + fsM]);
+
+ pc += 3;
+ }
+ /* fmov fsM, (sp) */
+ else if (instr[0] == 0xf9 && (instr[1] & 0xfd) == 0x34)
+ {
+ int fsM, sM, Y;
+ gdb_byte buf[1];
+
+ Y = (instr[1] & 0x02) >> 1;
+
+ status = target_read_memory (pc + 2, buf, 1);
+ if (status != 0)
+ break;