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

Commit b00c9d1

Browse files
author
Michael Clark
committed
Merge branch 'qemu-for-upstream' into riscv-all
2 parents 18a398f + 87c04c3 commit b00c9d1

34 files changed

+2386
-1665
lines changed

Makefile.objs

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ trace-events-subdirs += target/arm
253253
trace-events-subdirs += target/i386
254254
trace-events-subdirs += target/mips
255255
trace-events-subdirs += target/ppc
256+
trace-events-subdirs += target/riscv
256257
trace-events-subdirs += target/s390x
257258
trace-events-subdirs += target/sparc
258259
trace-events-subdirs += ui

disas/riscv.c

+70-191
Original file line numberDiff line numberDiff line change
@@ -87,33 +87,10 @@ typedef enum {
8787

8888
typedef enum {
8989
rvc_end,
90-
rvc_simm_6,
91-
rvc_imm_6,
92-
rvc_imm_7,
93-
rvc_imm_8,
94-
rvc_imm_9,
95-
rvc_imm_10,
96-
rvc_imm_12,
97-
rvc_imm_18,
98-
rvc_imm_nz,
99-
rvc_imm_x2,
100-
rvc_imm_x4,
101-
rvc_imm_x8,
102-
rvc_imm_x16,
103-
rvc_rd_b3,
104-
rvc_rs1_b3,
105-
rvc_rs2_b3,
106-
rvc_rd_eq_rs1,
10790
rvc_rd_eq_ra,
108-
rvc_rd_eq_sp,
10991
rvc_rd_eq_x0,
110-
rvc_rs1_eq_sp,
11192
rvc_rs1_eq_x0,
11293
rvc_rs2_eq_x0,
113-
rvc_rd_ne_x0_x2,
114-
rvc_rd_ne_x0,
115-
rvc_rs1_ne_x0,
116-
rvc_rs2_ne_x0,
11794
rvc_rs2_eq_rs1,
11895
rvc_rs1_eq_ra,
11996
rvc_imm_eq_zero,
@@ -527,14 +504,19 @@ typedef struct {
527504
const rvc_constraint *constraints;
528505
} rv_comp_data;
529506

507+
enum {
508+
rvcd_imm_nz = 0x1
509+
};
510+
530511
typedef struct {
531512
const char * const name;
532513
const rv_codec codec;
533514
const char * const format;
534515
const rv_comp_data *pseudo;
535-
const int decomp_rv32;
536-
const int decomp_rv64;
537-
const int decomp_rv128;
516+
const short decomp_rv32;
517+
const short decomp_rv64;
518+
const short decomp_rv128;
519+
const short decomp_data;
538520
} rv_opcode_data;
539521

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

556538
/* instruction formats */
557539

558-
#define rv_fmt_none "O\t"
559-
#define rv_fmt_rs1 "O\t1"
560-
#define rv_fmt_offset "O\to"
561-
#define rv_fmt_pred_succ "O\tp,s"
562-
#define rv_fmt_rs1_rs2 "O\t1,2"
563-
#define rv_fmt_rd_imm "O\t0,i"
564-
#define rv_fmt_rd_offset "O\t0,o"
565-
#define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
566-
#define rv_fmt_frd_rs1 "O\t3,1"
567-
#define rv_fmt_rd_frs1 "O\t0,4"
568-
#define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
569-
#define rv_fmt_frd_frs1_frs2 "O\t3,4,5"
570-
#define rv_fmt_rm_frd_frs1 "O\tr,3,4"
571-
#define rv_fmt_rm_frd_rs1 "O\tr,3,1"
572-
#define rv_fmt_rm_rd_frs1 "O\tr,0,4"
573-
#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5"
574-
#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6"
575-
#define rv_fmt_rd_rs1_imm "O\t0,1,i"
576-
#define rv_fmt_rd_rs1_offset "O\t0,1,i"
577-
#define rv_fmt_rd_offset_rs1 "O\t0,i(1)"
578-
#define rv_fmt_frd_offset_rs1 "O\t3,i(1)"
579-
#define rv_fmt_rd_csr_rs1 "O\t0,c,1"
580-
#define rv_fmt_rd_csr_zimm "O\t0,c,7"
581-
#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)"
582-
#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)"
583-
#define rv_fmt_rs1_rs2_offset "O\t1,2,o"
584-
#define rv_fmt_rs2_rs1_offset "O\t2,1,o"
585-
#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)"
586-
#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)"
587-
#define rv_fmt_rd "O\t0"
588-
#define rv_fmt_rd_zimm "O\t0,7"
589-
#define rv_fmt_rd_rs1 "O\t0,1"
590-
#define rv_fmt_rd_rs2 "O\t0,2"
591-
#define rv_fmt_rs1_offset "O\t1,o"
592-
#define rv_fmt_rs2_offset "O\t2,o"
540+
static const char rv_fmt_none[] = "O\t";
541+
static const char rv_fmt_rs1[] = "O\t1";
542+
static const char rv_fmt_offset[] = "O\to";
543+
static const char rv_fmt_pred_succ[] = "O\tp,s";
544+
static const char rv_fmt_rs1_rs2[] = "O\t1,2";
545+
static const char rv_fmt_rd_imm[] = "O\t0,i";
546+
static const char rv_fmt_rd_offset[] = "O\t0,o";
547+
static const char rv_fmt_rd_rs1_rs2[] = "O\t0,1,2";
548+
static const char rv_fmt_frd_rs1[] = "O\t3,1";
549+
static const char rv_fmt_rd_frs1[] = "O\t0,4";
550+
static const char rv_fmt_rd_frs1_frs2[] = "O\t0,4,5";
551+
static const char rv_fmt_frd_frs1_frs2[] = "O\t3,4,5";
552+
static const char rv_fmt_rm_frd_frs1[] = "O\tr,3,4";
553+
static const char rv_fmt_rm_frd_rs1[] = "O\tr,3,1";
554+
static const char rv_fmt_rm_rd_frs1[] = "O\tr,0,4";
555+
static const char rv_fmt_rm_frd_frs1_frs2[] = "O\tr,3,4,5";
556+
static const char rv_fmt_rm_frd_frs1_frs2_frs3[] = "O\tr,3,4,5,6";
557+
static const char rv_fmt_rd_rs1_imm[] = "O\t0,1,i";
558+
static const char rv_fmt_rd_rs1_offset[] = "O\t0,1,i";
559+
static const char rv_fmt_rd_offset_rs1[] = "O\t0,i(1)";
560+
static const char rv_fmt_frd_offset_rs1[] = "O\t3,i(1)";
561+
static const char rv_fmt_rd_csr_rs1[] = "O\t0,c,1";
562+
static const char rv_fmt_rd_csr_zimm[] = "O\t0,c,7";
563+
static const char rv_fmt_rs2_offset_rs1[] = "O\t2,i(1)";
564+
static const char rv_fmt_frs2_offset_rs1[] = "O\t5,i(1)";
565+
static const char rv_fmt_rs1_rs2_offset[] = "O\t1,2,o";
566+
static const char rv_fmt_rs2_rs1_offset[] = "O\t2,1,o";
567+
static const char rv_fmt_aqrl_rd_rs2_rs1[] = "OAR\t0,2,(1)";
568+
static const char rv_fmt_aqrl_rd_rs1[] = "OAR\t0,(1)";
569+
static const char rv_fmt_rd[] = "O\t0";
570+
static const char rv_fmt_rd_zimm[] = "O\t0,7";
571+
static const char rv_fmt_rd_rs1[] = "O\t0,1";
572+
static const char rv_fmt_rd_rs2[] = "O\t0,2";
573+
static const char rv_fmt_rs1_offset[] = "O\t1,o";
574+
static const char rv_fmt_rs2_offset[] = "O\t2,o";
593575

594576
/* pseudo-instruction constraints */
595577

@@ -632,7 +614,7 @@ static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, r
632614
static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end };
633615
static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
634616
static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end };
635-
static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
617+
static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc82, rvc_end };
636618
static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end };
637619
static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end };
638620
static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end };
@@ -1034,22 +1016,22 @@ const rv_opcode_data opcode_data[] = {
10341016
{ "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
10351017
{ "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
10361018
{ "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1037-
{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1019+
{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
10381020
{ "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
10391021
{ "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
10401022
{ "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
10411023
{ "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 },
10421024
{ "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
10431025
{ "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
10441026
{ "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1045-
{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1027+
{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
10461028
{ "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
10471029
{ "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1048-
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1049-
{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui },
1050-
{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli },
1051-
{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai },
1052-
{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi },
1030+
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
1031+
{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui, rvcd_imm_nz },
1032+
{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli, rvcd_imm_nz },
1033+
{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai, rvcd_imm_nz },
1034+
{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi, rvcd_imm_nz },
10531035
{ "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
10541036
{ "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
10551037
{ "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
@@ -1059,7 +1041,7 @@ const rv_opcode_data opcode_data[] = {
10591041
{ "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
10601042
{ "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
10611043
{ "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
1062-
{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli },
1044+
{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli, rvcd_imm_nz },
10631045
{ "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
10641046
{ "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
10651047
{ "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
@@ -2522,111 +2504,16 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
25222504
uint8_t rd = dec->rd, rs1 = dec->rs1, rs2 = dec->rs2;
25232505
while (*c != rvc_end) {
25242506
switch (*c) {
2525-
case rvc_simm_6:
2526-
if (!(imm >= -32 && imm < 32)) {
2527-
return false;
2528-
}
2529-
break;
2530-
case rvc_imm_6:
2531-
if (!(imm <= 63)) {
2532-
return false;
2533-
}
2534-
break;
2535-
case rvc_imm_7:
2536-
if (!(imm <= 127)) {
2537-
return false;
2538-
}
2539-
break;
2540-
case rvc_imm_8:
2541-
if (!(imm <= 255)) {
2542-
return false;
2543-
}
2544-
break;
2545-
case rvc_imm_9:
2546-
if (!(imm <= 511)) {
2547-
return false;
2548-
}
2549-
break;
2550-
case rvc_imm_10:
2551-
if (!(imm <= 1023)) {
2552-
return false;
2553-
}
2554-
break;
2555-
case rvc_imm_12:
2556-
if (!(imm <= 4095)) {
2557-
return false;
2558-
}
2559-
break;
2560-
case rvc_imm_18:
2561-
if (!(imm <= 262143)) {
2562-
return false;
2563-
}
2564-
break;
2565-
case rvc_imm_nz:
2566-
if (!(imm != 0)) {
2567-
return false;
2568-
}
2569-
break;
2570-
case rvc_imm_x2:
2571-
if (!((imm & 0b1) == 0)) {
2572-
return false;
2573-
}
2574-
break;
2575-
case rvc_imm_x4:
2576-
if (!((imm & 0b11) == 0)) {
2577-
return false;
2578-
}
2579-
break;
2580-
case rvc_imm_x8:
2581-
if (!((imm & 0b111) == 0)) {
2582-
return false;
2583-
}
2584-
break;
2585-
case rvc_imm_x16:
2586-
if (!((imm & 0b1111) == 0)) {
2587-
return false;
2588-
}
2589-
break;
2590-
case rvc_rd_b3:
2591-
if (!(rd >= 8 && rd <= 15)) {
2592-
return false;
2593-
}
2594-
break;
2595-
case rvc_rs1_b3:
2596-
if (!(rs1 >= 8 && rs1 <= 15)) {
2597-
return false;
2598-
}
2599-
break;
2600-
case rvc_rs2_b3:
2601-
if (!(rs2 >= 8 && rs2 <= 15)) {
2602-
return false;
2603-
}
2604-
break;
2605-
case rvc_rd_eq_rs1:
2606-
if (!(rd == rs1)) {
2607-
return false;
2608-
}
2609-
break;
26102507
case rvc_rd_eq_ra:
26112508
if (!(rd == 1)) {
26122509
return false;
26132510
}
26142511
break;
2615-
case rvc_rd_eq_sp:
2616-
if (!(rd == 2)) {
2617-
return false;
2618-
}
2619-
break;
26202512
case rvc_rd_eq_x0:
26212513
if (!(rd == 0)) {
26222514
return false;
26232515
}
26242516
break;
2625-
case rvc_rs1_eq_sp:
2626-
if (!(rs1 == 2)) {
2627-
return false;
2628-
}
2629-
break;
26302517
case rvc_rs1_eq_x0:
26312518
if (!(rs1 == 0)) {
26322519
return false;
@@ -2637,26 +2524,6 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
26372524
return false;
26382525
}
26392526
break;
2640-
case rvc_rd_ne_x0_x2:
2641-
if (!(rd != 0 && rd != 2)) {
2642-
return false;
2643-
}
2644-
break;
2645-
case rvc_rd_ne_x0:
2646-
if (!(rd != 0)) {
2647-
return false;
2648-
}
2649-
break;
2650-
case rvc_rs1_ne_x0:
2651-
if (!(rs1 != 0)) {
2652-
return false;
2653-
}
2654-
break;
2655-
case rvc_rs2_ne_x0:
2656-
if (!(rs2 != 0)) {
2657-
return false;
2658-
}
2659-
break;
26602527
case rvc_rs2_eq_rs1:
26612528
if (!(rs2 == rs1)) {
26622529
return false;
@@ -2933,26 +2800,38 @@ static void decode_inst_decompress_rv32(rv_decode *dec)
29332800
{
29342801
int decomp_op = opcode_data[dec->op].decomp_rv32;
29352802
if (decomp_op != rv_op_illegal) {
2936-
dec->op = decomp_op;
2937-
dec->codec = opcode_data[decomp_op].codec;
2803+
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
2804+
dec->op = rv_op_illegal;
2805+
} else {
2806+
dec->op = decomp_op;
2807+
dec->codec = opcode_data[decomp_op].codec;
2808+
}
29382809
}
29392810
}
29402811

29412812
static void decode_inst_decompress_rv64(rv_decode *dec)
29422813
{
29432814
int decomp_op = opcode_data[dec->op].decomp_rv64;
29442815
if (decomp_op != rv_op_illegal) {
2945-
dec->op = decomp_op;
2946-
dec->codec = opcode_data[decomp_op].codec;
2816+
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
2817+
dec->op = rv_op_illegal;
2818+
} else {
2819+
dec->op = decomp_op;
2820+
dec->codec = opcode_data[decomp_op].codec;
2821+
}
29472822
}
29482823
}
29492824

29502825
static void decode_inst_decompress_rv128(rv_decode *dec)
29512826
{
29522827
int decomp_op = opcode_data[dec->op].decomp_rv128;
29532828
if (decomp_op != rv_op_illegal) {
2954-
dec->op = decomp_op;
2955-
dec->codec = opcode_data[decomp_op].codec;
2829+
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
2830+
dec->op = rv_op_illegal;
2831+
} else {
2832+
dec->op = decomp_op;
2833+
dec->codec = opcode_data[decomp_op].codec;
2834+
}
29562835
}
29572836
}
29582837

hw/riscv/Makefile.objs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
obj-y += boot.o
12
obj-y += riscv_htif.o
23
obj-y += riscv_hart.o
34
obj-y += sifive_e.o

0 commit comments

Comments
 (0)