github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/engine/wazevo/backend/isa/arm64/abi_entry_preamble_test.go (about)

     1  package arm64
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/wasilibs/wazerox/internal/engine/wazevo/backend"
     7  	"github.com/wasilibs/wazerox/internal/engine/wazevo/ssa"
     8  	"github.com/wasilibs/wazerox/internal/testing/require"
     9  )
    10  
    11  func TestAbiImpl_constructEntryPreamble(t *testing.T) {
    12  	const i32, f32, i64, f64, v128 = ssa.TypeI32, ssa.TypeF32, ssa.TypeI64, ssa.TypeF64, ssa.TypeV128
    13  
    14  	for _, tc := range []struct {
    15  		name string
    16  		sig  *ssa.Signature
    17  		exp  string
    18  	}{
    19  		{
    20  			name: "empty",
    21  			sig:  &ssa.Signature{},
    22  			exp: `
    23  	mov x20, x0
    24  	str x29, [x20, #0x10]
    25  	mov x27, sp
    26  	str x27, [x20, #0x18]
    27  	str x30, [x20, #0x20]
    28  	mov sp, x26
    29  	bl x24
    30  	ldr x29, [x20, #0x10]
    31  	ldr x27, [x20, #0x18]
    32  	mov sp, x27
    33  	ldr x30, [x20, #0x20]
    34  	ret
    35  `,
    36  		},
    37  		{
    38  			name: "float reg params",
    39  			sig: &ssa.Signature{
    40  				Params: []ssa.Type{
    41  					i64, i64, // first and second will be skipped.
    42  					f32, f32, f32, f32, f64,
    43  				},
    44  			},
    45  			exp: `
    46  	mov x20, x0
    47  	str x29, [x20, #0x10]
    48  	mov x27, sp
    49  	str x27, [x20, #0x18]
    50  	str x30, [x20, #0x20]
    51  	mov sp, x26
    52  	ldr s0, [x19], #0x8
    53  	ldr s1, [x19], #0x8
    54  	ldr s2, [x19], #0x8
    55  	ldr s3, [x19], #0x8
    56  	ldr d4, [x19], #0x8
    57  	bl x24
    58  	ldr x29, [x20, #0x10]
    59  	ldr x27, [x20, #0x18]
    60  	mov sp, x27
    61  	ldr x30, [x20, #0x20]
    62  	ret
    63  `,
    64  		},
    65  		{
    66  			name: "int reg params",
    67  			sig: &ssa.Signature{
    68  				Params: []ssa.Type{
    69  					i64, i64, // first and second will be skipped.
    70  					i32, i32, i32, i64, i32,
    71  				},
    72  			},
    73  			exp: `
    74  	mov x20, x0
    75  	str x29, [x20, #0x10]
    76  	mov x27, sp
    77  	str x27, [x20, #0x18]
    78  	str x30, [x20, #0x20]
    79  	mov sp, x26
    80  	ldr w2, [x19], #0x8
    81  	ldr w3, [x19], #0x8
    82  	ldr w4, [x19], #0x8
    83  	ldr x5, [x19], #0x8
    84  	ldr w6, [x19], #0x8
    85  	bl x24
    86  	ldr x29, [x20, #0x10]
    87  	ldr x27, [x20, #0x18]
    88  	mov sp, x27
    89  	ldr x30, [x20, #0x20]
    90  	ret
    91  `,
    92  		},
    93  		{
    94  			name: "int/float reg params interleaved",
    95  			sig: &ssa.Signature{
    96  				Params: []ssa.Type{
    97  					i64, i64, // first and second will be skipped.
    98  					i32, f64, i32, f32, i64, i32, i64, f64, i32, f32, v128, f32,
    99  				},
   100  			},
   101  			exp: `
   102  	mov x20, x0
   103  	str x29, [x20, #0x10]
   104  	mov x27, sp
   105  	str x27, [x20, #0x18]
   106  	str x30, [x20, #0x20]
   107  	mov sp, x26
   108  	ldr w2, [x19], #0x8
   109  	ldr d0, [x19], #0x8
   110  	ldr w3, [x19], #0x8
   111  	ldr s1, [x19], #0x8
   112  	ldr x4, [x19], #0x8
   113  	ldr w5, [x19], #0x8
   114  	ldr x6, [x19], #0x8
   115  	ldr d2, [x19], #0x8
   116  	ldr w7, [x19], #0x8
   117  	ldr s3, [x19], #0x8
   118  	ldr q4, [x19], #0x10
   119  	ldr s5, [x19], #0x8
   120  	bl x24
   121  	ldr x29, [x20, #0x10]
   122  	ldr x27, [x20, #0x18]
   123  	mov sp, x27
   124  	ldr x30, [x20, #0x20]
   125  	ret
   126  `,
   127  		},
   128  		{
   129  			name: "int/float reg params/results interleaved",
   130  			sig: &ssa.Signature{
   131  				Params: []ssa.Type{
   132  					i64, i64, // first and second will be skipped.
   133  					i32, f64, i32, f32, i64,
   134  				},
   135  				Results: []ssa.Type{f32, f64, i32, f32, i64, i32, f64},
   136  			},
   137  			exp: `
   138  	mov x20, x0
   139  	str x29, [x20, #0x10]
   140  	mov x27, sp
   141  	str x27, [x20, #0x18]
   142  	str x30, [x20, #0x20]
   143  	mov sp, x26
   144  	mov x25, x19
   145  	ldr w2, [x25], #0x8
   146  	ldr d0, [x25], #0x8
   147  	ldr w3, [x25], #0x8
   148  	ldr s1, [x25], #0x8
   149  	ldr x4, [x25], #0x8
   150  	bl x24
   151  	str s0, [x19], #0x8
   152  	str d1, [x19], #0x8
   153  	str w0, [x19], #0x8
   154  	str s2, [x19], #0x8
   155  	str x1, [x19], #0x8
   156  	str w2, [x19], #0x8
   157  	str d3, [x19], #0x8
   158  	ldr x29, [x20, #0x10]
   159  	ldr x27, [x20, #0x18]
   160  	mov sp, x27
   161  	ldr x30, [x20, #0x20]
   162  	ret
   163  `,
   164  		},
   165  		{
   166  			name: "many results",
   167  			sig: &ssa.Signature{
   168  				Results: []ssa.Type{
   169  					f32, f64, i32, f32, i64, i32, i32, i64, i32, i64,
   170  					f32, f64, i32, f32, i64, i32, i32, i64, i32, i64,
   171  					f32, f64, f64, f32, f64, v128, v128,
   172  				},
   173  			},
   174  			exp: `
   175  	mov x20, x0
   176  	str x29, [x20, #0x10]
   177  	mov x27, sp
   178  	str x27, [x20, #0x18]
   179  	str x30, [x20, #0x20]
   180  	mov sp, x26
   181  	bl x24
   182  	str s0, [x19], #0x8
   183  	str d1, [x19], #0x8
   184  	str w0, [x19], #0x8
   185  	str s2, [x19], #0x8
   186  	str x1, [x19], #0x8
   187  	str w2, [x19], #0x8
   188  	str w3, [x19], #0x8
   189  	str x4, [x19], #0x8
   190  	str w5, [x19], #0x8
   191  	str x6, [x19], #0x8
   192  	str s3, [x19], #0x8
   193  	str d4, [x19], #0x8
   194  	str w7, [x19], #0x8
   195  	str s5, [x19], #0x8
   196  	ldr x15, [sp, #-0x70]
   197  	str x15, [x19], #0x8
   198  	ldr w15, [sp, #-0x68]
   199  	str w15, [x19], #0x8
   200  	ldr w15, [sp, #-0x60]
   201  	str w15, [x19], #0x8
   202  	ldr x15, [sp, #-0x58]
   203  	str x15, [x19], #0x8
   204  	ldr w15, [sp, #-0x50]
   205  	str w15, [x19], #0x8
   206  	ldr x15, [sp, #-0x48]
   207  	str x15, [x19], #0x8
   208  	str s6, [x19], #0x8
   209  	str d7, [x19], #0x8
   210  	ldr d15, [sp, #-0x40]
   211  	str d15, [x19], #0x8
   212  	ldr s15, [sp, #-0x38]
   213  	str s15, [x19], #0x8
   214  	ldr d15, [sp, #-0x30]
   215  	str d15, [x19], #0x8
   216  	ldr q15, [sp, #-0x28]
   217  	str q15, [x19], #0x10
   218  	ldr q15, [sp, #-0x18]
   219  	str q15, [x19], #0x10
   220  	ldr x29, [x20, #0x10]
   221  	ldr x27, [x20, #0x18]
   222  	mov sp, x27
   223  	ldr x30, [x20, #0x20]
   224  	ret
   225  `,
   226  		},
   227  		{
   228  			name: "many params",
   229  			sig: &ssa.Signature{
   230  				Params: []ssa.Type{
   231  					i32, i32, v128, v128, v128, i64, i32, i32, i64, i32, i64,
   232  					f32, f64, i32, f32, i64, i32, i32, i64, i32, i64,
   233  					f32, f64, f64, f32, f64, v128, v128, v128, v128, v128,
   234  				},
   235  			},
   236  			exp: `
   237  	mov x20, x0
   238  	str x29, [x20, #0x10]
   239  	mov x27, sp
   240  	str x27, [x20, #0x18]
   241  	str x30, [x20, #0x20]
   242  	mov sp, x26
   243  	ldr q0, [x19], #0x10
   244  	ldr q1, [x19], #0x10
   245  	ldr q2, [x19], #0x10
   246  	ldr x2, [x19], #0x8
   247  	ldr w3, [x19], #0x8
   248  	ldr w4, [x19], #0x8
   249  	ldr x5, [x19], #0x8
   250  	ldr w6, [x19], #0x8
   251  	ldr x7, [x19], #0x8
   252  	ldr s3, [x19], #0x8
   253  	ldr d4, [x19], #0x8
   254  	ldr w15, [x19], #0x8
   255  	str w15, [sp, #-0xa0]
   256  	ldr s5, [x19], #0x8
   257  	ldr x15, [x19], #0x8
   258  	str x15, [sp, #-0x98]
   259  	ldr w15, [x19], #0x8
   260  	str w15, [sp, #-0x90]
   261  	ldr w15, [x19], #0x8
   262  	str w15, [sp, #-0x88]
   263  	ldr x15, [x19], #0x8
   264  	str x15, [sp, #-0x80]
   265  	ldr w15, [x19], #0x8
   266  	str w15, [sp, #-0x78]
   267  	ldr x15, [x19], #0x8
   268  	str x15, [sp, #-0x70]
   269  	ldr s6, [x19], #0x8
   270  	ldr d7, [x19], #0x8
   271  	ldr d15, [x19], #0x8
   272  	str d15, [sp, #-0x68]
   273  	ldr s15, [x19], #0x8
   274  	str s15, [sp, #-0x60]
   275  	ldr d15, [x19], #0x8
   276  	str d15, [sp, #-0x58]
   277  	ldr q15, [x19], #0x10
   278  	str q15, [sp, #-0x50]
   279  	ldr q15, [x19], #0x10
   280  	str q15, [sp, #-0x40]
   281  	ldr q15, [x19], #0x10
   282  	str q15, [sp, #-0x30]
   283  	ldr q15, [x19], #0x10
   284  	str q15, [sp, #-0x20]
   285  	ldr q15, [x19], #0x10
   286  	str q15, [sp, #-0x10]
   287  	bl x24
   288  	ldr x29, [x20, #0x10]
   289  	ldr x27, [x20, #0x18]
   290  	mov sp, x27
   291  	ldr x30, [x20, #0x20]
   292  	ret
   293  `,
   294  		},
   295  		{
   296  			name: "many params and results",
   297  			sig: &ssa.Signature{
   298  				Params: []ssa.Type{
   299  					i32, i32, v128, v128, v128, i64, i32, i32, i64, i32, i64,
   300  					f32, f64, i32, f32, i64, i32, i32, i64, i32, i64,
   301  					f32, f64, f64, f32, f64, v128, v128, v128, v128, v128,
   302  				},
   303  				Results: []ssa.Type{
   304  					f32, f64, i32, f32, i64, i32, i32, i64, i32, i64,
   305  					i32, i32, v128, v128, v128, i64, i32, i32, i64, i32, i64,
   306  				},
   307  			},
   308  			exp: `
   309  	mov x20, x0
   310  	str x29, [x20, #0x10]
   311  	mov x27, sp
   312  	str x27, [x20, #0x18]
   313  	str x30, [x20, #0x20]
   314  	mov sp, x26
   315  	mov x25, x19
   316  	ldr q0, [x25], #0x10
   317  	ldr q1, [x25], #0x10
   318  	ldr q2, [x25], #0x10
   319  	ldr x2, [x25], #0x8
   320  	ldr w3, [x25], #0x8
   321  	ldr w4, [x25], #0x8
   322  	ldr x5, [x25], #0x8
   323  	ldr w6, [x25], #0x8
   324  	ldr x7, [x25], #0x8
   325  	ldr s3, [x25], #0x8
   326  	ldr d4, [x25], #0x8
   327  	ldr w15, [x25], #0x8
   328  	str w15, [sp, #-0xe0]
   329  	ldr s5, [x25], #0x8
   330  	ldr x15, [x25], #0x8
   331  	str x15, [sp, #-0xd8]
   332  	ldr w15, [x25], #0x8
   333  	str w15, [sp, #-0xd0]
   334  	ldr w15, [x25], #0x8
   335  	str w15, [sp, #-0xc8]
   336  	ldr x15, [x25], #0x8
   337  	str x15, [sp, #-0xc0]
   338  	ldr w15, [x25], #0x8
   339  	str w15, [sp, #-0xb8]
   340  	ldr x15, [x25], #0x8
   341  	str x15, [sp, #-0xb0]
   342  	ldr s6, [x25], #0x8
   343  	ldr d7, [x25], #0x8
   344  	ldr d15, [x25], #0x8
   345  	str d15, [sp, #-0xa8]
   346  	ldr s15, [x25], #0x8
   347  	str s15, [sp, #-0xa0]
   348  	ldr d15, [x25], #0x8
   349  	str d15, [sp, #-0x98]
   350  	ldr q15, [x25], #0x10
   351  	str q15, [sp, #-0x90]
   352  	ldr q15, [x25], #0x10
   353  	str q15, [sp, #-0x80]
   354  	ldr q15, [x25], #0x10
   355  	str q15, [sp, #-0x70]
   356  	ldr q15, [x25], #0x10
   357  	str q15, [sp, #-0x60]
   358  	ldr q15, [x25], #0x10
   359  	str q15, [sp, #-0x50]
   360  	bl x24
   361  	str s0, [x19], #0x8
   362  	str d1, [x19], #0x8
   363  	str w0, [x19], #0x8
   364  	str s2, [x19], #0x8
   365  	str x1, [x19], #0x8
   366  	str w2, [x19], #0x8
   367  	str w3, [x19], #0x8
   368  	str x4, [x19], #0x8
   369  	str w5, [x19], #0x8
   370  	str x6, [x19], #0x8
   371  	str w7, [x19], #0x8
   372  	ldr w15, [sp, #-0x40]
   373  	str w15, [x19], #0x8
   374  	str q3, [x19], #0x10
   375  	str q4, [x19], #0x10
   376  	str q5, [x19], #0x10
   377  	ldr x15, [sp, #-0x38]
   378  	str x15, [x19], #0x8
   379  	ldr w15, [sp, #-0x30]
   380  	str w15, [x19], #0x8
   381  	ldr w15, [sp, #-0x28]
   382  	str w15, [x19], #0x8
   383  	ldr x15, [sp, #-0x20]
   384  	str x15, [x19], #0x8
   385  	ldr w15, [sp, #-0x18]
   386  	str w15, [x19], #0x8
   387  	ldr x15, [sp, #-0x10]
   388  	str x15, [x19], #0x8
   389  	ldr x29, [x20, #0x10]
   390  	ldr x27, [x20, #0x18]
   391  	mov sp, x27
   392  	ldr x30, [x20, #0x20]
   393  	ret
   394  `,
   395  		},
   396  	} {
   397  		t.Run(tc.name, func(t *testing.T) {
   398  			_, _, m := newSetupWithMockContext()
   399  			abi := m.getOrCreateABIImpl(tc.sig)
   400  			m.rootInstr = abi.constructEntryPreamble()
   401  			require.Equal(t, tc.exp, m.Format())
   402  		})
   403  	}
   404  }
   405  
   406  func TestMachine_goEntryPreamblePassArg(t *testing.T) {
   407  	paramSlicePtr := x16VReg
   408  	for _, tc := range []struct {
   409  		arg                      backend.ABIArg
   410  		argSlotBeginOffsetFromSP int64
   411  		exp                      string
   412  	}{
   413  		// Reg kinds.
   414  		{
   415  			arg: backend.ABIArg{Type: ssa.TypeI32, Reg: x0VReg, Kind: backend.ABIArgKindReg},
   416  			exp: `
   417  	ldr w0, [x16], #0x8
   418  `,
   419  		},
   420  		{
   421  			arg: backend.ABIArg{Type: ssa.TypeI64, Reg: x0VReg, Kind: backend.ABIArgKindReg},
   422  			exp: `
   423  	ldr x0, [x16], #0x8
   424  `,
   425  		},
   426  		{
   427  			arg: backend.ABIArg{Type: ssa.TypeF32, Reg: v11VReg, Kind: backend.ABIArgKindReg},
   428  			exp: `
   429  	ldr s11, [x16], #0x8
   430  `,
   431  		},
   432  		{
   433  			arg: backend.ABIArg{Type: ssa.TypeF64, Reg: v12VReg, Kind: backend.ABIArgKindReg},
   434  			exp: `
   435  	ldr d12, [x16], #0x8
   436  `,
   437  		},
   438  		{
   439  			arg: backend.ABIArg{Type: ssa.TypeV128, Reg: v12VReg, Kind: backend.ABIArgKindReg},
   440  			exp: `
   441  	ldr q12, [x16], #0x10
   442  `,
   443  		},
   444  		{
   445  			arg: backend.ABIArg{Type: ssa.TypeV128, Reg: v12VReg, Kind: backend.ABIArgKindReg},
   446  			exp: `
   447  	ldr q12, [x16], #0x10
   448  `,
   449  		},
   450  		// Stack kinds.
   451  		{
   452  			arg: backend.ABIArg{Type: ssa.TypeI32, Offset: 0, Kind: backend.ABIArgKindStack},
   453  			exp: `
   454  	ldr w15, [x16], #0x8
   455  	str w15, [sp]
   456  `,
   457  		},
   458  		{
   459  			arg: backend.ABIArg{Type: ssa.TypeI32, Offset: 8, Kind: backend.ABIArgKindStack},
   460  			exp: `
   461  	ldr w15, [x16], #0x8
   462  	str w15, [sp, #0x8]
   463  `,
   464  		},
   465  		{
   466  			arg: backend.ABIArg{Type: ssa.TypeI64, Offset: 0, Kind: backend.ABIArgKindStack},
   467  			exp: `
   468  	ldr x15, [x16], #0x8
   469  	str x15, [sp]
   470  `,
   471  		},
   472  		{
   473  			arg: backend.ABIArg{Type: ssa.TypeI64, Offset: 128, Kind: backend.ABIArgKindStack},
   474  			exp: `
   475  	ldr x15, [x16], #0x8
   476  	str x15, [sp, #0x80]
   477  `,
   478  		},
   479  		{
   480  			arg: backend.ABIArg{Type: ssa.TypeF32, Offset: 64, Kind: backend.ABIArgKindStack},
   481  			exp: `
   482  	ldr s15, [x16], #0x8
   483  	str s15, [sp, #0x40]
   484  `,
   485  		},
   486  		{
   487  			arg: backend.ABIArg{Type: ssa.TypeF32, Offset: 2056, Kind: backend.ABIArgKindStack},
   488  			exp: `
   489  	ldr s15, [x16], #0x8
   490  	str s15, [sp, #0x808]
   491  `,
   492  		},
   493  		{
   494  			arg: backend.ABIArg{Type: ssa.TypeF64, Offset: 64, Kind: backend.ABIArgKindStack},
   495  			exp: `
   496  	ldr d15, [x16], #0x8
   497  	str d15, [sp, #0x40]
   498  `,
   499  		},
   500  		{
   501  			arg: backend.ABIArg{Type: ssa.TypeF64, Offset: 2056, Kind: backend.ABIArgKindStack},
   502  			exp: `
   503  	ldr d15, [x16], #0x8
   504  	str d15, [sp, #0x808]
   505  `,
   506  		},
   507  		{
   508  			arg: backend.ABIArg{Type: ssa.TypeV128, Offset: 64, Kind: backend.ABIArgKindStack},
   509  			exp: `
   510  	ldr q15, [x16], #0x10
   511  	str q15, [sp, #0x40]
   512  `,
   513  		},
   514  		{
   515  			arg: backend.ABIArg{Type: ssa.TypeV128, Offset: 2056, Kind: backend.ABIArgKindStack},
   516  			exp: `
   517  	ldr q15, [x16], #0x10
   518  	movz x27, #0x808, lsl 0
   519  	str q15, [sp, x27]
   520  `,
   521  		},
   522  		{
   523  			arg:                      backend.ABIArg{Type: ssa.TypeV128, Offset: 1024, Kind: backend.ABIArgKindStack},
   524  			argSlotBeginOffsetFromSP: -1648,
   525  			exp: `
   526  	ldr q15, [x16], #0x10
   527  	movn x27, #0x26f, lsl 0
   528  	str q15, [sp, x27]
   529  `,
   530  		},
   531  	} {
   532  		t.Run(tc.exp, func(t *testing.T) {
   533  			_, _, m := newSetupWithMockContext()
   534  			cur := m.allocateNop()
   535  			m.rootInstr = cur
   536  			m.goEntryPreamblePassArg(cur, paramSlicePtr, &tc.arg, tc.argSlotBeginOffsetFromSP)
   537  			require.Equal(t, tc.exp, m.Format())
   538  			m.Encode()
   539  		})
   540  	}
   541  }
   542  
   543  func TestMachine_goEntryPreamblePassResult(t *testing.T) {
   544  	paramSlicePtr := x16VReg
   545  	for _, tc := range []struct {
   546  		arg      backend.ABIArg
   547  		retStart int64
   548  		exp      string
   549  	}{
   550  		// Reg kinds.
   551  		{
   552  			arg: backend.ABIArg{Type: ssa.TypeI32, Reg: x0VReg, Kind: backend.ABIArgKindReg},
   553  			exp: `
   554  	str w0, [x16], #0x8
   555  `,
   556  		},
   557  		{
   558  			arg: backend.ABIArg{Type: ssa.TypeI64, Reg: x0VReg, Kind: backend.ABIArgKindReg},
   559  			exp: `
   560  	str x0, [x16], #0x8
   561  `,
   562  		},
   563  		{
   564  			arg: backend.ABIArg{Type: ssa.TypeF32, Reg: v11VReg, Kind: backend.ABIArgKindReg},
   565  			exp: `
   566  	str s11, [x16], #0x8
   567  `,
   568  		},
   569  		{
   570  			arg: backend.ABIArg{Type: ssa.TypeF64, Reg: v12VReg, Kind: backend.ABIArgKindReg},
   571  			exp: `
   572  	str d12, [x16], #0x8
   573  `,
   574  		},
   575  		{
   576  			arg: backend.ABIArg{Type: ssa.TypeV128, Reg: v12VReg, Kind: backend.ABIArgKindReg},
   577  			exp: `
   578  	str q12, [x16], #0x10
   579  `,
   580  		},
   581  		{
   582  			arg: backend.ABIArg{Type: ssa.TypeV128, Reg: v12VReg, Kind: backend.ABIArgKindReg},
   583  			exp: `
   584  	str q12, [x16], #0x10
   585  `,
   586  		},
   587  		// Stack kinds.
   588  		{
   589  			arg: backend.ABIArg{Type: ssa.TypeI32, Offset: 0, Kind: backend.ABIArgKindStack},
   590  			exp: `
   591  	ldr w15, [sp]
   592  	str w15, [x16], #0x8
   593  `,
   594  		},
   595  		{
   596  			arg:      backend.ABIArg{Type: ssa.TypeI32, Offset: 0, Kind: backend.ABIArgKindStack},
   597  			retStart: 1024,
   598  			exp: `
   599  	ldr w15, [sp, #0x400]
   600  	str w15, [x16], #0x8
   601  `,
   602  		},
   603  		{
   604  			arg: backend.ABIArg{Type: ssa.TypeI32, Offset: 8, Kind: backend.ABIArgKindStack},
   605  			exp: `
   606  	ldr w15, [sp, #0x8]
   607  	str w15, [x16], #0x8
   608  `,
   609  		},
   610  		{
   611  			arg:      backend.ABIArg{Type: ssa.TypeI32, Offset: 8, Kind: backend.ABIArgKindStack},
   612  			retStart: 1024,
   613  			exp: `
   614  	ldr w15, [sp, #0x408]
   615  	str w15, [x16], #0x8
   616  `,
   617  		},
   618  		{
   619  			arg: backend.ABIArg{Type: ssa.TypeI64, Offset: 0, Kind: backend.ABIArgKindStack},
   620  			exp: `
   621  	ldr x15, [sp]
   622  	str x15, [x16], #0x8
   623  `,
   624  		},
   625  		{
   626  			arg: backend.ABIArg{Type: ssa.TypeI64, Offset: 128, Kind: backend.ABIArgKindStack},
   627  			exp: `
   628  	ldr x15, [sp, #0x80]
   629  	str x15, [x16], #0x8
   630  `,
   631  		},
   632  		{
   633  			arg: backend.ABIArg{Type: ssa.TypeF32, Offset: 64, Kind: backend.ABIArgKindStack},
   634  			exp: `
   635  	ldr s15, [sp, #0x40]
   636  	str s15, [x16], #0x8
   637  `,
   638  		},
   639  		{
   640  			arg: backend.ABIArg{Type: ssa.TypeF32, Offset: 2056, Kind: backend.ABIArgKindStack},
   641  			exp: `
   642  	ldr s15, [sp, #0x808]
   643  	str s15, [x16], #0x8
   644  `,
   645  		},
   646  		{
   647  			arg: backend.ABIArg{Type: ssa.TypeF64, Offset: 64, Kind: backend.ABIArgKindStack},
   648  			exp: `
   649  	ldr d15, [sp, #0x40]
   650  	str d15, [x16], #0x8
   651  `,
   652  		},
   653  		{
   654  			arg: backend.ABIArg{Type: ssa.TypeF64, Offset: 2056, Kind: backend.ABIArgKindStack},
   655  			exp: `
   656  	ldr d15, [sp, #0x808]
   657  	str d15, [x16], #0x8
   658  `,
   659  		},
   660  		{
   661  			arg: backend.ABIArg{Type: ssa.TypeV128, Offset: 64, Kind: backend.ABIArgKindStack},
   662  			exp: `
   663  	ldr q15, [sp, #0x40]
   664  	str q15, [x16], #0x10
   665  `,
   666  		},
   667  		{
   668  			arg: backend.ABIArg{Type: ssa.TypeV128, Offset: 2056, Kind: backend.ABIArgKindStack},
   669  			exp: `
   670  	movz x27, #0x808, lsl 0
   671  	ldr q15, [sp, x27]
   672  	str q15, [x16], #0x10
   673  `,
   674  		},
   675  		{
   676  			arg:      backend.ABIArg{Type: ssa.TypeV128, Offset: 2056, Kind: backend.ABIArgKindStack},
   677  			retStart: -1024,
   678  			exp: `
   679  	movz x27, #0x408, lsl 0
   680  	ldr q15, [sp, x27]
   681  	str q15, [x16], #0x10
   682  `,
   683  		},
   684  	} {
   685  		t.Run(tc.exp, func(t *testing.T) {
   686  			_, _, m := newSetupWithMockContext()
   687  			cur := m.allocateNop()
   688  			m.rootInstr = cur
   689  			m.goEntryPreamblePassResult(cur, paramSlicePtr, &tc.arg, tc.retStart)
   690  			require.Equal(t, tc.exp, m.Format())
   691  			m.Encode()
   692  		})
   693  	}
   694  }