+void
+md_assemble (char *str)
+{
+ const char * pperr = 0;
+ int regmask=0, push=0, pop=0;
+
+ /* Special-case push/pop instruction macros. */
+ if (0 == strncmp (str, "push {", 6))
+ {
+ char * s = str + 6;
+ push = 1;
+ pperr = parse_reglist (s, ®mask);
+ }
+ else if (0 == strncmp (str, "pop {", 5))
+ {
+ char * s = str + 5;
+ pop = 1;
+ pperr = parse_reglist (s, ®mask);
+ }
+
+ if (pperr)
+ {
+ as_bad ("%s", pperr);
+ return;
+ }
+
+ if (push && regmask)
+ {
+ char buff[20];
+ int i,p ATTRIBUTE_UNUSED;
+
+ epiphany_assemble ("mov r15,4");
+ epiphany_assemble ("sub sp,sp,r15");
+
+ for (i = 0, p = 1; i <= 15; ++i, regmask >>= 1)
+ {
+ if (regmask == 1)
+ sprintf (buff, "str r%d,[sp]", i); /* Last one. */
+ else if (regmask & 1)
+ sprintf (buff, "str r%d,[sp],-r15", i);
+ else
+ continue;
+ epiphany_assemble (buff);
+ }
+ return;
+ }
+ else if (pop && regmask)
+ {
+ char buff[20];
+ int i,p;
+
+ epiphany_assemble ("mov r15,4");
+
+ for (i = 15, p = 1 << 15; i >= 0; --i, p >>= 1)
+ if (regmask & p)
+ {
+ sprintf (buff, "ldr r%d,[sp],+r15", i);
+ epiphany_assemble (buff);
+ }
+ return;
+ }
+
+ epiphany_assemble (str);
+}
+