#include "config.h"
#include <assert.h>
+#include <stdint.h>
#include <ucontext.h>
#if defined(__LINUX__)
#include "vm/types.h"
+#include "vm/jit/alpha/codegen.h"
#include "vm/jit/alpha/md-abi.h"
#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/md.h"
/* global variables ***********************************************************/
}
-/* md_get_method_patch_address *************************************************
+/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
is extracted from the load instruction(s) before the jump and added
*******************************************************************************/
-u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
+void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
{
- u4 mcode;
- s4 offset;
- u1 *pa; /* patch address */
-
- /* go back to the actual load instruction (2 instructions on Alpha) */
+ uint32_t *pc;
+ uint32_t mcode;
+ int opcode;
+ int base;
+ int32_t disp;
+ void *pa; /* patch address */
- ra = ra - 2 * 4;
+ /* Go back to the load instruction (2 instructions). */
- /* get first instruction word on current PC */
+ pc = ((uint32_t *) ra) - 2;
- mcode = *((u4 *) ra);
-
- /* check if we have 2 instructions (lui) */
+ /* Get first instruction word. */
- if ((mcode >> 16) == 0x3c19) {
- /* XXX write a regression for this */
- assert(0);
+ mcode = pc[0];
- /* get displacement of first instruction (lui) */
-
- offset = (s4) (mcode << 16);
-
- /* get displacement of second instruction (daddiu) */
-
- mcode = *((u4 *) (ra + 1 * 4));
+ /* Get opcode, base register and displacement. */
- assert((mcode >> 16) == 0x6739);
+ opcode = M_MEM_GET_Opcode(mcode);
+ base = M_MEM_GET_Rb(mcode);
+ disp = M_MEM_GET_Memory_disp(mcode);
- offset += (s2) (mcode & 0x0000ffff);
+ /* Check for short or long load (2 instructions). */
- } else {
- /* get first instruction (ldq) */
+ switch (opcode) {
+ case 0x29: /* LDQ: TODO use define */
+ switch (base) {
+ case REG_PV:
+ /* Calculate the data segment address. */
- mcode = *((u4 *) ra);
+ pa = ((uint8_t *) pv) + disp;
+ break;
- /* get the offset from the instruction */
-
- offset = (s2) (mcode & 0x0000ffff);
-
- /* check for call with REG_METHODPTR: ldq pv,0(at) */
-
- if ((mcode >> 16) == 0xa77c) {
- /* in this case we use the passed method pointer */
-
- /* return NULL if no mptr was specified (used for replacement) */
+ case REG_METHODPTR:
+ /* Return NULL if no mptr was specified (used for
+ replacement). */
if (mptr == NULL)
return NULL;
- pa = mptr + offset;
+ /* Calculate the address in the vftbl. */
- } else {
- /* in the normal case we check for a `ldq pv,-72(pv)' instruction */
+ pa = ((uint8_t *) mptr) + disp;
+ break;
- assert((mcode >> 16) == 0xa77b);
+ default:
+ vm_abort_disassemble(pc, 2, "md_jit_method_patch_address: unknown instruction %x", mcode);
+ return NULL;
+ }
+ break;
- /* and get the final data segment address */
+ case 0x09: /* LDAH: TODO use define */
+ /* XXX write a regression for this */
- pa = sfi->pv + offset;
- }
+ vm_abort("md_jit_method_patch_address: IMPLEMENT ME!");
+
+ pa = NULL;
+ break;
+
+ default:
+ vm_abort_disassemble(pc, 2, "md_jit_method_patch_address: unknown instruction %x", mcode);
+ return NULL;
}
return pa;