#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)
/* 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) {
/* 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];
/* 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) &&
/* 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 */
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);
/* 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) */
/* 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;
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;
}
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;
}
/* 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: