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

     1  package amd64
     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/backend/regalloc"
     9  	"github.com/tetratelabs/wazero/internal/testing/require"
    10  )
    11  
    12  func TestMachine_setupPrologue(t *testing.T) {
    13  	for _, tc := range []struct {
    14  		spillSlotSize int64
    15  		clobberedRegs []regalloc.VReg
    16  		exp           string
    17  		abi           backend.FunctionABI
    18  	}{
    19  		{
    20  			spillSlotSize: 0,
    21  			exp: `
    22  	pushq %rbp
    23  	movq %rsp, %rbp
    24  	ud2
    25  `,
    26  		},
    27  		{
    28  			exp: `
    29  	pushq %rbp
    30  	movq %rsp, %rbp
    31  	sub $16, %rsp
    32  	movdqu %xmm15, (%rsp)
    33  	sub $16, %rsp
    34  	movdqu %xmm1, (%rsp)
    35  	sub $16, %rsp
    36  	movdqu %xmm0, (%rsp)
    37  	pushq %rcx
    38  	pushq %rax
    39  	ud2
    40  `,
    41  			spillSlotSize: 0,
    42  			clobberedRegs: []regalloc.VReg{raxVReg, rcxVReg, xmm0VReg, xmm1VReg, xmm15VReg},
    43  		},
    44  		{
    45  			exp: `
    46  	pushq %rbp
    47  	movq %rsp, %rbp
    48  	sub $16, %rsp
    49  	movdqu %xmm15, (%rsp)
    50  	sub $16, %rsp
    51  	movdqu %xmm1, (%rsp)
    52  	sub $16, %rsp
    53  	movdqu %xmm0, (%rsp)
    54  	pushq %rcx
    55  	pushq %rax
    56  	sub $48, %rsp
    57  	ud2
    58  `,
    59  			spillSlotSize: 48,
    60  			clobberedRegs: []regalloc.VReg{raxVReg, rcxVReg, xmm0VReg, xmm1VReg, xmm15VReg},
    61  		},
    62  	} {
    63  		tc := tc
    64  		t.Run(tc.exp, func(t *testing.T) {
    65  			_, _, m := newSetupWithMockContext()
    66  			m.DisableStackCheck()
    67  			m.spillSlotSize = tc.spillSlotSize
    68  			m.clobberedRegs = tc.clobberedRegs
    69  			m.currentABI = &tc.abi
    70  
    71  			root := m.allocateNop()
    72  			m.ectx.RootInstr = root
    73  			udf := m.allocateInstr()
    74  			udf.asUD2()
    75  			root.next = udf
    76  			udf.prev = root
    77  
    78  			m.setupPrologue()
    79  			require.Equal(t, root, m.ectx.RootInstr)
    80  			err := m.Encode(context.Background())
    81  			require.NoError(t, err)
    82  			require.Equal(t, tc.exp, m.Format())
    83  		})
    84  	}
    85  }
    86  
    87  func TestMachine_postRegAlloc(t *testing.T) {
    88  	for _, tc := range []struct {
    89  		exp           string
    90  		abi           backend.FunctionABI
    91  		clobberedRegs []regalloc.VReg
    92  		spillSlotSize int64
    93  	}{
    94  		{
    95  			exp: `
    96  	movq %rbp, %rsp
    97  	popq %rbp
    98  	ret
    99  `,
   100  			spillSlotSize: 0,
   101  			clobberedRegs: nil,
   102  		},
   103  		{
   104  			exp: `
   105  	popq %rax
   106  	popq %rcx
   107  	movdqu (%rsp), %xmm0
   108  	add $16, %rsp
   109  	movdqu (%rsp), %xmm1
   110  	add $16, %rsp
   111  	movdqu (%rsp), %xmm15
   112  	add $16, %rsp
   113  	movq %rbp, %rsp
   114  	popq %rbp
   115  	ret
   116  `,
   117  			spillSlotSize: 0,
   118  			clobberedRegs: []regalloc.VReg{raxVReg, rcxVReg, xmm0VReg, xmm1VReg, xmm15VReg},
   119  		},
   120  		{
   121  			exp: `
   122  	add $160, %rsp
   123  	popq %rax
   124  	popq %rcx
   125  	movdqu (%rsp), %xmm0
   126  	add $16, %rsp
   127  	movdqu (%rsp), %xmm1
   128  	add $16, %rsp
   129  	movdqu (%rsp), %xmm15
   130  	add $16, %rsp
   131  	movq %rbp, %rsp
   132  	popq %rbp
   133  	ret
   134  `,
   135  			spillSlotSize: 160,
   136  			clobberedRegs: []regalloc.VReg{raxVReg, rcxVReg, xmm0VReg, xmm1VReg, xmm15VReg},
   137  		},
   138  	} {
   139  		tc := tc
   140  		t.Run(tc.exp, func(t *testing.T) {
   141  			_, _, m := newSetupWithMockContext()
   142  			m.spillSlotSize = tc.spillSlotSize
   143  			m.clobberedRegs = tc.clobberedRegs
   144  			m.currentABI = &tc.abi
   145  
   146  			root := m.allocateNop()
   147  			m.ectx.RootInstr = root
   148  			ret := m.allocateInstr()
   149  			ret.asRet()
   150  			root.next = ret
   151  			ret.prev = root
   152  			m.postRegAlloc()
   153  
   154  			require.Equal(t, root, m.ectx.RootInstr)
   155  			err := m.Encode(context.Background())
   156  			require.NoError(t, err)
   157  			require.Equal(t, tc.exp, m.Format())
   158  		})
   159  	}
   160  }