1 #ifndef _ASM_X86_ALTERNATIVE_ASM_H 2 #define _ASM_X86_ALTERNATIVE_ASM_H 3 4 #ifdef __ASSEMBLY__ 5 6 #include <asm/asm.h> 7 8 #ifdef CONFIG_SMP 9 .macro LOCK_PREFIX 10 672: lock 11 .pushsection .smp_locks,"a" 12 .balign 4 13 .long 672b - . 14 .popsection 15 .endm 16 #else 17 .macro LOCK_PREFIX 18 .endm 19 #endif 20 21 /* 22 * Issue one struct alt_instr descriptor entry (need to put it into 23 * the section .altinstructions, see below). This entry contains 24 * enough information for the alternatives patching code to patch an 25 * instruction. See apply_alternatives(). 26 */ 27 .macro altinstruction_entry orig alt feature orig_len alt_len pad_len 28 .long \orig - . 29 .long \alt - . 30 .word \feature 31 .byte \orig_len 32 .byte \alt_len 33 .byte \pad_len 34 .endm 35 36 /* 37 * Define an alternative between two instructions. If @feature is 38 * present, early code in apply_alternatives() replaces @oldinstr with 39 * @newinstr. ".skip" directive takes care of proper instruction padding 40 * in case @newinstr is longer than @oldinstr. 41 */ 42 .macro ALTERNATIVE oldinstr, newinstr, feature 43 140: 44 \oldinstr 45 141: 46 .skip -(((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)),0x90 47 142: 48 49 .pushsection .altinstructions,"a" 50 altinstruction_entry 140b,143f,\feature,142b-140b,144f-143f,142b-141b 51 .popsection 52 53 .pushsection .altinstr_replacement,"ax" 54 143: 55 \newinstr 56 144: 57 .popsection 58 .endm 59 60 #define old_len 141b-140b 61 #define new_len1 144f-143f 62 #define new_len2 145f-144f 63 64 /* 65 * max without conditionals. Idea adapted from: 66 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax 67 */ 68 #define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) 69 70 71 /* 72 * Same as ALTERNATIVE macro above but for two alternatives. If CPU 73 * has @feature1, it replaces @oldinstr with @newinstr1. If CPU has 74 * @feature2, it replaces @oldinstr with @feature2. 75 */ 76 .macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2 77 140: 78 \oldinstr 79 141: 80 .skip -((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \ 81 (alt_max_short(new_len1, new_len2) - (old_len)),0x90 82 142: 83 84 .pushsection .altinstructions,"a" 85 altinstruction_entry 140b,143f,\feature1,142b-140b,144f-143f,142b-141b 86 altinstruction_entry 140b,144f,\feature2,142b-140b,145f-144f,142b-141b 87 .popsection 88 89 .pushsection .altinstr_replacement,"ax" 90 143: 91 \newinstr1 92 144: 93 \newinstr2 94 145: 95 .popsection 96 .endm 97 98 #endif /* __ASSEMBLY__ */ 99 100 #endif /* _ASM_X86_ALTERNATIVE_ASM_H */ 101