diff --git a/src/coreclr/vm/arm64/asmhelpers.S b/src/coreclr/vm/arm64/asmhelpers.S index b4a87823304149..5a00639e6afbb4 100644 --- a/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/coreclr/vm/arm64/asmhelpers.S @@ -695,11 +695,11 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler #endif INLINE_GETTHREAD x20 // thrashes x0 on Apple OSes (and possibly other arg registers on other Unixes) - ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] + ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] cbnz x11, LOCAL_LABEL(HaveInterpThreadContext) #ifdef TARGET_APPLE - // There Thread::GetInterpThreadContext can destroy all argument registers, so we + // There Thread::GetInterpThreadContext can destroy all argument registers, so we // need to save them. For non-Apple, they have been already saved in the PROLOG_WITH_TRANSITION_BLOCK // Restore x0 thrashed by the INLINE_GETTHREAD mov x0, x21 @@ -887,6 +887,30 @@ NESTED_ENTRY InterpreterStubRet4Float, _TEXT, NoHandler EPILOG_RETURN NESTED_END InterpreterStubRet4Float, _TEXT +NESTED_ENTRY InterpreterStubRetVector64, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED fp, lr, -16 + // The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 // the IR bytecode pointer + mov x2, xzr + bl C_FUNC(ExecuteInterpretedMethod) + ldr d0, [x0] + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + EPILOG_RETURN +NESTED_END InterpreterStubRetVector64, _TEXT + +NESTED_ENTRY InterpreterStubRetVector128, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED fp, lr, -16 + // The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 // the IR bytecode pointer + mov x2, xzr + bl C_FUNC(ExecuteInterpretedMethod) + ldr q0, [x0] + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + EPILOG_RETURN +NESTED_END InterpreterStubRetVector128, _TEXT + // Copy arguments from the processor stack to the interpreter stack // The CPU stack slots are aligned to pointer size. @@ -1834,4 +1858,42 @@ NESTED_ENTRY CallJittedMethodRet4Float, _TEXT, NoHandler EPILOG_RETURN NESTED_END CallJittedMethodRet4Float, _TEXT +// X0 - routines array +// X1 - interpreter stack args location +// X2 - interpreter stack return value location +// X3 - stack arguments size (properly aligned) +NESTED_ENTRY CallJittedMethodRetVector64, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32 + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str d0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32 + EPILOG_RETURN +NESTED_END CallJittedMethodRetVector64, _TEXT + +// X0 - routines array +// X1 - interpreter stack args location +// X2 - interpreter stack return value location +// X3 - stack arguments size (properly aligned) +NESTED_ENTRY CallJittedMethodRetVector128, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32 + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str q0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32 + EPILOG_RETURN +NESTED_END CallJittedMethodRetVector128, _TEXT + #endif // FEATURE_INTERPRETER diff --git a/src/coreclr/vm/arm64/asmhelpers.asm b/src/coreclr/vm/arm64/asmhelpers.asm index 9d2f8ee955593f..f5de9e3488c7c4 100644 --- a/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/coreclr/vm/arm64/asmhelpers.asm @@ -1240,6 +1240,30 @@ HaveInterpThreadContext EPILOG_RETURN NESTED_END InterpreterStubRet4Float + NESTED_ENTRY InterpreterStubRetVector64 + PROLOG_SAVE_REG_PAIR fp, lr, #-16! + ; The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 ; the IR bytecode pointer + mov x2, xzr + bl ExecuteInterpretedMethod + ldr d0, [x0] + EPILOG_RESTORE_REG_PAIR fp, lr, #16! + EPILOG_RETURN + NESTED_END InterpreterStubRetVector64 + + NESTED_ENTRY InterpreterStubRetVector128 + PROLOG_SAVE_REG_PAIR fp, lr, #-16! + ; The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 ; the IR bytecode pointer + mov x2, xzr + bl ExecuteInterpretedMethod + ldr q0, [x0] + EPILOG_RESTORE_REG_PAIR fp, lr, #16! + EPILOG_RETURN + NESTED_END InterpreterStubRetVector128 + ; Routines for passing value type arguments by reference in general purpose registers X0..X7 ; from native code to the interpreter @@ -1259,7 +1283,7 @@ StoreCopyLoop ldr x11, [x10], #8 EPILOG_BRANCH_REG x11 LEAF_END Store_Stack - + LEAF_ENTRY Load_Stack_Ref ldr w11, [x10], #4 ; SP offset ldr w12, [x10], #4 ; size of the value type @@ -2117,6 +2141,44 @@ CopyLoop EPILOG_RETURN NESTED_END CallJittedMethodRet4Float + ; X0 - routines array + ; X1 - interpreter stack args location + ; X2 - interpreter stack return value location + ; X3 - stack arguments size (properly aligned) + NESTED_ENTRY CallJittedMethodRetVector64 + PROLOG_SAVE_REG_PAIR fp, lr, #-32! + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str d0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR fp, lr, #32! + EPILOG_RETURN + NESTED_END CallJittedMethodRetVector64 + + ; X0 - routines array + ; X1 - interpreter stack args location + ; X2 - interpreter stack return value location + ; X3 - stack arguments size (properly aligned) + NESTED_ENTRY CallJittedMethodRetVector128 + PROLOG_SAVE_REG_PAIR fp, lr, #-32! + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str q0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR fp, lr, #32! + EPILOG_RETURN + NESTED_END CallJittedMethodRetVector128 + #endif // FEATURE_INTERPRETER ; Must be at very end of file diff --git a/src/coreclr/vm/callstubgenerator.cpp b/src/coreclr/vm/callstubgenerator.cpp index bfc3931e0e0474..e9c22c4c6c5e3e 100644 --- a/src/coreclr/vm/callstubgenerator.cpp +++ b/src/coreclr/vm/callstubgenerator.cpp @@ -1090,6 +1090,8 @@ extern "C" void CallJittedMethodRetFloat(PCODE *routines, int8_t*pArgs, int8_t*p extern "C" void CallJittedMethodRet2Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); extern "C" void CallJittedMethodRet3Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); extern "C" void CallJittedMethodRet4Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); +extern "C" void CallJittedMethodRetVector64(PCODE *routines, int8_t *pArgs, int8_t *pRet, int totalStackSize); +extern "C" void CallJittedMethodRetVector128(PCODE *routines, int8_t *pArgs, int8_t *pRet, int totalStackSize); extern "C" void InterpreterStubRet2I8(); extern "C" void InterpreterStubRet2Double(); extern "C" void InterpreterStubRet3Double(); @@ -1098,6 +1100,8 @@ extern "C" void InterpreterStubRetFloat(); extern "C" void InterpreterStubRet2Float(); extern "C" void InterpreterStubRet3Float(); extern "C" void InterpreterStubRet4Float(); +extern "C" void InterpreterStubRetVector64(); +extern "C" void InterpreterStubRetVector128(); #endif // TARGET_ARM64 #if LOG_COMPUTE_CALL_STUB @@ -1154,6 +1158,10 @@ CallStubHeader::InvokeFunctionPtr CallStubGenerator::GetInvokeFunctionPtr(CallSt INVOKE_FUNCTION_PTR(CallJittedMethodRet3Float); case ReturnType4Float: INVOKE_FUNCTION_PTR(CallJittedMethodRet4Float); + case ReturnTypeVector64: + INVOKE_FUNCTION_PTR(CallJittedMethodRetVector64); + case ReturnTypeVector128: + INVOKE_FUNCTION_PTR(CallJittedMethodRetVector128); #endif // TARGET_ARM64 default: _ASSERTE(!"Unexpected return type for interpreter stub"); @@ -1215,6 +1223,10 @@ PCODE CallStubGenerator::GetInterpreterReturnTypeHandler(CallStubGenerator::Retu RETURN_TYPE_HANDLER(InterpreterStubRet3Float); case ReturnType4Float: RETURN_TYPE_HANDLER(InterpreterStubRet4Float); + case ReturnTypeVector64: + RETURN_TYPE_HANDLER(InterpreterStubRetVector64); + case ReturnTypeVector128: + RETURN_TYPE_HANDLER(InterpreterStubRetVector128); #endif // TARGET_ARM64 default: _ASSERTE(!"Unexpected return type for interpreter stub"); @@ -1724,7 +1736,7 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg } #else return ReturnTypeBuff; -#endif +#endif } else { @@ -1842,8 +1854,30 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg break; } break; +#ifdef FEATURE_SIMD + case CORINFO_HFA_ELEM_VECTOR64: + switch (thReturnValueType.GetSize()) + { + case 8: + return ReturnTypeVector64; + default: + _ASSERTE(!"Unsupported Vector64 HFA size"); + break; + } + break; + case CORINFO_HFA_ELEM_VECTOR128: + switch (thReturnValueType.GetSize()) + { + case 16: + return ReturnTypeVector128; + default: + _ASSERTE(!"Unsupported Vector128 HFA size"); + break; + } + break; +#endif default: - _ASSERTE(!"HFA types other than float and double are not supported yet"); + _ASSERTE(!"HFA type is not supported"); break; } } diff --git a/src/coreclr/vm/callstubgenerator.h b/src/coreclr/vm/callstubgenerator.h index 9f628f6ac08024..55ef6911480cdb 100644 --- a/src/coreclr/vm/callstubgenerator.h +++ b/src/coreclr/vm/callstubgenerator.h @@ -83,7 +83,9 @@ class CallStubGenerator ReturnTypeFloat, ReturnType2Float, ReturnType3Float, - ReturnType4Float + ReturnType4Float, + ReturnTypeVector64, + ReturnTypeVector128 #endif // TARGET_ARM64 };