Skip to content

Commit 2bbcfbd

Browse files
committed
Add support for Zba address generation extension
Add support for the RISC-V Zba address generation extension. These instructions combine shift and addition operations, enabling efficient address calculation in pointer arithmetic and memory access patterns. Supporting the Zba extension improves compatibility with the RISC-V specification and enables optimized handling of address generation tasks.
1 parent e069c63 commit 2bbcfbd

File tree

7 files changed

+97
-0
lines changed

7 files changed

+97
-0
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ $(call set-feature, Zicsr)
107107
ENABLE_Zifencei ?= 1
108108
$(call set-feature, Zifencei)
109109

110+
# Zba Address generation instructions
111+
ENABLE_Zba ?= 1
112+
$(call set-feature, Zba)
113+
110114
ENABLE_FULL4G ?= 0
111115

112116
# Experimental SDL oriented system calls

src/decode.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,30 @@ static inline bool op_op(rv_insn_t *ir, const uint32_t insn)
665665
break;
666666
#endif /* RV32_HAS(EXT_M) */
667667

668+
#if RV32_HAS(Zba)
669+
/* inst funct7 rs2 rs1 funct3 rd opcode
670+
* ------+-------+---+---+------+--+-------
671+
* SH1ADD 0010000 rs2 rs1 010 rd 0110011
672+
* SH2ADD 0010000 rs2 rs1 100 rd 0110011
673+
* SH3ADD 0010000 rs2 rs1 110 rd 0110011
674+
*/
675+
case 0b0010000:
676+
switch (funct3) {
677+
case 0b010: /* sh1add */
678+
ir->opcode = rv_insn_sh1add;
679+
break;
680+
case 0b100: /* sh2add */
681+
ir->opcode = rv_insn_sh2add;
682+
break;
683+
case 0b110: /* sh3add */
684+
ir->opcode = rv_insn_sh3add;
685+
break;
686+
default: /* illegal instruction */
687+
return false;
688+
}
689+
break;
690+
#endif /* RV32_HAS(Zba) */
691+
668692
case 0b0100000:
669693
switch (funct3) {
670694
case 0b000: /* SUB: Substract */

src/decode.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ enum op_field {
9797
_(csrrsi, 0, 4, 0, ENC(rs1, rd)) \
9898
_(csrrci, 0, 4, 0, ENC(rs1, rd)) \
9999
) \
100+
/* RV32 Zba Standard Extension */ \
101+
IIF(RV32_HAS(Zba))( \
102+
_(sh1add, 0, 4, 0, ENC(rs1, rs2, rd)) \
103+
_(sh2add, 0, 4, 0, ENC(rs1, rs2, rd)) \
104+
_(sh3add, 0, 4, 0, ENC(rs1, rs2, rd)) \
105+
) \
100106
/* RV32M Standard Extension */ \
101107
IIF(RV32_HAS(EXT_M))( \
102108
_(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
@@ -37,6 +37,11 @@
3737
#define RV32_FEATURE_Zifencei 1
3838
#endif
3939

40+
/* Zba Address generation instructions */
41+
#ifndef RV32_FEATURE_Zba
42+
#define RV32_FEATURE_Zba 1
43+
#endif
44+
4045
/* Experimental SDL oriented system calls */
4146
#ifndef RV32_FEATURE_SDL
4247
#define RV32_FEATURE_SDL 1

src/rv32_constopt.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,3 +1039,23 @@ CONSTOPT(cflw, {})
10391039
/* C.FSW */
10401040
CONSTOPT(cfsw, {})
10411041
#endif
1042+
1043+
#if RV32_HAS(Zba)
1044+
/* SH1ADD */
1045+
CONSTOPT(sh1add, {
1046+
if (ir->rd)
1047+
info->is_constant[ir->rd] = false;
1048+
})
1049+
1050+
/* SH2ADD */
1051+
CONSTOPT(sh2add, {
1052+
if (ir->rd)
1053+
info->is_constant[ir->rd] = false;
1054+
})
1055+
1056+
/* SH3ADD */
1057+
CONSTOPT(sh3add, {
1058+
if (ir->rd)
1059+
info->is_constant[ir->rd] = false;
1060+
})
1061+
#endif

src/rv32_template.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2600,3 +2600,33 @@ RVOP(
26002600
assert; /* FIXME: Implement */
26012601
}))
26022602
#endif
2603+
2604+
/* RV32Zba Standard Extension */
2605+
2606+
#if RV32_HAS(Zba)
2607+
2608+
/* SH1ADD */
2609+
RVOP(
2610+
sh1add,
2611+
{ rv->X[ir->rd] = (rv->X[ir->rs1] << 1) + rv->X[ir->rs2]; },
2612+
GEN({
2613+
assert; /* FIXME: Implement */
2614+
}))
2615+
2616+
/* SH2ADD */
2617+
RVOP(
2618+
sh2add,
2619+
{ rv->X[ir->rd] = (rv->X[ir->rs1] << 2) + rv->X[ir->rs2]; },
2620+
GEN({
2621+
assert; /* FIXME: Implement */
2622+
}))
2623+
2624+
/* SH3ADD */
2625+
RVOP(
2626+
sh3add,
2627+
{ rv->X[ir->rd] = (rv->X[ir->rs1] << 3) + rv->X[ir->rs2]; },
2628+
GEN({
2629+
assert; /* FIXME: Implement */
2630+
}))
2631+
2632+
#endif

src/t2c_template.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,14 @@ T2C_OP(cflw, { __UNREACHABLE; })
793793
T2C_OP(cfsw, { __UNREACHABLE; })
794794
#endif
795795

796+
#if RV32_HAS(Zba)
797+
T2C_OP(sh1add, { __UNREACHABLE; })
798+
799+
T2C_OP(sh2add, { __UNREACHABLE; })
800+
801+
T2C_OP(sh3add, { __UNREACHABLE; })
802+
#endif
803+
796804
T2C_OP(fuse1, {
797805
opcode_fuse_t *fuse = ir->fuse;
798806
for (int i = 0; i < ir->imm2; i++) {

0 commit comments

Comments
 (0)