+/* Helper function for v850_scan_prologue to handle prepare instruction. */
+
+static void
+handle_prepare (int insn, int insn2, CORE_ADDR * current_pc_ptr,
+ struct prologue_info *pi, struct pifsr **pifsr_ptr)
+{
+ CORE_ADDR current_pc = *current_pc_ptr;
+ struct pifsr *pifsr = *pifsr_ptr;
+ long next = insn2 & 0xffff;
+ long list12 = ((insn & 1) << 16) + (next & 0xffe0);
+ long offset = (insn & 0x3e) << 1;
+ static struct reg_list reg_table[] =
+ {
+ {0x00800, 20}, /* r20 */
+ {0x00400, 21}, /* r21 */
+ {0x00200, 22}, /* r22 */
+ {0x00100, 23}, /* r23 */
+ {0x08000, 24}, /* r24 */
+ {0x04000, 25}, /* r25 */
+ {0x02000, 26}, /* r26 */
+ {0x01000, 27}, /* r27 */
+ {0x00080, 28}, /* r28 */
+ {0x00040, 29}, /* r29 */
+ {0x10000, 30}, /* ep */
+ {0x00020, 31}, /* lp */
+ {0, 0} /* end of table */
+ };
+ int i;
+
+ if ((next & 0x1f) == 0x0b) /* skip imm16 argument */
+ current_pc += 2;
+ else if ((next & 0x1f) == 0x13) /* skip imm16 argument */
+ current_pc += 2;
+ else if ((next & 0x1f) == 0x1b) /* skip imm32 argument */
+ current_pc += 4;
+
+ /* Calculate the total size of the saved registers, and add it
+ it to the immediate value used to adjust SP. */
+ for (i = 0; reg_table[i].mask != 0; i++)
+ if (list12 & reg_table[i].mask)
+ offset += REGISTER_RAW_SIZE (regtable[i].regno);
+ pi->frameoffset -= offset;
+
+ /* Calculate the offsets of the registers relative to the value
+ the SP will have after the registers have been pushed and the
+ imm5 value has been subtracted from it. */
+ if (pifsr)
+ {
+ for (i = 0; reg_table[i].mask != 0; i++)
+ {
+ if (list12 & reg_table[i].mask)
+ {
+ int reg = reg_table[i].regno;
+ offset -= REGISTER_RAW_SIZE (reg);
+ pifsr->reg = reg;
+ pifsr->offset = offset;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+
+ /* Set result parameters. */
+ *current_pc_ptr = current_pc;
+ *pifsr_ptr = pifsr;
+}
+
+
+/* Helper function for v850_scan_prologue to handle pushm/pushl instructions.
+ FIXME: the SR bit of the register list is not supported; must check
+ that the compiler does not ever generate this bit. */
+
+static void
+handle_pushm (int insn, int insn2, struct prologue_info *pi,
+ struct pifsr **pifsr_ptr)
+{
+ struct pifsr *pifsr = *pifsr_ptr;
+ long list12 = ((insn & 0x0f) << 16) + (insn2 & 0xfff0);
+ long offset = 0;
+ static struct reg_list pushml_reg_table[] =
+ {
+ {0x80000, PS_REGNUM}, /* PSW */
+ {0x40000, 1}, /* r1 */
+ {0x20000, 2}, /* r2 */
+ {0x10000, 3}, /* r3 */
+ {0x00800, 4}, /* r4 */
+ {0x00400, 5}, /* r5 */
+ {0x00200, 6}, /* r6 */
+ {0x00100, 7}, /* r7 */
+ {0x08000, 8}, /* r8 */
+ {0x04000, 9}, /* r9 */
+ {0x02000, 10}, /* r10 */
+ {0x01000, 11}, /* r11 */
+ {0x00080, 12}, /* r12 */
+ {0x00040, 13}, /* r13 */
+ {0x00020, 14}, /* r14 */
+ {0x00010, 15}, /* r15 */
+ {0, 0} /* end of table */
+ };
+ static struct reg_list pushmh_reg_table[] =
+ {
+ {0x80000, 16}, /* r16 */
+ {0x40000, 17}, /* r17 */
+ {0x20000, 18}, /* r18 */
+ {0x10000, 19}, /* r19 */
+ {0x00800, 20}, /* r20 */
+ {0x00400, 21}, /* r21 */
+ {0x00200, 22}, /* r22 */
+ {0x00100, 23}, /* r23 */
+ {0x08000, 24}, /* r24 */
+ {0x04000, 25}, /* r25 */
+ {0x02000, 26}, /* r26 */
+ {0x01000, 27}, /* r27 */
+ {0x00080, 28}, /* r28 */
+ {0x00040, 29}, /* r29 */
+ {0x00010, 30}, /* r30 */
+ {0x00020, 31}, /* r31 */
+ {0, 0} /* end of table */
+ };
+ struct reg_list *reg_table;
+ int i;
+
+ /* Is this a pushml or a pushmh? */
+ if ((insn2 & 7) == 1)
+ reg_table = pushml_reg_table;
+ else
+ reg_table = pushmh_reg_table;
+
+ /* Calculate the total size of the saved registers, and add it
+ it to the immediate value used to adjust SP. */
+ for (i = 0; reg_table[i].mask != 0; i++)
+ if (list12 & reg_table[i].mask)
+ offset += REGISTER_RAW_SIZE (regtable[i].regno);
+ pi->frameoffset -= offset;
+
+ /* Calculate the offsets of the registers relative to the value
+ the SP will have after the registers have been pushed and the
+ imm5 value is subtracted from it. */
+ if (pifsr)
+ {
+ for (i = 0; reg_table[i].mask != 0; i++)
+ {
+ if (list12 & reg_table[i].mask)
+ {
+ int reg = reg_table[i].regno;
+ offset -= REGISTER_RAW_SIZE (reg);
+ pifsr->reg = reg;
+ pifsr->offset = offset;
+ pifsr->cur_frameoffset = pi->frameoffset;
+#ifdef DEBUG
+ printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
+#endif
+ pifsr++;
+ }
+ }
+ }
+#ifdef DEBUG
+ printf_filtered ("\tfound ctret after regsave func");
+#endif
+
+ /* Set result parameters. */
+ *pifsr_ptr = pifsr;
+}