github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/engine/wazevo/backend/isa/arm64/abi_go_call_test.go (about)

     1  package arm64
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  	"testing"
     7  
     8  	"github.com/tetratelabs/wazero/internal/engine/wazevo/backend"
     9  	"github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc"
    10  	"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
    11  	"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
    12  	"github.com/tetratelabs/wazero/internal/testing/require"
    13  )
    14  
    15  func Test_calleeSavedRegistersSorted(t *testing.T) {
    16  	var exp []regalloc.VReg
    17  	regInfo.CalleeSavedRegisters.Range(func(r regalloc.RealReg) {
    18  		exp = append(exp, regInfo.RealRegToVReg[r])
    19  	})
    20  	sort.Slice(exp, func(i, j int) bool {
    21  		return exp[i].RealReg() < exp[j].RealReg()
    22  	})
    23  
    24  	require.Equal(t, exp, calleeSavedRegistersSorted)
    25  }
    26  
    27  func TestMachine_CompileGoFunctionTrampoline(t *testing.T) {
    28  	for _, tc := range []struct {
    29  		name                 string
    30  		exitCode             wazevoapi.ExitCode
    31  		sig                  *ssa.Signature
    32  		needModuleContextPtr bool
    33  		exp                  string
    34  	}{
    35  		{
    36  			name:                 "listener",
    37  			exitCode:             wazevoapi.ExitCodeCallListenerBefore,
    38  			needModuleContextPtr: true,
    39  			sig: &ssa.Signature{
    40  				Params: []ssa.Type{
    41  					ssa.TypeI64, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32, ssa.TypeV128,
    42  					ssa.TypeI64, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32, ssa.TypeV128,
    43  					ssa.TypeI64, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32, ssa.TypeV128,
    44  					ssa.TypeI64, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32, ssa.TypeV128,
    45  				},
    46  				Results: []ssa.Type{
    47  					ssa.TypeV128, ssa.TypeI32, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32,
    48  					ssa.TypeV128, ssa.TypeI32, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32,
    49  					ssa.TypeV128, ssa.TypeI32, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32,
    50  					ssa.TypeV128, ssa.TypeI32, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32,
    51  					ssa.TypeV128, ssa.TypeI32, ssa.TypeI64, ssa.TypeV128, ssa.TypeF32,
    52  				},
    53  			},
    54  			exp: `
    55  	movz x27, #0xa0, lsl 0
    56  	sub sp, sp, x27
    57  	stp x30, x27, [sp, #-0x10]!
    58  	sub x27, sp, #0x130
    59  	ldr x11, [x0, #0x28]
    60  	subs xzr, x27, x11
    61  	b.ge #0x14
    62  	movz x27, #0x130, lsl 0
    63  	str x27, [x0, #0x40]
    64  	ldr x27, [x0, #0x50]
    65  	bl x27
    66  	add x17, sp, #0x10
    67  	str x19, [x0, #0x60]
    68  	str x20, [x0, #0x70]
    69  	str x21, [x0, #0x80]
    70  	str x22, [x0, #0x90]
    71  	str x23, [x0, #0xa0]
    72  	str x24, [x0, #0xb0]
    73  	str x25, [x0, #0xc0]
    74  	str x26, [x0, #0xd0]
    75  	str x28, [x0, #0xe0]
    76  	str q18, [x0, #0xf0]
    77  	str q19, [x0, #0x100]
    78  	str q20, [x0, #0x110]
    79  	str q21, [x0, #0x120]
    80  	str q22, [x0, #0x130]
    81  	str q23, [x0, #0x140]
    82  	str q24, [x0, #0x150]
    83  	str q25, [x0, #0x160]
    84  	str q26, [x0, #0x170]
    85  	str q27, [x0, #0x180]
    86  	str q28, [x0, #0x190]
    87  	str q29, [x0, #0x1a0]
    88  	str q30, [x0, #0x1b0]
    89  	str q31, [x0, #0x1c0]
    90  	str x1, [x0, #0x460]
    91  	sub sp, sp, #0x120
    92  	mov x15, sp
    93  	str q0, [x15], #0x10
    94  	str d1, [x15], #0x8
    95  	str q2, [x15], #0x10
    96  	str x2, [x15], #0x8
    97  	str x3, [x15], #0x8
    98  	str q3, [x15], #0x10
    99  	str d4, [x15], #0x8
   100  	str q5, [x15], #0x10
   101  	str x4, [x15], #0x8
   102  	str x5, [x15], #0x8
   103  	str q6, [x15], #0x10
   104  	str d7, [x15], #0x8
   105  	ldr q11, [x17], #0x10
   106  	str q11, [x15], #0x10
   107  	str x6, [x15], #0x8
   108  	str x7, [x15], #0x8
   109  	ldr q11, [x17], #0x10
   110  	str q11, [x15], #0x10
   111  	ldr s11, [x17], #0x8
   112  	str d11, [x15], #0x8
   113  	ldr q11, [x17], #0x10
   114  	str q11, [x15], #0x10
   115  	movz x27, #0x120, lsl 0
   116  	movz x16, #0x23, lsl 0
   117  	stp x27, x16, [sp, #-0x10]!
   118  	orr w17, wzr, #0xe
   119  	str w17, [x0]
   120  	mov x27, sp
   121  	str x27, [x0, #0x38]
   122  	adr x27, #0x20
   123  	str x27, [x0, #0x30]
   124  	exit_sequence x0
   125  	ldr x19, [x0, #0x60]
   126  	ldr x20, [x0, #0x70]
   127  	ldr x21, [x0, #0x80]
   128  	ldr x22, [x0, #0x90]
   129  	ldr x23, [x0, #0xa0]
   130  	ldr x24, [x0, #0xb0]
   131  	ldr x25, [x0, #0xc0]
   132  	ldr x26, [x0, #0xd0]
   133  	ldr x28, [x0, #0xe0]
   134  	ldr q18, [x0, #0xf0]
   135  	ldr q19, [x0, #0x100]
   136  	ldr q20, [x0, #0x110]
   137  	ldr q21, [x0, #0x120]
   138  	ldr q22, [x0, #0x130]
   139  	ldr q23, [x0, #0x140]
   140  	ldr q24, [x0, #0x150]
   141  	ldr q25, [x0, #0x160]
   142  	ldr q26, [x0, #0x170]
   143  	ldr q27, [x0, #0x180]
   144  	ldr q28, [x0, #0x190]
   145  	ldr q29, [x0, #0x1a0]
   146  	ldr q30, [x0, #0x1b0]
   147  	ldr q31, [x0, #0x1c0]
   148  	add x15, sp, #0x10
   149  	add sp, sp, #0x130
   150  	ldr x30, [sp], #0x10
   151  	add x17, sp, #0x38
   152  	add sp, sp, #0xa0
   153  	ldr q0, [x15], #0x10
   154  	ldr w0, [x15], #0x8
   155  	ldr x1, [x15], #0x8
   156  	ldr q1, [x15], #0x10
   157  	ldr s2, [x15], #0x8
   158  	ldr q3, [x15], #0x10
   159  	ldr w2, [x15], #0x8
   160  	ldr x3, [x15], #0x8
   161  	ldr q4, [x15], #0x10
   162  	ldr s5, [x15], #0x8
   163  	ldr q6, [x15], #0x10
   164  	ldr w4, [x15], #0x8
   165  	ldr x5, [x15], #0x8
   166  	ldr q7, [x15], #0x10
   167  	ldr s11, [x15], #0x8
   168  	str s11, [x17], #0x8
   169  	ldr q11, [x15], #0x10
   170  	str q11, [x17], #0x10
   171  	ldr w6, [x15], #0x8
   172  	ldr x7, [x15], #0x8
   173  	ldr q11, [x15], #0x10
   174  	str q11, [x17], #0x10
   175  	ldr s11, [x15], #0x8
   176  	str s11, [x17], #0x8
   177  	ldr q11, [x15], #0x10
   178  	str q11, [x17], #0x10
   179  	ldr w11, [x15], #0x8
   180  	str w11, [x17], #0x8
   181  	ldr x11, [x15], #0x8
   182  	str x11, [x17], #0x8
   183  	ldr q11, [x15], #0x10
   184  	str q11, [x17], #0x10
   185  	ldr s11, [x15], #0x8
   186  	str s11, [x17], #0x8
   187  	ret
   188  `,
   189  		},
   190  		{
   191  			name:     "go call",
   192  			exitCode: wazevoapi.ExitCodeCallGoFunctionWithIndex(100, false),
   193  			sig: &ssa.Signature{
   194  				Params:  []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeF64},
   195  				Results: []ssa.Type{ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64},
   196  			},
   197  			needModuleContextPtr: true,
   198  			exp: `
   199  	stp x30, xzr, [sp, #-0x10]!
   200  	sub x27, sp, #0x30
   201  	ldr x11, [x0, #0x28]
   202  	subs xzr, x27, x11
   203  	b.ge #0x14
   204  	orr x27, xzr, #0x30
   205  	str x27, [x0, #0x40]
   206  	ldr x27, [x0, #0x50]
   207  	bl x27
   208  	str x19, [x0, #0x60]
   209  	str x20, [x0, #0x70]
   210  	str x21, [x0, #0x80]
   211  	str x22, [x0, #0x90]
   212  	str x23, [x0, #0xa0]
   213  	str x24, [x0, #0xb0]
   214  	str x25, [x0, #0xc0]
   215  	str x26, [x0, #0xd0]
   216  	str x28, [x0, #0xe0]
   217  	str q18, [x0, #0xf0]
   218  	str q19, [x0, #0x100]
   219  	str q20, [x0, #0x110]
   220  	str q21, [x0, #0x120]
   221  	str q22, [x0, #0x130]
   222  	str q23, [x0, #0x140]
   223  	str q24, [x0, #0x150]
   224  	str q25, [x0, #0x160]
   225  	str q26, [x0, #0x170]
   226  	str q27, [x0, #0x180]
   227  	str q28, [x0, #0x190]
   228  	str q29, [x0, #0x1a0]
   229  	str q30, [x0, #0x1b0]
   230  	str q31, [x0, #0x1c0]
   231  	str x1, [x0, #0x460]
   232  	sub sp, sp, #0x20
   233  	mov x15, sp
   234  	str d0, [x15], #0x8
   235  	orr x27, xzr, #0x20
   236  	orr x16, xzr, #0x4
   237  	stp x27, x16, [sp, #-0x10]!
   238  	movz w17, #0x6406, lsl 0
   239  	str w17, [x0]
   240  	mov x27, sp
   241  	str x27, [x0, #0x38]
   242  	adr x27, #0x20
   243  	str x27, [x0, #0x30]
   244  	exit_sequence x0
   245  	ldr x19, [x0, #0x60]
   246  	ldr x20, [x0, #0x70]
   247  	ldr x21, [x0, #0x80]
   248  	ldr x22, [x0, #0x90]
   249  	ldr x23, [x0, #0xa0]
   250  	ldr x24, [x0, #0xb0]
   251  	ldr x25, [x0, #0xc0]
   252  	ldr x26, [x0, #0xd0]
   253  	ldr x28, [x0, #0xe0]
   254  	ldr q18, [x0, #0xf0]
   255  	ldr q19, [x0, #0x100]
   256  	ldr q20, [x0, #0x110]
   257  	ldr q21, [x0, #0x120]
   258  	ldr q22, [x0, #0x130]
   259  	ldr q23, [x0, #0x140]
   260  	ldr q24, [x0, #0x150]
   261  	ldr q25, [x0, #0x160]
   262  	ldr q26, [x0, #0x170]
   263  	ldr q27, [x0, #0x180]
   264  	ldr q28, [x0, #0x190]
   265  	ldr q29, [x0, #0x1a0]
   266  	ldr q30, [x0, #0x1b0]
   267  	ldr q31, [x0, #0x1c0]
   268  	add x15, sp, #0x10
   269  	add sp, sp, #0x30
   270  	ldr x30, [sp], #0x10
   271  	ldr w0, [x15], #0x8
   272  	ldr x1, [x15], #0x8
   273  	ldr s0, [x15], #0x8
   274  	ldr d1, [x15], #0x8
   275  	ret
   276  `,
   277  		},
   278  		{
   279  			name:     "go call",
   280  			exitCode: wazevoapi.ExitCodeCallGoFunctionWithIndex(100, false),
   281  			sig: &ssa.Signature{
   282  				Params:  []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeF64, ssa.TypeF64, ssa.TypeI32, ssa.TypeI32},
   283  				Results: []ssa.Type{},
   284  			},
   285  			needModuleContextPtr: true,
   286  			exp: `
   287  	stp x30, xzr, [sp, #-0x10]!
   288  	sub x27, sp, #0x30
   289  	ldr x11, [x0, #0x28]
   290  	subs xzr, x27, x11
   291  	b.ge #0x14
   292  	orr x27, xzr, #0x30
   293  	str x27, [x0, #0x40]
   294  	ldr x27, [x0, #0x50]
   295  	bl x27
   296  	str x19, [x0, #0x60]
   297  	str x20, [x0, #0x70]
   298  	str x21, [x0, #0x80]
   299  	str x22, [x0, #0x90]
   300  	str x23, [x0, #0xa0]
   301  	str x24, [x0, #0xb0]
   302  	str x25, [x0, #0xc0]
   303  	str x26, [x0, #0xd0]
   304  	str x28, [x0, #0xe0]
   305  	str q18, [x0, #0xf0]
   306  	str q19, [x0, #0x100]
   307  	str q20, [x0, #0x110]
   308  	str q21, [x0, #0x120]
   309  	str q22, [x0, #0x130]
   310  	str q23, [x0, #0x140]
   311  	str q24, [x0, #0x150]
   312  	str q25, [x0, #0x160]
   313  	str q26, [x0, #0x170]
   314  	str q27, [x0, #0x180]
   315  	str q28, [x0, #0x190]
   316  	str q29, [x0, #0x1a0]
   317  	str q30, [x0, #0x1b0]
   318  	str q31, [x0, #0x1c0]
   319  	str x1, [x0, #0x460]
   320  	sub sp, sp, #0x20
   321  	mov x15, sp
   322  	str d0, [x15], #0x8
   323  	str d1, [x15], #0x8
   324  	str x2, [x15], #0x8
   325  	str x3, [x15], #0x8
   326  	orr x27, xzr, #0x20
   327  	orr x16, xzr, #0x4
   328  	stp x27, x16, [sp, #-0x10]!
   329  	movz w17, #0x6406, lsl 0
   330  	str w17, [x0]
   331  	mov x27, sp
   332  	str x27, [x0, #0x38]
   333  	adr x27, #0x20
   334  	str x27, [x0, #0x30]
   335  	exit_sequence x0
   336  	ldr x19, [x0, #0x60]
   337  	ldr x20, [x0, #0x70]
   338  	ldr x21, [x0, #0x80]
   339  	ldr x22, [x0, #0x90]
   340  	ldr x23, [x0, #0xa0]
   341  	ldr x24, [x0, #0xb0]
   342  	ldr x25, [x0, #0xc0]
   343  	ldr x26, [x0, #0xd0]
   344  	ldr x28, [x0, #0xe0]
   345  	ldr q18, [x0, #0xf0]
   346  	ldr q19, [x0, #0x100]
   347  	ldr q20, [x0, #0x110]
   348  	ldr q21, [x0, #0x120]
   349  	ldr q22, [x0, #0x130]
   350  	ldr q23, [x0, #0x140]
   351  	ldr q24, [x0, #0x150]
   352  	ldr q25, [x0, #0x160]
   353  	ldr q26, [x0, #0x170]
   354  	ldr q27, [x0, #0x180]
   355  	ldr q28, [x0, #0x190]
   356  	ldr q29, [x0, #0x1a0]
   357  	ldr q30, [x0, #0x1b0]
   358  	ldr q31, [x0, #0x1c0]
   359  	add sp, sp, #0x30
   360  	ldr x30, [sp], #0x10
   361  	ret
   362  `,
   363  		},
   364  		{
   365  			name:     "grow memory",
   366  			exitCode: wazevoapi.ExitCodeGrowMemory,
   367  			sig: &ssa.Signature{
   368  				Params:  []ssa.Type{ssa.TypeI32, ssa.TypeI32},
   369  				Results: []ssa.Type{ssa.TypeI32},
   370  			},
   371  			exp: `
   372  	stp x30, xzr, [sp, #-0x10]!
   373  	sub x27, sp, #0x20
   374  	ldr x11, [x0, #0x28]
   375  	subs xzr, x27, x11
   376  	b.ge #0x14
   377  	orr x27, xzr, #0x20
   378  	str x27, [x0, #0x40]
   379  	ldr x27, [x0, #0x50]
   380  	bl x27
   381  	str x19, [x0, #0x60]
   382  	str x20, [x0, #0x70]
   383  	str x21, [x0, #0x80]
   384  	str x22, [x0, #0x90]
   385  	str x23, [x0, #0xa0]
   386  	str x24, [x0, #0xb0]
   387  	str x25, [x0, #0xc0]
   388  	str x26, [x0, #0xd0]
   389  	str x28, [x0, #0xe0]
   390  	str q18, [x0, #0xf0]
   391  	str q19, [x0, #0x100]
   392  	str q20, [x0, #0x110]
   393  	str q21, [x0, #0x120]
   394  	str q22, [x0, #0x130]
   395  	str q23, [x0, #0x140]
   396  	str q24, [x0, #0x150]
   397  	str q25, [x0, #0x160]
   398  	str q26, [x0, #0x170]
   399  	str q27, [x0, #0x180]
   400  	str q28, [x0, #0x190]
   401  	str q29, [x0, #0x1a0]
   402  	str q30, [x0, #0x1b0]
   403  	str q31, [x0, #0x1c0]
   404  	sub sp, sp, #0x10
   405  	mov x15, sp
   406  	str x1, [x15], #0x8
   407  	orr x27, xzr, #0x10
   408  	orr x16, xzr, #0x1
   409  	stp x27, x16, [sp, #-0x10]!
   410  	orr w17, wzr, #0x2
   411  	str w17, [x0]
   412  	mov x27, sp
   413  	str x27, [x0, #0x38]
   414  	adr x27, #0x20
   415  	str x27, [x0, #0x30]
   416  	exit_sequence x0
   417  	ldr x19, [x0, #0x60]
   418  	ldr x20, [x0, #0x70]
   419  	ldr x21, [x0, #0x80]
   420  	ldr x22, [x0, #0x90]
   421  	ldr x23, [x0, #0xa0]
   422  	ldr x24, [x0, #0xb0]
   423  	ldr x25, [x0, #0xc0]
   424  	ldr x26, [x0, #0xd0]
   425  	ldr x28, [x0, #0xe0]
   426  	ldr q18, [x0, #0xf0]
   427  	ldr q19, [x0, #0x100]
   428  	ldr q20, [x0, #0x110]
   429  	ldr q21, [x0, #0x120]
   430  	ldr q22, [x0, #0x130]
   431  	ldr q23, [x0, #0x140]
   432  	ldr q24, [x0, #0x150]
   433  	ldr q25, [x0, #0x160]
   434  	ldr q26, [x0, #0x170]
   435  	ldr q27, [x0, #0x180]
   436  	ldr q28, [x0, #0x190]
   437  	ldr q29, [x0, #0x1a0]
   438  	ldr q30, [x0, #0x1b0]
   439  	ldr q31, [x0, #0x1c0]
   440  	add x15, sp, #0x10
   441  	add sp, sp, #0x20
   442  	ldr x30, [sp], #0x10
   443  	ldr w0, [x15], #0x8
   444  	ret
   445  `,
   446  		},
   447  	} {
   448  		t.Run(tc.name, func(t *testing.T) {
   449  			_, _, m := newSetupWithMockContext()
   450  			m.CompileGoFunctionTrampoline(tc.exitCode, tc.sig, tc.needModuleContextPtr)
   451  
   452  			require.Equal(t, tc.exp, m.Format())
   453  
   454  			err := m.Encode(context.Background())
   455  			require.NoError(t, err)
   456  		})
   457  	}
   458  }
   459  
   460  func Test_goFunctionCallLoadStackArg(t *testing.T) {
   461  	originalArg0Reg := x17VReg
   462  	intVReg := x11VReg
   463  	floatVReg := v11VReg
   464  	for _, tc := range []struct {
   465  		name         string
   466  		arg          *backend.ABIArg
   467  		expResultReg regalloc.VReg
   468  		exp          string
   469  	}{
   470  		{
   471  			name:         "i32",
   472  			arg:          &backend.ABIArg{Type: ssa.TypeI32},
   473  			expResultReg: x11VReg,
   474  			exp: `
   475  	ldr w11, [x17], #0x8
   476  `,
   477  		},
   478  		{
   479  			name:         "i64",
   480  			arg:          &backend.ABIArg{Type: ssa.TypeI64},
   481  			expResultReg: x11VReg,
   482  			exp: `
   483  	ldr x11, [x17], #0x8
   484  `,
   485  		},
   486  		{
   487  			name:         "f32",
   488  			arg:          &backend.ABIArg{Type: ssa.TypeF32},
   489  			expResultReg: v11VReg,
   490  			exp: `
   491  	ldr s11, [x17], #0x8
   492  `,
   493  		},
   494  		{
   495  			name:         "f64",
   496  			arg:          &backend.ABIArg{Type: ssa.TypeF64},
   497  			expResultReg: v11VReg,
   498  			exp: `
   499  	ldr d11, [x17], #0x8
   500  `,
   501  		},
   502  		{
   503  			name:         "v128",
   504  			arg:          &backend.ABIArg{Type: ssa.TypeV128},
   505  			expResultReg: v11VReg,
   506  			exp: `
   507  	ldr q11, [x17], #0x10
   508  `,
   509  		},
   510  	} {
   511  		tc := tc
   512  		t.Run(tc.name, func(t *testing.T) {
   513  			t.Run(tc.name, func(t *testing.T) {
   514  				_, _, m := newSetupWithMockContext()
   515  
   516  				nop := m.allocateNop()
   517  				_, result := m.goFunctionCallLoadStackArg(nop, originalArg0Reg, tc.arg, intVReg, floatVReg)
   518  				require.Equal(t, tc.expResultReg, result)
   519  
   520  				m.executableContext.RootInstr = nop
   521  
   522  				require.Equal(t, tc.exp, m.Format())
   523  				err := m.Encode(context.Background())
   524  				require.NoError(t, err)
   525  			})
   526  		})
   527  	}
   528  }
   529  
   530  func Test_goFunctionCallStoreStackResult(t *testing.T) {
   531  	for _, tc := range []struct {
   532  		name      string
   533  		result    *backend.ABIArg
   534  		resultReg regalloc.VReg
   535  		exp       string
   536  	}{
   537  		{
   538  			name:      "i32",
   539  			result:    &backend.ABIArg{Offset: 16 * 3, Type: ssa.TypeI32},
   540  			resultReg: x11VReg,
   541  			exp: `
   542  	str w11, [sp], #0x8
   543  `,
   544  		},
   545  		{
   546  			name:      "i64",
   547  			result:    &backend.ABIArg{Offset: 16 * 3, Type: ssa.TypeI64},
   548  			resultReg: x11VReg,
   549  			exp: `
   550  	str x11, [sp], #0x8
   551  `,
   552  		},
   553  		{
   554  			name:      "f32",
   555  			result:    &backend.ABIArg{Offset: 16 * 3, Type: ssa.TypeF32},
   556  			resultReg: v11VReg,
   557  			exp: `
   558  	str s11, [sp], #0x8
   559  `,
   560  		},
   561  		{
   562  			name:      "f64",
   563  			result:    &backend.ABIArg{Offset: 16 * 3, Type: ssa.TypeF64},
   564  			resultReg: v11VReg,
   565  			exp: `
   566  	str d11, [sp], #0x8
   567  `,
   568  		},
   569  		{
   570  			name:      "v128",
   571  			result:    &backend.ABIArg{Offset: 16 * 3, Type: ssa.TypeV128},
   572  			resultReg: v11VReg,
   573  			exp: `
   574  	str q11, [sp], #0x10
   575  `,
   576  		},
   577  	} {
   578  		tc := tc
   579  		t.Run(tc.name, func(t *testing.T) {
   580  			t.Run(tc.name, func(t *testing.T) {
   581  				_, _, m := newSetupWithMockContext()
   582  				m.currentABI = &backend.FunctionABI{ArgStackSize: 8}
   583  
   584  				nop := m.allocateNop()
   585  				m.goFunctionCallStoreStackResult(nop, spVReg, tc.result, tc.resultReg)
   586  
   587  				m.executableContext.RootInstr = nop
   588  
   589  				require.Equal(t, tc.exp, m.Format())
   590  				err := m.Encode(context.Background())
   591  				require.NoError(t, err)
   592  			})
   593  		})
   594  	}
   595  }