@@ -703,6 +703,21 @@ void raise_exception(uint32_t cause, uint32_t tval)
703703 return ;
704704 }
705705
706+ switch (cause ){
707+ case CAUSE_MACHINE_ECALL :
708+ printf ("Unimplement Machine ecall!\n" );
709+ return ;
710+ case CAUSE_USER_ECALL :
711+ printf ("Unimplement User ecall!\n" );
712+ return ;
713+ case CAUSE_SUPERVISOR_ECALL :
714+ printf ("Unimplement Supervisor ecall!\n" );
715+ return ;
716+ case CAUSE_HYPERVISOR_ECALL :
717+ printf ("Unimplement Hypervisor ecall!\n" );
718+ return ;
719+ }
720+
706721 if (priv <= PRV_S ) {
707722 /* delegate the exception to the supervisor priviledge */
708723 if (cause & CAUSE_INTERRUPT )
@@ -780,7 +795,7 @@ int raise_interrupt()
780795
781796/* read 32-bit instruction from memory by PC */
782797
783- uint32_t get_insn32 (uint32_t pc , uint32_t * insn )
798+ unsigned char get_insn32 (uint32_t pc , uint32_t * insn )
784799{
785800#ifdef DEBUG_EXTRA
786801 if (pc && pc < minmemr ) minmemr = pc ;
@@ -789,9 +804,12 @@ uint32_t get_insn32(uint32_t pc, uint32_t *insn)
789804 uint32_t ptr = pc - ram_start ;
790805 if (ptr > RAM_SIZE ) return 1 ;
791806 uint8_t * p = ram + ptr ;
807+ #ifdef DEBUG_OUTPUT
808+ printf ("address %08x\n" , p [0 ] | (p [1 ] << 8 ) | (p [2 ] << 16 ) | (p [3 ] << 24 ));
809+ #endif
792810#ifdef RV32C
793811 if ((p [0 ] & 0x03 ) < 3 ){
794- * insn = (p [0 ] | (p [1 ] << 8 )) & 0x0000ffff ;
812+ * insn = (p [0 ] | (( p [1 ] << 8 ) & 0x0000ffff )) ;
795813 return CINSN ;
796814 }
797815#endif
@@ -1682,8 +1700,9 @@ void execute_instruction()
16821700 compliance test specific: if bit 0 of gp (x3) is 0, it is a syscall,
16831701 otherwise it is the program end, with the exit code in the bits 31:1
16841702 */
1703+ /* I modified the ecall convention which disabled the program end*/
16851704 if (begin_signature ) {
1686- if (reg [3 ] & 1 ) {
1705+ if (0 ){ // reg[3] & 1) {
16871706#ifdef DEBUG_OUTPUT
16881707 printf ("program end, result: %04x\n" , reg [3 ] >> 1 );
16891708#endif
@@ -1943,15 +1962,35 @@ void execute_instruction()
19431962 switch (funct3 ){
19441963 case 0 : /* C.NOP, C.ADDI */
19451964 if ( ((midpart >> 5 ) & 0x1f ) == 0 ){ /* C.NOP*/
1965+ #ifdef DEBUG_EXTRA
1966+ dprintf (">>> C.NOP\n" );
1967+ #endif
19461968 return ;
19471969 } else {
1948- rs1 = rd = (midpart >> 5 ) & 0x1f ;
1970+ #ifdef DEBUG_EXTRA
1971+ dprintf (">>> C.ADDI\n" );
1972+ #endif
1973+ rs1 = rd = ((midpart >> 5 ) & 0x1f ) + 8 ;
19491974 imm = (midpart & 0x1f ) | ((midpart >> 5 ) & 0x20 );
19501975 val = reg [rs1 ] + imm ;
19511976 }
19521977 break ;
19531978 case 1 : /* C.JAL, C.ADDIW */
1979+ #ifdef DEBUG_EXTRA
19541980 switch (XLEN ){
1981+ case 32 :
1982+ dprintf (">>> C.JAL\n" );
1983+ break ;
1984+ case 64 :
1985+ case 128 :
1986+ dprintf (">>> C.ADDIW\n" );
1987+ break ;
1988+ default :
1989+ dprintf (">>> Unknow XLEN\n" );
1990+ break ;
1991+ }
1992+ #endif
1993+ switch (XLEN ) {
19551994 case 32 :
19561995 imm = (midpart & 0x400 ) |
19571996 ((midpart << 3 ) & 0x200 ) |
@@ -1971,24 +2010,235 @@ void execute_instruction()
19712010 break ;
19722011 case 64 :
19732012 case 128 :
1974- rs1 = rd = (midpart >> 5 ) & 0x1f ;
2013+ rs1 = rd = (( midpart >> 5 ) & 0x1f ) ;
19752014 imm = (midpart >> (11 - 5 )) |
1976- midpart & 0x1f ;
2015+ ( midpart & 0x1f ) ;
19772016 val = reg [rs1 ] + imm ;
19782017 break ;
19792018 }
19802019 break ;
19812020 case 2 : /* C.LI */
2021+ #ifdef DEBUG_EXTRA
2022+ dprintf (">>> C.LI\n" );
2023+ #endif
2024+ rs1 = rd = ((midpart >> 5 ) & 0x1f );
2025+ imm = ((midpart >> 5 ) & 0x20 ) | (midpart & 0x1f );
2026+ val = imm ;
2027+ printf ("%08x, rd: %d\n" , val , rd );
19822028 break ;
19832029 case 3 : /* C.ADDI16SP, C.LUI */
2030+ #ifdef DEBUG_EXTRA
2031+ switch (rd ){
2032+ case 2 :
2033+ dprintf (">>> C.ADDI16SP\n" );
2034+ break ;
2035+ default :
2036+ dprintf (">>> C.LUI\n" );
2037+ }
2038+ #endif
2039+ rs1 = rd = ((midpart >> 5 ) & 0x1f );
2040+ switch (rd ){
2041+ case 2 :
2042+ imm = ((midpart >> 4 ) & 0x1 ) |
2043+ ((midpart << 1 ) & 0x2 ) |
2044+ ((midpart ) & 0x8 ) |
2045+ ((midpart << 2 ) & 0xc ) |
2046+ ((midpart >> 5 ) & 0x10 );
2047+ imm = imm << 4 ;
2048+ val = reg [rd ] + imm ;
2049+ break ;
2050+ default :
2051+ imm = (midpart & 0x1f ) | ((midpart >> 5 ) & 0x20 );
2052+ imm = ((imm << 12 ) & 0xfffff000 );
2053+ imm = imm << 14 >> 14 ;
2054+ if (rd != 0 )
2055+ val = reg [rd ] | imm ;
2056+ break ;
2057+ }
19842058 break ;
19852059 case 4 : /* C.SRLI, C.SRLI64, C.SRAI, C.SRAI64, C.ANDI, C.SUB, C.XOR, C.OR, C.AND, C.SUBW, C.ADDW*/
2060+ switch (((midpart >> 8 ) & 0x3 )){
2061+ case 0 : /* C.SRLI C.SRLI64 */
2062+ #ifdef DEBUG_EXTRA
2063+ switch (XLEN ){
2064+ case 32 :
2065+ case 64 :
2066+ dprintf (">>> C.SRLI\n" );
2067+ break ;
2068+ case 128 :
2069+ dprintf (">>> C.SRLI64\n" );
2070+ break ;
2071+ }
2072+ #endif
2073+ switch (XLEN ){
2074+ case 32 :
2075+ case 64 :
2076+ rs1 = rd = ((midpart >> 5 ) & 0x1f ) + 8 ;
2077+ imm = (midpart & 0xf ) | (midpart >> 5 & 0x10 );
2078+ val = reg [rs1 ];
2079+ break ;
2080+ case 128 :
2081+ rs1 = rd = ((midpart >> 5 ) & 0x1f ) + 8 ;
2082+ imm = 64 ;
2083+ val = reg [rs1 ];
2084+ break ;
2085+ }
2086+ val = val >> imm ;
2087+ break ;
2088+ case 1 : /* C.SRAI C.SRAI64 */
2089+ #ifdef DEBUG_EXTRA
2090+ switch (XLEN ){
2091+ case 32 :
2092+ case 64 :
2093+ dprintf (">>> C.SRAI\n" );
2094+ case 128 :
2095+ dprintf (">>> C.SRAI64\n" );
2096+ }
2097+ #endif
2098+ switch (XLEN ){
2099+ case 32 : case 64 :
2100+ rs1 = rd = ((midpart >> 5 ) & 0x1f ) + 8 ;
2101+ imm = (midpart & 0xf ) | ((midpart >> 5 ) & 0x10 );
2102+ val = reg [rs1 ];
2103+ break ;
2104+ case 128 :
2105+ rs1 = rd = ((midpart >> 5 ) & 0x1f ) + 8 ;
2106+ imm = 64 ;
2107+ val = reg [rs1 ];
2108+ break ;
2109+ }
2110+ val = val << imm ;
2111+ break ;
2112+ case 2 : /* C.ANDI */
2113+ #ifdef DEBUG_EXTRA
2114+ dprintf (">>> C.ANDI\n" );
2115+ #endif
2116+ rs1 = rd = ((midpart >> 5 ) & 0x7 ) + 8 ;
2117+ imm = (midpart & 0x1f ) | ((midpart >> 5 ) & 0x10 );
2118+ val = reg [rs1 ];
2119+ val = val & imm ;
2120+ break ;
2121+ case 3 : /* C.SUB, C.XOR, C.OR, C.AND, C.SUBW, C.ADDW */
2122+ rs2 = (midpart & 0x7 ) + 8 ;
2123+ rs1 = rd = ((midpart >> 5 ) & 0x7 ) + 8 ;
2124+ switch (((midpart >> 3 ) & 0x3 ) | ((midpart >> 8 ) & 0x4 ) ){
2125+ case 0 : /* C.SUB */
2126+ #ifdef DEBUG_EXTRA
2127+ dprintf (">>> C.SUB\n" );
2128+ #endif
2129+ val = reg [rd ] - reg [rs2 ];
2130+ break ;
2131+ case 1 : /* C.XOR */
2132+ #ifdef DEBUG_EXTRA
2133+ dprintf (">>> C.XOR\n" );
2134+ #endif
2135+ val = reg [rd ] ^ reg [rs2 ];
2136+ break ;
2137+ case 2 : /* C.OR */
2138+ #ifdef DEBUG_EXTRA
2139+ dprintf (">>> C.OR\n" );
2140+ #endif
2141+ val = reg [rd ] | reg [rs2 ];
2142+ break ;
2143+ case 3 : /* C.AND */
2144+ #ifdef DEBUG_EXTRA
2145+ dprintf (">>> C.AND\n" );
2146+ #endif
2147+ val = reg [rd ] & reg [rs2 ];
2148+ break ;
2149+ case 4 : /* C.SUBW */
2150+ #ifdef DEBUG_EXTRA
2151+ dprintf (">>> C.SUBW\n" );
2152+ #endif
2153+ val = reg [rd ] - reg [rs2 ];
2154+ if (XLEN == 128 ){
2155+ val = (int32_t ) (val << 96 ) >> 96 ;
2156+ }else if (XLEN == 64 ){
2157+ val = (int32_t ) (val << 32 ) >> 32 ;
2158+ }else {
2159+ raise_exception (CAUSE_ILLEGAL_INSTRUCTION , insn );
2160+ }
2161+ break ;
2162+ case 5 : /* C.ADDW */
2163+ #ifdef DEBUG_EXTRA
2164+ dprintf (">>> C.ADDW\n" );
2165+ #endif
2166+ val = reg [rd ] + reg [rs2 ];
2167+ if (XLEN == 128 ){
2168+ val = (int32_t ) (val << 96 ) >> 96 ;
2169+ }else if (XLEN == 64 ){
2170+ val = (int32_t ) (val << 32 ) >> 32 ;
2171+ }else {
2172+ raise_exception (CAUSE_ILLEGAL_INSTRUCTION , insn );
2173+ }
2174+ break ;
2175+ case 6 :
2176+ case 7 :
2177+ /* NOP */
2178+ break ;
2179+ }
2180+ }
19862181 break ;
19872182 case 5 : /* C.J */
2183+ #ifdef DEBUG_EXTRA
2184+ dprintf (">>> C.J\n" );
2185+ #endif
2186+ rd = 0 ;
2187+ imm = ((midpart >> 1 ) & 0x7 ) |
2188+ ((midpart >> 6 ) & 0x8 ) |
2189+ ((midpart << 5 ) & 0x10 ) |
2190+ ((midpart ) & 0x20 ) |
2191+ ((midpart << 2 ) & 0x40 ) |
2192+ ((midpart ) & 0x180 )|
2193+ ((midpart << 3 ) & 0x200 )|
2194+ ((midpart ) & 0x400 );
2195+ imm = (imm << 1 ) << 20 >> 20 ;
2196+ next_pc = (int32_t )(pc + imm );
2197+ if (next_pc > pc ) forward_counter ++ ;
2198+ else backward_counter ++ ;
2199+ jump_counter ++ ;
19882200 break ;
19892201 case 6 : /* C.BEQZ */
2202+ #ifdef DEBUG_EXTRA
2203+ dprintf (">>> C.BEQZ\n" );
2204+ #endif
2205+ rs1 = ((midpart >> 5 ) & 0x7 ) + 8 ;
2206+ rd = 0 ;
2207+ if (reg [rs1 ] == 0 ){
2208+ imm = ((midpart >> 1 ) & 0x3 ) |
2209+ ((midpart >> 3 ) & 0xc ) |
2210+ ((midpart << 4 ) & 0x10 ) |
2211+ ((midpart << 2 ) & 0x60 ) |
2212+ ((midpart ) & 0x80 );
2213+ imm = (imm << 1 ) << 23 >> 23 ;
2214+ next_pc = (int32_t )(pc + imm );
2215+ if (next_pc > pc ) forward_counter ++ ;
2216+ else backward_counter ++ ;
2217+ jump_counter ++ ;
2218+ }
19902219 break ;
19912220 case 7 : /* C.BNEZ */
2221+ #ifdef DEBUG_EXTRA
2222+ dprintf (">>> C.BNEZ\n" );
2223+ #endif
2224+ rs1 = ((midpart >> 5 ) & 0x7 ) + 8 ;
2225+ rd = 0 ;
2226+ imm = 0 ;
2227+ if (reg [rs1 ] != 0 ){
2228+ imm = ((midpart >> 1 ) & 0x3 ) |
2229+ ((midpart >> 6 ) & 0xc ) |
2230+ ((midpart << 4 ) & 0x10 ) |
2231+ ((midpart << 2 ) & 0x60 ) |
2232+ ((midpart ) & 0x80 );
2233+ imm = (imm << 1 ) << 23 >> 23 ;
2234+ next_pc = (int32_t )(pc + imm );
2235+ if (next_pc > pc ) forward_counter ++ ;
2236+ else backward_counter ++ ;
2237+ jump_counter ++ ;
2238+ }
2239+ #ifdef DEBUG_EXTRA
2240+ printf ("rd : %d, rs1: %d, imm: %d, reg[rs1] : %d, pc: %08x, next_pc: %08x\n" , rd , rs1 , imm , reg [rs1 ]);
2241+ #endif
19922242 break ;
19932243 default :
19942244 raise_exception (CAUSE_ILLEGAL_INSTRUCTION , insn );
@@ -2042,11 +2292,11 @@ void riscv_cpu_interp_x32()
20422292 /* Compressed or normal */
20432293 insn_type = get_insn32 (pc , & insn );
20442294#ifdef RV32C
2045- if (insn_type )
2295+ if (insn_type == CINSN )
20462296 next_pc = pc + 2 ;
20472297#endif
20482298#ifdef DEBUG_EXTRA
2049- printf ("insn : %#x \n" , insn );
2299+ printf ("insn_type : %s \n" , insn_type == CINSN ? "CINSN" : "INSN" );
20502300#endif
20512301 insn_counter ++ ;
20522302
@@ -2056,8 +2306,8 @@ void riscv_cpu_interp_x32()
20562306 execute_instruction ();
20572307 }
20582308
2059- /* test for misaligned fetches */
2060- if (next_pc & 3 ) {
2309+ /* test for misaligned fetches , in order to match the compressed instruction. */
2310+ if (next_pc & 0x1 ) {
20612311 raise_exception (CAUSE_MISALIGNED_FETCH , next_pc );
20622312 }
20632313
0 commit comments