[avr-gcc] Erzwungene Sprungtabelle, wie?

OP #1197677
Lesenswert?

Mahlzeit Forum :)

Wie kann ich dem GCC mitteilen das er für ein zusammenhängendes Switch 
Konstrukt eine Sprungtabelle erzeugen soll?

Wenn ich also habe:
1
switch(foo)
2
{
3
  case 0:
4
    // Code
5
    break;
6
  case 1:
7
    // Code
8
    break;
9
  case 2:
10
    // Code
11
    break;
12
  // Weiter von 3 bis...
13
  case 14:
14
    // Code
15
    break;
16
  case 15:
17
    // Code
18
    break;
19
}

Soll daraus intern im Compiler nicht umbedingt das da werden:
1
if(foo==1){...code...}
2
if(foo==2){...code...}
3
if(foo==3){...code...}
4
...
5
if(foo==14){...code...}
6
if(foo==15){...code...}
Sondern eher:
1
const int footab[] = {footab_pointer0,footab_pointer1,...,footab_pointer15}; //Geht das so?
2
goto footab[foo]; // Ja, ich weis, wenn hier was anderes als 0..15 ankommt springt er ins Nirvana.
3

4
footab_pointer0:
5
// Code
6
goto keinfoo;
7
footab_pointer1:
8
// Code
9
goto keinfoo;
10
footab_pointer2:
11
// Code
12
goto keinfoo;
13
...
14
footab_pointer14:
15
// Code
16
goto keinfoo;
17
footab_pointer15:
18
// Code
19
keinfoo:

EDIT: Kleine Berichtigung am letzten Beispiel...
OP #1197696
Lesenswert?

Das ist zwar jetzt x86, aber scheinbar schnallt der das:
1
#include "stdio.h"
2

3
void main(void)
4
{
5
  char foo;
6
  
7
  switch(foo)
8
  {
9
    case 0:
10
      printf("0\n");
11
      break;
12
    case 1:
13
      printf("0\n");
14
      break;
15
    case 2:
16
      printf("0\n");
17
      break;
18
    case 3:
19
      printf("0\n");
20
      break;
21
    case 4:
22
      printf("0\n");
23
      break;
24
    case 5:
25
      printf("0\n");
26
      break;
27
  }
28
  
29
}
wird zu
1
  .file  "main.c"
2
  .section  .rodata
3
.LC0:
4
  .string  "0"
5
  .text
6
.globl main
7
  .type  main, @function
8
main:
9
.LFB2:
10
  pushq  %rbp
11
.LCFI0:
12
  movq  %rsp, %rbp
13
.LCFI1:
14
  subq  $32, %rsp
15
.LCFI2:
16
  movsbl  -1(%rbp),%eax
17
  movl  %eax, -20(%rbp)
18
  cmpl  $5, -20(%rbp)
19
  ja  .L10
20
  mov  -20(%rbp), %eax
21
  movq  .L9(,%rax,8), %rax
22
  jmp  *%rax
23
  .section  .rodata
24
  .align 8
25
  .align 4
26
.L9:
27
  .quad  .L3
28
  .quad  .L4
29
  .quad  .L5
30
  .quad  .L6
31
  .quad  .L7
32
  .quad  .L8
33
  .text
34
.L3:
35
  movl  $.LC0, %edi
36
  call  puts
37
  jmp  .L10
38
.L4:
39
  movl  $.LC0, %edi
40
  call  puts
41
  jmp  .L10
42
.L5:
43
  movl  $.LC0, %edi
44
  call  puts
45
  jmp  .L10
46
.L6:
47
  movl  $.LC0, %edi
48
  call  puts
49
  jmp  .L10
50
.L7:
51
  movl  $.LC0, %edi
52
  call  puts
53
  jmp  .L10
54
.L8:
55
  movl  $.LC0, %edi
56
  call  puts
57
.L10:
58
  leave
59
  ret
60
.LFE2:
61
  .size  main, .-main
62
  .section  .eh_frame,"a",@progbits
63
.Lframe1:
64
  .long  .LECIE1-.LSCIE1
65
.LSCIE1:
66
  .long  0x0
67
  .byte  0x1
68
  .string  "zR"
69
  .uleb128 0x1
70
  .sleb128 -8
71
  .byte  0x10
72
  .uleb128 0x1
73
  .byte  0x3
74
  .byte  0xc
75
  .uleb128 0x7
76
  .uleb128 0x8
77
  .byte  0x90
78
  .uleb128 0x1
79
  .align 8
80
.LECIE1:
81
.LSFDE1:
82
  .long  .LEFDE1-.LASFDE1
83
.LASFDE1:
84
  .long  .LASFDE1-.Lframe1
85
  .long  .LFB2
86
  .long  .LFE2-.LFB2
87
  .uleb128 0x0
88
  .byte  0x4
89
  .long  .LCFI0-.LFB2
90
  .byte  0xe
91
  .uleb128 0x10
92
  .byte  0x86
93
  .uleb128 0x2
94
  .byte  0x4
95
  .long  .LCFI1-.LCFI0
96
  .byte  0xd
97
  .uleb128 0x6
98
  .align 8
99
.LEFDE1:
100
  .ident  "GCC: (Ubuntu 4.3.2-1ubuntu12) 4.3.2"
101
  .section  .note.GNU-stack,"",@progbits

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren