Browse Source

[opcodes, sim, xcc] made *w insns illegal in RV32

now generic variants behave differently in RV32 and RV64.
cs250
Andrew Waterman 16 years ago
parent
commit
21ce327f5d
  1. 57
      riscv/decode.h
  2. 10
      riscv/execute.h
  3. 3
      riscv/insns/add.h
  4. 3
      riscv/insns/addi.h
  5. 1
      riscv/insns/addiw.h
  6. 2
      riscv/insns/addw.h
  7. 2
      riscv/insns/amo_add.h
  8. 2
      riscv/insns/amo_and.h
  9. 2
      riscv/insns/amo_max.h
  10. 2
      riscv/insns/amo_maxu.h
  11. 2
      riscv/insns/amo_min.h
  12. 2
      riscv/insns/amo_minu.h
  13. 2
      riscv/insns/amo_or.h
  14. 2
      riscv/insns/amo_swap.h
  15. 2
      riscv/insns/cvt_d_l.h
  16. 2
      riscv/insns/cvt_l_d.h
  17. 2
      riscv/insns/cvt_l_s.h
  18. 2
      riscv/insns/cvt_s_l.h
  19. 2
      riscv/insns/cvtu_d_l.h
  20. 2
      riscv/insns/cvtu_l_d.h
  21. 2
      riscv/insns/cvtu_l_s.h
  22. 2
      riscv/insns/cvtu_s_l.h
  23. 10
      riscv/insns/div.h
  24. 3
      riscv/insns/divu.h
  25. 7
      riscv/insns/divuw.h
  26. 9
      riscv/insns/divw.h
  27. 2
      riscv/insns/ld.h
  28. 2
      riscv/insns/mfcr.h
  29. 2
      riscv/insns/mff_d.h
  30. 2
      riscv/insns/mfpcr.h
  31. 2
      riscv/insns/mtf_d.h
  32. 3
      riscv/insns/mul.h
  33. 12
      riscv/insns/mulh.h
  34. 6
      riscv/insns/mulhu.h
  35. 2
      riscv/insns/mulhuw.h
  36. 2
      riscv/insns/mulhw.h
  37. 2
      riscv/insns/mulw.h
  38. 7
      riscv/insns/rem.h
  39. 5
      riscv/insns/remu.h
  40. 7
      riscv/insns/remuw.h
  41. 9
      riscv/insns/remw.h
  42. 2
      riscv/insns/sd.h
  43. 3
      riscv/insns/sll.h
  44. 10
      riscv/insns/slli.h
  45. 1
      riscv/insns/slliw.h
  46. 1
      riscv/insns/sllw.h
  47. 3
      riscv/insns/sra.h
  48. 10
      riscv/insns/srai.h
  49. 1
      riscv/insns/sraiw.h
  50. 1
      riscv/insns/sraw.h
  51. 6
      riscv/insns/srl.h
  52. 10
      riscv/insns/srli.h
  53. 1
      riscv/insns/srliw.h
  54. 1
      riscv/insns/srlw.h
  55. 3
      riscv/insns/sub.h
  56. 1
      riscv/insns/subw.h
  57. 22
      riscv/processor.cc
  58. 8
      riscv/processor.h
  59. 6
      riscv/sim.cc

57
riscv/decode.h

@ -6,19 +6,6 @@
#include "config.h"
#ifdef RISCV_ENABLE_64BIT
# define support_64bit 1
#else
# define support_64bit 0
#endif
#ifdef RISCV_ENABLE_FPU
# define support_fp 1
#else
# define support_fp 0
#endif
typedef int int128_t __attribute__((mode(TI)));
typedef unsigned int uint128_t __attribute__((mode(TI)));
@ -28,9 +15,8 @@ typedef uint64_t freg_t;
const int OPCODE_BITS = 7;
const int GPR_BITS = 8*sizeof(reg_t);
const int GPRID_BITS = 5;
const int NGPR = 1 << GPRID_BITS;
const int XPRID_BITS = 5;
const int NXPR = 1 << XPRID_BITS;
const int FPR_BITS = 64;
const int FPRID_BITS = 5;
@ -87,8 +73,8 @@ struct itype_t
unsigned opcode : OPCODE_BITS;
unsigned funct : FUNCT_BITS;
signed imm12 : IMM_BITS;
unsigned rs1 : GPRID_BITS;
unsigned rd : GPRID_BITS;
unsigned rs1 : XPRID_BITS;
unsigned rd : XPRID_BITS;
};
struct btype_t
@ -96,8 +82,8 @@ struct btype_t
unsigned opcode : OPCODE_BITS;
unsigned funct : FUNCT_BITS;
unsigned immlo : IMMLO_BITS;
unsigned rs2 : GPRID_BITS;
unsigned rs1 : GPRID_BITS;
unsigned rs2 : XPRID_BITS;
unsigned rs1 : XPRID_BITS;
signed immhi : IMM_BITS-IMMLO_BITS;
};
@ -112,16 +98,16 @@ struct rtype_t
unsigned opcode : OPCODE_BITS;
unsigned funct : FUNCT_BITS;
unsigned functr : FUNCTR_BITS;
unsigned rs2 : GPRID_BITS;
unsigned rs1 : GPRID_BITS;
unsigned rd : GPRID_BITS;
unsigned rs2 : XPRID_BITS;
unsigned rs1 : XPRID_BITS;
unsigned rd : XPRID_BITS;
};
struct ltype_t
{
unsigned opcode : OPCODE_BITS;
unsigned bigimm : BIGIMM_BITS;
unsigned rd : GPRID_BITS;
unsigned rd : XPRID_BITS;
};
struct ftype_t
@ -170,14 +156,14 @@ private:
#endif
// helpful macros, etc
#define RS1 R[insn.rtype.rs1]
#define RS2 R[insn.rtype.rs2]
#define RD do_writeback(R,insn.rtype.rd)
#define RA do_writeback(R,1)
#define FRS1 FR[insn.ftype.rs1]
#define FRS2 FR[insn.ftype.rs2]
#define FRS3 FR[insn.ftype.rs3]
#define FRD FR[insn.ftype.rd]
#define RS1 XPR[insn.rtype.rs1]
#define RS2 XPR[insn.rtype.rs2]
#define RD do_writeback(XPR,insn.rtype.rd)
#define RA do_writeback(XPR,1)
#define FRS1 FPR[insn.ftype.rs1]
#define FRS2 FPR[insn.ftype.rs2]
#define FRS3 FPR[insn.ftype.rs3]
#define FRD FPR[insn.ftype.rd]
#define BIGIMM insn.ltype.bigimm
#define SIMM insn.itype.imm12
#define BIMM ((signed)insn.btype.immlo | (insn.btype.immhi << IMMLO_BITS))
@ -190,9 +176,10 @@ private:
((fsr & FSR_RD) >> FSR_RD_SHIFT))
#define require_supervisor if(!(sr & SR_S)) throw trap_privileged_instruction
#define require64 if(gprlen != 64) throw trap_illegal_instruction
#define xpr64 (xprlen == 64)
#define require_xpr64 if(!xpr64) throw trap_illegal_instruction
#define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled
#define cmp_trunc(reg) (reg_t(reg) << (64-gprlen))
#define cmp_trunc(reg) (reg_t(reg) << (64-xprlen))
#define set_fp_exceptions ({ set_fsr(fsr | \
(softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
softfloat_exceptionFlags = 0; })
@ -202,4 +189,6 @@ static inline sreg_t sext32(int32_t arg)
return arg;
}
#define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen))
#endif

10
riscv/execute.h

@ -768,11 +768,6 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/divuw.h"
break;
}
if((insn.bits & 0x1ffff) == 0xcf7)
{
#include "insns/mulhuw.h"
break;
}
if((insn.bits & 0x1ffff) == 0xf7)
{
#include "insns/mulw.h"
@ -783,11 +778,6 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/remw.h"
break;
}
if((insn.bits & 0x1ffff) == 0x8f7)
{
#include "insns/mulhw.h"
break;
}
if((insn.bits & 0x1ffff) == 0x10f7)
{
#include "insns/divw.h"

3
riscv/insns/add.h

@ -1,2 +1 @@
require64;
RD = RS1 + RS2;
RD = sext_xprlen(RS1 + RS2);

3
riscv/insns/addi.h

@ -1,2 +1 @@
require64;
RD = SIMM + RS1;
RD = sext_xprlen(RS1 + SIMM);

1
riscv/insns/addiw.h

@ -1 +1,2 @@
require_xpr64;
RD = sext32(SIMM + RS1);

2
riscv/insns/addw.h

@ -1,2 +1,2 @@
require_xpr64;
RD = sext32(RS1 + RS2);

2
riscv/insns/amo_add.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2 + v);
RD = v;

2
riscv/insns/amo_and.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2 & v);
RD = v;

2
riscv/insns/amo_max.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
sreg_t v = mmu.load_int64(RS1);
mmu.store_uint64(RS1, std::max(sreg_t(RS2),v));
RD = v;

2
riscv/insns/amo_maxu.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, std::max(RS2,v));
RD = v;

2
riscv/insns/amo_min.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
sreg_t v = mmu.load_int64(RS1);
mmu.store_uint64(RS1, std::min(sreg_t(RS2),v));
RD = v;

2
riscv/insns/amo_minu.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, std::min(RS2,v));
RD = v;

2
riscv/insns/amo_or.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2 | v);
RD = v;

2
riscv/insns/amo_swap.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2);
RD = v;

2
riscv/insns/cvt_d_l.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f64(RS1);

2
riscv/insns/cvt_l_d.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f64_to_i64_r_minMag(FRS1,true);

2
riscv/insns/cvt_l_s.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f32_to_i64_r_minMag(FRS1,true);

2
riscv/insns/cvt_s_l.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f32(RS1);

2
riscv/insns/cvtu_d_l.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f64(RS1);

2
riscv/insns/cvtu_l_d.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f64_to_i64_r_minMag(FRS1,true);

2
riscv/insns/cvtu_l_s.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f32_to_i64_r_minMag(FRS1,true);

2
riscv/insns/cvtu_s_l.h

@ -1,4 +1,4 @@
require64;
require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f32(RS1);

10
riscv/insns/div.h

@ -1,5 +1,9 @@
require64;
if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1))
RD = sreg_t(RS1) < 0 ? INT64_MIN : INT64_MAX;
{
if(xpr64)
RD = sreg_t(RS1) < 0 ? INT64_MIN : INT64_MAX;
else
RD = sreg_t(RS1) < 0 ? sext32(INT32_MIN) : INT32_MAX;
}
else
RD = sreg_t(RS1) / sreg_t(RS2);
RD = sext_xprlen(sreg_t(RS1) / sreg_t(RS2));

3
riscv/insns/divu.h

@ -1,5 +1,4 @@
require64;
if(RS2 == 0)
RD = UINT64_MAX;
else
RD = RS1 / RS2;
RD = sext_xprlen(RS1 / RS2);

7
riscv/insns/divuw.h

@ -1,4 +1,5 @@
if(uint32_t(RS2) == 0)
RD = sext32(UINT32_MAX);
require_xpr64;
if(RS2 == 0)
RD = UINT64_MAX;
else
RD = sext32(uint32_t(RS1)/uint32_t(RS2));
RD = sext32(RS1 / RS2);

9
riscv/insns/divw.h

@ -1,4 +1,7 @@
if(int32_t(RS2) == 0 || (int32_t(RS1) == INT32_MIN && int32_t(RS2) == -1))
RD = sext32(int32_t(RS1) < 0 ? INT32_MIN : INT32_MAX);
require_xpr64;
// INT64_MIN/-1 corner case shouldn't occur in correct code, since
// INT64_MIN is not a proper 32-bit signed value
if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1))
RD = sext32(sreg_t(RS1) < 0 ? INT32_MIN : INT32_MAX);
else
RD = sext32(int32_t(RS1)/int32_t(RS2));
RD = sext32(sreg_t(RS1) / sreg_t(RS2));

2
riscv/insns/ld.h

@ -1,2 +1,2 @@
require64;
require_xpr64;
RD = mmu.load_int64(RS1+SIMM);

2
riscv/insns/mfcr.h

@ -15,4 +15,4 @@ switch(insn.rtype.rs2)
val = -1;
}
RD = gprlen == 64 ? val : sext32(val);
RD = sext_xprlen(val);

2
riscv/insns/mff_d.h

@ -1,3 +1,3 @@
require64;
require_xpr64;
require_fp;
RD = FRS2;

2
riscv/insns/mfpcr.h

@ -45,4 +45,4 @@ switch(insn.rtype.rs2)
val = -1;
}
RD = gprlen == 64 ? val : sext32(val);
RD = sext_xprlen(val);

2
riscv/insns/mtf_d.h

@ -1,3 +1,3 @@
require64;
require_xpr64;
require_fp;
FRD = RS1;

3
riscv/insns/mul.h

@ -1,2 +1 @@
require64;
RD = RS1 * RS2;
RD = sext_xprlen(RS1 * RS2);

12
riscv/insns/mulh.h

@ -1,4 +1,8 @@
require64;
int64_t rb = RS1;
int64_t ra = RS2;
RD = (int128_t(rb) * int128_t(ra)) >> 64;
if(xpr64)
{
int64_t a = RS1;
int64_t b = RS2;
RD = (int128_t(a) * int128_t(b)) >> 64;
}
else
RD = sext32((sreg_t(RS1) * sreg_t(RS2)) >> 32);

6
riscv/insns/mulhu.h

@ -1,2 +1,4 @@
require64;
RD = (uint128_t(RS1) * uint128_t(RS2)) >> 64;
if(xpr64)
RD = (uint128_t(RS1) * uint128_t(RS2)) >> 64;
else
RD = sext32((RS1 * RS2) >> 32);

2
riscv/insns/mulhuw.h

@ -1,2 +0,0 @@
RD = sext32((RS1 * RS2) >> 32);

2
riscv/insns/mulhw.h

@ -1,2 +0,0 @@
RD = sext32((sreg_t(RS1) * sreg_t(RS2)) >> 32);

2
riscv/insns/mulw.h

@ -1,2 +1,2 @@
require_xpr64;
RD = sext32(RS1 * RS2);

7
riscv/insns/rem.h

@ -1,5 +1,6 @@
require64;
if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1))
if(RS2 == 0)
RD = RS1;
else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1)
RD = 0;
else
RD = sreg_t(RS1) % sreg_t(RS2);
RD = sext_xprlen(sreg_t(RS1) % sreg_t(RS2));

5
riscv/insns/remu.h

@ -1,5 +1,4 @@
require64;
if(RS2 == 0)
RD = 0;
RD = RS1;
else
RD = RS1 % RS2;
RD = sext_xprlen(RS1 % RS2);

7
riscv/insns/remuw.h

@ -1,4 +1,5 @@
if(uint32_t(RS2) == 0)
RD = 0;
require_xpr64;
if(RS2 == 0)
RD = RS1;
else
RD = sext32(uint32_t(RS1) % uint32_t(RS2));
RD = sext32(RS1 % RS2);

9
riscv/insns/remw.h

@ -1,4 +1,9 @@
if(int32_t(RS2) == 0 || (int32_t(RS1) == INT32_MIN && int32_t(RS2) == -1))
require_xpr64;
// INT64_MIN/-1 corner case shouldn't occur in correct code, since
// INT64_MIN is not a proper 32-bit signed value
if(RS2 == 0)
RD = RS1;
else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1)
RD = 0;
else
RD = sext32(int32_t(RS1) % int32_t(RS2));
RD = sext32(sreg_t(RS1) % sreg_t(RS2));

2
riscv/insns/sd.h

@ -1,2 +1,2 @@
require64;
require_xpr64;
mmu.store_uint64(RS1+BIMM, RS2);

3
riscv/insns/sll.h

@ -1,2 +1 @@
require64;
RD = RS1 << (RS2 & 0x3F);
RD = sext_xprlen(RS1 << (RS2 & (xprlen-1)));

10
riscv/insns/slli.h

@ -1,2 +1,8 @@
require64;
RD = RS1 << SHAMT;
if(xpr64)
RD = RS1 << SHAMT;
else
{
if(SHAMT & 0x20)
throw trap_illegal_instruction;
RD = sext32(RS1 << SHAMT);
}

1
riscv/insns/slliw.h

@ -1 +1,2 @@
require_xpr64;
RD = sext32(RS1 << SHAMTW);

1
riscv/insns/sllw.h

@ -1 +1,2 @@
require_xpr64;
RD = sext32(RS1 << (RS2 & 0x1F));

3
riscv/insns/sra.h

@ -1,2 +1 @@
require64;
RD = sreg_t(RS1) >> (RS2 & 0x3F);
RD = sext_xprlen(sreg_t(RS1) >> (RS2 & (xprlen-1)));

10
riscv/insns/srai.h

@ -1,2 +1,8 @@
require64;
RD = sreg_t(RS1) >> SHAMT;
if(xpr64)
RD = sreg_t(RS1) >> SHAMT;
else
{
if(SHAMT & 0x20)
throw trap_illegal_instruction;
RD = sext32(sreg_t(RS1) >> SHAMT);
}

1
riscv/insns/sraiw.h

@ -1 +1,2 @@
require_xpr64;
RD = sext32(sreg_t(RS1) >> SHAMTW);

1
riscv/insns/sraw.h

@ -1 +1,2 @@
require_xpr64;
RD = sext32(sreg_t(RS1) >> (RS2 & 0x1F));

6
riscv/insns/srl.h

@ -1,2 +1,4 @@
require64;
RD = RS1 >> (RS2 & 0x3F);
if(xpr64)
RD = RS1 >> (RS2 & 0x3F);
else
RD = sext32((uint32_t)RS1 >> (RS2 & 0x1F));

10
riscv/insns/srli.h

@ -1,2 +1,8 @@
require64;
RD = RS1 >> SHAMT;
if(xpr64)
RD = RS1 >> SHAMT;
else
{
if(SHAMT & 0x20)
throw trap_illegal_instruction;
RD = sext32((uint32_t)RS1 >> SHAMT);
}

1
riscv/insns/srliw.h

@ -1 +1,2 @@
require_xpr64;
RD = sext32((uint32_t)RS1 >> SHAMTW);

1
riscv/insns/srlw.h

@ -1 +1,2 @@
require_xpr64;
RD = sext32((uint32_t)RS1 >> (RS2 & 0x1F));

3
riscv/insns/sub.h

@ -1,2 +1 @@
require64;
RD = RS1 - RS2;
RD = sext_xprlen(RS1 - RS2);

1
riscv/insns/subw.h

@ -1,2 +1,3 @@
require_xpr64;
RD = sext32(RS1 - RS2);

22
riscv/processor.cc

@ -12,8 +12,8 @@
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));
memset(XPR,0,sizeof(XPR));
memset(FPR,0,sizeof(FPR));
pc = 0;
evec = 0;
epc = 0;
@ -26,7 +26,7 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
count = 0;
compare = 0;
interrupts_pending = 0;
set_sr(SR_S | (support_64bit ? SR_SX : 0));
set_sr(SR_S | SR_SX); // SX ignored if 64b mode not supported
set_fsr(0);
memset(counters,0,sizeof(counters));
@ -48,12 +48,14 @@ void processor_t::init(uint32_t _id)
void processor_t::set_sr(uint32_t val)
{
sr = val & ~SR_ZERO;
if(!support_64bit)
sr &= ~(SR_SX | SR_UX);
if(!support_fp)
sr &= ~SR_EF;
gprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
#ifndef RISCV_ENABLE_64BIT
sr &= ~(SR_SX | SR_UX);
#endif
#ifndef RISCV_ENABLE_64BIT
sr &= ~SR_EF;
#endif
xprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
}
void processor_t::set_fsr(uint32_t val)
@ -86,7 +88,7 @@ void processor_t::step(size_t n, bool noisy)
#include "execute.h"
pc = npc;
R[0] = 0;
XPR[0] = 0;
if(count++ == compare)
interrupts_pending |= 1 << TIMER_IRQ;

8
riscv/processor.h

@ -19,8 +19,8 @@ private:
sim_t* sim;
// architected state
reg_t R[NGPR];
freg_t FR[NFPR];
reg_t XPR[NXPR];
freg_t FPR[NFPR];
// privileged control registers
reg_t pc;
@ -41,8 +41,8 @@ private:
// unprivileged control registers
uint32_t fsr;
// 32-bit or 64-bit mode (redundant with sr)
int gprlen;
// # of bits in an XPR (32 or 64). (redundant with sr)
int xprlen;
// shared memory
mmu_t mmu;

6
riscv/sim.cc

@ -163,10 +163,10 @@ reg_t sim_t::get_reg(const std::vector<std::string>& args)
int p = atoi(args[0].c_str());
int r = atoi(args[1].c_str());
if(p >= (int)procs.size() || r >= NGPR)
if(p >= (int)procs.size() || r >= NXPR)
throw trap_illegal_instruction;
return procs[p].R[r];
return procs[p].XPR[r];
}
reg_t sim_t::get_freg(const std::vector<std::string>& args)
@ -179,7 +179,7 @@ reg_t sim_t::get_freg(const std::vector<std::string>& args)
if(p >= (int)procs.size() || r >= NFPR)
throw trap_illegal_instruction;
return procs[p].FR[r];
return procs[p].FPR[r];
}
reg_t sim_t::get_tohost(const std::vector<std::string>& args)

Loading…
Cancel
Save