+/* -- assembler routines inserted here. */
+
+/* -- asm.c */
+/* Handle register lists for LDMx and STMx. */
+
+static int
+parse_register_number (const char **strp)
+{
+ int regno;
+
+ if (**strp < '0' || **strp > '9')
+ return -1; /* Error. */
+ regno = **strp - '0';
+ ++*strp;
+
+ if (**strp >= '0' && **strp <= '9')
+ {
+ regno = regno * 10 + (**strp - '0');
+ ++*strp;
+ }
+
+ return regno;
+}
+
+static const char *
+parse_register_list (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
+ const char **strp,
+ int opindex ATTRIBUTE_UNUSED,
+ unsigned long *valuep,
+ int high_low, /* 0 == high, 1 == low. */
+ int load_store) /* 0 == load, 1 == store. */
+{
+ *valuep = 0;
+ while (**strp && **strp != ')')
+ {
+ int regno;
+
+ if (**strp != 'R' && **strp != 'r')
+ break;
+ ++*strp;
+
+ regno = parse_register_number (strp);
+ if (regno == -1)
+ return _("Register number is not valid");
+ if (regno > 7 && !high_low)
+ return _("Register must be between r0 and r7");
+ if (regno < 8 && high_low)
+ return _("Register must be between r8 and r15");
+
+ if (high_low)
+ regno -= 8;
+
+ if (load_store) /* Mask is reversed for store. */
+ *valuep |= 0x80 >> regno;
+ else
+ *valuep |= 1 << regno;
+
+ if (**strp == ',')
+ {
+ if (*(*strp + 1) == ')')
+ break;
+ ++*strp;
+ }
+ }
+
+ if (!*strp || **strp != ')')
+ return _("Register list is not valid");
+
+ return NULL;
+}
+
+static const char *
+parse_low_register_list_ld (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ return parse_register_list (cd, strp, opindex, valuep,
+ 0 /* Low. */, 0 /* Load. */);
+}
+
+static const char *
+parse_hi_register_list_ld (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ return parse_register_list (cd, strp, opindex, valuep,
+ 1 /* High. */, 0 /* Load. */);
+}
+
+static const char *
+parse_low_register_list_st (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ return parse_register_list (cd, strp, opindex, valuep,
+ 0 /* Low. */, 1 /* Store. */);
+}
+
+static const char *
+parse_hi_register_list_st (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ return parse_register_list (cd, strp, opindex, valuep,
+ 1 /* High. */, 1 /* Store. */);
+}
+
+/* -- */
+
+const char * fr30_cgen_parse_operand
+ (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);