Skip to content

Commit 0619c74

Browse files
author
Jingqing3948
committed
Add float instruction map
1 parent 55617ee commit 0619c74

File tree

5 files changed

+141
-9
lines changed

5 files changed

+141
-9
lines changed

src/machine/core.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ static InstructionFlags unsupported_inst_flags_to_check(Xlen xlen,
1919
flags_to_check |= IMF_AMO;
2020
if (!isa_word.contains('M'))
2121
flags_to_check |= IMF_MUL;
22+
if(!isa_word.contains('F'))
23+
flags_to_check |= (IMF_ALU_REQ_RD_F | IMF_ALU_REQ_RS_F | IMF_ALU_REQ_RT_F);
2224
return InstructionFlags(flags_to_check);
2325
}
2426

@@ -321,8 +323,9 @@ DecodeState Core::decode(const FetchInterstage &dt) {
321323
// When instruction does not specify register, it is set to x0 as operations on x0 have no
322324
// side effects (not even visualization).
323325
RegisterValue val_rs
324-
= (flags & IMF_ALU_RS_ID) ? uint64_t(size_t(num_rs)) : regs->read_gp(num_rs);
325-
RegisterValue val_rt = regs->read_gp(num_rt);
326+
= (flags & IMF_ALU_RS_ID) ? uint64_t(size_t(num_rs)) : (flags & IMF_ALU_REQ_RS_F) ? regs->read_fp(num_rs) : regs->read_gp(num_rs);
327+
RegisterValue val_rt
328+
= (flags & IMF_ALU_REQ_RT_F) ? regs->read_fp(num_rt) : regs->read_gp(num_rt);
326329
RegisterValue immediate_val = dt.inst.immediate();
327330
const bool regwrite = flags & IMF_REGWRITE;
328331

src/machine/instruction.cpp

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ static const ArgumentDesc arg_desc_list[] = {
6565
ArgumentDesc('s', 'g', 0, 0x1f, { { { 5, 15 } }, 0 }),
6666
// Source register 2 (rs2/rt)
6767
ArgumentDesc('t', 'g', 0, 0x1f, { { { 5, 20 } }, 0 }),
68+
// Float destination register (rd)
69+
ArgumentDesc('D', 'f', 0, 0x1f, { { { 5, 7 } }, 0 }),
70+
// Float source register 1 (rs1/rs)
71+
ArgumentDesc('S', 'f', 0, 0x1f, { { { 5, 15 } }, 0 }),
72+
// Float source register 1 (rs1/rs)
73+
ArgumentDesc('T', 'f', 0, 0x1f, { { { 5, 20 } }, 0 }),
6874
// I-type immediate for arithmetic instructions (12bits)
6975
ArgumentDesc('j', 'n', -0x800, 0x7ff, { { { 12, 20 } }, 0 }),
7076
// Shift for bit shift instructions (5bits)
@@ -368,6 +374,13 @@ static const struct InstructionMap LOAD_map[] = {
368374
IM_UNKNOWN,
369375
};
370376

377+
static const struct InstructionMap F_LOAD_map[] = {
378+
IM_UNKNOWN,
379+
IM_UNKNOWN,
380+
{"flw", IT_I, { .alu_op=AluOp::ADD }, AC_I32, nullptr, {"D", "o(s)"}, 0x2007, 0x707f, { .flags = FLAGS_ALU_I_LOAD | IMF_ALU_REQ_RD_F }, nullptr},
381+
{"fld", IT_I, { .alu_op=AluOp::ADD }, AC_I64, nullptr, {"D", "o(s)"}, 0x3007, 0x707f, { .flags = FLAGS_ALU_I_LOAD | IMF_ALU_REQ_RD_F }, nullptr},
382+
};
383+
371384
static const struct InstructionMap SRI_map[] = { // 0xfe00707f mask changed to 0xfc00707f to support RV64I
372385
{"srli", IT_I, { .alu_op=AluOp::SR }, NOMEM, nullptr, {"d", "s", ">"}, 0x00005013,0xfc00707f, { .flags = FLAGS_ALU_I }, nullptr}, // SRLI
373386
{"srai", IT_I, { .alu_op=AluOp::SR }, NOMEM, nullptr, {"d", "s", ">"}, 0x40005013,0xfc00707f, { .flags = (FLAGS_ALU_I | IMF_ALU_MOD) }, nullptr}, // SRAI
@@ -395,6 +408,13 @@ static const struct InstructionMap STORE_map[] = {
395408
IM_UNKNOWN,
396409
};
397410

411+
static const struct InstructionMap F_STORE_map[] = {
412+
IM_UNKNOWN,
413+
IM_UNKNOWN,
414+
{"fsw", IT_I, { .alu_op=AluOp::ADD }, AC_U32, nullptr, {"T", "q(s)"}, 0x2027, 0x707f, { .flags = FLAGS_ALU_I_STORE | IMF_ALU_REQ_RT_F }, nullptr}, // FSW
415+
{"fsd", IT_I, { .alu_op=AluOp::ADD }, AC_U64, nullptr, {"T", "q(s)"}, 0x3027, 0x707f, { .flags = FLAGS_ALU_I_STORE | IMF_ALU_REQ_RT_F }, nullptr}, // FSD
416+
};
417+
398418
static const struct InstructionMap ADD_map[] = {
399419
{"add", IT_R, { .alu_op=AluOp::ADD }, NOMEM, nullptr, {"d", "s", "t"}, 0x00000033, 0xfe00707f, { .flags = FLAGS_ALU_T_R_STD }, nullptr},
400420
{"sub", IT_R, { .alu_op=AluOp::ADD }, NOMEM, nullptr, {"d", "s", "t"}, 0x40000033, 0xfe00707f, { .flags = FLAGS_ALU_T_R_STD | IMF_ALU_MOD }, inst_aliases_sub},
@@ -578,28 +598,96 @@ static const struct InstructionMap OP_32_map[] = {
578598

579599
// Full, uncomprese, instructions top level map
580600

601+
static const struct InstructionMap F_sgnj_map[] = {
602+
{"fsgnj.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x20000053, 0xfe00707f, {}, nullptr},
603+
{"fsgnjn.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x20001053, 0xfe00707f, {}, nullptr},
604+
{"fsgnjx.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x20002053, 0xfe00707f, {}, nullptr},
605+
IM_UNKNOWN,
606+
IM_UNKNOWN,
607+
IM_UNKNOWN,
608+
IM_UNKNOWN,
609+
IM_UNKNOWN,
610+
};
611+
612+
static const struct InstructionMap F_ex_map[] = {
613+
{"fmin.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x28000053, 0xfe00707f, {}, nullptr},
614+
{"fmax.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x28001053, 0xfe00707f, {}, nullptr},
615+
};
616+
617+
static const struct InstructionMap F_cvt_w_s_map[] = {
618+
{"fcvt.w.s",IT_I, NOALU, NOMEM, nullptr, {}, 0xc0000053, 0xfff0007f, {}, nullptr},
619+
{"fcvt.wu.s",IT_I, NOALU, NOMEM, nullptr, {}, 0xc0100053, 0xfff0007f, {}, nullptr},
620+
};
621+
622+
static const struct InstructionMap F_cp_map[] = {
623+
{"fle.s",IT_I, NOALU, NOMEM, nullptr, {}, 0xa0002053, 0xfe00707f, {}, nullptr},
624+
{"flt.s",IT_I, NOALU, NOMEM, nullptr, {}, 0xa0001053, 0xfe00707f, {}, nullptr},
625+
{"feq.s",IT_I, NOALU, NOMEM, nullptr, {}, 0xa0000053, 0xfe00707f, {}, nullptr},
626+
IM_UNKNOWN,
627+
};
628+
629+
static const struct InstructionMap F_cvt_s_w_map[] = {
630+
{"fcvt.s.w",IT_I, NOALU, NOMEM, nullptr, {}, 0xd0000053, 0xfff0007f, {}, nullptr},
631+
{"fcvt.s.wu",IT_I, NOALU, NOMEM, nullptr, {}, 0xd0100053, 0xfff0007f, {}, nullptr},
632+
};
633+
634+
static const struct InstructionMap F_inst_map[] = {
635+
{"fadd.s",IT_I, { .alu_op=AluOp::ADD }, NOMEM, nullptr, {"D", "S", "T"}, 0x53, 0xfe00007f, { .flags = FLAGS_ALU_T_R_STD | IMF_ALU_REQ_RT_F | IMF_ALU_REQ_RS_F | IMF_ALU_REQ_RD_F }, nullptr},
636+
{"fsub.s",IT_I, NOALU, NOMEM, nullptr, {"D", "S", "T"}, 0x8000053, 0xfe00007f, { .flags = FLAGS_ALU_T_R_STD | IMF_ALU_REQ_RT_F | IMF_ALU_REQ_RS_F | IMF_ALU_REQ_RD_F | IMF_ALU_MOD}, nullptr},
637+
{"fmul.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x10000053, 0xfe00007f, {}, nullptr},
638+
{"fdiv.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x18000053, 0xfe00007f, {}, nullptr},
639+
{"fsgnj",IT_I, NOALU, NOMEM, F_sgnj_map, {}, 0x20000053, 0xfe00007f, { .subfield = {3, 12} }, nullptr},
640+
{"f-ex.s",IT_I, NOALU, NOMEM, F_ex_map, {}, 0x28000053, 0xfe00007f, { .subfield = {1, 12} }, nullptr},
641+
IM_UNKNOWN,
642+
IM_UNKNOWN,
643+
IM_UNKNOWN,
644+
IM_UNKNOWN,
645+
IM_UNKNOWN,
646+
{"fsqrt.s",IT_I, NOALU, NOMEM, nullptr, {}, 0x58000053, 0xfe00007f, {}, nullptr},
647+
IM_UNKNOWN,
648+
IM_UNKNOWN,
649+
IM_UNKNOWN,
650+
IM_UNKNOWN,
651+
IM_UNKNOWN,
652+
IM_UNKNOWN,
653+
IM_UNKNOWN,
654+
IM_UNKNOWN,
655+
{"f-cp",IT_I, NOALU, NOMEM, F_cp_map, {}, 0xa0000053, 0xfe00007f, { .subfield = {2, 12} }, nullptr},
656+
IM_UNKNOWN,
657+
IM_UNKNOWN,
658+
IM_UNKNOWN,
659+
{"fcvt-w-s",IT_I, NOALU, NOMEM, F_cvt_w_s_map, {}, 0xc0000053, 0xfe00007f, { .subfield = {1, 20} }, nullptr},
660+
IM_UNKNOWN,
661+
{"fcvt-s-w",IT_I, NOALU, NOMEM, F_cvt_s_w_map, {}, 0xd0000053, 0xfe00007f, { .subfield = {1, 20} }, nullptr},
662+
IM_UNKNOWN,
663+
{"fmv.x.w",IT_I, { .alu_op=AluOp::ADD }, AC_I32, nullptr, {"d", "S"}, 0xe0000053, 0xfe00007f, {}, nullptr},
664+
IM_UNKNOWN,
665+
{"fmv.w.x",IT_I, { .alu_op=AluOp::ADD }, AC_I32, nullptr, {"D", "s"}, 0xf0000053, 0xfe00007f, {}, nullptr},
666+
IM_UNKNOWN,
667+
};
668+
581669
static const struct InstructionMap I_inst_map[] = {
582670
{"load", IT_I, NOALU, NOMEM, LOAD_map, {}, 0x03, 0x7f, { .subfield = {3, 12} }, nullptr}, // LOAD
583-
IM_UNKNOWN, // LOAD-FP
671+
{"load-fp", IT_I, NOALU, NOMEM, F_LOAD_map, {}, 0x07, 0x7f, { .subfield = {2, 12} }, nullptr}, // LOAD-FP
584672
IM_UNKNOWN, // custom-0
585673
{"misc-mem", IT_I, NOALU, NOMEM, MISC_MEM_map, {}, 0x0f, 0x7f, { .subfield = {3, 12} }, nullptr}, // MISC-MEM
586674
{"op-imm", IT_I, NOALU, NOMEM, OP_IMM_map, {}, 0x13, 0x7f, { .subfield = {3, 12} }, nullptr}, // OP-IMM
587675
{"auipc", IT_U, { .alu_op=AluOp::ADD }, NOMEM, nullptr, {"d", "u"}, 0x17, 0x7f, { .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_PC_TO_ALU }, nullptr}, // AUIPC
588676
{"op-imm-32", IT_I, NOALU, NOMEM, OP_IMM_32_map, {}, 0x1b, 0x7f, { .subfield = {3, 12} }, nullptr}, // OP-IMM-32 IM_UNKNOWN, // OP-IMM-32
589677
IM_UNKNOWN, // 48b
590678
{"store", IT_I, NOALU, NOMEM, STORE_map, {}, 0x23, 0x7f, { .subfield = {3, 12} }, nullptr}, // STORE
591-
IM_UNKNOWN, // STORE-FP
679+
{"store-fp", IT_I, NOALU, NOMEM, F_STORE_map, {}, 0x27, 0x7f, { .subfield = {2, 12} }, nullptr}, // STORE-FP
592680
IM_UNKNOWN, // custom-1
593681
{"amo", IT_R, NOALU, NOMEM, AMO_map, {}, 0x2f, 0x7f, { .subfield = {3, 12} }, nullptr}, // OP-32
594682
{"op", IT_R, NOALU, NOMEM, OP_map, {}, 0x33, 0x7f, { .subfield = {1, 25} }, nullptr}, // OP
595683
{"lui", IT_U, { .alu_op=AluOp::ADD }, NOMEM, nullptr, {"d", "u"}, 0x37, 0x7f, { .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE }, nullptr}, // LUI
596684
{"op-32", IT_R, NOALU, NOMEM, OP_32_map, {}, 0x3b, 0x7f, { .subfield = {1, 25} }, nullptr}, // OP-32
597685
IM_UNKNOWN, // 64b
598-
IM_UNKNOWN, // MADD
599-
IM_UNKNOWN, // MSUB
600-
IM_UNKNOWN, // NMSUB
601-
IM_UNKNOWN, // NMADD
602-
IM_UNKNOWN, // OP-FP
686+
{"fmadd.s", IT_I, NOALU, NOMEM, nullptr, {}, 0x43, 0x7f, {}, nullptr}, // FMADD.S
687+
{"fmsub.s", IT_I, NOALU, NOMEM, nullptr, {}, 0x47, 0x7f, {}, nullptr}, // FMSUB.S
688+
{"fnmsub.s", IT_I, NOALU, NOMEM, nullptr, {}, 0x4b, 0x7f, {}, nullptr}, // FNMSUB.S
689+
{"fnmadd.s", IT_I, NOALU, NOMEM, nullptr, {}, 0x4f, 0x7f, {}, nullptr}, // FNMADD.S
690+
{"op-fp",IT_I, NOALU, NOMEM, F_inst_map, {}, 0x600007f, 0x7f, { .subfield={5,27} }, nullptr}, // OP-FP
603691
IM_UNKNOWN, // reserved
604692
IM_UNKNOWN, // custom-2/rv128
605693
IM_UNKNOWN, // 48b
@@ -804,6 +892,14 @@ QString Instruction::to_str(Address inst_addr) const {
804892
}
805893
break;
806894
}
895+
case 'f': {
896+
if (symbolic_registers_enabled) {
897+
res += QString(Rv_regnames[field]);
898+
} else {
899+
res += "f" + QString::number(field);
900+
}
901+
break;
902+
}
807903
case 'p':
808904
case 'a': {
809905
field += (int32_t)inst_addr.get_raw();

src/machine/instruction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ enum InstructionFlags : unsigned {
6060
// TODO do we want to add those signals to the visualization?
6161

6262
IMF_RV64 = 1L << 24, /**< Mark instructions which are available in 64-bit mode only. */
63+
64+
// RV64/32F
65+
IMF_ALU_REQ_RS_F = 1L << 25, /** < Execution phase/ALU/mem requires RS value in Float Reg*/
66+
IMF_ALU_REQ_RT_F = 1L << 26, /**< Execution phase/ALU/mem requires RT value in Float Reg*/
67+
IMF_ALU_REQ_RD_F = 1L << 27, /**< Execution phase/ALU/mem requires RD value in Float Reg*/
6368
};
6469

6570
/**

src/machine/registers.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Registers::Registers() : QObject() {
1919
Registers::Registers(const Registers &orig) : QObject() {
2020
this->pc = orig.read_pc();
2121
this->gp = orig.gp;
22+
this->fp = orig.fp;
2223
}
2324

2425
Address Registers::read_pc() const {
@@ -54,6 +55,17 @@ void Registers::write_gp(RegisterId reg, RegisterValue value) {
5455
emit gp_update(reg, value);
5556
}
5657

58+
RegisterValue Registers::read_fp(RegisterId reg) const {
59+
RegisterValue value = this->fp.at(reg);
60+
emit gp_read(reg, value);
61+
return value;
62+
}
63+
64+
void Registers::write_fp(RegisterId reg, RegisterValue value) {
65+
this->fp.at(reg) = value;
66+
emit fp_update(reg, value);
67+
}
68+
5769
bool Registers::operator==(const Registers &c) const {
5870
if (read_pc() != c.read_pc()) { return false; }
5971
if (this->gp != c.gp) { return false; }
@@ -69,6 +81,9 @@ void Registers::reset() {
6981
for (int i = 1; i < 32; i++) {
7082
write_gp(i, 0);
7183
}
84+
for (int i = 1; i < 32; i++) {
85+
write_fp(i, 0);
86+
}
7287
write_gp(2_reg, SP_INIT.get_raw()); // initialize to safe RAM area -
7388
// corresponds to Linux
7489
}

src/machine/registers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ namespace machine {
1616
*/
1717
constexpr size_t REGISTER_COUNT = 32;
1818

19+
/**
20+
* Float register count
21+
*/
22+
constexpr size_t FLOAT_REGISTER_COUNT = 32;
23+
1924
/**
2025
* General-purpose register identifier
2126
*/
@@ -63,6 +68,9 @@ class Registers : public QObject {
6368
void write_gp(RegisterId reg, RegisterValue value); // Write general-purpose
6469
// register
6570

71+
RegisterValue read_fp(RegisterId reg) const; // Read floating-point register
72+
void write_fp(RegisterId reg, RegisterValue value); // Write floating-point register
73+
6674
bool operator==(const Registers &c) const;
6775
bool operator!=(const Registers &c) const;
6876

@@ -72,6 +80,7 @@ class Registers : public QObject {
7280
void pc_update(Address val);
7381
void gp_update(RegisterId reg, RegisterValue val);
7482
void gp_read(RegisterId reg, RegisterValue val) const;
83+
void fp_update(RegisterId reg, RegisterValue val);
7584

7685
private:
7786
/**
@@ -81,6 +90,10 @@ class Registers : public QObject {
8190
* Getters and setters will never try to read or write zero register.
8291
*/
8392
std::array<RegisterValue, REGISTER_COUNT> gp {};
93+
/**
94+
* Float registers
95+
*/
96+
std::array<RegisterValue, FLOAT_REGISTER_COUNT> fp {};
8497
Address pc {}; // program counter
8598
};
8699

0 commit comments

Comments
 (0)