Browse Source

[sim,xcc] Changed instruction format to RISC-V

Massive changes to gcc, binutils to support new instruction encoding.
Simulator reflects these changes.
cs250
Andrew Waterman 16 years ago
parent
commit
e8125348b3
  1. 2
      riscv/applink.cc
  2. 2
      riscv/common.h
  3. 47
      riscv/decode.h
  4. 1636
      riscv/execute.h
  5. 2
      riscv/insns/add.h
  6. 2
      riscv/insns/addi.h
  7. 2
      riscv/insns/and.h
  8. 2
      riscv/insns/andi.h
  9. 2
      riscv/insns/beq.h
  10. 2
      riscv/insns/ble.h
  11. 2
      riscv/insns/bleu.h
  12. 2
      riscv/insns/blt.h
  13. 2
      riscv/insns/bltu.h
  14. 2
      riscv/insns/bne.h
  15. 2
      riscv/insns/dadd.h
  16. 2
      riscv/insns/daddi.h
  17. 2
      riscv/insns/ddiv.h
  18. 2
      riscv/insns/ddivu.h
  19. 2
      riscv/insns/di.h
  20. 2
      riscv/insns/div.h
  21. 2
      riscv/insns/divu.h
  22. 16
      riscv/insns/dmfc0.h
  23. 10
      riscv/insns/dmtc0.h
  24. 2
      riscv/insns/dmul.h
  25. 4
      riscv/insns/dmulh.h
  26. 2
      riscv/insns/dmulhu.h
  27. 2
      riscv/insns/drem.h
  28. 2
      riscv/insns/dremu.h
  29. 2
      riscv/insns/dsll.h
  30. 2
      riscv/insns/dsll32.h
  31. 2
      riscv/insns/dsllv.h
  32. 2
      riscv/insns/dsra.h
  33. 2
      riscv/insns/dsra32.h
  34. 2
      riscv/insns/dsrav.h
  35. 2
      riscv/insns/dsrl.h
  36. 2
      riscv/insns/dsrl32.h
  37. 2
      riscv/insns/dsrlv.h
  38. 2
      riscv/insns/dsub.h
  39. 2
      riscv/insns/ei.h
  40. 3
      riscv/insns/jalr_c.h
  41. 1
      riscv/insns/jalr_j.h
  42. 1
      riscv/insns/jalr_r.h
  43. 2
      riscv/insns/lb.h
  44. 2
      riscv/insns/lbu.h
  45. 2
      riscv/insns/ld.h
  46. 2
      riscv/insns/lh.h
  47. 2
      riscv/insns/lhu.h
  48. 2
      riscv/insns/lui.h
  49. 2
      riscv/insns/lw.h
  50. 2
      riscv/insns/lwu.h
  51. 16
      riscv/insns/mfc0.h
  52. 2
      riscv/insns/movn.h
  53. 2
      riscv/insns/movz.h
  54. 10
      riscv/insns/mtc0.h
  55. 2
      riscv/insns/mul.h
  56. 2
      riscv/insns/mulh.h
  57. 2
      riscv/insns/mulhu.h
  58. 2
      riscv/insns/nor.h
  59. 2
      riscv/insns/or.h
  60. 2
      riscv/insns/ori.h
  61. 1
      riscv/insns/rdpc.h
  62. 2
      riscv/insns/rem.h
  63. 2
      riscv/insns/remu.h
  64. 2
      riscv/insns/sb.h
  65. 2
      riscv/insns/sd.h
  66. 2
      riscv/insns/sh.h
  67. 2
      riscv/insns/sll.h
  68. 2
      riscv/insns/sllv.h
  69. 1
      riscv/insns/slori.h
  70. 2
      riscv/insns/slt.h
  71. 2
      riscv/insns/slti.h
  72. 2
      riscv/insns/sltiu.h
  73. 2
      riscv/insns/sltu.h
  74. 2
      riscv/insns/sra.h
  75. 2
      riscv/insns/srav.h
  76. 2
      riscv/insns/srl.h
  77. 2
      riscv/insns/srlv.h
  78. 2
      riscv/insns/sub.h
  79. 2
      riscv/insns/sw.h
  80. 2
      riscv/insns/xor.h
  81. 2
      riscv/insns/xori.h
  82. 2
      riscv/mmu.h
  83. 5
      riscv/processor.cc

2
riscv/applink.cc

@ -80,7 +80,7 @@ int appserver_link_t::wait_for_packet()
{
packet p;
int bytes = read(fromhost_fd,&p,sizeof(p));
if(bytes < offsetof(packet,data))
if(bytes < (signed)offsetof(packet,data))
throw io_error("read failed");
if(p.seqno != seqno)

2
riscv/common.h

@ -20,4 +20,6 @@
print_and_die(__str); \
} } while(0)
#define static_assert(x) switch (x) case 0: case (x):
#endif

47
riscv/decode.h

@ -2,12 +2,15 @@
#define _RISCV_DECODE_H
#include <stdint.h>
typedef int int128_t __attribute__((mode(TI)));
typedef unsigned int uint128_t __attribute__((mode(TI)));
#define support_64bit 1
typedef int64_t sreg_t;
typedef uint64_t reg_t;
const int OPCODE_BITS = 6;
const int OPCODE_BITS = 7;
const int JTYPE_OPCODE_BITS = 5;
const int GPR_BITS = 8*sizeof(reg_t);
const int GPRID_BITS = 5;
@ -17,10 +20,11 @@ const int FPR_BITS = 64;
const int FPRID_BITS = 5;
const int NFPR = 1 << FPRID_BITS;
const int IMM_BITS = 16;
const int TARGET_BITS = 26;
const int SHAMT_BITS = 5;
const int FUNCT_BITS = 6;
const int IMM_BITS = 12;
const int TARGET_BITS = 27;
const int SHAMT_BITS = 6;
const int FUNCT_BITS = 3;
const int BIGIMM_BITS = 20;
#define SR_ET 0x0000000000000001ULL
#define SR_PS 0x0000000000000004ULL
@ -35,24 +39,33 @@ const int FUNCT_BITS = 6;
struct itype_t
{
unsigned imm : IMM_BITS;
unsigned rt : GPRID_BITS;
unsigned rs : GPRID_BITS;
unsigned funct : FUNCT_BITS;
unsigned rb : GPRID_BITS;
unsigned ra : GPRID_BITS;
unsigned opcode : OPCODE_BITS;
};
struct jtype_t
{
unsigned target : TARGET_BITS;
unsigned opcode : OPCODE_BITS;
unsigned jump_opcode : JTYPE_OPCODE_BITS;
};
struct rtype_t
{
unsigned funct : FUNCT_BITS;
unsigned rc : GPRID_BITS;
unsigned shamt : SHAMT_BITS;
unsigned rd : GPRID_BITS;
unsigned unused : 1;
unsigned funct : FUNCT_BITS;
unsigned rb : GPRID_BITS;
unsigned ra : GPRID_BITS;
unsigned opcode : OPCODE_BITS;
};
struct btype_t
{
unsigned bigimm : BIGIMM_BITS;
unsigned rt : GPRID_BITS;
unsigned rs : GPRID_BITS;
unsigned opcode : OPCODE_BITS;
};
@ -61,19 +74,21 @@ union insn_t
itype_t itype;
jtype_t jtype;
rtype_t rtype;
btype_t btype;
uint32_t bits;
};
// helpful macros, etc
#define RS R[insn.rtype.rs]
#define RT R[insn.rtype.rt]
#define RD R[insn.rtype.rd]
#define RA R[insn.rtype.ra]
#define RB R[insn.rtype.rb]
#define RC R[insn.rtype.rc]
#define BIGIMM insn.btype.bigimm
#define IMM insn.itype.imm
#define SIMM ((int16_t)insn.itype.imm)
#define SIMM ((int32_t)((uint32_t)insn.itype.imm<<(32-IMM_BITS))>>(32-IMM_BITS))
#define SHAMT insn.rtype.shamt
#define TARGET insn.jtype.target
#define BRANCH_TARGET (npc + (SIMM*sizeof(insn_t)))
#define JUMP_TARGET ((npc & ~((1<<TARGET_BITS)-1)) + TARGET*sizeof(insn_t))
#define JUMP_TARGET ((npc & ~((1<<TARGET_BITS)*sizeof(insn_t)-1)) + TARGET*sizeof(insn_t))
#define require_supervisor if(!(sr & SR_S)) throw trap_privileged_instruction
#define require64 if(gprlen != 64) throw trap_illegal_instruction

1636
riscv/execute.h

File diff suppressed because it is too large

2
riscv/insns/add.h

@ -1,2 +1,2 @@
RD = sext32(RS + RT);
RC = sext32(RA + RB);

2
riscv/insns/addi.h

@ -1 +1 @@
RT = sext32(RS + SIMM);
RA = sext32(SIMM + RB);

2
riscv/insns/and.h

@ -1 +1 @@
RD = RS & RT;
RC = RA & RB;

2
riscv/insns/andi.h

@ -1 +1 @@
RT = RS & IMM;
RA = IMM & RB;

2
riscv/insns/beq.h

@ -1,2 +1,2 @@
if(cmp_trunc(RS) == cmp_trunc(RT))
if(cmp_trunc(RA) == cmp_trunc(RB))
npc = BRANCH_TARGET;

2
riscv/insns/ble.h

@ -1,2 +1,2 @@
if(sreg_t(cmp_trunc(RS)) <= sreg_t(cmp_trunc(RT)))
if(sreg_t(cmp_trunc(RA)) <= sreg_t(cmp_trunc(RB)))
npc = BRANCH_TARGET;

2
riscv/insns/bleu.h

@ -1,2 +1,2 @@
if(cmp_trunc(RS) <= cmp_trunc(RT))
if(cmp_trunc(RA) <= cmp_trunc(RB))
npc = BRANCH_TARGET;

2
riscv/insns/blt.h

@ -1,2 +1,2 @@
if(sreg_t(cmp_trunc(RS)) < sreg_t(cmp_trunc(RT)))
if(sreg_t(cmp_trunc(RA)) < sreg_t(cmp_trunc(RB)))
npc = BRANCH_TARGET;

2
riscv/insns/bltu.h

@ -1,2 +1,2 @@
if(cmp_trunc(RS) < cmp_trunc(RT))
if(cmp_trunc(RA) < cmp_trunc(RB))
npc = BRANCH_TARGET;

2
riscv/insns/bne.h

@ -1,2 +1,2 @@
if(cmp_trunc(RS) != cmp_trunc(RT))
if(cmp_trunc(RA) != cmp_trunc(RB))
npc = BRANCH_TARGET;

2
riscv/insns/dadd.h

@ -1,2 +1,2 @@
require64;
RD = RS + RT;
RC = RA + RB;

2
riscv/insns/daddi.h

@ -1,2 +1,2 @@
require64;
RT = RS + SIMM;
RA = SIMM + RB;

2
riscv/insns/ddiv.h

@ -1,2 +1,2 @@
require64;
RD = sreg_t(RS) / sreg_t(RT);
RC = sreg_t(RA) / sreg_t(RB);

2
riscv/insns/ddivu.h

@ -1,2 +1,2 @@
require64;
RD = RS / RT;
RC = RA / RB;

2
riscv/insns/di.h

@ -1,4 +1,4 @@
require_supervisor;
uint32_t temp = sr;
set_sr(sr & ~SR_ET);
RT = temp;
RA = temp;

2
riscv/insns/div.h

@ -1,2 +1,2 @@
RD = sext32(int32_t(RS)/int32_t(RT));
RC = sext32(int32_t(RA)/int32_t(RB));

2
riscv/insns/divu.h

@ -1,2 +1,2 @@
RD = sext32(uint32_t(RS)/uint32_t(RT));
RC = sext32(uint32_t(RA)/uint32_t(RB));

16
riscv/insns/dmfc0.h

@ -1,29 +1,29 @@
require_supervisor;
require64;
switch(insn.rtype.rs)
switch(insn.rtype.rb)
{
case 0:
RT = sr;
RA = sr;
break;
case 1:
RT = epc;
RA = epc;
break;
case 2:
RT = badvaddr;
RA = badvaddr;
break;
case 3:
RT = ebase;
RA = ebase;
break;
case 8:
RT = MEMSIZE >> 12;
RA = MEMSIZE >> 12;
break;
case 17:
RT = sim->get_fromhost();
RA = sim->get_fromhost();
break;
default:
RT = -1;
RA = -1;
}

10
riscv/insns/dmtc0.h

@ -1,19 +1,19 @@
require_supervisor;
require64;
switch(insn.rtype.rs)
switch(insn.rtype.rb)
{
case 0:
set_sr(RT);
set_sr(RA);
break;
case 1:
epc = RT;
epc = RA;
break;
case 3:
ebase = RT & ~0xFFF;
ebase = RA & ~0xFFF;
break;
case 16:
sim->set_tohost(RT);
sim->set_tohost(RA);
break;
}

2
riscv/insns/dmul.h

@ -1,2 +1,2 @@
require64;
RD = RS * RT;
RC = RA * RB;

4
riscv/insns/dmulh.h

@ -0,0 +1,4 @@
require64;
int64_t rb = RA;
int64_t ra = RB;
RC = (int128_t(rb) * int128_t(ra)) >> 64;

2
riscv/insns/dmulhu.h

@ -0,0 +1,2 @@
require64;
RC = (uint128_t(RA) * uint128_t(RB)) >> 64;

2
riscv/insns/drem.h

@ -0,0 +1,2 @@
require64;
RC = sreg_t(RA) % sreg_t(RB);

2
riscv/insns/dremu.h

@ -0,0 +1,2 @@
require64;
RC = RA % RB;

2
riscv/insns/dsll.h

@ -1,2 +1,2 @@
require64;
RD = RT << SHAMT;
RC = RB << SHAMT;

2
riscv/insns/dsll32.h

@ -1,2 +1,2 @@
require64;
RD = RT << (32+SHAMT);
RC = RB << (32+SHAMT);

2
riscv/insns/dsllv.h

@ -1,2 +1,2 @@
require64;
RD = RT << (RS & 0x3F);
RC = RB << (RA & 0x3F);

2
riscv/insns/dsra.h

@ -1,2 +1,2 @@
require64;
RD = sreg_t(RT) >> SHAMT;
RC = sreg_t(RB) >> SHAMT;

2
riscv/insns/dsra32.h

@ -1,2 +1,2 @@
require64;
RD = sreg_t(RT) >> (32+SHAMT);
RC = sreg_t(RB) >> (32+SHAMT);

2
riscv/insns/dsrav.h

@ -1,2 +1,2 @@
require64;
RD = RT >> (RS & 0x3F);
RC = RB >> (RA & 0x3F);

2
riscv/insns/dsrl.h

@ -1,2 +1,2 @@
require64;
RD = RT >> SHAMT;
RC = RB >> SHAMT;

2
riscv/insns/dsrl32.h

@ -1,2 +1,2 @@
require64;
RD = RT >> (32+SHAMT);
RC = RB >> (32+SHAMT);

2
riscv/insns/dsrlv.h

@ -1,2 +1,2 @@
require64;
RD = RT >> (RS & 0x3F);
RC = RB >> (RA & 0x3F);

2
riscv/insns/dsub.h

@ -1,2 +1,2 @@
require64;
RD = RS - RT;
RC = RA - RB;

2
riscv/insns/ei.h

@ -1,4 +1,4 @@
require_supervisor;
uint32_t temp = sr;
set_sr(sr | SR_ET);
RT = temp;
RA = temp;

3
riscv/insns/jalr_c.h

@ -0,0 +1,3 @@
uint32_t temp = npc;
npc = RA;
RC = temp;

1
riscv/insns/jalr_j.h

@ -0,0 +1 @@
#include "jalr_c.h"

1
riscv/insns/jalr_r.h

@ -0,0 +1 @@
#include "jalr_c.h"

2
riscv/insns/lb.h

@ -1 +1 @@
RT = mmu.load_int8(RS+SIMM);
RA = mmu.load_int8(RB+SIMM);

2
riscv/insns/lbu.h

@ -1 +1 @@
RT = mmu.load_uint8(RS+SIMM);
RA = mmu.load_uint8(RB+SIMM);

2
riscv/insns/ld.h

@ -1,2 +1,2 @@
require64;
RT = mmu.load_int64(RS+SIMM);
RA = mmu.load_int64(RB+SIMM);

2
riscv/insns/lh.h

@ -1 +1 @@
RT = mmu.load_int16(RS+SIMM);
RA = mmu.load_int16(RB+SIMM);

2
riscv/insns/lhu.h

@ -1 +1 @@
RT = mmu.load_uint16(RS+SIMM);
RA = mmu.load_uint16(RB+SIMM);

2
riscv/insns/lui.h

@ -1 +1 @@
RT = IMM << 16;
RA = sext32(BIGIMM << IMM_BITS);

2
riscv/insns/lw.h

@ -1 +1 @@
RT = mmu.load_int32(RS+SIMM);
RA = mmu.load_int32(RB+SIMM);

2
riscv/insns/lwu.h

@ -1 +1 @@
RT = mmu.load_uint32(RS+SIMM);
RA = mmu.load_uint32(RB+SIMM);

16
riscv/insns/mfc0.h

@ -1,28 +1,28 @@
require_supervisor;
switch(insn.rtype.rs)
switch(insn.rtype.rb)
{
case 0:
RT = sext32(sr);
RA = sext32(sr);
break;
case 1:
RT = sext32(epc);
RA = sext32(epc);
break;
case 2:
RT = sext32(badvaddr);
RA = sext32(badvaddr);
break;
case 3:
RT = sext32(ebase);
RA = sext32(ebase);
break;
case 8:
RT = sext32(MEMSIZE >> 12);
RA = sext32(MEMSIZE >> 12);
break;
case 17:
RT = sext32(sim->get_fromhost());
RA = sext32(sim->get_fromhost());
break;
default:
RT = -1;
RA = -1;
}

2
riscv/insns/movn.h

@ -1 +1 @@
if(RT) RD = RS;
if(RB) RC = RA;

2
riscv/insns/movz.h

@ -1 +1 @@
if(!RT) RD = RS;
if(!RB) RC = RA;

10
riscv/insns/mtc0.h

@ -1,18 +1,18 @@
require_supervisor;
switch(insn.rtype.rs)
switch(insn.rtype.rb)
{
case 0:
set_sr(sext32(RT));
set_sr(sext32(RA));
break;
case 1:
epc = sext32(RT);
epc = sext32(RA);
break;
case 3:
ebase = sext32(RT & ~0xFFF);
ebase = sext32(RA & ~0xFFF);
break;
case 16:
sim->set_tohost(sext32(RT));
sim->set_tohost(sext32(RA));
break;
}

2
riscv/insns/mul.h

@ -1,2 +1,2 @@
RD = sext32(RS * RT);
RC = sext32(RA * RB);

2
riscv/insns/mulh.h

@ -0,0 +1,2 @@
RC = sext32((sreg_t(RA) * sreg_t(RB)) >> 32);

2
riscv/insns/mulhu.h

@ -0,0 +1,2 @@
RC = sext32((RA * RB) >> 32);

2
riscv/insns/nor.h

@ -1 +1 @@
RD = ~(RS | RT);
RC = ~(RA | RB);

2
riscv/insns/or.h

@ -1 +1 @@
RD = RS | RT;
RC = RA | RB;

2
riscv/insns/ori.h

@ -1 +1 @@
RT = RS | IMM;
RA = IMM | RB;

1
riscv/insns/rdpc.h

@ -0,0 +1 @@
RC = npc;

2
riscv/insns/rem.h

@ -0,0 +1,2 @@
RC = sext32(int32_t(RA) % int32_t(RB));

2
riscv/insns/remu.h

@ -0,0 +1,2 @@
RC = sext32(uint32_t(RA) % uint32_t(RB));

2
riscv/insns/sb.h

@ -1 +1 @@
mmu.store_uint8(RS+SIMM, RT);
mmu.store_uint8(RB+SIMM, RA);

2
riscv/insns/sd.h

@ -1,2 +1,2 @@
require64;
mmu.store_uint64(RS+SIMM, RT);
mmu.store_uint64(RB+SIMM, RA);

2
riscv/insns/sh.h

@ -1 +1 @@
mmu.store_uint16(RS+SIMM, RT);
mmu.store_uint16(RB+SIMM, RA);

2
riscv/insns/sll.h

@ -1 +1 @@
RD = sext32(RT << SHAMT);
RC = sext32(RB << SHAMT);

2
riscv/insns/sllv.h

@ -1 +1 @@
RD = sext32(RT << (RS & 0x1F));
RC = sext32(RB << (RA & 0x1F));

1
riscv/insns/slori.h

@ -0,0 +1 @@
RA = (RA << 32) | (BIGIMM << IMM_BITS);

2
riscv/insns/slt.h

@ -1 +1 @@
RD = sreg_t(cmp_trunc(RS)) < sreg_t(cmp_trunc(RT));
RC = sreg_t(cmp_trunc(RA)) < sreg_t(cmp_trunc(RB));

2
riscv/insns/slti.h

@ -1 +1 @@
RT = sreg_t(cmp_trunc(RS)) < sreg_t(cmp_trunc(SIMM));
RA = sreg_t(cmp_trunc(RB)) < sreg_t(cmp_trunc(SIMM));

2
riscv/insns/sltiu.h

@ -1 +1 @@
RT = cmp_trunc(RS) < cmp_trunc(SIMM);
RA = cmp_trunc(RB) < cmp_trunc(SIMM);

2
riscv/insns/sltu.h

@ -1 +1 @@
RD = cmp_trunc(RS) < cmp_trunc(RT);
RC = cmp_trunc(RA) < cmp_trunc(RB);

2
riscv/insns/sra.h

@ -1 +1 @@
RD = sext32(sreg_t(RT) >> SHAMT);
RC = sext32(sreg_t(RB) >> SHAMT);

2
riscv/insns/srav.h

@ -1 +1 @@
RD = sext32(sreg_t(RT) >> (RS & 0x1F));
RC = sext32(sreg_t(RB) >> (RA & 0x1F));

2
riscv/insns/srl.h

@ -1 +1 @@
RD = sext32(RT >> SHAMT);
RC = sext32(RB >> SHAMT);

2
riscv/insns/srlv.h

@ -1 +1 @@
RD = sext32(RT >> (RS & 0x1F));
RC = sext32(RB >> (RA & 0x1F));

2
riscv/insns/sub.h

@ -1,2 +1,2 @@
RD = sext32(RS - RT);
RC = sext32(RA - RB);

2
riscv/insns/sw.h

@ -1 +1 @@
mmu.store_uint32(RS+SIMM, RT);
mmu.store_uint32(RB+SIMM, RA);

2
riscv/insns/xor.h

@ -1 +1 @@
RD = RS ^ RT;
RC = RA ^ RB;

2
riscv/insns/xori.h

@ -1 +1 @@
RT = RS ^ IMM;
RA = IMM ^ RB;

2
riscv/mmu.h

@ -4,7 +4,7 @@
class mmu_t
{
public:
mmu_t(char* _mem, size_t _memsz) : mem(_mem), memsz(_memsz) {}
mmu_t(char* _mem, size_t _memsz) : mem(_mem), memsz(_memsz), badvaddr(0) {}
#define load_func(type) \
type##_t load_##type(reg_t addr) { \

5
riscv/processor.cc

@ -18,6 +18,9 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
set_sr(SR_S);
memset(counters,0,sizeof(counters));
static_assert(sizeof(insn_t) == 4);
static_assert(sizeof(uint128_t) == 16 && sizeof(int128_t) == 16);
}
void processor_t::init(uint32_t _id)
@ -45,8 +48,6 @@ void processor_t::step(size_t n, bool noisy)
{
insn_t insn = mmu.load_insn(pc);
int opcode = insn.rtype.opcode;
int funct = insn.rtype.funct;
reg_t npc = pc+sizeof(insn);
if(noisy)

Loading…
Cancel
Save