When I compile a switch statement with optimization in GCC, it sets up a jump table like this,
(fcn) sym.foo 148
  sym.foo (unsigned int arg1);
; arg unsigned int arg1 @ rdi
0x000006e0      83ff06         cmp edi, 6                              ; arg1
0x000006e3      0f87a7000000   ja case.default.0x790
0x000006e9      488d156c0100.  lea rdx, [0x0000085c]
0x000006f0      89ff           mov edi, edi
0x000006f2      4883ec08       sub rsp, 8
0x000006f6      486304ba       movsxd rax, dword [rdx + rdi*4]
0x000006fa      4801d0         add rax, rdx                            ; '('
;-- switch.0x000006fd:
0x000006fd      ffe0           jmp rax                                 ; switch table (7 cases) at 0x85c
Is the MOVSXD and ADD the best way to do that,
movsxd rax, dword [rdx + rdi*4]
add rax, rdx
Isn't that the same as using LEA with displacement
lea rax, [rdx + rdi*4 + rdx]
It occurs to me that I probably don't understand what's going on here. RDX seems to be the start off the start of the jump table. RDI is the incoming argument to the switch statement. Why are we adding RDX twice though?
This is the switch statement I was compiling with -O3,
int foo (int x) {
  switch(x) {
    //case 0: puts("\nzero"); break;
    case 1: puts("\none"); break;
    case 2: puts("\ntwo"); break;
    case 3: puts("\nthree"); break;
    case 4: puts("\nfour"); break;
    case 5: puts("\nfive"); break;
    case 6: puts("\nsix"); break;
  }
  return 0;
}
 
     
    