dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and to


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. db78cf32b742817d8cf15b3376dcb24b65d5d027
Date: Sun, 18 Apr 2010 16:39:22 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET engine, compilers and tools (pnet)".

The branch, master has been updated
       via  db78cf32b742817d8cf15b3376dcb24b65d5d027 (commit)
      from  0f11b3a6d01de97f24df6730ac41336716358857 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/pnet.git/commit/?id=db78cf32b742817d8cf15b3376dcb24b65d5d027

commit db78cf32b742817d8cf15b3376dcb24b65d5d027
Author: Klaus Treichel <address@hidden>
Date:   Sun Apr 18 18:38:54 2010 +0200

    Optimize calculating the address of an array element.

diff --git a/ChangeLog b/ChangeLog
index 43b398f..c109995 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2010-04-18  Klaus Treichel  <address@hidden>
+
+       * engine/cvm.h: Replace the opcode COP_CKARRAY_LOAD_I4 by the two
+       opcodes COP_ELEM_ADDR_SHIFT_I4 and COP_ELEM_ADDR_MUL_I4.
+
+       * engine/cvm_dasm.c: Sync opcode tables with cvm.h.
+
+       * engine/cvm_lengths.h: Likewise
+
+       * engine/cvm_ptr.c (COP_ELEM_ADDR_SHIFT_I4, COP_ELEM_ADDR_MUL_I4): 
+       Implement the two new opcodes.
+       (COP_CKARRAY_LOAD_I4): Remove implementation of this opcode.
+
+       * engine/cvmc_ptr.c (GetArrayElementAddress): Ad new support function
+       for the cli LDELEMA opcode.
+       (CVMCoder_ArrayAccess): Use the new function for the IL_OP_LDELEMA
+       opcode.
+
+       * engine/md_amd64.h (md_lea_memindex_shift): Add macro for unrolling the
+       COP_ELEM_ADDR_SHIFT_I4 opcode.
+
+       * engine/md_x86.h (md_lea_memindex_shift): Likewise.
+
+       * engine/unroll_ptr.c (COP_ELEM_ADDR_SHIFT_I4, COP_ELEM_ADDR_MUL_I4):
+       Add support for unrolling these opcodes.
+
 2010-04-11  Klaus Treichel  <address@hidden>
 
        * configure.in: Add check for the endianness of the target.
diff --git a/engine/cvm.h b/engine/cvm.h
index dda6b75..eddc2b2 100644
--- a/engine/cvm.h
+++ b/engine/cvm.h
@@ -266,50 +266,48 @@ extern    "C" {
 #define        COP_SWRITE_ELEM                         0xBB
 #define        COP_IWRITE_ELEM                         0xBC
 #define        COP_PWRITE_ELEM                         0xBD
-#define        COP_CKARRAY_LOAD_I4                     0xBE
-#define        COP_CKARRAY_LOAD_I8                     0xBF
-#define        COP_CKARRAY_STORE_I8            0xC0
-#define        COP_ARRAY_LEN                           0xC1
+#define        COP_ELEM_ADDR_SHIFT_I4          0xBE
+#define        COP_ELEM_ADDR_MUL_I4            0xBF
+#define        COP_CKARRAY_LOAD_I8                     0xC0
+#define        COP_CKARRAY_STORE_I8            0xC1
+#define        COP_ARRAY_LEN                           0xC2
 
 /*
  * Field opcodes.
  */
-#define        COP_BREAD_FIELD                         0xC2
-#define        COP_UBREAD_FIELD                        0xC3
-#define        COP_SREAD_FIELD                         0xC4
-#define        COP_USREAD_FIELD                        0xC5
-#define        COP_IREAD_FIELD                         0xC6
-#define        COP_PREAD_FIELD                         0xC7
-#define        COP_BWRITE_FIELD                        0xC8
-#define        COP_SWRITE_FIELD                        0xC9
-#define        COP_IWRITE_FIELD                        0xCA
-#define        COP_PWRITE_FIELD                        0xCB
-#define        COP_PREAD_THIS                          0xCC
-#define        COP_IREAD_THIS                          0xCD
+#define        COP_BREAD_FIELD                         0xC3
+#define        COP_UBREAD_FIELD                        0xC4
+#define        COP_SREAD_FIELD                         0xC5
+#define        COP_USREAD_FIELD                        0xC6
+#define        COP_IREAD_FIELD                         0xC7
+#define        COP_PREAD_FIELD                         0xC8
+#define        COP_BWRITE_FIELD                        0xC9
+#define        COP_SWRITE_FIELD                        0xCA
+#define        COP_IWRITE_FIELD                        0xCB
+#define        COP_PWRITE_FIELD                        0xCC
+#define        COP_PREAD_THIS                          0xCD
+#define        COP_IREAD_THIS                          0xCE
 
 /*
  * Call management opcodes.
  */
-#define        COP_CALL                                        0xCE
-#define        COP_CALL_CTOR                           0xCF
-#define        COP_CALL_NATIVE                         0xD0
-#define        COP_CALL_NATIVE_VOID            0xD1
-#define        COP_CALL_NATIVE_RAW                     0xD2
-#define        COP_CALL_NATIVE_VOID_RAW        0xD3
-#define        COP_CALL_VIRTUAL                        0xD4
-#define        COP_CALL_INTERFACE                      0xD5
-#define        COP_RETURN                                      0xD6
-#define        COP_RETURN_1                            0xD7
-#define        COP_RETURN_2                            0xD8
-#define        COP_RETURN_N                            0xD9
-#define        COP_JSR                                         0xDA
-#define        COP_RET_JSR                                     0xDB
-#define        COP_PUSH_THREAD                         0xDC
-#define        COP_PUSH_THREAD_RAW                     0xDD
-#define        COP_PUSHDOWN                            0xDE
-/*
- * #define     COP_CCTOR_ONCE                          0xDF     NOT USED 
ANYMORE
- */
+#define        COP_CALL                                        0xCF
+#define        COP_CALL_CTOR                           0xD0
+#define        COP_CALL_NATIVE                         0xD1
+#define        COP_CALL_NATIVE_VOID            0xD2
+#define        COP_CALL_NATIVE_RAW                     0xD3
+#define        COP_CALL_NATIVE_VOID_RAW        0xD4
+#define        COP_CALL_VIRTUAL                        0xD5
+#define        COP_CALL_INTERFACE                      0xD6
+#define        COP_RETURN                                      0xD7
+#define        COP_RETURN_1                            0xD8
+#define        COP_RETURN_2                            0xD9
+#define        COP_RETURN_N                            0xDA
+#define        COP_JSR                                         0xDB
+#define        COP_RET_JSR                                     0xDC
+#define        COP_PUSH_THREAD                         0xDD
+#define        COP_PUSH_THREAD_RAW                     0xDE
+#define        COP_PUSHDOWN                            0xDF
 #define        COP_CALLI                                       0xE0
 #define        COP_JMPI                                        0xE1
 
diff --git a/engine/cvm_dasm.c b/engine/cvm_dasm.c
index f8e386f..e6eabec 100644
--- a/engine/cvm_dasm.c
+++ b/engine/cvm_dasm.c
@@ -316,7 +316,8 @@ static CVMOpcode const opcodes[256] = {
        {"swrite_elem",         CVM_OPER_NONE},
        {"iwrite_elem",         CVM_OPER_NONE},
        {"pwrite_elem",         CVM_OPER_NONE},
-       {"ckarray_load_i4",     CVM_OPER_NONE},
+       {"elem_addr_shift_i4", CVM_OPER_UINT8},
+       {"elem_addr_mul_i4", CVM_OPER_UINT32},
        {"ckarray_load_i8",     CVM_OPER_NONE},
        {"ckarray_store_i8", CVM_OPER_TWO_UINT8},
        {"array_len",           CVM_OPER_NONE},
@@ -357,7 +358,6 @@ static CVMOpcode const opcodes[256] = {
        {"push_thread",         CVM_OPER_NONE},
        {"push_thread_raw",     CVM_OPER_NONE},
        {"pushdown",            CVM_OPER_UINT32},
-       {"cctor_once",          CVM_OPER_NONE},
        {"calli",                       CVM_OPER_NONE},
        {"jmpi",                        CVM_OPER_NONE},
 
@@ -423,7 +423,7 @@ static CVMOpcode const opcodes[256] = {
         */
        {"prefix",                      CVM_OPER_PREFIX},
 };
-static CVMOpcode const prefixOpcodes[0x90] = {
+static CVMOpcode const prefixOpcodes[0xA0] = {
        /*
         * Reserved opcodes.
         */
@@ -644,13 +644,45 @@ static CVMOpcode const prefixOpcodes[0x90] = {
        {"tanh",                        CVM_OPER_NONE},
 
        /*
+        * Unroller support opcodes.
+        */
+       {"unroll_stack",        CVM_OPER_NONE},
+       {"unroll_stack_return", CVM_OPER_NONE},
+
+       /*
+        * Generics support opcodes.
+        */
+       {"repl_word_n",         CVM_OPER_UINT32},
+       {"call_virtgen",        CVM_OPER_TWO_UINT32},
+
+       /*
+        * Inlined array functions.
+        */
+       {"sarray_copy_aai4", CVM_OPER_UINT32},
+       {"sarray_copy_ai4ai4i4", CVM_OPER_UINT32},
+       {"sarray_clear_ai4i4", CVM_OPER_UINT32},
+
+       /*
+        * Enghanced method profiling opcodes.
+        */
+       {"profile_start",       CVM_OPER_NONE},
+       {"profile_end",         CVM_OPER_NONE},
+
+       /*
         * Reserved opcodes.
         */
-       {"preserved_8B",        CVM_OPER_NONE},
-       {"preserved_8C",        CVM_OPER_NONE},
-       {"preserved_8D",        CVM_OPER_NONE},
-       {"preserved_8E",        CVM_OPER_NONE},
-       {"preserved_8F",        CVM_OPER_NONE},
+       {"preserved_94",        CVM_OPER_NONE},
+       {"preserved_95",        CVM_OPER_NONE},
+       {"preserved_96",        CVM_OPER_NONE},
+       {"preserved_97",        CVM_OPER_NONE},
+       {"preserved_98",        CVM_OPER_NONE},
+       {"preserved_99",        CVM_OPER_NONE},
+       {"preserved_9A",        CVM_OPER_NONE},
+       {"preserved_9B",        CVM_OPER_NONE},
+       {"preserved_9C",        CVM_OPER_NONE},
+       {"preserved_9D",        CVM_OPER_NONE},
+       {"preserved_9E",        CVM_OPER_NONE},
+       {"preserved_9F",        CVM_OPER_NONE}
 };
 
 /*
diff --git a/engine/cvm_lengths.c b/engine/cvm_lengths.c
index 76622fa..d1d5c58 100644
--- a/engine/cvm_lengths.c
+++ b/engine/cvm_lengths.c
@@ -269,7 +269,8 @@ unsigned char const _ILCVMLengths[512] = {
        /* swrite_elem */               CVM_LEN_NONE,
        /* iwrite_elem */               CVM_LEN_NONE,
        /* pwrite_elem */               CVM_LEN_NONE,
-       /* ckarray_load_i4 */   CVM_LEN_NONE,
+       /* elem_addr_shift_i4 */ CVM_LEN_BYTE,
+       /* elem_addr_mul_i4 */  CVM_LEN_WORD,
        /* ckarray_load_i8 */   CVM_LEN_NONE,
        /* ckarray_store_i8 */  CVM_LEN_BYTE2,
        /* array_len */                 CVM_LEN_NONE,
@@ -310,7 +311,6 @@ unsigned char const _ILCVMLengths[512] = {
        /* push_thread */               CVM_LEN_NONE,
        /* push_thread_raw */   CVM_LEN_NONE,
        /* pushdown */                  CVM_LEN_WORD,
-       /* cctor_once */                CVM_LEN_NONE,
        /* calli */                             CVM_LEN_NONE,
        /* jmpi */                              CVM_LEN_NONE,
 
@@ -589,16 +589,36 @@ unsigned char const _ILCVMLengths[512] = {
        /* sqrt */                              CVMP_LEN_NONE,
        /* tan */                               CVMP_LEN_NONE,
        /* tanh */                              CVMP_LEN_NONE,
-       /* preserved_8b */              CVMP_LEN_NONE,
-       /* preserved_8c */              CVMP_LEN_NONE,
-       /* preserved_8d */              CVMP_LEN_NONE,
-       /* preserved_8e */              CVMP_LEN_NONE,
-       /* preserved_8f */              CVMP_LEN_NONE,
-
-       /* preserved_90 */              CVMP_LEN_NONE,
-       /* preserved_91 */              CVMP_LEN_NONE,
-       /* preserved_92 */              CVMP_LEN_NONE,
-       /* preserved_93 */              CVMP_LEN_NONE,
+
+       /*
+        * Unroller support opcodes.
+        */
+
+       /* unroll_stack */              CVMP_LEN_NONE,
+       /* unroll_stack_return */ CVMP_LEN_NONE,
+
+       /*
+        * Generics support opcodes.
+        */
+
+       /* repl_word_n */               CVMP_LEN_WORD,
+       /* call_virtgen */              CVMP_LEN_WORD2,
+
+       /*
+        * Inlined array functions.
+        */
+
+       /* sarray_copy_aai4 */  CVMP_LEN_WORD,
+       /* sarray_copy_ai4ai4i4 */ CVMP_LEN_WORD,
+       /* sarray_clear_ai4i4 */ CVMP_LEN_WORD,
+
+       /*
+        * Enghanced method profiling opcodes.
+        */
+
+       /* profile_start */             CVMP_LEN_NONE,
+       /* profile_end */               CVMP_LEN_NONE,
+
        /* preserved_94 */              CVMP_LEN_NONE,
        /* preserved_95 */              CVMP_LEN_NONE,
        /* preserved_96 */              CVMP_LEN_NONE,
diff --git a/engine/cvm_ptr.c b/engine/cvm_ptr.c
index e847f7c..db8bd1d 100644
--- a/engine/cvm_ptr.c
+++ b/engine/cvm_ptr.c
@@ -1600,32 +1600,28 @@ VMCASE(COP_PWRITE_ELEM):
 VMBREAK(COP_PWRITE_ELEM);
 
 /**
- * <opcode name="ckarray_load_i4" group="Array handling">
- *   <operation>Check an array load with an <code>int32</code>
- *                             index</operation>
+ * <opcode name="elem_addr_shift_i4" group="Array handling">
+ *   <operation>Load the address of an array element with an
+ *                             <code>int32</code> index where the size of an 
array
+ *                             element is a power of two</operation>
  *
- *   <format>ckarray_load_i4</format>
- *   <dformat>{ckarray_load_i4}</dformat>
+ *   <format>elem_addr_shift_i4<fsep/>N[1]</format>
+ *   <dformat>{elem_addr_shift_i4}<fsep/>N</dformat>
  *
- *   <form name="ckarray_load_i4" code="COP_CKARRAY_LOAD_I4"/>
+ *   <form name="elem_addr_shift_i4" code="COP_ELEM_ADDR_SHIFT_I4"/>
  *
  *   <before>..., array, index</before>
- *   <after>..., pointer, index</after>
+ *   <after>..., pointer</after>
  *
- *   <description>Retrieve <i>array</i> and <i>index</i>
- *   from the stack (without popping them) as the types <code>ptr</code>
- *   and <code>int32</code> respectively.  Throw a
- *   <code>System.IndexOutOfRangeException</code> if <i>index</i> is
- *   out of range.  Otherwise set <i>pointer</i> to the address of
- *   the first element in the array.</description>
+ *   <description>Pop <i>array</i> and <i>index</i> from the stack as the
+ *   types <code>ptr</code> and <code>int32</code> respectively.
+ *   Throw a <code>System.IndexOutOfRangeException</code> if <i>index</i>
+ *   is out of range.  Otherwise push <i>pointer</i> the address of the
+ *   <i>index</i>'th element in the array on the stack. The size of each
+ *   array element is 1 << <i>N</i> bytes.</description>
  *
  *   <notes>This instruction is used to assist in obtaining the address
- *   of an array element.  The program will normally follow this
- *   instruction with an <i>imul</i> operation to adjust the index
- *   for the size of the elements, followed by <i>padd_i4</i> to compute
- *   the final element address.  This instruction sequence can also be
- *   used in combination with <i>mread</i> to fetch odd-sized array
- *   elements by pointer.</notes>
+ *   of an array element where the element size is a power of two.</notes>
  *
  *   <exceptions>
  *     <exception name="System.NullReferenceException">Raised if
@@ -1635,7 +1631,7 @@ VMBREAK(COP_PWRITE_ELEM);
  *   </exceptions>
  * </opcode>
  */
-VMCASE(COP_CKARRAY_LOAD_I4):
+VMCASE(COP_ELEM_ADDR_SHIFT_I4):
 {
        /* Check an array load that uses an I4 index */
        BEGIN_NULL_CHECK_STMT((tempptr = stacktop[-2].ptrValue))
@@ -1643,10 +1639,66 @@ VMCASE(COP_CKARRAY_LOAD_I4):
                if(stacktop[-1].uintValue <
                                ((ILUInt32)(ArrayLength(tempptr))))
                {
-                       /* Adjust the pointer to address the first array 
element */
+                       /* Replace the array by the address to the requested 
array alamant */
                        stacktop[-2].ptrValue = (void *)(((unsigned char 
*)tempptr) +
-                                                                               
         sizeof(System_Array));
-                       MODIFY_PC_AND_STACK(CVM_LEN_NONE, 0);
+                                                                               
         sizeof(System_Array)) +
+                                                                               
         (stacktop[-1].uintValue << CVM_ARG_BYTE);
+                       MODIFY_PC_AND_STACK(CVM_LEN_BYTE, -1);
+               }
+               else
+               {
+                       ARRAY_INDEX_EXCEPTION();
+               }
+       }
+       END_NULL_CHECK();
+}
+VMBREAK(COP_ELEM_ADDR_SHIFT_I4);
+
+/**
+ * <opcode name="elem_addr_mul_i4" group="Array handling">
+ *   <operation>Load the address of an array element with an
+ *                             <code>int32</code> index with arbitrary element 
sizes.
+ *                             </operation>
+ *
+ *   <format>elem_addr_mul_i4</format>
+ *   <dformat>{elem_addr_mul_i4}</dformat>
+ *
+ *   <form name="elem_addr_mul_i4" code="COP_ELEM_ADDR_MUL_I4"/>
+ *
+ *   <before>..., array, index</before>
+ *   <after>..., pointer</after>
+ *
+ *   <description>Pop <i>array</i> and <i>index</i> from the stack as the
+ *   types <code>ptr</code> and <code>int32</code> respectively.
+ *   Throw a <code>System.IndexOutOfRangeException</code> if <i>index</i>
+ *   is out of range.  Otherwise push <i>pointer</i> the address of the
+ *   element at <i>index</i> in the array on the stack.</description>
+ *
+ *   <notes>This instruction is used to assist in obtaining the address
+ *   of an array element where the element size is an arbitrary 32 bit
+ *   value.</notes>
+ *
+ *   <exceptions>
+ *     <exception name="System.NullReferenceException">Raised if
+ *     <i>array</i> is <code>null</code>.</exception>
+ *     <exception name="System.IndexOutOfRangeException">Raised if
+ *     <i>index</i> is not within the array's bounds.</exception>
+ *   </exceptions>
+ * </opcode>
+ */
+VMCASE(COP_ELEM_ADDR_MUL_I4):
+{
+       /* Check an array load that uses an I4 index */
+       BEGIN_NULL_CHECK_STMT((tempptr = stacktop[-2].ptrValue))
+       {
+               if(stacktop[-1].uintValue <
+                               ((ILUInt32)(ArrayLength(tempptr))))
+               {
+                       /* Replace the array by the address to the requested 
array alamant */
+                       stacktop[-2].ptrValue = (void *)(((unsigned char 
*)tempptr) +
+                                                                               
         sizeof(System_Array)) +
+                                                                               
         (stacktop[-1].uintValue * CVM_ARG_WORD);
+                       MODIFY_PC_AND_STACK(CVM_LEN_WORD, -1);
                }
                else
                {
@@ -1655,7 +1707,7 @@ VMCASE(COP_CKARRAY_LOAD_I4):
        }
        END_NULL_CHECK();
 }
-VMBREAK(COP_CKARRAY_LOAD_I4);
+VMBREAK(COP_ELEM_ADDR_MUL_I4);
 
 /**
  * <opcode name="ckarray_load_i8" group="Array handling">
diff --git a/engine/cvmc_ptr.c b/engine/cvmc_ptr.c
index e8c6d43..ad3287d 100644
--- a/engine/cvmc_ptr.c
+++ b/engine/cvmc_ptr.c
@@ -21,6 +21,84 @@
 #ifdef IL_CVMC_CODE
 
 /*
+ * Load the address of an array element.
+ */
+static void GetArrayElementAddress(ILCoder *coder, ILEngineType indexType,
+                                                                  int size)
+{
+#ifdef IL_NATIVE_INT64
+       if(indexType == ILEngineType_I4)
+#endif
+       {
+               /* Check if size is a power of two */
+               if((size > 0) && ((size & (size -1)) == 0))
+               {
+                       int shift = 0;
+
+                       while((size & (1 << shift)) == 0)
+                       {
+                               ++shift;
+                       }
+                       CVM_OUT_BYTE(COP_ELEM_ADDR_SHIFT_I4, shift);
+                       CVM_ADJUST(-1);
+               }
+               else
+               {
+                       CVM_OUT_WORD(COP_ELEM_ADDR_MUL_I4, size);
+                       CVM_ADJUST(-1);
+               }
+       }
+#ifdef IL_NATIVE_INT64
+       else
+       {
+               CVM_OUT_NONE(COP_CKARRAY_LOAD_I8);
+               if(size == 2)
+               {
+                       CVM_OUT_NONE(COP_LDC_I4_1);
+                       CVM_ADJUST(1);
+                       CVM_OUT_NONE(COP_LSHL);
+                       CVM_ADJUST(-1);
+               }
+               else if(size == 4)
+               {
+                       CVM_OUT_NONE(COP_LDC_I4_2);
+                       CVM_ADJUST(1);
+                       CVM_OUT_NONE(COP_LSHL);
+                       CVM_ADJUST(-1);
+               }
+               else if(size == 8)
+               {
+                       CVM_OUT_NONE(COP_LDC_I4_3);
+                       CVM_ADJUST(1);
+                       CVM_OUT_NONE(COP_LSHL);
+                       CVM_ADJUST(-1);
+               }
+               else if(size != 1)
+               {
+                       if(size < 8)
+                       {
+                               CVM_OUT_NONE(COP_LDC_I4_0 + size);
+                       }
+                       else if(size < 128)
+                       {
+                               CVM_OUT_BYTE(COP_LDC_I4_S, size);
+                       }
+                       else
+                       {
+                               CVM_OUT_WORD(COP_LDC_I4, size);
+                       }
+                       CVM_OUT_NONE(COP_IU2L);
+                       CVM_ADJUST(CVM_WORDS_PER_LONG);
+                       CVM_OUT_NONE(COP_LMUL);
+                       CVM_ADJUST(-CVM_WORDS_PER_LONG);
+               }
+               CVM_OUT_NONE(COP_PADD_I8);
+               CVM_ADJUST(-CVM_WORDS_PER_LONG);
+       }
+#endif
+}
+
+/*
  * Load elements from an array.
  */
 static void LoadArrayElem(ILCoder *coder, int opcode1, int opcode2,
@@ -118,101 +196,7 @@ static void CVMCoder_ArrayAccess(ILCoder *coder, int 
opcode,
                        /* Load the address of an array element */
                        size = 
_ILSizeOfTypeLocked(_ILCoderToILCVMCoder(coder)->process,
                                                                           
elemType);
-               #ifdef IL_NATIVE_INT64
-                       if(indexType == ILEngineType_I4)
-               #endif
-                       {
-                               CVM_OUT_NONE(COP_CKARRAY_LOAD_I4);
-                               if(size == 2)
-                               {
-                                       CVM_OUT_NONE(COP_LDC_I4_1);
-                                       CVM_ADJUST(1);
-                                       CVM_OUT_NONE(COP_ISHL);
-                                       CVM_ADJUST(-1);
-                               }
-                               else if(size == 4)
-                               {
-                                       CVM_OUT_NONE(COP_LDC_I4_2);
-                                       CVM_ADJUST(1);
-                                       CVM_OUT_NONE(COP_ISHL);
-                                       CVM_ADJUST(-1);
-                               }
-                               else if(size == 8)
-                               {
-                                       CVM_OUT_NONE(COP_LDC_I4_3);
-                                       CVM_ADJUST(1);
-                                       CVM_OUT_NONE(COP_ISHL);
-                                       CVM_ADJUST(-1);
-                               }
-                               else if(size != 1)
-                               {
-                                       if(size < 8)
-                                       {
-                                               CVM_OUT_NONE(COP_LDC_I4_0 + 
size);
-                                       }
-                                       else if(size < 128)
-                                       {
-                                               CVM_OUT_BYTE(COP_LDC_I4_S, 
size);
-                                       }
-                                       else
-                                       {
-                                               CVM_OUT_WORD(COP_LDC_I4, size);
-                                       }
-                                       CVM_ADJUST(1);
-                                       CVM_OUT_NONE(COP_IMUL);
-                                       CVM_ADJUST(-1);
-                               }
-                               CVM_OUT_NONE(COP_PADD_I4);
-                               CVM_ADJUST(-1);
-                       }
-               #ifdef IL_NATIVE_INT64
-                       else
-                       {
-                               CVM_OUT_NONE(COP_CKARRAY_LOAD_I8);
-                               if(size == 2)
-                               {
-                                       CVM_OUT_NONE(COP_LDC_I4_1);
-                                       CVM_ADJUST(1);
-                                       CVM_OUT_NONE(COP_LSHL);
-                                       CVM_ADJUST(-1);
-                               }
-                               else if(size == 4)
-                               {
-                                       CVM_OUT_NONE(COP_LDC_I4_2);
-                                       CVM_ADJUST(1);
-                                       CVM_OUT_NONE(COP_LSHL);
-                                       CVM_ADJUST(-1);
-                               }
-                               else if(size == 8)
-                               {
-                                       CVM_OUT_NONE(COP_LDC_I4_3);
-                                       CVM_ADJUST(1);
-                                       CVM_OUT_NONE(COP_LSHL);
-                                       CVM_ADJUST(-1);
-                               }
-                               else if(size != 1)
-                               {
-                                       if(size < 8)
-                                       {
-                                               CVM_OUT_NONE(COP_LDC_I4_0 + 
size);
-                                       }
-                                       else if(size < 128)
-                                       {
-                                               CVM_OUT_BYTE(COP_LDC_I4_S, 
size);
-                                       }
-                                       else
-                                       {
-                                               CVM_OUT_WORD(COP_LDC_I4, size);
-                                       }
-                                       CVM_OUT_NONE(COP_IU2L);
-                                       CVM_ADJUST(CVM_WORDS_PER_LONG);
-                                       CVM_OUT_NONE(COP_LMUL);
-                                       CVM_ADJUST(-CVM_WORDS_PER_LONG);
-                               }
-                               CVM_OUT_NONE(COP_PADD_I8);
-                               CVM_ADJUST(-CVM_WORDS_PER_LONG);
-                       }
-               #endif
+                       GetArrayElementAddress(coder, indexType, size);
                }
                break;
 
diff --git a/engine/md_amd64.h b/engine/md_amd64.h
index 50c3297..a5f1a95 100644
--- a/engine/md_amd64.h
+++ b/engine/md_amd64.h
@@ -597,6 +597,24 @@ extern md_inst_ptr _md_amd64_switch(md_inst_ptr inst, int 
reg, void * table);
                        } while (0)
 
 /*
+ * Load the effective address of a memory base + shifted index into
+ * a register.
+ * WARNING: indexreg might be destroyed by this operation.
+ */
+#define        md_lea_memindex_shift(inst,reg,basereg,indexreg,shift,offset)   
\
+                       do { \
+                               if((shift) <= 3) \
+                               { \
+                                       amd64_lea_memindex((inst), (reg), 
(basereg), (offset), (indexreg), (shift)); \
+                               } \
+                               else \
+                               { \
+                                       amd64_shift_reg_imm((inst), X86_SHL, 
(indexreg), (shift)); \
+                                       amd64_lea_memindex((inst), (reg), 
(basereg), (offset), (indexreg), 0); \
+                               } \
+                       } while (0)
+
+/*
  * Move values between registers.
  */
 #define        md_mov_reg_reg(inst,dreg,sreg)  \
diff --git a/engine/md_x86.h b/engine/md_x86.h
index 9d1d1df..e250e8b 100644
--- a/engine/md_x86.h
+++ b/engine/md_x86.h
@@ -642,6 +642,24 @@ extern md_inst_ptr _md_x86_widen_byte(md_inst_ptr inst, 
int reg, int isSigned);
                        } while (0)
 
 /*
+ * Load the effective address of a memory base + shifted index into
+ * a register.
+ * WARNING: indexreg might be destroyed by this operation.
+ */
+#define        md_lea_memindex_shift(inst,reg,basereg,indexreg,shift,offset)   
\
+                       do { \
+                               if((shift) <= 3) \
+                               { \
+                                       x86_lea_memindex((inst), (reg), 
(basereg), (offset), (indexreg), (shift)); \
+                               } \
+                               else \
+                               { \
+                                       x86_shift_reg_imm((inst), X86_SHL, 
(indexreg), (shift)); \
+                                       x86_lea_memindex((inst), (reg), 
(basereg), (offset), (indexreg), 0); \
+                               } \
+                       } while (0)
+
+/*
  * Move values between registers.
  */
 #define        md_mov_reg_reg(inst,dreg,sreg)  \
diff --git a/engine/unroll_ptr.c b/engine/unroll_ptr.c
index bf70844..9ef59f2 100644
--- a/engine/unroll_ptr.c
+++ b/engine/unroll_ptr.c
@@ -999,6 +999,42 @@ case COP_ARRAY_LEN:
 }
 break;
 
+#ifdef md_lea_memindex_shift
+
+case COP_ELEM_ADDR_SHIFT_I4:
+{
+       /* Load the effective address of an element from an array */
+       unsigned temp = (unsigned)CVM_ARG_BYTE;
+       UNROLL_START();
+       GetTopTwoWordRegisters(&unroll, &reg, &reg2,
+                                                  MD_REG1_NATIVE | 
MD_REG2_32BIT);
+       CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
+       md_lea_memindex_shift(unroll.out, reg, reg, reg2, temp, 
MD_ARRAY_HEADER);
+       FreeTopRegister(&unroll, -1);
+       MODIFY_UNROLL_PC(CVM_LEN_BYTE);
+}
+break;
+
+#endif /* md_lea_memindex_shift */
+
+#ifdef md_lea_memindex_mul
+
+case COP_ELEM_ADDR_MUL_I4:
+{
+       /* Load the effective address of an element from an array */
+       ILUInt32 temp = (unsigned)CVM_ARG_WORD;
+       UNROLL_START();
+       GetTopTwoWordRegisters(&unroll, &reg, &reg2,
+                                                  MD_REG1_NATIVE | 
MD_REG2_32BIT);
+       CheckArrayAccess(&unroll, reg, reg2, pc, (unsigned char *)inst);
+       md_lea_memindex_mul(unroll.out, reg, reg, reg2, temp, MD_ARRAY_HEADER);
+       FreeTopRegister(&unroll, -1);
+       MODIFY_UNROLL_PC(CVM_LEN_WORD);
+}
+break;
+
+#endif /* md_lea_memindex_mul */
+
 case COP_BREAD_FIELD:
 {
        /* Read a byte field from an object */

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog            |   26 ++++++++
 engine/cvm.h         |   70 ++++++++++----------
 engine/cvm_dasm.c    |   48 ++++++++++++--
 engine/cvm_lengths.c |   44 +++++++++----
 engine/cvm_ptr.c     |  100 ++++++++++++++++++++++-------
 engine/cvmc_ptr.c    |  174 +++++++++++++++++++++++---------------------------
 engine/md_amd64.h    |   18 +++++
 engine/md_x86.h      |   18 +++++
 engine/unroll_ptr.c  |   36 ++++++++++
 9 files changed, 359 insertions(+), 175 deletions(-)


hooks/post-receive
-- 
DotGNU Portable.NET engine, compilers and tools (pnet)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]