blob: 72b6e613fb463957932402d2904feb6406ae249a [file]
/* PR middle-end/126236 */
/* { dg-do assemble } */
/* { dg-options "-O2 -save-temps" } */
/* Each of the 11 continuing handlers, the default handler and the loop entry
get a dispatch of their own, so 13 register indirect branches. All of them
share the one table, whose entries are relative to a single base label,
which must be defined exactly once. */
void
interp (const unsigned char *pc, volatile unsigned *state)
{
for (;;)
switch (*pc++)
{
case 0: return;
case 1: state[0] += 1; break;
case 2: state[1] ^= 2; break;
case 3: state[2] -= 3; break;
case 4: state[3] |= 4; break;
case 5: state[4] &= 5; break;
case 6: state[5] += 6; break;
case 7: state[6] ^= 7; break;
case 8: state[7] -= 8; break;
case 9: state[8] |= 9; break;
case 10: state[9] &= 10; break;
case 11: state[10] += 11; break;
default: state[11] ^= 12; break;
}
}
/* { dg-final { scan-assembler-times "\\tbr\\tx" 13 } } */
/* { dg-final { scan-assembler-times "\\.Lrtx\[0-9\]+:" 1 } } */
/* A copy can sit far from that one base label, further than ADR reaches, so the
copies materialise it with ADRP and ADD. */
/* { dg-final { scan-assembler-times "adrp\\tx\[0-9\]+, \\.Lrtx" 13 } } */
/* { dg-final { scan-assembler-times "add\\tx\[0-9\]+, x\[0-9\]+, :lo12:\\.Lrtx" 13 } } */
/* { dg-final { scan-assembler-not "\\tadr\\tx\[0-9\]+, \\.Lrtx" } } */