Skip to content
This repository was archived by the owner on Jan 25, 2022. It is now read-only.

Commit d3ea623

Browse files
author
f74064054@mail.ncku.edu.tw
committed
Modified some implementataion detail to support compressed instruction
1 parent e097b23 commit d3ea623

File tree

10 files changed

+13664
-382
lines changed

10 files changed

+13664
-382
lines changed

debug.txt

Lines changed: 12249 additions & 0 deletions
Large diffs are not rendered by default.

emu-rv32i.c

Lines changed: 260 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)