[xcc,pk,sim] Added first part of FP support
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Thu, 5 Aug 2010 00:04:24 +0000 (17:04 -0700)
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Thu, 5 Aug 2010 00:04:24 +0000 (17:04 -0700)
In particular, FP loads, stores, and moves now work.

20 files changed:
riscv/decode.h
riscv/execute.h
riscv/insns/dmfc1.h [deleted file]
riscv/insns/dmtc1.h [deleted file]
riscv/insns/l_d.h
riscv/insns/l_s.h
riscv/insns/mfc1.h [deleted file]
riscv/insns/mff_d.h [new file with mode: 0644]
riscv/insns/mff_s.h [new file with mode: 0644]
riscv/insns/mfhc1.h [deleted file]
riscv/insns/mov_fmt.h
riscv/insns/mtc1.h [deleted file]
riscv/insns/mtf_d.h [new file with mode: 0644]
riscv/insns/mtf_s.h [new file with mode: 0644]
riscv/insns/mthc1.h [deleted file]
riscv/insns/s_d.h
riscv/insns/s_s.h
riscv/processor.cc
riscv/processor.h
riscv/trap.h

index 40c79f72ca23cc75cb371a6391d44520a18f08e1..1357b37e781956284d66bf3a16fa7efa8159c4b9 100644 (file)
@@ -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)
index 242786fe36317d77361c7a952a243ad083468d68..d5c69d742546c2e9546b4c895dc4e36a2fb257be 100644 (file)
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/dmtc1.h b/riscv/insns/dmtc1.h
deleted file mode 100644 (file)
index e69de29..0000000
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..279fff2f92f93765aa5289e99ca1aa2e3592534e 100644 (file)
@@ -0,0 +1,2 @@
+require_fp;
+FRA.bits = mmu.load_int64(RB+SIMM);
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..11cdf182ea2259d1a4f5ddeb6be7feda6559e566 100644 (file)
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/mff_d.h b/riscv/insns/mff_d.h
new file mode 100644 (file)
index 0000000..f1bb205
--- /dev/null
@@ -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 (file)
index 0000000..9e3b9c4
--- /dev/null
@@ -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 (file)
index e69de29..0000000
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9bbde8a04ae10c768f99b0d6663a86f4f0ca84df 100644 (file)
@@ -0,0 +1,2 @@
+require_fp;
+FRC = FRA;
diff --git a/riscv/insns/mtc1.h b/riscv/insns/mtc1.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/mtf_d.h b/riscv/insns/mtf_d.h
new file mode 100644 (file)
index 0000000..b0eeca9
--- /dev/null
@@ -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 (file)
index 0000000..04f33fe
--- /dev/null
@@ -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 (file)
index e69de29..0000000
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2d2f9c342b4c4745b77c4f3623f728f75fa1f063 100644 (file)
@@ -0,0 +1,2 @@
+require_fp;
+mmu.store_uint64(RB+SIMM, FRA.bits);
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6c3006ecfa7fd3fd3fb6f5deccd841f52c712e04 100644 (file)
@@ -0,0 +1,2 @@
+require_fp;
+mmu.store_uint32(RB+SIMM, FRA.bits);
index ad8ee67b32a7ed3fd073abd44d8f2577c98a001c..5751c70006e2f2dc02d62857ea4bdbf12b14caff 100644 (file)
@@ -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);
 }
index 33ca93921efcce200f7a3eba37dd6260530a2172..652fa07c6a4cc5b4ee2aaf8d06cc25f21a279140 100644 (file)
@@ -20,6 +20,7 @@ private:
 
   // architected state
   reg_t R[NGPR];
+  freg_t FR[NFPR];
   reg_t pc;
   reg_t epc;
   reg_t badvaddr;
index 026cc76ece42d6f3b6e6c55861dd950049bbc844..d4400eafea30ead1dff1f3dff1f2b4032cb85105 100644 (file)
@@ -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), \