/* * Handle a unary opcode. */ static void JITCoder_Unary(ILCoder *coder, int opcode, ILEngineType type) { ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder); _ILJitStackItemNew(value); ILJitValue result = 0; _ILJitStackPop(jitCoder, value); switch(opcode) { case IL_OP_NEG: { result = jit_insn_neg(jitCoder->jitFunction, _ILJitStackItemValue(value)); } break; case IL_OP_NOT: { result = jit_insn_not(jitCoder->jitFunction, _ILJitStackItemValue(value)); } break; case IL_OP_CKFINITE: { /* Check the stack Top-most F value to see if it is finite */ result = jit_insn_is_finite(jitCoder->jitFunction, _ILJitStackItemValue(value)); } break; } _ILJitStackPushValue(jitCoder, result); }
/* * Handle a shift opcode. */ static void JITCoder_Shift(ILCoder *coder, int opcode, ILEngineType type1, ILEngineType type2) { ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder); _ILJitStackItemNew(value2); _ILJitStackItemNew(value1); ILJitValue result = 0; _ILJitStackPop(jitCoder, value2); _ILJitStackPop(jitCoder, value1); /* Determine how to perform the operation */ switch(opcode) { case IL_OP_SHL: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_shl(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SHR: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result= jit_insn_shr(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SHR_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_shr(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; } _ILJitStackPushValue(jitCoder, result); }
/* * Inline function to get the character at the specified indexe in a * string. */ static int _ILJitSystemStringChars(ILJITCoder *jitCoder, ILMethod *method, ILCoderMethodInfo *methodInfo, ILJitStackItem *args, ILInt32 numArgs) { ILJitFunction jitFunction = ILJitFunctionFromILMethod(method); ILClass *stringClass = ILMethod_Owner(method); ILJitValue length; ILJitValue stringBase; ILJitValue returnValue; if(!jitFunction) { /* We need to layout the class first. */ if(!_LayoutClass(ILExecThreadCurrent(), stringClass)) { return 0; } if(!(jitFunction = ILJitFunctionFromILMethod(method))) { return 0; } } #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && defined(_IL_JIT_ENABLE_DEBUG) if(jitCoder->flags & IL_CODER_FLAG_STATS) { ILMutexLock(globalTraceMutex); fprintf(stdout, "Inline System.String::get_Chars\n"); ILMutexUnlock(globalTraceMutex); } #endif _ILJitStackItemCheckNull(jitCoder, args[0]); length = _ILJitStringGetLength(jitCoder->jitFunction, _ILJitStackItemValue(args[0])); JITC_START_CHECK_STRING_INDEX(jitCoder, length, _ILJitStackItemValue(args[1])) stringBase = _ILJitStringGetStart(jitCoder->jitFunction, _ILJitStackItemValue(args[0])); returnValue = jit_insn_load_elem(jitCoder->jitFunction, stringBase, _ILJitStackItemValue(args[1]), _IL_JIT_TYPE_CHAR); JITC_END_CHECK_STRING_INDEX(jitCoder) _ILJitStackPushValue(jitCoder, returnValue); return 1; }
/* * Output a comparison instruction. */ static void JITCoder_Compare(ILCoder *coder, int opcode, ILEngineType type1, ILEngineType type2, int invertTest) { ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder); _ILJitStackItemNew(value2); _ILJitStackItemNew(value1); ILJitValue temp; _ILJitStackPop(jitCoder, value2); _ILJitStackPop(jitCoder, value1); temp = OutputCompare(jitCoder, opcode, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); if(invertTest) { temp = jit_insn_to_not_bool(jitCoder->jitFunction, temp); } else { temp = jit_insn_to_bool(jitCoder->jitFunction, temp); } _ILJitStackPushValue(jitCoder, temp); }
/* * Handle a binary opcode. */ static void JITCoder_Binary(ILCoder *coder, int opcode, ILEngineType type1, ILEngineType type2) { ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder); _ILJitStackItemNew(value2); _ILJitStackItemNew(value1); ILJitValue result = 0; _ILJitStackPop(jitCoder, value2); _ILJitStackPop(jitCoder, value1); switch(opcode) { case IL_OP_ADD: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_add(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_ADD_OVF: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_add_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_ADD_OVF_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_add_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SUB: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_sub(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SUB_OVF: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_sub_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SUB_OVF_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_sub_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_MUL: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_mul(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_MUL_OVF: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_mul_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_MUL_OVF_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_mul_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_DIV: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_div(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_DIV_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_div(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_REM: { AdjustMixedBinary(jitCoder, 0, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_rem(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_REM_UN: { AdjustMixedBinary(jitCoder, 1, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); result = jit_insn_rem(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_AND: { result = jit_insn_and(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_OR: { result = jit_insn_or(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_XOR: { result = jit_insn_xor(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; default: { return; } } _ILJitStackPushValue(jitCoder, result); }
/* * Handle a binary opcode when pointer arithmetic is involved. */ static void JITCoder_BinaryPtr(ILCoder *coder, int opcode, ILEngineType type1, ILEngineType type2) { ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder); int value1IsPointer = _IL_JIT_ENGINE_TYPE_IS_POINTER(type1); int value2IsPointer = _IL_JIT_ENGINE_TYPE_IS_POINTER(type2); _ILJitStackItemNew(value2); _ILJitStackItemNew(value1); ILJitValue result = 0; _ILJitStackPop(jitCoder, value2); _ILJitStackPop(jitCoder, value1); switch(opcode) { case IL_OP_ADD: { result = jit_insn_add(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } case IL_OP_ADD_OVF_UN: { result = jit_insn_add_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; case IL_OP_SUB: { result = jit_insn_sub(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } case IL_OP_SUB_OVF_UN: { result = jit_insn_sub_ovf(jitCoder->jitFunction, _ILJitStackItemValue(value1), _ILJitStackItemValue(value2)); } break; } if(value1IsPointer && value2IsPointer) { /* We can't keep the reference information for this case. */ _ILJitStackPushValue(jitCoder, result); } else if(value1IsPointer) { /* Keep the reference information for value1. */ _ILJitStackItemSetValue(value1, result); _ILJitStackPush(jitCoder, value1); } else if(value2IsPointer) { /* Keep the reference information for value2. */ _ILJitStackItemSetValue(value2, result); _ILJitStackPush(jitCoder, value2); } else { /* There is no pointer involved in this operation. */ _ILJitStackPushValue(jitCoder, result); } }
/* * Inline function to create a new string with the given length */ static int _ILJitSystemStringNew(ILJITCoder *jitCoder, ILMethod *method, ILCoderMethodInfo *methodInfo, ILJitStackItem *args, ILInt32 numArgs) { ILJitFunction jitFunction = ILJitFunctionFromILMethod(method); ILClass *stringClass = ILMethod_Owner(method); ILJitValue newString; ILJitValue callArgs[2]; if(!jitFunction) { /* We need to layout the class first. */ if(!_LayoutClass(ILExecThreadCurrent(), stringClass)) { return 0; } if(!(jitFunction = ILJitFunctionFromILMethod(method))) { return 0; } } #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && defined(_IL_JIT_ENABLE_DEBUG) if(jitCoder->flags & IL_CODER_FLAG_STATS) { ILMutexLock(globalTraceMutex); fprintf(stdout, "Inline System.String::NewString\n"); ILMutexUnlock(globalTraceMutex); } #endif /* We call the alloc functions. */ /* They thow an out of memory exception so we don't need to care. */ callArgs[0] = jit_value_create_nint_constant(jitCoder->jitFunction, _IL_JIT_TYPE_VPTR, (jit_nint)stringClass); if(!callArgs[0]) { return 0; } callArgs[1] = _ILJitValueConvertImplicit(jitCoder->jitFunction, _ILJitStackItemValue(args[0]), _IL_JIT_TYPE_UINT32); if(!callArgs[1]) { return 0; } newString = jit_insn_call_native(jitCoder->jitFunction, "_ILJitStringAlloc", _ILJitStringAlloc, _ILJitSignature_ILJitStringAlloc, callArgs, 2, 0); if(!newString) { return 0; } _ILJitStackPushValue(jitCoder, newString); return 1; }