This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [again] switch() statements on ARM/Thumb
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: Adrian von Bidder <avbidder at acter dot ch>
- Cc: Richard dot Earnshaw at arm dot com, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 09 Jan 2002 13:13:45 +0000
- Subject: Re: [again] switch() statements on ARM/Thumb
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
> On Wed, 2002-01-09 at 12:51, Richard Earnshaw wrote:
> > > +; this works only if the label_ref is close enough (10 bit word aligned)
> > > +; but it should only be called from thumbpic_casesi anyway.
> > > +(define_insn "*thumb_adr"
> > > + [(set (match_operand:SI 0 "s_register_operand" "=l")
> > > + (label_ref (match_operand 1 "" "")))]
> > > + "TARGET_THUMB"
> > > + "adr\\t%0, %a1"
> > > + [(set_attr "length" "2")]
> > > +)
> > > +
> >
> > I'm very nervous about this. In particular the assertion that this will
> > only be generated by thumbpic_casesi and so will always be in range.
> > Experience has shown that combine and CSE are very good at making use of
> > such patterns in ways that are unexpected and that then lead to compiler
> > aborts or invalid assembly code.
>
> As I said this is the part I am least happy with, too. I'm not convinced
> that the (set (match_operand:SI 0 "s_register_operand" "=l") (label_ref
> (match_operand 1 "" ""))) construct is even legal, but I could not find
> the Official Way of loading the (pc relaive) address of a code label
> into a register.
>
> Alternatively I could make this a named insn and emit it manually from
> the C code part of the casesi, but I though doing it this way would
> allow the optimizer to play around with it some more.
>
> > I can't prove that it won't work, but
> > have you run the entire testsuite (in thumb mode, of course) and shown
> > that this doesn't cause regressions?
>
The safest way to do it would be to use an unspec. Create a constant,
say THUMB_SWITCH_TABLE_ADDR at the top of the MD file, then define your
insn as
(define_insn "*thumb_adr"
[(set (match_operand:SI 0 "s_register_operand" "=l")
(unspec [(label_ref (match_operand 1 "" "")))]
THUMB_SWITCH_TABLE_ADDR))]
...
Then combine and CSE will never create anything that will match this by
accident.