+/**
+ * Decode the trap instruction at the given PC.
+ *
+ * @param trp information about trap to be filled
+ * @param sig signal number
+ * @param xpc exception PC
+ * @param es execution state of the machine
+ * @return true if trap was decoded successfully, false otherwise.
+ */
+bool md_trap_decode(trapinfo_t* trp, int sig, void* xpc, executionstate_t* es)
+{
+ switch (sig) {
+ case TRAP_SIGILL:
+ if (N_RR_GET_OPC(xpc) == OPC_ILL) {
+ int32_t reg = N_ILL_GET_REG(xpc);
+ trp->type = N_ILL_GET_TYPE(xpc);
+ trp->value = es->intregs[reg];
+ return true;
+ }
+ return false;
+
+ case TRAP_SIGSEGV:
+ {
+ int is_null;
+ int32_t base;
+ switch (N_RX_GET_OPC(xpc)) {
+ case OPC_L:
+ case OPC_ST:
+ case OPC_CL: /* array size check on NULL array */
+ base = N_RX_GET_BASE(xpc);
+ if (base == 0) {
+ is_null = 1;
+ } else if (es->intregs[base] == 0) {
+ is_null = 1;
+ } else {
+ is_null = 0;
+ }
+ break;
+ default:
+ is_null = 0;
+ break;
+ }
+
+ // Check for implicit NullPointerException.
+ if (is_null) {
+ trp->type = TRAP_NullPointerException;
+ trp->value = 0;
+ return true;
+ }
+
+ return false;
+ }
+
+ case TRAP_SIGFPE:
+ {
+ if (N_RR_GET_OPC(xpc) == OPC_DR) {
+ int r2 = N_RR_GET_REG2(xpc);
+ if (es->intregs[r2] == 0) {
+ trp->type = TRAP_ArithmeticException;
+ trp->value = 0;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ default:
+ return false;
+ }
+}
+
+
+