[(set (subreg:SI (match_operand:DI 0 "register_operand") 0)
        (unspec [...] SUPER_LD32_LO))
   (set (subreg:SI (match_operand:DI 0 "register_operand") 4)
        (unspec [...] SUPER_LD32_HI))]

I finally looked at my code instead of going by memory. :-)

I think you should turn what you have now into a define_expand, and make a separate define_insn which does not see the subregs but only SImode operands:

(define_insn "*super_ld32_internal"
  [(set (match_operand:SI 0 "s_register_operand" "=r")
          (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
                      (match_operand:SI 2 "s_register_operand" "r")]
                      SUPER_LD32_LO))
   (set (match_operand:SI 3 "s_register_operand" "=r")
          (unspec:SI [(match_dup 1)
                      (match_dup 2)]
                      SUPER_LD32_HI))]
  "TARGET_ARM"
  "*
  {
    return \"superld32 %0, %1, %2\";
  }"
  []
)

The way you were doing it until now, when lower-subreg tried to replace the DImode pseudo with two SImode pseudos, the insn wasn't recognized anymore and so the substitution failed.

Paolo

Reply via email to