-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge patch series "Allow calls in alternatives"
Heiko Stuebner <heiko@sntech.de> says: From: Heiko Stuebner <heiko.stuebner@vrull.eu> This series is split out of my work on optimizing string functions and provides the basics to: - actually allowing calls in alternatives Function calls use auipc + jalr to reach those 32bit relative addresses but when they're compiled the offset will be wrong as alternatives live in a different section. So when the patch gets applied the address will point to the wrong location. So similar to arm64 the target addresses need to be updated. This is probably also helpful for other things needing more complex code in alternatives. For v2 I got into some sort of cleanup spree for the general instruction parsing that already existed. A number of places do their own instruction parsing and I tried consolidating some of them. Noteable, the kvm parts still do, but I had to stop somewhere :-) * b4-shazam-merge: RISC-V: fix auipc-jalr addresses in patched alternatives RISC-V: add helpers for handling immediates in U-type and I-type pairs RISC-V: add rd reg parsing to insn.h header RISC-V: add U-type imm parsing to insn.h header RISC-V: kprobes: use central defined funct3 constants RISC-V: rename parse_asm.h to insn.h RISC-V: Move riscv_insn_is_* macros into a common header RISC-V: add auipc elements to parse_asm header RISC-V: add ebreak instructions to definitions RISC-V: detach funct-values from their offset RISC-V: add prefix to all constants/macros in parse_asm.h RISC-V: fix funct4 definition for c.jalr in parse_asm.h Link: https://lore.kernel.org/r/20221223221332.4127602-1-heiko@sntech.de Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
- x86_urgent_for_6.4-rc4
- x86_urgent_for_v6.4_rc6
- x86_urgent_for_v6.4_rc2
- x86_urgent_for_v6.3
- x86_urgent_for_v6.3_rc7
- x86_urgent_for_v6.3_rc6
- x86_urgent_for_v6.3_rc4
- x86_urgent_for_v6.3_rc3
- x86_urgent_for_v6.3_rc2
- x86_tdx_for_6.4
- x86_shstk_for_6.4
- x86_sev_for_v6.4_rc1
- x86_paravirt_for_v6.4_rc1
- x86_mm_for_6.4
- x86_misc_for_v6.4_rc1
- x86_fpu_for_6.4
- x86_cpu_for_v6.4_rc1
- x86_cleanups_for_v6.4_rc1
- x86_cache_for_6.4
- x86_acpi_for_v6.4_rc1
- x86-urgent-2023-05-28
- x86-apic-2023-04-24
- v6.9-rc4
- v6.9-rc3
- v6.9-rc2
- v6.9-rc1
- v6.8.6
- v6.8.5
- v6.8.4
- v6.8.3
- v6.8.2
- v6.8.1
- v6.8
- v6.8-rc7
- v6.8-rc6
- v6.8-rc5
- v6.8-rc4
- v6.8-rc3
- v6.8-rc2
- v6.8-rc1
- v6.7.12
- v6.7.11
- v6.7.10
- v6.7.9
- v6.7.8
- v6.7.7
- v6.7.6
- v6.7.5
- v6.7.4
- v6.7.3
- v6.7.2
- v6.7.1
- v6.7
- v6.7-rc8
- v6.7-rc7
- v6.7-rc6
- v6.7-rc5
- v6.7-rc4
- v6.7-rc3
- v6.7-rc2
- v6.7-rc1
- v6.6.27
- v6.6.26
- v6.6.25
- v6.6.24
- v6.6.23
- v6.6.22
- v6.6.21
- v6.6.20
- v6.6.19
- v6.6.18
- v6.6.17
- v6.6.16
- v6.6.15
- v6.6.14
- v6.6.13
- v6.6.12
- v6.6.11
- v6.6.10
- v6.6.9
- v6.6.8
- v6.6.7
- v6.6.6
- v6.6.5
- v6.6.4
- v6.6.3
- v6.6.2
- v6.6.1
- v6.6
- v6.6-rc7
- v6.6-rc6
- v6.6-rc5
- v6.6-rc4
- v6.6-rc3
- v6.6-rc2
- v6.6-rc1
- v6.5.13
- v6.5.12
- v6.5.11
- v6.5.10
- v6.5.9
- v6.5.8
- v6.5.7
- v6.5.6
- v6.5.5
- v6.5.4
- v6.5.3
- v6.5.2
- v6.5.1
- v6.5
- v6.5-rc7
- v6.5-rc6
- v6.5-rc5
- v6.5-rc4
- v6.5-rc3
- v6.5-rc2
- v6.5-rc1
- v6.4.16
- v6.4.15
- v6.4.14
- v6.4.13
- v6.4.12
- v6.4.11
- v6.4.10
- v6.4.9
- v6.4.8
- v6.4.7
- v6.4.6
- v6.4.5
- v6.4.4
- v6.4.3
- v6.4.2
- v6.4.1
- v6.4
- v6.4-rc7
- v6.4-rc6
- v6.4-rc5
- v6.4-rc4
- v6.4-rc3
- v6.4-rc2
- v6.4-rc1
- v6.3.13
- v6.3.12
- v6.3.11
- v6.3.10
- v6.3.9
- v6.3.8
- v6.3.7
- v6.3.6
- v6.3.5
- v6.3.4
- v6.3.3
- v6.3.2
- v6.3.1
- v6.3
- v6.3-rc7
- v6.3-rc6
- v6.3-rc5
- v6.3-rc4
- v6.3-rc3
- v6.3-rc2
- v6.3-rc1
- unmap-fix-20230629
- timers-core-2023-04-28
- timers-core-2023-04-24
- timers_urgent_for_v6.4_rc2
- thermal-6.6-rc1
- thermal-6.6-rc1-3
- thermal-6.6-rc1-2
- thermal-6.5-rc4
- thermal-6.5-rc1
- thermal-6.4-rc8
- thermal-6.4-rc4
- thermal-6.4-rc1
- thermal-6.4-rc1-3
- thermal-6.4-rc1-2
- thermal-6.3-rc7
- thermal-6.3-rc5
- thermal-6.3-rc4
- thermal-6.3-rc2
- smp-core-2023-04-27
- sched-core-2023-04-27
- sched_urgent_for_v6.4_rc2
- sched_urgent_for_v6.3_rc7
- sched_urgent_for_v6.3_rc4
- ras_urgent_for_v6.3_rc3
- ras_core_for_v6.4_rc1
- pm-6.6-rc1
- pm-6.6-rc1-3
- pm-6.6-rc1-2
- pm-6.5-rc6
- pm-6.5-rc5
- pm-6.5-rc4
- pm-6.5-rc3
- pm-6.5-rc2
- pm-6.5-rc1
- pm-6.5-rc1-2
- pm-6.4-rc4
- pm-6.4-rc3
- pm-6.4-rc1
- pm-6.4-rc1-2
- pm-6.3-rc7
- pm-6.3-rc3
- perf-urgent-2023-05-28
- perf-core-2023-04-27
- perf_urgent_for_v6.4_rc2
- perf_urgent_for_v6.3_rc6
- perf_urgent_for_v6.3_rc4
- perf_urgent_for_v6.3_rc3
- objtool-urgent-2023-05-28
- objtool-core-2023-04-27
- next-20230912
- next-20230809
- next-20230803
- next-20230801
- next-20230724
- next-20230721
- next-20230718
- next-20230717
- next-20230714
- next-20230706
- next-20230620
- next-20230608
- next-20230512
- next-20230511
- next-20230508
- next-20230504
- next-20230426
- next-20230419
- next-20230411
- next-20230405
- next-20230324
- next-20230320
- next-20230302
- next-20230228
- next-20230217
- next-20230208
- next-20230206
- next-20230203
- next-20230123
- next-20230105
- md-next-20230825
- md-next-20230817
- md-next-20230814-resend
- md-next-20230729
- md-next-20230623
- md-next-20230613
- md-next-2023-04-28
- md-fixes-20230630
- md-fixes-2023-05-24
- md-fixes-2023-03-29
- mariux-6.12.29-483
- mariux-6.12.27-482
- mariux-6.12.23-481
- mariux-6.12.23-480
- mariux-6.12.11-479
- mariux-6.6.35-477
- mariux-6.6.27-472
- mariux-6.6.26-471
- mariux-6.6.25-470
- mariux-6.6.24-469
- mariux-6.6.23-468
- mariux-6.6.22-467
- mariux-6.6.22-466
- mariux-6.6.22-465
- mariux-6.6.21-464
- mariux-6.6.20-463
- mariux-6.6.19-462
- mariux-6.6.12-461
- mariux-6.6.11-460
- mariux-6.5.2-455
- mariux-6.5.2-452
- mariux-6.5.2-451
- locking-core-2023-05-05
- locking_urgent_for_v6.4_rc2
- irq-urgent-2023-05-28
- irq-core-2023-04-24
- irq_urgent_for_v6.4_rc5
- irq_urgent_for_v6.3
- hwmon-for-v6.3-rc4
- hwmon-for-v6.3-rc3
- core-entry-2023-04-24
- core-debugobjects-2023-05-28
- core-debugobjects-2023-05-06
- core-debugobjects-2023-04-24
- core_urgent_for_v6.3_rc4
- ata-6.6-rc1
- ata-6.5-rc5
- ata-6.5-rc4
- ata-6.5-rc3
- ata-6.5-rc1
- ata-6.4-rc7
- ata-6.4-rc5
- ata-6.4-rc3
- ata-6.4-rc1
- ata-6.3-rc7
- ata-6.3-rc3
- ata-6.3-fix
- amd-drm-next-6.4-2023-03-31
- amd-drm-fixes-6.3-2023-03-30
- amd-drm-fixes-6.3-2023-03-29
- amd-drm-fixes-6.3-2023-03-23
- amd-drm-fixes-6.3-2023-03-15
- amd-drm-fixes-6.3-2023-03-09
- acpi-6.6-rc1
- acpi-6.5-rc8
- acpi-6.5-rc6
- acpi-6.5-rc1
- acpi-6.5-rc1-3
- acpi-6.5-rc1-2
- acpi-6.4-rc8
- acpi-6.4-rc3
- acpi-6.4-rc1
- acpi-6.4-rc1-3
- acpi-6.4-rc1-2
- acpi-6.3-rc7
- acpi-6.3-rc6
- acpi-6.3-rc5
- acpi-6.3-rc4
- acpi-6.3-rc3
- Ubuntu-unstable-6.5.0-4.4
- Ubuntu-unstable-6.5.0-2.2
- Ubuntu-unstable-6.5.0-1.1
- Ubuntu-unstable-6.4.0-8.8
- Ubuntu-unstable-6.4.0-5.5
- Ubuntu-unstable-6.3.0-2.2
- Ubuntu-unstable-6.3.0-1.1
Showing
8 changed files
with
436 additions
and
295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,340 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* Copyright (C) 2020 SiFive | ||
*/ | ||
|
||
#include <linux/bits.h> | ||
|
||
#define RV_INSN_FUNCT3_MASK GENMASK(14, 12) | ||
#define RV_INSN_FUNCT3_OPOFF 12 | ||
#define RV_INSN_OPCODE_MASK GENMASK(6, 0) | ||
#define RV_INSN_OPCODE_OPOFF 0 | ||
#define RV_INSN_FUNCT12_OPOFF 20 | ||
|
||
#define RV_ENCODE_FUNCT3(f_) (RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF) | ||
#define RV_ENCODE_FUNCT12(f_) (RVG_FUNCT12_##f_ << RV_INSN_FUNCT12_OPOFF) | ||
|
||
/* The bit field of immediate value in I-type instruction */ | ||
#define RV_I_IMM_SIGN_OPOFF 31 | ||
#define RV_I_IMM_11_0_OPOFF 20 | ||
#define RV_I_IMM_SIGN_OFF 12 | ||
#define RV_I_IMM_11_0_OFF 0 | ||
#define RV_I_IMM_11_0_MASK GENMASK(11, 0) | ||
|
||
/* The bit field of immediate value in J-type instruction */ | ||
#define RV_J_IMM_SIGN_OPOFF 31 | ||
#define RV_J_IMM_10_1_OPOFF 21 | ||
#define RV_J_IMM_11_OPOFF 20 | ||
#define RV_J_IMM_19_12_OPOFF 12 | ||
#define RV_J_IMM_SIGN_OFF 20 | ||
#define RV_J_IMM_10_1_OFF 1 | ||
#define RV_J_IMM_11_OFF 11 | ||
#define RV_J_IMM_19_12_OFF 12 | ||
#define RV_J_IMM_10_1_MASK GENMASK(9, 0) | ||
#define RV_J_IMM_11_MASK GENMASK(0, 0) | ||
#define RV_J_IMM_19_12_MASK GENMASK(7, 0) | ||
|
||
/* | ||
* U-type IMMs contain the upper 20bits [31:20] of an immediate with | ||
* the rest filled in by zeros, so no shifting required. Similarly, | ||
* bit31 contains the signed state, so no sign extension necessary. | ||
*/ | ||
#define RV_U_IMM_SIGN_OPOFF 31 | ||
#define RV_U_IMM_31_12_OPOFF 0 | ||
#define RV_U_IMM_31_12_MASK GENMASK(31, 12) | ||
|
||
/* The bit field of immediate value in B-type instruction */ | ||
#define RV_B_IMM_SIGN_OPOFF 31 | ||
#define RV_B_IMM_10_5_OPOFF 25 | ||
#define RV_B_IMM_4_1_OPOFF 8 | ||
#define RV_B_IMM_11_OPOFF 7 | ||
#define RV_B_IMM_SIGN_OFF 12 | ||
#define RV_B_IMM_10_5_OFF 5 | ||
#define RV_B_IMM_4_1_OFF 1 | ||
#define RV_B_IMM_11_OFF 11 | ||
#define RV_B_IMM_10_5_MASK GENMASK(5, 0) | ||
#define RV_B_IMM_4_1_MASK GENMASK(3, 0) | ||
#define RV_B_IMM_11_MASK GENMASK(0, 0) | ||
|
||
/* The register offset in RVG instruction */ | ||
#define RVG_RS1_OPOFF 15 | ||
#define RVG_RS2_OPOFF 20 | ||
#define RVG_RD_OPOFF 7 | ||
#define RVG_RD_MASK GENMASK(4, 0) | ||
|
||
/* The bit field of immediate value in RVC J instruction */ | ||
#define RVC_J_IMM_SIGN_OPOFF 12 | ||
#define RVC_J_IMM_4_OPOFF 11 | ||
#define RVC_J_IMM_9_8_OPOFF 9 | ||
#define RVC_J_IMM_10_OPOFF 8 | ||
#define RVC_J_IMM_6_OPOFF 7 | ||
#define RVC_J_IMM_7_OPOFF 6 | ||
#define RVC_J_IMM_3_1_OPOFF 3 | ||
#define RVC_J_IMM_5_OPOFF 2 | ||
#define RVC_J_IMM_SIGN_OFF 11 | ||
#define RVC_J_IMM_4_OFF 4 | ||
#define RVC_J_IMM_9_8_OFF 8 | ||
#define RVC_J_IMM_10_OFF 10 | ||
#define RVC_J_IMM_6_OFF 6 | ||
#define RVC_J_IMM_7_OFF 7 | ||
#define RVC_J_IMM_3_1_OFF 1 | ||
#define RVC_J_IMM_5_OFF 5 | ||
#define RVC_J_IMM_4_MASK GENMASK(0, 0) | ||
#define RVC_J_IMM_9_8_MASK GENMASK(1, 0) | ||
#define RVC_J_IMM_10_MASK GENMASK(0, 0) | ||
#define RVC_J_IMM_6_MASK GENMASK(0, 0) | ||
#define RVC_J_IMM_7_MASK GENMASK(0, 0) | ||
#define RVC_J_IMM_3_1_MASK GENMASK(2, 0) | ||
#define RVC_J_IMM_5_MASK GENMASK(0, 0) | ||
|
||
/* The bit field of immediate value in RVC B instruction */ | ||
#define RVC_B_IMM_SIGN_OPOFF 12 | ||
#define RVC_B_IMM_4_3_OPOFF 10 | ||
#define RVC_B_IMM_7_6_OPOFF 5 | ||
#define RVC_B_IMM_2_1_OPOFF 3 | ||
#define RVC_B_IMM_5_OPOFF 2 | ||
#define RVC_B_IMM_SIGN_OFF 8 | ||
#define RVC_B_IMM_4_3_OFF 3 | ||
#define RVC_B_IMM_7_6_OFF 6 | ||
#define RVC_B_IMM_2_1_OFF 1 | ||
#define RVC_B_IMM_5_OFF 5 | ||
#define RVC_B_IMM_4_3_MASK GENMASK(1, 0) | ||
#define RVC_B_IMM_7_6_MASK GENMASK(1, 0) | ||
#define RVC_B_IMM_2_1_MASK GENMASK(1, 0) | ||
#define RVC_B_IMM_5_MASK GENMASK(0, 0) | ||
|
||
#define RVC_INSN_FUNCT4_MASK GENMASK(15, 12) | ||
#define RVC_INSN_FUNCT4_OPOFF 12 | ||
#define RVC_INSN_FUNCT3_MASK GENMASK(15, 13) | ||
#define RVC_INSN_FUNCT3_OPOFF 13 | ||
#define RVC_INSN_J_RS2_MASK GENMASK(6, 2) | ||
#define RVC_INSN_OPCODE_MASK GENMASK(1, 0) | ||
#define RVC_ENCODE_FUNCT3(f_) (RVC_FUNCT3_##f_ << RVC_INSN_FUNCT3_OPOFF) | ||
#define RVC_ENCODE_FUNCT4(f_) (RVC_FUNCT4_##f_ << RVC_INSN_FUNCT4_OPOFF) | ||
|
||
/* The register offset in RVC op=C0 instruction */ | ||
#define RVC_C0_RS1_OPOFF 7 | ||
#define RVC_C0_RS2_OPOFF 2 | ||
#define RVC_C0_RD_OPOFF 2 | ||
|
||
/* The register offset in RVC op=C1 instruction */ | ||
#define RVC_C1_RS1_OPOFF 7 | ||
#define RVC_C1_RS2_OPOFF 2 | ||
#define RVC_C1_RD_OPOFF 7 | ||
|
||
/* The register offset in RVC op=C2 instruction */ | ||
#define RVC_C2_RS1_OPOFF 7 | ||
#define RVC_C2_RS2_OPOFF 2 | ||
#define RVC_C2_RD_OPOFF 7 | ||
|
||
/* parts of opcode for RVG*/ | ||
#define RVG_OPCODE_AUIPC 0x17 | ||
#define RVG_OPCODE_BRANCH 0x63 | ||
#define RVG_OPCODE_JALR 0x67 | ||
#define RVG_OPCODE_JAL 0x6f | ||
#define RVG_OPCODE_SYSTEM 0x73 | ||
|
||
/* parts of opcode for RVC*/ | ||
#define RVC_OPCODE_C0 0x0 | ||
#define RVC_OPCODE_C1 0x1 | ||
#define RVC_OPCODE_C2 0x2 | ||
|
||
/* parts of funct3 code for I, M, A extension*/ | ||
#define RVG_FUNCT3_JALR 0x0 | ||
#define RVG_FUNCT3_BEQ 0x0 | ||
#define RVG_FUNCT3_BNE 0x1 | ||
#define RVG_FUNCT3_BLT 0x4 | ||
#define RVG_FUNCT3_BGE 0x5 | ||
#define RVG_FUNCT3_BLTU 0x6 | ||
#define RVG_FUNCT3_BGEU 0x7 | ||
|
||
/* parts of funct3 code for C extension*/ | ||
#define RVC_FUNCT3_C_BEQZ 0x6 | ||
#define RVC_FUNCT3_C_BNEZ 0x7 | ||
#define RVC_FUNCT3_C_J 0x5 | ||
#define RVC_FUNCT3_C_JAL 0x1 | ||
#define RVC_FUNCT4_C_JR 0x8 | ||
#define RVC_FUNCT4_C_JALR 0x9 | ||
#define RVC_FUNCT4_C_EBREAK 0x9 | ||
|
||
#define RVG_FUNCT12_EBREAK 0x1 | ||
#define RVG_FUNCT12_SRET 0x102 | ||
|
||
#define RVG_MATCH_AUIPC (RVG_OPCODE_AUIPC) | ||
#define RVG_MATCH_JALR (RV_ENCODE_FUNCT3(JALR) | RVG_OPCODE_JALR) | ||
#define RVG_MATCH_JAL (RVG_OPCODE_JAL) | ||
#define RVG_MATCH_BEQ (RV_ENCODE_FUNCT3(BEQ) | RVG_OPCODE_BRANCH) | ||
#define RVG_MATCH_BNE (RV_ENCODE_FUNCT3(BNE) | RVG_OPCODE_BRANCH) | ||
#define RVG_MATCH_BLT (RV_ENCODE_FUNCT3(BLT) | RVG_OPCODE_BRANCH) | ||
#define RVG_MATCH_BGE (RV_ENCODE_FUNCT3(BGE) | RVG_OPCODE_BRANCH) | ||
#define RVG_MATCH_BLTU (RV_ENCODE_FUNCT3(BLTU) | RVG_OPCODE_BRANCH) | ||
#define RVG_MATCH_BGEU (RV_ENCODE_FUNCT3(BGEU) | RVG_OPCODE_BRANCH) | ||
#define RVG_MATCH_EBREAK (RV_ENCODE_FUNCT12(EBREAK) | RVG_OPCODE_SYSTEM) | ||
#define RVG_MATCH_SRET (RV_ENCODE_FUNCT12(SRET) | RVG_OPCODE_SYSTEM) | ||
#define RVC_MATCH_C_BEQZ (RVC_ENCODE_FUNCT3(C_BEQZ) | RVC_OPCODE_C1) | ||
#define RVC_MATCH_C_BNEZ (RVC_ENCODE_FUNCT3(C_BNEZ) | RVC_OPCODE_C1) | ||
#define RVC_MATCH_C_J (RVC_ENCODE_FUNCT3(C_J) | RVC_OPCODE_C1) | ||
#define RVC_MATCH_C_JAL (RVC_ENCODE_FUNCT3(C_JAL) | RVC_OPCODE_C1) | ||
#define RVC_MATCH_C_JR (RVC_ENCODE_FUNCT4(C_JR) | RVC_OPCODE_C2) | ||
#define RVC_MATCH_C_JALR (RVC_ENCODE_FUNCT4(C_JALR) | RVC_OPCODE_C2) | ||
#define RVC_MATCH_C_EBREAK (RVC_ENCODE_FUNCT4(C_EBREAK) | RVC_OPCODE_C2) | ||
|
||
#define RVG_MASK_AUIPC (RV_INSN_OPCODE_MASK) | ||
#define RVG_MASK_JALR (RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK) | ||
#define RVG_MASK_JAL (RV_INSN_OPCODE_MASK) | ||
#define RVC_MASK_C_JALR (RVC_INSN_FUNCT4_MASK | RVC_INSN_J_RS2_MASK | RVC_INSN_OPCODE_MASK) | ||
#define RVC_MASK_C_JR (RVC_INSN_FUNCT4_MASK | RVC_INSN_J_RS2_MASK | RVC_INSN_OPCODE_MASK) | ||
#define RVC_MASK_C_JAL (RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK) | ||
#define RVC_MASK_C_J (RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK) | ||
#define RVG_MASK_BEQ (RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK) | ||
#define RVG_MASK_BNE (RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK) | ||
#define RVG_MASK_BLT (RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK) | ||
#define RVG_MASK_BGE (RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK) | ||
#define RVG_MASK_BLTU (RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK) | ||
#define RVG_MASK_BGEU (RV_INSN_FUNCT3_MASK | RV_INSN_OPCODE_MASK) | ||
#define RVC_MASK_C_BEQZ (RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK) | ||
#define RVC_MASK_C_BNEZ (RVC_INSN_FUNCT3_MASK | RVC_INSN_OPCODE_MASK) | ||
#define RVC_MASK_C_EBREAK 0xffff | ||
#define RVG_MASK_EBREAK 0xffffffff | ||
#define RVG_MASK_SRET 0xffffffff | ||
|
||
#define __INSN_LENGTH_MASK _UL(0x3) | ||
#define __INSN_LENGTH_GE_32 _UL(0x3) | ||
#define __INSN_OPCODE_MASK _UL(0x7F) | ||
#define __INSN_BRANCH_OPCODE _UL(RVG_OPCODE_BRANCH) | ||
|
||
#define __RISCV_INSN_FUNCS(name, mask, val) \ | ||
static __always_inline bool riscv_insn_is_##name(u32 code) \ | ||
{ \ | ||
BUILD_BUG_ON(~(mask) & (val)); \ | ||
return (code & (mask)) == (val); \ | ||
} \ | ||
|
||
#if __riscv_xlen == 32 | ||
/* C.JAL is an RV32C-only instruction */ | ||
__RISCV_INSN_FUNCS(c_jal, RVC_MASK_C_JAL, RVC_MATCH_C_JAL) | ||
#else | ||
#define riscv_insn_is_c_jal(opcode) 0 | ||
#endif | ||
__RISCV_INSN_FUNCS(auipc, RVG_MASK_AUIPC, RVG_MATCH_AUIPC) | ||
__RISCV_INSN_FUNCS(jalr, RVG_MASK_JALR, RVG_MATCH_JALR) | ||
__RISCV_INSN_FUNCS(jal, RVG_MASK_JAL, RVG_MATCH_JAL) | ||
__RISCV_INSN_FUNCS(c_jr, RVC_MASK_C_JR, RVC_MATCH_C_JR) | ||
__RISCV_INSN_FUNCS(c_jalr, RVC_MASK_C_JALR, RVC_MATCH_C_JALR) | ||
__RISCV_INSN_FUNCS(c_j, RVC_MASK_C_J, RVC_MATCH_C_J) | ||
__RISCV_INSN_FUNCS(beq, RVG_MASK_BEQ, RVG_MATCH_BEQ) | ||
__RISCV_INSN_FUNCS(bne, RVG_MASK_BNE, RVG_MATCH_BNE) | ||
__RISCV_INSN_FUNCS(blt, RVG_MASK_BLT, RVG_MATCH_BLT) | ||
__RISCV_INSN_FUNCS(bge, RVG_MASK_BGE, RVG_MATCH_BGE) | ||
__RISCV_INSN_FUNCS(bltu, RVG_MASK_BLTU, RVG_MATCH_BLTU) | ||
__RISCV_INSN_FUNCS(bgeu, RVG_MASK_BGEU, RVG_MATCH_BGEU) | ||
__RISCV_INSN_FUNCS(c_beqz, RVC_MASK_C_BEQZ, RVC_MATCH_C_BEQZ) | ||
__RISCV_INSN_FUNCS(c_bnez, RVC_MASK_C_BNEZ, RVC_MATCH_C_BNEZ) | ||
__RISCV_INSN_FUNCS(c_ebreak, RVC_MASK_C_EBREAK, RVC_MATCH_C_EBREAK) | ||
__RISCV_INSN_FUNCS(ebreak, RVG_MASK_EBREAK, RVG_MATCH_EBREAK) | ||
__RISCV_INSN_FUNCS(sret, RVG_MASK_SRET, RVG_MATCH_SRET) | ||
|
||
/* special case to catch _any_ branch instruction */ | ||
static __always_inline bool riscv_insn_is_branch(u32 code) | ||
{ | ||
return (code & RV_INSN_OPCODE_MASK) == RVG_OPCODE_BRANCH; | ||
} | ||
|
||
#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1)) | ||
#define RVC_IMM_SIGN(x) (-(((x) >> 12) & 1)) | ||
#define RV_X(X, s, mask) (((X) >> (s)) & (mask)) | ||
#define RVC_X(X, s, mask) RV_X(X, s, mask) | ||
|
||
#define RV_EXTRACT_RD_REG(x) \ | ||
({typeof(x) x_ = (x); \ | ||
(RV_X(x_, RVG_RD_OPOFF, RVG_RD_MASK)); }) | ||
|
||
#define RV_EXTRACT_UTYPE_IMM(x) \ | ||
({typeof(x) x_ = (x); \ | ||
(RV_X(x_, RV_U_IMM_31_12_OPOFF, RV_U_IMM_31_12_MASK)); }) | ||
|
||
#define RV_EXTRACT_JTYPE_IMM(x) \ | ||
({typeof(x) x_ = (x); \ | ||
(RV_X(x_, RV_J_IMM_10_1_OPOFF, RV_J_IMM_10_1_MASK) << RV_J_IMM_10_1_OFF) | \ | ||
(RV_X(x_, RV_J_IMM_11_OPOFF, RV_J_IMM_11_MASK) << RV_J_IMM_11_OFF) | \ | ||
(RV_X(x_, RV_J_IMM_19_12_OPOFF, RV_J_IMM_19_12_MASK) << RV_J_IMM_19_12_OFF) | \ | ||
(RV_IMM_SIGN(x_) << RV_J_IMM_SIGN_OFF); }) | ||
|
||
#define RV_EXTRACT_ITYPE_IMM(x) \ | ||
({typeof(x) x_ = (x); \ | ||
(RV_X(x_, RV_I_IMM_11_0_OPOFF, RV_I_IMM_11_0_MASK)) | \ | ||
(RV_IMM_SIGN(x_) << RV_I_IMM_SIGN_OFF); }) | ||
|
||
#define RV_EXTRACT_BTYPE_IMM(x) \ | ||
({typeof(x) x_ = (x); \ | ||
(RV_X(x_, RV_B_IMM_4_1_OPOFF, RV_B_IMM_4_1_MASK) << RV_B_IMM_4_1_OFF) | \ | ||
(RV_X(x_, RV_B_IMM_10_5_OPOFF, RV_B_IMM_10_5_MASK) << RV_B_IMM_10_5_OFF) | \ | ||
(RV_X(x_, RV_B_IMM_11_OPOFF, RV_B_IMM_11_MASK) << RV_B_IMM_11_OFF) | \ | ||
(RV_IMM_SIGN(x_) << RV_B_IMM_SIGN_OFF); }) | ||
|
||
#define RVC_EXTRACT_JTYPE_IMM(x) \ | ||
({typeof(x) x_ = (x); \ | ||
(RVC_X(x_, RVC_J_IMM_3_1_OPOFF, RVC_J_IMM_3_1_MASK) << RVC_J_IMM_3_1_OFF) | \ | ||
(RVC_X(x_, RVC_J_IMM_4_OPOFF, RVC_J_IMM_4_MASK) << RVC_J_IMM_4_OFF) | \ | ||
(RVC_X(x_, RVC_J_IMM_5_OPOFF, RVC_J_IMM_5_MASK) << RVC_J_IMM_5_OFF) | \ | ||
(RVC_X(x_, RVC_J_IMM_6_OPOFF, RVC_J_IMM_6_MASK) << RVC_J_IMM_6_OFF) | \ | ||
(RVC_X(x_, RVC_J_IMM_7_OPOFF, RVC_J_IMM_7_MASK) << RVC_J_IMM_7_OFF) | \ | ||
(RVC_X(x_, RVC_J_IMM_9_8_OPOFF, RVC_J_IMM_9_8_MASK) << RVC_J_IMM_9_8_OFF) | \ | ||
(RVC_X(x_, RVC_J_IMM_10_OPOFF, RVC_J_IMM_10_MASK) << RVC_J_IMM_10_OFF) | \ | ||
(RVC_IMM_SIGN(x_) << RVC_J_IMM_SIGN_OFF); }) | ||
|
||
#define RVC_EXTRACT_BTYPE_IMM(x) \ | ||
({typeof(x) x_ = (x); \ | ||
(RVC_X(x_, RVC_B_IMM_2_1_OPOFF, RVC_B_IMM_2_1_MASK) << RVC_B_IMM_2_1_OFF) | \ | ||
(RVC_X(x_, RVC_B_IMM_4_3_OPOFF, RVC_B_IMM_4_3_MASK) << RVC_B_IMM_4_3_OFF) | \ | ||
(RVC_X(x_, RVC_B_IMM_5_OPOFF, RVC_B_IMM_5_MASK) << RVC_B_IMM_5_OFF) | \ | ||
(RVC_X(x_, RVC_B_IMM_7_6_OPOFF, RVC_B_IMM_7_6_MASK) << RVC_B_IMM_7_6_OFF) | \ | ||
(RVC_IMM_SIGN(x_) << RVC_B_IMM_SIGN_OFF); }) | ||
|
||
/* | ||
* Put together one immediate from a U-type and I-type instruction pair. | ||
* | ||
* The U-type contains an upper immediate, meaning bits[31:12] with [11:0] | ||
* being zero, while the I-type contains a 12bit immediate. | ||
* Combined these can encode larger 32bit values and are used for example | ||
* in auipc + jalr pairs to allow larger jumps. | ||
* | ||
* @utype_insn: instruction containing the upper immediate | ||
* @itype_insn: instruction | ||
* Return: combined immediate | ||
*/ | ||
static inline s32 riscv_insn_extract_utype_itype_imm(u32 utype_insn, u32 itype_insn) | ||
{ | ||
s32 imm; | ||
|
||
imm = RV_EXTRACT_UTYPE_IMM(utype_insn); | ||
imm += RV_EXTRACT_ITYPE_IMM(itype_insn); | ||
|
||
return imm; | ||
} | ||
|
||
/* | ||
* Update a set of two instructions (U-type + I-type) with an immediate value. | ||
* | ||
* Used for example in auipc+jalrs pairs the U-type instructions contains | ||
* a 20bit upper immediate representing bits[31:12], while the I-type | ||
* instruction contains a 12bit immediate representing bits[11:0]. | ||
* | ||
* This also takes into account that both separate immediates are | ||
* considered as signed values, so if the I-type immediate becomes | ||
* negative (BIT(11) set) the U-type part gets adjusted. | ||
* | ||
* @utype_insn: pointer to the utype instruction of the pair | ||
* @itype_insn: pointer to the itype instruction of the pair | ||
* @imm: the immediate to insert into the two instructions | ||
*/ | ||
static inline void riscv_insn_insert_utype_itype_imm(u32 *utype_insn, u32 *itype_insn, s32 imm) | ||
{ | ||
/* drop possible old IMM values */ | ||
*utype_insn &= ~(RV_U_IMM_31_12_MASK); | ||
*itype_insn &= ~(RV_I_IMM_11_0_MASK << RV_I_IMM_11_0_OPOFF); | ||
|
||
/* add the adapted IMMs */ | ||
*utype_insn |= (imm & RV_U_IMM_31_12_MASK) + ((imm & BIT(11)) << 1); | ||
*itype_insn |= ((imm & RV_I_IMM_11_0_MASK) << RV_I_IMM_11_0_OPOFF); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters