1 /*
2  * Trickery to allow this header to be included at the C level, to permit
3  * proper dependency tracking in .*.o.d files, while still having it contain
4  * assembler only macros.
5  */
6 #ifndef __ASSEMBLY__
7 # if 0
8   .if 0
9 # endif
10 asm ( "\t.include \"asm/indirect_thunk_asm.h\"" );
11 # if 0
12   .endif
13 # endif
14 #else
15 
16 .macro INDIRECT_BRANCH insn:req arg:req
17 /*
18  * Create an indirect branch.  insn is one of call/jmp, arg is a single
19  * register.
20  *
21  * With no compiler support, this degrades into a plain indirect call/jmp.
22  * With compiler support, dispatch to the correct __x86_indirect_thunk_*
23  */
24     .if CONFIG_INDIRECT_THUNK == 1
25 
26         $done = 0
27         .irp reg, ax, cx, dx, bx, bp, si, di, 8, 9, 10, 11, 12, 13, 14, 15
28         .ifeqs "\arg", "%r\reg"
29             \insn __x86_indirect_thunk_r\reg
30             $done = 1
31            .exitm
32         .endif
33         .endr
34 
35         .if $done != 1
36             .error "Bad register arg \arg"
37         .endif
38 
39     .else
40         \insn *\arg
41     .endif
42 .endm
43 
44 /* Convenience wrappers. */
45 .macro INDIRECT_CALL arg:req
46     INDIRECT_BRANCH call \arg
47 .endm
48 
49 .macro INDIRECT_JMP arg:req
50     INDIRECT_BRANCH jmp \arg
51 .endm
52 
53 #endif
54