@@ -30,6 +30,7 @@ typedef enum {
3030	ArgGsharedVTOnStack ,
3131	ArgValuetypeAddrInIReg ,
3232	ArgVtypeAsScalar ,
33+ 	ArgSIMD ,
3334	ArgInvalid ,
3435} ArgStorage ;
3536
@@ -49,7 +50,7 @@ struct CallInfo {
4950// WASM ABI: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md 
5051
5152static  ArgStorage 
52- get_storage  (MonoType  * type , gboolean  is_return )
53+ get_storage  (MonoType  * type , gboolean  is_return ,  gboolean   enable_simd )
5354{
5455	switch  (type -> type ) {
5556	case  MONO_TYPE_I1 :
@@ -84,6 +85,9 @@ get_storage (MonoType *type, gboolean is_return)
8485		/* fall through */ 
8586	case  MONO_TYPE_VALUETYPE :
8687	case  MONO_TYPE_TYPEDBYREF : {
88+ 		MonoClass  * klass  =  mono_class_from_mono_type_internal  (type );
89+ 		if  (enable_simd  &&  m_class_is_simd_type  (klass ))
90+ 			return  ArgSIMD ;
8791		if  (mini_wasm_is_scalar_vtype  (type ))
8892			return  ArgVtypeAsScalar ;
8993		return  is_return  ? ArgValuetypeAddrInIReg  : ArgValuetypeAddrOnStack ;
@@ -102,7 +106,7 @@ get_storage (MonoType *type, gboolean is_return)
102106}
103107
104108static  CallInfo * 
105- get_call_info  (MonoMemPool  * mp , MonoMethodSignature  * sig )
109+ get_call_info  (MonoMemPool  * mp , MonoMethodSignature  * sig ,  gboolean   enable_simd )
106110{
107111	int  n  =  sig -> hasthis  +  sig -> param_count ;
108112	CallInfo  * cinfo ;
@@ -117,7 +121,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
117121
118122	/* return value */ 
119123	cinfo -> ret .type  =  mini_get_underlying_type  (sig -> ret );
120- 	cinfo -> ret .storage  =  get_storage  (cinfo -> ret .type , TRUE);
124+ 	cinfo -> ret .storage  =  get_storage  (cinfo -> ret .type , TRUE,  enable_simd );
121125
122126	if  (sig -> hasthis )
123127		cinfo -> args  [0 ].storage  =  ArgOnStack ;
@@ -128,7 +132,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
128132	int  i ;
129133	for  (i  =  0 ; i  <  sig -> param_count ; ++ i ) {
130134		cinfo -> args  [i  +  sig -> hasthis ].type  =  mini_get_underlying_type  (sig -> params  [i ]);
131- 		cinfo -> args  [i  +  sig -> hasthis ].storage  =  get_storage  (cinfo -> args  [i  +  sig -> hasthis ].type , FALSE);
135+ 		cinfo -> args  [i  +  sig -> hasthis ].storage  =  get_storage  (cinfo -> args  [i  +  sig -> hasthis ].type , FALSE,  enable_simd );
132136	}
133137
134138	return  cinfo ;
@@ -249,7 +253,7 @@ mono_arch_create_vars (MonoCompile *cfg)
249253	sig  =  mono_method_signature_internal  (cfg -> method );
250254
251255	if  (!cfg -> arch .cinfo )
252- 		cfg -> arch .cinfo  =  get_call_info  (cfg -> mempool , sig );
256+ 		cfg -> arch .cinfo  =  get_call_info  (cfg -> mempool , sig , ( cfg -> opt   &   MONO_OPT_SIMD )  !=   0 );
253257	cinfo  =  (CallInfo  * )cfg -> arch .cinfo ;
254258
255259	// if (cinfo->ret.storage == ArgValuetypeInReg) 
@@ -341,28 +345,37 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
341345	CallInfo  * cinfo ;
342346	LLVMCallInfo  * linfo ;
343347
344- 	cinfo  =  get_call_info  (cfg -> mempool , sig );
348+ 	cinfo  =  get_call_info  (cfg -> mempool , sig , ( cfg -> opt   &   MONO_OPT_SIMD )  !=   0 );
345349	n  =  cinfo -> nargs ;
346350
347351	linfo  =  mono_mempool_alloc0  (cfg -> mempool , sizeof  (LLVMCallInfo ) +  (sizeof  (LLVMArgInfo ) *  n ));
348352
349- 	if  (cinfo -> ret .storage  ==  ArgVtypeAsScalar ) {
353+ 	switch  (cinfo -> ret .storage ) {
354+ 	case  ArgVtypeAsScalar :
350355		linfo -> ret .storage  =  LLVMArgWasmVtypeAsScalar ;
351356		linfo -> ret .esize  =  mono_class_value_size  (mono_class_from_mono_type_internal  (cinfo -> ret .type ), NULL );
352- 	} else  if  (mini_type_is_vtype  (sig -> ret )) {
353- 		/* Vtype returned using a hidden argument */ 
354- 		linfo -> ret .storage  =  LLVMArgVtypeRetAddr ;
355- 		// linfo->vret_arg_index = cinfo->vret_arg_index; 
356- 	} else  {
357- 		if  (sig -> ret -> type  !=  MONO_TYPE_VOID )
358- 			linfo -> ret .storage  =  LLVMArgNormal ;
357+ 		break ;
358+ 	case  ArgSIMD :
359+ 		linfo -> ret .storage  =  LLVMArgNormal ;
360+ 		break ;
361+ 	default :
362+ 		if  (mini_type_is_vtype  (sig -> ret )) {
363+ 			/* Vtype returned using a hidden argument */ 
364+ 			linfo -> ret .storage  =  LLVMArgVtypeRetAddr ;
365+ 			// linfo->vret_arg_index = cinfo->vret_arg_index; 
366+ 		} else  {
367+ 			if  (sig -> ret -> type  !=  MONO_TYPE_VOID )
368+ 				linfo -> ret .storage  =  LLVMArgNormal ;
369+ 		}
370+ 		break ;
359371	}
360372
361373	for  (i  =  0 ; i  <  n ; ++ i ) {
362374		ArgInfo  * ainfo  =  & cinfo -> args [i ];
363375
364376		switch  (ainfo -> storage ) {
365377		case  ArgOnStack :
378+ 		case  ArgSIMD :
366379			linfo -> args  [i ].storage  =  LLVMArgNormal ;
367380			break ;
368381		case  ArgValuetypeAddrOnStack :
0 commit comments