methoddesc *md;
s4 disp;
s4 i, t;
+ s4 stackslots;
/* get required compiler data */
M_NOP;
/* XXX jit-c-call */
- M_LDA(REG_SP, REG_SP, -(1 + FLT_ARG_CNT) * 8);
+ stackslots = 1 + FLT_ARG_CNT;
+ ALIGN_STACK_SLOTS(stackslots);
+
+ M_LDA(REG_SP, REG_SP, -(stackslots * 8));
/* save float argument registers */
M_DLD(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
}
*/
- M_LDA(REG_SP, REG_SP, (1 + FLT_ARG_CNT) * 8);
+ M_LDA(REG_SP, REG_SP, stackslots * 8);
/* mark trace code */
M_NOP;
- /* XXX jit-c-call */
- M_LDA(REG_SP, REG_SP, -(1 * 8));
+ /* XXX jit-c-call (keep stack aligned)*/
+ M_LDA(REG_SP, REG_SP, -(2 * 8));
M_DST(REG_FRESULT, REG_SP, JITSTACK);
M_DLD(REG_FRESULT, REG_SP, JITSTACK);
- M_LDA(REG_SP, REG_SP, 1 * 8);
+ M_LDA(REG_SP, REG_SP, 2 * 8);
/* mark trace code */
-/* src/vm/jit/alpha/linux/md.c - machine dependent Alpha Linux functions
+/* src/vm/jit/sparc64/solaris/md-os.c - machine dependent SPARC Solaris functions
Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
#include <assert.h>
#include <ucontext.h>
+/* work around name clash */
+#define REG_SP_OS REG_SP
#undef REG_SP
#include "vm/types.h"
+#include "vm/jit/sparc64/codegen.h"
#include "vm/jit/sparc64/md-abi.h"
#include "vm/exceptions.h"
#include "vm/jit/stacktrace.h"
+ptrint md_get_reg_from_context(mcontext_t *_mc, u4 rindex)
+{
+ ptrint val;
+ s8 *window;
+
+
+ /* return 0 for REG_ZERO */
+
+ if (rindex == 0)
+ return 0;
+
+
+ if (rindex <= 15) {
+
+ /* register is in global or out range, available in context */
+
+ }
+ else {
+ assert(rindex <= 31);
+
+ /* register is local or in, need to fetch from regsave area on stack */
+ /*
+ window = ctx->sigc_regs.u_regs[REG_SP] + BIAS;
+ val = window[rindex - 16];
+ */
+ }
+
+ return val;
+}
+
/* md_signal_handler_sigsegv ***************************************************
NullPointerException signal handler for hardware null pointer
u1 *sp;
u1 *ra;
u1 *xpc;
+ s4 d;
+ s4 s1;
+ s4 disp;
+ ptrint val;
+ s4 type;
+ java_objectheader *e;
_uc = (ucontext_t *) _p;
_mc = &_uc->uc_mcontext;
- instr = *((s4 *) (_mc->gregs[REG_PC]));
- /*addr = _mc->sc_regs[(instr >> 16) & 0x1f];*/
- addr = 0;
+ pv = (u1 *) md_get_reg_from_context(_mc, REG_PV_CALLEE);
+#if 0
+ sp = (u1 *) md_get_reg_from_context(ctx, REG_SP);
+ ra = (u1 *) md_get_reg_from_context(ctx, REG_RA_CALLEE); /* this is correct for leafs */
+ xpc = (u1 *) ctx->sigc_regs.tpc;
- if (addr == 0) {
+ /* get exception-throwing instruction */
+
+ mcode = *((u4 *) xpc);
+
+ d = M_OP3_GET_RD(mcode);
+ s1 = M_OP3_GET_RS(mcode);
+ disp = M_OP3_GET_IMM(mcode);
+
+ /* flush register windows? */
+
+ val = md_get_reg_from_context(ctx, d);
+
+ /* check for special-load */
+
+ if (s1 == REG_ZERO) {
+ /* we use the exception type as load displacement */
+
+ type = disp;
+ }
+ else {
+ /* This is a normal NPE: addr must be NULL and the NPE-type
+ define is 0. */
+
+ addr = md_get_reg_from_context(ctx, s1);
+ type = (s4) addr;
+ }
+#endif
+ e = exceptions_new_hardware_exception(pv, sp, ra, xpc, type, val);
+
+ /* set registers */
+
+ _mc->gregs[REG_G2] = (ptrint) e; /* REG_ITMP2_XPTR */
+ _mc->gregs[REG_G3] = (ptrint) xpc; /* REG_ITMP3_XPC */
+ _mc->gregs[REG_PC] = (ptrint) asm_handle_exception;
+ _mc->gregs[REG_nPC] = (ptrint) asm_handle_exception + 4;
#if 0
+ if (addr == 0) {
+
pv = (u1 *) _mc->gregs[REG_G3];
- sp = (u1 *) _mc->mc_fp;
- ra = (u1 *) _mc->mc_i7; /* this is correct for leafs */
- xpc = (u1 *) _mc->mc_gregs[MC_PC];
+ sp = (u1 *) (_uc->uc_stack.ss_sp);
+ /*ra = (u1 *) _mc->mc_i7;*/ /* this is correct for leafs */
+ ra = 0;
+ xpc = (u1 *) _mc->gregs[REG_PC];
- _mc->mc_gregs[MC_G4] =
+ _mc->gregs[REG_G4] =
(ptrint) stacktrace_hardware_nullpointerexception(pv, sp, ra, xpc);
- _mc->mc_gregs[MC_G5] = (ptrint) xpc;
- _mc->mc_gregs[MC_PC] = (ptrint) asm_handle_exception;
-#endif
- assert(0);
+ _mc->gregs[REG_G5] = (ptrint) xpc;
+ _mc->gregs[REG_PC] = (ptrint) asm_handle_exception;
} else {
addr += (long) ((instr << 16) >> 16);
*/
assert(0);
}
+#endif
}