You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2008/03/17 09:04:04 UTC

svn commit: r637775 - in /harmony/enhanced/drlvm/trunk/vm: include/open/ jitrino/src/codegenerator/ia32/ jitrino/src/jet/ vmcore/src/jit/ vmcore/src/lil/ia32/ vmcore/src/util/ia32/base/

Author: mfursov
Date: Mon Mar 17 01:04:01 2008
New Revision: 637775

URL: http://svn.apache.org/viewvc?rev=637775&view=rev
Log:
HARMONY-4620 [drlvm][jit] XMM based calling conversion for x86 mode

Modified:
    harmony/enhanced/drlvm/trunk/vm/include/open/rt_helpers.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_arith.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_dbg.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_stk.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/rt_helper_info.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/ini_iA32.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/rt_helpers.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/rt_helpers.h?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/rt_helpers.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/rt_helpers.h Mon Mar 17 01:04:01 2008
@@ -705,6 +705,7 @@
     CALLING_CONVENTION_DRL = 0,
     CALLING_CONVENTION_STDCALL,
     CALLING_CONVENTION_CDECL,
+    CALLING_CONVENTION_MULTIARRAY
 };
 
 /** 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp Mon Mar 17 01:04:01 2008
@@ -22,8 +22,8 @@
 #include "Ia32CallingConvention.h"
 #include "Ia32IRManager.h"
 
-namespace Jitrino{
-namespace Ia32{
+namespace Jitrino {
+namespace Ia32 {
 
 const CallingConvention * CallingConvention::str2cc(const char * cc_name) {
     if( NULL == cc_name ) { // default
@@ -35,7 +35,7 @@
     }
 
     if( !strcmpi(cc_name, "drl") ) {
-        return &CallingConvention_DRL;
+        return &CallingConvention_Managed;
     }
 
     if( !strcmpi(cc_name, "cdecl") ) {
@@ -48,12 +48,12 @@
 
 //========================================================================================
 STDCALLCallingConvention        CallingConvention_STDCALL;
-DRLCallingConvention            CallingConvention_DRL;
 CDECLCallingConvention          CallingConvention_CDECL;
-
+ManagedCallingConvention        CallingConvention_Managed;
+MultiArrayCallingConvention     CallingConvention_MultiArray;
 
 //========================================================================================
-// class STDCALLCallingConvention
+// STDCALLCallingConvention
 //========================================================================================
 
 #ifdef _EM64T_
@@ -66,22 +66,68 @@
 #endif
 #endif
 
+#ifdef _IA32_
 //______________________________________________________________________________________
-void    STDCALLCallingConvention::getOpndInfo(ArgKind kind, uint32 count, OpndInfo * infos)const
+void STDCALLCallingConventionIA32::getOpndInfo(ArgKind kind, uint32 count, OpndInfo * infos) const
 {
-    if (kind==ArgKind_InArg){
-#ifdef _EM64T_
-        uint32 gpreg = 0;
-#ifdef _WIN64
-#define fpreg gpreg
+    if (kind == ArgKind_InArg) {
+        for (uint32 i=0; i<count; i++){
+    
+            Type::Tag typeTag=(Type::Tag)infos[i].typeTag;
+            OpndSize size=IRManager::getTypeSize(typeTag);
+            assert(size!=OpndSize_Null && size<=OpndSize_64);
+
+            infos[i].slotCount=1;
+            infos[i].slots[0]=RegName_Null;
+            infos[i].isReg=false;
+    
+            if (size==OpndSize_64){
+                infos[i].slotCount=2;
+                infos[i].slots[1]=RegName_Null;
+            }
+        }
+    } else {
+        assert(kind == ArgKind_RetArg);
+        assert(count <= 1);
+        if (count == 1) {
+            Type::Tag typeTag=(Type::Tag)infos[0].typeTag;
+            infos[0].isReg=true;
+            switch (typeTag) {
+                case Type::Void:
+                    infos[0].slotCount=0;
+                    break;
+                case Type::Float:
+                case Type::Double:
+                case Type::Single:
+                    infos[0].slotCount=1;
+                    infos[0].slots[0]=RegName_FP0;
+                    break;
+                default: {
+                    OpndSize size=IRManager::getTypeSize(typeTag);
+                    assert(size!=OpndSize_Null && size<=OpndSize_64);
+    
+                    infos[0].slotCount=1;
+                    infos[0].slots[0]=RegName_EAX;
+        
+                    if (size == OpndSize_64) {
+                        infos[0].slotCount=2;
+                        infos[0].slots[1]=RegName_EDX;
+                    }
+                }
+            };
+        }
+    }
+}
+
 #else
+void STDCALLCallingConventionEM64T::getOpndInfo(ArgKind kind, uint32 count, OpndInfo * infos) const
+{
+    if (kind == ArgKind_InArg) {
+        uint32 gpreg = 0;
         uint32 fpreg = 0;
-#endif
-#endif
         for (uint32 i=0; i<count; i++){
     
             Type::Tag typeTag=(Type::Tag)infos[i].typeTag;
-#ifdef _EM64T_
             if(((typeTag>Type::Float  ||typeTag<Type::Single)  && gpreg < lengthof(fastCallGPRegs))) {
                 infos[i].slotCount=1;
                 infos[i].slots[0]=fastCallGPRegs[gpreg];
@@ -97,142 +143,109 @@
                 infos[i].slots[0]=RegName_Null;
                 infos[i].isReg=false;
             }
-            
-    
-#else
-            OpndSize size=IRManager::getTypeSize(typeTag);
-            assert(size!=OpndSize_Null && size<=OpndSize_64);
-
-            infos[i].slotCount=1;
-            infos[i].slots[0]=RegName_Null;
-            infos[i].isReg=false;
-    
-            if (size==OpndSize_64){
-                infos[i].slotCount=2;
-                infos[i].slots[1]=RegName_Null;
-            }
-#endif
-    
         }
-    }else{
-        for (uint32 i=0; i<count; i++){
-            Type::Tag typeTag=(Type::Tag)infos[i].typeTag;
-            infos[i].isReg=true;
-            if (i>0){
-                infos[i].slotCount=0;
-            }else{
-                switch(typeTag){
-                    case Type::Void:
-                        infos[i].slotCount=0;
-                        break;
-                    case Type::Float:
-                    case Type::Double:
-                    case Type::Single:
-#ifdef _EM64T_
-                        infos[i].slotCount=1;
-                        infos[i].slots[0]=RegName_XMM0;
-#else
-                        infos[i].slotCount=1;
-                        infos[i].slots[0]=RegName_FP0;
-#endif
-                        break;
-                    default:
-                    {
-                        OpndSize size=IRManager::getTypeSize(typeTag);
-#ifdef _EM64T_
-                        infos[i].slotCount=1;
-                        infos[i].slots[0]=RegName_RAX;
-        
-                        if (size==OpndSize_128){
-                            infos[i].slotCount=2;
-                            infos[i].slots[1]=RegName_RDX;
-                        }
-#else
-                        assert(size!=OpndSize_Null && size<=OpndSize_64);
-    
-                        infos[i].slotCount=1;
-                        infos[i].slots[0]=RegName_EAX;
-        
-                        if (size==OpndSize_64){
-                            infos[i].slotCount=2;
-                            infos[i].slots[1]=RegName_EDX;
-                        }
-#endif
+    } else {
+        assert(kind == ArgKind_RetArg);
+        assert(count <= 1);
+        if (count == 1) {
+            Type::Tag typeTag=(Type::Tag)infos[0].typeTag;
+            infos[0].isReg=true;
+            switch (typeTag) {
+                case Type::Void:
+                    infos[0].slotCount=0;
+                    break;
+                case Type::Float:
+                case Type::Double:
+                case Type::Single:
+                    infos[0].slotCount=1;
+                    infos[0].slots[0]=RegName_XMM0;
+                    break;
+                default: {
+                    OpndSize size=IRManager::getTypeSize(typeTag);
+                    infos[0].slotCount=1;
+                    infos[0].slots[0]=RegName_RAX;
+                    
+                    if (size == OpndSize_128) {
+                        infos[0].slotCount=2;
+                        infos[0].slots[1]=RegName_RDX;
                     }
                 }
-            }
+            };
         }
     }
 }
+#endif
 
+#ifdef _IA32_
 //______________________________________________________________________________________
-Constraint  STDCALLCallingConvention::getCalleeSavedRegs(OpndKind regKind)const
+Constraint STDCALLCallingConventionIA32::getCalleeSavedRegs(OpndKind regKind) const
+{
+    switch (regKind){
+        case OpndKind_GPReg:
+            return (Constraint(RegName_EBX)|RegName_EBP|RegName_ESI|RegName_EDI);
+        default:
+            return Constraint();
+    }
+}
+
+#else
+Constraint STDCALLCallingConventionEM64T::getCalleeSavedRegs(OpndKind regKind) const
 {
     switch (regKind){
         case OpndKind_GPReg:
 #ifdef _WIN64
             return (Constraint(RegName_RBX)|RegName_RBP|RegName_R12|RegName_R13|RegName_R14|RegName_R15|RegName_RSI|RegName_RDI);
-#elif _EM64T_
-            return (Constraint(RegName_RBX)|RegName_RBP|RegName_R12|RegName_R13|RegName_R14|RegName_R15);
 #else
-            return (Constraint(RegName_EBX)|RegName_EBP|RegName_ESI|RegName_EDI);
+            return (Constraint(RegName_RBX)|RegName_RBP|RegName_R12|RegName_R13|RegName_R14|RegName_R15);
 #endif
         default:
             return Constraint();
     }
 }
-#ifdef _EM64T_
+#endif
+
+
 //______________________________________________________________________________________
-void    CDECLCallingConvention::getOpndInfo(ArgKind kind, uint32 count, OpndInfo * infos)const
+#ifdef _IA32_
+void ManagedCallingConventionIA32::getOpndInfo(ArgKind kind, uint32 count, OpndInfo * infos) const
 {
-    if (kind==ArgKind_InArg){
-        for (uint32 i=0; i<count; i++){
-    
-                infos[i].slotCount=1;
-                infos[i].slots[0]=RegName_Null;
-                infos[i].isReg=false;
+    if (kind == ArgKind_RetArg) {
+        assert(count <= 1);
+        if (count == 1) {
+            Type::Tag typeTag = (Type::Tag)infos[0].typeTag;
+            switch (typeTag) {
+                case Type::Float:
+                case Type::Double:
+                case Type::Single:
+                    infos[0].isReg = true;
+                    infos[0].slotCount = 1;
+                    infos[0].slots[0] = RegName_XMM0;
+                    return;
+                default:;
+            };
         }
-    }else{
-        for (uint32 i=0; i<count; i++){
-            Type::Tag typeTag=(Type::Tag)infos[i].typeTag;
-            if (i>0){
-                infos[i].isReg=false;
-                infos[i].slotCount=0;
-            }else{
-                switch(typeTag){
-                    case Type::Void:
-                        infos[i].isReg=false;
-                        infos[i].slotCount=0;
-                        break;
-                    case Type::Float:
-                    case Type::Double:
-                    case Type::Single:
-                        infos[i].isReg=true;
-                        infos[i].slotCount=1;
-                        infos[i].slots[0]=RegName_XMM0;
-                        break;
-                    default:
-                    {
-                        OpndSize size=IRManager::getTypeSize(typeTag);
-                        infos[i].slotCount=1;
-                        infos[i].slots[0]=RegName_RAX;
-                        infos[i].isReg=true;
         
-                        if (size==OpndSize_128){
-                            infos[i].slotCount=2;
-                            infos[i].slots[1]=RegName_RDX;
-                        }
-                    }
-                }
-            }
-        }
     }
+    return STDCALLCallingConventionIA32::getOpndInfo(kind, count, infos);
 }
-
+#else
 #endif
 
-//______________________________________________________________________________________
-
+#ifdef _IA32_
+#else
+void MultiArrayCallingConventionEM64T::getOpndInfo(ArgKind kind, uint32 count, OpndInfo * infos) const
+{
+    if (kind == ArgKind_InArg){
+        for (uint32 i = 0; i < count; i++) {    
+                infos[i].slotCount = 1;
+                infos[i].slots[0] = RegName_Null;
+                infos[i].isReg = false;
+        }
+    } else {
+        CDECLCallingConventionEM64T::getOpndInfo(kind, count, infos);
+    }
+}
+#endif
 
 };  // namespace Ia32
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.h?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.h Mon Mar 17 01:04:01 2008
@@ -63,14 +63,14 @@
 //========================================================================================
 // class CallingConvention
 //========================================================================================
-/**
-Interface CallingConvention describes a particular calling convention.
-
-As calling convention rules can be more or less formally defined, 
-it is worth to define this entity as a separate class or interface
-Implementers of this interface are used as arguments to some IRManager methods 
 
-*/
+/**
+ * Interface CallingConvention describes a particular calling convention.
+ * 
+ * As calling convention rules can be more or less formally defined,
+ * it is worth to define this entity as a separate class or interface
+ * Implementers of this interface are used as arguments to some IRManager methods 
+ */
 class CallingConvention
 {   
 public: 
@@ -129,79 +129,117 @@
 
 
 //========================================================================================
-// class STDCALLCallingConvention
+// STDCALLCallingConvention
 //========================================================================================
-/** Implementation of CallingConvention for the STDCALL calling convention
-*/
 
-class STDCALLCallingConvention: public CallingConvention
+/**
+ * Implementation of CallingConvention for the STDCALL calling convention
+ */
+class STDCALLCallingConventionIA32: public CallingConvention
 {   
 public: 
     
-    virtual ~STDCALLCallingConvention() {}
-    virtual void    getOpndInfo(ArgKind kind, uint32 argCount, OpndInfo * infos)const;
-    virtual Constraint  getCalleeSavedRegs(OpndKind regKind)const;
-#ifdef _EM64T_
-    virtual bool    calleeRestoresStack()const{ return false; }
-    virtual uint32 getStackAlignment()const { return STACK_ALIGNMENT; }
-#else
-    virtual bool    calleeRestoresStack()const{ return true; }
-#endif
-    virtual bool    pushLastToFirst()const{ return true; }
+    virtual             ~STDCALLCallingConventionIA32() {}
+    virtual void        getOpndInfo(ArgKind kind, uint32 argCount, OpndInfo * infos) const;
+    virtual Constraint  getCalleeSavedRegs(OpndKind regKind) const;
+    virtual bool        calleeRestoresStack() const{ return true; }
+    virtual bool        pushLastToFirst() const { return true; }
+
+};
+
+class STDCALLCallingConventionEM64T: public CallingConvention
+{   
+public: 
+    
+    virtual             ~STDCALLCallingConventionEM64T() {}
+    virtual void        getOpndInfo(ArgKind kind, uint32 argCount, OpndInfo * infos) const;
+    virtual Constraint  getCalleeSavedRegs(OpndKind regKind) const;
+    virtual bool        calleeRestoresStack() const { return false; }
+    virtual uint32      getStackAlignment() const { return STACK_ALIGNMENT; }
+    virtual bool        pushLastToFirst() const { return true; }
 
 };
 
 //========================================================================================
-// class DRLCallingConvention
+// CDECL CallingConvention
 //========================================================================================
 
 /**
- * Implementation of CallingConvention for the DRL IA32 calling convention
+ * Implementation of CallingConvention for the CDECL calling convention
  */
-class DRLCallingConventionIA32: public STDCALLCallingConvention
+class CDECLCallingConventionIA32: public STDCALLCallingConventionIA32
 {   
 public: 
-    virtual ~DRLCallingConventionIA32() {}
-    virtual bool    pushLastToFirst()const{ return false; }
-    virtual uint32 getStackAlignment()const { return STACK_ALIGNMENT; }
+    virtual         ~CDECLCallingConventionIA32() {}
+    virtual bool    calleeRestoresStack() const { return false; }
 };
 
-/**
- * Implementation of CallingConvention for the DRL EM64T calling convention
- */
-class DRLCallingConventionEM64T: public STDCALLCallingConvention
+class CDECLCallingConventionEM64T: public STDCALLCallingConventionEM64T
 {   
 public: 
-    virtual ~DRLCallingConventionEM64T() {}
-    virtual uint32 getStackAlignment()const { return STACK_ALIGNMENT; }
+    virtual         ~CDECLCallingConventionEM64T() {}
 };
 
 //========================================================================================
-// class CDECLCallingConvention
+//  Managed CallingConvention
 //========================================================================================
-/** Implementation of CallingConvention for the CDECL calling convention
-*/
-class CDECLCallingConvention: public STDCALLCallingConvention
+
+/**
+ * Implementation of CallingConvention for the Managed calling convention
+ */
+class ManagedCallingConventionIA32: public STDCALLCallingConventionIA32
 {   
 public: 
-    virtual ~CDECLCallingConvention() {}
-    virtual bool    calleeRestoresStack()const{ return false; }
-#ifdef _EM64T_
-    virtual void    getOpndInfo(ArgKind kind, uint32 argCount, OpndInfo * infos)const;
-    virtual bool    pushLastToFirst()const{ return true; }
-    virtual uint32 getStackAlignment()const { return STACK_ALIGNMENT; }
-#endif
+    virtual         ~ManagedCallingConventionIA32() {}
+    virtual void    getOpndInfo(ArgKind kind, uint32 argCount, OpndInfo * infos) const;
+    virtual bool    pushLastToFirst( ) const { return false; }
+    virtual uint32  getStackAlignment() const { return STACK_ALIGNMENT; }
+};
+
+class ManagedCallingConventionEM64T: public STDCALLCallingConventionEM64T
+{   
+public: 
+    virtual         ~ManagedCallingConventionEM64T() {}
+};
+
+
+//========================================================================================
+//  MultiArray CallingConvention
+//========================================================================================
+
+/**
+ * Special calling convention for multi-array creation.
+ * It's CDECL like but always passes arguments through the stack. 
+ */
+class MultiArrayCallingConventionIA32: public CDECLCallingConventionIA32
+{
+public:
+    virtual         ~MultiArrayCallingConventionIA32() {}
+};
+
+class MultiArrayCallingConventionEM64T: public CDECLCallingConventionEM64T
+{
+public:
+    virtual         ~MultiArrayCallingConventionEM64T() {}    
+    virtual void    getOpndInfo(ArgKind kind, uint32 argCount, OpndInfo * infos) const;
 };
 
 #ifdef _EM64T_
-typedef DRLCallingConventionEM64T   DRLCallingConvention;
+typedef STDCALLCallingConventionEM64T       STDCALLCallingConvention;
+typedef CDECLCallingConventionEM64T         CDECLCallingConvention;
+typedef ManagedCallingConventionEM64T       ManagedCallingConvention;
+typedef MultiArrayCallingConventionEM64T    MultiArrayCallingConvention;
 #else
-typedef DRLCallingConventionIA32    DRLCallingConvention;
+typedef STDCALLCallingConventionIA32        STDCALLCallingConvention;
+typedef CDECLCallingConventionIA32          CDECLCallingConvention;
+typedef ManagedCallingConventionIA32        ManagedCallingConvention;
+typedef MultiArrayCallingConventionIA32     MultiArrayCallingConvention;
 #endif
 
 extern STDCALLCallingConvention     CallingConvention_STDCALL;
-extern DRLCallingConvention         CallingConvention_DRL;
 extern CDECLCallingConvention       CallingConvention_CDECL;
+extern ManagedCallingConvention     CallingConvention_Managed;
+extern MultiArrayCallingConvention  CallingConvention_MultiArray;
 
 }; // namespace Ia32
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp Mon Mar 17 01:04:01 2008
@@ -1267,11 +1267,13 @@
     HELPER_CALLING_CONVENTION callConv = compilationInterface.getRuntimeHelperCallingConvention(helperId);
     switch (callConv){
         case CALLING_CONVENTION_DRL:
-            return &CallingConvention_DRL;
+            return &CallingConvention_Managed;
         case CALLING_CONVENTION_STDCALL:
             return &CallingConvention_STDCALL;
         case CALLING_CONVENTION_CDECL:
             return &CallingConvention_CDECL;
+        case CALLING_CONVENTION_MULTIARRAY:
+            return &CallingConvention_MultiArray;
         default:
             assert(0);
             return NULL;
@@ -1281,7 +1283,7 @@
 //_________________________________________________________________________________________________
 const CallingConvention * IRManager::getCallingConvention(MethodDesc * methodDesc)const
 {
-    return &CallingConvention_DRL;
+    return &CallingConvention_Managed;
 }
 
 //_________________________________________________________________________________________________

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h Mon Mar 17 01:04:01 2008
@@ -260,7 +260,7 @@
 
     const CallingConvention * getCallingConvention(MethodDesc * methodDesc)const;
 
-    const CallingConvention * getDefaultManagedCallingConvention() const { return &CallingConvention_DRL; }
+    const CallingConvention * getDefaultManagedCallingConvention() const { return &CallingConvention_Managed; }
 
     EntryPointPseudoInst * getEntryPointInst()const { return entryPointInst; }
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp Mon Mar 17 01:04:01 2008
@@ -440,24 +440,36 @@
         return;
     }
     switch(jinst.opcode) {
-    case OPCODE_IRETURN:
-        gen_return(i32);
-        break;
-    case OPCODE_LRETURN:
-        gen_return(i64);
-        break;
-    case OPCODE_FRETURN:
-        gen_return(flt32);
-        break;
-    case OPCODE_DRETURN:
-        gen_return(dbl64);
-        break;
-    case OPCODE_ARETURN:
-        gen_return(jobj);
-        break;
-    case OPCODE_RETURN:
-        gen_return(jvoid);   
+    case OPCODE_IRETURN: {
+        static const CallSig cs(CCONV_MANAGED, i32);
+        gen_return(cs);
+        break;
+    }
+    case OPCODE_LRETURN: {
+        static const CallSig cs(CCONV_MANAGED, i64);
+        gen_return(cs);
+        break;
+    }
+    case OPCODE_FRETURN: {
+        static const CallSig cs(CCONV_MANAGED, flt32);
+        gen_return(cs);
+        break;
+    }
+    case OPCODE_DRETURN: {
+        static const CallSig cs(CCONV_MANAGED, dbl64);
+        gen_return(cs);
+        break;
+    }
+    case OPCODE_ARETURN: {
+        static const CallSig cs(CCONV_MANAGED, jobj);
+        gen_return(cs);
+        break;
+    }
+    case OPCODE_RETURN: {
+        static const CallSig cs(CCONV_MANAGED, jvoid);
+        gen_return(cs);   
         break;
+    }
     default: assert(false);   break;
     };
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.cpp Mon Mar 17 01:04:01 2008
@@ -48,10 +48,10 @@
 namespace Jitrino {
 namespace Jet {
 
-const CallSig ci_helper_o(CCONV_HELPERS, jobj);
-const CallSig ci_helper_v(CCONV_HELPERS);
-const CallSig ci_helper_oi(CCONV_HELPERS, jobj, i32);
-const CallSig ci_helper_linkerr(CCONV_HELPERS, jobj, i32, i32);
+const CallSig ci_helper_o(CCONV_HELPERS, jvoid, jobj);
+const CallSig ci_helper_v(CCONV_HELPERS, jvoid);
+const CallSig ci_helper_oi(CCONV_HELPERS, jobj, jobj, i32);
+const CallSig ci_helper_linkerr(CCONV_HELPERS, jvoid, jobj, i32, i32);
 
 void CodeGen::do_mov(const Val& dst_s, const Val& src_s, bool skipTypeCheck)
 {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h Mon Mar 17 01:04:01 2008
@@ -324,17 +324,18 @@
     void gen_athrow(void);
     
     /**
-     * @brief Update BBState and pushes the given jtype on operand stack,
-     * as if the code just executed a call that returned the given jtype.
+     * @brief Update BBState and pushes return value on operand stack,
+     * as if the code just executed a call that returned the given value.
      * 
      * The item location is set according to the calling convention on 
      * which registers to use to return value of the given type.
      *
      * On IA-32 (where the float/double are returned through FPU) the 
      * item is spilled (code is generated to do so) into memory first.
-     * @param jtyp - type of the value 'returned'
+     * @param cs - calling signature descrubing the method to push return
+     *             value for.
      */
-    void gen_save_ret(jtype jtyp);
+    void gen_save_ret(const CallSig& cs);
     
     /**
      * @brief Generates code to call one of the throw_ helpers.

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_arith.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_arith.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_arith.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_arith.cpp Mon Mar 17 01:04:01 2008
@@ -300,52 +300,62 @@
 
     unsigned stackFix = 0;
     bool shft = op == OPCODE_ISHL || op == OPCODE_ISHR || op == OPCODE_IUSHR;
+    const CallSig* rcs = NULL;
     if (is_f(jt)) {
+        assert(jt == dbl64 || jt == flt32);
         char * helper = NULL;
         bool is_dbl = jt == dbl64;
         if (op == OPCODE_INEG) {
-            CallSig cs(CCONV_STDCALL, jt);
-            stackFix = gen_stack_to_args(true, cs, 0, 1);
+            static const CallSig cs_dbl(CCONV_STDCALL, dbl64, dbl64);
+            static const CallSig cs_flt(CCONV_STDCALL, flt32, flt32);
+            rcs = is_dbl? &cs_dbl : &cs_flt;
+            stackFix = gen_stack_to_args(true, *rcs, 0, 1);
             helper = is_dbl ? (char*)&rt_h_neg_dbl64 : (char*)&rt_h_neg_flt32;
-            gen_call_novm(cs, helper, 1);
-            runlock(cs);
+            gen_call_novm(*rcs, helper, 1);
+            runlock(*rcs);
         }
         else {
             //if (m_jframe->dip(1).stype == st_imm && )
-            CallSig cs(CCONV_STDCALL, jt, jt, i32);
-            stackFix = gen_stack_to_args(true, cs, 0, 2);
+            static const CallSig cs_dbl(CCONV_STDCALL, dbl64, dbl64, dbl64, i32);
+            static const CallSig cs_flt(CCONV_STDCALL, flt32, flt32, flt32, i32);
+            rcs = is_dbl? &cs_dbl : &cs_flt;
+            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
             helper = is_dbl ? (char*)&rt_h_dbl_a : (char*)&rt_h_flt_a;
-            gen_call_novm(cs, helper, 2, op);
-            runlock(cs);
+            gen_call_novm(*rcs, helper, 2, op);
+            runlock(*rcs);
         }
     }
     else if (jt==i64) {
         if (op == OPCODE_INEG) {
-            CallSig cs(CCONV_STDCALL, jt);
-            stackFix = gen_stack_to_args(true, cs, 0, 1);
-            gen_call_novm(cs, (void*)&rt_h_neg_i64, 1);
-            runlock(cs);
+            static const CallSig cs(CCONV_STDCALL, i64, i64);
+            rcs = &cs;
+            stackFix = gen_stack_to_args(true, *rcs, 0, 1);
+            gen_call_novm(*rcs, (void*)&rt_h_neg_i64, 1);
+            runlock(*rcs);
         }
         else if (shft) {
-            CallSig cs(CCONV_STDCALL, jt, i32, i32);
-            stackFix = gen_stack_to_args(true, cs, 0, 2);
-            gen_call_novm(cs, (void*)&rt_h_i64_shift, 2, op);
-            runlock(cs);
+            static const CallSig cs(CCONV_STDCALL, i64, i64, i32, i32);
+            rcs = &cs;
+            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
+            gen_call_novm(*rcs, (void*)&rt_h_i64_shift, 2, op);
+            runlock(*rcs);
         }
         else {
-            CallSig cs(CCONV_STDCALL, jt, jt, i32);
-            stackFix = gen_stack_to_args(true, cs, 0, 2);
-            gen_call_novm(cs, (void*)&rt_h_i64_a, 2, op);
-            runlock(cs);
+            static const CallSig cs(CCONV_STDCALL, i64, i64, i64, i32);
+            rcs = &cs;
+            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
+            gen_call_novm(*rcs, (void*)&rt_h_i64_a, 2, op);
+            runlock(*rcs);
         }
     }
     else {
         assert(jt==i32);
         if (op == OPCODE_INEG) {
-            CallSig cs(CCONV_STDCALL, jt);
-            stackFix = gen_stack_to_args(true, cs, 0, 1);
-            gen_call_novm(cs, (void*)&rt_h_neg_i32, 1);
-            runlock(cs);
+            static const CallSig cs(CCONV_STDCALL, i32, i32);
+            rcs = &cs;
+            stackFix = gen_stack_to_args(true, *rcs, 0, 1);
+            gen_call_novm(*rcs, (void*)&rt_h_neg_i32, 1);
+            runlock(*rcs);
         }
         else if (op == OPCODE_IADD || op == OPCODE_ISUB) {
             const Val& op2 = vstack(0);
@@ -365,13 +375,15 @@
             return;
         }
         else {
-            CallSig cs(CCONV_STDCALL, jt, jt, i32);
-            stackFix = gen_stack_to_args(true, cs, 0, 2);
-            gen_call_novm(cs, (void*)&rt_h_i32_a, 2, op);
-            runlock(cs);
+            static const CallSig cs(CCONV_STDCALL, i32, i32, i32, i32);
+            rcs = &cs;
+            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
+            gen_call_novm(*rcs, (void*)&rt_h_i32_a, 2, op);
+            runlock(*rcs);
         }
     }
-    gen_save_ret(jt);
+    assert(rcs != NULL);
+    gen_save_ret(*rcs);
     if (stackFix != 0) {
         alu(alu_sub, sp, stackFix);
     }
@@ -384,14 +396,14 @@
         return;
     }
     char *helper = (char *) cnv_matrix_impls[from][to];
-    CallSig cs(CCONV_STDCALL, from);
+    const CallSig cs(CCONV_STDCALL, to, from);
     unsigned stackFix = gen_stack_to_args(true, cs, 0);
     gen_call_novm(cs, helper, 1);
     if (stackFix != 0) {
         alu(alu_sub, sp, stackFix);
     }
     runlock(cs);
-    gen_save_ret(to);
+    gen_save_ret(cs);
 }
 
 void CodeGen::gen_x_cmp(JavaByteCodes op, jtype jt)
@@ -408,26 +420,26 @@
             helper = op == OPCODE_FCMPG ? 
                                  (char*)&rt_h_fcmp_g : (char*)&rt_h_fcmp_l;
         }
-        const CallSig cs(CCONV_STDCALL, jt, jt);
+        const CallSig cs(CCONV_STDCALL, i32, jt, jt);
         unsigned stackFix = gen_stack_to_args(true, cs, 0);
         gen_call_novm(cs, helper, 2);
         if (stackFix != 0) {
             alu(alu_sub, sp, stackFix);
         }
         runlock(cs);
-        gen_save_ret(i32);
+        gen_save_ret(cs);
         return;
     }
     assert(op == OPCODE_LCMP);
     char *helper = (char *)rt_h_lcmp;
-    static const CallSig cs(CCONV_STDCALL, i64, i64);
+    static const CallSig cs(CCONV_STDCALL, i32, i64, i64);
     unsigned stackFix = gen_stack_to_args(true, cs, 0);
     gen_call_novm(cs, helper, 2);
     if (stackFix != 0) {
         alu(alu_sub, sp, stackFix);
     }
     runlock(cs);
-    gen_save_ret(i32);
+    gen_save_ret(cs);
 }
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_dbg.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_dbg.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_dbg.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_dbg.cpp Mon Mar 17 01:04:01 2008
@@ -33,7 +33,7 @@
 namespace Jitrino {
 namespace Jet {
 
-const CallSig CodeGen::cs_trace_arg(CCONV_STDCALL, jobj, i32, i32);
+const CallSig CodeGen::cs_trace_arg(CCONV_STDCALL, jvoid, jobj, i32, i32);
 
 
 void CodeGen::dbg_check_mem(void)
@@ -137,7 +137,7 @@
     strcpy(lost, tmp_buf);
     strcat(lost, id_buf);
     if (save_regs) { push_all(); }
-    static const CallSig cs(CCONV_STDCALL, jobj);
+    static const CallSig cs(CCONV_STDCALL, jvoid, jobj);
     call(is_set(DBG_CHECK_STACK), gr0, (void*)&dbg_rt_out, cs, 0, lost);
     if (save_regs) { pop_all(); }
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp Mon Mar 17 01:04:01 2008
@@ -134,7 +134,7 @@
     // stack: [.., aref, idx, val]
     if (jt == jobj && helperOk) {
         gen_write_barrier(m_curr_inst->opcode, NULL, Opnd(0));
-        static const CallSig cs_aastore(CCONV_HELPERS, jobj, i32, jobj);
+        static const CallSig cs_aastore(CCONV_HELPERS, jvoid, jobj, i32, jobj);
         unsigned stackFix = gen_stack_to_args(true, cs_aastore, 0);
         gen_call_vm(cs_aastore, rt_helper_aastore, 3);
         if (stackFix != 0) {
@@ -241,9 +241,10 @@
             Val& ref = vstack(ref_depth, true);
             where = Opnd(jt, ref.reg(), fld_offset);
         }  else { //field is not resolved -> generate code to request offset
-            static const CallSig cs_get_offset(CCONV_HELPERS, iplatf, i32, i32);
+            static const CallSig cs_get_offset(CCONV_HELPERS, iplatf, iplatf, i32, i32);
             gen_call_vm(cs_get_offset, rt_helper_field_get_offset_withresolve, 0, fieldOp.enclClass, fieldOp.cpIndex, fieldOp.isPut());
             runlock(cs_get_offset);
+            AR gr_ret = cs_get_offset.ret_reg(0);
             rlock(gr_ret);
             Val& ref = vstack(ref_depth, true);
             runlock(gr_ret);
@@ -255,9 +256,10 @@
             char * fld_addr = (char*)field_get_address(fieldOp.fld);
             where = vaddr(jt, fld_addr);
         }  else { //field is not resolved -> generate code to request address
-            static const CallSig cs_get_addr(CCONV_HELPERS, iplatf, i32, i32);
+            static const CallSig cs_get_addr(CCONV_HELPERS, iplatf, iplatf, i32, i32);
             gen_call_vm(cs_get_addr, rt_helper_field_get_address_withresolve, 0, fieldOp.enclClass, fieldOp.cpIndex, fieldOp.isPut());
             runlock(cs_get_addr);
+            AR gr_ret = cs_get_addr.ret_reg(0);
             where = Opnd(jt, gr_ret, 0);
         }
     }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp Mon Mar 17 01:04:01 2008
@@ -83,6 +83,7 @@
     // portable and 'official' way:
     gen_call_vm(platform_v, rt_helper_get_tls_base_ptr, 0);
     // The address of flag is now in gr_ret
+    AR gr_ret = platform_v.ret_reg(0);
     Opnd mem(i32, gr_ret, rt_suspend_req_flag_offset);
     alu(alu_cmp, mem, Opnd(0));
     unsigned br_off = br(z, 0, 0, taken);
@@ -125,11 +126,11 @@
 
 #ifndef _EM64T_
     // Workaround since do_mov do not put jlong on stack in gen_args on ia32
-    const CallSig cs_ti_fmodif(CCONV_HELPERS, jobj, jobj, i32, i32, jobj, jobj);
+    static const CallSig cs_ti_fmodif(CCONV_HELPERS, jvoid, jobj, jobj, i32, i32, jobj, jobj);
     Val vlocation((jlong)m_pc);
     Val vlocationHi((jlong)0);
 #else
-    const CallSig cs_ti_fmodif(CCONV_HELPERS, jobj, jobj, i64, jobj, jobj);
+    static const CallSig cs_ti_fmodif(CCONV_HELPERS, jvoid, jobj, jobj, i64, jobj, jobj);
     Val vlocation((jlong)m_pc);
 #endif
 
@@ -222,11 +223,11 @@
 
 #ifndef _EM64T_
     // Workaround since do_mov do not put jlong on stack in gen_args on ia32
-    const CallSig cs_ti_faccess(CCONV_HELPERS, jobj, jobj, i32, i32, jobj);
+    static const CallSig cs_ti_faccess(CCONV_HELPERS, jvoid, jobj, jobj, i32, i32, jobj);
     Val vlocation((jlong)m_pc);
     Val vlocationHi((jlong)0);
 #else
-    const CallSig cs_ti_faccess(CCONV_HELPERS, jobj, jobj, i64, jobj);
+    static const CallSig cs_ti_faccess(CCONV_HELPERS, jvoid, jobj, jobj, i64, jobj);
     Val vlocation((jlong)m_pc);
 #endif
     rlock(cs_ti_faccess);
@@ -354,7 +355,7 @@
 
     // WB4C has the following signature:
     //(object written to, slot written to, value written to slot)
-    static const CallSig wb4c_sig(CCONV_CDECL, jobj, jobj, jobj);
+    static const CallSig wb4c_sig(CCONV_CDECL, jvoid, jobj, jobj, jobj);
     //static char* wb4c_helper = xxx_gc_heap_slot_write_ref
     static char* wb4c_helper = (char*)vm_helper_get_addr(VM_RT_GC_HEAP_WRITE_REF);
 
@@ -365,7 +366,7 @@
     }
     // WB4J has the following signature:
     //(object written to, slot written to, value written to slot, metaA, metaB, mode)
-    static const CallSig wb4j_sig(CCONV_MANAGED, jobj, jobj, jobj, i32, i32, i32);
+    static const CallSig wb4j_sig(CCONV_CDECL, jvoid, jobj, jobj, jobj, i32, i32, i32);
     static char* wb4j_helper = NULL;
     
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp Mon Mar 17 01:04:01 2008
@@ -44,7 +44,7 @@
 /**
  * CallSig for monitor_enter and monitor_exit helpers.
  */
-static CallSig cs_mon(CCONV_HELPERS, jobj);
+static const CallSig cs_mon(CCONV_HELPERS, jvoid, jobj);
 
 
 void Compiler::gen_prolog(void) {
@@ -515,7 +515,7 @@
         alu(alu_cmp, mem, Opnd(0));
         unsigned br_off = br(z, 0, 0, taken);
         
-        static const CallSig cs_ti_menter(CCONV_HELPERS, jobj);
+        static const CallSig cs_ti_menter(CCONV_HELPERS, jvoid, jobj);
         gen_call_vm(cs_ti_menter, rt_helper_ti_method_enter, 0, m_method);
         
         patch(br_off, ip());
@@ -552,8 +552,9 @@
     }
 }
 
-void Compiler::gen_return(jtype retType)
+void Compiler::gen_return(const CallSig& cs)
 {
+    jtype retType = cs.ret_jt(); 
     if (is_set(DBG_TRACE_EE)) {
         gen_dbg_rt(true, "exiting : %s", meth_fname());
     }
@@ -608,7 +609,7 @@
     if (compilation_params.exe_notify_method_exit) {
 
         // JVMTI helper takes pointer to return value and method handle
-        const CallSig cs_ti_mexit(CCONV_HELPERS, jobj, jobj);
+        static const CallSig cs_ti_mexit(CCONV_HELPERS, jvoid, jobj, jobj);
         // The call is a bit unusual, and is processed as follows:
         // we load an address of the top of the operand stack into 
         // a temporary register, and then pass this value as pointer
@@ -649,26 +650,28 @@
         patch(br_off, ip());
     }
 
+    AR out_reg = cs.ret_reg(0); 
     if (is_f(retType)) {
-#ifdef _IA32_
-        // On IA-32 always swap to memory first, then upload into FPU
-        vswap(0);
-        ld(retType, fr_ret, m_base, vstack_off(0));
-#else
-        // Make sure the item is not immediate
-        Val op = vstack(0, vis_imm(0));
-        if (!op.is_reg() || op.reg() != fr_ret) {
-            Opnd ret(retType, fr_ret);
+        if (out_reg == fp0) {
+            // On IA-32 always swap to memory first, then upload into FPU
+            vswap(0);
+            ld(retType, out_reg, m_base, vstack_off(0));
+        } else {
+            // Make sure the item is not immediate
+            Val op = vstack(0, vis_imm(0));
+            if (!op.is_reg() || op.reg() != out_reg) {
+                Opnd ret(retType, out_reg);
             mov(ret, op.as_opnd());
+            }
         }
-#endif
     }
     else if (is_big(retType)) {
 #ifdef _IA32_
         vswap(0);
         vswap(1);
-        ld4(eax.reg(), m_base, vstack_off(0));
-        ld4(edx.reg(), m_base, vstack_off(1));
+        AR out_reg1 = cs.ret_reg(1); 
+        ld4(out_reg, m_base, vstack_off(0));
+        ld4(out_reg1, m_base, vstack_off(1));
 #else
         assert(false && "Unexpected case - 'big' type on EM64T");
 #endif
@@ -676,8 +679,8 @@
     }
     else if (retType != jvoid) {
         Val& op = vstack(0);
-        if (!op.is_reg() || op.reg() != gr_ret) {
-            Opnd ret(retType, gr_ret);
+        if (!op.is_reg() || op.reg() != out_reg) {
+            Opnd ret(retType, out_reg);
             mov(ret, op.as_opnd());
         }
     }
@@ -740,7 +743,7 @@
 
     const JInst& jinst = *m_curr_inst;
     
-    CallSig cs(CCONV_MANAGED, args);
+    CallSig cs(CCONV_MANAGED, retType, args);
     for (unsigned i=0; i<cs.count(); i++) {
         AR ar = cs.reg(i);
         if (ar == ar_x) continue;
@@ -759,7 +762,7 @@
         runlock(cs); // due to gen_stack_to_args()
         gen_gc_stack(-1, true);
         if (retType != jvoid) {
-            gen_save_ret(retType);
+            gen_save_ret(cs);
         }
         if (stackFix != 0) {
             alu(alu_sub, sp, stackFix);
@@ -799,16 +802,18 @@
     if (meth == NULL) {
         //lazy resolution mode: get method addr and call it.
         assert(m_lazy_resolution);
+        AR gr_ret = ar_x;
         //1. get method address
         if (opcod == OPCODE_INVOKESTATIC || opcod == OPCODE_INVOKESPECIAL) {
-            static const CallSig cs_get_is_addr(CCONV_HELPERS, iplatf, i32);
+            static const CallSig cs_get_is_addr(CCONV_HELPERS, iplatf, iplatf, i32);
             char* helper = opcod == OPCODE_INVOKESTATIC ?  rt_helper_get_invokestatic_addr_withresolve :
                                                            rt_helper_get_invokespecial_addr_withresolve;
             gen_call_vm(cs_get_is_addr, helper, 0, m_klass, cpIndex);
             runlock(cs_get_is_addr);
+            gr_ret = cs_get_is_addr.ret_reg(0);
         } else {
             assert(opcod == OPCODE_INVOKEVIRTUAL || opcod == OPCODE_INVOKEINTERFACE);
-            static const CallSig cs_get_iv_addr(CCONV_HELPERS, iplatf, i32, jobj);
+            static const CallSig cs_get_iv_addr(CCONV_HELPERS, iplatf, iplatf, i32, jobj);
             char * helper = opcod == OPCODE_INVOKEVIRTUAL ? rt_helper_get_invokevirtual_addr_withresolve : 
                                                             rt_helper_get_invokeinterface_addr_withresolve;
             // setup constant parameters first,
@@ -817,6 +822,7 @@
             gen_args(cs_get_iv_addr, 0, &vclass, &vcpIdx, &thiz);
             gen_call_vm(cs_get_iv_addr, helper, 3);
             runlock(cs_get_iv_addr);
+            gr_ret = cs_get_iv_addr.ret_reg(0);
         } 
         rlock(gr_ret); //WARN: call addr is in gr_ret -> lock it
 
@@ -833,7 +839,7 @@
     else if (opcod == OPCODE_INVOKEINTERFACE) {
         // if it's INVOKEINTERFACE, then first resolve it
         Class_Handle klass = method_get_class(meth);
-        const CallSig cs_vtbl(CCONV_HELPERS, jobj, jobj);
+        const CallSig cs_vtbl(CCONV_HELPERS, iplatf, jobj, jobj);
         // Prepare args for ldInterface helper
         if (cs_vtbl.reg(0) == gr_x) {
             assert(cs_vtbl.size() != 0);
@@ -848,7 +854,7 @@
             mov(cs_vtbl.get(0), thiz.as_opnd());
         }
         gen_call_vm(cs_vtbl, rt_helper_get_vtable, 1, klass);
-
+        AR gr_ret = cs_vtbl.ret_reg(0);
         //
         // Method's vtable is in gr_ret now, prepare stack
         //
@@ -902,7 +908,7 @@
     runlock(cs);
     
     if (retType != jvoid) {
-        gen_save_ret(retType);
+        gen_save_ret(cs);
     }
     if (stackFix != 0) {
         alu(alu_sub, sp, stackFix);
@@ -939,10 +945,11 @@
     }
 }
 
-void CodeGen::gen_save_ret(jtype jt)
+void CodeGen::gen_save_ret(const CallSig& cs)
 {
+    jtype jt = cs.ret_jt();
     assert(jt != jvoid);
-    AR ar = is_f(jt) ? fr_ret : gr_ret;
+    AR ar = cs.ret_reg(0);
     if (jt==i8) {
         sx1(Opnd(i32, ar), Opnd(jt,ar));
         jt = i32;
@@ -956,7 +963,7 @@
         jt = i32;
     }
 #ifdef _IA32_
-    if(ar == fr_ret) {
+    if(ar == fp0) {
         // Cant use vstack_off right here, as the item is not yet pushed.
         unsigned slot = m_jframe->size();
         if (is_wide(jt)) {
@@ -964,13 +971,12 @@
         }
         vpush(Val(jt, m_base, voff(m_stack.stack_slot(slot))));
         //
-        st(jt, fr_ret, m_base, vstack_off(0));
+        st(jt, fp0, m_base, vstack_off(0));
     }
     else if (is_big(jt)) {
         assert(jt==i64);
-        static const AR eax = virt(RegName_EAX);
-        static const AR edx = virt(RegName_EDX);
-        vpush2(Val(jt, eax), Val(jt, edx));
+        AR ar1 = cs.ret_reg(1);
+        vpush2(Val(jt, ar), Val(jt, ar1));
     }
     else
 #endif
@@ -985,7 +991,7 @@
         AR gtmp = gr0;
         //ld(jobj, gtmp, bp, m_stack.stack_slot(m_jframe->depth2slot(0)));
         Opnd tmp(jt, gtmp);
-        mov(tmp, Opnd(jt, gr_ret));
+        mov(tmp, Opnd(jt, ar));
         if (cs_trace_arg.reg(0) != gr_x)  { 
             if (cs_trace_arg.size() != 0) {
                 alu(alu_sub, sp, cs_trace_arg.size());

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp Mon Mar 17 01:04:01 2008
@@ -57,7 +57,7 @@
         return;
     } 
     assert(lazy);
-    static const CallSig cs_newarray_withresolve(CCONV_HELPERS, iplatf, i32, i32);
+    static const CallSig cs_newarray_withresolve(CCONV_HELPERS, jobj, iplatf, i32, i32);
     Val sizeVal = vstack(0);
     // setup constant parameters first,
     Val vclass(iplatf, enclClass);
@@ -65,7 +65,7 @@
     gen_args(cs_newarray_withresolve, 0, &vclass, &vcpIdx, &sizeVal);
     gen_call_vm(cs_newarray_withresolve, rt_helper_new_array_withresolve, 3);
     vpop();// pop array size
-    gen_save_ret(jobj);
+    gen_save_ret(cs_newarray_withresolve);
 
     // the returned can not be null, marking as such.
     vstack(0).set(VA_NZ);
@@ -84,7 +84,7 @@
         gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0,
                        m_klass, jinst.op0, jinst.opcode);
     }
-    static const CallSig cs_new_arr(CCONV_HELPERS, i32, jobj);
+    static const CallSig cs_new_arr(CCONV_HELPERS, jobj, i32, jobj);
     unsigned stackFix = gen_stack_to_args(true, cs_new_arr, 0, 1);
     gen_call_vm(cs_new_arr, rt_helper_new_array, 1, ah);
     runlock(cs_new_arr);
@@ -92,7 +92,7 @@
     if (stackFix != 0) {
         alu(alu_sub, sp, stackFix);
     }
-    gen_save_ret(jobj);
+    gen_save_ret(cs_new_arr);
     // the returned can not be null, marking as such.
     vstack(0).set(VA_NZ);
     // allocation assumes GC invocation
@@ -120,9 +120,10 @@
     bool resolve = !lazy || class_cp_is_entry_resolved(enclClass, cpIndex);
     if(!resolve) {
         assert(lazy);
-        static CallSig ci_get_class_withresolve(CCONV_HELPERS, iplatf, i32);
+        static const CallSig ci_get_class_withresolve(CCONV_HELPERS, jobj, iplatf, i32);
         gen_call_vm(ci_get_class_withresolve, rt_helper_get_class_withresolve, 0, enclClass, cpIndex);
         runlock(ci_get_class_withresolve);
+        AR gr_ret = ci_get_class_withresolve.ret_reg(0);
         klassVal = Val(jobj, gr_ret);
     }  else {
         klass = resolve_class(m_compileHandle, enclClass, cpIndex);
@@ -131,7 +132,7 @@
     rlock(klassVal); // to protect gr_ret while setting up helper args
 
     // note: need to restore the stack - the cdecl-like function
-    CallSig ci(CCONV_CDECL|CCONV_MEM|CCONV_L2R, args);
+    CallSig ci(CCONV_CDECL|CCONV_MEM|CCONV_L2R|CCONV_RETURN_FP_THROUGH_FPU, jobj, args);
     unsigned stackFix = gen_stack_to_args(true, ci, 0, num_dims);
 
     runlock(klassVal);
@@ -148,7 +149,7 @@
     if (stackFix != 0) {
         alu(alu_sub, sp, stackFix);
     }
-    gen_save_ret(jobj);
+    gen_save_ret(ci);
     // the returned can not be null, marking as such.
     vstack(0).set(VA_NZ);
     // allocation assumes GC invocation
@@ -160,7 +161,11 @@
 {
     bool lazy = m_lazy_resolution;
     bool resolve = !lazy || class_cp_is_entry_resolved(enclClass, cpIndex);
+    const CallSig* ci = NULL; 
     if (resolve) {
+        static const CallSig ci_new(CCONV_HELPERS, jobj, i32, jobj);
+        ci = &ci_new;
+
         Class_Handle klass = resolve_class_new(m_compileHandle, enclClass, cpIndex);
         if (klass == NULL) {
             gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0, enclClass, cpIndex, OPCODE_NEW);
@@ -170,15 +175,15 @@
             }
             unsigned size = class_get_boxed_data_size(klass);
             Allocation_Handle ah = class_get_allocation_handle(klass);
-            static CallSig ci_new(CCONV_HELPERS, i32, jobj);
             gen_call_vm(ci_new, rt_helper_new, 0, size, ah);
         }
     } else {
         assert(lazy);
-        static CallSig ci_new_with_resolve(CCONV_HELPERS, iplatf, i32);
+        static const CallSig ci_new_with_resolve(CCONV_HELPERS, jobj, iplatf, i32);
+        ci = &ci_new_with_resolve;
         gen_call_vm(ci_new_with_resolve, rt_helper_new_withresolve, 0, enclClass, cpIndex);
     }
-    gen_save_ret(jobj);
+    gen_save_ret(*ci);
     vstack(0).set(VA_NZ);// the returned can not be null, marking as such.
     m_bbstate->seen_gcpt = true;// allocation assumes GC invocation
 
@@ -195,19 +200,23 @@
             // resolution has failed
             gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0, enclClass, cpIdx, opcode);
         }
-        static const CallSig cs(CCONV_HELPERS, jobj, jobj);
+        static const CallSig cs_checkcast(CCONV_HELPERS, jobj, jobj, jobj);
+        static const CallSig cs_instanceof(CCONV_HELPERS, i32, jobj, jobj);
+        const CallSig& cs = (opcode == OPCODE_CHECKCAST) ? cs_checkcast : cs_instanceof;   
+        char * helper = (opcode == OPCODE_CHECKCAST) ? rt_helper_checkcast : rt_helper_instanceof;
         unsigned stackFix = gen_stack_to_args(true, cs, 0, 1);
-        char * helper = opcode == OPCODE_CHECKCAST ? rt_helper_checkcast : rt_helper_instanceof;
         gen_call_vm(cs, helper, 1, klass);
         if (stackFix != 0) {
             alu(alu_sub, sp, stackFix);
         }
         runlock(cs);
-        gen_save_ret(opcode == OPCODE_CHECKCAST ? jobj : i32);
+        gen_save_ret(cs);
     } else {
         assert(lazy);
-        static const CallSig cs_with_resolve(CCONV_HELPERS, iplatf, i32, jobj);
-        char * helper = opcode == OPCODE_CHECKCAST ? rt_helper_checkcast_withresolve : rt_helper_instanceof_withresolve;
+        static const CallSig cs_checkcast_with_resolve(CCONV_HELPERS, jobj, iplatf, i32, jobj);
+        static const CallSig cs_instanceof_with_resolve(CCONV_HELPERS, i32, iplatf, i32, jobj);
+        const CallSig& cs_with_resolve = (opcode == OPCODE_CHECKCAST) ? cs_checkcast_with_resolve : cs_instanceof_with_resolve;
+        char * helper = (opcode == OPCODE_CHECKCAST) ? rt_helper_checkcast_withresolve : rt_helper_instanceof_withresolve;
         Val tos = vstack(0);
         // setup constant parameters first,
         Val vclass(iplatf, enclClass);
@@ -216,7 +225,7 @@
         gen_call_vm(cs_with_resolve, helper, 3);
         runlock(cs_with_resolve);
         vpop();//pop obj
-        gen_save_ret(opcode == OPCODE_CHECKCAST ? jobj : i32);
+        gen_save_ret(cs_with_resolve);
     }
 }
 
@@ -224,7 +233,7 @@
 {
     const JInst& jinst = *m_curr_inst;
     gen_check_null(0);
-    static const CallSig cs_mon(CCONV_HELPERS, jobj);
+    static const CallSig cs_mon(CCONV_HELPERS, jvoid, jobj);
     unsigned stackFix = gen_stack_to_args(true, cs_mon, 0);
     gen_call_vm(cs_mon,
             jinst.opcode == OPCODE_MONITORENTER ? 
@@ -237,7 +246,7 @@
 
 void CodeGen::gen_athrow(void)
 {
-    static const CallSig cs_throw(CCONV_HELPERS, jobj);
+    static const CallSig cs_throw(CCONV_HELPERS, jvoid, jobj);
     unsigned stackFix = gen_stack_to_args(true, cs_throw, 0);
     gen_call_vm(cs_throw, rt_helper_throw, 1);
     runlock(cs_throw);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp Mon Mar 17 01:04:01 2008
@@ -693,14 +693,14 @@
         // if top of the stack is currently not on the gr_ret, then 
         // force it to be there
         Val& ev = m_jframe->dip(0);
-        if (!ev.is_reg() || ev.reg() != gr_ret) {
+        if (!ev.is_reg() || ev.reg() != gr0) {
             // locals were just spilled and no other stack items left
-            // therefore gr_ret must be unused, simply load the Exception
-            assert(rrefs(gr_ret) == 0);
-            Opnd reg(ev.jt(), gr_ret);
+            // therefore gr0 must be unused, simply load the Exception
+            assert(rrefs(gr0) == 0);
+            Opnd reg(ev.jt(), gr0);
             do_mov(reg, ev.as_opnd());
             rfree(ev);
-            ev.to_reg(gr_ret);
+            ev.to_reg(gr0);
             rref(ev);
         }
     }
@@ -717,8 +717,8 @@
         assert(m_jframe->size() == 1);
         Val& s = m_jframe->dip(0);
         if (!s.is_reg()) {
-            rref(gr_ret);
-            s = Val(jobj, gr_ret);
+            rref(gr0);
+            s = Val(jobj, gr0);
             // We're entering exception handler - that do not have 'direct'
             // (non exception) ways in it - the object on the top of the 
             // stack is exception and is guaranteed to be non-null.
@@ -727,7 +727,7 @@
             }
         }
         else {
-            assert(s.reg() == gr_ret);
+            assert(s.reg() == gr0);
         }
     }
     // We always process 0th BB as multiref BB - see also gen_prolog() 
@@ -767,7 +767,7 @@
     for (unsigned i=0; i<m_jframe->size(); i++) {
         Val& s = m_jframe->dip(i);
         if (i==0 && bbinfo.ehandler) {
-            assert(s.is_reg() && s.reg() == gr_ret); 
+            assert(s.is_reg() && s.reg() == gr0); 
         }
         else {
             s = Val(s.jt(), m_base, vstack_off(i));

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_stk.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_stk.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_stk.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_stk.cpp Mon Mar 17 01:04:01 2008
@@ -69,7 +69,7 @@
     }
     assert(m_curr_inst->opcode != OPCODE_LDC2_W);
     gen_call_vm(ci_helper_oi, rt_helper_ldc_string, 0, m_klass, m_curr_inst->op0);
-    gen_save_ret(jobj);
+    gen_save_ret(ci_helper_oi);
     vstack(0).set(VA_NZ);
     m_bbstate->seen_gcpt = true;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp Mon Mar 17 01:04:01 2008
@@ -1035,7 +1035,8 @@
         // That's why the exception object acts like a return value - for 
         // example on IA32 it's in EAX.
         //
-        gen_save_ret(jobj);
+        static const CallSig cs(CCONV_MANAGED, jobj);
+        gen_save_ret(cs);
     }
     
     if (is_set(DBG_TRACE_CG)) {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h Mon Mar 17 01:04:01 2008
@@ -294,7 +294,7 @@
     /**
      * @brief Generates method's epilogue (on RETURN instructions) code.
      */
-    void gen_return(jtype retType);
+    void gen_return(const CallSig& cs);
     
     /**
      * @brief Prepares BBState as it was left by gen_bb_leave().

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp Mon Mar 17 01:04:01 2008
@@ -29,15 +29,31 @@
 namespace Jitrino {
 namespace Jet {
 
-const CallSig helper_v(CCONV_HELPERS);
-const CallSig platform_v(CCONV_HELPERS);
+const CallSig helper_v(CCONV_HELPERS, jvoid);
+const CallSig platform_v(CCONV_HELPERS, iplatf);
 
-void CallSig::init(void)
+void CallSig::init()
 {
     unsigned num = (unsigned)m_args.size();
     m_data.resize(num);
     unsigned fps = 0, gps = 0;
 
+    // Assign return value
+    m_ret_reg[0] = -1;
+    m_ret_reg[1] = -1;
+    if (is_f(m_ret_jt)) {
+        if (m_cc & CCONV_RETURN_FP_THROUGH_FPU) {
+            m_ret_reg[0] = fp0;
+        } else {
+            m_ret_reg[0] = fr0;
+        }
+    } else if (m_ret_jt != jvoid) {
+        m_ret_reg[0] = gr0;
+        if (is_wide(m_ret_jt)) {
+            m_ret_reg[1] = gr3;
+        }
+    }
+    
     //
     // Assign registers
     //

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.h?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.h Mon Mar 17 01:04:01 2008
@@ -51,11 +51,6 @@
 #define CCONV_CALLER_POPS           (0x00000002)
 
 /**
- * @brief All args go though memory.
- */
-#define CCONV_MEM                   (0x00000020)
-
-/**
  * @brief When entering a function, obey the (sp)%%4 == 0 rule.
  */
 #define CCONV_STACK_ALIGN4          (0x00000004)
@@ -72,20 +67,29 @@
 #define CCONV_STACK_ALIGN16         (0x00000010)
 
 /**
- * Mask to extract stack alignment form calling convention.
+ * @brief Mask to extract stack alignment form calling convention.
  */
 #define CCONV_STACK_ALIGN_MASK      (CCONV_STACK_ALIGN4 | CCONV_STACK_ALIGN_HALF16 | CCONV_STACK_ALIGN16)
 
+/**
+ * @brief All args go though memory.
+ */
+#define CCONV_MEM                   (0x00000020)
+
+/**
+ * @brief Use FPU register stack to return floating point, xmm0 otherwise.
+ */
+#define CCONV_RETURN_FP_THROUGH_FPU (0x00000040)
 
 /**
  * @brief IA-32's stdcall convention.
  */
-#define CCONV_STDCALL_IA32     (CCONV_MEM)
+#define CCONV_STDCALL_IA32     (CCONV_MEM | CCONV_RETURN_FP_THROUGH_FPU)
 
 /**
  * @brief IA-32's cdecl convention.
  */
-#define CCONV_CDECL_IA32       (CCONV_CALLER_POPS | CCONV_MEM)
+#define CCONV_CDECL_IA32       (CCONV_CALLER_POPS | CCONV_MEM | CCONV_RETURN_FP_THROUGH_FPU)
 
 #ifdef _EM64T_
     /**
@@ -122,7 +126,7 @@
  * @brief A special case - VM's helper MULTIANEWARRAY always has cdecl-like
  *        convention.
  */
-#define CCONV_MULTIANEWARRAY   CCONV_CDECL_IA32
+#define CCONV_MULTIANEWARRAY    CCONV_CDECL_IA32
 
 #ifdef _EM64T_
     /**
@@ -133,7 +137,7 @@
     #define CCONV_MANAGED   CCONV_MANAGED_IA32
 #endif
 
-#define CCONV_HELPERS   CCONV_STDCALL
+#define CCONV_HELPERS       CCONV_STDCALL
 
 ///@}   // ~JET_CCONV
 
@@ -192,11 +196,12 @@
     /**
      * @brief Initializes CallSig object with the given arg types.
      */
-    CallSig(unsigned cc, 
+    CallSig(unsigned cc, jtype ret = jvoid, 
             jtype arg0=jvoid, jtype arg1=jvoid, jtype arg2=jvoid,
             jtype arg3=jvoid, jtype arg4=jvoid, jtype arg5=jvoid)
     {
         m_cc = cc;
+        m_ret_jt = ret;
         if (arg0 != jvoid)  { m_args.push_back(arg0); }
         if (arg1 != jvoid)  { m_args.push_back(arg1); }
         if (arg2 != jvoid)  { m_args.push_back(arg2); }
@@ -232,8 +237,9 @@
      * @brief Constructs and initializes CallSig object with the given 
      *        calling convention and list of args types.
      */
-    CallSig(unsigned cc, const vector<jtype>& args)
+    CallSig(unsigned cc, const jtype ret, const vector<jtype>& args)
     {
+        m_ret_jt = ret;
         init(cc, args);
     }
     
@@ -302,6 +308,22 @@
     }
     
     /**
+     * @params i slot number. For example on IA32 ret_reg(0) is eax, ret_reg(1) is edx.
+     * @returns register which holds return value, or ar_x
+     *          of the value comes through the memory.
+     */
+    AR ret_reg(unsigned i) const
+    { 
+        assert(i < 2);
+        return (m_ret_reg[i] <= 0) ? ar_x : (AR)m_ret_reg[i];
+    }
+    
+    /**
+     * @returns type of return value.
+     */
+    jtype ret_jt() const { return m_ret_jt; }
+    
+    /**
      * @returns Offset (in bytes) from #sp of the given argument, or -1 if 
      *          the argument is passed on register.
      */
@@ -366,7 +388,7 @@
      *
      * Counts args offsets and required stack size.
      */
-    void init(void);
+    void init();
     /**
      * @brief An info about argument types.
      */
@@ -399,6 +421,11 @@
      *        CallSig object.
      */
     unsigned                m_cc;
+    /**
+     * @brief              
+     */
+    int                     m_ret_reg[2];
+    jtype                   m_ret_jt;
 };
 
 /**

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.cpp Mon Mar 17 01:04:01 2008
@@ -191,11 +191,9 @@
     if (ar == sp) {
         return "sp";
     }
-#ifdef _IA32_
-    if (ar == fr_ret) {
-        return "fr_ret";
+    if (ar == fp0) {
+        return "fp0";
     }
-#endif
     if (platf) {
         return to_str_impl(ar);
     }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h Mon Mar 17 01:04:01 2008
@@ -286,9 +286,6 @@
  * The type index is unique only within the given group of registers and 
  * lies in the range of [gr_idx(gr0); gr_idx(gr0+gr_total-1)] for gr 
  * registers and [fr_idx(fr0); fr_idx(fr0+fr_total-1)], inclusive.
- *
- * @note On IA-32, fr_ret is treated in a special way - see
- * Encoder class description.
  * 
  */
 enum AR {
@@ -313,14 +310,7 @@
     //
     // Specials
     //
-#ifdef _EM64T_
-    fr_ret = fr0,
-#else
-    fr_ret,
-#endif
-    gr_ret = gr0,
-    //
-    //
+    fp0, // top FPU stacked register
     //
 #ifdef _EM64T_
     gr_num=15,      /// not including sp
@@ -340,7 +330,7 @@
  */
 inline bool is_f(AR ar)
 {
-    return (fr0 <= ar && ar < (fr0+gr_total));
+    return (fr0 <= ar && ar < (fr0+fr_total));
 }
 
 /**
@@ -420,12 +410,6 @@
  */
 inline unsigned ar_idx(AR ar)
 {
-#ifdef _IA32_
-    if (ar == fr_ret) {
-        // fake usage of fr0
-        ar = fr0;
-    }
-#endif
     assert(ar-gr0 < ar_total);
     return ar-gr0;
 }
@@ -824,12 +808,10 @@
  *  - (all) 'PUSH fr' is emulated as 
  *  'sub sp, num_of_slots_for(dbl64) ; mov [sp], fr'. 'POP fr' is emulated 
  *  the same way.
- *  - (IA-32)fr_ret is 'virtual' register and is treated in a special way -
- *  all IA-32 calling conventions use FPU stack to return float point 
- *  values, so only 'mov/ld fr_ret, mem' and 'mov/st mem, fr_ret' are 
+ *  - (IA-32) Only 'mov/ld fp0, mem' and 'mov/st mem, fp0' are 
  *  allowed. In this case, FST/FLD instructions are generated. \b NOTE: 
  *  this simulation is only done in #fld and #fst methods, you can \b not
- *  do #mov with fr_ret. This limitation is intentional, to remove 
+ *  do #mov with fp0. This limitation is intentional, to remove 
  *  additional check and branch from the hot exectuion path in #mov.
  * 
  * call() operation is made indirect only (trough a GR register). This is 
@@ -1076,7 +1058,7 @@
      * Loads from memory into the specified register.
      *
      * Just a wrapper around mov().
-     * @note On IA32 fr_ret loads are threated in a special way.
+     * @note On IA32 fp0 loads are threated in a special way.
      */
     void ld(jtype jt, AR ar, AR base, int disp=0, AR index = ar_x, 
             unsigned scale=0)
@@ -1106,7 +1088,7 @@
      * Loads from memory into the specified FR register.
      *
      * Just a wrapper around mov().
-     * @note On IA32 fr_ret loads are threated in a special way.
+     * @note On IA32 fp0 loads are threated in a special way.
      */
     void fld(jtype jt, AR ar, AR base, int disp=0, AR index = ar_x, 
              unsigned scale=0);
@@ -1114,7 +1096,7 @@
      * Stores from the specified FR register into memory .
      *
      * Just a wrapper around mov().
-     * @note On IA32 fr_ret stores are threated in a special way.
+     * @note On IA32 fp0 stores are threated in a special way.
      */
     void fst(jtype jt, AR ar, AR base, int disp=0, AR index = gr_x, 
              unsigned scale=0);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp Mon Mar 17 01:04:01 2008
@@ -78,7 +78,9 @@
             reg = getRegName(OpndKind_XMMReg, 
                             jt == jvoid ? OpndSize_64 : to_size(jt), idx);
         }
-        else {
+        else if (ar == fp0) {
+            reg = RegName_FP0;
+        } else {
             assert(idx<COUNTOF(reg_map));
             reg = reg_map[idx];
         
@@ -467,11 +469,6 @@
 
 string Encoder::to_str_impl(AR ar)
 {
-#ifdef _IA32_
-    if (ar == fr_ret) {
-        return "ST(0)";
-    }
-#endif
     RegName reg = devirt(ar);
     return getRegNameString(reg);
 }
@@ -606,9 +603,7 @@
 #endif    
     EncoderBase::Operands args;
 
-#ifdef _IA32_
-    assert(_op0.reg() != fr_ret && _op1.reg() != fr_ret);
-#endif
+    assert(_op0.reg() != fp0 && _op1.reg() != fp0);
     assert(is_f(_op0.jt()) == is_f(_op1.jt()));
     
 #ifdef _EM64T_
@@ -906,17 +901,13 @@
     EncoderBase::Operands args;
     Mnemonic mn = jt == dbl64 ? Mnemonic_MOVSD : Mnemonic_MOVSS;
     OpndSize sz = jt == dbl64 ? OpndSize_64 : OpndSize_32;
-#ifdef _EM64T_
-    args.add(devirt(op0, jt));
-#else
-    if (op0 == fr_ret) {
+    if (op0 == fp0) {
         mn = Mnemonic_FLD;
         args.add(jt == dbl64 ? RegName_FP0D : RegName_FP0S);
     }
     else {
         args.add(devirt(op0, jt));
     }
-#endif
     args.add(EncoderBase::Operand(sz, devirt(base), devirt(index), scale, disp));
     ip(EncoderBase::encode(ip(), mn, args));
 }
@@ -928,17 +919,13 @@
     OpndSize sz = jt == dbl64 ? OpndSize_64 : OpndSize_32;
     Mnemonic mn = jt == dbl64 ? Mnemonic_MOVSD : Mnemonic_MOVSS;
     args.add(EncoderBase::Operand(sz, devirt(base), devirt(index), scale, disp));
-#ifdef _EM64T_
-    args.add(devirt(op0, jt));
-#else
-    if (op0 == fr_ret) {
+    if (op0 == fp0) {
         mn = Mnemonic_FSTP;
         args.add(jt == dbl64 ? RegName_FP0D : RegName_FP0S);
     }
     else {
         args.add(devirt(op0, jt));
     }
-#endif
     ip(EncoderBase::encode(ip(), mn, args));
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/rt_helper_info.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/rt_helper_info.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/rt_helper_info.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/rt_helper_info.cpp Mon Mar 17 01:04:01 2008
@@ -50,7 +50,7 @@
             INTERRUPTIBLE_ALWAYS,              CALLING_CONVENTION_STDCALL,              2,
             NULL,   NULL,   "(Lorg/vmmagic/unboxed/Address;I)Lorg/vmmagic/unboxed/Address;",   NULL},
     {VM_RT_MULTIANEWARRAY_RESOLVED,            "VM_RT_MULTIANEWARRAY_RESOLVED",
-            INTERRUPTIBLE_ALWAYS,              CALLING_CONVENTION_CDECL,                8,
+            INTERRUPTIBLE_ALWAYS,              CALLING_CONVENTION_MULTIARRAY,           8,
             NULL,   NULL,   NULL,   NULL},
     {VM_RT_LDC_STRING,                         "VM_RT_LDC_STRING",
             INTERRUPTIBLE_ALWAYS,              CALLING_CONVENTION_STDCALL,              2,

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/lil/ia32/lil_code_generator_ia32.cpp Mon Mar 17 01:04:01 2008
@@ -1400,9 +1400,20 @@
     {
         adjust_stack_for_return();
         unsigned sz = sig_size_on_stack(ctxt.entry_sig);
+        LilCc cc = lil_sig_get_cc(ctxt.entry_sig);
+        LilType type = lil_sig_get_ret_type(ctxt.entry_sig);
+        
+        if (cc == LCC_Managed && (type == LT_F4 || type == LT_F8)) {
+            // Managed calling convention uses XMM to return floating point values on IA32.
+            // So we need to copy return value from FPU stack to XMM.
+            int disp = (type == LT_F8) ? -8 : -4;
+            M_Opnd memloc(esp_reg, disp);
+            *buf = fst(*buf, memloc, (type == LT_F8), true);
+            *buf = sse_mov(*buf, xmm0_reg, memloc, (type == LT_F8));
+        }
         
         if (ctxt.entry_cc.callee_pop) {
-            if (lil_sig_get_cc(ctxt.entry_sig) == LCC_Managed) {
+            if (cc == LCC_Managed) {
                 // Managed calling convention assumes callee responsibility to 
                 // handle alignment properly. Assuming that arguments were aligned, 
                 // size of input arguments plus return pointer on the stack also should be aligned

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/ini_iA32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/ini_iA32.cpp?rev=637775&r1=637774&r2=637775&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/ini_iA32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/ini_iA32.cpp Mon Mar 17 01:04:01 2008
@@ -51,19 +51,13 @@
 
 #include "dump.h"
 
-typedef double (*DoubleFuncPtr)(uint32* args, int args_size, void* func);
 typedef ManagedObject* (*RefFuncPtr)(uint32* args, int args_size, void* func);
-typedef float (*FloatFuncPtr)(uint32* args, int args_size, void* func);
 typedef int32 (*IntFuncPtr)(uint32* args, int args_size, void* func);
 typedef int64 (*LongFuncPtr)(uint32* args, int args_size, void* func);
+typedef float (*FloatFuncPtr)(uint32* args, int args_size, void* func);
+typedef double (*DoubleFuncPtr)(uint32* args, int args_size, void* func);
 
-static IntFuncPtr gen_invoke_managed_func() {
-    static IntFuncPtr func = NULL;
-    
-    if (func) {
-        return func;
-    }
-
+static char* gen_invoke_common_managed_func(char* stub) {
     // Defines stack alignment on managed function enter.
     const int32 STACK_ALIGNMENT = MANAGED_STACK_ALIGNMENT;
     const int32 STACK_ALIGNMENT_MASK = ~(STACK_ALIGNMENT - 1);
@@ -78,18 +72,9 @@
     const int32 STACK_FUNC_OFFSET = 16;
     const int32 STACK_CALLEE_SAVED_OFFSET = -12;
     
-    const int STUB_SIZE = 124;
-    char * stub = (char *) malloc_fixed_code_for_jit(STUB_SIZE,
-        DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_DEFAULT, CAA_Allocate);
-#ifdef _DEBUG
-    memset(stub, 0xcc /*int 3*/, STUB_SIZE);
-#endif
-    
     tl::MemoryPool pool;
     LilCguLabelAddresses labels(&pool, stub);
     
-    func = (IntFuncPtr) stub;
-
     // Initialize ebp-based stack frame.
     stub = push(stub, ebp_opnd);
     stub = mov(stub, ebp_opnd, esp_opnd);
@@ -143,13 +128,86 @@
     
     // Leave current frame.
     stub = pop(stub, ebp_opnd);
+
+    return stub;
+}
+
+static IntFuncPtr gen_invoke_int_managed_func() {
+    static IntFuncPtr func = NULL;
+    
+    if (func) {
+        return func;
+    }
+
+    const int STUB_SIZE = 124;
+    
+    char * stub = (char *) malloc_fixed_code_for_jit(STUB_SIZE,
+        DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_DEFAULT, CAA_Allocate);
+
+    func = (IntFuncPtr) stub;
+    stub = gen_invoke_common_managed_func(stub);
+        
     stub = ret(stub);
     
     assert(stub - (char *)func <= STUB_SIZE);
 
-    DUMP_STUB(func, "invoke_managed_func", stub - (char *)func);
+    DUMP_STUB(func, "invoke_int_managed_func", stub - (char *)func);
+    return func;
+}
 
+static FloatFuncPtr gen_invoke_float_managed_func() {
+    static FloatFuncPtr func = NULL;
+    
+    if (func) {
+        return func;
+    }
+
+    const int STUB_SIZE = 132;
+    
+    char * stub = (char *) malloc_fixed_code_for_jit(STUB_SIZE,
+        DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_DEFAULT, CAA_Allocate);
+
+    func = (FloatFuncPtr) stub;
+    stub = gen_invoke_common_managed_func(stub);
+
+    // Put return value on FPU stack.
+    M_Opnd memloc(esp_reg, -4);
+    stub = sse_mov(stub, memloc, xmm0_opnd, false);
+    stub = fld(stub, memloc, false);
+    stub = ret(stub);
+    
+    assert(stub - (char *)func <= STUB_SIZE);
+
+    DUMP_STUB(func, "invoke_float_managed_func", stub - (char *)func);
+    return func;    
+}
+
+static DoubleFuncPtr gen_invoke_double_managed_func() {
+    static DoubleFuncPtr func = NULL;
+    
+    if (func) {
+        return func;
+    }
+
+    const int STUB_SIZE = 132;
+    
+    char * stub = (char *) malloc_fixed_code_for_jit(STUB_SIZE,
+        DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_DEFAULT, CAA_Allocate);
+
+    func = (DoubleFuncPtr) stub;
+    stub = gen_invoke_common_managed_func(stub);
+
+    // Put return value on FPU stack.
+    M_Opnd memloc(esp_reg, -8);
+    stub = sse_mov(stub, memloc, xmm0_opnd, true);
+    stub = fld(stub, memloc, true);
+    stub = ret(stub);
+    
+    assert(stub - (char *)func <= STUB_SIZE);
+
+    DUMP_STUB(func, "invoke_double_managed_func", stub - (char *)func);
     return func;
+    
 }
 
 void
@@ -163,8 +221,6 @@
 
 //    fprintf(stderr, "Not implemented\n");
 
-    static const IntFuncPtr invoke_managed_func = gen_invoke_managed_func();
-
     Method *method = (Method*) methodID;
     TRACE("enter method "
             << method->get_class()->get_name()->bytes << " "
@@ -242,11 +298,14 @@
     arg_words += argId;
     argId = sz - argId;
 
+    static const IntFuncPtr invoke_managed_func = gen_invoke_int_managed_func();
+    static const FloatFuncPtr invoke_float_managed_func = gen_invoke_float_managed_func();
+    static const DoubleFuncPtr invoke_double_managed_func = gen_invoke_double_managed_func();
+
     switch(ret_type) {
         case JAVA_TYPE_VOID:
             invoke_managed_func(arg_words, argId, meth_addr);
             break;
-
         case JAVA_TYPE_CLASS:
         case JAVA_TYPE_ARRAY:
         case JAVA_TYPE_STRING:
@@ -268,11 +327,11 @@
         case JAVA_TYPE_CHAR:
         case JAVA_TYPE_SHORT:
         case JAVA_TYPE_INT:
-            resultPtr->i = ((IntFuncPtr)invoke_managed_func)(arg_words, argId, meth_addr);
+            resultPtr->i = invoke_managed_func(arg_words, argId, meth_addr);
             break;
 
         case JAVA_TYPE_FLOAT:
-            resultPtr->f = ((FloatFuncPtr)invoke_managed_func)(arg_words, argId, meth_addr);
+            resultPtr->f = invoke_float_managed_func(arg_words, argId, meth_addr);
             break;
 
         case JAVA_TYPE_LONG:
@@ -280,7 +339,7 @@
             break;
 
         case JAVA_TYPE_DOUBLE:
-            resultPtr->d = ((DoubleFuncPtr)invoke_managed_func)(arg_words, argId, meth_addr);
+            resultPtr->d = invoke_double_managed_func(arg_words, argId, meth_addr);
             break;
 
         default: