162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_ALTERNATIVE_ASM_H 362306a36Sopenharmony_ci#define _ASM_ALTERNATIVE_ASM_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#ifdef __ASSEMBLY__ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <asm/asm.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci/* 1062306a36Sopenharmony_ci * Issue one struct alt_instr descriptor entry (need to put it into 1162306a36Sopenharmony_ci * the section .altinstructions, see below). This entry contains 1262306a36Sopenharmony_ci * enough information for the alternatives patching code to patch an 1362306a36Sopenharmony_ci * instruction. See apply_alternatives(). 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci.macro altinstruction_entry orig alt feature orig_len alt_len 1662306a36Sopenharmony_ci .long \orig - . 1762306a36Sopenharmony_ci .long \alt - . 1862306a36Sopenharmony_ci .short \feature 1962306a36Sopenharmony_ci .byte \orig_len 2062306a36Sopenharmony_ci .byte \alt_len 2162306a36Sopenharmony_ci.endm 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* 2462306a36Sopenharmony_ci * Define an alternative between two instructions. If @feature is 2562306a36Sopenharmony_ci * present, early code in apply_alternatives() replaces @oldinstr with 2662306a36Sopenharmony_ci * @newinstr. ".fill" directive takes care of proper instruction padding 2762306a36Sopenharmony_ci * in case @newinstr is longer than @oldinstr. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ci.macro ALTERNATIVE oldinstr, newinstr, feature 3062306a36Sopenharmony_ci140 : 3162306a36Sopenharmony_ci \oldinstr 3262306a36Sopenharmony_ci141 : 3362306a36Sopenharmony_ci .fill - (((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)) / 4, 4, 0x03400000 3462306a36Sopenharmony_ci142 : 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci .pushsection .altinstructions, "a" 3762306a36Sopenharmony_ci altinstruction_entry 140b, 143f, \feature, 142b-140b, 144f-143f 3862306a36Sopenharmony_ci .popsection 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci .subsection 1 4162306a36Sopenharmony_ci143 : 4262306a36Sopenharmony_ci \newinstr 4362306a36Sopenharmony_ci144 : 4462306a36Sopenharmony_ci .previous 4562306a36Sopenharmony_ci.endm 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define old_len (141b-140b) 4862306a36Sopenharmony_ci#define new_len1 (144f-143f) 4962306a36Sopenharmony_ci#define new_len2 (145f-144f) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * Same as ALTERNATIVE macro above but for two alternatives. If CPU 5562306a36Sopenharmony_ci * has @feature1, it replaces @oldinstr with @newinstr1. If CPU has 5662306a36Sopenharmony_ci * @feature2, it replaces @oldinstr with @feature2. 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_ci.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2 5962306a36Sopenharmony_ci140 : 6062306a36Sopenharmony_ci \oldinstr 6162306a36Sopenharmony_ci141 : 6262306a36Sopenharmony_ci .fill - ((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \ 6362306a36Sopenharmony_ci (alt_max_short(new_len1, new_len2) - (old_len)) / 4, 4, 0x03400000 6462306a36Sopenharmony_ci142 : 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci .pushsection .altinstructions, "a" 6762306a36Sopenharmony_ci altinstruction_entry 140b, 143f, \feature1, 142b-140b, 144f-143f, 142b-141b 6862306a36Sopenharmony_ci altinstruction_entry 140b, 144f, \feature2, 142b-140b, 145f-144f, 142b-141b 6962306a36Sopenharmony_ci .popsection 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci .subsection 1 7262306a36Sopenharmony_ci143 : 7362306a36Sopenharmony_ci \newinstr1 7462306a36Sopenharmony_ci144 : 7562306a36Sopenharmony_ci \newinstr2 7662306a36Sopenharmony_ci145 : 7762306a36Sopenharmony_ci .previous 7862306a36Sopenharmony_ci.endm 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */ 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#endif /* _ASM_ALTERNATIVE_ASM_H */ 83