This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: m68k fmovem
- From: kevin diggs <diggskevin38 at gmail dot com>
- To: Andreas Schwab <schwab at linux-m68k dot org>
- Cc: binutils at sourceware dot org
- Date: Tue, 1 Mar 2011 02:20:32 -0600
- Subject: Re: m68k fmovem
- References: <AANLkTim74Yco1_k01rxjAq0wtAQQ564ZYHnTw_=5yTjo@mail.gmail.com> <m2mxlh1fg3.fsf@igel.home> <AANLkTi=RGGZzepg=y01475V81WX+Mcxg4bz8C-a6ETMC@mail.gmail.com> <AANLkTi=KDC6xgz801-fN9h9CkB50vYqVe46=uvVtTSaQ@mail.gmail.com> <AANLkTikxn4CA1Xd1+Q6=ZB3UENitntG4KaDb-vCZPias@mail.gmail.com>
Hi,
Adding some debug statements to tc-m68k.c reveals that (at least in
2.16.1) the statement:
fmovem.l %fpcr,%d0
tries the operand pattern "IiL8~s" first (from m68k-opc.c). This fails
to match because the '~' operand type does not include register
direct. Unfortunately, the 'L' operand type changes the mode
(opP->mode=REGLST) at line 1745.
The operand pattern "Iis8%s" is tried next. This would have matched
... except the 's' operand type wants the mode to be CONTROL. But this
got mucked up in the previous operand pattern check. If I comment out
the losing++; at line 1817 then:
unsigned int f(unsigned int *save)
{
unsigned int fpctrreg;
asm volatile("fmovem.l %%fpcr,%0\n"
:"=d"(fpctrreg)
);
asm volatile("fmoveml %%fpcr/%%fpsr,%0@\n"
:
:"a"(save)
);
return fpctrreg;
}
will assemble the first fmovem.l to 'f200 b000' which I think is
correct (and also matches what a similar fmove produces).
A quick check of the latest tc-m68k.c and m68k-opc.c (via cvsweb)
would seem to indicate that this should issue should still exist
(unless something has changed to alter the order that the operand
patterns are tried).
Any tips/pointers on how to fix this would be appreciated.
Can we just change the order of the first two fmoveml patterns in
m68k_op.c? Will that change the order that they are tried?
I am a little afraid of trashing some other instruction.
Thanks!
kevin
--- gas/config/tc-m68k-old_c Tue Mar 22 07:31:48 2005
+++ gas/config/tc-m68k-new_c Thu Dec 31 17:51:35 1903
@@ -1143,6 +1143,9 @@
return;
}
+ fprintf(stderr,__FILE__"`%s()-%d: mnemonic=%s, opcode struct=%p, opcode="
+ "%lx\n",__func__,__LINE__,instring,opcode,opcode->m_opcode);
+
/* Found a legitimate opcode, start matching operands. */
while (*p == ' ')
++p;
@@ -1213,10 +1216,16 @@
++losing;
else
{
+ fprintf(stderr,__FILE__"`%s()-%d: operand match string \"%s\"\n",
+ __func__,__LINE__,opcode->m_operands);
+
for (s = opcode->m_operands, opP = &the_ins.operands[0];
*s && !losing;
s += 2, opP++)
{
+ fprintf(stderr,__FILE__"`%s()-%d: matching operand %c%c\n",
+ __func__,__LINE__,*s,s[1]);
+
/* Warning: this switch is huge! */
/* I've tried to organize the cases into this order:
non-alpha first, then alpha by letter. Lower-case
@@ -1797,11 +1806,16 @@
break;
case 's':
+ fprintf(stderr,__FILE__"`%s()-%d: mode=%d, CONTROL=%d, "
+ "reg=%d, FPI=%d/FPS=%d/FPC=%d\n",
+ __func__,__LINE__,opP->mode,CONTROL,opP->reg,FPI,FPS,FPC);
+
if (opP->mode != CONTROL
|| ! (opP->reg == FPI
|| opP->reg == FPS
|| opP->reg == FPC))
- losing++;
+// losing++;
+ ;
break;
case 'S':