aboutsummaryrefslogtreecommitdiff
path: root/riscv/decode.h
blob: 40c79f72ca23cc75cb371a6391d44520a18f08e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef _RISCV_DECODE_H
#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 = 7;
const int JTYPE_OPCODE_BITS = 5;

const int GPR_BITS = 8*sizeof(reg_t);
const int GPRID_BITS = 5;
const int NGPR = 1 << GPRID_BITS;

const int FPR_BITS = 64;
const int FPRID_BITS = 5;
const int NFPR = 1 << FPRID_BITS;

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
#define SR_S     0x0000000000000008ULL
#define SR_EF    0x0000000000000010ULL
#define SR_UX    0x0000000000000020ULL
#define SR_KX    0x0000000000000040ULL
#define SR_IM    0x000000000000FF00ULL
#define SR_ZERO  0xFFFFFFFFFFFF0082ULL

// note: bit fields are in little-endian order
struct itype_t
{
  unsigned imm : IMM_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 jump_opcode : JTYPE_OPCODE_BITS;
};

struct rtype_t
{
  unsigned rc : GPRID_BITS;
  unsigned shamt : SHAMT_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 opcode : OPCODE_BITS;
};

union insn_t
{
  itype_t itype;
  jtype_t jtype;
  rtype_t rtype;
  btype_t btype;
  uint32_t bits;
};

// helpful macros, etc
#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 ((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)*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
#define cmp_trunc(reg) (reg_t(reg) << (64-gprlen))

static inline sreg_t sext32(int32_t arg)
{
  return arg;
}

#endif