This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Back end question.


"Dmitry" <mittie@ukr.net> writes:

> So if for example I could write something like this
> (set (reg:CCCZ ST0) (const_int 1))
> And the compiler would think that by that I've set a carry and zero flag for example?
> And how later a branch instruction could determine whether a carry or a zero flag was previously set in that CCCZ mode?

Yes, you could write that, though it would be unlikely to succeed.  The
compiler doesn't really know anything about carry or zero flags.  It
only knows what your backend says.  The branch instruction in your
backend could look for (const_int 1).  The problem with this example is
that you haven't mentioned the value being compared, so the branch
instruction could match any test.  But if you do write an expression
which uses the registers, then you could write pretty much any
expression, as long as some insn sets it and the branch instruction
tests it.

Ian


> Thanks.
> Dmitry.
>
> --- ÐÑÑÐÐÐÐÐ ÑÐÐÐÑÐÐÐÐ ---
>  ÐÑ ÐÐÐÐ: "Ian Lance Taylor" <iant@google.com> 
>  ÐÐÐÑ: "Dmitry" <mittie@ukr.net> 
>  ÐÐÑÐ: 6 ÐÐÑ 2011, 18:28:46 
>  ÐÐÐÐ: Re: Back end question. 
>  
>
>
>> "Dmitry" <mittie@ukr.net> writes:
>> 
>> > Thanks Ian for your patience. But still I get that I can set several bits with one compare, but how can I use one compare if I need to compare with two different values?
>> > To set a zero bit I should compare with 0 to set an overflow bit I should compare with 65535?
>> 
>> I think you are approaching this the wrong way. The value that you set
>> in the flags register is not the expression which the flags register
>> stores. It is the expression which the flag register is about. That
>> expression then has to match what the branch instruction looks for.
>> 
>> It is not necessary to compare with 65535 to set the overflow flag.
>> It's just necessary to have some comparison which the branch instruction
>> will match.
>> 
>> In any case it is quite difficult to write C code which does a single
>> comparison and then does two branches, one on the overflow flag and one
>> on the zero flag.
>> 
>> Ian
>> 
>> > --- ÐÑÑÐÐÐÐÐ ÑÐÐÐÑÐÐÐÐ ---
>> > ÐÑ ÐÐÐÐ: "Ian Lance Taylor" <iant@google.com> 
>> > ÐÐÐÑ: "Dmitry" <mittie@ukr.net> 
>> > ÐÐÑÐ: 5 ÐÐÑ 2011, 21:06:29 
>> > ÐÐÐÐ: Re: Back end question. 
>> > 
>> >
>> >
>> >> "Dmitry" <mittie@ukr.net> writes:
>> >> 
>> >> > Yes Ian I understand the whole idea of different CC modes but, what I was asking is how could I load actual values to the separate status bits. I mean in the i386 example you gave "(set (reg:CCC FLAGS_REG) (compare:CCC ..." it sets the only one bit with one set rtx. But if it had CCCZ mode for example (carry + zero bits) it should go like:
>> >> > (set (reg:CCCZ FLAGS_REG) (compare:CCCZ ... - carry bit computation
>> >> > (set (reg:CCCZ FLAGS_REG) (compare:CCCZ ... - zero bit computation
>> >> > or a parallel of some sort?
>> >> > So the question is how could I set the correct values for carry and zero bits? What should go after "(set (reg:CCCZ FLAGS_REG) ..." for two separate status bits?
>> >> 
>> >> A set to FLAGS_REG of a compare does not set one bit. It sets whatever
>> >> bits are represented by the mode. So you don't need multiple sets of a
>> >> single register. That doesn't even make sense in gcc's RTL
>> >> representation.
>> >> 
>> >> Think about how the value is used: it is used in a conditional
>> >> instruction which is looking at the compare. That conditional can test
>> >> whichever bits the mode permits.
>> >> 
>> >> Ian
>> >> 
>> >> > --- ÐÑÑÐÐÐÐÐ ÑÐÐÐÑÐÐÐÐ ---
>> >> > ÐÑ ÐÐÐÐ: "Ian Lance Taylor" <iant@google.com> 
>> >> > ÐÐÐÑ: "Dmitry" <mittie@ukr.net> 
>> >> > ÐÐÑÐ: 5 ÐÐÑ 2011, 19:44:55 
>> >> > ÐÐÐÐ: Re: Back end question. 
>> >> > 
>> >> >
>> >> >
>> >> >> "Dmitry" <mittie@ukr.net> writes:
>> >> >> 
>> >> >> > Yes but as you've said, it's a carry flag setter, but how could this example be transformed if I need to store not only carry flag but also for example a zero flag? Could you write such an example, please?
>> >> >> 
>> >> >> You do exactly the same thing, but you define a mode which means that
>> >> >> both the zero flag and the carry flag are valid. Then your test can
>> >> >> look for that mode in the flags register. Don't look at this insn in
>> >> >> isolation--look at it in conjunction with some conditional insn that
>> >> >> tests the value in the flags register. The conditional test is going to
>> >> >> be testing the result of the plus operation compared with zero, in some
>> >> >> mode.
>> >> >> 
>> >> >> The i386 backend uses CCmode to represent all the flags, and uses the
>> >> >> other modes to represent subsets of the flags.
>> >> >> 
>> >> >> Ian
>> >> >> 
>> >> >> > --- ÐÑÑÐÐÐÐÐ ÑÐÐÐÑÐÐÐÐ ---
>> >> >> > ÐÑ ÐÐÐÐ: "Ian Lance Taylor" <iant@google.com> 
>> >> >> > ÐÐÐÑ: "Dmitry" <mittie@ukr.net> 
>> >> >> > ÐÐÑÐ: 5 ÐÐÑ 2011, 17:41:38 
>> >> >> > ÐÐÐÐ: Re: Back end question. 
>> >> >> > 
>> >> >> >
>> >> >> >
>> >> >> >> "Dmitry" <mittie@ukr.net> writes:
>> >> >> >> 
>> >> >> >> > Ok but if people do not set each status bit individually, how do they set several not related bits in one CC mode and in one set rtx?
>> >> >> >> 
>> >> >> >> They represent the collection of bits as a mode, as you've been
>> >> >> >> discussing.
>> >> >> >> 
>> >> >> >> E.g., from config/i386/i386.md
>> >> >> >> 
>> >> >> >> (define_insn "*<plusminus_insn><mode>3_cc_overflow"
>> >> >> >> [(set (reg:CCC FLAGS_REG)
>> >> >> >> (compare:CCC
>> >> >> >> (plusminus:SWI
>> >> >> >> (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
>> >> >> >> (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
>> >> >> >> (match_dup 1)))
>> >> >> >> (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
>> >> >> >> (plusminus:SWI (match_dup 1) (match_dup 2)))]
>> >> >> >> "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
>> >> >> >> "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
>> >> >> >> [(set_attr "type" "alu")
>> >> >> >> (set_attr "mode" "<MODE>")])
>> >> >> >> 
>> >> >> >> 
>> >> >> >> Here the CCC mode (defined in i386-modes.def) means that the carry flag
>> >> >> >> is valid.
>> >> >> >> 
>> >> >> >> Ian
>> >> >> >> 
>> >> >> >> 
>> >> >> 
>> >> >> 
>> >> 
>> >> 
>> 
>> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]