Browse Source

[xcc,sim,opcodes] more rvc instructions and bug fixes

cs250
Andrew Waterman 15 years ago
parent
commit
66eda0b75e
  1. 6
      riscv/decode.h
  2. 492
      riscv/execute.h
  3. 2
      riscv/insns/c_addi.h
  4. 2
      riscv/insns/c_j.h
  5. 2
      riscv/insns/c_li.h
  6. 2
      riscv/insns/c_move.h
  7. 4
      riscv/mmu.h
  8. 3
      riscv/processor.cc

6
riscv/decode.h

@ -204,8 +204,14 @@ private:
// RVC stuff // RVC stuff
#define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
#define CRD do_writeback(XPR,(insn.bits >> 5) & 0x1f) #define CRD do_writeback(XPR,(insn.bits >> 5) & 0x1f)
#define CRS1 XPR[(insn.bits >> 10) & 0x1f]
#define CRS2 XPR[(insn.bits >> 5) & 0x1f]
#define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26) #define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26)
#define CIMM10 ((int32_t)((insn.bits >> 5) & 0x3ff) << 22 >> 22)
#define CJUMP_TARGET (pc + (CIMM10 << JUMP_ALIGN_BITS))
// vector stuff // vector stuff
#define VL vl #define VL vl

492
riscv/execute.h

@ -11,6 +11,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h" #include "insns/c_li.h"
break; break;
} }
case 0x2:
{
switch((insn.bits >> 0x7) & 0x7)
{
case 0x0:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x1:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x2:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x3:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x4:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x5:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x6:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x7:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
default:
{
throw trap_illegal_instruction;
}
}
break;
}
case 0x3: case 0x3:
{ {
switch((insn.bits >> 0x7) & 0x7) switch((insn.bits >> 0x7) & 0x7)
@ -609,6 +732,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h" #include "insns/c_li.h"
break; break;
} }
case 0x22:
{
switch((insn.bits >> 0x7) & 0x7)
{
case 0x0:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x1:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x2:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x3:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x4:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x5:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x6:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x7:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
default:
{
throw trap_illegal_instruction;
}
}
break;
}
case 0x23: case 0x23:
{ {
switch((insn.bits >> 0x7) & 0x7) switch((insn.bits >> 0x7) & 0x7)
@ -1034,6 +1280,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h" #include "insns/c_li.h"
break; break;
} }
case 0x42:
{
switch((insn.bits >> 0x7) & 0x7)
{
case 0x0:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x1:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x2:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x3:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x4:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x5:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x6:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x7:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
default:
{
throw trap_illegal_instruction;
}
}
break;
}
case 0x43: case 0x43:
{ {
switch((insn.bits >> 0x7) & 0x7) switch((insn.bits >> 0x7) & 0x7)
@ -1570,6 +1939,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h" #include "insns/c_li.h"
break; break;
} }
case 0x62:
{
switch((insn.bits >> 0x7) & 0x7)
{
case 0x0:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x1:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x2:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x3:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x4:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x5:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x6:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
case 0x7:
{
if((insn.bits & 0x801f) == 0x2)
{
#include "insns/c_move.h"
break;
}
if((insn.bits & 0x801f) == 0x8002)
{
#include "insns/c_j.h"
break;
}
throw trap_illegal_instruction;
}
default:
{
throw trap_illegal_instruction;
}
}
break;
}
case 0x63: case 0x63:
{ {
switch((insn.bits >> 0x7) & 0x7) switch((insn.bits >> 0x7) & 0x7)

2
riscv/insns/c_addi.h

@ -1,2 +1,2 @@
require_rvc; require_rvc;
CRD = sext_xprlen(CRD + SIMM); CRD = sext_xprlen(CRS2 + CIMM6);

2
riscv/insns/c_j.h

@ -0,0 +1,2 @@
require_rvc;
npc = CJUMP_TARGET;

2
riscv/insns/c_li.h

@ -1,2 +1,2 @@
require_rvc; require_rvc;
CRD = SIMM; CRD = CIMM6;

2
riscv/insns/c_move.h

@ -0,0 +1,2 @@
require_rvc;
CRD = CRS1;

4
riscv/mmu.h

@ -25,9 +25,7 @@ public:
uint16_t hi = *(uint16_t*)(mem+addr+2); uint16_t hi = *(uint16_t*)(mem+addr+2);
insn_t insn; insn_t insn;
insn.bits = lo; insn.bits = lo | ((uint32_t)hi << 16);
if((lo & 0x3) == 0x3)
insn.bits |= (uint32_t)hi << 16;
return insn; return insn;
} }

3
riscv/processor.cc

@ -180,7 +180,8 @@ void processor_t::disasm(insn_t insn, reg_t pc)
info.buffer_length = sizeof(insn); info.buffer_length = sizeof(insn);
info.buffer_vma = pc; info.buffer_vma = pc;
demand(print_insn_little_mips(pc, &info) == sizeof(insn), "disasm bug!"); int ret = print_insn_little_mips(pc, &info);
demand(ret == (INSN_IS_RVC(insn.bits) ? 2 : 4), "disasm bug!");
#else #else
printf("unknown"); printf("unknown");
#endif #endif

Loading…
Cancel
Save