Skip to content

Commit 42a6ad8

Browse files
committed
Add support for Zbb basic bit-manipulation extension
Add support for the RISC-V Zbb basic bit-manipulation extension. This extension introduces fundamental bitwise operations such as bit counting, bit field extraction, and bit rotation, enabling efficient data manipulation and low-level computation. Supporting the Zbb extension improves compatibility with the RISC-V specification and enables optimized handling of bitwise operations in a wide range of applications.
1 parent 2bbcfbd commit 42a6ad8

File tree

7 files changed

+480
-0
lines changed

7 files changed

+480
-0
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ $(call set-feature, Zifencei)
111111
ENABLE_Zba ?= 1
112112
$(call set-feature, Zba)
113113

114+
# Zbb Basic bit-manipulation
115+
ENABLE_Zbb ?= 1
116+
$(call set-feature, Zbb)
117+
114118
ENABLE_FULL4G ?= 0
115119

116120
# Experimental SDL oriented system calls

src/decode.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,28 @@ static inline bool op_op_imm(rv_insn_t *ir, const uint32_t insn)
464464
ir->opcode = rv_insn_addi;
465465
break;
466466
case 1: /* SLLI: Shift Left Logical */
467+
#if RV32_HAS(Zbb)
468+
if (ir->imm == 0b011000000000) { /* clz */
469+
ir->opcode = rv_insn_clz;
470+
return true;
471+
}
472+
if (ir->imm == 0b011000000001) { /* ctz */
473+
ir->opcode = rv_insn_ctz;
474+
return true;
475+
}
476+
if (ir->imm == 0b011000000010) { /* cpop */
477+
ir->opcode = rv_insn_cpop;
478+
return true;
479+
}
480+
if (ir->imm == 0b011000000100) { /* sext.b */
481+
ir->opcode = rv_insn_sextb;
482+
return true;
483+
}
484+
if (ir->imm == 0b011000000101) { /* sext.h */
485+
ir->opcode = rv_insn_sexth;
486+
return true;
487+
}
488+
#endif
467489
ir->opcode = rv_insn_slli;
468490
if (unlikely(ir->imm & (1 << 5)))
469491
return false;
@@ -478,6 +500,20 @@ static inline bool op_op_imm(rv_insn_t *ir, const uint32_t insn)
478500
ir->opcode = rv_insn_xori;
479501
break;
480502
case 5:
503+
#if RV32_HAS(Zbb)
504+
if ((ir->imm >> 5) == 0b0110000) { /* rori */
505+
ir->opcode = rv_insn_rori;
506+
return true;
507+
}
508+
if (ir->imm == 0b001010000111) { /* orc.b */
509+
ir->opcode = rv_insn_orcb;
510+
return true;
511+
}
512+
if (ir->imm == 0b011010011000) { /* rev8 */
513+
ir->opcode = rv_insn_rev8;
514+
return true;
515+
}
516+
#endif
481517
/* SLL, SRL, and SRA perform logical left, logical right, and
482518
* arithmetic right shifts on the value in register rs1.
483519
*/
@@ -689,6 +725,53 @@ static inline bool op_op(rv_insn_t *ir, const uint32_t insn)
689725
break;
690726
#endif /* RV32_HAS(Zba) */
691727

728+
#if RV32_HAS(Zbb)
729+
/* inst funct7 rs2 rs1 funct3 rd opcode
730+
* ------+-------+---+---+------+--+-------
731+
* MAX 0000101 rs2 rs1 110 rd 0110011
732+
* MIN 0000101 rs2 rs1 100 rd 0110011
733+
* MAXU 0000101 rs2 rs1 111 rd 0110011
734+
* MINU 0000101 rs2 rs1 101 rd 0110011
735+
* ROL 0110000 rs2 rs1 001 rd 0110011
736+
* ROR 0110000 rs2 rs1 101 rd 0110011
737+
*/
738+
case 0b0000101:
739+
switch (funct3) {
740+
case 0b110: /* max */
741+
ir->opcode = rv_insn_max;
742+
break;
743+
case 0b100: /* min */
744+
ir->opcode = rv_insn_min;
745+
break;
746+
case 0b111: /* maxu */
747+
ir->opcode = rv_insn_maxu;
748+
break;
749+
case 0b101: /* minu */
750+
ir->opcode = rv_insn_minu;
751+
break;
752+
default: /* illegal instruction */
753+
return false;
754+
}
755+
break;
756+
case 0b0110000:
757+
switch (funct3) {
758+
case 0b001: /* rol */
759+
ir->opcode = rv_insn_rol;
760+
break;
761+
case 0b101: /* ror */
762+
ir->opcode = rv_insn_ror;
763+
break;
764+
default: /* illegal instruction */
765+
return false;
766+
}
767+
break;
768+
case 0b0000100:
769+
if (unlikely(ir->rs2))
770+
return false;
771+
ir->opcode = rv_insn_zexth;
772+
break;
773+
#endif /* RV32_HAS(Zbb) */
774+
692775
case 0b0100000:
693776
switch (funct3) {
694777
case 0b000: /* SUB: Substract */
@@ -697,6 +780,18 @@ static inline bool op_op(rv_insn_t *ir, const uint32_t insn)
697780
case 0b101: /* SRA: Shift Right Arithmetic */
698781
ir->opcode = rv_insn_sra;
699782
break;
783+
#if RV32_HAS(Zbb)
784+
case 0b111: /* ANDN */
785+
ir->opcode = rv_insn_andn;
786+
break;
787+
case 0b110: /* ORN */
788+
ir->opcode = rv_insn_orn;
789+
break;
790+
case 0b100: /* XNOR */
791+
ir->opcode = rv_insn_xnor;
792+
break;
793+
#endif /* RV32_HAS(Zbb) */
794+
700795
default: /* illegal instruction */
701796
return false;
702797
}

src/decode.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,27 @@ enum op_field {
103103
_(sh2add, 0, 4, 0, ENC(rs1, rs2, rd)) \
104104
_(sh3add, 0, 4, 0, ENC(rs1, rs2, rd)) \
105105
) \
106+
/* RV32 Zbb Standard Extension */ \
107+
IIF(RV32_HAS(Zbb))( \
108+
_(andn, 0, 4, 0, ENC(rs1, rs2, rd)) \
109+
_(orn, 0, 4, 0, ENC(rs1, rs2, rd)) \
110+
_(xnor, 0, 4, 0, ENC(rs1, rs2, rd)) \
111+
_(clz, 0, 4, 0, ENC(rs1, rd)) \
112+
_(ctz, 0, 4, 0, ENC(rs1, rd)) \
113+
_(cpop, 0, 4, 0, ENC(rs1, rd)) \
114+
_(max, 0, 4, 0, ENC(rs1, rs2, rd)) \
115+
_(maxu, 0, 4, 0, ENC(rs1, rs2, rd)) \
116+
_(min, 0, 4, 0, ENC(rs1, rs2, rd)) \
117+
_(minu, 0, 4, 0, ENC(rs1, rs2, rd)) \
118+
_(sextb, 0, 4, 0, ENC(rs1, rd)) \
119+
_(sexth, 0, 4, 0, ENC(rs1, rd)) \
120+
_(zexth, 0, 4, 0, ENC(rs1, rd)) \
121+
_(rol, 0, 4, 0, ENC(rs1, rs2, rd)) \
122+
_(ror, 0, 4, 0, ENC(rs1, rs2, rd)) \
123+
_(rori, 0, 4, 0, ENC(rs1, rd)) \
124+
_(orcb, 0, 4, 0, ENC(rs1, rd)) \
125+
_(rev8, 0, 4, 0, ENC(rs1, rd)) \
126+
) \
106127
/* RV32M Standard Extension */ \
107128
IIF(RV32_HAS(EXT_M))( \
108129
_(mul, 0, 4, 1, ENC(rs1, rs2, rd)) \

src/feature.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242
#define RV32_FEATURE_Zba 1
4343
#endif
4444

45+
/* Zbb Basic bit-manipulation */
46+
#ifndef RV32_FEATURE_Zbb
47+
#define RV32_FEATURE_Zbb 1
48+
#endif
49+
4550
/* Experimental SDL oriented system calls */
4651
#ifndef RV32_FEATURE_SDL
4752
#define RV32_FEATURE_SDL 1

src/rv32_constopt.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,3 +1059,113 @@ CONSTOPT(sh3add, {
10591059
info->is_constant[ir->rd] = false;
10601060
})
10611061
#endif
1062+
1063+
#if RV32_HAS(Zbb)
1064+
/* ANDN */
1065+
CONSTOPT(andn, {
1066+
if (ir->rd)
1067+
info->is_constant[ir->rd] = false;
1068+
})
1069+
1070+
/* ORN */
1071+
CONSTOPT(orn, {
1072+
if (ir->rd)
1073+
info->is_constant[ir->rd] = false;
1074+
})
1075+
1076+
/* XNOR */
1077+
CONSTOPT(xnor, {
1078+
if (ir->rd)
1079+
info->is_constant[ir->rd] = false;
1080+
})
1081+
1082+
/* CLZ */
1083+
CONSTOPT(clz, {
1084+
if (ir->rd)
1085+
info->is_constant[ir->rd] = false;
1086+
})
1087+
1088+
/* CTZ */
1089+
CONSTOPT(ctz, {
1090+
if (ir->rd)
1091+
info->is_constant[ir->rd] = false;
1092+
})
1093+
1094+
/* CPOP */
1095+
CONSTOPT(cpop, {
1096+
if (ir->rd)
1097+
info->is_constant[ir->rd] = false;
1098+
})
1099+
1100+
/* MAX */
1101+
CONSTOPT(max, {
1102+
if (ir->rd)
1103+
info->is_constant[ir->rd] = false;
1104+
})
1105+
1106+
/* MAXU */
1107+
CONSTOPT(maxu, {
1108+
if (ir->rd)
1109+
info->is_constant[ir->rd] = false;
1110+
})
1111+
1112+
/* MIN */
1113+
CONSTOPT(min, {
1114+
if (ir->rd)
1115+
info->is_constant[ir->rd] = false;
1116+
})
1117+
1118+
/* MINU */
1119+
CONSTOPT(minu, {
1120+
if (ir->rd)
1121+
info->is_constant[ir->rd] = false;
1122+
})
1123+
1124+
/* SEXT.B */
1125+
CONSTOPT(sextb, {
1126+
if (ir->rd)
1127+
info->is_constant[ir->rd] = false;
1128+
})
1129+
1130+
/* SEXT.H */
1131+
CONSTOPT(sexth, {
1132+
if (ir->rd)
1133+
info->is_constant[ir->rd] = false;
1134+
})
1135+
1136+
/* ZEXT.H */
1137+
CONSTOPT(zexth, {
1138+
if (ir->rd)
1139+
info->is_constant[ir->rd] = false;
1140+
})
1141+
1142+
/* ROL */
1143+
CONSTOPT(rol, {
1144+
if (ir->rd)
1145+
info->is_constant[ir->rd] = false;
1146+
})
1147+
1148+
/* ROR */
1149+
CONSTOPT(ror, {
1150+
if (ir->rd)
1151+
info->is_constant[ir->rd] = false;
1152+
})
1153+
1154+
/* RORI */
1155+
CONSTOPT(rori, {
1156+
if (ir->rd)
1157+
info->is_constant[ir->rd] = false;
1158+
})
1159+
1160+
/* ORCB */
1161+
CONSTOPT(orcb, {
1162+
if (ir->rd)
1163+
info->is_constant[ir->rd] = false;
1164+
})
1165+
1166+
/* REV8 */
1167+
CONSTOPT(rev8, {
1168+
if (ir->rd)
1169+
info->is_constant[ir->rd] = false;
1170+
})
1171+
#endif

0 commit comments

Comments
 (0)