harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Geir Magnusson Jr <g...@pobox.com>
Subject 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
Date Sat, 07 Oct 2006 18:19:28 GMT
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


Mime
View raw message