[Top][All Lists]
[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 */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] pnet ./ChangeLog engine/jitc.c engine/jitc.h en...,
Klaus Treichel <=