Skip to content

Commit 8436338

Browse files
committed
Support RV32FC
1 parent 8391ae2 commit 8436338

File tree

4 files changed

+156
-10
lines changed

4 files changed

+156
-10
lines changed

src/decode.c

+87-10
Original file line numberDiff line numberDiff line change
@@ -1668,15 +1668,92 @@ static inline bool op_cbnez(rv_insn_t *ir, const uint32_t insn)
16681668
#define op_cbnez OP_UNIMP
16691669
#endif /* RV32_HAS(EXT_C) */
16701670

1671-
/* TODO: RV32C.F support */
1672-
#define op_cfldsp OP_UNIMP
1673-
#define op_cflwsp OP_UNIMP
1674-
#define op_cfswsp OP_UNIMP
1675-
#define op_cfsdsp OP_UNIMP
1676-
#define op_cfld OP_UNIMP
1677-
#define op_cflw OP_UNIMP
1671+
#if RV32_HAS(EXT_C) && RV32_HAS(EXT_F)
1672+
/* C.FLWSP: CI-format
1673+
* 15 13 12 11 7 6 2 1 0
1674+
* | funct3 | imm | rd | imm | op |
1675+
*/
1676+
static inline bool op_cflwsp(rv_insn_t *ir, const uint32_t insn)
1677+
{
1678+
/* inst funct3 imm rd imm op
1679+
* -------+------+-------+-----+-------------+--
1680+
* C.FLWSP 001 uimm[5] rd uimm[4:2|7:6] 10
1681+
*/
1682+
uint16_t tmp = 0;
1683+
tmp |= (insn & 0x70) >> 2;
1684+
tmp |= (insn & 0x0c) << 4;
1685+
tmp |= (insn & 0x1000) >> 7;
1686+
ir->imm = tmp;
1687+
ir->rd = c_decode_rd(insn);
1688+
ir->opcode = rv_insn_cflwsp;
1689+
return true;
1690+
}
1691+
1692+
/* C.FSWSP: CSS-Format
1693+
* 15 13 12 7 6 2 1 0
1694+
* | funct3 | imm | rs2 | op |
1695+
*/
1696+
static inline bool op_cfswsp(rv_insn_t *ir, const uint32_t insn)
1697+
{
1698+
/* inst funct3 imm rs2 op
1699+
* -------+------+-------------+---+--
1700+
* C.FSWSP 111 uimm[5:2|7:6] rs2 10
1701+
*/
1702+
ir->imm = (insn & 0x1e00) >> 7 | (insn & 0x180) >> 1;
1703+
ir->rs2 = c_decode_rs2(insn);
1704+
ir->opcode = rv_insn_cfswsp;
1705+
return true;
1706+
}
1707+
1708+
/* C.LW: CL-format
1709+
* 15 13 12 10 9 7 6 5 4 2 1 0
1710+
* | funct3 | imm | rs1' | imm | rd' | op |
1711+
*/
1712+
static inline bool op_cflw(rv_insn_t *ir, const uint32_t insn)
1713+
{
1714+
/* inst funct3 imm rs1' imm rd' op
1715+
* -----+------+---------+----+---------+---+--
1716+
* C.FLW 010 uimm[5:3] rs1' uimm[7:6] rd' 00
1717+
*/
1718+
uint16_t tmp = 0;
1719+
tmp |= (insn & 0b0000000001000000) >> 4;
1720+
tmp |= (insn & FC_IMM_12_10) >> 7;
1721+
tmp |= (insn & 0b0000000000100000) << 1;
1722+
ir->imm = tmp;
1723+
ir->rd = c_decode_rdc(insn) | 0x08;
1724+
ir->rs1 = c_decode_rs1c(insn) | 0x08;
1725+
ir->opcode = rv_insn_cflw;
1726+
return true;
1727+
}
1728+
1729+
/* C.FSW: CS-format
1730+
* 15 13 12 10 9 7 6 5 4 2 1 0
1731+
* | funct3 | imm | rs1' | imm | rs2' | op |
1732+
*/
1733+
static inline bool op_cfsw(rv_insn_t *ir, const uint32_t insn)
1734+
{
1735+
/* inst funct3 imm rs1' imm rs2' op
1736+
* -----+------+---------+----+---------+----+--
1737+
* C.FSW 110 uimm[5:3] rs1' uimm[2|6] rs2' 00
1738+
*/
1739+
uint32_t tmp = 0;
1740+
/* ....xxxx....xxxx */
1741+
tmp |= (insn & 0b0000000001000000) >> 4;
1742+
tmp |= (insn & FC_IMM_12_10) >> 7;
1743+
tmp |= (insn & 0b0000000000100000) << 1;
1744+
ir->imm = tmp;
1745+
ir->rs1 = c_decode_rs1c(insn) | 0x08;
1746+
ir->rs2 = c_decode_rs2c(insn) | 0x08;
1747+
ir->opcode = rv_insn_cfsw;
1748+
return true;
1749+
}
1750+
1751+
#else /* !(RV32_HAS(EXT_C) && RV32_HAS(EXT_F)) */
16781752
#define op_cfsw OP_UNIMP
1679-
#define op_cfsd OP_UNIMP
1753+
#define op_cflw OP_UNIMP
1754+
#define op_cfswsp OP_UNIMP
1755+
#define op_cflwsp OP_UNIMP
1756+
#endif /* RV32_HAS(EXT_C) && RV32_HAS(EXT_F) */
16801757

16811758
/* handler for all unimplemented opcodes */
16821759
static inline bool op_unimp(rv_insn_t *ir UNUSED, uint32_t insn UNUSED)
@@ -1710,11 +1787,11 @@ bool rv_decode(rv_insn_t *ir, uint32_t insn)
17101787
static const decode_t rvc_jump_table[] = {
17111788
// 00 01 10 11
17121789
OP(caddi4spn), OP(caddi), OP(cslli), OP(unimp), // 000
1713-
OP(cfld), OP(cjal), OP(cfldsp), OP(unimp), // 001
1790+
OP(unimp), OP(cjal), OP(unimp), OP(unimp), // 001
17141791
OP(clw), OP(cli), OP(clwsp), OP(unimp), // 010
17151792
OP(cflw), OP(clui), OP(cflwsp), OP(unimp), // 011
17161793
OP(unimp), OP(cmisc_alu), OP(ccr), OP(unimp), // 100
1717-
OP(cfsd), OP(cj), OP(cfsdsp), OP(unimp), // 101
1794+
OP(unimp), OP(cj), OP(unimp), OP(unimp), // 101
17181795
OP(csw), OP(cbeqz), OP(cswsp), OP(unimp), // 110
17191796
OP(cfsw), OP(cbnez), OP(cfswsp), OP(unimp), // 111
17201797
};

src/decode.h

+7
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ enum op_field {
176176
_(cjalr, 1, 2, 1, ENC(rs1, rs2, rd)) \
177177
_(cadd, 0, 2, 1, ENC(rs1, rs2, rd)) \
178178
_(cswsp, 0, 2, 1, ENC(rs2)) \
179+
/* RV32FC Instruction */ \
180+
IIF(RV32_HAS(EXT_F))( \
181+
_(cflwsp, 0, 2, 1, ENC(rd)) \
182+
_(cfswsp, 0, 2, 1, ENC(rs2)) \
183+
_(cflw, 0, 2, 1, ENC(rs1, rd)) \
184+
_(cfsw, 0, 2, 1, ENC(rs1, rs2)) \
185+
) \
179186
)
180187
/* clang-format on */
181188

src/rv32_constopt.c

+16
Original file line numberDiff line numberDiff line change
@@ -979,3 +979,19 @@ CONSTOPT(cadd, {
979979
/* C.SWSP */
980980
CONSTOPT(cswsp, {})
981981
#endif
982+
983+
/* RV32FC Standard Extension */
984+
985+
#if RV32_HAS(EXT_F) && RV32_HAS(EXT_C)
986+
/* C.FLWSP */
987+
CONSTOPT(cflwsp, {})
988+
989+
/* C.FSWSP */
990+
CONSTOPT(cfswsp, {})
991+
992+
/* C.FLW */
993+
CONSTOPT(cflw, {})
994+
995+
/* C.FSW */
996+
CONSTOPT(cfsw, {})
997+
#endif

src/rv32_template.c

+46
Original file line numberDiff line numberDiff line change
@@ -2272,3 +2272,49 @@ RVOP(
22722272
st, S32, TMP1, TMP0, 0;
22732273
}))
22742274
#endif
2275+
2276+
#if RV32_HAS(EXT_C) && RV32_HAS(EXT_F)
2277+
/* C.FLWSP */
2278+
RVOP(
2279+
cflwsp,
2280+
{
2281+
const uint32_t addr = rv->X[rv_reg_sp] + ir->imm;
2282+
rv->F[ir->rd].v = rv->io.mem_read_w(addr);
2283+
},
2284+
GEN({
2285+
assert; /* FIXME: Implement */
2286+
}))
2287+
2288+
/* C.FSWSP */
2289+
RVOP(
2290+
cfswsp,
2291+
{
2292+
const uint32_t addr = rv->X[rv_reg_sp] + ir->imm;
2293+
rv->io.mem_write_w(addr, rv->F[ir->rs2].v);
2294+
},
2295+
GEN({
2296+
assert; /* FIXME: Implement */
2297+
}))
2298+
2299+
/* C.FLW */
2300+
RVOP(
2301+
cflw,
2302+
{
2303+
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
2304+
rv->F[ir->rd].v = rv->io.mem_read_w(addr);
2305+
},
2306+
GEN({
2307+
assert; /* FIXME: Implement */
2308+
}))
2309+
2310+
/* C.FSW */
2311+
RVOP(
2312+
cfsw,
2313+
{
2314+
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
2315+
rv->io.mem_write_w(addr, rv->F[ir->rs2].v);
2316+
},
2317+
GEN({
2318+
assert; /* FIXME: Implement */
2319+
}))
2320+
#endif

0 commit comments

Comments
 (0)