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) |
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
Return to the
comp.compilers page.
Search the
comp.compilers archives again.