You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by wj...@apache.org on 2006/10/06 21:52:21 UTC
svn commit: r453745 - in
/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet: bcproc.cpp cg.h
cg_fld_arr.cpp cg_obj.cpp compiler.h enc.cpp enc.h enc_ia32.cpp magics.cpp
Author: wjwashburn
Date: Fri Oct 6 12:52:20 2006
New Revision: 453745
URL: http://svn.apache.org/viewvc?view=rev&rev=453745
Log:
HARMONY-1677, vmmagic for Jitrino.JET compiler. Basically all the vmmagic regression tests pass except atomic CAS
Tested on windowsXP and RedHat Linux w/ gcc 3.4.5
Added:
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp
Modified:
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp Fri Oct 6 12:52:20 2006
@@ -46,37 +46,43 @@
gen_dbg_check_stack(true);
}
- const InstrDesc& idesc = instrs[jinst.opcode];
- switch (idesc.ik) {
- case ik_a:
- handle_ik_a(jinst);
- break;
- case ik_cf:
- handle_ik_cf(jinst);
- break;
- case ik_cnv:
- handle_ik_cnv(jinst);
- break;
- case ik_ls:
- handle_ik_ls(jinst);
- break;
- case ik_meth:
- handle_ik_meth(jinst);
- break;
- case ik_obj:
- handle_ik_obj(jinst);
- break;
- case ik_stack:
- handle_ik_stack(jinst);
- break;
- case ik_throw:
- gen_athrow();
- break;
- default:
- assert(jinst.opcode == OPCODE_NOP);
- break;
- };
-
+ // First test if this is a magic. If not, then proceed with regular
+ // code gen.
+ if (!gen_magic()) {
+ const InstrDesc& idesc = instrs[jinst.opcode];
+ switch (idesc.ik) {
+ case ik_a:
+ handle_ik_a(jinst);
+ break;
+ case ik_cf:
+ handle_ik_cf(jinst);
+ break;
+ case ik_cnv:
+ handle_ik_cnv(jinst);
+ break;
+ case ik_ls:
+ handle_ik_ls(jinst);
+ break;
+ case ik_meth:
+ handle_ik_meth(jinst);
+ break;
+ case ik_obj:
+ handle_ik_obj(jinst);
+ break;
+ case ik_stack:
+ handle_ik_stack(jinst);
+ break;
+ case ik_throw:
+ gen_athrow();
+ break;
+ default:
+ assert(jinst.opcode == OPCODE_NOP);
+ break;
+ } // ~switch(opcodegroup)
+ } else { // if (!gen_magic()) {
+ // no op. Just check stack (if applicable) and do mem manipulations
+ }
+
if (is_set(DBG_CHECK_STACK)) {
gen_dbg_check_stack(false);
}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h Fri Oct 6 12:52:20 2006
@@ -375,7 +375,7 @@
*
* Also invokes gen_check_bounds() and gen_check_null().
*/
- void gen_arr_store(jtype jt);
+ void gen_arr_store(jtype jt, bool helperOk = true);
/**
* @brief Generates code to check bounds for array access.
* @param aref_depth - depth (in the operand stack) of the array's object
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp Fri Oct 6 12:52:20 2006
@@ -124,11 +124,11 @@
}
}
-void CodeGen::gen_arr_store(jtype jt)
+void CodeGen::gen_arr_store(jtype jt, bool helperOk)
{
vunref(jt);
// stack: [.., aref, idx, val]
- if (jt == jobj) {
+ if (jt == jobj && helperOk) {
static const CallSig cs_aastore(CCONV_HELPERS, jobj, i32, jobj);
unsigned stackFix = gen_stack_to_args(true, cs_aastore, 0);
#ifdef _EM64T_
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp Fri Oct 6 12:52:20 2006
@@ -39,8 +39,9 @@
void CodeGen::gen_new_array(Allocation_Handle ah)
{
const JInst& jinst = *m_curr_inst;
- assert(jinst.opcode == OPCODE_NEWARRAY ||
- jinst.opcode == OPCODE_ANEWARRAY);
+ assert(jinst.opcode == OPCODE_NEWARRAY
+ || jinst.opcode == OPCODE_ANEWARRAY
+ || jinst.opcode == OPCODE_INVOKESTATIC); //OPCODE_INVOKESTATIC is used to generate magic
if (ah == 0) {
// it's unexpected that that something failed for a primitive type
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h Fri Oct 6 12:52:20 2006
@@ -350,6 +350,12 @@
*/
void gen_ret(unsigned idx);
+ /**
+ * @brief Checks current inst and generates magic if needed
+ * @return - true if current inst is magic call, false otherwise.
+ */
+ bool gen_magic(void);
+
//
// Method being compiled info
//
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp Fri Oct 6 12:52:20 2006
@@ -314,7 +314,10 @@
if (cond==lt) return ":lt";
if (cond==eq) return ":eq";
if (cond==ne) return ":ne";
+ if (cond==ae) return ":ae";
+ if (cond==be) return ":be";
if (cond==above) return ":above";
+ if (cond==below) return ":below";
assert(false);
return "???";
}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h Fri Oct 6 12:52:20 2006
@@ -455,7 +455,7 @@
// signed
ge, le, gt, lt, eq, z=eq, ne, nz=ne,
/// unsigned
- above,
+ ae, be, above, below,
//
cond_none
};
@@ -476,7 +476,7 @@
*/
unsigned gen_num_calle_save(void);
/**
- * @brief Returns i-th float-point register for regiter-based calling
+ * @brief Returns i-th float-point register for register-based calling
* conventions.
*
* The presumption used: the set of registers is constant across a platform
@@ -487,7 +487,7 @@
*/
AR get_cconv_fr(unsigned i);
/**
- * @brief Returns i-th general-purpose register for regiter-based calling
+ * @brief Returns i-th general-purpose register for register-based calling
* conventions.
* @see get_cconv_fr
*/
@@ -502,7 +502,7 @@
* @brief Represents an operand the Encoder works with.
*
* The Opnd can represent either immediate integer constant, or a register
- * operand, or a memory operand with compex address form [base+index*scale+
+ * operand, or a memory operand with complex address form [base+index*scale+
* displacement].
*
* Once created, instances of Opnd class are immutable. E.g. to change the
@@ -531,7 +531,7 @@
* @brief Constructs immediate operand of the given type and
* initializes immediate field with the given value.
*
- * The width of any_val is wide enough to fit any neccessary value -
+ * The width of any_val is wide enough to fit any necessary value -
* a pointer, #dbl64 or #i64.
*/
Opnd(jtype jt, jlong any_val)
@@ -998,6 +998,38 @@
}
/**
+ * Performs bitwise NOT operation.
+ */
+ void bitwise_not(const Opnd& op0) {
+ if (is_trace_on()) {
+ trace(string("not"), to_str(op0), to_str(""));
+ }
+ not_impl(op0);
+ }
+
+ /**
+ * Generates CMOVxx operation.
+ */
+ void cmovcc(COND cond, const Opnd& op0, const Opnd& op1)
+ {
+ if (is_trace_on()) {
+ trace(string("cmov:")+ to_str(cond), to_str(op0), to_str(op1));
+ }
+ cmovcc_impl(cond, op0, op1);
+ }
+
+ /**
+ * Generates CMPXCHG operation.
+ */
+ void cmpxchg(bool lockPrefix, AR addrBaseReg, AR newReg, AR oldReg)
+ {
+ if (is_trace_on()) {
+ trace(string("cmpxchg:")+ (lockPrefix ? "(locked) ":"") + to_str(addrBaseReg), to_str(newReg), to_str(oldReg));
+ }
+ cmpxchg_impl(lockPrefix, addrBaseReg, newReg, oldReg);
+ }
+
+ /**
* Generates ALU operation between two registers.
*
* The registers are used as \c jt type.
@@ -1418,8 +1450,14 @@
/// Implementation of mov().
void mov_impl(const Opnd& op0, const Opnd& op1);
+ /// Implementation of not().
+ void not_impl(const Opnd& op0);
/// Implementation of alu().
void alu_impl(ALU op, const Opnd& op0, const Opnd& op1);
+ /// Implementation of cmovcc().
+ void cmovcc_impl(COND c, const Opnd& op0, const Opnd& op1);
+ /// Implementation of cmpxchg().
+ void cmpxchg_impl(bool lockPrefix, AR addrReg, AR newReg, AR oldReg);
/// Implementation of lea().
void lea_impl(const Opnd& reg, const Opnd& mem);
/// Implementation of movp().
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp?view=diff&rev=453745&r1=453744&r2=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp Fri Oct 6 12:52:20 2006
@@ -247,13 +247,22 @@
ConditionMnemonic devirt(COND cond)
{
- if (cond==ge) return ConditionMnemonic_GE;
- if (cond==le) return ConditionMnemonic_LE;
- if (cond==gt) return ConditionMnemonic_G;
- if (cond==lt) return ConditionMnemonic_L;
- if (cond==eq) return ConditionMnemonic_Z;
- if (cond==ne) return ConditionMnemonic_NZ;
- if (cond==above) return ConditionMnemonic_A;
+ switch (cond) {
+ case ge: return ConditionMnemonic_GE;
+ case le: return ConditionMnemonic_LE;
+ case gt: return ConditionMnemonic_G;
+ case lt: return ConditionMnemonic_L;
+
+ case eq: return ConditionMnemonic_Z;
+ case ne: return ConditionMnemonic_NZ;
+
+ case be : return ConditionMnemonic_BE;
+ case ae : return ConditionMnemonic_AE;
+ case above: return ConditionMnemonic_A;
+ case below: return ConditionMnemonic_B;
+
+ default: break;
+ }
assert(false);
return ConditionMnemonic_Count;
}
@@ -631,6 +640,14 @@
emu_unfix_opnds(this, op0, op1, _op0, _op1);
}
+void Encoder::not_impl(const Opnd& op0)
+{
+ Mnemonic mn = Mnemonic_NOT;
+ EncoderBase::Operands args;
+ add_arg(args, op0, false);
+ ip(EncoderBase::encode(ip(), mn, args));
+}
+
void Encoder::alu_impl(ALU alu, const Opnd& op0, const Opnd& op1)
{
Mnemonic mn = to_mn(op0.jt(), alu);
@@ -639,6 +656,54 @@
// For alu_test can not shrink imm32 to imm8.
add_arg(args, Opnd(op1), alu != alu_test);
ip(EncoderBase::encode(ip(), mn, args));
+}
+
+void Encoder::cmovcc_impl(COND c, const Opnd& op0, const Opnd& op1)
+{
+ ConditionMnemonic cm = devirt(c);
+ Mnemonic mn = (Mnemonic)(Mnemonic_CMOVcc + cm);
+ EncoderBase::Operands args;
+ add_args(args, op0);
+ add_args(args, op1);
+ ip(EncoderBase::encode(ip(), mn, args));
+}
+
+//TODO: reuse the same func for all XCHG ops in this file
+static void xchg_regs(Encoder * enc, RegName reg1, RegName reg2) {
+ EncoderBase::Operands xargs;
+ xargs.add(reg1);
+ xargs.add(reg2);
+ enc->ip(EncoderBase::encode(enc->ip(), Mnemonic_XCHG, xargs));
+}
+
+void Encoder::cmpxchg_impl(bool lockPrefix, AR addrReg, AR newReg, AR oldReg) {
+ RegName dNewReg = devirt(newReg);
+ RegName dOldReg = devirt(oldReg);
+ RegName dAddrReg = devirt(addrReg);
+ bool eaxFix = dOldReg != RegName_EAX;
+ if (eaxFix) {
+ if (dAddrReg == RegName_EAX) {
+ dAddrReg = dOldReg;
+ } else if (dNewReg == RegName_EAX) {
+ dNewReg = dOldReg;
+ }
+ xchg_regs(this, dOldReg, RegName_EAX);
+ }
+
+ if (lockPrefix) {
+ ip(EncoderBase::prefix(ip(), InstPrefix_LOCK));
+ }
+
+ EncoderBase::Operands args;
+ args.add(EncoderBase::Operand(OpndSize_32, dAddrReg, 0)); //TODO: EM64t fix!
+ args.add(dNewReg);
+ args.add(RegName_EAX);
+ ip(EncoderBase::encode(ip(), Mnemonic_CMPXCHG, args));
+
+ if (eaxFix) {
+ xchg_regs(this, RegName_EAX, devirt(oldReg));
+ }
+
}
void Encoder::lea_impl(const Opnd& reg, const Opnd& mem)
Added: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp?view=auto&rev=453745
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp Fri Oct 6 12:52:20 2006
@@ -0,0 +1,528 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+ * @version $Revision$
+ */
+
+/**
+ * @file
+ * @brief Magics and WBs support for MMTk.
+*/
+
+#include "compiler.h"
+#include "enc_defs.h"
+#include "enc.h"
+
+#include "open/vm.h"
+#include "jit_import.h"
+#include "jit_intf.h"
+
+#include <vector>
+using std::vector;
+
+namespace Jitrino {
+namespace Jet {
+
+bool is_magic(Class_Handle k)
+{
+ static const char unboxedName[] = "org/vmmagic/unboxed/";
+ static const unsigned nameLen = sizeof(unboxedName)-1;
+ const char * kname = class_get_name(k);
+ return !strncmp(kname, unboxedName, nameLen);
+}
+
+bool is_magic(Method_Handle m)
+{
+ Class_Handle klass = method_get_class(m);
+ return is_magic(klass);
+}
+
+
+static size_t sizeof_jt(jtype jt) {
+ static size_t sizes[] = {
+ 1, //i8,
+ 2, //i16,
+ 2, //u16,
+ 4, //i32,
+ 8, //i64,
+ 4, //flt32,
+ 8, //dbl64,
+ 4, //jobj,
+ 4, //jvoid,
+ 4, //jretAddr,
+ 0, //jtypes_count,
+ };
+ size_t res= sizes[jt];
+ assert(res >= 1 && res<=8 && (res%2==0 || res == 1));
+ return res;
+}
+
+/** creates new opnd with the specified type and generates move from old one to new one */
+static void vstack_replace_top_opnd(Compiler* c, jtype jt) {
+ Opnd before = c->vstack(0).as_opnd();
+ assert(sizeof_jt(jt) >= sizeof_jt(before.jt()) && sizeof(jt)<=32);
+ Opnd after(jt, c->valloc(jt));
+ c->mov(after, before);
+ c->vpop();
+ c->vpush(after);
+}
+
+bool Compiler::gen_magic(void)
+{
+#ifdef _EM64T_
+ return false; //not tested
+#else
+ const JInst& jinst = m_insts[m_pc];
+ if (jinst.opcode != OPCODE_INVOKEVIRTUAL &&
+ jinst.opcode != OPCODE_INVOKESTATIC &&
+ jinst.opcode != OPCODE_INVOKESPECIAL &&
+ jinst.opcode != OPCODE_NEW) {
+ return false;
+ }
+
+ if (jinst.opcode == OPCODE_NEW) {
+ // trying to create a magic instance ?
+ Class_Handle klass = NULL;
+ klass = vm_resolve_class_new(m_compileHandle, m_klass, jinst.op0);
+ if (!is_magic(klass)) {
+ // not a magic - proceed as usual
+ return false;
+ }
+ // Create fake instance on the stack:
+ vpush(jobj);
+ vstack(0).set(VA_NZ);
+ return true;
+ }
+ //
+ //
+ //
+ JavaByteCodes opkod = jinst.opcode;
+ vector<jtype> args;
+ jtype retType;
+ bool is_static = opkod == OPCODE_INVOKESTATIC;
+ get_args_info(is_static, jinst.op0, args, &retType);
+ Method_Handle meth = NULL;
+ if (opkod == OPCODE_INVOKESTATIC) {
+ meth = resolve_static_method(m_compileHandle, m_klass, jinst.op0);
+ }
+ else if (opkod == OPCODE_INVOKEVIRTUAL) {
+ meth = resolve_virtual_method(m_compileHandle, m_klass, jinst.op0);
+ }
+ else {
+ assert(opkod == OPCODE_INVOKESPECIAL);
+ meth = resolve_special_method(m_compileHandle, m_klass, jinst.op0);
+ }
+ if (meth == NULL || !is_magic(meth)) {
+ return false;
+ }
+ //
+ //
+ //
+ const char* mname = method_get_name(meth);
+ //
+ // Construction
+ //
+ if (!strcmp(mname, "<init>")) {
+ // Currently only 'new <Magic>()' expected and handled
+ assert(args.size() == 1);
+ vpop();
+ return true;
+ }
+
+ //
+ // ADD, SUB, DIFF, etc - 2 args arithmetics
+ ALU oper = alu_count;
+
+ if (!strcmp(mname, "add")) { oper = alu_add; }
+ else if (!strcmp(mname, "plus")) { oper = alu_add; }
+ else if (!strcmp(mname, "sub")) { oper = alu_sub; }
+ else if (!strcmp(mname, "minus")) { oper = alu_sub; }
+ else if (!strcmp(mname, "diff")) { oper = alu_sub; }
+ else if (!strcmp(mname, "or")) { oper = alu_or; }
+ else if (!strcmp(mname, "xor")) { oper = alu_xor; }
+ else if (!strcmp(mname, "and")) { oper = alu_and; }
+ if (oper != alu_count) {
+ Val& v0 = vstack(0, true);
+ Val& v1 = vstack(1, true);
+ Opnd newObj(jobj, valloc(jobj));
+ mov(newObj, v1.as_opnd());
+ alu(oper, newObj, v0.as_opnd());
+ vpop();
+ vpop();
+ vpush(newObj);
+ return true;
+ }
+
+ JavaByteCodes shiftOp = OPCODE_NOP;
+ if (!strcmp(mname, "lsh")) {shiftOp = OPCODE_ISHL;}
+ else if (!strcmp(mname, "rsha")) {shiftOp = OPCODE_ISHR;}
+ else if (!strcmp(mname, "rshl")) {shiftOp = OPCODE_IUSHR;}
+
+ if (shiftOp != OPCODE_NOP) {
+ Opnd shiftAmount = vstack(0, false).as_opnd(i32);
+ shiftAmount = vstack(0, true).as_opnd(i32);
+ rlock(shiftAmount.reg());
+ vpop();
+ //changing type of obj opnd type to ia32
+ vstack_replace_top_opnd(this, i32);
+ vpush(shiftAmount);
+ runlock(shiftAmount.reg());
+ //processing as java bytecode and converting back to the obj type
+ gen_a(shiftOp, i32);
+ vstack_replace_top_opnd(this, jobj);
+ return true;
+ }
+
+ if (!strcmp(mname, "not")) {
+ Opnd v1 = vstack(0, true).as_opnd(jobj);
+ rlock(v1.reg());
+ Opnd v2(jobj, valloc(jobj));
+ mov(v2, v1);
+ bitwise_not(v2);
+ runlock(v1.reg());
+ vpop();
+ vpush(v2);
+ return true;
+ }
+
+ //
+ // EQ, GE, GT, LE, LT, sXX - 2 args compare
+ //
+ COND cm = cond_none;
+ if (!strcmp(mname, "EQ")) { cm = eq; }
+ if (!strcmp(mname, "equals")) { cm = eq; }
+ else if (!strcmp(mname, "NE")) { cm = ne; }
+ // unsigned compare
+ else if (!strcmp(mname, "GE")) { cm = ae; }
+ else if (!strcmp(mname, "GT")) { cm = above; }
+ else if (!strcmp(mname, "LE")) { cm = be;}
+ else if (!strcmp(mname, "LT")) { cm = below; }
+ // signed compare
+ else if (!strcmp(mname, "sGE")) { cm = ge; }
+ else if (!strcmp(mname, "sGT")) { cm = gt; }
+ else if (!strcmp(mname, "sLE")) { cm = le;}
+ else if (!strcmp(mname, "sLT")) { cm = lt; }
+ //
+ if (cm != cond_none) {
+ Opnd o1 = vstack(1, true).as_opnd(i32);
+ Opnd o2 = vstack(0, true).as_opnd(i32);
+ alu(alu_cmp, o1, o2);
+ vpop();
+ vpop();
+ Opnd boolResult(i32, valloc(i32));
+ rlock(boolResult.reg());
+ mov(boolResult, g_iconst_0);
+ cmovcc(cm, boolResult, vaddr(i32, &g_iconst_1));
+ runlock(boolResult.reg());
+ vpush(boolResult);
+ return true;
+ }
+
+ //
+ // is<Smth> one arg testing
+ //
+ bool oneArgCmp = false;
+ int theConst = 0;
+ if (!strcmp(mname, "isZero")) { oneArgCmp = true; theConst = 0; }
+ else if (!strcmp(mname, "isMax")) { oneArgCmp = true; theConst = ~0; }
+ else if (!strcmp(mname, "isNull")) { oneArgCmp = true; theConst = 0; }
+ if (oneArgCmp) {
+ AR regVal = vstack(0, true).reg();
+ rlock(regVal);
+ alu(alu_cmp, Opnd(jobj, regVal), theConst);
+
+ //save the result
+ AR resultReg = valloc(i32);
+ rlock(resultReg);
+ mov(resultReg, Opnd(g_iconst_0));
+ cmovcc(z, resultReg, vaddr(i32, &g_iconst_1));
+ runlock(resultReg);
+ vpop();
+ vpush(Opnd(i32, resultReg));
+
+ runlock(regVal);
+ return true;
+ }
+
+ //
+ // fromXXX - static creation from something
+ //
+ if (!strcmp(mname, "fromInt")) {
+ vstack_replace_top_opnd(this, jobj);
+ return true;
+ }
+ else if (!strcmp(mname, "fromIntSignExtend")) {
+ vstack_replace_top_opnd(this, jobj);
+ return true;
+ }
+ else if (!strcmp(mname, "fromIntZeroExtend")) {
+ vstack_replace_top_opnd(this, jobj);
+ return true;
+ }
+ else if (!strcmp(mname, "fromObject") ||
+ !strcmp(mname, "toAddress") ||
+ !strcmp(mname, "toObjectReference"))
+ {
+ vstack_replace_top_opnd(this, jobj);
+ return true;
+ }
+
+ const char* msig = method_get_descriptor(meth);
+ //
+ // load<type> things
+ //
+ jtype jt = jvoid;
+ bool load = true;
+ bool has_offset = false;
+
+ if (!strcmp(mname, "loadObjectReference")) { jt = jobj; }
+ else if (!strcmp(mname, "loadAddress")) { jt = jobj; }
+ else if (!strcmp(mname, "loadWord")) { jt = jobj; }
+ else if (!strcmp(mname, "loadByte")) { jt = i8; }
+ else if (!strcmp(mname, "loadChar")) { jt = u16; }
+ else if (!strcmp(mname, "loadDouble")) { jt = dbl64; }
+ else if (!strcmp(mname, "loadFloat")) { jt = flt32; }
+ else if (!strcmp(mname, "loadInt")) { jt = i32; }
+ else if (!strcmp(mname, "loadLong")) { jt = i64; }
+ else if (!strcmp(mname, "loadShort")) { jt = i16; }
+ else if (!strcmp(mname, "prepareWord")) { jt = i32; }
+ else if (!strcmp(mname, "prepareObjectReference")) { jt = jobj;}
+ else if (!strcmp(mname, "prepareAddress")) { jt = jobj;}
+ else if (!strcmp(mname, "prepareInt")) { jt = i32; }
+ else if (!strcmp(mname, "store")) {
+ load = false;
+ // store() must have at least one arg
+ assert(strlen(msig) > strlen("()V"));
+ char ch = msig[1]; // first symbol after '('.
+ VM_Data_Type vdt = (VM_Data_Type)ch;
+ switch(vdt) {
+ case VM_DATA_TYPE_BOOLEAN: // i8
+ case VM_DATA_TYPE_INT8: jt = i8; break;
+ case VM_DATA_TYPE_INT16: jt = i16; break;
+ case VM_DATA_TYPE_CHAR: jt = u16; break;
+ case VM_DATA_TYPE_INT32: jt = i32; break;
+ case VM_DATA_TYPE_INT64: jt = i64; break;
+ case VM_DATA_TYPE_F4: jt = flt32; break;
+ case VM_DATA_TYPE_F8: jt = dbl64; break;
+ case VM_DATA_TYPE_ARRAY: // jobj
+ case VM_DATA_TYPE_CLASS: jt = jobj; break;
+ default: assert(false);
+ }
+ jtype retType;
+ vector<jtype> args;
+ get_args_info(meth, args, &retType);
+ assert(args.size()>=2);
+ has_offset = args.size() > 2;
+ }
+ if (jt != jvoid) {
+ size_t jt_size = sizeof_jt(jt);
+ if (load) {
+ // if loadXX() has any arg, then it's offset
+ if(strncmp(msig, "()", 2)) {
+ has_offset = true;
+ }
+ }
+ unsigned addr_depth = has_offset ? 1 : 0;
+ if (!load) {
+ ++addr_depth;
+ if (is_wide(jt)) {
+ ++addr_depth;
+ }
+ }
+ AR addrReg = vstack(addr_depth, true).reg();
+ rlock(addrReg);
+
+ if (has_offset) {
+ //Add offset. Save to the new location.
+ AR addrWithOffsetReg = valloc(jobj);
+ mov(addrWithOffsetReg, addrReg);
+ runlock(addrReg);
+ addrReg = addrWithOffsetReg;
+ rlock(addrReg);
+
+ AR offsetReg = vstack(0, true).reg();
+ vpop();
+ alu(alu_add, addrReg, offsetReg);
+ }
+
+ if (load) {
+ vpop();
+ if (!is_big(jt)) {
+ AR resReg = valloc(jt);
+ ld(jt, resReg, addrReg);
+ Opnd resOpnd(jt, resReg);
+ if (jt_size < 4) {
+ Opnd extendedOpnd(i32, valloc(i32));
+ if (jt == u16) {
+ zx2(extendedOpnd, resOpnd);
+ } else {
+ sx(extendedOpnd, resOpnd);
+ }
+ resOpnd = extendedOpnd;
+ }
+ vpush(resOpnd);
+
+ } else { //code is taken from array element load -> TODO: avoid duplication
+ AR ar_lo = valloc(jt);
+ Opnd lo(jt, ar_lo);
+ rlock(lo);
+
+ do_mov(lo, Opnd(i32, addrReg, 0));
+
+ AR ar_hi = valloc(jt);
+ Opnd hi(jt, ar_hi);
+ rlock(hi);
+ Opnd mem_hi(jt, Opnd(i32, addrReg, 4));
+ do_mov(hi, mem_hi);
+ vpush2(lo, hi);
+ runlock(lo);
+ runlock(hi);
+ }
+ } else {
+ Opnd v0 = vstack(0, true).as_opnd(jt);
+ if (!is_big(jt)) {
+ mov(Opnd(jt, addrReg, 0), v0);
+ } else {
+ do_mov(Opnd(i32, addrReg, 0), v0);
+ Opnd v1 = vstack(1, true).as_opnd(jt);
+ do_mov(Opnd(i32, addrReg, 4), v1);
+ }
+ vpop(); // pop out value
+ vpop(); // pop out Address
+ }
+ runlock(addrReg);
+ return true;
+ }
+ //
+ // max, one, zero
+ //
+ bool loadConst = false;
+ if (!strcmp(mname, "max")) { loadConst = true; theConst = -1;}
+ else if (!strcmp(mname, "one")) { loadConst = true; theConst = 1;}
+ else if (!strcmp(mname, "zero")) { loadConst = true; theConst = 0;}
+ else if (!strcmp(mname, "nullReference"))
+ { loadConst = true; theConst = 0;}
+ if (loadConst) {
+ Opnd regOpnd(jobj, valloc(jobj));
+ mov(regOpnd, theConst);
+ vpush(regOpnd);
+ return true;
+ }
+ //
+ // toInt, toLong, toObjectRef, toWord(), etc.
+ //
+ jt = jvoid;
+ if (!strcmp(mname, "toInt")) { jt = i32; }
+ else if (!strcmp(mname, "toLong")) { jt = i64; }
+ else if (!strcmp(mname, "toObjectRef")) { jt = jobj; }
+ else if (!strcmp(mname, "toWord")) { jt = jobj; }
+ else if (!strcmp(mname, "toAddress")) { jt = jobj; }
+ else if (!strcmp(mname, "toObject")) { jt = jobj; }
+ else if (!strcmp(mname, "toExtent")) { jt = jobj; }
+ else if (!strcmp(mname, "toOffset")) { jt = jobj; }
+ if (jt != jvoid) {
+ if (jt!=i64) {
+ vstack_replace_top_opnd(this, jt);
+ return true;
+ }
+ vstack_replace_top_opnd(this, i32);
+
+ Opnd srcOpnd = vstack(0, true).as_opnd(i32);
+ Opnd lo(jt, valloc(jt));
+ do_mov(lo, srcOpnd);
+
+ Opnd hi(jt, g_iconst_0);
+ vpop();
+ vpush2(lo, hi);
+ return true;
+ }
+
+ if (!strcmp(mname, "attempt")) {
+ AR addrReg;
+ if (args.size() == 4) { //attempt with Offset
+ AR newAddressReg = valloc(jobj);
+ rlock(newAddressReg);
+ addrReg= vstack(3, true).reg();
+ mov(newAddressReg, addrReg);
+ AR offsetReg= vstack(0, true).reg();
+ alu(alu_add, newAddressReg, offsetReg);
+ runlock(newAddressReg);
+ addrReg = newAddressReg;
+ vpop();
+ } else {
+ addrReg = vstack(2, true).reg();
+ }
+ rlock(addrReg);
+ AR newReg = vstack(0, true).reg();
+ rlock(newReg);
+ AR oldReg = vstack(1, true).reg();
+
+ cmpxchg(true, addrReg, newReg, oldReg);
+
+ runlock(addrReg);
+ runlock(newReg);
+
+ //save the result
+ AR resultReg = valloc(i32);
+ rlock(resultReg);
+ mov(resultReg, Opnd(g_iconst_0));
+ cmovcc(z, resultReg, vaddr(i32, &g_iconst_1));
+ runlock(resultReg);
+
+ //fixing the stack and saving the result.
+ vpop();
+ vpop();
+ vpop();
+ vpush(Opnd(i32, resultReg));
+
+ return true;
+ }
+
+ //
+ // xArray stuff
+ //
+ if (!strcmp(mname, "create")) {
+ VM_Data_Type atype = VM_DATA_TYPE_INT32;
+ Class_Handle elem_class = class_get_class_of_primitive_type(atype);
+ assert(elem_class != NULL);
+ Class_Handle array_class = class_get_array_of_class(elem_class);
+ assert(array_class != NULL);
+ Allocation_Handle ah = class_get_allocation_handle(array_class);
+ gen_new_array(ah);
+ return true;
+ }
+
+ if (!strcmp(mname, "get")) {
+ gen_arr_load(jobj);
+ return true;
+ }
+
+ if (!strcmp(mname, "set")) {
+ gen_arr_store(jobj, false);
+ return true;
+ }
+ if (!strcmp(mname, "length")) {
+ gen_array_length();
+ return true;
+ }
+ //assert(false);
+ return false;
+
+#endif //not em64t
+}
+
+}}; // ~namespace Jitrino::Jet
Re: svn commit: r453745 - in /incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet: bcproc.cpp cg.h cg_fld_arr.cpp cg_obj.cpp compiler.h enc.cpp enc.h enc_ia32.cpp magics.cpp
Posted by Mikhail Fursov <mi...@gmail.com>.
I tested CAS ops in this implementation and it worked.
Could you show me the test that fails?
On 10/8/06, Geir Magnusson Jr <ge...@pobox.com> wrote:
>
> Did that test pass before?
>
> wjwashburn@apache.org wrote:
> > Author: wjwashburn
> > Date: Fri Oct 6 12:52:20 2006
> > New Revision: 453745
> >
> > URL: http://svn.apache.org/viewvc?view=rev&rev=453745
> > Log:
> > HARMONY-1677, vmmagic for Jitrino.JET compiler. Basically all the
> vmmagic regression tests pass except atomic CAS
>
--
Mikhail Fursov
Re: svn commit: r453745 - in /incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet:
bcproc.cpp cg.h cg_fld_arr.cpp cg_obj.cpp compiler.h enc.cpp enc.h enc_ia32.cpp
magics.cpp
Posted by Geir Magnusson Jr <ge...@pobox.com>.
Did that test pass before?
wjwashburn@apache.org wrote:
> Author: wjwashburn
> Date: Fri Oct 6 12:52:20 2006
> New Revision: 453745
>
> URL: http://svn.apache.org/viewvc?view=rev&rev=453745
> Log:
> HARMONY-1677, vmmagic for Jitrino.JET compiler. Basically all the vmmagic regression tests pass except atomic CAS
> Tested on windowsXP and RedHat Linux w/ gcc 3.4.5
>
> Added:
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp
> Modified:
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
> incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp Fri Oct 6 12:52:20 2006
> @@ -46,37 +46,43 @@
> gen_dbg_check_stack(true);
> }
>
> - const InstrDesc& idesc = instrs[jinst.opcode];
> - switch (idesc.ik) {
> - case ik_a:
> - handle_ik_a(jinst);
> - break;
> - case ik_cf:
> - handle_ik_cf(jinst);
> - break;
> - case ik_cnv:
> - handle_ik_cnv(jinst);
> - break;
> - case ik_ls:
> - handle_ik_ls(jinst);
> - break;
> - case ik_meth:
> - handle_ik_meth(jinst);
> - break;
> - case ik_obj:
> - handle_ik_obj(jinst);
> - break;
> - case ik_stack:
> - handle_ik_stack(jinst);
> - break;
> - case ik_throw:
> - gen_athrow();
> - break;
> - default:
> - assert(jinst.opcode == OPCODE_NOP);
> - break;
> - };
> -
> + // First test if this is a magic. If not, then proceed with regular
> + // code gen.
> + if (!gen_magic()) {
> + const InstrDesc& idesc = instrs[jinst.opcode];
> + switch (idesc.ik) {
> + case ik_a:
> + handle_ik_a(jinst);
> + break;
> + case ik_cf:
> + handle_ik_cf(jinst);
> + break;
> + case ik_cnv:
> + handle_ik_cnv(jinst);
> + break;
> + case ik_ls:
> + handle_ik_ls(jinst);
> + break;
> + case ik_meth:
> + handle_ik_meth(jinst);
> + break;
> + case ik_obj:
> + handle_ik_obj(jinst);
> + break;
> + case ik_stack:
> + handle_ik_stack(jinst);
> + break;
> + case ik_throw:
> + gen_athrow();
> + break;
> + default:
> + assert(jinst.opcode == OPCODE_NOP);
> + break;
> + } // ~switch(opcodegroup)
> + } else { // if (!gen_magic()) {
> + // no op. Just check stack (if applicable) and do mem manipulations
> + }
> +
> if (is_set(DBG_CHECK_STACK)) {
> gen_dbg_check_stack(false);
> }
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h Fri Oct 6 12:52:20 2006
> @@ -375,7 +375,7 @@
> *
> * Also invokes gen_check_bounds() and gen_check_null().
> */
> - void gen_arr_store(jtype jt);
> + void gen_arr_store(jtype jt, bool helperOk = true);
> /**
> * @brief Generates code to check bounds for array access.
> * @param aref_depth - depth (in the operand stack) of the array's object
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp Fri Oct 6 12:52:20 2006
> @@ -124,11 +124,11 @@
> }
> }
>
> -void CodeGen::gen_arr_store(jtype jt)
> +void CodeGen::gen_arr_store(jtype jt, bool helperOk)
> {
> vunref(jt);
> // stack: [.., aref, idx, val]
> - if (jt == jobj) {
> + if (jt == jobj && helperOk) {
> static const CallSig cs_aastore(CCONV_HELPERS, jobj, i32, jobj);
> unsigned stackFix = gen_stack_to_args(true, cs_aastore, 0);
> #ifdef _EM64T_
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp Fri Oct 6 12:52:20 2006
> @@ -39,8 +39,9 @@
> void CodeGen::gen_new_array(Allocation_Handle ah)
> {
> const JInst& jinst = *m_curr_inst;
> - assert(jinst.opcode == OPCODE_NEWARRAY ||
> - jinst.opcode == OPCODE_ANEWARRAY);
> + assert(jinst.opcode == OPCODE_NEWARRAY
> + || jinst.opcode == OPCODE_ANEWARRAY
> + || jinst.opcode == OPCODE_INVOKESTATIC); //OPCODE_INVOKESTATIC is used to generate magic
>
> if (ah == 0) {
> // it's unexpected that that something failed for a primitive type
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h Fri Oct 6 12:52:20 2006
> @@ -350,6 +350,12 @@
> */
> void gen_ret(unsigned idx);
>
> + /**
> + * @brief Checks current inst and generates magic if needed
> + * @return - true if current inst is magic call, false otherwise.
> + */
> + bool gen_magic(void);
> +
> //
> // Method being compiled info
> //
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp Fri Oct 6 12:52:20 2006
> @@ -314,7 +314,10 @@
> if (cond==lt) return ":lt";
> if (cond==eq) return ":eq";
> if (cond==ne) return ":ne";
> + if (cond==ae) return ":ae";
> + if (cond==be) return ":be";
> if (cond==above) return ":above";
> + if (cond==below) return ":below";
> assert(false);
> return "???";
> }
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h Fri Oct 6 12:52:20 2006
> @@ -455,7 +455,7 @@
> // signed
> ge, le, gt, lt, eq, z=eq, ne, nz=ne,
> /// unsigned
> - above,
> + ae, be, above, below,
> //
> cond_none
> };
> @@ -476,7 +476,7 @@
> */
> unsigned gen_num_calle_save(void);
> /**
> - * @brief Returns i-th float-point register for regiter-based calling
> + * @brief Returns i-th float-point register for register-based calling
> * conventions.
> *
> * The presumption used: the set of registers is constant across a platform
> @@ -487,7 +487,7 @@
> */
> AR get_cconv_fr(unsigned i);
> /**
> - * @brief Returns i-th general-purpose register for regiter-based calling
> + * @brief Returns i-th general-purpose register for register-based calling
> * conventions.
> * @see get_cconv_fr
> */
> @@ -502,7 +502,7 @@
> * @brief Represents an operand the Encoder works with.
> *
> * The Opnd can represent either immediate integer constant, or a register
> - * operand, or a memory operand with compex address form [base+index*scale+
> + * operand, or a memory operand with complex address form [base+index*scale+
> * displacement].
> *
> * Once created, instances of Opnd class are immutable. E.g. to change the
> @@ -531,7 +531,7 @@
> * @brief Constructs immediate operand of the given type and
> * initializes immediate field with the given value.
> *
> - * The width of any_val is wide enough to fit any neccessary value -
> + * The width of any_val is wide enough to fit any necessary value -
> * a pointer, #dbl64 or #i64.
> */
> Opnd(jtype jt, jlong any_val)
> @@ -998,6 +998,38 @@
> }
>
> /**
> + * Performs bitwise NOT operation.
> + */
> + void bitwise_not(const Opnd& op0) {
> + if (is_trace_on()) {
> + trace(string("not"), to_str(op0), to_str(""));
> + }
> + not_impl(op0);
> + }
> +
> + /**
> + * Generates CMOVxx operation.
> + */
> + void cmovcc(COND cond, const Opnd& op0, const Opnd& op1)
> + {
> + if (is_trace_on()) {
> + trace(string("cmov:")+ to_str(cond), to_str(op0), to_str(op1));
> + }
> + cmovcc_impl(cond, op0, op1);
> + }
> +
> + /**
> + * Generates CMPXCHG operation.
> + */
> + void cmpxchg(bool lockPrefix, AR addrBaseReg, AR newReg, AR oldReg)
> + {
> + if (is_trace_on()) {
> + trace(string("cmpxchg:")+ (lockPrefix ? "(locked) ":"") + to_str(addrBaseReg), to_str(newReg), to_str(oldReg));
> + }
> + cmpxchg_impl(lockPrefix, addrBaseReg, newReg, oldReg);
> + }
> +
> + /**
> * Generates ALU operation between two registers.
> *
> * The registers are used as \c jt type.
> @@ -1418,8 +1450,14 @@
>
> /// Implementation of mov().
> void mov_impl(const Opnd& op0, const Opnd& op1);
> + /// Implementation of not().
> + void not_impl(const Opnd& op0);
> /// Implementation of alu().
> void alu_impl(ALU op, const Opnd& op0, const Opnd& op1);
> + /// Implementation of cmovcc().
> + void cmovcc_impl(COND c, const Opnd& op0, const Opnd& op1);
> + /// Implementation of cmpxchg().
> + void cmpxchg_impl(bool lockPrefix, AR addrReg, AR newReg, AR oldReg);
> /// Implementation of lea().
> void lea_impl(const Opnd& reg, const Opnd& mem);
> /// Implementation of movp().
>
> Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp?view=diff&rev=453745&r1=453744&r2=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp (original)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp Fri Oct 6 12:52:20 2006
> @@ -247,13 +247,22 @@
>
> ConditionMnemonic devirt(COND cond)
> {
> - if (cond==ge) return ConditionMnemonic_GE;
> - if (cond==le) return ConditionMnemonic_LE;
> - if (cond==gt) return ConditionMnemonic_G;
> - if (cond==lt) return ConditionMnemonic_L;
> - if (cond==eq) return ConditionMnemonic_Z;
> - if (cond==ne) return ConditionMnemonic_NZ;
> - if (cond==above) return ConditionMnemonic_A;
> + switch (cond) {
> + case ge: return ConditionMnemonic_GE;
> + case le: return ConditionMnemonic_LE;
> + case gt: return ConditionMnemonic_G;
> + case lt: return ConditionMnemonic_L;
> +
> + case eq: return ConditionMnemonic_Z;
> + case ne: return ConditionMnemonic_NZ;
> +
> + case be : return ConditionMnemonic_BE;
> + case ae : return ConditionMnemonic_AE;
> + case above: return ConditionMnemonic_A;
> + case below: return ConditionMnemonic_B;
> +
> + default: break;
> + }
> assert(false);
> return ConditionMnemonic_Count;
> }
> @@ -631,6 +640,14 @@
> emu_unfix_opnds(this, op0, op1, _op0, _op1);
> }
>
> +void Encoder::not_impl(const Opnd& op0)
> +{
> + Mnemonic mn = Mnemonic_NOT;
> + EncoderBase::Operands args;
> + add_arg(args, op0, false);
> + ip(EncoderBase::encode(ip(), mn, args));
> +}
> +
> void Encoder::alu_impl(ALU alu, const Opnd& op0, const Opnd& op1)
> {
> Mnemonic mn = to_mn(op0.jt(), alu);
> @@ -639,6 +656,54 @@
> // For alu_test can not shrink imm32 to imm8.
> add_arg(args, Opnd(op1), alu != alu_test);
> ip(EncoderBase::encode(ip(), mn, args));
> +}
> +
> +void Encoder::cmovcc_impl(COND c, const Opnd& op0, const Opnd& op1)
> +{
> + ConditionMnemonic cm = devirt(c);
> + Mnemonic mn = (Mnemonic)(Mnemonic_CMOVcc + cm);
> + EncoderBase::Operands args;
> + add_args(args, op0);
> + add_args(args, op1);
> + ip(EncoderBase::encode(ip(), mn, args));
> +}
> +
> +//TODO: reuse the same func for all XCHG ops in this file
> +static void xchg_regs(Encoder * enc, RegName reg1, RegName reg2) {
> + EncoderBase::Operands xargs;
> + xargs.add(reg1);
> + xargs.add(reg2);
> + enc->ip(EncoderBase::encode(enc->ip(), Mnemonic_XCHG, xargs));
> +}
> +
> +void Encoder::cmpxchg_impl(bool lockPrefix, AR addrReg, AR newReg, AR oldReg) {
> + RegName dNewReg = devirt(newReg);
> + RegName dOldReg = devirt(oldReg);
> + RegName dAddrReg = devirt(addrReg);
> + bool eaxFix = dOldReg != RegName_EAX;
> + if (eaxFix) {
> + if (dAddrReg == RegName_EAX) {
> + dAddrReg = dOldReg;
> + } else if (dNewReg == RegName_EAX) {
> + dNewReg = dOldReg;
> + }
> + xchg_regs(this, dOldReg, RegName_EAX);
> + }
> +
> + if (lockPrefix) {
> + ip(EncoderBase::prefix(ip(), InstPrefix_LOCK));
> + }
> +
> + EncoderBase::Operands args;
> + args.add(EncoderBase::Operand(OpndSize_32, dAddrReg, 0)); //TODO: EM64t fix!
> + args.add(dNewReg);
> + args.add(RegName_EAX);
> + ip(EncoderBase::encode(ip(), Mnemonic_CMPXCHG, args));
> +
> + if (eaxFix) {
> + xchg_regs(this, RegName_EAX, devirt(oldReg));
> + }
> +
> }
>
> void Encoder::lea_impl(const Opnd& reg, const Opnd& mem)
>
> Added: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp
> URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp?view=auto&rev=453745
> ==============================================================================
> --- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp (added)
> +++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp Fri Oct 6 12:52:20 2006
> @@ -0,0 +1,528 @@
> +/*
> +* Licensed to the Apache Software Foundation (ASF) under one or more
> +* contributor license agreements. See the NOTICE file distributed with
> +* this work for additional information regarding copyright ownership.
> +* The ASF licenses this file to You under the Apache License, Version 2.0
> +* (the "License"); you may not use this file except in compliance with
> +* the License. You may obtain a copy of the License at
> +*
> +* http://www.apache.org/licenses/LICENSE-2.0
> +*
> +* Unless required by applicable law or agreed to in writing, software
> +* distributed under the License is distributed on an "AS IS" BASIS,
> +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> +* See the License for the specific language governing permissions and
> +* limitations under the License.
> +*/
> +/**
> + * @version $Revision$
> + */
> +
> +/**
> + * @file
> + * @brief Magics and WBs support for MMTk.
> +*/
> +
> +#include "compiler.h"
> +#include "enc_defs.h"
> +#include "enc.h"
> +
> +#include "open/vm.h"
> +#include "jit_import.h"
> +#include "jit_intf.h"
> +
> +#include <vector>
> +using std::vector;
> +
> +namespace Jitrino {
> +namespace Jet {
> +
> +bool is_magic(Class_Handle k)
> +{
> + static const char unboxedName[] = "org/vmmagic/unboxed/";
> + static const unsigned nameLen = sizeof(unboxedName)-1;
> + const char * kname = class_get_name(k);
> + return !strncmp(kname, unboxedName, nameLen);
> +}
> +
> +bool is_magic(Method_Handle m)
> +{
> + Class_Handle klass = method_get_class(m);
> + return is_magic(klass);
> +}
> +
> +
> +static size_t sizeof_jt(jtype jt) {
> + static size_t sizes[] = {
> + 1, //i8,
> + 2, //i16,
> + 2, //u16,
> + 4, //i32,
> + 8, //i64,
> + 4, //flt32,
> + 8, //dbl64,
> + 4, //jobj,
> + 4, //jvoid,
> + 4, //jretAddr,
> + 0, //jtypes_count,
> + };
> + size_t res= sizes[jt];
> + assert(res >= 1 && res<=8 && (res%2==0 || res == 1));
> + return res;
> +}
> +
> +/** creates new opnd with the specified type and generates move from old one to new one */
> +static void vstack_replace_top_opnd(Compiler* c, jtype jt) {
> + Opnd before = c->vstack(0).as_opnd();
> + assert(sizeof_jt(jt) >= sizeof_jt(before.jt()) && sizeof(jt)<=32);
> + Opnd after(jt, c->valloc(jt));
> + c->mov(after, before);
> + c->vpop();
> + c->vpush(after);
> +}
> +
> +bool Compiler::gen_magic(void)
> +{
> +#ifdef _EM64T_
> + return false; //not tested
> +#else
> + const JInst& jinst = m_insts[m_pc];
> + if (jinst.opcode != OPCODE_INVOKEVIRTUAL &&
> + jinst.opcode != OPCODE_INVOKESTATIC &&
> + jinst.opcode != OPCODE_INVOKESPECIAL &&
> + jinst.opcode != OPCODE_NEW) {
> + return false;
> + }
> +
> + if (jinst.opcode == OPCODE_NEW) {
> + // trying to create a magic instance ?
> + Class_Handle klass = NULL;
> + klass = vm_resolve_class_new(m_compileHandle, m_klass, jinst.op0);
> + if (!is_magic(klass)) {
> + // not a magic - proceed as usual
> + return false;
> + }
> + // Create fake instance on the stack:
> + vpush(jobj);
> + vstack(0).set(VA_NZ);
> + return true;
> + }
> + //
> + //
> + //
> + JavaByteCodes opkod = jinst.opcode;
> + vector<jtype> args;
> + jtype retType;
> + bool is_static = opkod == OPCODE_INVOKESTATIC;
> + get_args_info(is_static, jinst.op0, args, &retType);
> + Method_Handle meth = NULL;
> + if (opkod == OPCODE_INVOKESTATIC) {
> + meth = resolve_static_method(m_compileHandle, m_klass, jinst.op0);
> + }
> + else if (opkod == OPCODE_INVOKEVIRTUAL) {
> + meth = resolve_virtual_method(m_compileHandle, m_klass, jinst.op0);
> + }
> + else {
> + assert(opkod == OPCODE_INVOKESPECIAL);
> + meth = resolve_special_method(m_compileHandle, m_klass, jinst.op0);
> + }
> + if (meth == NULL || !is_magic(meth)) {
> + return false;
> + }
> + //
> + //
> + //
> + const char* mname = method_get_name(meth);
> + //
> + // Construction
> + //
> + if (!strcmp(mname, "<init>")) {
> + // Currently only 'new <Magic>()' expected and handled
> + assert(args.size() == 1);
> + vpop();
> + return true;
> + }
> +
> + //
> + // ADD, SUB, DIFF, etc - 2 args arithmetics
> + ALU oper = alu_count;
> +
> + if (!strcmp(mname, "add")) { oper = alu_add; }
> + else if (!strcmp(mname, "plus")) { oper = alu_add; }
> + else if (!strcmp(mname, "sub")) { oper = alu_sub; }
> + else if (!strcmp(mname, "minus")) { oper = alu_sub; }
> + else if (!strcmp(mname, "diff")) { oper = alu_sub; }
> + else if (!strcmp(mname, "or")) { oper = alu_or; }
> + else if (!strcmp(mname, "xor")) { oper = alu_xor; }
> + else if (!strcmp(mname, "and")) { oper = alu_and; }
> + if (oper != alu_count) {
> + Val& v0 = vstack(0, true);
> + Val& v1 = vstack(1, true);
> + Opnd newObj(jobj, valloc(jobj));
> + mov(newObj, v1.as_opnd());
> + alu(oper, newObj, v0.as_opnd());
> + vpop();
> + vpop();
> + vpush(newObj);
> + return true;
> + }
> +
> + JavaByteCodes shiftOp = OPCODE_NOP;
> + if (!strcmp(mname, "lsh")) {shiftOp = OPCODE_ISHL;}
> + else if (!strcmp(mname, "rsha")) {shiftOp = OPCODE_ISHR;}
> + else if (!strcmp(mname, "rshl")) {shiftOp = OPCODE_IUSHR;}
> +
> + if (shiftOp != OPCODE_NOP) {
> + Opnd shiftAmount = vstack(0, false).as_opnd(i32);
> + shiftAmount = vstack(0, true).as_opnd(i32);
> + rlock(shiftAmount.reg());
> + vpop();
> + //changing type of obj opnd type to ia32
> + vstack_replace_top_opnd(this, i32);
> + vpush(shiftAmount);
> + runlock(shiftAmount.reg());
> + //processing as java bytecode and converting back to the obj type
> + gen_a(shiftOp, i32);
> + vstack_replace_top_opnd(this, jobj);
> + return true;
> + }
> +
> + if (!strcmp(mname, "not")) {
> + Opnd v1 = vstack(0, true).as_opnd(jobj);
> + rlock(v1.reg());
> + Opnd v2(jobj, valloc(jobj));
> + mov(v2, v1);
> + bitwise_not(v2);
> + runlock(v1.reg());
> + vpop();
> + vpush(v2);
> + return true;
> + }
> +
> + //
> + // EQ, GE, GT, LE, LT, sXX - 2 args compare
> + //
> + COND cm = cond_none;
> + if (!strcmp(mname, "EQ")) { cm = eq; }
> + if (!strcmp(mname, "equals")) { cm = eq; }
> + else if (!strcmp(mname, "NE")) { cm = ne; }
> + // unsigned compare
> + else if (!strcmp(mname, "GE")) { cm = ae; }
> + else if (!strcmp(mname, "GT")) { cm = above; }
> + else if (!strcmp(mname, "LE")) { cm = be;}
> + else if (!strcmp(mname, "LT")) { cm = below; }
> + // signed compare
> + else if (!strcmp(mname, "sGE")) { cm = ge; }
> + else if (!strcmp(mname, "sGT")) { cm = gt; }
> + else if (!strcmp(mname, "sLE")) { cm = le;}
> + else if (!strcmp(mname, "sLT")) { cm = lt; }
> + //
> + if (cm != cond_none) {
> + Opnd o1 = vstack(1, true).as_opnd(i32);
> + Opnd o2 = vstack(0, true).as_opnd(i32);
> + alu(alu_cmp, o1, o2);
> + vpop();
> + vpop();
> + Opnd boolResult(i32, valloc(i32));
> + rlock(boolResult.reg());
> + mov(boolResult, g_iconst_0);
> + cmovcc(cm, boolResult, vaddr(i32, &g_iconst_1));
> + runlock(boolResult.reg());
> + vpush(boolResult);
> + return true;
> + }
> +
> + //
> + // is<Smth> one arg testing
> + //
> + bool oneArgCmp = false;
> + int theConst = 0;
> + if (!strcmp(mname, "isZero")) { oneArgCmp = true; theConst = 0; }
> + else if (!strcmp(mname, "isMax")) { oneArgCmp = true; theConst = ~0; }
> + else if (!strcmp(mname, "isNull")) { oneArgCmp = true; theConst = 0; }
> + if (oneArgCmp) {
> + AR regVal = vstack(0, true).reg();
> + rlock(regVal);
> + alu(alu_cmp, Opnd(jobj, regVal), theConst);
> +
> + //save the result
> + AR resultReg = valloc(i32);
> + rlock(resultReg);
> + mov(resultReg, Opnd(g_iconst_0));
> + cmovcc(z, resultReg, vaddr(i32, &g_iconst_1));
> + runlock(resultReg);
> + vpop();
> + vpush(Opnd(i32, resultReg));
> +
> + runlock(regVal);
> + return true;
> + }
> +
> + //
> + // fromXXX - static creation from something
> + //
> + if (!strcmp(mname, "fromInt")) {
> + vstack_replace_top_opnd(this, jobj);
> + return true;
> + }
> + else if (!strcmp(mname, "fromIntSignExtend")) {
> + vstack_replace_top_opnd(this, jobj);
> + return true;
> + }
> + else if (!strcmp(mname, "fromIntZeroExtend")) {
> + vstack_replace_top_opnd(this, jobj);
> + return true;
> + }
> + else if (!strcmp(mname, "fromObject") ||
> + !strcmp(mname, "toAddress") ||
> + !strcmp(mname, "toObjectReference"))
> + {
> + vstack_replace_top_opnd(this, jobj);
> + return true;
> + }
> +
> + const char* msig = method_get_descriptor(meth);
> + //
> + // load<type> things
> + //
> + jtype jt = jvoid;
> + bool load = true;
> + bool has_offset = false;
> +
> + if (!strcmp(mname, "loadObjectReference")) { jt = jobj; }
> + else if (!strcmp(mname, "loadAddress")) { jt = jobj; }
> + else if (!strcmp(mname, "loadWord")) { jt = jobj; }
> + else if (!strcmp(mname, "loadByte")) { jt = i8; }
> + else if (!strcmp(mname, "loadChar")) { jt = u16; }
> + else if (!strcmp(mname, "loadDouble")) { jt = dbl64; }
> + else if (!strcmp(mname, "loadFloat")) { jt = flt32; }
> + else if (!strcmp(mname, "loadInt")) { jt = i32; }
> + else if (!strcmp(mname, "loadLong")) { jt = i64; }
> + else if (!strcmp(mname, "loadShort")) { jt = i16; }
> + else if (!strcmp(mname, "prepareWord")) { jt = i32; }
> + else if (!strcmp(mname, "prepareObjectReference")) { jt = jobj;}
> + else if (!strcmp(mname, "prepareAddress")) { jt = jobj;}
> + else if (!strcmp(mname, "prepareInt")) { jt = i32; }
> + else if (!strcmp(mname, "store")) {
> + load = false;
> + // store() must have at least one arg
> + assert(strlen(msig) > strlen("()V"));
> + char ch = msig[1]; // first symbol after '('.
> + VM_Data_Type vdt = (VM_Data_Type)ch;
> + switch(vdt) {
> + case VM_DATA_TYPE_BOOLEAN: // i8
> + case VM_DATA_TYPE_INT8: jt = i8; break;
> + case VM_DATA_TYPE_INT16: jt = i16; break;
> + case VM_DATA_TYPE_CHAR: jt = u16; break;
> + case VM_DATA_TYPE_INT32: jt = i32; break;
> + case VM_DATA_TYPE_INT64: jt = i64; break;
> + case VM_DATA_TYPE_F4: jt = flt32; break;
> + case VM_DATA_TYPE_F8: jt = dbl64; break;
> + case VM_DATA_TYPE_ARRAY: // jobj
> + case VM_DATA_TYPE_CLASS: jt = jobj; break;
> + default: assert(false);
> + }
> + jtype retType;
> + vector<jtype> args;
> + get_args_info(meth, args, &retType);
> + assert(args.size()>=2);
> + has_offset = args.size() > 2;
> + }
> + if (jt != jvoid) {
> + size_t jt_size = sizeof_jt(jt);
> + if (load) {
> + // if loadXX() has any arg, then it's offset
> + if(strncmp(msig, "()", 2)) {
> + has_offset = true;
> + }
> + }
> + unsigned addr_depth = has_offset ? 1 : 0;
> + if (!load) {
> + ++addr_depth;
> + if (is_wide(jt)) {
> + ++addr_depth;
> + }
> + }
> + AR addrReg = vstack(addr_depth, true).reg();
> + rlock(addrReg);
> +
> + if (has_offset) {
> + //Add offset. Save to the new location.
> + AR addrWithOffsetReg = valloc(jobj);
> + mov(addrWithOffsetReg, addrReg);
> + runlock(addrReg);
> + addrReg = addrWithOffsetReg;
> + rlock(addrReg);
> +
> + AR offsetReg = vstack(0, true).reg();
> + vpop();
> + alu(alu_add, addrReg, offsetReg);
> + }
> +
> + if (load) {
> + vpop();
> + if (!is_big(jt)) {
> + AR resReg = valloc(jt);
> + ld(jt, resReg, addrReg);
> + Opnd resOpnd(jt, resReg);
> + if (jt_size < 4) {
> + Opnd extendedOpnd(i32, valloc(i32));
> + if (jt == u16) {
> + zx2(extendedOpnd, resOpnd);
> + } else {
> + sx(extendedOpnd, resOpnd);
> + }
> + resOpnd = extendedOpnd;
> + }
> + vpush(resOpnd);
> +
> + } else { //code is taken from array element load -> TODO: avoid duplication
> + AR ar_lo = valloc(jt);
> + Opnd lo(jt, ar_lo);
> + rlock(lo);
> +
> + do_mov(lo, Opnd(i32, addrReg, 0));
> +
> + AR ar_hi = valloc(jt);
> + Opnd hi(jt, ar_hi);
> + rlock(hi);
> + Opnd mem_hi(jt, Opnd(i32, addrReg, 4));
> + do_mov(hi, mem_hi);
> + vpush2(lo, hi);
> + runlock(lo);
> + runlock(hi);
> + }
> + } else {
> + Opnd v0 = vstack(0, true).as_opnd(jt);
> + if (!is_big(jt)) {
> + mov(Opnd(jt, addrReg, 0), v0);
> + } else {
> + do_mov(Opnd(i32, addrReg, 0), v0);
> + Opnd v1 = vstack(1, true).as_opnd(jt);
> + do_mov(Opnd(i32, addrReg, 4), v1);
> + }
> + vpop(); // pop out value
> + vpop(); // pop out Address
> + }
> + runlock(addrReg);
> + return true;
> + }
> + //
> + // max, one, zero
> + //
> + bool loadConst = false;
> + if (!strcmp(mname, "max")) { loadConst = true; theConst = -1;}
> + else if (!strcmp(mname, "one")) { loadConst = true; theConst = 1;}
> + else if (!strcmp(mname, "zero")) { loadConst = true; theConst = 0;}
> + else if (!strcmp(mname, "nullReference"))
> + { loadConst = true; theConst = 0;}
> + if (loadConst) {
> + Opnd regOpnd(jobj, valloc(jobj));
> + mov(regOpnd, theConst);
> + vpush(regOpnd);
> + return true;
> + }
> + //
> + // toInt, toLong, toObjectRef, toWord(), etc.
> + //
> + jt = jvoid;
> + if (!strcmp(mname, "toInt")) { jt = i32; }
> + else if (!strcmp(mname, "toLong")) { jt = i64; }
> + else if (!strcmp(mname, "toObjectRef")) { jt = jobj; }
> + else if (!strcmp(mname, "toWord")) { jt = jobj; }
> + else if (!strcmp(mname, "toAddress")) { jt = jobj; }
> + else if (!strcmp(mname, "toObject")) { jt = jobj; }
> + else if (!strcmp(mname, "toExtent")) { jt = jobj; }
> + else if (!strcmp(mname, "toOffset")) { jt = jobj; }
> + if (jt != jvoid) {
> + if (jt!=i64) {
> + vstack_replace_top_opnd(this, jt);
> + return true;
> + }
> + vstack_replace_top_opnd(this, i32);
> +
> + Opnd srcOpnd = vstack(0, true).as_opnd(i32);
> + Opnd lo(jt, valloc(jt));
> + do_mov(lo, srcOpnd);
> +
> + Opnd hi(jt, g_iconst_0);
> + vpop();
> + vpush2(lo, hi);
> + return true;
> + }
> +
> + if (!strcmp(mname, "attempt")) {
> + AR addrReg;
> + if (args.size() == 4) { //attempt with Offset
> + AR newAddressReg = valloc(jobj);
> + rlock(newAddressReg);
> + addrReg= vstack(3, true).reg();
> + mov(newAddressReg, addrReg);
> + AR offsetReg= vstack(0, true).reg();
> + alu(alu_add, newAddressReg, offsetReg);
> + runlock(newAddressReg);
> + addrReg = newAddressReg;
> + vpop();
> + } else {
> + addrReg = vstack(2, true).reg();
> + }
> + rlock(addrReg);
> + AR newReg = vstack(0, true).reg();
> + rlock(newReg);
> + AR oldReg = vstack(1, true).reg();
> +
> + cmpxchg(true, addrReg, newReg, oldReg);
> +
> + runlock(addrReg);
> + runlock(newReg);
> +
> + //save the result
> + AR resultReg = valloc(i32);
> + rlock(resultReg);
> + mov(resultReg, Opnd(g_iconst_0));
> + cmovcc(z, resultReg, vaddr(i32, &g_iconst_1));
> + runlock(resultReg);
> +
> + //fixing the stack and saving the result.
> + vpop();
> + vpop();
> + vpop();
> + vpush(Opnd(i32, resultReg));
> +
> + return true;
> + }
> +
> + //
> + // xArray stuff
> + //
> + if (!strcmp(mname, "create")) {
> + VM_Data_Type atype = VM_DATA_TYPE_INT32;
> + Class_Handle elem_class = class_get_class_of_primitive_type(atype);
> + assert(elem_class != NULL);
> + Class_Handle array_class = class_get_array_of_class(elem_class);
> + assert(array_class != NULL);
> + Allocation_Handle ah = class_get_allocation_handle(array_class);
> + gen_new_array(ah);
> + return true;
> + }
> +
> + if (!strcmp(mname, "get")) {
> + gen_arr_load(jobj);
> + return true;
> + }
> +
> + if (!strcmp(mname, "set")) {
> + gen_arr_store(jobj, false);
> + return true;
> + }
> + if (!strcmp(mname, "length")) {
> + gen_array_length();
> + return true;
> + }
> + //assert(false);
> + return false;
> +
> +#endif //not em64t
> +}
> +
> +}}; // ~namespace Jitrino::Jet
>
>
>
>
---------------------------------------------------------------------
Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
For additional commands, e-mail: harmony-dev-help@incubator.apache.org