aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-08-04 17:04:24 -0700
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-08-04 17:04:24 -0700
commit40998b44795970f2921819c79bdf180a19fa4613 (patch)
tree5c486b1f673fc41e0aaa86b00d9ae7d1bb5dbbc1 /riscv
parent6b5af53e2b6d77ed2e6d1b437d397852fe29eb30 (diff)
downloadriscv-isa-sim-40998b44795970f2921819c79bdf180a19fa4613.zip
riscv-isa-sim-40998b44795970f2921819c79bdf180a19fa4613.tar.gz
riscv-isa-sim-40998b44795970f2921819c79bdf180a19fa4613.tar.bz2
[xcc,pk,sim] Added first part of FP support
In particular, FP loads, stores, and moves now work.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/decode.h24
-rw-r--r--riscv/execute.h26
-rw-r--r--riscv/insns/dmfc1.h0
-rw-r--r--riscv/insns/dmtc1.h0
-rw-r--r--riscv/insns/l_d.h2
-rw-r--r--riscv/insns/l_s.h2
-rw-r--r--riscv/insns/mfc1.h0
-rw-r--r--riscv/insns/mff_d.h3
-rw-r--r--riscv/insns/mff_s.h2
-rw-r--r--riscv/insns/mfhc1.h0
-rw-r--r--riscv/insns/mov_fmt.h2
-rw-r--r--riscv/insns/mtc1.h0
-rw-r--r--riscv/insns/mtf_d.h3
-rw-r--r--riscv/insns/mtf_s.h2
-rw-r--r--riscv/insns/mthc1.h0
-rw-r--r--riscv/insns/s_d.h2
-rw-r--r--riscv/insns/s_s.h2
-rw-r--r--riscv/processor.cc6
-rw-r--r--riscv/processor.h1
-rw-r--r--riscv/trap.h8
20 files changed, 63 insertions, 22 deletions
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
--- a/riscv/insns/dmfc1.h
+++ /dev/null
diff --git a/riscv/insns/dmtc1.h b/riscv/insns/dmtc1.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/dmtc1.h
+++ /dev/null
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
--- a/riscv/insns/mfc1.h
+++ /dev/null
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
--- a/riscv/insns/mfhc1.h
+++ /dev/null
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
--- a/riscv/insns/mtc1.h
+++ /dev/null
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
--- a/riscv/insns/mthc1.h
+++ /dev/null
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), \