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

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-04-14
     Ever confirmed|0                           |1

--- Comment #5 from Jeffrey A. Law <law at redhat dot com> ---
So what's happening here is the compact-branch support broke mips16.

It's pretty obvious if we look at mips.md:

(define_insn "*<optab>"
  [(any_return)]
  ""
  {
    operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
    return mips_output_jump (operands, 0, -1, false);
  }
  [(set_attr "type"     "jump")
   (set_attr "mode"     "none")])

;; Normal return.

(define_insn "<optab>_internal"
  [(any_return)
   (use (match_operand 0 "pmode_register_operand" ""))]
  ""
  {
    operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
    return mips_output_jump (operands, 0, -1, false);
  }
  [(set_attr "type"     "jump")
   (set_attr "mode"     "none")])


Where RETURN_ADDR_REGNUM is always 31, even on mips16.  So no matter what if we
generate any of the return insns matching those patterns we'll emit a jr $31.

I'm not familiar with this aspect of the MIPS port (it's 15+ years since I've
done any serious MIPS work), but ISTM that at least for the _internal version
we shouldn't be overwriting operands[0] -- whatever generates that pattern
should be passing us the right register.

For return and simple_return, we might need to conditionalize the assignment to
operands[0] since the return register is not provided.

Reply via email to