Hello Stefan and Segher,
In order to:"
(set (reg:BImode var1) (compare (reg:SImode d) (reg:SImode c)))
[var1 is BImode in the CCreg]
I do this in a define_expand. It writes to reg:SImode varx, also in CCreg.
As the reg is now SImode, it consists of 4 regs of BImode. (I declared
QImode),
and in the first 3 of them, it writes the results of the LT, GT and EQ
comparison
either as 1 or 0.
(define_insn "comparison_internal_signed"
[(parallel [(set (subreg:QI (match_operand:SI 0 "cc_reg_operand"
"=y") 0)
(if_then_else (lt:QI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2
"gpc_reg_operand" "r"))
(const_int 1)
(const_int 0) ))
(set ... // similar code for subregs 1,2
with comparison operators gt, eq
The second step is then to take the correct subreg (0,1,2 - depending
the flag), and
pass this as the 'var1'.
This works, except I get an error (which I disabled) on the subreg part.
Note that,
now, as Segher told me, I have declared the individual bits of the CC
reg as QI mode,
and the group of bits set by the compare as SI mode. This works, because
the description
of the hardware allows the compiler to store nothing else than BI mode
in the CC reg.
(the compare operation only stores 0 or 1, nothing else.)
If there is a better way to do this, resulting in the end result that
the logical AND of the
piece of code I gave, and, in general, resulting in the compiler storing
the boolean operands
in the condition code register (and NOT in the general-purpose 32-bit
registers), then I am
all for it, please tell me, I am learning.
From a hardware point of view, you want the booleans in the condition
code register, NOT
in the general register file, from the point of view of efficiency of
the processor. (The condition
code register is a much 'cheaper' and 'faster' resource than the general
register file.) Note that
this is similar to storing the operands of the floating-point unit in
floating-point registers. In
PowerPc paradigm (unlike others), there is not only an integer unit, and
a floating point unit
(optional), but also a logical unit with separate registers (the
condition register).
Best Regards,
Henri.
On 01/31/2020 12:24 PM, Segher Boessenkool wrote:
Hi again,
On Fri, Jan 31, 2020 at 08:31:14AM +0100, Henri Cloetens wrote:
(set (reg:CCmode CC_REG) (compare (reg:SImode d) (reg:SImode c)))
(set (reg:SImode var1) (match_eq [(reg:CCmode CC_REG) (const_int 0)]))
Yes, and that is exactly what I DO NOT want. I want:
(set (reg:BImode var1) (compare (reg:SImode d) (reg:SImode c)))
[var1 is BImode in the CCreg]
You will have to decide whether you want conditions in GCC to be modeled
as a single bit like this, or as a group of three bits. What fits best
depends on what your hardware actually does.
What Stefan says is very true, you do not need or want optimised code at
expand time. I would add that you do not need or want the RTL expressions
to look optimised either: it's only the resulting machine code that you
should care about. Using a CCmode result is often written as comparing
that CC register against 0, but that does not mean the hardware actually
does any work there, it's just picking out what part of the comparison
result you care about.
I got it working. It results, however, in non-standard usage of the SUBREG,
and I got what looks like a compiler bug with that. I mean, a checking
routine
reports an error where I do not see one, I disabled it for the time
being, will
find out if it works like this or not.
Like said before, this means you did *not* get it working, the bug is in
your code. Sorry.
Segher