diff options
author | Christopher Celio <celio@eecs.berkeley.edu> | 2012-09-07 21:56:51 -0700 |
---|---|---|
committer | Christopher Celio <celio@eecs.berkeley.edu> | 2012-09-07 21:56:51 -0700 |
commit | d6a522404a38405ecfad78839d4c29bf5cb02e9b (patch) | |
tree | 3ccddd3e3d13a82fe187c25cfb45203108e9035e /pk | |
parent | 6336ef155fabdd15eecf11949b7e13a49e279738 (diff) | |
download | pk-d6a522404a38405ecfad78839d4c29bf5cb02e9b.zip pk-d6a522404a38405ecfad78839d4c29bf5cb02e9b.tar.gz pk-d6a522404a38405ecfad78839d4c29bf5cb02e9b.tar.bz2 |
Added rough emulation support for div/rem/mul.
Diffstat (limited to 'pk')
-rw-r--r-- | pk/handlers.c | 8 | ||||
-rw-r--r-- | pk/int.c | 66 | ||||
-rw-r--r-- | pk/pk.h | 2 | ||||
-rw-r--r-- | pk/pk.mk.in | 2 |
4 files changed, 77 insertions, 1 deletions
diff --git a/pk/handlers.c b/pk/handlers.c index 817f14d..8b959e8 100644 --- a/pk/handlers.c +++ b/pk/handlers.c @@ -4,7 +4,7 @@ int have_fp = 1; // initialized to 1 because it can't be in the .bss section! int have_vector = 1; - + static void handle_vector_disabled(trapframe_t* tf) { if (have_vector) @@ -41,6 +41,12 @@ static void handle_illegal_instruction(trapframe_t* tf) } #endif + if(emulate_int(tf) == 0) + { + advance_pc(tf); + return; + } + dump_tf(tf); panic("An illegal instruction was executed!"); } diff --git a/pk/int.c b/pk/int.c new file mode 100644 index 0000000..1424e73 --- /dev/null +++ b/pk/int.c @@ -0,0 +1,66 @@ +#include "pk.h" +#include "pcr.h" + + +#include "softint.h" +#include "riscv-opc.h" +#include <stdint.h> + +#define noisy 0 + + +int emulate_int(trapframe_t* tf) +{ + if(noisy) + printk("Int emulation at pc %lx, insn %x\n",tf->epc,(uint32_t)tf->insn); + + #define RS1 ((tf->insn >> 22) & 0x1F) + #define RS2 ((tf->insn >> 17) & 0x1F) + #define RD ((tf->insn >> 27) & 0x1F) + +// #define XRS1 (tf->gpr[RS1]) +// #define XRS2 (tf->gpr[RS2]) + #define XRD (tf->gpr[RD]) + + unsigned long xrs1 = tf->gpr[RS1]; + unsigned long xrs2 = tf->gpr[RS2]; + + #define IS_INSN(x) ((tf->insn & MASK_ ## x) == MATCH_ ## x) + + if(IS_INSN(DIV)) + { + if(noisy) + printk("emulating div\n"); + XRD = softint_divu(xrs1, xrs2); + } + else if(IS_INSN(DIVU)) + { + if(noisy) + printk("emulating divu\n"); + XRD = softint_divu( xrs1, xrs2); + } + else if(IS_INSN(MUL)) + { + if(noisy) + printk("emulating mul\n"); + XRD = softint_mul(xrs1, xrs2); + } + else if(IS_INSN(REM)) + { + if(noisy) + printk("emulating rem\n"); + XRD = softint_remu(xrs1, xrs2); + } + else if(IS_INSN(REMU)) + { + if(noisy) + printk("emulating remu\n"); + XRD = softint_remu(xrs1, xrs2); + } + else + return -1; + + return 0; +} + + @@ -32,6 +32,8 @@ extern uint32_t mem_mb; int emulate_fp(trapframe_t*); void init_fp(trapframe_t* tf); +int emulate_int(trapframe_t*); + void printk(const char* s, ...); void init_tf(trapframe_t*, long pc, long sp, int user64); void pop_tf(trapframe_t*); diff --git a/pk/pk.mk.in b/pk/pk.mk.in index 19e630c..2a3c863 100644 --- a/pk/pk.mk.in +++ b/pk/pk.mk.in @@ -1,6 +1,7 @@ pk_subproject_deps = \ softfloat_riscv \ softfloat \ + softint \ pk_hdrs = \ pk.h \ @@ -19,6 +20,7 @@ pk_c_srcs = \ handlers.c \ frontend.c \ fp.c \ + int.c \ memset.c \ strlen.c \ elf.c \ |