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/int.c | |
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/int.c')
-rw-r--r-- | pk/int.c | 66 |
1 files changed, 66 insertions, 0 deletions
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; +} + + |