Richard Sandiford wrote:
>
> You might as well make the first operand a register_operand and
> avoid the REG_P check.
  I agree. I implemented this change and it works as expected.

>More importantly:
>
>>        operands[4] = simplify_gen_subreg(QImode,operands[1],HImode,0);
>>        operands[5] = simplify_gen_subreg(QImode,operands[1],HImode,1);
>
> ..this code is designed to handle REGs and CONST_INTs correctly,
> and avoid the problem you were seeing.  (As Eric says, gen_int_mode
> is the canonical way of generating a correct CONST_INT in cases where
> you do need to create one manually.  In this case it's simpler to use
> simplify_gen_subreg though.)
  I modified the code as below and now I do not have the problems I had
before.

   else if (CONST_INT == GET_CODE (operands[1])
          || REG_P (operands[1])) {
       operands[4] = simplify_gen_subreg(QImode,operands[1],HImode,0);
       operands[5] = simplify_gen_subreg(QImode,operands[1],HImode,1);
   }

> I notice you're generating subregs of symbolic constants,
> but I'm not sure that's really supported.
   I did this so that I can generate rtl code that I can latter trap
with the define_insn's below.

(define_insn "movqi_hiword"
  [(set (match_operand:QI 0 "register_operand" "")
        (subreg:QI (match_operand:HI 1 "general_operand" "") 0))]
  ""
  "move\t%0,#HIWORD(%1)" )

(define_insn "*movqi_lowword"
  [(set (match_operand:QI 0 "register_operand" "")
        (subreg:QI (match_operand:HI 1 "general_operand" "") 1))]
  ""
  "move\t%0,#LOWWORD(%1)" )

  Do you recommend a better way to do this?



> As far as the MEM_P case goes:
[...]
>
> you can use:
>
>     operands[4] = adjust_address (operands[1], QImode, 1);
>     operands[5] = adjust_address (operands[1], QImode, 0);
>
  I also implemented this and it works nicely. Many thanks!

> The CONST handling looks suspicious here.  CONSTs aren't memory references,
> but you split them into memory references.
  In my debugging session, all cases I say CONSTs they were used for
memory. I will look at this in more detail.


> Also, you need to beware of cases in which operands[1] overlaps
> operands[0].  The splitter says:
>
>  [(set (match_dup 2) (match_dup 4))
>   (set (match_dup 3) (match_dup 5))]
>
> and operands[2] is always the highpart:
>
>    operands[2] = gen_highpart(QImode, operands[0]);
>
> but consider the case in which operands[1] (and thus operands[4])
> is a memory reference that uses the high part of operands[0] as
> a base register.  In that case, the base register will be modified
> by the first split instruction and have the wrong value in the
> second split instruction.  See other ports for the canonical way
> of handling this.

Thanks for the heads up. Could you point me to a specific target/file?


Best regards,
-Omar

Reply via email to