Skip to content
This repository has been archived by the owner on Apr 13, 2019. It is now read-only.

Commit

Permalink
Merge branch 'qemu-for-upstream' into riscv-all
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Clark committed Sep 16, 2018
2 parents 18a398f + 87c04c3 commit b00c9d1
Show file tree
Hide file tree
Showing 34 changed files with 2,386 additions and 1,665 deletions.
1 change: 1 addition & 0 deletions Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ trace-events-subdirs += target/arm
trace-events-subdirs += target/i386
trace-events-subdirs += target/mips
trace-events-subdirs += target/ppc
trace-events-subdirs += target/riscv
trace-events-subdirs += target/s390x
trace-events-subdirs += target/sparc
trace-events-subdirs += ui
Expand Down
261 changes: 70 additions & 191 deletions disas/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,33 +87,10 @@ typedef enum {

typedef enum {
rvc_end,
rvc_simm_6,
rvc_imm_6,
rvc_imm_7,
rvc_imm_8,
rvc_imm_9,
rvc_imm_10,
rvc_imm_12,
rvc_imm_18,
rvc_imm_nz,
rvc_imm_x2,
rvc_imm_x4,
rvc_imm_x8,
rvc_imm_x16,
rvc_rd_b3,
rvc_rs1_b3,
rvc_rs2_b3,
rvc_rd_eq_rs1,
rvc_rd_eq_ra,
rvc_rd_eq_sp,
rvc_rd_eq_x0,
rvc_rs1_eq_sp,
rvc_rs1_eq_x0,
rvc_rs2_eq_x0,
rvc_rd_ne_x0_x2,
rvc_rd_ne_x0,
rvc_rs1_ne_x0,
rvc_rs2_ne_x0,
rvc_rs2_eq_rs1,
rvc_rs1_eq_ra,
rvc_imm_eq_zero,
Expand Down Expand Up @@ -527,14 +504,19 @@ typedef struct {
const rvc_constraint *constraints;
} rv_comp_data;

enum {
rvcd_imm_nz = 0x1
};

typedef struct {
const char * const name;
const rv_codec codec;
const char * const format;
const rv_comp_data *pseudo;
const int decomp_rv32;
const int decomp_rv64;
const int decomp_rv128;
const short decomp_rv32;
const short decomp_rv64;
const short decomp_rv128;
const short decomp_data;
} rv_opcode_data;

/* register names */
Expand All @@ -555,41 +537,41 @@ static const char rv_freg_name_sym[32][5] = {

/* instruction formats */

#define rv_fmt_none "O\t"
#define rv_fmt_rs1 "O\t1"
#define rv_fmt_offset "O\to"
#define rv_fmt_pred_succ "O\tp,s"
#define rv_fmt_rs1_rs2 "O\t1,2"
#define rv_fmt_rd_imm "O\t0,i"
#define rv_fmt_rd_offset "O\t0,o"
#define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
#define rv_fmt_frd_rs1 "O\t3,1"
#define rv_fmt_rd_frs1 "O\t0,4"
#define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
#define rv_fmt_frd_frs1_frs2 "O\t3,4,5"
#define rv_fmt_rm_frd_frs1 "O\tr,3,4"
#define rv_fmt_rm_frd_rs1 "O\tr,3,1"
#define rv_fmt_rm_rd_frs1 "O\tr,0,4"
#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5"
#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6"
#define rv_fmt_rd_rs1_imm "O\t0,1,i"
#define rv_fmt_rd_rs1_offset "O\t0,1,i"
#define rv_fmt_rd_offset_rs1 "O\t0,i(1)"
#define rv_fmt_frd_offset_rs1 "O\t3,i(1)"
#define rv_fmt_rd_csr_rs1 "O\t0,c,1"
#define rv_fmt_rd_csr_zimm "O\t0,c,7"
#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)"
#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)"
#define rv_fmt_rs1_rs2_offset "O\t1,2,o"
#define rv_fmt_rs2_rs1_offset "O\t2,1,o"
#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)"
#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)"
#define rv_fmt_rd "O\t0"
#define rv_fmt_rd_zimm "O\t0,7"
#define rv_fmt_rd_rs1 "O\t0,1"
#define rv_fmt_rd_rs2 "O\t0,2"
#define rv_fmt_rs1_offset "O\t1,o"
#define rv_fmt_rs2_offset "O\t2,o"
static const char rv_fmt_none[] = "O\t";
static const char rv_fmt_rs1[] = "O\t1";
static const char rv_fmt_offset[] = "O\to";
static const char rv_fmt_pred_succ[] = "O\tp,s";
static const char rv_fmt_rs1_rs2[] = "O\t1,2";
static const char rv_fmt_rd_imm[] = "O\t0,i";
static const char rv_fmt_rd_offset[] = "O\t0,o";
static const char rv_fmt_rd_rs1_rs2[] = "O\t0,1,2";
static const char rv_fmt_frd_rs1[] = "O\t3,1";
static const char rv_fmt_rd_frs1[] = "O\t0,4";
static const char rv_fmt_rd_frs1_frs2[] = "O\t0,4,5";
static const char rv_fmt_frd_frs1_frs2[] = "O\t3,4,5";
static const char rv_fmt_rm_frd_frs1[] = "O\tr,3,4";
static const char rv_fmt_rm_frd_rs1[] = "O\tr,3,1";
static const char rv_fmt_rm_rd_frs1[] = "O\tr,0,4";
static const char rv_fmt_rm_frd_frs1_frs2[] = "O\tr,3,4,5";
static const char rv_fmt_rm_frd_frs1_frs2_frs3[] = "O\tr,3,4,5,6";
static const char rv_fmt_rd_rs1_imm[] = "O\t0,1,i";
static const char rv_fmt_rd_rs1_offset[] = "O\t0,1,i";
static const char rv_fmt_rd_offset_rs1[] = "O\t0,i(1)";
static const char rv_fmt_frd_offset_rs1[] = "O\t3,i(1)";
static const char rv_fmt_rd_csr_rs1[] = "O\t0,c,1";
static const char rv_fmt_rd_csr_zimm[] = "O\t0,c,7";
static const char rv_fmt_rs2_offset_rs1[] = "O\t2,i(1)";
static const char rv_fmt_frs2_offset_rs1[] = "O\t5,i(1)";
static const char rv_fmt_rs1_rs2_offset[] = "O\t1,2,o";
static const char rv_fmt_rs2_rs1_offset[] = "O\t2,1,o";
static const char rv_fmt_aqrl_rd_rs2_rs1[] = "OAR\t0,2,(1)";
static const char rv_fmt_aqrl_rd_rs1[] = "OAR\t0,(1)";
static const char rv_fmt_rd[] = "O\t0";
static const char rv_fmt_rd_zimm[] = "O\t0,7";
static const char rv_fmt_rd_rs1[] = "O\t0,1";
static const char rv_fmt_rd_rs2[] = "O\t0,2";
static const char rv_fmt_rs1_offset[] = "O\t1,o";
static const char rv_fmt_rs2_offset[] = "O\t2,o";

/* pseudo-instruction constraints */

Expand Down Expand Up @@ -632,7 +614,7 @@ static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, r
static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end };
static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end };
static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc82, rvc_end };
static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end };
static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end };
static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end };
Expand Down Expand Up @@ -1034,22 +1016,22 @@ const rv_opcode_data opcode_data[] = {
{ "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
{ "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
{ "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
{ "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
{ "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
{ "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
{ "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 },
{ "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
{ "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
{ "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
{ "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
{ "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui },
{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli },
{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai },
{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi },
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui, rvcd_imm_nz },
{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli, rvcd_imm_nz },
{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai, rvcd_imm_nz },
{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi, rvcd_imm_nz },
{ "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
{ "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
{ "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
Expand All @@ -1059,7 +1041,7 @@ const rv_opcode_data opcode_data[] = {
{ "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
{ "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
{ "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli },
{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli, rvcd_imm_nz },
{ "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
{ "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
{ "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
Expand Down Expand Up @@ -2522,111 +2504,16 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
uint8_t rd = dec->rd, rs1 = dec->rs1, rs2 = dec->rs2;
while (*c != rvc_end) {
switch (*c) {
case rvc_simm_6:
if (!(imm >= -32 && imm < 32)) {
return false;
}
break;
case rvc_imm_6:
if (!(imm <= 63)) {
return false;
}
break;
case rvc_imm_7:
if (!(imm <= 127)) {
return false;
}
break;
case rvc_imm_8:
if (!(imm <= 255)) {
return false;
}
break;
case rvc_imm_9:
if (!(imm <= 511)) {
return false;
}
break;
case rvc_imm_10:
if (!(imm <= 1023)) {
return false;
}
break;
case rvc_imm_12:
if (!(imm <= 4095)) {
return false;
}
break;
case rvc_imm_18:
if (!(imm <= 262143)) {
return false;
}
break;
case rvc_imm_nz:
if (!(imm != 0)) {
return false;
}
break;
case rvc_imm_x2:
if (!((imm & 0b1) == 0)) {
return false;
}
break;
case rvc_imm_x4:
if (!((imm & 0b11) == 0)) {
return false;
}
break;
case rvc_imm_x8:
if (!((imm & 0b111) == 0)) {
return false;
}
break;
case rvc_imm_x16:
if (!((imm & 0b1111) == 0)) {
return false;
}
break;
case rvc_rd_b3:
if (!(rd >= 8 && rd <= 15)) {
return false;
}
break;
case rvc_rs1_b3:
if (!(rs1 >= 8 && rs1 <= 15)) {
return false;
}
break;
case rvc_rs2_b3:
if (!(rs2 >= 8 && rs2 <= 15)) {
return false;
}
break;
case rvc_rd_eq_rs1:
if (!(rd == rs1)) {
return false;
}
break;
case rvc_rd_eq_ra:
if (!(rd == 1)) {
return false;
}
break;
case rvc_rd_eq_sp:
if (!(rd == 2)) {
return false;
}
break;
case rvc_rd_eq_x0:
if (!(rd == 0)) {
return false;
}
break;
case rvc_rs1_eq_sp:
if (!(rs1 == 2)) {
return false;
}
break;
case rvc_rs1_eq_x0:
if (!(rs1 == 0)) {
return false;
Expand All @@ -2637,26 +2524,6 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
return false;
}
break;
case rvc_rd_ne_x0_x2:
if (!(rd != 0 && rd != 2)) {
return false;
}
break;
case rvc_rd_ne_x0:
if (!(rd != 0)) {
return false;
}
break;
case rvc_rs1_ne_x0:
if (!(rs1 != 0)) {
return false;
}
break;
case rvc_rs2_ne_x0:
if (!(rs2 != 0)) {
return false;
}
break;
case rvc_rs2_eq_rs1:
if (!(rs2 == rs1)) {
return false;
Expand Down Expand Up @@ -2933,26 +2800,38 @@ static void decode_inst_decompress_rv32(rv_decode *dec)
{
int decomp_op = opcode_data[dec->op].decomp_rv32;
if (decomp_op != rv_op_illegal) {
dec->op = decomp_op;
dec->codec = opcode_data[decomp_op].codec;
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
dec->op = rv_op_illegal;
} else {
dec->op = decomp_op;
dec->codec = opcode_data[decomp_op].codec;
}
}
}

static void decode_inst_decompress_rv64(rv_decode *dec)
{
int decomp_op = opcode_data[dec->op].decomp_rv64;
if (decomp_op != rv_op_illegal) {
dec->op = decomp_op;
dec->codec = opcode_data[decomp_op].codec;
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
dec->op = rv_op_illegal;
} else {
dec->op = decomp_op;
dec->codec = opcode_data[decomp_op].codec;
}
}
}

static void decode_inst_decompress_rv128(rv_decode *dec)
{
int decomp_op = opcode_data[dec->op].decomp_rv128;
if (decomp_op != rv_op_illegal) {
dec->op = decomp_op;
dec->codec = opcode_data[decomp_op].codec;
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
dec->op = rv_op_illegal;
} else {
dec->op = decomp_op;
dec->codec = opcode_data[decomp_op].codec;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions hw/riscv/Makefile.objs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
obj-y += boot.o
obj-y += riscv_htif.o
obj-y += riscv_hart.o
obj-y += sifive_e.o
Expand Down
Loading

0 comments on commit b00c9d1

Please sign in to comment.