@@ -13,32 +13,25 @@ struct alt_instr {
1313 s32 repl_offset ; /* offset to replacement instruction */
1414 u16 facility ; /* facility bit set for replacement */
1515 u8 instrlen ; /* length of original instruction */
16- u8 replacementlen ; /* length of new instruction */
1716} __packed ;
1817
1918void apply_alternative_instructions (void );
2019void apply_alternatives (struct alt_instr * start , struct alt_instr * end );
2120
2221/*
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+ * +---------------------------------+
3226 *
3327 * .altinstr_replacement section
34- * +---------------------+ -----------+
28+ * +---------------------- -----------+
3529 * |6641: |6651:
3630 * | alternative instr 1 |
37- * +-----------+---------+- - - - - -+
38- * |6642: |6652: |
39- * | alternative instr 2 | padding
40- * +---------------------+- - - - - -+
41- * ^ runtime ^
31+ * +---------------------------------+
32+ * |6642: |6652:
33+ * | alternative instr 2 |
34+ * +---------------------------------+
4235 *
4336 * .altinstructions section
4437 * +---------------------------------+
@@ -47,77 +40,31 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
4740 * +---------------------------------+
4841 */
4942
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
5445#define oldinstr_len "662b-661b"
55- #define oldinstr_total_len e_oldinstr_pad_end"b-661b"
5646#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"
10350
10451#define ALTINSTR_ENTRY (facility , num ) \
10552 "\t.long 661b - .\n" /* old instruction */ \
10653 "\t.long " b_altinstr (num )"b - .\n" /* alt instruction */ \
10754 "\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"
11058
11159#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"
11461
11562/* alternative assembly primitive: */
11663#define ALTERNATIVE (oldinstr , altinstr , facility ) \
11764 ".pushsection .altinstr_replacement, \"ax\"\n" \
11865 ALTINSTR_REPLACEMENT(altinstr, 1) \
11966 ".popsection\n" \
120- OLDINSTR(oldinstr, 1 ) \
67+ OLDINSTR(oldinstr) \
12168 ".pushsection .altinstructions,\"a\"\n" \
12269 ALTINSTR_ENTRY(facility, 1) \
12370 ".popsection\n"
@@ -127,7 +74,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
12774 ALTINSTR_REPLACEMENT(altinstr1, 1) \
12875 ALTINSTR_REPLACEMENT(altinstr2, 2) \
12976 ".popsection\n" \
130- OLDINSTR_2 (oldinstr, 1, 2) \
77+ OLDINSTR (oldinstr) \
13178 ".pushsection .altinstructions,\"a\"\n" \
13279 ALTINSTR_ENTRY(facility1, 1) \
13380 ALTINSTR_ENTRY(facility2, 2) \
0 commit comments