1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _ASM_ALTERNATIVE_ASM_H 3#define _ASM_ALTERNATIVE_ASM_H 4 5#ifdef __ASSEMBLY__ 6 7#include <asm/asm.h> 8 9/* 10 * Issue one struct alt_instr descriptor entry (need to put it into 11 * the section .altinstructions, see below). This entry contains 12 * enough information for the alternatives patching code to patch an 13 * instruction. See apply_alternatives(). 14 */ 15.macro altinstruction_entry orig alt feature orig_len alt_len 16 .long \orig - . 17 .long \alt - . 18 .short \feature 19 .byte \orig_len 20 .byte \alt_len 21.endm 22 23/* 24 * Define an alternative between two instructions. If @feature is 25 * present, early code in apply_alternatives() replaces @oldinstr with 26 * @newinstr. ".fill" directive takes care of proper instruction padding 27 * in case @newinstr is longer than @oldinstr. 28 */ 29.macro ALTERNATIVE oldinstr, newinstr, feature 30140 : 31 \oldinstr 32141 : 33 .fill - (((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)) / 4, 4, 0x03400000 34142 : 35 36 .pushsection .altinstructions, "a" 37 altinstruction_entry 140b, 143f, \feature, 142b-140b, 144f-143f 38 .popsection 39 40 .subsection 1 41143 : 42 \newinstr 43144 : 44 .previous 45.endm 46 47#define old_len (141b-140b) 48#define new_len1 (144f-143f) 49#define new_len2 (145f-144f) 50 51#define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) 52 53/* 54 * Same as ALTERNATIVE macro above but for two alternatives. If CPU 55 * has @feature1, it replaces @oldinstr with @newinstr1. If CPU has 56 * @feature2, it replaces @oldinstr with @feature2. 57 */ 58.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2 59140 : 60 \oldinstr 61141 : 62 .fill - ((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \ 63 (alt_max_short(new_len1, new_len2) - (old_len)) / 4, 4, 0x03400000 64142 : 65 66 .pushsection .altinstructions, "a" 67 altinstruction_entry 140b, 143f, \feature1, 142b-140b, 144f-143f, 142b-141b 68 altinstruction_entry 140b, 144f, \feature2, 142b-140b, 145f-144f, 142b-141b 69 .popsection 70 71 .subsection 1 72143 : 73 \newinstr1 74144 : 75 \newinstr2 76145 : 77 .previous 78.endm 79 80#endif /* __ASSEMBLY__ */ 81 82#endif /* _ASM_ALTERNATIVE_ASM_H */ 83