* src/vm/jit/s390/codegen.h: Added functions for instruction parsing and manipulation...
authorPeter Molnar <pm@complang.tuwien.ac.at>
Sat, 29 Sep 2007 20:47:09 +0000 (20:47 +0000)
committerPeter Molnar <pm@complang.tuwien.ac.at>
Sat, 29 Sep 2007 20:47:09 +0000 (20:47 +0000)
* src/vm/jit/s390/codegen.c (codegen_emit): Replaced handcrafted machined code patching by marco.
* src/vm/jit/s390/emit.c (emit_branch): Likewise.
* src/vm/jit/s390/md.c (md_jit_method_patch_address, md_signal_handler_sigsegv, md_signal_handler_sigill, md_signal_handler_sigfpe): Replaced handcrafted machine code parsing and patching by calls to new functions.
* src/vm/jit/s390/patcher.c (patcher_invokeinterface, patcher_invokevirtual, patcher_get_putfield): Likewise.

src/vm/jit/s390/codegen.c
src/vm/jit/s390/codegen.h
src/vm/jit/s390/emit.c
src/vm/jit/s390/md.c
src/vm/jit/s390/patcher.c

index 1dcafaf24f701d16b5f0c0ebaf0dd43f132a0d8a..e5ebb14d37637161843d35bf192a88ce97fa8faa 100644 (file)
@@ -2534,9 +2534,8 @@ bool codegen_emit(jitdata *jd)
                                        assert(0);
                                }
 
-
                                if (out_ref != NULL) {
-                                       *(u4 *)out_ref |= (u4)(cd->mcodeptr - out_ref) / 2;
+                                       N_BRC_BACK_PATCH(out_ref);
                                }
 
                        }
index e95a54791b28502c0880e3d26cb72aaace3f9638..8cb750ac9e50340626144c4f53efead7f62ca56f 100644 (file)
 
 #define SZ_RR 2
 
+static inline uint8_t N_RR_GET_OPC(uint8_t *instrp) {
+       return instrp[0];
+}
+
+static inline uint8_t N_RR_GET_REG1(uint8_t *instrp) {
+       return (instrp[1] >> 4) & 0xF;
+}
+
+static inline uint8_t N_RR_GET_REG2(uint8_t *instrp) {
+       return (instrp[1] & 0xF);
+}
+
 #define N_RR2(op, i) \
        _CODE2( (_OP(op) << 8) | _I8(i) )
 
 
 #define SZ_RX 4
 
+static inline uint8_t N_RX_GET_OPC(uint8_t *instrp) {
+       return instrp[0];
+}
+
+static inline uint8_t N_RX_GET_REG(uint8_t *instrp) {
+       return (instrp[1] >> 4) & 0xF;  
+}
+
+static inline uint8_t N_RX_GET_INDEX(uint8_t *instrp) {
+       return (instrp[1] & 0xF);       
+}
+
+static inline uint8_t N_RX_GET_BASE(uint8_t *instrp) {
+       return (instrp[2] >> 4) & 0xF;
+}
+
+static inline uint16_t N_RX_GET_DISP(uint8_t *instrp) {
+       return *(uint16_t *)(instrp + 2) & 0xFFF;
+}
+
+static inline void N_RX_SET_DISP(uint8_t *instrp, uint16_t disp) {
+       *(uint16_t *)(instrp + 2) |= (disp & 0xFFF);
+}
+
 #define N_RI(op1, op2, r1, i2) \
        _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_SI16(i2) )
 
+static inline int16_t N_RI_GET_IMM(uint8_t *instrp) {
+       return *(int16_t *)(instrp + 2);
+}
+
+static inline void N_RI_SET_IMM(uint8_t *instrp, int16_t imm) {
+       *(int16_t *)(instrp + 2) = imm;
+}
+
 #define N_RI2(op1, op2, r1, i2) \
        _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_UI16(i2) )
 
  * 0                 15
  */
 #define N_ILL(data) _CODE2(0x0200 | _UBITS(data, 8))
-#define SZ_ILL 2
+#      define OPC_ILL 0x02
+#      define SZ_ILL 2
+
+static inline uint8_t N_ILL_GET_REG(uint8_t *instrp) {
+       return (instrp[1] >> 4) & 0xF;
+}
+
+static inline uint8_t N_ILL_GET_TYPE(uint8_t *instrp) {
+       return (instrp[1] & 0xF);
+}
 
 #define N_LONG(l) _CODE4(l)
 #define SZ_LONG 4
 #define N_CHI(r1, i2) N_RI(0xA7, 0xE, r1, i2)
 #define N_CLR(r1, r2) N_RR(0x15, r1, r2)
 #define N_CL(r1, d2, x2, b2) N_RX(0x55, r1, d2, x2, b2)
+#      define OPC_CL 0x55
 #define N_CLI(d1, b1, i2) N_SI(0x95, d1, b1, i2)
 #define N_CLC(d1, l, b1, d2, b2) N_SS(0xD5, d1, (l - 1), b1, d2, b2)
 #define N_CLM(r1, m3, d2, b2) N_RS(0xBD, r1, m3, d2, b2)
 #define N_CUTFU(r1, r2) N_RRE(0xB2A7, r1, r2)
 #define N_CPYA(r1, r2) N_RRE(0xB240, r1, r2)
 #define N_DR(r1, r2) N_RR(0x1D, r1, r2)
+#      define OPC_DR 0x1D
 #define N_D(r1, d2, x2, b2) N_RX(0x5D, r1, d2, x2, b2)
 #define N_XR(r1, r2) N_RR(0x17, r1, r2)
 #define N_X(r1, d2, x2, b2) N_RX(0x57, r1, d2, x2, b2)
 #define N_LR(r1, r2) N_RR(0x18, r1, r2)
 #define N_L(r1, d2, x2, b2) N_RX(0x58, r1, d2, x2, b2)
 #      define SZ_L SZ_RX
+#      define OPC_L 0x58
 #define N_LAM(r1, r3, d2, b2) N_RS(0x9A, r1, r3, d2, b2)
 #define N_LA(r1, d2, x2, b2) N_RX(0x41, r1, d2, x2, b2)
 #define N_LAE(r1, d2, x2, b2) N_RX(0x51, r1, d2, x2, b2)
 #define N_SRA(r1, d2, b2) N_RS(0x8A, r1, 0x00, d2, b2)
 #define N_SRL(r1, d2, b2) N_RS(0x88, r1, 0x00, d2, b2)
 #define N_ST(r1, d2, x2, b2) N_RX(0x50, r1, d2, x2, b2)
+#      define OPC_ST 0x50
 #define N_STAM(r1, r3, d2, b2) N_RS(0x9B, r1, r3, d2, b2)
 #define N_STC(r1, d2, x2, b2) N_RX(0x42, r1, d2, x2, b2)
 #define N_STCM(r1, m3, d2, b2) N_RS(0xBE, r1, m3, d2, b2)
index a2294e230807cba65a823c500b3597fd5ec79698..f0f9ba0c6f6b875c46c2c6f2008c1326c10d1f52 100644 (file)
@@ -678,9 +678,7 @@ void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt) {
 
                /* Patch back the displacement */
 
-               if (ref != NULL) {
-                       *(u4 *)ref |= (u4)((cd->mcodeptr - ref) / 2);
-               }
+               N_BRC_BACK_PATCH(ref);
        }
 }
 
index e2c1fcc94a70d6e415e6c2bab507bf5381854494..36b81f242acd63f556a9e36830192fd388a0208a 100644 (file)
@@ -159,11 +159,11 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
        /* Check opcodes and verify it is a null pointer exception */
 
-       switch (xpc[0]) {
-               case 0x58: /* L */
-               case 0x50: /* ST */
-               case 0x55: /* CL (array size check on NULL array) */
-                       base = (xpc[2] >> 4) & 0xF;
+       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 (_mc->gregs[base] == 0) {
@@ -223,13 +223,13 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
 
        /* Our trap instruction has the format: { 0x02, one_byte_of_data }. */
 
-       if ((siginfo->si_code == ILL_ILLOPC) && (xpc[0] == 0x02)) {
+       if ((siginfo->si_code == ILL_ILLOPC) && (N_RR_GET_OPC(xpc) == OPC_ILL)) {
 
                /* bits 7-4 contain a register holding a value */
-               reg = (xpc[1] >> 4) & 0xF;
+               reg = N_ILL_GET_REG(xpc);
 
                /* bits 3-0 designate the exception type */
-               type = xpc[1] & 0xF;  
+               type = N_ILL_GET_TYPE(xpc);
 
                pv = (u1 *)_mc->gregs[REG_PV] - N_PV_OFFSET;
                sp = (u1 *)_mc->gregs[REG_SP];
@@ -284,10 +284,10 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
 
        /* Check opcodes */
 
-       if (xpc[0] == 0x1D) { /* DR */
+       if (N_RR_GET_OPC(xpc) == OPC_DR) { /* DR */
 
-               r1 = (xpc[1] >> 4) & 0xF;
-               r2 = xpc[1] & 0xF;
+               r1 = N_RR_GET_REG1(xpc);
+               r2 = N_RR_GET_REG2(xpc);
 
                if (
                        (_mc->gregs[r1] == 0xFFFFFFFF) &&
@@ -476,12 +476,12 @@ void *md_jit_method_patch_address(void* pv, void *ra, void *mptr)
 
        /* go back to the load before the call instruction */
 
-       pc = ((uint8_t *) ra) - 2 /* sizeof bcr */ - 4 /* sizeof l */;
+       pc = ((uint8_t *) ra) - SZ_BCR - SZ_L;
 
        /* get the base register of the load */
 
-       base  = pc[2] >> 4;
-       index = pc[1] & 0xF;
+       base  = N_RX_GET_BASE(pc);
+       index = N_RX_GET_INDEX(pc);
 
        /* check for the different calls */
 
@@ -489,15 +489,14 @@ void *md_jit_method_patch_address(void* pv, void *ra, void *mptr)
                case REG_PV:
                        /* INVOKESTATIC/SPECIAL */
 
-               
                        switch (index) {
                                case R0:
                                        /* the offset is in the load instruction */
-                                       offset = ((*(uint16_t *) (pc + 2)) & 0xFFF) + N_PV_OFFSET;
+                                       offset = N_RX_GET_DISP(pc) + N_PV_OFFSET;
                                        break;
                                case REG_ITMP1:
                                        /* the offset is in the immediate load before the load */
-                                       offset = *((int16_t *) (pc - 2));
+                                       offset = N_RI_GET_IMM(pc - SZ_L);
                                        break;
                                default:
                                        assert(0);
@@ -512,7 +511,7 @@ void *md_jit_method_patch_address(void* pv, void *ra, void *mptr)
                        /* mptr relative */
                        /* INVOKEVIRTUAL/INTERFACE */
 
-                       offset = *((uint16_t *) (pc + 2)) & 0xFFF;
+                       offset = N_RX_GET_DISP(pc);
 
                        /* return NULL if no mptr was specified (used for replacement) */
 
index b3fdb897be554b8c60984fa20eae9f36893f2684..af32a263e2e35fc16c82c9854cce64348b79c44b 100644 (file)
@@ -150,15 +150,15 @@ bool patcher_get_putfield(patchref_t *pr)
        /* patch correct offset */
 
        if (fi->type == TYPE_LNG) {
-               assert(N_VALID_DISP(fi->offset + 4));
+               ASSERT_VALID_DISP(fi->offset + 4);
                /* 2 RX operations, for 2 words; each already contains a 0 or 4 offset. */
-               *((u4 *) ra ) |= (fi->offset + (*((u4 *) ra) & 0xF));
-               ra += 4;
-               *((u4 *) ra ) |= (fi->offset + (*((u4 *) ra) & 0xF));
+               N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra));
+               ra += SZ_RX;
+               N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra));
        } else {
-               assert(N_VALID_DISP(fi->offset));
+               ASSERT_VALID_DISP(fi->offset);
                /* 1 RX operation */
-               *((u4 *) ra) |= fi->offset;
+               N_RX_SET_DISP(ra, fi->offset);
        }
 
        return true;
@@ -237,9 +237,9 @@ bool patcher_invokevirtual(patchref_t *pr)
        off = (s4) (OFFSET(vftbl_t, table[0]) +
                                                                   sizeof(methodptr) * m->vftblindex);
 
-       assert(N_VALID_DISP(off));
+       ASSERT_VALID_DISP(off);
 
-       *((s4 *)(ra + 4)) |= off;
+       N_RX_SET_DISP(ra + SZ_RX, off);
 
        return true;
 }
@@ -290,12 +290,13 @@ bool patcher_invokeinterface(patchref_t *pr)
 
        off =
                (s4) (sizeof(methodptr) * (m - m->class->methods));
+
        ASSERT_VALID_DISP(off);
 
        /* patch them */
 
-       *((s4 *)(ra + 4)) |= (u2)idx;
-       *((s4 *)(ra + 4 + 4 + 4)) |= off;
+       N_RI_SET_IMM(ra + SZ_L, idx);
+       N_RX_SET_DISP(ra + SZ_L + SZ_LHI + SZ_L, off);
 
        return true;
 }
@@ -443,27 +444,27 @@ bool patcher_checkcast_instanceof_interface(patchref_t *pr)
 
        /* From here, split your editor and open codegen.c */
 
-       switch (*(ra + 1) >> 4) {
+       switch (N_RX_GET_REG(ra)) {
                case REG_ITMP1: 
                        /* First M_ALD is into ITMP1 */
                        /* INSTANCEOF code */
 
-                       *(u4 *)(ra + SZ_L + SZ_L) |= (u2)(s2)(- c->index);
-                       *(u4 *)(ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC) |=
-                               (u2)(s2)(OFFSET(vftbl_t, interfacetable[0]) -
-                                       c->index * sizeof(methodptr*));
-
+                       N_RI_SET_IMM(ra + SZ_L + SZ_L, - c->index);
+                       N_RI_SET_IMM(
+                               ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC,
+                               (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*))
+                       );
                        break;
 
                case REG_ITMP2:
                        /* First M_ALD is into ITMP2 */
                        /* CHECKCAST code */
 
-                       *(u4 *)(ra + SZ_L + SZ_L) |= (u2)(s2)(- c->index);
-                       *(u4 *)(ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC + SZ_ILL) |=
-                               (u2)(s2)(OFFSET(vftbl_t, interfacetable[0]) -
-                                       c->index * sizeof(methodptr*));
-
+                       N_RI_SET_IMM(ra + SZ_L + SZ_L, c->index);
+                       N_RI_SET_IMM(
+                               ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC + SZ_ILL,
+                               (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*))
+                       );
                        break;
 
                default: