18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_ALTERNATIVE_ASM_H 38c2ecf20Sopenharmony_ci#define _ASM_ALTERNATIVE_ASM_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <asm/asm.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* 108c2ecf20Sopenharmony_ci * Issue one struct alt_instr descriptor entry (need to put it into 118c2ecf20Sopenharmony_ci * the section .altinstructions, see below). This entry contains 128c2ecf20Sopenharmony_ci * enough information for the alternatives patching code to patch an 138c2ecf20Sopenharmony_ci * instruction. See apply_alternatives(). 148c2ecf20Sopenharmony_ci */ 158c2ecf20Sopenharmony_ci.macro altinstruction_entry orig alt feature orig_len alt_len 168c2ecf20Sopenharmony_ci .long \orig - . 178c2ecf20Sopenharmony_ci .long \alt - . 188c2ecf20Sopenharmony_ci .short \feature 198c2ecf20Sopenharmony_ci .byte \orig_len 208c2ecf20Sopenharmony_ci .byte \alt_len 218c2ecf20Sopenharmony_ci.endm 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* 248c2ecf20Sopenharmony_ci * Define an alternative between two instructions. If @feature is 258c2ecf20Sopenharmony_ci * present, early code in apply_alternatives() replaces @oldinstr with 268c2ecf20Sopenharmony_ci * @newinstr. ".fill" directive takes care of proper instruction padding 278c2ecf20Sopenharmony_ci * in case @newinstr is longer than @oldinstr. 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci.macro ALTERNATIVE oldinstr, newinstr, feature 308c2ecf20Sopenharmony_ci140 : 318c2ecf20Sopenharmony_ci \oldinstr 328c2ecf20Sopenharmony_ci141 : 338c2ecf20Sopenharmony_ci .fill - (((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)) / 4, 4, 0x03400000 348c2ecf20Sopenharmony_ci142 : 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci .pushsection .altinstructions, "a" 378c2ecf20Sopenharmony_ci altinstruction_entry 140b, 143f, \feature, 142b-140b, 144f-143f 388c2ecf20Sopenharmony_ci .popsection 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci .subsection 1 418c2ecf20Sopenharmony_ci143 : 428c2ecf20Sopenharmony_ci \newinstr 438c2ecf20Sopenharmony_ci144 : 448c2ecf20Sopenharmony_ci .previous 458c2ecf20Sopenharmony_ci.endm 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define old_len (141b-140b) 488c2ecf20Sopenharmony_ci#define new_len1 (144f-143f) 498c2ecf20Sopenharmony_ci#define new_len2 (145f-144f) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/* 548c2ecf20Sopenharmony_ci * Same as ALTERNATIVE macro above but for two alternatives. If CPU 558c2ecf20Sopenharmony_ci * has @feature1, it replaces @oldinstr with @newinstr1. If CPU has 568c2ecf20Sopenharmony_ci * @feature2, it replaces @oldinstr with @feature2. 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2 598c2ecf20Sopenharmony_ci140 : 608c2ecf20Sopenharmony_ci \oldinstr 618c2ecf20Sopenharmony_ci141 : 628c2ecf20Sopenharmony_ci .fill - ((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \ 638c2ecf20Sopenharmony_ci (alt_max_short(new_len1, new_len2) - (old_len)) / 4, 4, 0x03400000 648c2ecf20Sopenharmony_ci142 : 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci .pushsection .altinstructions, "a" 678c2ecf20Sopenharmony_ci altinstruction_entry 140b, 143f, \feature1, 142b-140b, 144f-143f, 142b-141b 688c2ecf20Sopenharmony_ci altinstruction_entry 140b, 144f, \feature2, 142b-140b, 145f-144f, 142b-141b 698c2ecf20Sopenharmony_ci .popsection 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci .subsection 1 728c2ecf20Sopenharmony_ci143 : 738c2ecf20Sopenharmony_ci \newinstr1 748c2ecf20Sopenharmony_ci144 : 758c2ecf20Sopenharmony_ci \newinstr2 768c2ecf20Sopenharmony_ci145 : 778c2ecf20Sopenharmony_ci .previous 788c2ecf20Sopenharmony_ci.endm 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#endif /* _ASM_ALTERNATIVE_ASM_H */ 83