On Mon, Oct 26, 2020 at 9:05 PM Uros Bizjak <ubiz...@gmail.com> wrote:
>
> On Mon, Oct 26, 2020 at 8:10 PM Qing Zhao <qing.z...@oracle.com> wrote:
> >
> >
> >
> > > On Oct 26, 2020, at 1:42 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
> > >
> > > On Mon, Oct 26, 2020 at 6:30 PM Qing Zhao <qing.z...@oracle.com> wrote:
> > >>
> > >>
> > >> The following is the current change in i386.c, could you check whether 
> > >> the logic is good?
> > >
> > > x87 handling looks good to me.
> > >
> > > One remaining question: If the function uses MMX regs (either
> > > internally or as an argument register), but exits in x87 mode, does
> > > your logic clear the x87 stack?
> >
> > Yes but not completely yes.
> >
> > FIRST, As following:
> >
> >   /* Then, decide which mode (MMX mode or x87 mode) the function exit with.
> >      In order to decide whether we need to clear the MMX registers or the
> >      stack registers.  */
> >   bool exit_with_mmx_mode = false;
> >
> >   exit_with_mmx_mode = ((GET_CODE (crtl->return_rtx) == REG)
> >                         && (MMX_REG_P (crtl->return_rtx)));
> >
> >   /* then, let's see whether we can zero all st registers togeter.  */
> >   if (!exit_with_mmx_mode)
> >     st_zeroed = zero_all_st_registers (need_zeroed_hardregs);
> >
> >
> > We first check whether this routine exit with mmx mode, if Not then it’s 
> > X87 mode
> > (at exit, “EMMS” should already been called per ABI), then
> > The st/mm registers will be cleared as x87 stack registers.
> >
> > However, within the routine “zero_all_st_registers”:
> >
> > static bool
> > zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
> > {
> >   unsigned int num_of_st = 0;
> >   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
> >     if (STACK_REGNO_P (regno)
> >         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
> >       {
> >         num_of_st++;
> >         break;
> >       }
> >
> >   if (num_of_st == 0)
> >     return false;
> >
> >
> > In the above, I currently only check whether any “Stack” registers need to 
> > be zeroed or not.
> > But looks like we should also check any “MMX” register need to be zeroed or 
> > not too. If there is any
> > “MMX” register need to be zeroed, we still need to clear the whole X87 
> > stack?
>
> I think so, but I have to check the details.

Please compile the following testcase with "-m32 -mmmx":

--cut here--
#include <stdio.h>

typedef int __v2si __attribute__ ((vector_size (8)));

__v2si zzz;

void
__attribute__ ((noinline))
mmx (__v2si a, __v2si b, __v2si c)
{
  __v2si res;

  res = __builtin_ia32_paddd (a, b);
  zzz = __builtin_ia32_paddd (res, c);

  __builtin_ia32_emms ();
}


int main ()
{
  __v2si a = { 123, 345 };
  __v2si b = { 234, 456 };
  __v2si c = { 345, 567 };

  mmx (a, b, c);

  printf ("%i, %i\n", zzz[0], zzz[1]);

  return 0;
}
--cut here--

at the end of mmx() function:

0x080491ed in mmx ()
(gdb) disass
Dump of assembler code for function mmx:
  0x080491e0 <+0>:     paddd  %mm1,%mm0
  0x080491e3 <+3>:     paddd  %mm2,%mm0
  0x080491e6 <+6>:     movq   %mm0,0x804c020
=> 0x080491ed <+13>:    emms
  0x080491ef <+15>:    ret
End of assembler dump.
(gdb) i r flo
st0            <invalid float value> (raw 0xffff00000558000002be)
st1            <invalid float value> (raw 0xffff000001c8000000ea)
st2            <invalid float value> (raw 0xffff0000023700000159)
st3            0                   (raw 0x00000000000000000000)
st4            0                   (raw 0x00000000000000000000)
st5            0                   (raw 0x00000000000000000000)
st6            0                   (raw 0x00000000000000000000)
st7            0                   (raw 0x00000000000000000000)
fctrl          0x37f               895
fstat          0x0                 0
ftag           0x556a              21866
fiseg          0x0                 0
fioff          0x0                 0
foseg          0x0                 0
fooff          0x0                 0
fop            0x0                 0

There are still values in the MMX registers. However, we are in x87
mode, so the whole stack has to be cleared.

Now, what to do if the function uses x87 registers and exits in MMX
mode? I guess we have to clear all MMX registers (modulo return value
reg).

Uros.

Reply via email to