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

     1  package amd64
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
     7  	"github.com/tetratelabs/wazero/internal/testing/require"
     8  )
     9  
    10  func TestMachineCompileEntryPreamble(t *testing.T) {
    11  	for _, tc := range []struct {
    12  		name string
    13  		sig  *ssa.Signature
    14  		exp  string
    15  	}{
    16  		{
    17  			name: "basic",
    18  			sig: &ssa.Signature{
    19  				// execContext and moduleContext are passed in %rax and %rcx.
    20  				Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64},
    21  			},
    22  			exp: `
    23  	movq %rax, %rdx
    24  	mov.q %rbp, 16(%rax)
    25  	mov.q %rsp, 24(%rax)
    26  	movq %r13, %rsp
    27  	xor %rbp, %rbp
    28  	callq *%r14
    29  	movq 16(%rdx), %rbp
    30  	movq 24(%rdx), %rsp
    31  	ret
    32  `,
    33  		},
    34  		{
    35  			name: "only regs args",
    36  			sig: &ssa.Signature{
    37  				// execContext and moduleContext are passed in %rax and %rcx.
    38  				Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64},
    39  			},
    40  			exp: `
    41  	movq %rax, %rdx
    42  	mov.q %rbp, 16(%rax)
    43  	mov.q %rsp, 24(%rax)
    44  	movq %r13, %rsp
    45  	movzx.lq (%r12), %rcx
    46  	movq 8(%r12), %rdi
    47  	movss 16(%r12), %xmm0
    48  	movsd 24(%r12), %xmm1
    49  	movdqu 32(%r12), %xmm2
    50  	movq 48(%r12), %rsi
    51  	xor %rbp, %rbp
    52  	callq *%r14
    53  	movq 16(%rdx), %rbp
    54  	movq 24(%rdx), %rsp
    55  	ret
    56  `,
    57  		},
    58  		{
    59  			name: "only regs rets",
    60  			sig: &ssa.Signature{
    61  				// execContext and moduleContext are passed in %rax and %rcx.
    62  				Params:  []ssa.Type{ssa.TypeI64, ssa.TypeI64},
    63  				Results: []ssa.Type{ssa.TypeI32, ssa.TypeV128, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64},
    64  			},
    65  			exp: `
    66  	movq %rax, %rdx
    67  	mov.q %rbp, 16(%rax)
    68  	mov.q %rsp, 24(%rax)
    69  	movq %r13, %rsp
    70  	xor %rbp, %rbp
    71  	callq *%r14
    72  	mov.l %rax, (%r12)
    73  	movdqu %xmm0, 8(%r12)
    74  	mov.q %rbx, 24(%r12)
    75  	movss %xmm1, 32(%r12)
    76  	movsd %xmm2, 40(%r12)
    77  	movq 16(%rdx), %rbp
    78  	movq 24(%rdx), %rsp
    79  	ret
    80  `,
    81  		},
    82  		{
    83  			name: "only regs args/rets",
    84  			sig: &ssa.Signature{
    85  				// execContext and moduleContext are passed in %rax and %rcx.
    86  				Params:  []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64},
    87  				Results: []ssa.Type{ssa.TypeI32, ssa.TypeV128, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64},
    88  			},
    89  			exp: `
    90  	movq %rax, %rdx
    91  	mov.q %rbp, 16(%rax)
    92  	mov.q %rsp, 24(%rax)
    93  	movq %r13, %rsp
    94  	movzx.lq (%r12), %rcx
    95  	movq 8(%r12), %rdi
    96  	movss 16(%r12), %xmm0
    97  	movsd 24(%r12), %xmm1
    98  	movdqu 32(%r12), %xmm2
    99  	movq 48(%r12), %rsi
   100  	xor %rbp, %rbp
   101  	callq *%r14
   102  	mov.l %rax, (%r12)
   103  	movdqu %xmm0, 8(%r12)
   104  	mov.q %rbx, 24(%r12)
   105  	movss %xmm1, 32(%r12)
   106  	movsd %xmm2, 40(%r12)
   107  	movq 16(%rdx), %rbp
   108  	movq 24(%rdx), %rsp
   109  	ret
   110  `,
   111  		},
   112  		{
   113  			name: "many args",
   114  			sig: &ssa.Signature{
   115  				// execContext and moduleContext are passed in %rax and %rcx.
   116  				Params: []ssa.Type{
   117  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   118  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   119  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   120  				},
   121  			},
   122  			exp: `
   123  	movq %rax, %rdx
   124  	mov.q %rbp, 16(%rax)
   125  	mov.q %rsp, 24(%rax)
   126  	movq %r13, %rsp
   127  	sub $64, %rsp
   128  	movzx.lq (%r12), %rcx
   129  	movq 8(%r12), %rdi
   130  	movss 16(%r12), %xmm0
   131  	movsd 24(%r12), %xmm1
   132  	movdqu 32(%r12), %xmm2
   133  	movq 48(%r12), %rsi
   134  	movq 56(%r12), %r8
   135  	movq 64(%r12), %r9
   136  	movzx.lq 72(%r12), %r10
   137  	movq 80(%r12), %r11
   138  	movss 88(%r12), %xmm3
   139  	movsd 96(%r12), %xmm4
   140  	movdqu 104(%r12), %xmm5
   141  	movq 120(%r12), %r15
   142  	mov.q %r15, (%rsp)
   143  	movq 128(%r12), %r15
   144  	mov.q %r15, 8(%rsp)
   145  	movq 136(%r12), %r15
   146  	mov.q %r15, 16(%rsp)
   147  	movzx.lq 144(%r12), %r15
   148  	mov.l %r15, 24(%rsp)
   149  	movq 152(%r12), %r15
   150  	mov.q %r15, 32(%rsp)
   151  	movss 160(%r12), %xmm6
   152  	movsd 168(%r12), %xmm7
   153  	movdqu 176(%r12), %xmm15
   154  	movdqu %xmm15, 40(%rsp)
   155  	movq 192(%r12), %r15
   156  	mov.q %r15, 56(%rsp)
   157  	xor %rbp, %rbp
   158  	callq *%r14
   159  	movq 16(%rdx), %rbp
   160  	movq 24(%rdx), %rsp
   161  	ret
   162  `,
   163  		},
   164  		{
   165  			name: "many results",
   166  			sig: &ssa.Signature{
   167  				// execContext and moduleContext are passed in %rax and %rcx.
   168  				Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64},
   169  				Results: []ssa.Type{
   170  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   171  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   172  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   173  				},
   174  			},
   175  			exp: `
   176  	movq %rax, %rdx
   177  	mov.q %rbp, 16(%rax)
   178  	mov.q %rsp, 24(%rax)
   179  	movq %r13, %rsp
   180  	sub $64, %rsp
   181  	xor %rbp, %rbp
   182  	callq *%r14
   183  	mov.q %rax, (%r12)
   184  	mov.q %rbx, 8(%r12)
   185  	mov.l %rcx, 16(%r12)
   186  	mov.q %rdi, 24(%r12)
   187  	movss %xmm0, 32(%r12)
   188  	movsd %xmm1, 40(%r12)
   189  	movdqu %xmm2, 48(%r12)
   190  	mov.q %rsi, 64(%r12)
   191  	mov.q %r8, 72(%r12)
   192  	mov.q %r9, 80(%r12)
   193  	mov.l %r10, 88(%r12)
   194  	mov.q %r11, 96(%r12)
   195  	movss %xmm3, 104(%r12)
   196  	movsd %xmm4, 112(%r12)
   197  	movdqu %xmm5, 120(%r12)
   198  	movq (%rsp), %r15
   199  	mov.q %r15, 136(%r12)
   200  	movq 8(%rsp), %r15
   201  	mov.q %r15, 144(%r12)
   202  	movq 16(%rsp), %r15
   203  	mov.q %r15, 152(%r12)
   204  	movzx.lq 24(%rsp), %r15
   205  	mov.l %r15, 160(%r12)
   206  	movq 32(%rsp), %r15
   207  	mov.q %r15, 168(%r12)
   208  	movss %xmm6, 176(%r12)
   209  	movsd %xmm7, 184(%r12)
   210  	movdqu 40(%rsp), %xmm15
   211  	movdqu %xmm15, 192(%r12)
   212  	movq 56(%rsp), %r15
   213  	mov.q %r15, 208(%r12)
   214  	movq 16(%rdx), %rbp
   215  	movq 24(%rdx), %rsp
   216  	ret
   217  `,
   218  		},
   219  		{
   220  			name: "many args results",
   221  			sig: &ssa.Signature{
   222  				// execContext and moduleContext are passed in %rax and %rcx.
   223  				Params: []ssa.Type{
   224  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   225  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   226  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   227  				},
   228  				Results: []ssa.Type{
   229  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   230  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   231  					ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, ssa.TypeI64,
   232  				},
   233  			},
   234  			exp: `
   235  	movq %rax, %rdx
   236  	mov.q %rbp, 16(%rax)
   237  	mov.q %rsp, 24(%rax)
   238  	movq %r13, %rsp
   239  	sub $128, %rsp
   240  	movzx.lq (%r12), %rcx
   241  	movq 8(%r12), %rdi
   242  	movss 16(%r12), %xmm0
   243  	movsd 24(%r12), %xmm1
   244  	movdqu 32(%r12), %xmm2
   245  	movq 48(%r12), %rsi
   246  	movq 56(%r12), %r8
   247  	movq 64(%r12), %r9
   248  	movzx.lq 72(%r12), %r10
   249  	movq 80(%r12), %r11
   250  	movss 88(%r12), %xmm3
   251  	movsd 96(%r12), %xmm4
   252  	movdqu 104(%r12), %xmm5
   253  	movq 120(%r12), %r15
   254  	mov.q %r15, (%rsp)
   255  	movq 128(%r12), %r15
   256  	mov.q %r15, 8(%rsp)
   257  	movq 136(%r12), %r15
   258  	mov.q %r15, 16(%rsp)
   259  	movzx.lq 144(%r12), %r15
   260  	mov.l %r15, 24(%rsp)
   261  	movq 152(%r12), %r15
   262  	mov.q %r15, 32(%rsp)
   263  	movss 160(%r12), %xmm6
   264  	movsd 168(%r12), %xmm7
   265  	movdqu 176(%r12), %xmm15
   266  	movdqu %xmm15, 40(%rsp)
   267  	movq 192(%r12), %r15
   268  	mov.q %r15, 56(%rsp)
   269  	xor %rbp, %rbp
   270  	callq *%r14
   271  	mov.q %rax, (%r12)
   272  	mov.q %rbx, 8(%r12)
   273  	mov.l %rcx, 16(%r12)
   274  	mov.q %rdi, 24(%r12)
   275  	movss %xmm0, 32(%r12)
   276  	movsd %xmm1, 40(%r12)
   277  	movdqu %xmm2, 48(%r12)
   278  	mov.q %rsi, 64(%r12)
   279  	mov.q %r8, 72(%r12)
   280  	mov.q %r9, 80(%r12)
   281  	mov.l %r10, 88(%r12)
   282  	mov.q %r11, 96(%r12)
   283  	movss %xmm3, 104(%r12)
   284  	movsd %xmm4, 112(%r12)
   285  	movdqu %xmm5, 120(%r12)
   286  	movq 64(%rsp), %r15
   287  	mov.q %r15, 136(%r12)
   288  	movq 72(%rsp), %r15
   289  	mov.q %r15, 144(%r12)
   290  	movq 80(%rsp), %r15
   291  	mov.q %r15, 152(%r12)
   292  	movzx.lq 88(%rsp), %r15
   293  	mov.l %r15, 160(%r12)
   294  	movq 96(%rsp), %r15
   295  	mov.q %r15, 168(%r12)
   296  	movss %xmm6, 176(%r12)
   297  	movsd %xmm7, 184(%r12)
   298  	movdqu 104(%rsp), %xmm15
   299  	movdqu %xmm15, 192(%r12)
   300  	movq 120(%rsp), %r15
   301  	mov.q %r15, 208(%r12)
   302  	movq 16(%rdx), %rbp
   303  	movq 24(%rdx), %rsp
   304  	ret
   305  `,
   306  		},
   307  	} {
   308  		t.Run(tc.name, func(t *testing.T) {
   309  			_, _, m := newSetupWithMockContext()
   310  			m.ectx.RootInstr = m.compileEntryPreamble(tc.sig)
   311  			require.Equal(t, tc.exp, m.Format())
   312  		})
   313  	}
   314  }