https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71106

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Doing a movmisalign for mips is actually very easy:


;; Unaligned load/store (movmisalign<mode>)
(define_expand "movmisalign<mode>"
  [(set (match_operand:GPR 0 "nonimmediate_operand")
        (match_operand:GPR 1 "move_operand"))]
 ""
{
  if (MEM_P (operands[0]))
    {
      operands[1] = force_reg (<MODE>mode, operands[1]);
      if (!mips_expand_ins_as_unaligned_store (operands[0],
                                               operands[1],
                                               GET_MODE_BITSIZE (<MODE>mode),
0))
        gcc_unreachable ();
    }
  else if (MEM_P (operands[1]))
   {
      if (!mips_expand_ext_as_unaligned_load (operands[0],
                                              operands[1],
                                              GET_MODE_BITSIZE (<MODE>mode), 0,
0))
        gcc_unreachable ();
    }
  else
    gcc_unreachable ();
  DONE;
})

---- CUT -----
I had this in Cavium's GCC for years now but I never got around to testing it
to the trunk.

There was one issue with it, the MEM did not always have an alignment set on
it.
Sprinkling some "set_mem_align (mem, align);" in expr.c fixes that issue.
--- CUT ---
The testcase which fails was:
extern int nc;
void f(void)
{
    unsigned char resp[1024];
    int c;
    int bl = 0;
    unsigned long long *dwords = (unsigned long long *)(resp + 5);
    for (c=0; c<nc; c++)
    {
        ff(dwords[bl/64]);
        bl++;
    }
}
--- CUT ----

Reply via email to