[avr-gcc] Erzwungene Sprungtabelle, wie?

OP #1197677
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
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
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.