1 /* 2 * Copyright (c) 2024 Raspberry Pi Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _HARDWARE_HAZARD3_INSTRUCTIONS_H 8 #define _HARDWARE_HAZARD3_INSTRUCTIONS_H 9 10 #include "pico.h" 11 12 // Get list of supported extensions based on platform: 13 #include "hardware/hazard3/features.h" 14 15 /** \file hardware/hazard3/instructions.h 16 * \addtogroup hardware_hazard3 17 * 18 * \brief Intrinsics and asm macros for Hazard3 custom instructions 19 * 20 * The implementation of these intrinsics depends on the feature macros 21 * defined in hardware/hazard3/features.h. When the relevant feature is not 22 * present, the intrinsics fall back on an RV32I equivalent if possible. 23 * 24 */ 25 26 #ifdef __ASSEMBLER__ 27 28 // Assembly language instruction macros for Hazard3 custom instructions 29 30 // h3.bextm: Extract up to 8 consecutive bits from register rs1, with the 31 // first bit indexed by rs2, and bit count configured by an immediate value. 32 // R-format instruction. Pseudocode: 33 // 34 // rd = (rs1 >> rs2[4:0]) & ~(-1 << nbits) 35 36 .macro h3.bextm rd rs1 rs2 nbits 37 .if (\nbits < 1) || (\nbits > 8) 38 .err 39 .endif 40 #ifdef __hazard3_extension_xh3bextm 41 .insn r 0x0b, 0x4, (((\nbits - 1) & 0x7 ) << 1), \rd, \rs1, \rs2 42 #else 43 srl \rd, \rs1, \rs2 44 andi \rd, \rd, ((1 << \nbits) - 1) 45 #endif 46 .endm 47 48 // h3.bextmi: Extract up to 8 consecutive bits from register rs1, with the 49 // first bit index and the number of bits both configured by immediate 50 // values. I-format instruction. Pseudocode: 51 // 52 // rd = (rs1 >> shamt) & ~(-1 << nbits) 53 54 .macro h3.bextmi rd rs1 shamt nbits 55 .if (\nbits < 1) || (\nbits > 8) 56 .err 57 .endif 58 .if (\shamt < 0) || (\shamt > 31) 59 .err 60 .endif 61 #ifdef __hazard3_extension_xh3bextm 62 .insn i 0x0b, 0x4, \rd, \rs1, (\shamt & 0x1f) | (((\nbits - 1) & 0x7 ) << 6) 63 #else 64 srli \rd, \rs1, \shamt 65 andi \rd, \rd, ((1 << \nbits) - 1) 66 #endif 67 .endm 68 69 // h3.block: enter an idle state until another processor in the same 70 // multiprocessor complex executes an h3.unblock instruction, or the 71 // processor is interrupted. Fall through immediately if an h3.unblock has 72 // been received since the last execution of an h3.block on this processor. 73 // On RP2350, processors also have their own h3.unblock signals reflected 74 // back to them. 75 76 .macro h3.block 77 #ifdef __hazard3_extension_xh3power 78 slt x0, x0, x0 79 #else 80 nop 81 #endif 82 .endm 83 84 // h3.unblock: signal other processors in the same multiprocessor complex to 85 // exit the idle state entered by an h3.block instruction. On RP2350, this 86 // signal is also reflected back to the processor that executed the 87 // h3.unblock, which will cause that processor's next h3.block to fall 88 // through immediately. 89 90 .macro h3.unblock 91 #ifdef __hazard3_extension_xh3power 92 slt x0, x0, x1 93 #else 94 nop 95 #endif 96 .endm 97 98 #else // !__ASSEMBLER__ 99 100 // C language instruction macros for Hazard3 custom instructions 101 102 #ifdef __cplusplus 103 extern "C" { 104 #endif 105 106 // nbits must be a constant expression 107 #ifdef __hazard3_extension_xh3bextm 108 #define __hazard3_bextm(nbits, rs1, rs2) ({\ 109 uint32_t __h3_bextm_rd; \ 110 asm (".insn r 0x0b, 0, %3, %0, %1, %2"\ 111 : "=r" (__h3_bextm_rd) \ 112 : "r" (rs1), "r" (rs2), "i" ((((nbits) - 1) & 0x7) << 1)\ 113 ); \ 114 __h3_bextm_rd; \ 115 }) 116 #else 117 #define __hazard3_bextm(nbits, rs1, rs2) (((rs1) >> ((rs2) & 0x1f)) & (0xffu >> (7 - (((nbits) - 1) & 0x7)))) 118 #endif 119 120 // nbits and shamt must be constant expressions 121 #ifdef __hazard3_extension_xh3bextm 122 #define __hazard3_bextmi(nbits, rs1, shamt) ({\ 123 uint32_t __h3_bextmi_rd; \ 124 asm (".insn i 0x0b, 0x4, %0, %1, %2"\ 125 : "=r" (__h3_bextmi_rd) \ 126 : "r" (rs1), "i" ((((nbits) - 1) & 0x7) << 6 | ((shamt) & 0x1f)) \ 127 ); \ 128 __h3_bextmi_rd; \ 129 }) 130 #else 131 #define __hazard3_bextm(nbits, rs1, rs2) (((rs1) >> ((shamt) & 0x1f)) & (0xffu >> (7 - (((nbits) - 1) & 0x7)))) 132 #endif 133 134 #ifdef __hazard3_extension_xh3power 135 #define __hazard3_block() asm volatile ("slt x0, x0, x0" : : : "memory") 136 #else 137 #define __hazard3_block() do {} while (0) 138 #endif 139 140 #ifdef __hazard3_extension_xh3power 141 #define __hazard3_unblock() asm volatile ("slt x0, x0, x1" : : : "memory") 142 #else 143 #define __hazard3_unblock() do {} while (0) 144 #endif 145 146 #ifdef __cplusplus 147 } 148 #endif 149 150 #endif // !__ASSEMBLER__ 151 152 #endif 153