On Wed, 27 Jun 2007 08:17:47 +0200, "Paolo Bonzini" <[EMAIL PROTECTED]>
said:
> 
> >   if (get_attr_cirrus (prev_active_insn(insn)) == CIRRUS_COMPARE)
> >       return \"beq\\t%l0\;bvs\\t%l0\"; else return \"bge\\t%l0\;nop\";
> >   "
> >   [(set_attr "conds" "jump_clob")
> >    (set_attr "length" "8")]
> > )
> > 
> > As you can see, I need to replace all bge with a maverick crunch
> > equivalent.  However, "bge" is still also used with integer comparisons,
> > e.g:
> 
> I think you should generate the compare using a different mode for the 
> CC register (like cc:CCMAV) and then use two patterns:
> 
> ; Special pattern to match GE for MAVERICK.  Most restrictive
> ; pattern goes first.
> (define_insn "*arm_cirrus_bge"
>    [(set (pc)
>       (if_then_else (ge (match_operand:CCMAV 1 "cc_register" "") (const_int 
> 0))
>                     (label_ref (match_operand 0 "" ""))
>                     (pc)))]
>    "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
>    "beq\\t%l0\;bvs\\t%l0\"
>    [(set_attr "conds" "jump_clob")
>     (set_attr "length" "8")]
> )
> 
> ; Special pattern to match GE for ARM.
> (define_insn "*arm_bge"
>    [(set (pc)
>       (if_then_else (ge (match_operand 1 "cc_register" "") (const_int 0))
>                     (label_ref (match_operand 0 "" ""))
>                     (pc)))]
>    "TARGET_ARM && TARGET_HARD_FLOAT"
>    "bge\\t%l0\"
>    [(set_attr "conds" "jump_clob")
>     (set_attr "length" "4")]
> )

Yep, this will work.  Floating point comparisons are already done in
CCFP mode, so I have used that.  NB, I already tried this earlier, but I
think most of my problem comes from conditional execution ...

I tried changing:

(define_cond_exec
  [(match_operator 0 "arm_comparison_operator"
    [(match_operand 1 "cc_register" "")
     (const_int 0)])]
  "TARGET_ARM"
  ""
)

to:

(define_cond_exec
  [(match_operator 0 "maverick_comparison_operator"
    [(match_operand:CCFP 1 "cc_register" "")
     (const_int 0)])]
  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
  ""
)

(define_cond_exec
  [(match_operator 0 "arm_comparison_operator"
    [(match_operand 1 "cc_register" "")
     (const_int 0)])]
  "TARGET_ARM"
  ""
)

But I think I also need to modify or add to all the other scc and / ior
etc lines, since I think combining scc's / condexecs doesn't work
correctly.  I think the if the above define_cond_exec is still there,
then gcc thinks it can optimize all ge execution, and so optimises the
above output from arm_bge, and deletes the label.  I rebuilt gcc with
all conditional execution disabled to see if it would work.  I did this
by commenting out any line referencing arm_comparison_operator or
define_cond_exec.

However, when I compile a c++ program, the compiler still can't generate
the label again, and it fails with:

internal compiler error: output_operand: '%l' operand isn't a label

then of course the assembler fails with:

undefined local label

NB, I shouldn't need the second arm_bge as it should be handled by the
code in arm_condition_code, for non MAVERICK and Maverick non-floating
point.  I've also disabled DImode on Maverick, since it is only signed
or unsigned, and not both at the same time.  I think it will also cause
similar comparison-based problems too.  Incidentally, is it possible to
do something like:

(if_then_else (ge (match_operand:CCFP,CCDI 1 "cc_register" "")
(const_int 0))

And can someone explain what is the difference between these two lines:

if_then_else (ge (match_operand:CCFP 1 "cc_register" "") (const_int 0))
if_then_else (ge:CCFP (match_operand 1 "cc_register" "") (const_int 0))

Is the second line still valid syntax?

Reply via email to