Re: q: gcc backend condition codes

Michael Meissner <mrmnews@the-meissners.org>
2 Jul 2003 00:42:15 -0400

          From comp.compilers

Related articles
q: gcc backend condition codes erez@savan.com (Erez Doron) (2003-06-20)
Re: q: gcc backend condition codes kers@hplb.hpl.hp.com (Chris Dollin) (2003-06-22)
Re: q: gcc backend condition codes jle@forest.owlnet.rice.edu (2003-06-25)
Re: q: gcc backend condition codes mrmnews@the-meissners.org (Michael Meissner) (2003-07-02)
| List of all articles for this month |

From: Michael Meissner <mrmnews@the-meissners.org>
Newsgroups: comp.compilers
Date: 2 Jul 2003 00:42:15 -0400
Organization: Compilers Central
References: 03-06-092
Keywords: architecture
Posted-Date: 02 Jul 2003 00:42:15 EDT

Erez Doron <erez@savan.com> writes:


> I'm trying to port gcc to a new processor.
>
> the assembeler does not have a flags register.
>
> instead, every instruction can be preceded with a condition.
>
> e.g.
> if r1>r2 mov r2,r1
>
> is a maximum function.
>
> how can i acomplish that ? (examples is good)


There are two levels to answering your question. The first is how to
add the basic support for things like if-then-else, etc. to the
compiler, and the second is how to enable condition execution without
using jumps.


In terms of adding the basic if-then-else support, it depends on how
the condition is set. You have machines like the ARM which have a
single set of condition codes, that a previous comparison sets. On
machines like the ARM, you typically treat the condition codes as one
register using CCmode, etc. to set it.


                (set (reg:CC <cc>)
                          (compare:CC (reg:SI <reg1>)
                                                  (reg:SI <reg2>)))


                (set (pc)
                          (if_then_else (ne:CC (reg:CC <cc>)
                                                                    (const_int 0))
                                                      (label_ref ...)
                                                      (pc)))


On the other hand you have machines like the IA64 which have a set of 1 bit
predicate registers, which is evaluated for every instruction (with typically
one predicate register that is hardwired to always return1 1). The IA-64 has
64 predicates, and the compare instructions set 2 predicates, one if the
compare succeeded, and one if it failed. By convention, the IA-64 GCC port
uses the even register for the true value and the odd register for the false,
and pretends there are only 1/2 as many predicates.


                (set (reg:BI <pred>)
                          (gt:BI (reg:SI <reg1>)
                                        (reg:SI <reg2>)))


                (set (pc)
                          (if_then_else (ne:BI (reg:BI <pred>)
                                                                    (const_int 0))
                                                      (label_ref ...)
                                                      (pc)))


The FRV is a third way of doing things, in that it has a subset of the
instructions that are conditionally executed, but still has multiple condition
code registers.


To enable conditional execution of instructions (other than jumps), you use the
cond_exec insn:


                (cond_exec
                    (ne:BI (reg:BI <pred>)
                                  (const_int 0))
                    (set (reg:SI <reg1>)
                              (reg:SI <reg2>))
                  "move %3,%2 if %1")


To avoid doubling or tripling the number of patterns that cond_exec would
introduce, you want to use match-operator. For example from the FRV:


                (define_insn "*cond_exec_si_unary1"
                    [(cond_exec
                        (match_operator 0 "ccr_eqne_operator"
                                                        [(match_operand 1 "cr_operand" "C")
                                                          (const_int 0)])
                        (set (match_operand:SI 2 "integer_register_operand" "=d")
                                  (match_operator:SI 3 "condexec_si_unary_operator"
                                                                        [(match_operand:SI 4 "integer_register_operand" "d")])))]
                    ""
                    "*
                {
                    switch (GET_CODE (operands[3]))
                        {
                            case NOT: return \"cnot %4, %2, %1, %e0\";
                            case NEG: return \"csub %., %4, %2, %1, %e0\";
                            default: abort ();
                        }
                }"
                    [(set_attr "length" "4")
                      (set_attr "type" "int")])




--
Michael Meissner
email: mrmnews@the-meissners.org
http://www.the-meissners.org
x


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.