@@ -94,6 +94,10 @@ original copyright:
9494#define DEBUG_EXTRA
9595#endif
9696
97+ #if 1
98+ #define RV32C
99+ #endif
100+
97101/* added by Shaos: */
98102#define STRICT_RV32I
99103#define FALSE (0)
@@ -216,12 +220,18 @@ int machine_running = TRUE;
216220#define PRV_H 2
217221#define PRV_M 3
218222
223+ /* Instruction state*/
224+ #define CINSN 1
225+ #define INSN 0
226+ unsigned char insn_type ;
227+
219228/* CPU state */
220229uint32_t pc ;
221230uint32_t next_pc ;
222231uint32_t insn ;
223232uint32_t reg [32 ];
224233
234+
225235uint8_t priv = PRV_M ; /* see PRV_x */
226236uint8_t fs ; /* MSTATUS_FS value */
227237uint8_t mxl ; /* MXL field in MISA register */
@@ -770,7 +780,7 @@ int raise_interrupt()
770780
771781/* read 32-bit instruction from memory by PC */
772782
773- uint32_t get_insn32 (uint32_t pc )
783+ uint32_t get_insn32 (uint32_t pc , uint32_t * insn )
774784{
775785#ifdef DEBUG_EXTRA
776786 if (pc && pc < minmemr ) minmemr = pc ;
@@ -779,9 +789,14 @@ uint32_t get_insn32(uint32_t pc)
779789 uint32_t ptr = pc - ram_start ;
780790 if (ptr > RAM_SIZE ) return 1 ;
781791 uint8_t * p = ram + ptr ;
782- if ((p [0 ] & 0x03 ) < 3 )
783- return p [0 ] | (p [1 ] << 8 );
784- return p [0 ] | (p [1 ] << 8 ) | (p [2 ] << 16 ) | (p [3 ] << 24 );
792+ #ifdef RV32C
793+ if ((p [0 ] & 0x03 ) < 3 ){
794+ * insn = (p [0 ] | (p [1 ] << 8 )) & 0x0000ffff ;
795+ return CINSN ;
796+ }
797+ #endif
798+ * insn = p [0 ] | (p [1 ] << 8 ) | (p [2 ] << 16 ) | (p [3 ] << 24 );
799+ return INSN ;
785800}
786801
787802/* read 8-bit data from memory */
@@ -1055,10 +1070,22 @@ void execute_instruction()
10551070 int32_t imm , cond , err ;
10561071 uint32_t addr , val = 0 , val2 ;
10571072
1058- opcode = insn & 0x7f ;
1059- rd = (insn >> 7 ) & 0x1f ;
1060- rs1 = (insn >> 15 ) & 0x1f ;
1061- rs2 = (insn >> 20 ) & 0x1f ;
1073+ uint16_t midpart ;
1074+
1075+ if (insn_type == INSN ){
1076+ opcode = insn & 0x7f ;
1077+ rd = (insn >> 7 ) & 0x1f ;
1078+ rs1 = (insn >> 15 ) & 0x1f ;
1079+ rs2 = (insn >> 20 ) & 0x1f ;
1080+ }
1081+
1082+ #ifdef RV32C
1083+ if (insn_type == CINSN ){
1084+ opcode = insn & 0x3 ;
1085+ }
1086+ #endif
1087+
1088+
10621089
10631090 switch (opcode ) {
10641091
@@ -1906,10 +1933,72 @@ void execute_instruction()
19061933 break ;
19071934
19081935#endif
1909- #ifndef RV32C
1910-
1911- case 1 : /* Compressed insn */
1912-
1936+ #ifdef RV32C
1937+ /* Compressed insn */
1938+ case 0 :
1939+ break ;
1940+ case 1 :
1941+ funct3 = (insn >> 13 ) & 0x7 ;
1942+ midpart = (insn >> 2 ) & 0x07ff ;
1943+ switch (funct3 ){
1944+ case 0 : /* C.NOP, C.ADDI */
1945+ if ( ((midpart >> 5 ) & 0x1f ) == 0 ){ /* C.NOP*/
1946+ return ;
1947+ } else {
1948+ rs1 = rd = (midpart >> 5 ) & 0x1f ;
1949+ imm = (midpart & 0x1f ) | ((midpart >> 5 ) & 0x20 );
1950+ val = reg [rs1 ] + imm ;
1951+ }
1952+ break ;
1953+ case 1 : /* C.JAL, C.ADDIW */
1954+ switch (XLEN ){
1955+ case 32 :
1956+ imm = (midpart & 0x400 ) |
1957+ ((midpart << 3 ) & 0x200 ) |
1958+ (midpart & 0x170 ) |
1959+ ((midpart << 2 ) & 0x40 ) |
1960+ (midpart & 0x20 ) |
1961+ ((midpart << 4 ) & 0x10 ) |
1962+ ((midpart >> 6 ) & 0x8 ) |
1963+ ((midpart >> 1 ) & 0x7 );
1964+ imm = imm & 0xfffe ;
1965+ if (rd != 0 )
1966+ reg [1 ] = pc + 2 ; /* Store the link to x1 register */
1967+ next_pc = (int32_t )(pc + imm );
1968+ if (next_pc > pc ) forward_counter ++ ;
1969+ else backward_counter ++ ;
1970+ jump_counter ++ ;
1971+ break ;
1972+ case 64 :
1973+ case 128 :
1974+ rs1 = rd = (midpart >> 5 ) & 0x1f ;
1975+ imm = (midpart >> (11 - 5 )) |
1976+ midpart & 0x1f ;
1977+ val = reg [rs1 ] + imm ;
1978+ break ;
1979+ }
1980+ break ;
1981+ case 2 : /* C.LI */
1982+ break ;
1983+ case 3 : /* C.ADDI16SP, C.LUI */
1984+ break ;
1985+ case 4 : /* C.SRLI, C.SRLI64, C.SRAI, C.SRAI64, C.ANDI, C.SUB, C.XOR, C.OR, C.AND, C.SUBW, C.ADDW*/
1986+ break ;
1987+ case 5 : /* C.J */
1988+ break ;
1989+ case 6 : /* C.BEQZ */
1990+ break ;
1991+ case 7 : /* C.BNEZ */
1992+ break ;
1993+ default :
1994+ raise_exception (CAUSE_ILLEGAL_INSTRUCTION , insn );
1995+ return ;
1996+ }
1997+ if (rd != 0 ){
1998+ reg [rd ] = val ;
1999+ }
2000+ break ;
2001+ case 2 :
19132002 break ;
19142003
19152004#endif
@@ -1950,8 +2039,12 @@ void riscv_cpu_interp_x32()
19502039 if ((mip & mie ) != 0 && (mstatus & MSTATUS_MIE )) {
19512040 raise_interrupt ();
19522041 } else {
1953- /* normal instruction execution */
1954- insn = get_insn32 (pc );
2042+ /* Compressed or normal */
2043+ insn_type = get_insn32 (pc , & insn );
2044+ #ifdef RV32C
2045+ if (insn_type )
2046+ next_pc = pc + 2 ;
2047+ #endif
19552048#ifdef DEBUG_EXTRA
19562049 printf ("insn : %#x\n" , insn );
19572050#endif
0 commit comments