This is the mail archive of the
mailing list for the GCC project.
Re: Question about CASE_DROPS_THROUGH
- From: Roger Sayle <roger at eyesopen dot com>
- To: Steven Bosscher <stevenb at suse dot de>
- Cc: gcc at gcc dot gnu dot org
- Date: Sun, 20 Jun 2004 10:09:52 -0600 (MDT)
- Subject: Re: Question about CASE_DROPS_THROUGH
On Sun, 20 Jun 2004, Steven Bosscher wrote:
> There is this target macro CASE_DROPS_THROUGH that is only defined
> by the vax backend:
> /* Define this if the case instruction drops through after the table
> when the index is out of range. Don't define it if the case insn
> jumps to the default label instead. */
> #define CASE_DROPS_THROUGH
> Is there a different way to get the same behavior somehow without
> this define (such as prefixing the switch blocks with a range
> check perhaps?). vax is the only target that defines this macro,
> so there's not even a way to see if it still works properly.
> (IMHO the whole vax backend should go away for that reason, but
> that's a different issue).
> I'm not even sure how this is supposed to work. "Out of range" of
> what range, the case range??
[Disclaimer: My memory is a bit hazy, as this was all a long time ago]
The VAX architecture CISC is fairly unique in that it provides a real
"casesi" instruction. Whereas most other architectures implement C's
switch statements via a "table jump" instruction sequence that subtracts
the lower bound, performs an unsigned comparison, and then indexes the
appropriate entry from an array of label pointers, the VAX performs all
of this in a single instruction op-code.
It's casesi insn ("case_") takes three immediate operands, the register
to switch upon, the lower bound and the number of elements in the case
table. The case table then immediately follows the "case_" insn in the
instruction stream; the ultimate variable length instruction.
GCC's CASE_DROPS_THROUGH reflects the fact that in the eyes of the VAX
architects, this "macro" case instruction is really just a conditional
jump, and if the index is outside the bounds specified in the instruction,
control resumes after the case table.
Of course, its possible for the VAX to implement this behaviour exactly
the same way as its done on other targets, with indirect jump via pointer
to a read-only branch table in a constant pool (outside the instruction
stream). However, I suspect RMS's original intention was to support this
peculiar instruction "natively" for best performance and code size.
Alas, the VAX backends's unique requirement to keep the "offset table"
in the RTL stream has been the source of continual headaches for GCC.
Perhaps rather than drop support for the VAX completely, a compromise
would be to simply discontinue support of its' CASE_ op-code? This
simplifies much CFG manipulation, with only a small performance/space
cost to the VAX.