This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: i370 port

Paul Edwards wrote:

> I've managed to isolate the problem to a small test program.
> Any suggestions on how to debug this?

> bug27.c:28: error: unrecognizable insn:
> (insn 116 34 35 2 (set (reg:SI 5 5)
>         (plus:SI (plus:SI (reg:SI 2 2 [orig:54 i ] [54])
>                 (reg/f:SI 13 13))
>             (const_int 104 [0x68]))) -1 (nil)
>     (nil))

Ah, yes.  The problem is that reload assumes any valid address
can be loaded into a register with a single instruction, and
it will thus simply generate such instructions unconditionally
-- and if the target then doesn't actually provide such a pattern,
it will fail with "unrecognizable insn".

The "LA" pattern you showed accepts only "(certain) single register
+ constant", which doesn't match the pattern above "register +
register + constant".

The difficulty is now that while "LA" *does* actually support adding
base + index + displacement, you cannot simply add a pattern 
expressing that, because LA only does a 31-bit add, so it must only
be used to add addresses, not when adding general 32-bit SImode

The way I handle this in the s390 port is to provide a "forced"
LA instruction pattern using a magic marker that prevents the
pattern from being matched by regular instructions, and then add
a secondary reload to emit that "forced" LA when reload needs
to load an address.

Here's the relevant snippets from the 3.4 s390 back-end:

/* We need a secondary reload when loading a PLUS which is
   not a valid operand for LOAD ADDRESS.  */
  s390_secondary_input_reload_class ((CLASS), (MODE), (IN))

(define_insn "*la_31"
  [(set (match_operand:SI 0 "register_operand" "=d,d")
        (match_operand:QI 1 "address_operand" "U,W"))]
  "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
  [(set_attr "op_type"  "RX,RXY")
   (set_attr "type"     "la")])

(define_insn "force_la_31"
  [(set (match_operand:SI 0 "register_operand" "=d,d")
        (match_operand:QI 1 "address_operand" "U,W"))
   (use (const_int 0))]
  [(set_attr "op_type"  "RX")
   (set_attr "type"     "la")])

(define_expand "reload_insi"
  [(parallel [(match_operand:SI 0 "register_operand" "=a")
              (match_operand:SI 1 "s390_plus_operand" "")
              (match_operand:SI 2 "register_operand" "=&a")])]
  s390_expand_plus_operand (operands[0], operands[1], operands[2]);

(and of course the functions in s390.c called by these.)

You ought to be able to do something similar in your backend ...


  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]