[xcc] minor performance tweaks
[riscv-isa-sim.git] / riscv / decode.h
index 7638de90b9926b45f72a376ada0a204d1ab886f8..2078e58ae2cc028e1b5959a9f04ca0ce2abf4a62 100644 (file)
@@ -45,6 +45,7 @@ const int JUMP_ALIGN_BITS = 1;
 #define SR_VM    0x0000000000010000ULL
 #define SR_ZERO  ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_UX|SR_SX|SR_IM|SR_VM)
 #define SR_IM_SHIFT 8
+#define IPI_IRQ 5
 #define TIMER_IRQ 7
 
 #define CAUSE_EXCCODE 0x000000FF
@@ -142,30 +143,29 @@ union insn_t
   uint32_t bits;
 };
 
-#if 0
 #include <stdio.h>
-class trace_writeback
+class do_writeback
 {
 public:
-  trace_writeback(reg_t* _rf, int _rd) : rf(_rf), rd(_rd) {}
+  do_writeback(reg_t* _rf, int _rd) : rf(_rf), rd(_rd) {}
 
-  reg_t operator = (reg_t rhs)
+  const do_writeback& operator = (reg_t rhs)
   {
+#if 0
     printf("R[%x] <= %llx\n",rd,(long long)rhs);
+#endif
     rf[rd] = rhs;
-    return rhs;
+    rf[0] = 0;
+    return *this;
   }
 
+  operator reg_t() { return rf[rd]; }
+
 private:
   reg_t* rf;
   int rd;
 };
 
-#define do_writeback(rf,rd) trace_writeback(rf,rd)
-#else
-#define do_writeback(rf,rd) rf[rd]
-#endif
-
 #define throw_illegal_instruction \
   ({ if (utmode) throw trap_vector_illegal_instruction; \
      else throw trap_illegal_instruction; })
@@ -192,11 +192,11 @@ private:
               if(rm > 4) throw_illegal_instruction; \
               rm; })
 
-#define require_supervisor if(!(sr & SR_S)) throw trap_privileged_instruction
+#define require_supervisor if(unlikely(!(sr & SR_S))) throw trap_privileged_instruction
 #define xpr64 (xprlen == 64)
-#define require_xpr64 if(!xpr64) throw_illegal_instruction
-#define require_xpr32 if(xpr64) throw_illegal_instruction
-#define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled
+#define require_xpr64 if(unlikely(!xpr64)) throw_illegal_instruction
+#define require_xpr32 if(unlikely(xpr64)) throw_illegal_instruction
+#define require_fp if(unlikely(!(sr & SR_EF))) throw trap_fp_disabled
 #define require_vector \
   ({ if(!(sr & SR_EV)) throw trap_vector_disabled; \
     else if (!utmode && (vecbanks_count < 3)) throw trap_vector_bank; \
@@ -206,17 +206,30 @@ private:
                                (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
                              softfloat_exceptionFlags = 0; })
 
-#define require_rvc if(!(sr & SR_EC)) throw_illegal_instruction
-#define insn_length(x) (((x).bits & 0x3) < 0x3 ? 2 : 4)
-
 #define sext32(x) ((sreg_t)(int32_t)(x))
 #define zext32(x) ((reg_t)(uint32_t)(x))
 #define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen))
 #define zext_xprlen(x) ((reg_t(x) << (64-xprlen)) >> (64-xprlen))
 
+#ifndef RISCV_ENABLE_RVC
+# define set_pc(x) \
+  do { if((x) & (sizeof(insn_t)-1)) \
+       { badvaddr = (x); throw trap_instruction_address_misaligned; } \
+       npc = (x); \
+     } while(0)
+#else
+# define set_pc(x) \
+  do { if((x) & ((sr & SR_EC) ? 1 : 3)) \
+       { badvaddr = (x); throw trap_instruction_address_misaligned; } \
+       npc = (x); \
+     } while(0)
+#endif
+
 // RVC stuff
 
 #define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
+#define insn_length(x) (INSN_IS_RVC(x) ? 2 : 4)
+#define require_rvc if(!(sr & SR_EC)) throw_illegal_instruction
 
 #define CRD_REGNUM ((insn.bits >> 5) & 0x1f)
 #define CRD do_writeback(XPR, CRD_REGNUM)