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
#define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
#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 CIMM10 ((int32_t)((insn.bits >> 5) & 0x3ff) << 22 >> 22)
#define CJUMP_TARGET (pc + (CIMM10 << JUMP_ALIGN_BITS))
// vector stuff
#define VL vl

492
riscv/execute.h

@ -11,6 +11,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
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:
{
switch((insn.bits >> 0x7) & 0x7)
@ -609,6 +732,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
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:
{
switch((insn.bits >> 0x7) & 0x7)
@ -1034,6 +1280,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
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:
{
switch((insn.bits >> 0x7) & 0x7)
@ -1570,6 +1939,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
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:
{
switch((insn.bits >> 0x7) & 0x7)

2
riscv/insns/c_addi.h

@ -1,2 +1,2 @@
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;
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);
insn_t insn;
insn.bits = lo;
if((lo & 0x3) == 0x3)
insn.bits |= (uint32_t)hi << 16;
insn.bits = lo | ((uint32_t)hi << 16);
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_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
printf("unknown");
#endif

Loading…
Cancel
Save