lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | /* Used by the elf ifunc tests. */ |
| 2 | #ifndef ELF_IFUNC_SEL_H |
| 3 | #define ELF_IFUNC_SEL_H 1 |
| 4 | |
| 5 | extern int global; |
| 6 | |
| 7 | static inline void * |
| 8 | ifunc_sel (int (*f1) (void), int (*f2) (void), int (*f3) (void)) |
| 9 | { |
| 10 | register void *ret __asm__ ("r3"); |
| 11 | __asm__ ("mflr 12\n\t" |
| 12 | "bcl 20,31,1f\n" |
| 13 | "1:\tmflr 11\n\t" |
| 14 | "mtlr 12\n\t" |
| 15 | "addis 12,11,global-1b@ha\n\t" |
| 16 | "lwz 12,global-1b@l(12)\n\t" |
| 17 | "addis %0,11,%2-1b@ha\n\t" |
| 18 | "addi %0,%0,%2-1b@l\n\t" |
| 19 | "cmpwi 12,1\n\t" |
| 20 | "beqlr\n\t" |
| 21 | "addis %0,11,%3-1b@ha\n\t" |
| 22 | "addi %0,%0,%3-1b@l\n\t" |
| 23 | "cmpwi 12,-1\n\t" |
| 24 | "beqlr\n\t" |
| 25 | "addis %0,11,%4-1b@ha\n\t" |
| 26 | "addi %0,%0,%4-1b@l" |
| 27 | : "=r" (ret) |
| 28 | : "X" (&global), "X" (f1), "X" (f2), "X" (f3)); |
| 29 | return ret; |
| 30 | } |
| 31 | |
| 32 | static inline void * |
| 33 | ifunc_one (int (*f1) (void)) |
| 34 | { |
| 35 | register void *ret __asm__ ("r3"); |
| 36 | __asm__ ("mflr 12\n\t" |
| 37 | "bcl 20,31,1f\n" |
| 38 | "1:\tmflr %0\n\t" |
| 39 | "mtlr 12\n\t" |
| 40 | "addis %0,%0,%1-1b@ha\n\t" |
| 41 | "addi %0,%0,%1-1b@l" |
| 42 | : "=r" (ret) |
| 43 | : "X" (f1)); |
| 44 | return ret; |
| 45 | } |
| 46 | #endif |