/* src/vm/jit/powerpc/codegen.c - machine code generator for 32-bit PowerPC
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "native/native.h"
#include "threads/lock-common.h"
+#include "threads/threads-common.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
/* XXX TODO: only do this if arithmetic check is really done! */
- M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
+ M_IOR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
/* XXX could be optimized */
emit_arithmetic_check(cd, iptr, REG_ITMP3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_AND_IMM(s2, 0x1f, REG_ITMP3);
+ M_IAND_IMM(s2, 0x1f, REG_ITMP3);
M_SLL(s1, REG_ITMP3, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_AND_IMM(s2, 0x1f, REG_ITMP3);
+ M_IAND_IMM(s2, 0x1f, REG_ITMP3);
M_SRA(s1, REG_ITMP3, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_AND_IMM(s2, 0x1f, REG_ITMP2);
+ M_IAND_IMM(s2, 0x1f, REG_ITMP2);
M_SRL(s1, REG_ITMP2, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_AND(s1, s2, d);
+ M_IAND(s1, s2, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
- M_AND_IMM(s1, iptr->sx.val.i, d);
+ M_IAND_IMM(s1, iptr->sx.val.i, d);
/*
else if (iptr->sx.val.i == 0xffffff) {
M_RLWINM(s1, 0, 8, 31, d);
*/
else {
ICONST(REG_ITMP3, iptr->sx.val.i);
- M_AND(s1, REG_ITMP3, d);
+ M_IAND(s1, REG_ITMP3, d);
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
- M_AND(s1, s2, GET_LOW_REG(d));
+ M_IAND(s1, s2, GET_LOW_REG(d));
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
- M_AND(s1, s2, GET_HIGH_REG(d));
+ M_IAND(s1, s2, GET_HIGH_REG(d));
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
if ((s3 >= 0) && (s3 <= 65535))
- M_AND_IMM(s1, s3, GET_LOW_REG(d));
+ M_IAND_IMM(s1, s3, GET_LOW_REG(d));
else {
ICONST(REG_ITMP3, s3);
- M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
+ M_IAND(s1, REG_ITMP3, GET_LOW_REG(d));
}
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s3 = iptr->sx.val.l >> 32;
if ((s3 >= 0) && (s3 <= 65535))
- M_AND_IMM(s1, s3, GET_HIGH_REG(d));
+ M_IAND_IMM(s1, s3, GET_HIGH_REG(d));
else {
ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
- M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
+ M_IAND(s1, REG_ITMP3, GET_HIGH_REG(d));
}
emit_store_dst(jd, iptr, d);
break;
M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
if (iptr->sx.val.i >= 32768) {
M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
- M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
+ M_IOR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
M_IADD(s1, REG_ITMP2, REG_ITMP2);
}
else {
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_OR(s1, s2, d);
+ M_IOR(s1, s2, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
- M_OR_IMM(s1, iptr->sx.val.i, d);
+ M_IOR_IMM(s1, iptr->sx.val.i, d);
else {
ICONST(REG_ITMP3, iptr->sx.val.i);
- M_OR(s1, REG_ITMP3, d);
+ M_IOR(s1, REG_ITMP3, d);
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
- M_OR(s1, s2, GET_LOW_REG(d));
+ M_IOR(s1, s2, GET_LOW_REG(d));
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
- M_OR(s1, s2, GET_HIGH_REG(d));
+ M_IOR(s1, s2, GET_HIGH_REG(d));
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
if ((s3 >= 0) && (s3 <= 65535))
- M_OR_IMM(s1, s3, GET_LOW_REG(d));
+ M_IOR_IMM(s1, s3, GET_LOW_REG(d));
else {
ICONST(REG_ITMP3, s3);
- M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
+ M_IOR(s1, REG_ITMP3, GET_LOW_REG(d));
}
s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
s3 = iptr->sx.val.l >> 32;
if ((s3 >= 0) && (s3 <= 65535))
- M_OR_IMM(s1, s3, GET_HIGH_REG(d));
+ M_IOR_IMM(s1, s3, GET_HIGH_REG(d));
else {
ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
- M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
+ M_IOR(s1, REG_ITMP3, GET_HIGH_REG(d));
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
if (iptr->sx.val.l == 0) {
- M_OR_TST(s1, s2, REG_ITMP3);
+ M_IOR_TST(s1, s2, REG_ITMP3);
}
else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
M_XOR_IMM(s2, 0, REG_ITMP2);
M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
- M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+ M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
}
else {
ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
M_XOR(s1, REG_ITMP3, REG_ITMP1);
ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
M_XOR(s2, REG_ITMP3, REG_ITMP2);
- M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+ M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
}
emit_beq(cd, iptr->dst.block);
break;
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
/* if (iptr->sx.val.l == 0) { */
-/* M_OR(s1, s2, REG_ITMP3); */
+/* M_IOR(s1, s2, REG_ITMP3); */
/* M_CMPI(REG_ITMP3, 0); */
/* } else */
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
if (iptr->sx.val.l == 0) {
- M_OR_TST(s1, s2, REG_ITMP3);
+ M_IOR_TST(s1, s2, REG_ITMP3);
}
else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
M_XOR_IMM(s2, 0, REG_ITMP2);
M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
- M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+ M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
}
else {
ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
M_XOR(s1, REG_ITMP3, REG_ITMP1);
ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
M_XOR(s2, REG_ITMP3, REG_ITMP2);
- M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+ M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
}
emit_bne(cd, iptr->dst.block);
break;
s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
/* if (iptr->sx.val.l == 0) { */
-/* M_OR(s1, s2, REG_ITMP3); */
+/* M_IOR(s1, s2, REG_ITMP3); */
/* M_CMPI(REG_ITMP3, 0); */
/* } else */
disp);
M_ILD(REG_ITMP2, REG_PV, disp);
- M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
+ M_IAND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
emit_label_beq(cd, BRANCH_LABEL_2);
}
iptr->sx.s23.s3.c.ref, disp);
M_ILD(REG_ITMP3, REG_PV, disp);
- M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
+ M_IAND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
emit_label_beq(cd, BRANCH_LABEL_2);
}
s4 s1, s2;
int disp;
- /* get required compiler data */
+ /* Sanity check. */
+
+ assert(f != NULL);
+
+ /* Get required compiler data. */
m = jd->m;
code = jd->code;
/* src/vm/jit/powerpc/codegen.h - code generation macros and definitions for
32-bit PowerPC
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
} while (0)
-/* instruction macros *********************************************************/
+/* machine instruction macros **************************************************
+
+ Argument order:
+
+ machine instruction macro:
+ Same order as for the mnemonic (d, s1, s2).
+
+ emit macro:
+ Same order as in the instruction encoding.
+
+*******************************************************************************/
+
+#define MI_and(rA,rS,rB) M_OP3(31, 28, 0, 0, rS, rA, rB)
+#define MI_anddot(rA,rS,rB) M_OP3(31, 28, 0, 1, rS, rA, rB)
+#define MI_andi(rA,rS,UIMM) M_OP2_IMM(28, rS, rA, UIMM)
+
+#define MI_lwarx(rD,rA,rB) M_OP3(31, 20, 0, 0, rD, rA, rB)
+
+#define MI_or(rA,rS,rB) M_OP3(31, 444, 0, 0, rS, rA, rB)
+#define MI_ordot(rA,rS,rB) M_OP3(31, 444, 0, 1, rS, rA, rB)
+#define MI_ori(rA,rS,UIMM) M_OP2_IMM(24, rS, rA, UIMM)
+
+#define MI_subf(rD,rA,rB) M_OP3(31, 40, 0, 0, rD, rA, rB)
+#define MI_subfdot(rD,rA,rB) M_OP3(31, 40, 0, 1, rD, rA, rB)
+#define MI_stwcxdot(rS,rA,rB) M_OP3(31, 150, 0, 1, rS, rA, rB)
+#define MI_sync M_OP3(31, 598, 0, 0, 0, 0, 0)
+
+
+/* HIR macros ******************************************************************
+
+ Argument order:
+
+ HIR macro:
+ Default usage in CACAO (s1, s2, d).
+
+ machine instruction macro:
+ Same order as for the mnemonic (d, s1, s2).
+
+*******************************************************************************/
+
+#define M_IAND(a,b,d) MI_and(d, a, b)
+#define M_IAND_IMM(a,b,d) MI_andi(d, a, b)
+
+#define M_IOR(a,b,d) MI_or(d, a, b)
+#define M_IOR_IMM(a,b,d) MI_ori(d, a, b)
+#define M_IOR_TST(a,b,d) MI_ordot(d, a, b)
+
+#define M_ISUB(a,b,d) MI_subf(d, b, a)
+#define M_ISUB_TST(a,b,d) MI_subfdot(d, b, a)
+
+#define M_MOV(a,d) MI_or(d, a, a)
+
+#define M_NOP MI_ori(0, 0, 0)
+
+
+#define M_AADD(a,b,d) M_IADD(a, b, d)
+#define M_AADD_IMM(a,b,d) M_IADD_IMM(a, b, d)
+
#define M_IADD(a,b,c) M_OP3(31, 266, 0, 0, c, a, b)
#define M_IADD_IMM(a,b,c) M_OP2_IMM(14, c, a, b)
#define M_ADDE(a,b,c) M_OP3(31, 138, 0, 0, c, a, b)
#define M_ADDZE(a,b) M_OP3(31, 202, 0, 0, b, a, 0)
#define M_ADDME(a,b) M_OP3(31, 234, 0, 0, b, a, 0)
-#define M_ISUB(a,b,c) M_OP3(31, 40, 0, 0, c, b, a)
-#define M_ISUBTST(a,b,c) M_OP3(31, 40, 0, 1, c, b, a)
#define M_SUBC(a,b,c) M_OP3(31, 8, 0, 0, c, b, a)
#define M_SUBIC(a,b,c) M_OP2_IMM(8, c, b, a)
#define M_SUBE(a,b,c) M_OP3(31, 136, 0, 0, c, b, a)
#define M_SUBZE(a,b) M_OP3(31, 200, 0, 0, b, a, 0)
#define M_SUBME(a,b) M_OP3(31, 232, 0, 0, b, a, 0)
-#define M_AND(a,b,c) M_OP3(31, 28, 0, 0, a, c, b)
-#define M_AND_IMM(a,b,c) M_OP2_IMM(28, a, c, b)
#define M_ANDIS(a,b,c) M_OP2_IMM(29, a, c, b)
-#define M_OR(a,b,c) M_OP3(31, 444, 0, 0, a, c, b)
-#define M_OR_TST(a,b,c) M_OP3(31, 444, 0, 1, a, c, b)
-#define M_OR_IMM(a,b,c) M_OP2_IMM(24, a, c, b)
#define M_ORIS(a,b,c) M_OP2_IMM(25, a, c, b)
#define M_XOR(a,b,c) M_OP3(31, 316, 0, 0, a, c, b)
#define M_XOR_IMM(a,b,c) M_OP2_IMM(26, a, c, b)
#define M_SRL_IMM(a,b,c) M_RLWINM(a,32-(b),b,31,c)
#define M_ADDIS(a,b,c) M_OP2_IMM(15, c, a, b)
#define M_STFIWX(a,b,c) M_OP3(31, 983, 0, 0, a, b, c)
+
#define M_LWZX(a,b,c) M_OP3(31, 23, 0, 0, a, b, c)
#define M_LHZX(a,b,c) M_OP3(31, 279, 0, 0, a, b, c)
#define M_LHAX(a,b,c) M_OP3(31, 343, 0, 0, a, b, c)
M_STWU_INTERN(a,b,lo); \
} else { \
M_ADDIS(REG_ZERO,hi,REG_ITMP3); \
- M_OR_IMM(REG_ITMP3,lo,REG_ITMP3); \
+ M_IOR_IMM(REG_ITMP3,lo,REG_ITMP3); \
M_STWUX(REG_SP,REG_SP,REG_ITMP3); \
} \
} while (0)
#define M_TRAP M_OP3(31, 4, 0, 0, 31, 0, 0)
#define M_TRAPGEU(a,b) M_OP3(31, 4, 0, 0, 5, a, b)
-#define M_NOP M_OR_IMM(0, 0, 0)
-#define M_MOV(a,b) M_OR(a, a, b)
#define M_TST(a) M_OP3(31, 444, 0, 1, a, a, a)
#define M_DADD(a,b,c) M_OP3(63, 21, 0, 0, c, a, b)
#define M_LDATST(a,b,c) M_ADDICTST(b, c, a)
#define M_CLR(a) M_IADD_IMM(0, 0, a)
-#define M_AADD_IMM(a,b,c) M_IADD_IMM(a, b, c)
#endif /* _CODEGEN_H */