From 40998b44795970f2921819c79bdf180a19fa4613 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 4 Aug 2010 17:04:24 -0700 Subject: [PATCH] [xcc,pk,sim] Added first part of FP support In particular, FP loads, stores, and moves now work. --- riscv/decode.h | 24 ++++++++++++++++++++++++ riscv/execute.h | 26 ++++---------------------- riscv/insns/dmfc1.h | 0 riscv/insns/dmtc1.h | 0 riscv/insns/l_d.h | 2 ++ riscv/insns/l_s.h | 2 ++ riscv/insns/mfc1.h | 0 riscv/insns/mff_d.h | 3 +++ riscv/insns/mff_s.h | 2 ++ riscv/insns/mfhc1.h | 0 riscv/insns/mov_fmt.h | 2 ++ riscv/insns/mtc1.h | 0 riscv/insns/mtf_d.h | 3 +++ riscv/insns/mtf_s.h | 2 ++ riscv/insns/mthc1.h | 0 riscv/insns/s_d.h | 2 ++ riscv/insns/s_s.h | 2 ++ riscv/processor.cc | 6 ++++++ riscv/processor.h | 1 + riscv/trap.h | 8 ++++++++ 20 files changed, 63 insertions(+), 22 deletions(-) delete mode 100644 riscv/insns/dmfc1.h delete mode 100644 riscv/insns/dmtc1.h delete mode 100644 riscv/insns/mfc1.h create mode 100644 riscv/insns/mff_d.h create mode 100644 riscv/insns/mff_s.h delete mode 100644 riscv/insns/mfhc1.h delete mode 100644 riscv/insns/mtc1.h create mode 100644 riscv/insns/mtf_d.h create mode 100644 riscv/insns/mtf_s.h delete mode 100644 riscv/insns/mthc1.h diff --git a/riscv/decode.h b/riscv/decode.h index 40c79f7..1357b37 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -9,6 +9,13 @@ typedef unsigned int uint128_t __attribute__((mode(TI))); typedef int64_t sreg_t; typedef uint64_t reg_t; +union freg_t +{ + float sp; + double dp; + uint64_t bits; +}; + const int OPCODE_BITS = 7; const int JTYPE_OPCODE_BITS = 5; @@ -24,6 +31,7 @@ const int IMM_BITS = 12; const int TARGET_BITS = 27; const int SHAMT_BITS = 6; const int FUNCT_BITS = 3; +const int FFUNCT_BITS = 5; const int BIGIMM_BITS = 20; #define SR_ET 0x0000000000000001ULL @@ -69,12 +77,23 @@ struct btype_t unsigned opcode : OPCODE_BITS; }; +struct ftype_t +{ + unsigned rc : FPRID_BITS; + unsigned rd : FPRID_BITS; + unsigned ffunct : FFUNCT_BITS; + unsigned rb : FPRID_BITS; + unsigned ra : FPRID_BITS; + unsigned opcode : OPCODE_BITS; +}; + union insn_t { itype_t itype; jtype_t jtype; rtype_t rtype; btype_t btype; + ftype_t ftype; uint32_t bits; }; @@ -82,6 +101,10 @@ union insn_t #define RA R[insn.rtype.ra] #define RB R[insn.rtype.rb] #define RC R[insn.rtype.rc] +#define FRA FR[insn.ftype.ra] +#define FRB FR[insn.ftype.rb] +#define FRC FR[insn.ftype.rc] +#define FRD FR[insn.ftype.rd] #define BIGIMM insn.btype.bigimm #define IMM insn.itype.imm #define SIMM ((int32_t)((uint32_t)insn.itype.imm<<(32-IMM_BITS))>>(32-IMM_BITS)) @@ -92,6 +115,7 @@ union insn_t #define require_supervisor if(!(sr & SR_S)) throw trap_privileged_instruction #define require64 if(gprlen != 64) throw trap_illegal_instruction +#define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled #define cmp_trunc(reg) (reg_t(reg) << (64-gprlen)) static inline sreg_t sext32(int32_t arg) diff --git a/riscv/execute.h b/riscv/execute.h index 242786f..d5c69d7 100644 --- a/riscv/execute.h +++ b/riscv/execute.h @@ -235,7 +235,7 @@ switch((insn.bits >> 0x19) & 0x7f) { if((insn.bits & 0xfe007fff) == 0xd4000000) { - #include "insns/mfc1.h" + #include "insns/mff_s.h" break; } #include "insns/unimp.h" @@ -244,7 +244,7 @@ switch((insn.bits >> 0x19) & 0x7f) { if((insn.bits & 0xfe007fff) == 0xd4001000) { - #include "insns/dmfc1.h" + #include "insns/mff_d.h" break; } #include "insns/unimp.h" @@ -258,20 +258,11 @@ switch((insn.bits >> 0x19) & 0x7f) } #include "insns/unimp.h" } - case 0x3: - { - if((insn.bits & 0xfe007fff) == 0xd4003000) - { - #include "insns/mfhc1.h" - break; - } - #include "insns/unimp.h" - } case 0x4: { if((insn.bits & 0xfe007fff) == 0xd4004000) { - #include "insns/mtc1.h" + #include "insns/mtf_s.h" break; } #include "insns/unimp.h" @@ -280,7 +271,7 @@ switch((insn.bits >> 0x19) & 0x7f) { if((insn.bits & 0xfe007fff) == 0xd4005000) { - #include "insns/dmtc1.h" + #include "insns/mtf_d.h" break; } #include "insns/unimp.h" @@ -294,15 +285,6 @@ switch((insn.bits >> 0x19) & 0x7f) } #include "insns/unimp.h" } - case 0x7: - { - if((insn.bits & 0xfe007fff) == 0xd4007000) - { - #include "insns/mthc1.h" - break; - } - #include "insns/unimp.h" - } default: { #include "insns/unimp.h" diff --git a/riscv/insns/dmfc1.h b/riscv/insns/dmfc1.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/dmtc1.h b/riscv/insns/dmtc1.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/l_d.h b/riscv/insns/l_d.h index e69de29..279fff2 100644 --- a/riscv/insns/l_d.h +++ b/riscv/insns/l_d.h @@ -0,0 +1,2 @@ +require_fp; +FRA.bits = mmu.load_int64(RB+SIMM); diff --git a/riscv/insns/l_s.h b/riscv/insns/l_s.h index e69de29..11cdf18 100644 --- a/riscv/insns/l_s.h +++ b/riscv/insns/l_s.h @@ -0,0 +1,2 @@ +require_fp; +FRA.bits = mmu.load_int32(RB+SIMM); diff --git a/riscv/insns/mfc1.h b/riscv/insns/mfc1.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/mff_d.h b/riscv/insns/mff_d.h new file mode 100644 index 0000000..f1bb205 --- /dev/null +++ b/riscv/insns/mff_d.h @@ -0,0 +1,3 @@ +require64; +require_fp; +RA = FRB.bits; diff --git a/riscv/insns/mff_s.h b/riscv/insns/mff_s.h new file mode 100644 index 0000000..9e3b9c4 --- /dev/null +++ b/riscv/insns/mff_s.h @@ -0,0 +1,2 @@ +require_fp; +RA = sext32(FRB.bits); diff --git a/riscv/insns/mfhc1.h b/riscv/insns/mfhc1.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/mov_fmt.h b/riscv/insns/mov_fmt.h index e69de29..9bbde8a 100644 --- a/riscv/insns/mov_fmt.h +++ b/riscv/insns/mov_fmt.h @@ -0,0 +1,2 @@ +require_fp; +FRC = FRA; diff --git a/riscv/insns/mtc1.h b/riscv/insns/mtc1.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/mtf_d.h b/riscv/insns/mtf_d.h new file mode 100644 index 0000000..b0eeca9 --- /dev/null +++ b/riscv/insns/mtf_d.h @@ -0,0 +1,3 @@ +require64; +require_fp; +FRA.bits = RB; diff --git a/riscv/insns/mtf_s.h b/riscv/insns/mtf_s.h new file mode 100644 index 0000000..04f33fe --- /dev/null +++ b/riscv/insns/mtf_s.h @@ -0,0 +1,2 @@ +require_fp; +FRA.bits = RB; diff --git a/riscv/insns/mthc1.h b/riscv/insns/mthc1.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/s_d.h b/riscv/insns/s_d.h index e69de29..2d2f9c3 100644 --- a/riscv/insns/s_d.h +++ b/riscv/insns/s_d.h @@ -0,0 +1,2 @@ +require_fp; +mmu.store_uint64(RB+SIMM, FRA.bits); diff --git a/riscv/insns/s_s.h b/riscv/insns/s_s.h index e69de29..6c3006e 100644 --- a/riscv/insns/s_s.h +++ b/riscv/insns/s_s.h @@ -0,0 +1,2 @@ +require_fp; +mmu.store_uint32(RB+SIMM, FRA.bits); diff --git a/riscv/processor.cc b/riscv/processor.cc index ad8ee67..5751c70 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -11,6 +11,7 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz) : sim(_sim), mmu(_mem,_memsz) { memset(R,0,sizeof(R)); + memset(FR,0,sizeof(FR)); pc = 0; ebase = 0; epc = 0; @@ -19,6 +20,11 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz) memset(counters,0,sizeof(counters)); + // a few assumptions about endianness, including freg_t union + static_assert(BYTE_ORDER == LITTLE_ENDIAN); + static_assert(sizeof(freg_t) == 8); + static_assert(sizeof(reg_t) == 8); + static_assert(sizeof(insn_t) == 4); static_assert(sizeof(uint128_t) == 16 && sizeof(int128_t) == 16); } diff --git a/riscv/processor.h b/riscv/processor.h index 33ca939..652fa07 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -20,6 +20,7 @@ private: // architected state reg_t R[NGPR]; + freg_t FR[NFPR]; reg_t pc; reg_t epc; reg_t badvaddr; diff --git a/riscv/trap.h b/riscv/trap.h index 026cc76..d4400ea 100644 --- a/riscv/trap.h +++ b/riscv/trap.h @@ -4,12 +4,20 @@ #define TRAP_LIST \ DECLARE_TRAP(illegal_instruction), \ DECLARE_TRAP(privileged_instruction), \ + DECLARE_TRAP(fp_disabled), \ + DECLARE_TRAP(reserved0), \ DECLARE_TRAP(instruction_address_misaligned), \ DECLARE_TRAP(data_address_misaligned), \ DECLARE_TRAP(instruction_access_fault), \ DECLARE_TRAP(data_access_fault), \ DECLARE_TRAP(syscall), \ DECLARE_TRAP(breakpoint), \ + DECLARE_TRAP(reserved1), \ + DECLARE_TRAP(reserved2), \ + DECLARE_TRAP(reserved3), \ + DECLARE_TRAP(reserved4), \ + DECLARE_TRAP(reserved5), \ + DECLARE_TRAP(reserved6), \ DECLARE_TRAP(int0), \ DECLARE_TRAP(int1), \ DECLARE_TRAP(int2), \ -- 2.30.2