@@ -87,33 +87,10 @@ typedef enum {
87
87
88
88
typedef enum {
89
89
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 ,
107
90
rvc_rd_eq_ra ,
108
- rvc_rd_eq_sp ,
109
91
rvc_rd_eq_x0 ,
110
- rvc_rs1_eq_sp ,
111
92
rvc_rs1_eq_x0 ,
112
93
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 ,
117
94
rvc_rs2_eq_rs1 ,
118
95
rvc_rs1_eq_ra ,
119
96
rvc_imm_eq_zero ,
@@ -527,14 +504,19 @@ typedef struct {
527
504
const rvc_constraint * constraints ;
528
505
} rv_comp_data ;
529
506
507
+ enum {
508
+ rvcd_imm_nz = 0x1
509
+ };
510
+
530
511
typedef struct {
531
512
const char * const name ;
532
513
const rv_codec codec ;
533
514
const char * const format ;
534
515
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 ;
538
520
} rv_opcode_data ;
539
521
540
522
/* register names */
@@ -555,41 +537,41 @@ static const char rv_freg_name_sym[32][5] = {
555
537
556
538
/* instruction formats */
557
539
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" ;
593
575
594
576
/* pseudo-instruction constraints */
595
577
@@ -632,7 +614,7 @@ static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, r
632
614
static const rvc_constraint rvcc_rdinstret [] = { rvc_rs1_eq_x0 , rvc_csr_eq_0xc02 , rvc_end };
633
615
static const rvc_constraint rvcc_rdcycleh [] = { rvc_rs1_eq_x0 , rvc_csr_eq_0xc80 , rvc_end };
634
616
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 };
636
618
static const rvc_constraint rvcc_frcsr [] = { rvc_rs1_eq_x0 , rvc_csr_eq_0x003 , rvc_end };
637
619
static const rvc_constraint rvcc_frrm [] = { rvc_rs1_eq_x0 , rvc_csr_eq_0x002 , rvc_end };
638
620
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[] = {
1034
1016
{ "fcvt.q.lu" , rv_codec_r_m , rv_fmt_rm_frd_rs1 , NULL , 0 , 0 , 0 },
1035
1017
{ "fmv.x.q" , rv_codec_r , rv_fmt_rd_frs1 , NULL , 0 , 0 , 0 },
1036
1018
{ "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 },
1038
1020
{ "c.fld" , rv_codec_cl_ld , rv_fmt_frd_offset_rs1 , NULL , rv_op_fld , rv_op_fld , 0 },
1039
1021
{ "c.lw" , rv_codec_cl_lw , rv_fmt_rd_offset_rs1 , NULL , rv_op_lw , rv_op_lw , rv_op_lw },
1040
1022
{ "c.flw" , rv_codec_cl_lw , rv_fmt_frd_offset_rs1 , NULL , rv_op_flw , 0 , 0 },
1041
1023
{ "c.fsd" , rv_codec_cs_sd , rv_fmt_frs2_offset_rs1 , NULL , rv_op_fsd , rv_op_fsd , 0 },
1042
1024
{ "c.sw" , rv_codec_cs_sw , rv_fmt_rs2_offset_rs1 , NULL , rv_op_sw , rv_op_sw , rv_op_sw },
1043
1025
{ "c.fsw" , rv_codec_cs_sw , rv_fmt_frs2_offset_rs1 , NULL , rv_op_fsw , 0 , 0 },
1044
1026
{ "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 },
1046
1028
{ "c.jal" , rv_codec_cj_jal , rv_fmt_rd_offset , NULL , rv_op_jal , 0 , 0 },
1047
1029
{ "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 },
1053
1035
{ "c.sub" , rv_codec_cs , rv_fmt_rd_rs1_rs2 , NULL , rv_op_sub , rv_op_sub , rv_op_sub },
1054
1036
{ "c.xor" , rv_codec_cs , rv_fmt_rd_rs1_rs2 , NULL , rv_op_xor , rv_op_xor , rv_op_xor },
1055
1037
{ "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[] = {
1059
1041
{ "c.j" , rv_codec_cj , rv_fmt_rd_offset , NULL , rv_op_jal , rv_op_jal , rv_op_jal },
1060
1042
{ "c.beqz" , rv_codec_cb , rv_fmt_rs1_rs2_offset , NULL , rv_op_beq , rv_op_beq , rv_op_beq },
1061
1043
{ "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 },
1063
1045
{ "c.fldsp" , rv_codec_ci_ldsp , rv_fmt_frd_offset_rs1 , NULL , rv_op_fld , rv_op_fld , rv_op_fld },
1064
1046
{ "c.lwsp" , rv_codec_ci_lwsp , rv_fmt_rd_offset_rs1 , NULL , rv_op_lw , rv_op_lw , rv_op_lw },
1065
1047
{ "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)
2522
2504
uint8_t rd = dec -> rd , rs1 = dec -> rs1 , rs2 = dec -> rs2 ;
2523
2505
while (* c != rvc_end ) {
2524
2506
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 ;
2610
2507
case rvc_rd_eq_ra :
2611
2508
if (!(rd == 1 )) {
2612
2509
return false;
2613
2510
}
2614
2511
break ;
2615
- case rvc_rd_eq_sp :
2616
- if (!(rd == 2 )) {
2617
- return false;
2618
- }
2619
- break ;
2620
2512
case rvc_rd_eq_x0 :
2621
2513
if (!(rd == 0 )) {
2622
2514
return false;
2623
2515
}
2624
2516
break ;
2625
- case rvc_rs1_eq_sp :
2626
- if (!(rs1 == 2 )) {
2627
- return false;
2628
- }
2629
- break ;
2630
2517
case rvc_rs1_eq_x0 :
2631
2518
if (!(rs1 == 0 )) {
2632
2519
return false;
@@ -2637,26 +2524,6 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
2637
2524
return false;
2638
2525
}
2639
2526
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 ;
2660
2527
case rvc_rs2_eq_rs1 :
2661
2528
if (!(rs2 == rs1 )) {
2662
2529
return false;
@@ -2933,26 +2800,38 @@ static void decode_inst_decompress_rv32(rv_decode *dec)
2933
2800
{
2934
2801
int decomp_op = opcode_data [dec -> op ].decomp_rv32 ;
2935
2802
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
+ }
2938
2809
}
2939
2810
}
2940
2811
2941
2812
static void decode_inst_decompress_rv64 (rv_decode * dec )
2942
2813
{
2943
2814
int decomp_op = opcode_data [dec -> op ].decomp_rv64 ;
2944
2815
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
+ }
2947
2822
}
2948
2823
}
2949
2824
2950
2825
static void decode_inst_decompress_rv128 (rv_decode * dec )
2951
2826
{
2952
2827
int decomp_op = opcode_data [dec -> op ].decomp_rv128 ;
2953
2828
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
+ }
2956
2835
}
2957
2836
}
2958
2837
0 commit comments