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

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

[dotgnu-pnet-commits] pnet ./ChangeLog engine/jitc.c engine/jitc.h en...


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] pnet ./ChangeLog engine/jitc.c engine/jitc.h en...
Date: Fri, 30 Dec 2005 17:42:19 +0000

CVSROOT:        /cvsroot/dotgnu-pnet
Module name:    pnet
Branch:         
Changes by:     Klaus Treichel <address@hidden> 05/12/30 17:42:19

Modified files:
        .              : ChangeLog 
        engine         : jitc.c jitc.h jitc_branch.c 

Log message:
        Add compare and branch instructions in the jit coder.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/ChangeLog.diff?tr1=1.3260&tr2=1.3261&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc.c.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc.h.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc_branch.c.diff?tr1=1.1&tr2=1.2&r1=text&r2=text

Patches:
Index: pnet/ChangeLog
diff -u pnet/ChangeLog:1.3260 pnet/ChangeLog:1.3261
--- pnet/ChangeLog:1.3260       Thu Dec 29 15:56:52 2005
+++ pnet/ChangeLog      Fri Dec 30 17:42:19 2005
@@ -1,3 +1,8 @@
+2005-12-30  Klaus Treichel  <address@hidden>
+
+       * engine/jitc.c, engine/jitc.h, engine/jitc_branch.c: Add compare and
+       branch instructions.
+
 2005-12-29  Klaus Treichel  <address@hidden>
 
        * engine/convert.c: Add a version of ConvertMethod for use with the jit
Index: pnet/engine/jitc.c
diff -u pnet/engine/jitc.c:1.6 pnet/engine/jitc.c:1.7
--- pnet/engine/jitc.c:1.6      Thu Dec 29 15:56:52 2005
+++ pnet/engine/jitc.c  Fri Dec 30 17:42:19 2005
@@ -77,6 +77,18 @@
 #endif
 
 /*
+ * Define the structure of a JIT label.
+ */
+typedef struct _tagILJITLabel ILJITLabel;
+struct _tagILJITLabel
+{
+       ILUInt32        address;                /* Address in the IL code */
+       jit_label_t     label;                  /* the libjit label */
+       ILJITLabel *next;                       /* Next label block */
+
+};
+
+/*
  * Define the structure of a JIT coder's instance block.
  */
 typedef struct _tagILJITCoder ILJITCoder;
@@ -100,6 +112,11 @@
        int                             numLocals;
        int                             maxLocals;
 
+       /* Handle the labels. */
+       ILMemPool               labelPool;
+       ILJITLabel     *labelList;
+       int                             labelOutOfMemory;
+
        /* The current jitted function. */
        ILJitFunction   jitFunction;
 };
@@ -486,6 +503,11 @@
        /* Init the current jitted function. */
        coder->jitFunction = 0;
 
+       /* Init the label stuff. */
+       ILMemPoolInit(&(coder->labelPool), sizeof(ILJITLabel), 8);
+       coder->labelList = 0;
+       coder->labelOutOfMemory = 0;
+
        /* Ready to go */
        return &(coder->coder);
 }
Index: pnet/engine/jitc.h
diff -u pnet/engine/jitc.h:1.4 pnet/engine/jitc.h:1.5
--- pnet/engine/jitc.h:1.4      Thu Dec 29 15:56:52 2005
+++ pnet/engine/jitc.h  Fri Dec 30 17:42:19 2005
@@ -34,6 +34,7 @@
 #define _IL_JIT_TYPE_INT16     jit_type_short
 #define _IL_JIT_TYPE_INT32     jit_type_int
 #define _IL_JIT_TYPE_INT64     jit_type_long
+#define _IL_JIT_TYPE_NINT      jit_type_nint
 #define _IL_JIT_TYPE_INTPTR    jit_type_void_ptr
 #define _IL_JIT_TYPE_NFLOAT    jit_type_nfloat
 #define _IL_JIT_TYPE_SBYTE     jit_type_sbyte
@@ -41,6 +42,7 @@
 #define _IL_JIT_TYPE_UINT16    jit_type_ushort
 #define _IL_JIT_TYPE_UINT32    jit_type_uint
 #define _IL_JIT_TYPE_UINT64    jit_type_ulong
+#define _IL_JIT_TYPE_NUINT     jit_type_nuint
 #define _IL_JIT_TYPE_VPTR      jit_type_void_ptr;
  
 /*
Index: pnet/engine/jitc_branch.c
diff -u pnet/engine/jitc_branch.c:1.1 pnet/engine/jitc_branch.c:1.2
--- pnet/engine/jitc_branch.c:1.1       Mon Dec 19 18:00:35 2005
+++ pnet/engine/jitc_branch.c   Fri Dec 30 17:42:19 2005
@@ -21,12 +21,294 @@
 #ifdef IL_JITC_CODE
 
 /*
+ * Look for a label for a specific IL address.  Create
+ * a new label if necessary.
+ */
+static ILJITLabel *GetLabel(ILJITCoder *coder, ILUInt32 address)
+{
+       ILJITLabel *label;
+       label = coder->labelList;
+       while(label != 0)
+       {
+               if(label->address == address)
+               {
+                       return label;
+               }
+               label = label->next;
+       }
+       label = ILMemPoolAlloc(&(coder->labelPool), ILJITLabel);
+       if(label)
+       {
+               label->address = address;
+               label->label = jit_label_undefined;
+               label->next = coder->labelList;
+               coder->labelList = label;
+       }
+       else
+       {
+               coder->labelOutOfMemory = 1;
+       }
+       return label;
+}
+
+/*
  * Handle a label.
  */
-static void JITCoder_Label(ILCoder *_coder, ILUInt32 offset)
+static void JITCoder_Label(ILCoder *coder, ILUInt32 offset)
 {
+       ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+       ILJITLabel *label = GetLabel(jitCoder, offset);
+
+       if(label)
+       {
+               jit_insn_label(jitCoder->jitFunction, &(label->label));
+       }
 }
 
+/*
+ * Check if the typeKind is a long.
+ */
+#ifdef IL_NATIVE_INT64
+#define _JIT_TYPEKIND_IS_LONG(typeKind) \
+((typeKind == JIT_TYPE_LONG)   || \
+ (typeKind == JIT_TYPE_ULONG)  || \
+ (typeKind == JIT_TYPE_NINT)   || \
+ (typeKind == JIT_TYPE_NUINT)  || \
+ (type1Kind == JIT_TYPE_PTR))
+#else
+#define _JIT_TYPEKIND_IS_LONG(typeKind) \
+((typeKind == JIT_TYPE_LONG)   || \
+ (typeKind == JIT_TYPE_ULONG))
+#endif
+
+/*
+ * Check if the typeKind is unsigned.
+ */
+#define _JIT_TYPEKIND_IS_UNSIGNED(typeKind) \
+((typeKind == JIT_TYPE_ULONG)  || \
+ (typeKind == JIT_TYPE_NUINT)  || \
+ (typeKind == JIT_TYPE_UINT)   || \
+ (typeKind == JIT_TYPE_USHORT) || \
+ (type1Kind == JIT_TYPE_UBYTE))
+
+/*
+ * Check if the typeKind is signed.
+ */
+#define _JIT_TYPEKIND_IS_SIGNED(typeKind) \
+((typeKind == JIT_TYPE_LONG)   || \
+ (typeKind == JIT_TYPE_NINT)   || \
+ (typeKind == JIT_TYPE_INT)    || \
+ (typeKind == JIT_TYPE_SHORT)  || \
+ (type1Kind == JIT_TYPE_SBYTE))
+
+/*
+ * Readjust the stack to normalize binary operands when
+ * I and I4 are mixed together.  Also determine which of
+ * I4 or I8 to use if the operation involves I.
+ */
+static void AdjustMixedBinary(ILJITCoder *coder, int isUnsigned,
+                                                         ILJitValue *value1, 
ILJitValue *value2)
+                                                         
+{
+       ILJitType type1 = jit_value_get_type(*value1);
+       ILJitType newType1 = type1;
+       ILJitType type2 = jit_value_get_type(*value2);
+       ILJitType newType2 = type2;
+       int type1Kind = jit_type_get_kind(type1);
+       int type2Kind = jit_type_get_kind(type2);
+       int type1IsLong = _JIT_TYPEKIND_IS_LONG(type1Kind);
+       int type2IsLong = _JIT_TYPEKIND_IS_LONG(type2Kind);
+
+       /* If the arguments mix I8 and I4, then cast the I4 value to I8 */
+       if(type1IsLong && !type2IsLong)
+       {
+               if(isUnsigned)
+               {
+                       newType2 = _IL_JIT_TYPE_UINT64;
+               }
+               else
+               {
+                       newType2 = _IL_JIT_TYPE_INT64;
+               }
+               type2Kind = jit_type_get_kind(newType2);
+               type2IsLong = 1;
+       }
+       else if(!type1IsLong && type2IsLong)
+       {
+               if(isUnsigned)
+               {
+                       newType1 = _IL_JIT_TYPE_UINT64;
+               }
+               else
+               {
+                       newType1 = _IL_JIT_TYPE_INT64;
+               }
+               type1Kind = jit_type_get_kind(newType1);
+               type1IsLong = 1;
+       }
+
+       if(isUnsigned)
+       {
+               if(_JIT_TYPEKIND_IS_SIGNED(type1Kind))
+               {
+                       if(type1IsLong)
+                       {
+                               newType1 = _IL_JIT_TYPE_UINT64;
+                       }
+                       else
+                       {
+                               newType1 = _IL_JIT_TYPE_UINT32;
+                       }
+                       type1Kind = jit_type_get_kind(newType1);
+               }
+               if(_JIT_TYPEKIND_IS_SIGNED(type2Kind))
+               {
+                       if(type2IsLong)
+                       {
+                               newType2 = _IL_JIT_TYPE_UINT64;
+                       }
+                       else
+                       {
+                               newType2 = _IL_JIT_TYPE_UINT32;
+                       }
+                       type2Kind = jit_type_get_kind(newType2);
+               }
+       }
+       else
+       {
+               if(_JIT_TYPEKIND_IS_UNSIGNED(type1Kind))
+               {
+                       if(type1IsLong)
+                       {
+                               newType1 = _IL_JIT_TYPE_INT64;
+                       }
+                       else
+                       {
+                               newType1 = _IL_JIT_TYPE_INT32;
+                       }
+                       type1Kind = jit_type_get_kind(newType1);
+               }
+               if(_JIT_TYPEKIND_IS_UNSIGNED(type2Kind))
+               {
+                       if(type2IsLong)
+                       {
+                               newType2 = _IL_JIT_TYPE_INT64;
+                       }
+                       else
+                       {
+                               newType2 = _IL_JIT_TYPE_INT32;
+                       }
+                       type2Kind = jit_type_get_kind(newType2);
+               }
+       }
+       
+       /* now do the conversion if necessairy. */
+       if(type1 != newType1)
+       {
+               *value1 = jit_insn_convert(coder->jitFunction, *value1, 
newType1, 0);
+       }
+       if(type2 != newType2)
+       {
+               *value2 = jit_insn_convert(coder->jitFunction, *value2, 
newType2, 0);
+       }
+}
+
+/*
+ * Output a comparision between the 2 top most values on the evaluation stack.
+ * The result value is returned.
+ */
+static ILJitValue OutputCompare(ILJITCoder *coder, int opcode,
+                                                    ILJitValue *value1, 
ILJitValue *value2)
+{
+       switch(opcode)
+       {
+               case IL_OP_PREFIX + IL_PREFIX_OP_CEQ:
+               case IL_OP_BEQ:
+               {
+                       /* Test two values for equality */
+                       AdjustMixedBinary(coder, 0, value1, value2);
+                       return jit_insn_eq(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_BNE_UN:
+               {
+                       /* Test two unsigned values for inequality */
+                       AdjustMixedBinary(coder, 1, value1, value2);
+                       return jit_insn_ne(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_PREFIX + IL_PREFIX_OP_CGT:
+               case IL_OP_BGT:
+               {
+                       /* Test two signed values for greater than */
+                       AdjustMixedBinary(coder, 0, value1, value2);
+                       return jit_insn_gt(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_PREFIX + IL_PREFIX_OP_CGT_UN:
+               case IL_OP_BGT_UN:
+               {
+                       /* Test two unsigned values for greater than */
+                       AdjustMixedBinary(coder, 1, value1, value2);
+                       return jit_insn_gt(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_BGE:
+               {
+                       /* Test two signed values for greater than  or equal */
+                       AdjustMixedBinary(coder, 0, value1, value2);
+                       return jit_insn_ge(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_BGE_UN:
+               {
+                       /* Test two unsigned values for greater than  or equal 
*/
+                       AdjustMixedBinary(coder, 1, value1, value2);
+                       return jit_insn_ge(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_PREFIX + IL_PREFIX_OP_CLT:
+               case IL_OP_BLT:
+               {
+                       /* Test two signed values for less than */
+                       AdjustMixedBinary(coder, 0, value1, value2);
+                       return jit_insn_lt(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_PREFIX + IL_PREFIX_OP_CLT_UN:
+               case IL_OP_BLT_UN:
+               {
+                       /* Test two unsigned values for less than */
+                       AdjustMixedBinary(coder, 1, value1, value2);
+                       return jit_insn_lt(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_BLE:
+               {
+                       /* Test two signed values for less than or equal */
+                       AdjustMixedBinary(coder, 0, value1, value2);
+                       return jit_insn_le(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+
+               case IL_OP_BLE_UN:
+               {
+                       /* Test two unsigned values for less than  or equal */
+                       AdjustMixedBinary(coder, 1, value1, value2);
+                       return jit_insn_lt(coder->jitFunction, *value1, 
*value2);
+               }
+               break;
+       }
+       return 0;
+}
 
 /*
  * Output a branch instruction using a JIT coder.
@@ -34,6 +316,166 @@
 static void JITCoder_Branch(ILCoder *coder, int opcode, ILUInt32 dest,
                                                    ILEngineType type1, 
ILEngineType type2)
 {
+       ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+       ILJITLabel *label = GetLabel(jitCoder, dest);
+       ILJitValue temp;
+
+       /* Determine what form of branch to use */
+       switch(opcode)
+       {
+               case IL_OP_BR:
+               case IL_OP_BR_S:
+               case IL_OP_LEAVE:
+               case IL_OP_LEAVE_S:
+               {
+                       /* Unconditional branch */
+                       jit_insn_branch(jitCoder->jitFunction, &(label->label));
+               }
+               break;
+
+               case IL_OP_BRTRUE_S:
+               case IL_OP_BRTRUE:
+               {
+                       /* Branch if the top-most stack item is true */
+                       jit_insn_branch_if(jitCoder->jitFunction,
+                                                               
jitCoder->jitStack[jitCoder->stackTop - 1],
+                                                               
&(label->label));
+                       JITC_ADJUST(jitCoder, -1);
+               }
+               break;
+
+               case IL_OP_BRFALSE_S:
+               case IL_OP_BRFALSE:
+               {
+                       /* Branch if the top-most stack item is false */
+                       jit_insn_branch_if_not(jitCoder->jitFunction,
+                                                                       
jitCoder->jitStack[jitCoder->stackTop - 1],
+                                                                       
&(label->label));
+                       JITC_ADJUST(jitCoder, -1);
+               }
+               break;
+
+               case IL_OP_BEQ:
+               case IL_OP_BEQ_S:
+               {
+                       /* Equality testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BEQ,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BNE_UN:
+               case IL_OP_BNE_UN_S:
+               {
+                       /* Unsigned inequality testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BNE_UN,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BGT:
+               case IL_OP_BGT_S:
+               {
+                       /* Signed greater than testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BGT,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BGT_UN:
+               case IL_OP_BGT_UN_S:
+               {
+                       /* Unsigned greater than testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BGT_UN,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BGE:
+               case IL_OP_BGE_S:
+               {
+                       /* Signed greater than or equal testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BGE,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BGE_UN:
+               case IL_OP_BGE_UN_S:
+               {
+                       /* Unsigned greater than or equal testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BGE_UN,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BLT:
+               case IL_OP_BLT_S:
+               {
+                       /* Signed less than testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BLT,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BLT_UN:
+               case IL_OP_BLT_UN_S:
+               {
+                       /* Unsigned less than testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BLT_UN,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BLE:
+               case IL_OP_BLE_S:
+               {
+                       /* Signed less than or equal testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BLE,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+
+               case IL_OP_BLE_UN:
+               case IL_OP_BLE_UN_S:
+               {
+                       /* Unsigned less than or equal testing branch */
+                       temp = OutputCompare(jitCoder, IL_OP_BLE_UN,
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+                       jit_insn_branch_if(jitCoder->jitFunction, temp, 
&(label->label));
+                       JITC_ADJUST(jitCoder, -2);
+               }
+               break;
+       }
+
 }
 
 /*
@@ -57,6 +499,22 @@
                                                     ILEngineType type1, 
ILEngineType type2,
                                                         int invertTest)
 {
+       ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+       ILJitValue temp;
+
+       temp = OutputCompare(jitCoder, opcode,
+                                                
&(jitCoder->jitStack[jitCoder->stackTop - 1]),
+                                                
&(jitCoder->jitStack[jitCoder->stackTop - 2]));
+       if(invertTest)
+       {
+               temp = jit_insn_to_not_bool(jitCoder->jitFunction, temp);
+       }
+       else
+       {
+               temp = jit_insn_to_bool(jitCoder->jitFunction, temp);
+       }
+       jitCoder->jitStack[jitCoder->stackTop - 2] = temp;
+       JITC_ADJUST(jitCoder, -1);
 }
 
 #endif /* IL_JITC_CODE */




reply via email to

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