@@ -13,32 +13,25 @@ struct alt_instr {
13
13
s32 repl_offset ; /* offset to replacement instruction */
14
14
u16 facility ; /* facility bit set for replacement */
15
15
u8 instrlen ; /* length of original instruction */
16
- u8 replacementlen ; /* length of new instruction */
17
16
} __packed ;
18
17
19
18
void apply_alternative_instructions (void );
20
19
void apply_alternatives (struct alt_instr * start , struct alt_instr * end );
21
20
22
21
/*
23
- * |661: |662: |6620 |663:
24
- * +-----------+---------------------+
25
- * | oldinstr | oldinstr_padding |
26
- * | +----------+----------+
27
- * | | | |
28
- * | | >6 bytes |6/4/2 nops|
29
- * | |6 bytes jg----------->
30
- * +-----------+---------------------+
31
- * ^^ static padding ^^
22
+ * +---------------------------------+
23
+ * |661: |662:
24
+ * | oldinstr |
25
+ * +---------------------------------+
32
26
*
33
27
* .altinstr_replacement section
34
- * +---------------------+ -----------+
28
+ * +---------------------- -----------+
35
29
* |6641: |6651:
36
30
* | alternative instr 1 |
37
- * +-----------+---------+- - - - - -+
38
- * |6642: |6652: |
39
- * | alternative instr 2 | padding
40
- * +---------------------+- - - - - -+
41
- * ^ runtime ^
31
+ * +---------------------------------+
32
+ * |6642: |6652:
33
+ * | alternative instr 2 |
34
+ * +---------------------------------+
42
35
*
43
36
* .altinstructions section
44
37
* +---------------------------------+
@@ -47,77 +40,31 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
47
40
* +---------------------------------+
48
41
*/
49
42
50
- #define b_altinstr (num ) "664"#num
51
- #define e_altinstr (num ) "665"#num
52
-
53
- #define e_oldinstr_pad_end "663"
43
+ #define b_altinstr (num ) "664"#num
44
+ #define e_altinstr (num ) "665"#num
54
45
#define oldinstr_len "662b-661b"
55
- #define oldinstr_total_len e_oldinstr_pad_end"b-661b"
56
46
#define altinstr_len (num ) e_altinstr(num)"b-"b_altinstr(num)"b"
57
- #define oldinstr_pad_len (num ) \
58
- "-(((" altinstr_len(num) ")-(" oldinstr_len ")) > 0) * " \
59
- "((" altinstr_len(num) ")-(" oldinstr_len "))"
60
-
61
- #define INSTR_LEN_SANITY_CHECK (len ) \
62
- ".if " len " > 254\n" \
63
- "\t.error \"cpu alternatives does not support instructions " \
64
- "blocks > 254 bytes\"\n" \
65
- ".endif\n" \
66
- ".if (" len ") %% 2\n" \
67
- "\t.error \"cpu alternatives instructions length is odd\"\n" \
68
- ".endif\n"
69
-
70
- #define OLDINSTR_PADDING (oldinstr , num ) \
71
- ".if " oldinstr_pad_len(num) " > 6\n" \
72
- "\tjg " e_oldinstr_pad_end "f\n" \
73
- "6620:\n" \
74
- "\t.rept (" oldinstr_pad_len(num) " - (6620b-662b)) / 2\n" \
75
- "\tnopr\n" \
76
- ".else\n" \
77
- "\t.rept " oldinstr_pad_len(num) " / 6\n" \
78
- "\t.brcl 0,0\n" \
79
- "\t.endr\n" \
80
- "\t.rept " oldinstr_pad_len(num) " %% 6 / 4\n" \
81
- "\tnop\n" \
82
- "\t.endr\n" \
83
- "\t.rept " oldinstr_pad_len(num) " %% 6 %% 4 / 2\n" \
84
- "\tnopr\n" \
85
- ".endr\n" \
86
- ".endif\n"
87
-
88
- #define OLDINSTR (oldinstr , num ) \
89
- "661:\n\t" oldinstr "\n662:\n" \
90
- OLDINSTR_PADDING(oldinstr, num) \
91
- e_oldinstr_pad_end ":\n" \
92
- INSTR_LEN_SANITY_CHECK(oldinstr_len)
93
-
94
- #define OLDINSTR_2 (oldinstr , num1 , num2 ) \
95
- "661:\n\t" oldinstr "\n662:\n" \
96
- ".if " altinstr_len(num1) " < " altinstr_len(num2) "\n" \
97
- OLDINSTR_PADDING(oldinstr, num2) \
98
- ".else\n" \
99
- OLDINSTR_PADDING(oldinstr, num1) \
100
- ".endif\n" \
101
- e_oldinstr_pad_end ":\n" \
102
- INSTR_LEN_SANITY_CHECK(oldinstr_len)
47
+
48
+ #define OLDINSTR (oldinstr ) \
49
+ "661:\n\t" oldinstr "\n662:\n"
103
50
104
51
#define ALTINSTR_ENTRY (facility , num ) \
105
52
"\t.long 661b - .\n" /* old instruction */ \
106
53
"\t.long " b_altinstr (num )"b - .\n" /* alt instruction */ \
107
54
"\t.word " __stringify (facility ) "\n" /* facility bit */ \
108
- "\t.byte " oldinstr_total_len "\n" /* source len */ \
109
- "\t.byte " altinstr_len (num ) "\n" /* alt instruction len */
55
+ "\t.byte " oldinstr_len "\n" /* instruction len */ \
56
+ "\t.org . - (" oldinstr_len ") + (" altinstr_len (num ) ")\n" \
57
+ "\t.org . - (" altinstr_len (num ) ") + (" oldinstr_len ")\n"
110
58
111
59
#define ALTINSTR_REPLACEMENT (altinstr , num ) /* replacement */ \
112
- b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n" \
113
- INSTR_LEN_SANITY_CHECK(altinstr_len(num))
60
+ b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n"
114
61
115
62
/* alternative assembly primitive: */
116
63
#define ALTERNATIVE (oldinstr , altinstr , facility ) \
117
64
".pushsection .altinstr_replacement, \"ax\"\n" \
118
65
ALTINSTR_REPLACEMENT(altinstr, 1) \
119
66
".popsection\n" \
120
- OLDINSTR(oldinstr, 1 ) \
67
+ OLDINSTR(oldinstr) \
121
68
".pushsection .altinstructions,\"a\"\n" \
122
69
ALTINSTR_ENTRY(facility, 1) \
123
70
".popsection\n"
@@ -127,7 +74,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
127
74
ALTINSTR_REPLACEMENT(altinstr1, 1) \
128
75
ALTINSTR_REPLACEMENT(altinstr2, 2) \
129
76
".popsection\n" \
130
- OLDINSTR_2 (oldinstr, 1, 2) \
77
+ OLDINSTR (oldinstr) \
131
78
".pushsection .altinstructions,\"a\"\n" \
132
79
ALTINSTR_ENTRY(facility1, 1) \
133
80
ALTINSTR_ENTRY(facility2, 2) \
0 commit comments