Did that test pass before? [EMAIL PROTECTED] 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]