/* src/vm/jit/x86_64/emit.c - x86_64 code emitter functions
- 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 "threads/lock-common.h"
-#include "vm/exceptions.h"
+#include "vm/options.h"
#include "vm/jit/abi.h"
#include "vm/jit/abi-asm.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/trace.h"
-
-#include "vmcore/options.h"
+#include "vm/jit/codegen-common.hpp"
+#include "vm/jit/emit-common.hpp"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/patcher-common.hpp"
+#include "vm/jit/replace.hpp"
+#include "vm/jit/trace.hpp"
+#include "vm/jit/trap.h"
/* emit_load *******************************************************************
*******************************************************************************/
-inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
+void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
{
codegendata *cd;
s4 disp;
-#if 0
- s4 s;
- u2 opcode;
-#endif
/* get required compiler data */
cd = jd->cd;
-#if 0
- /* do we have to generate a conditional move? */
-
- if ((iptr != NULL) && (iptr->opc & ICMD_CONDITION_MASK)) {
- /* the passed register d is actually the source register */
-
- s = d;
-
- /* Only pass the opcode to codegen_reg_of_var to get the real
- destination register. */
-
- opcode = iptr->opc & ICMD_OPCODE_MASK;
-
- /* get the real destination register */
-
- d = codegen_reg_of_var(rd, opcode, dst, REG_ITMP1);
-
- /* and emit the conditional move */
-
- emit_cmovxx(cd, iptr, s, d);
- }
-#endif
-
if (IS_INMEMORY(dst->flags)) {
COUNT_SPILLS;
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(reg);
M_BNE(8);
- M_ALD_MEM(reg, EXCEPTION_HARDWARE_ARITHMETIC);
+ M_ALD_MEM(reg, TRAP_ArithmeticException);
}
}
M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
M_ICMP(REG_ITMP3, s2);
M_BULT(8);
- M_ALD_MEM(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+ M_ALD_MEM(s2, TRAP_ArrayIndexOutOfBoundsException);
}
}
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(REG_RESULT);
M_BNE(8);
- M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_ARRAYSTORE);
+ M_ALD_MEM(REG_RESULT, TRAP_ArrayStoreException);
}
}
case BRANCH_LE:
M_BGT(8);
break;
+ case BRANCH_GE:
+ M_BLT(8);
+ break;
case BRANCH_EQ:
M_BNE(8);
break;
+ case BRANCH_NE:
+ M_BEQ(8);
+ break;
case BRANCH_UGT:
M_BULE(8);
break;
default:
vm_abort("emit_classcast_check: unknown condition %d", condition);
}
- M_ALD_MEM(s1, EXCEPTION_HARDWARE_CLASSCAST);
+ M_ALD_MEM(s1, TRAP_ClassCastException);
}
}
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(reg);
M_BNE(8);
- M_ALD_MEM(reg, EXCEPTION_HARDWARE_NULLPOINTER);
+ M_ALD_MEM(reg, TRAP_NullPointerException);
}
}
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(REG_RESULT);
M_BNE(8);
- M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_EXCEPTION);
+ M_ALD_MEM(REG_RESULT, TRAP_CHECK_EXCEPTION);
}
}
void emit_trap_compiler(codegendata *cd)
{
- M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+ M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
}
}
+void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
+{
+ emit_rex(1,(dreg),0,(reg));
+ *(cd->mcodeptr++) = 0x0f;
+ *(cd->mcodeptr++) = 0xb6;
+ /* XXX: why do reg and dreg have to be exchanged */
+ emit_reg((dreg),(reg));
+}
+
+
void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
{
emit_rex(1,(dreg),0,(reg));
void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
if (IS_IMM8(imm)) {
- emit_rex(1,(basereg),0,0);
+ emit_rex(1,0,0,(basereg));
*(cd->mcodeptr++) = 0x83;
emit_membase(cd, (basereg),(disp),(opc));
emit_imm8((imm));
} else {
- emit_rex(1,(basereg),0,0);
+ emit_rex(1,0,0,(basereg));
*(cd->mcodeptr++) = 0x81;
emit_membase(cd, (basereg),(disp),(opc));
emit_imm32((imm));
void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
if (IS_IMM8(imm)) {
- emit_rex(0,(basereg),0,0);
+ emit_rex(0,0,0,(basereg));
*(cd->mcodeptr++) = 0x83;
emit_membase(cd, (basereg),(disp),(opc));
emit_imm8((imm));
} else {
- emit_rex(0,(basereg),0,0);
+ emit_rex(0,0,0,(basereg));
*(cd->mcodeptr++) = 0x81;
emit_membase(cd, (basereg),(disp),(opc));
emit_imm32((imm));
}
+void emit_incl_reg(codegendata *cd, s8 reg)
+{
+ *(cd->mcodeptr++) = 0xff;
+ emit_reg(0,(reg));
+}
+
+void emit_incq_reg(codegendata *cd, s8 reg)
+{
+ emit_rex(1,0,0,(reg));
+ *(cd->mcodeptr++) = 0xff;
+ emit_reg(0,(reg));
+}
void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
{
emit_membase(cd, (basereg),(disp),0);
}
+void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp)
+{
+ emit_rex(1,0,0,(basereg));
+ *(cd->mcodeptr++) = 0xff;
+ emit_membase(cd, (basereg),(disp),0);
+}
+
void emit_cltd(codegendata *cd) {
emit_imm32((imm));
}
+/* like emit_jmp_imm but allows 8 bit optimization */
+void emit_jmp_imm2(codegendata *cd, s8 imm) {
+ if (IS_IMM8(imm)) {
+ *(cd->mcodeptr++) = 0xeb;
+ emit_imm8((imm));
+ }
+ else {
+ *(cd->mcodeptr++) = 0xe9;
+ emit_imm32((imm));
+ }
+}
+
void emit_jmp_reg(codegendata *cd, s8 reg) {
emit_rex(0,0,0,(reg));