github.com/tetratelabs/wazero@v1.7.1/internal/engine/wazevo/backend/isa/arm64/abi_entry_preamble_test.go (about)

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