@@ -3070,42 +3070,63 @@ enum Nf {
30703070#undef INSN
30713071
30723072// Cache Management Operations
3073- #define INSN (NAME, funct ) \
3074- void NAME (Register Rs1) { \
3075- unsigned insn = 0 ; \
3076- patch ((address)&insn, 6 , 0 , 0b0001111 ); \
3077- patch ((address)&insn, 14 , 12 , 0b010 ); \
3078- patch_reg ((address)&insn, 15 , Rs1); \
3079- patch ((address)&insn, 31 , 20 , funct); \
3080- emit (insn); \
3073+ // These instruction may be turned off for user space.
3074+ private:
3075+ enum CBO_FUNCT : unsigned int {
3076+ CBO_INVAL = 0b0000000000000 ,
3077+ CBO_CLEAN = 0b0000000000001 ,
3078+ CBO_FLUSH = 0b0000000000010 ,
3079+ CBO_ZERO = 0b0000000000100
3080+ };
3081+
3082+ template <CBO_FUNCT FUNCT>
3083+ void cbo_base (Register Rs1) {
3084+ assert ((UseZicbom && FUNCT != CBO_ZERO) || UseZicboz, " sanity" );
3085+ unsigned insn = 0 ;
3086+ patch ((address)&insn, 6 , 0 , 0b0001111 );
3087+ patch ((address)&insn, 14 , 12 , 0b010 );
3088+ patch_reg ((address)&insn, 15 , Rs1);
3089+ patch ((address)&insn, 31 , 20 , FUNCT);
3090+ emit (insn);
30813091 }
30823092
3083- INSN (cbo_inval, 0b0000000000000 );
3084- INSN (cbo_clean, 0b0000000000001 );
3085- INSN (cbo_flush, 0b0000000000010 );
3086- INSN (cbo_zero, 0b0000000000100 );
3093+ // This instruction have some security implication.
3094+ // At this time it's not likely to be enabled for user mode.
3095+ void cbo_inval (Register Rs1) { cbo_base<CBO_INVAL>(Rs1); }
3096+ public:
3097+ // Zicbom
3098+ void cbo_clean (Register Rs1) { cbo_base<CBO_CLEAN>(Rs1); }
3099+ void cbo_flush (Register Rs1) { cbo_base<CBO_FLUSH>(Rs1); }
3100+ // Zicboz
3101+ void cbo_zero (Register Rs1) { cbo_base<CBO_ZERO>(Rs1); }
30873102
3088- #undef INSN
3103+ private:
3104+ enum PREFETCH_FUNCT : unsigned int {
3105+ PREFETCH_I = 0b0000000000000 ,
3106+ PREFETCH_R = 0b0000000000001 ,
3107+ PREFETCH_W = 0b0000000000011
3108+ };
30893109
3090- #define INSN (NAME, funct ) \
3091- void NAME (Register Rs1, int32_t offset) { \
3092- guarantee ((offset & 0x1f ) == 0 , " offset lowest 5 bits must be zero" ); \
3093- int32_t upperOffset = offset >> 5 ; \
3094- unsigned insn = 0 ; \
3095- patch ((address)&insn, 6 , 0 , 0b0010011 ); \
3096- patch ((address)&insn, 14 , 12 , 0b110 ); \
3097- patch_reg ((address)&insn, 15 , Rs1); \
3098- patch ((address)&insn, 24 , 20 , funct); \
3099- upperOffset &= 0x7f ; \
3100- patch ((address)&insn, 31 , 25 , upperOffset); \
3101- emit (insn); \
3110+ template <PREFETCH_FUNCT FUNCT>
3111+ void prefetch_base (Register Rs1, int32_t offset) {
3112+ assert_cond (UseZicbop);
3113+ guarantee ((offset & 0x1f ) == 0 , " offset lowest 5 bits must be zero" );
3114+ int32_t upperOffset = offset >> 5 ;
3115+ unsigned insn = 0 ;
3116+ patch ((address)&insn, 6 , 0 , 0b0010011 );
3117+ patch ((address)&insn, 14 , 12 , 0b110 );
3118+ patch_reg ((address)&insn, 15 , Rs1);
3119+ patch ((address)&insn, 24 , 20 , FUNCT);
3120+ upperOffset &= 0x7f ;
3121+ patch ((address)&insn, 31 , 25 , upperOffset);
3122+ emit (insn);
31023123 }
31033124
3104- INSN (prefetch_i, 0b0000000000000 );
3105- INSN (prefetch_r, 0b0000000000001 );
3106- INSN (prefetch_w, 0b0000000000011 );
3107-
3108- # undef INSN
3125+ public:
3126+ // Zicbop
3127+ void prefetch_i (Register Rs1, int32_t offset) { prefetch_base<PREFETCH_I>(Rs1, offset); }
3128+ void prefetch_r (Register Rs1, int32_t offset) { prefetch_base<PREFETCH_R>(Rs1, offset); }
3129+ void prefetch_w (Register Rs1, int32_t offset) { prefetch_base<PREFETCH_W>(Rs1, offset); }
31093130
31103131// -------------- Zicond Instruction Definitions --------------
31113132// Zicond conditional operations extension
0 commit comments