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