This is the mail archive of the gcc@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]

volatile workaround and how to mark register unused?


Fellows,

For the code given (attr interupt here is only to show registers usage)

volatile int a;
int __attribute__ ((interrupt)) foo( )
{
        return a > 7;
}

GCC produces the assembler code

foo:
        push    r12
        push    r15
        mov     #llo(0), r15     ;  11  *movhi3/7       [length = 1]
        mov     &a, r12          ;  12  *movhi3/6       [length = 2]
        cmp     #llo(8), r12     ;  31  cmphi   [length = 1]
        jl      .L2     ;       .L2      ;  14  blt     [length = 1]
        mov     #llo(1), r15     ;  15  *movhi3/7       [length = 1]
.L2:
        pop     r15
        pop     r12
        reti

which is correct. (The constant 8 being substituded into cmp instruction on machine dependend reorg pass).
The main problem here is a volatile variable 'a', which defenition involves redudant moves. 

As I understand, standard predicates (general_operand for example) sometimes does not match if variable is volatile)

However I define cmphi as:

(define_insn "cmphi"
  [(set (cc0)
        (compare:HI (match_operand:HI 0 "nonimmediate_operand_msp430" "rm")
                    (match_operand:HI 1 "general_operand_msp430" "rmi")))]
 ""
 "* return msp430_emit_cmphi(insn, operands, NULL);"
[(set_attr "length" "3")      
   (set_attr "cc" "compare")])

where predicates are:

{
        int save_volatile_ok = volatile_ok;
        int niop = 0;
        
        volatile_ok = 1;
        niop = nonimmediate_operand(op,mode); // or general_operand in this example
        volatile_ok = save_volatile_ok;
        
        return niop;
}

Such defenition of 'XX_msp430' predicates for some move/or/and/etc. instructions gives desired output.
For example:
	a |= 1;
will be:
	bis #llo(1), &a	; iorHI

The first question is:
	Why this does not work for compare insn pattern?

Ok, to avoid redudant registers usage, I define peephole:

(define_peephole2
  [(set (match_operand:HI 0 "register_operand" "")    
        (match_operand:HI 1 "nonimmediate_operand_msp430" "rm"))
   (set (cc0)    
        (compare:HI (match_dup 0) 
                    (match_operand:HI 2 "general_operand_msp430" "rmi")))]
"dead_or_set_p(insn,operands[0])"
  [(set (cc0) (compare:HI (match_dup 1) (match_dup 2)))]
"") 

Then I get:
        push    r12
        push    r15
        mov     #llo(0), r15     ;  11  *movhi3/7       [length = 1]
        cmp     #llo(8), &a      ;  33  cmphi   [length = 2]
        jl      .L2     ;       .L2      ;  14  blt     [length = 1]
        mov     #llo(1), r15     ;  15  *movhi3/7       [length = 1]
.L2:
        pop     r15
        pop     r12
        reti

>From this output one can see, that register operand 0 (r12) marked as used (therefore pushed).

So, next question is then:
	How to mark register unused by instructions sequence within peephole2 defenition?
	Or this should/may/must be done on machine dependend reorg pass by analysing all insns?

And one more. In a peephole2 condition I use 'dead_or_set_p(insn,operands[0])'. Which pattern 
'insn' parameter refers to? ( I actually got several peepholes2 with the same condition and they all work)

Thanks in advance,
Dmitry.



*********************************************************************
   ("`-''-/").___..--''"`-._     (\       Dimmy the Wild      UA1ACZ
    `6_ 6  )   `-.  (     ).`-.__.`)      Enterprise Information Sys 
    (_Y_.)'  ._   )  `._ `. ``-..-'       Nevsky prospekt,   20 / 44
  _..`--'_..-_/  /--'_.' ,'               Saint Petersburg,   Russia
 (il),-''  (li),'  ((!.-'                 +7 (812) 314-8860, 5585314
*********************************************************************


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