Forum: Compiler & IDEs [avr-gcc] Erzwungene Sprungtabelle, wie?


von Markus S. (bastetfur)


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...

von ... .. (docean) Benutzerseite


Lesenswert?

Was wird den erzeugt?

Assembler Listing?

von Markus S. (bastetfur)


Lesenswert?

Das weis ich ja nicht ob der GCC in der Lage ist zu erkennen das hier 
aufeinander folgende Werte abgefragt werden.

von Markus S. (bastetfur)


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

von Karl H. (kbuchegg)


Lesenswert?

Markus Stehr wrote:
> Das weis ich ja nicht ob der GCC in der Lage ist zu erkennen das hier
> aufeinander folgende Werte abgefragt werden.

Normelerweise erkennen Compiler das. Ist ja auch nicht weiter 
Raketentechnik. Klarheit bringt wohl nur das Assemblerlisting.

von Markus S. (bastetfur)


Lesenswert?

Ok, er kanns, sogar ohne Optimizer.
Thread kann zu :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.