This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
volatile workaround and how to mark register unused?
- From: Dmitry <diwil at eis dot ru>
- To: gcc at gcc dot gnu dot org
- Date: Wed, 20 Mar 2002 14:22:30 +0300
- Subject: volatile workaround and how to mark register unused?
- Organization: eis.ru
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
*********************************************************************