wa-lang.org/wazero@v1.0.2/internal/asm/arm64/impl_1_test.go (about)

     1  package arm64
     2  
     3  import (
     4  	"encoding/hex"
     5  	"testing"
     6  
     7  	"wa-lang.org/wazero/internal/asm"
     8  	"wa-lang.org/wazero/internal/testing/require"
     9  )
    10  
    11  func TestNodeImpl_AssignJumpTarget(t *testing.T) {
    12  	n := &nodeImpl{}
    13  	target := &nodeImpl{}
    14  	n.AssignJumpTarget(target)
    15  	require.Equal(t, n.jumpTarget, target)
    16  }
    17  
    18  func TestNodeImpl_AssignDestinationConstant(t *testing.T) {
    19  	n := &nodeImpl{}
    20  	n.AssignDestinationConstant(12345)
    21  	require.Equal(t, int64(12345), n.dstConst)
    22  }
    23  
    24  func TestNodeImpl_AssignSourceConstant(t *testing.T) {
    25  	n := &nodeImpl{}
    26  	n.AssignSourceConstant(12345)
    27  	require.Equal(t, int64(12345), n.srcConst)
    28  }
    29  
    30  func TestNodeImpl_String(t *testing.T) {
    31  	tests := []struct {
    32  		in  *nodeImpl
    33  		exp string
    34  	}{
    35  		{
    36  			in:  &nodeImpl{instruction: NOP, types: operandTypesNoneToNone},
    37  			exp: "NOP",
    38  		},
    39  		{
    40  			in:  &nodeImpl{instruction: BCONDEQ, types: operandTypesNoneToRegister, dstReg: RegR1},
    41  			exp: "BCONDEQ R1",
    42  		},
    43  		{
    44  			in:  &nodeImpl{instruction: BCONDNE, types: operandTypesNoneToBranch, jumpTarget: &nodeImpl{instruction: NOP}},
    45  			exp: "BCONDNE {NOP}",
    46  		},
    47  		{
    48  			in:  &nodeImpl{instruction: ADD, types: operandTypesRegisterToRegister, srcReg: RegV0, dstReg: RegV10},
    49  			exp: "ADD V0, V10",
    50  		},
    51  		{
    52  			in: &nodeImpl{
    53  				instruction: ADD, types: operandTypesLeftShiftedRegisterToRegister,
    54  				srcReg: RegR0, srcReg2: RegR11, srcConst: 4, dstReg: RegR10,
    55  			},
    56  			exp: "ADD (R0, R11 << 4), R10",
    57  		},
    58  		{
    59  			in:  &nodeImpl{instruction: ADD, types: operandTypesTwoRegistersToRegister, srcReg: RegR0, srcReg2: RegR8, dstReg: RegR10},
    60  			exp: "ADD (R0, R8), R10",
    61  		},
    62  		{
    63  			in: &nodeImpl{
    64  				instruction: MSUB, types: operandTypesThreeRegistersToRegister,
    65  				srcReg: RegR0, srcReg2: RegR8, dstReg: RegR10, dstReg2: RegR1,
    66  			},
    67  			exp: "MSUB (R0, R8, R10), R1)",
    68  		},
    69  		{
    70  			in:  &nodeImpl{instruction: CMPW, types: operandTypesTwoRegistersToNone, srcReg: RegR0, srcReg2: RegR8},
    71  			exp: "CMPW (R0, R8)",
    72  		},
    73  		{
    74  			in:  &nodeImpl{instruction: CMP, types: operandTypesRegisterAndConstToNone, srcReg: RegR0, srcConst: 0x123},
    75  			exp: "CMP (R0, 0x123)",
    76  		},
    77  		{
    78  			in:  &nodeImpl{instruction: MOVD, types: operandTypesRegisterToMemory, srcReg: RegR0, dstReg: RegR8, dstConst: 0x123},
    79  			exp: "MOVD R0, [R8 + 0x123]",
    80  		},
    81  		{
    82  			in:  &nodeImpl{instruction: MOVD, types: operandTypesRegisterToMemory, srcReg: RegR0, dstReg: RegR8, dstReg2: RegR6},
    83  			exp: "MOVD R0, [R8 + R6]",
    84  		},
    85  		{
    86  			in:  &nodeImpl{instruction: MOVD, types: operandTypesMemoryToRegister, srcReg: RegR0, srcConst: 0x123, dstReg: RegR8},
    87  			exp: "MOVD [R0 + 0x123], R8",
    88  		},
    89  		{
    90  			in:  &nodeImpl{instruction: MOVD, types: operandTypesMemoryToRegister, srcReg: RegR0, srcReg2: RegR6, dstReg: RegR8},
    91  			exp: "MOVD [R0 + R6], R8",
    92  		},
    93  		{
    94  			in:  &nodeImpl{instruction: MOVD, types: operandTypesConstToRegister, srcConst: 0x123, dstReg: RegR8},
    95  			exp: "MOVD 0x123, R8",
    96  		},
    97  		{
    98  			in: &nodeImpl{
    99  				instruction: VMOV, types: operandTypesMemoryToVectorRegister,
   100  				srcReg: RegR1, dstReg: RegV29, vectorArrangement: VectorArrangement2S,
   101  			},
   102  			exp: "VMOV [R1], V29.2S",
   103  		},
   104  		{
   105  			in: &nodeImpl{
   106  				instruction: VMOV, types: operandTypesVectorRegisterToMemory,
   107  				dstReg: RegR1, dstReg2: RegR6,
   108  				srcReg: RegV29, vectorArrangement: VectorArrangementQ,
   109  			},
   110  			exp: "VMOV V29.Q, [R1 + R6]",
   111  		},
   112  		{
   113  			in: &nodeImpl{
   114  				instruction: VMOV, types: operandTypesVectorRegisterToMemory,
   115  				dstReg: RegR1, dstConst: 0x10,
   116  				srcReg: RegV29, vectorArrangement: VectorArrangementQ,
   117  			},
   118  			exp: "VMOV V29.Q, [R1 + 0x10]",
   119  		},
   120  		{
   121  			in: &nodeImpl{
   122  				instruction: VMOV, types: operandTypesRegisterToVectorRegister,
   123  				srcReg: RegR1, dstReg: RegV29, vectorArrangement: VectorArrangement2D, dstVectorIndex: 1,
   124  			},
   125  			exp: "VMOV R1, V29.2D[1]",
   126  		},
   127  		{
   128  			in: &nodeImpl{
   129  				instruction: VCNT, types: operandTypesVectorRegisterToVectorRegister,
   130  				srcReg: RegV3, dstReg: RegV29, vectorArrangement: VectorArrangement2D, srcVectorIndex: 1,
   131  			},
   132  			exp: "VCNT V3.2D, V29.2D",
   133  		},
   134  		{
   135  			in: &nodeImpl{
   136  				instruction: VCNT, types: operandTypesVectorRegisterToVectorRegister,
   137  				srcReg: RegV3, dstReg: RegV29, vectorArrangement: VectorArrangement2D, srcVectorIndex: 1,
   138  			},
   139  			exp: "VCNT V3.2D, V29.2D",
   140  		},
   141  		{
   142  			in: &nodeImpl{
   143  				instruction: UMOV, types: operandTypesVectorRegisterToRegister,
   144  				srcReg: RegV31, dstReg: RegR8, vectorArrangement: VectorArrangementS, srcVectorIndex: 1,
   145  			},
   146  			exp: "UMOV V31.S[1], R8",
   147  		},
   148  		{
   149  			in: &nodeImpl{
   150  				instruction: UMOV, types: operandTypesTwoVectorRegistersToVectorRegister,
   151  				srcReg: RegV31, srcReg2: RegV1, dstReg: RegV8, vectorArrangement: VectorArrangementS, srcVectorIndex: 1,
   152  			},
   153  			exp: "UMOV (V31.S, V1.S), V8.S",
   154  		},
   155  		{
   156  			in: &nodeImpl{
   157  				instruction: VORR, types: operandTypesStaticConstToVectorRegister,
   158  				staticConst: &asm.StaticConst{Raw: []byte{1, 2, 3, 4}},
   159  				dstReg:      RegV8, vectorArrangement: VectorArrangement16B, srcVectorIndex: 1,
   160  			},
   161  			exp: "VORR $0x01020304 V8.16B",
   162  		},
   163  	}
   164  
   165  	for _, tt := range tests {
   166  		tc := tt
   167  		t.Run(tc.exp, func(t *testing.T) {
   168  			require.Equal(t, tc.exp, tc.in.String())
   169  		})
   170  	}
   171  }
   172  
   173  func TestAssemblerImpl_addNode(t *testing.T) {
   174  	a := NewAssembler(RegR10)
   175  
   176  	root := &nodeImpl{}
   177  	a.addNode(root)
   178  	require.Equal(t, a.Root, root)
   179  	require.Equal(t, a.Current, root)
   180  	require.Nil(t, root.next)
   181  
   182  	next := &nodeImpl{}
   183  	a.addNode(next)
   184  	require.Equal(t, a.Root, root)
   185  	require.Equal(t, a.Current, next)
   186  	require.Equal(t, next, root.next)
   187  	require.Nil(t, next.next)
   188  }
   189  
   190  func TestAssemblerImpl_newNode(t *testing.T) {
   191  	a := NewAssembler(RegR10)
   192  	actual := a.newNode(MOVD, operandTypesMemoryToRegister)
   193  	require.Equal(t, MOVD, actual.instruction)
   194  	require.Equal(t, operandTypeMemory, actual.types.src)
   195  	require.Equal(t, operandTypeRegister, actual.types.dst)
   196  	require.Equal(t, actual, a.Root)
   197  	require.Equal(t, actual, a.Current)
   198  }
   199  
   200  func TestAssemblerImpl_CompileStandAlone(t *testing.T) {
   201  	a := NewAssembler(RegR10)
   202  	a.CompileStandAlone(RET)
   203  	actualNode := a.Current
   204  	require.Equal(t, RET, actualNode.instruction)
   205  	require.Equal(t, operandTypeNone, actualNode.types.src)
   206  	require.Equal(t, operandTypeNone, actualNode.types.dst)
   207  }
   208  
   209  func TestAssemblerImpl_CompileConstToRegister(t *testing.T) {
   210  	a := NewAssembler(RegR10)
   211  	a.CompileConstToRegister(MOVD, 1000, RegR10)
   212  	actualNode := a.Current
   213  	require.Equal(t, MOVD, actualNode.instruction)
   214  	require.Equal(t, int64(1000), actualNode.srcConst)
   215  	require.Equal(t, RegR10, actualNode.dstReg)
   216  	require.Equal(t, operandTypeConst, actualNode.types.src)
   217  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   218  }
   219  
   220  func TestAssemblerImpl_CompileRegisterToRegister(t *testing.T) {
   221  	a := NewAssembler(RegR10)
   222  	a.CompileRegisterToRegister(MOVD, RegR15, RegR27)
   223  	actualNode := a.Current
   224  	require.Equal(t, MOVD, actualNode.instruction)
   225  	require.Equal(t, RegR15, actualNode.srcReg)
   226  	require.Equal(t, RegR27, actualNode.dstReg)
   227  	require.Equal(t, operandTypeRegister, actualNode.types.src)
   228  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   229  }
   230  
   231  func TestAssemblerImpl_CompileMemoryToRegister(t *testing.T) {
   232  	a := NewAssembler(RegR10)
   233  	a.CompileMemoryToRegister(MOVD, RegR15, 100, RegR27)
   234  	actualNode := a.Current
   235  	require.Equal(t, MOVD, actualNode.instruction)
   236  	require.Equal(t, RegR15, actualNode.srcReg)
   237  	require.Equal(t, int64(100), actualNode.srcConst)
   238  	require.Equal(t, RegR27, actualNode.dstReg)
   239  	require.Equal(t, operandTypeMemory, actualNode.types.src)
   240  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   241  }
   242  
   243  func TestAssemblerImpl_CompileRegisterToMemory(t *testing.T) {
   244  	a := NewAssembler(RegR10)
   245  	a.CompileRegisterToMemory(MOVD, RegR15, RegR27, 100)
   246  	actualNode := a.Current
   247  	require.Equal(t, MOVD, actualNode.instruction)
   248  	require.Equal(t, RegR15, actualNode.srcReg)
   249  	require.Equal(t, RegR27, actualNode.dstReg)
   250  	require.Equal(t, int64(100), actualNode.dstConst)
   251  	require.Equal(t, operandTypeRegister, actualNode.types.src)
   252  	require.Equal(t, operandTypeMemory, actualNode.types.dst)
   253  }
   254  
   255  func TestAssemblerImpl_CompileJump(t *testing.T) {
   256  	a := NewAssembler(RegR10)
   257  	a.CompileJump(B)
   258  	actualNode := a.Current
   259  	require.Equal(t, B, actualNode.instruction)
   260  	require.Equal(t, operandTypeNone, actualNode.types.src)
   261  	require.Equal(t, operandTypeBranch, actualNode.types.dst)
   262  }
   263  
   264  func TestAssemblerImpl_CompileJumpToRegister(t *testing.T) {
   265  	a := NewAssembler(RegR10)
   266  	a.CompileJumpToRegister(BCONDNE, RegR27)
   267  	actualNode := a.Current
   268  	require.Equal(t, BCONDNE, actualNode.instruction)
   269  	require.Equal(t, RegR27, actualNode.dstReg)
   270  	require.Equal(t, operandTypeNone, actualNode.types.src)
   271  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   272  }
   273  
   274  func TestAssemblerImpl_CompileReadInstructionAddress(t *testing.T) {
   275  	a := NewAssembler(RegR10)
   276  	a.CompileReadInstructionAddress(RegR10, RET)
   277  	actualNode := a.Current
   278  	require.Equal(t, ADR, actualNode.instruction)
   279  	require.Equal(t, RegR10, actualNode.dstReg)
   280  	require.Equal(t, operandTypeMemory, actualNode.types.src)
   281  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   282  	require.Equal(t, RET, actualNode.readInstructionAddressBeforeTargetInstruction)
   283  }
   284  
   285  func Test_CompileMemoryWithRegisterOffsetToRegister(t *testing.T) {
   286  	a := NewAssembler(RegR10)
   287  	a.CompileMemoryWithRegisterOffsetToRegister(MOVD, RegR27, RegR10, RegR0)
   288  	actualNode := a.Current
   289  	require.Equal(t, MOVD, actualNode.instruction)
   290  	require.Equal(t, RegR27, actualNode.srcReg)
   291  	require.Equal(t, RegR10, actualNode.srcReg2)
   292  	require.Equal(t, RegR0, actualNode.dstReg)
   293  	require.Equal(t, operandTypeMemory, actualNode.types.src)
   294  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   295  }
   296  
   297  func Test_CompileMemoryWithRegisterOffsetToVectorRegister(t *testing.T) {
   298  	a := NewAssembler(RegR10)
   299  	a.CompileMemoryWithRegisterOffsetToVectorRegister(MOVD, RegR27, RegR10, RegV31, VectorArrangementS)
   300  	actualNode := a.Current
   301  	require.Equal(t, MOVD, actualNode.instruction)
   302  	require.Equal(t, RegR27, actualNode.srcReg)
   303  	require.Equal(t, RegR10, actualNode.srcReg2)
   304  	require.Equal(t, RegV31, actualNode.dstReg)
   305  	require.Equal(t, VectorArrangementS, actualNode.vectorArrangement)
   306  	require.Equal(t, operandTypeMemory, actualNode.types.src)
   307  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   308  }
   309  
   310  func Test_CompileRegisterToMemoryWithRegisterOffset(t *testing.T) {
   311  	a := NewAssembler(RegR10)
   312  	a.CompileRegisterToMemoryWithRegisterOffset(MOVD, RegR27, RegR10, RegR0)
   313  	actualNode := a.Current
   314  	require.Equal(t, MOVD, actualNode.instruction)
   315  	require.Equal(t, RegR27, actualNode.srcReg)
   316  	require.Equal(t, RegR10, actualNode.dstReg)
   317  	require.Equal(t, RegR0, actualNode.dstReg2)
   318  	require.Equal(t, operandTypeRegister, actualNode.types.src)
   319  	require.Equal(t, operandTypeMemory, actualNode.types.dst)
   320  }
   321  
   322  func Test_CompileVectorRegisterToMemoryWithRegisterOffset(t *testing.T) {
   323  	a := NewAssembler(RegR10)
   324  	a.CompileVectorRegisterToMemoryWithRegisterOffset(MOVD, RegV31, RegR10, RegR0, VectorArrangement2D)
   325  	actualNode := a.Current
   326  	require.Equal(t, MOVD, actualNode.instruction)
   327  	require.Equal(t, RegV31, actualNode.srcReg)
   328  	require.Equal(t, RegR10, actualNode.dstReg)
   329  	require.Equal(t, RegR0, actualNode.dstReg2)
   330  	require.Equal(t, VectorArrangement2D, actualNode.vectorArrangement)
   331  	require.Equal(t, operandTypeVectorRegister, actualNode.types.src)
   332  	require.Equal(t, operandTypeMemory, actualNode.types.dst)
   333  }
   334  
   335  func Test_CompileTwoRegistersToRegister(t *testing.T) {
   336  	a := NewAssembler(RegR10)
   337  	a.CompileTwoRegistersToRegister(MOVD, RegR27, RegR10, RegR0)
   338  	actualNode := a.Current
   339  	require.Equal(t, MOVD, actualNode.instruction)
   340  	require.Equal(t, RegR27, actualNode.srcReg)
   341  	require.Equal(t, RegR10, actualNode.srcReg2)
   342  	require.Equal(t, RegR0, actualNode.dstReg)
   343  	require.Equal(t, operandTypeTwoRegisters, actualNode.types.src)
   344  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   345  }
   346  
   347  func Test_CompileThreeRegistersToRegister(t *testing.T) {
   348  	a := NewAssembler(RegR10)
   349  	a.CompileThreeRegistersToRegister(MOVD, RegR27, RegR10, RegR0, RegR28)
   350  	actualNode := a.Current
   351  	require.Equal(t, MOVD, actualNode.instruction)
   352  	require.Equal(t, RegR27, actualNode.srcReg)
   353  	require.Equal(t, RegR10, actualNode.srcReg2)
   354  	require.Equal(t, RegR0, actualNode.dstReg)
   355  	require.Equal(t, RegR28, actualNode.dstReg2)
   356  	require.Equal(t, operandTypeThreeRegisters, actualNode.types.src)
   357  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   358  }
   359  
   360  func Test_CompileTwoRegistersToNone(t *testing.T) {
   361  	a := NewAssembler(RegR10)
   362  	a.CompileTwoRegistersToNone(CMP, RegR27, RegR10)
   363  	actualNode := a.Current
   364  	require.Equal(t, CMP, actualNode.instruction)
   365  	require.Equal(t, RegR27, actualNode.srcReg)
   366  	require.Equal(t, RegR10, actualNode.srcReg2)
   367  	require.Equal(t, operandTypeTwoRegisters, actualNode.types.src)
   368  	require.Equal(t, operandTypeNone, actualNode.types.dst)
   369  }
   370  
   371  func Test_CompileRegisterAndConstToNone(t *testing.T) {
   372  	a := NewAssembler(RegR10)
   373  	a.CompileRegisterAndConstToNone(CMP, RegR27, 10)
   374  	actualNode := a.Current
   375  	require.Equal(t, CMP, actualNode.instruction)
   376  	require.Equal(t, RegR27, actualNode.srcReg)
   377  	require.Equal(t, int64(10), actualNode.srcConst)
   378  	require.Equal(t, operandTypeRegisterAndConst, actualNode.types.src)
   379  	require.Equal(t, operandTypeNone, actualNode.types.dst)
   380  }
   381  
   382  func Test_CompileLeftShiftedRegisterToRegister(t *testing.T) {
   383  	a := NewAssembler(RegR10)
   384  	a.CompileLeftShiftedRegisterToRegister(ADD, RegR27, 10, RegR28, RegR5)
   385  	actualNode := a.Current
   386  	require.Equal(t, ADD, actualNode.instruction)
   387  	require.Equal(t, RegR28, actualNode.srcReg)
   388  	require.Equal(t, RegR27, actualNode.srcReg2)
   389  	require.Equal(t, int64(10), actualNode.srcConst)
   390  	require.Equal(t, RegR5, actualNode.dstReg)
   391  	require.Equal(t, operandTypeLeftShiftedRegister, actualNode.types.src)
   392  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   393  }
   394  
   395  func Test_CompileConditionalRegisterSet(t *testing.T) {
   396  	a := NewAssembler(RegR10)
   397  	a.CompileConditionalRegisterSet(CondNE, RegR10)
   398  	actualNode := a.Current
   399  	require.Equal(t, CSET, actualNode.instruction)
   400  	require.Equal(t, RegCondNE, actualNode.srcReg)
   401  	require.Equal(t, RegR10, actualNode.dstReg)
   402  	require.Equal(t, operandTypeRegister, actualNode.types.src)
   403  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   404  }
   405  
   406  func Test_CompileMemoryToVectorRegister(t *testing.T) {
   407  	a := NewAssembler(RegR10)
   408  	a.CompileMemoryToVectorRegister(VMOV, RegR10, 10, RegV3, VectorArrangement1D)
   409  	actualNode := a.Current
   410  	require.Equal(t, VMOV, actualNode.instruction)
   411  	require.Equal(t, RegR10, actualNode.srcReg)
   412  	require.Equal(t, int64(10), actualNode.srcConst)
   413  	require.Equal(t, RegV3, actualNode.dstReg)
   414  	require.Equal(t, operandTypeMemory, actualNode.types.src)
   415  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   416  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   417  }
   418  
   419  func Test_CompileVectorRegisterToMemory(t *testing.T) {
   420  	a := NewAssembler(RegR10)
   421  	a.CompileVectorRegisterToMemory(VMOV, RegV3, RegR10, 12, VectorArrangement1D)
   422  	actualNode := a.Current
   423  	require.Equal(t, VMOV, actualNode.instruction)
   424  	require.Equal(t, RegV3, actualNode.srcReg)
   425  	require.Equal(t, RegR10, actualNode.dstReg)
   426  	require.Equal(t, int64(12), actualNode.dstConst)
   427  	require.Equal(t, operandTypeVectorRegister, actualNode.types.src)
   428  	require.Equal(t, operandTypeMemory, actualNode.types.dst)
   429  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   430  }
   431  
   432  func Test_CompileRegisterToVectorRegister(t *testing.T) {
   433  	a := NewAssembler(RegR10)
   434  	a.CompileRegisterToVectorRegister(VMOV, RegV3, RegR10, VectorArrangement1D, 10)
   435  	actualNode := a.Current
   436  	require.Equal(t, VMOV, actualNode.instruction)
   437  	require.Equal(t, RegV3, actualNode.srcReg)
   438  	require.Equal(t, RegR10, actualNode.dstReg)
   439  	require.Equal(t, operandTypeRegister, actualNode.types.src)
   440  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   441  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   442  	require.Equal(t, VectorIndex(10), actualNode.dstVectorIndex)
   443  }
   444  
   445  func Test_CompileVectorRegisterToRegister(t *testing.T) {
   446  	a := NewAssembler(RegR10)
   447  	a.CompileVectorRegisterToRegister(VMOV, RegR10, RegV3, VectorArrangement1D, 10)
   448  	actualNode := a.Current
   449  	require.Equal(t, VMOV, actualNode.instruction)
   450  	require.Equal(t, RegR10, actualNode.srcReg)
   451  	require.Equal(t, RegV3, actualNode.dstReg)
   452  	require.Equal(t, operandTypeVectorRegister, actualNode.types.src)
   453  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   454  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   455  	require.Equal(t, VectorIndex(10), actualNode.srcVectorIndex)
   456  }
   457  
   458  func Test_CompileVectorRegisterToVectorRegister(t *testing.T) {
   459  	a := NewAssembler(RegR10)
   460  	a.CompileVectorRegisterToVectorRegister(VMOV, RegV3, RegV10, VectorArrangement1D, 1, 2)
   461  	actualNode := a.Current
   462  	require.Equal(t, VMOV, actualNode.instruction)
   463  	require.Equal(t, RegV3, actualNode.srcReg)
   464  	require.Equal(t, RegV10, actualNode.dstReg)
   465  	require.Equal(t, operandTypeVectorRegister, actualNode.types.src)
   466  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   467  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   468  	require.Equal(t, VectorIndex(1), actualNode.srcVectorIndex)
   469  	require.Equal(t, VectorIndex(2), actualNode.dstVectorIndex)
   470  }
   471  
   472  func Test_CompileVectorRegisterToVectorRegisterWithConst(t *testing.T) {
   473  	a := NewAssembler(RegR10)
   474  	a.CompileVectorRegisterToVectorRegisterWithConst(VMOV, RegV3, RegV10, VectorArrangement1D, 1234)
   475  	actualNode := a.Current
   476  	require.Equal(t, VMOV, actualNode.instruction)
   477  	require.Equal(t, RegV3, actualNode.srcReg)
   478  	require.Equal(t, RegV10, actualNode.dstReg)
   479  	require.Equal(t, operandTypeVectorRegister, actualNode.types.src)
   480  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   481  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   482  	require.Equal(t, int64(1234), actualNode.srcConst)
   483  }
   484  
   485  func Test_CompileTwoVectorRegistersToVectorRegister(t *testing.T) {
   486  	a := NewAssembler(RegR10)
   487  	a.CompileTwoVectorRegistersToVectorRegister(VMOV, RegV3, RegV15, RegV10, VectorArrangement1D)
   488  	actualNode := a.Current
   489  	require.Equal(t, VMOV, actualNode.instruction)
   490  	require.Equal(t, RegV3, actualNode.srcReg)
   491  	require.Equal(t, RegV15, actualNode.srcReg2)
   492  	require.Equal(t, RegV10, actualNode.dstReg)
   493  	require.Equal(t, operandTypeTwoVectorRegisters, actualNode.types.src)
   494  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   495  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   496  }
   497  
   498  func Test_CompileTwoVectorRegistersToVectorRegisterWithConst(t *testing.T) {
   499  	a := NewAssembler(RegR10)
   500  	a.CompileTwoVectorRegistersToVectorRegisterWithConst(VMOV, RegV3, RegV15, RegV10, VectorArrangement1D, 1234)
   501  	actualNode := a.Current
   502  	require.Equal(t, VMOV, actualNode.instruction)
   503  	require.Equal(t, RegV3, actualNode.srcReg)
   504  	require.Equal(t, RegV15, actualNode.srcReg2)
   505  	require.Equal(t, int64(1234), actualNode.srcConst)
   506  	require.Equal(t, RegV10, actualNode.dstReg)
   507  	require.Equal(t, operandTypeTwoVectorRegisters, actualNode.types.src)
   508  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   509  	require.Equal(t, VectorArrangement1D, actualNode.vectorArrangement)
   510  }
   511  
   512  func Test_CompileStaticConstToVectorRegister(t *testing.T) {
   513  	s := asm.NewStaticConst([]byte{1, 2, 3, 4})
   514  	a := NewAssembler(RegR10)
   515  	a.CompileStaticConstToVectorRegister(VMOV, s, RegV3, VectorArrangement2D)
   516  	actualNode := a.Current
   517  	require.Equal(t, VMOV, actualNode.instruction)
   518  	require.Equal(t, s, actualNode.staticConst)
   519  	require.Equal(t, RegV3, actualNode.dstReg)
   520  	require.Equal(t, operandTypeStaticConst, actualNode.types.src)
   521  	require.Equal(t, operandTypeVectorRegister, actualNode.types.dst)
   522  	require.Equal(t, VectorArrangement2D, actualNode.vectorArrangement)
   523  }
   524  
   525  func Test_CompileStaticConstToRegister(t *testing.T) {
   526  	s := asm.NewStaticConst([]byte{1, 2, 3, 4})
   527  	a := NewAssembler(RegR10)
   528  	a.CompileStaticConstToRegister(ADR, s, RegR27)
   529  	actualNode := a.Current
   530  	require.Equal(t, ADR, actualNode.instruction)
   531  	require.Equal(t, s, actualNode.staticConst)
   532  	require.Equal(t, RegR27, actualNode.dstReg)
   533  	require.Equal(t, operandTypeMemory, actualNode.types.src)
   534  	require.Equal(t, operandTypeRegister, actualNode.types.dst)
   535  }
   536  
   537  func Test_checkRegisterToRegisterType(t *testing.T) {
   538  	tests := []struct {
   539  		src, dst                     asm.Register
   540  		requireSrcInt, requireDstInt bool
   541  		expErr                       string
   542  	}{
   543  		{src: RegR10, dst: RegR30, requireSrcInt: true, requireDstInt: true, expErr: ""},
   544  		{src: RegR10, dst: RegR30, requireSrcInt: false, requireDstInt: true, expErr: "src requires float register but got R10"},
   545  		{src: RegR10, dst: RegR30, requireSrcInt: false, requireDstInt: false, expErr: "src requires float register but got R10"},
   546  		{src: RegR10, dst: RegR30, requireSrcInt: true, requireDstInt: false, expErr: "dst requires float register but got R30"},
   547  
   548  		{src: RegR10, dst: RegV30, requireSrcInt: true, requireDstInt: false, expErr: ""},
   549  		{src: RegR10, dst: RegV30, requireSrcInt: false, requireDstInt: true, expErr: "src requires float register but got R10"},
   550  		{src: RegR10, dst: RegV30, requireSrcInt: false, requireDstInt: false, expErr: "src requires float register but got R10"},
   551  		{src: RegR10, dst: RegV30, requireSrcInt: true, requireDstInt: true, expErr: "dst requires int register but got V30"},
   552  
   553  		{src: RegV10, dst: RegR30, requireSrcInt: false, requireDstInt: true, expErr: ""},
   554  		{src: RegV10, dst: RegR30, requireSrcInt: true, requireDstInt: true, expErr: "src requires int register but got V10"},
   555  		{src: RegV10, dst: RegR30, requireSrcInt: true, requireDstInt: false, expErr: "src requires int register but got V10"},
   556  		{src: RegV10, dst: RegR30, requireSrcInt: false, requireDstInt: false, expErr: "dst requires float register but got R30"},
   557  
   558  		{src: RegV10, dst: RegV30, requireSrcInt: false, requireDstInt: false, expErr: ""},
   559  		{src: RegV10, dst: RegV30, requireSrcInt: true, requireDstInt: false, expErr: "src requires int register but got V10"},
   560  		{src: RegV10, dst: RegV30, requireSrcInt: true, requireDstInt: true, expErr: "src requires int register but got V10"},
   561  		{src: RegV10, dst: RegV30, requireSrcInt: false, requireDstInt: true, expErr: "dst requires int register but got V30"},
   562  	}
   563  
   564  	for _, tt := range tests {
   565  		tc := tt
   566  		actual := checkRegisterToRegisterType(tc.src, tc.dst, tc.requireSrcInt, tc.requireDstInt)
   567  		if tc.expErr != "" {
   568  			require.EqualError(t, actual, tc.expErr)
   569  		} else {
   570  			require.NoError(t, actual)
   571  		}
   572  	}
   573  }
   574  
   575  func TestAssemblerImpl_encodeNoneToNone(t *testing.T) {
   576  	t.Run("error", func(t *testing.T) {
   577  		a := NewAssembler(asm.NilRegister)
   578  		err := a.encodeNoneToNone(&nodeImpl{instruction: ADD})
   579  		require.EqualError(t, err, "ADD is unsupported for from:none,to:none type")
   580  	})
   581  	t.Run("ok", func(t *testing.T) {
   582  		a := NewAssembler(asm.NilRegister)
   583  		err := a.encodeNoneToNone(&nodeImpl{instruction: NOP})
   584  		require.NoError(t, err)
   585  
   586  		// NOP must be ignored.
   587  		actual := a.Buf.Bytes()
   588  		require.Zero(t, len(actual))
   589  	})
   590  }
   591  
   592  func Test_validateMemoryOffset(t *testing.T) {
   593  	tests := []struct {
   594  		offset int64
   595  		expErr string
   596  	}{
   597  		{offset: 0},
   598  		{offset: -256},
   599  		{offset: 255},
   600  		{offset: 123 * 8},
   601  		{offset: 123 * 4},
   602  		{offset: -257, expErr: "negative memory offset must be larget than or equal -256 but got -257"},
   603  		{offset: 257, expErr: "large memory offset (>255) must be a multiple of 4 but got 257"},
   604  	}
   605  
   606  	for _, tt := range tests {
   607  		tc := tt
   608  		actual := validateMemoryOffset(tc.offset)
   609  		if tc.expErr == "" {
   610  			require.NoError(t, actual)
   611  		} else {
   612  			require.EqualError(t, actual, tc.expErr)
   613  		}
   614  	}
   615  }
   616  
   617  func TestAssemblerImpl_EncodeVectorRegisterToMemory(t *testing.T) {
   618  	tests := []struct {
   619  		name string
   620  		n    *nodeImpl
   621  		exp  []byte
   622  	}{
   623  		// Register offset cases.
   624  		{
   625  			name: "str b11, [x12, x6]",
   626  			n: &nodeImpl{
   627  				instruction:       VMOV,
   628  				srcReg:            RegV11,
   629  				dstReg:            RegR12,
   630  				dstReg2:           RegR6,
   631  				vectorArrangement: VectorArrangementB,
   632  			},
   633  			exp: []byte{0x8b, 0x69, 0x26, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   634  		},
   635  		{
   636  			name: "str h11, [x12, x6]",
   637  			n: &nodeImpl{
   638  				instruction:       VMOV,
   639  				srcReg:            RegV11,
   640  				dstReg:            RegR0,
   641  				dstReg2:           RegR6,
   642  				vectorArrangement: VectorArrangementH,
   643  			},
   644  			exp: []byte{0xb, 0x68, 0x26, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   645  		},
   646  		{
   647  			name: "str s11, [x29, x6]",
   648  			n: &nodeImpl{
   649  				instruction:       VMOV,
   650  				srcReg:            RegV11,
   651  				dstReg:            RegR29,
   652  				dstReg2:           RegR6,
   653  				vectorArrangement: VectorArrangementS,
   654  			},
   655  			exp: []byte{0xab, 0x6b, 0x26, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   656  		},
   657  		{
   658  			name: "str d0, [x0, x0]",
   659  			n: &nodeImpl{
   660  				instruction:       VMOV,
   661  				srcReg:            RegV0,
   662  				dstReg:            RegR0,
   663  				dstReg2:           RegR0,
   664  				vectorArrangement: VectorArrangementD,
   665  			},
   666  			exp: []byte{0x0, 0x68, 0x20, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   667  		},
   668  		{
   669  			name: "str q30, [x30, x29]",
   670  			n: &nodeImpl{
   671  				instruction:       VMOV,
   672  				srcReg:            RegV30,
   673  				dstReg:            RegR30,
   674  				dstReg2:           RegR29,
   675  				vectorArrangement: VectorArrangementQ,
   676  			},
   677  			exp: []byte{0xde, 0x6b, 0xbd, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   678  		},
   679  		// Constant offset cases.
   680  		{
   681  			name: "str b11, [x12, #0x7b]",
   682  			n: &nodeImpl{
   683  				instruction:       VMOV,
   684  				srcReg:            RegV11,
   685  				dstReg:            RegR12,
   686  				dstConst:          0x7b,
   687  				vectorArrangement: VectorArrangementB,
   688  			},
   689  			exp: []byte{0x8b, 0xed, 0x1, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   690  		},
   691  		{
   692  			name: "ldr w10, #0xc ; str h11, [x12, x10]",
   693  			n: &nodeImpl{
   694  				instruction:       VMOV,
   695  				srcReg:            RegV11,
   696  				dstReg:            RegR12,
   697  				dstConst:          1 << 30,
   698  				vectorArrangement: VectorArrangementH,
   699  			},
   700  			exp: []byte{0x6a, 0x0, 0x0, 0x18, 0x8b, 0x69, 0x2a, 0x7c, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x40},
   701  		},
   702  		{
   703  			name: "ldr w10, #0xc ; str s11, [x12, x10]",
   704  			n: &nodeImpl{
   705  				instruction:       VMOV,
   706  				srcReg:            RegV11,
   707  				dstReg:            RegR12,
   708  				dstConst:          (1 << 28) + 4,
   709  				vectorArrangement: VectorArrangementS,
   710  			},
   711  			exp: []byte{0x6a, 0x0, 0x0, 0x18, 0x8b, 0x69, 0x2a, 0xbc, 0x0, 0x0, 0x0, 0x14, 0x4, 0x0, 0x0, 0x10},
   712  		},
   713  		{
   714  			name: "str d11, [x12, #0x3d8]",
   715  			n: &nodeImpl{
   716  				instruction:       VMOV,
   717  				srcReg:            RegV11,
   718  				dstReg:            RegR12,
   719  				dstConst:          0x3d8,
   720  				vectorArrangement: VectorArrangementD,
   721  			},
   722  			exp: []byte{0x8b, 0xed, 0x1, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   723  		},
   724  		{
   725  			name: "stur q1, [x30, #1]",
   726  			n: &nodeImpl{
   727  				instruction:       VMOV,
   728  				srcReg:            RegV1,
   729  				dstReg:            RegR30,
   730  				dstConst:          1,
   731  				vectorArrangement: VectorArrangementQ,
   732  			},
   733  			exp: []byte{0xc1, 0x13, 0x80, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   734  		},
   735  		{
   736  			name: "str q1, [x30, #0x100]",
   737  			n: &nodeImpl{
   738  				instruction:       VMOV,
   739  				srcReg:            RegV1,
   740  				dstReg:            RegR30,
   741  				dstConst:          0x100,
   742  				vectorArrangement: VectorArrangementQ,
   743  			},
   744  			exp: []byte{0xc1, 0x43, 0x80, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   745  		},
   746  		{
   747  			name: "stur q1, [x30, #0xfc]",
   748  			n: &nodeImpl{
   749  				instruction: VMOV,
   750  				srcReg:      RegV1,
   751  				dstReg:      RegR30,
   752  				// This offset is not a multiple of 16 bytes, but fits in 9-bit signed integer,
   753  				// therefore it can be encoded as one instruction of "unscaled immediate".
   754  				dstConst:          0xfc,
   755  				vectorArrangement: VectorArrangementQ,
   756  			},
   757  			exp: []byte{0xc1, 0xc3, 0x8f, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   758  		},
   759  		{
   760  			name: `ldr w10, #0xc; str q11, [x12, x10]`,
   761  			n: &nodeImpl{
   762  				instruction: VMOV,
   763  				srcReg:      RegV11,
   764  				dstReg:      RegR12,
   765  				// This case offset is not a multiple of 16 bytes and doesn't fit in 9-bit signed integer,
   766  				// therefore, we encode the offset in a temporary register, then store it with the register offset variant.
   767  				dstConst:          0x108,
   768  				vectorArrangement: VectorArrangementQ,
   769  			},
   770  			exp: []byte{0x6a, 0x0, 0x0, 0x18, 0x8b, 0x69, 0xaa, 0x3c, 0x0, 0x0, 0x0, 0x14, 0x8, 0x1, 0x0, 0x0},
   771  		},
   772  	}
   773  
   774  	for _, tt := range tests {
   775  		tc := tt
   776  		t.Run(tc.name, func(t *testing.T) {
   777  			a := NewAssembler(RegR10)
   778  			err := a.encodeVectorRegisterToMemory(tc.n)
   779  			require.NoError(t, err)
   780  
   781  			a.maybeFlushConstPool(true)
   782  
   783  			actual, err := a.Assemble()
   784  			require.NoError(t, err)
   785  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
   786  		})
   787  	}
   788  }
   789  
   790  func TestAssemblerImpl_EncodeMemoryToVectorRegister(t *testing.T) {
   791  	tests := []struct {
   792  		name string
   793  		n    *nodeImpl
   794  		exp  []byte
   795  	}{
   796  		// ldr Register offset cases.
   797  		{
   798  			name: "ldr b11, [x12, x8]",
   799  			n: &nodeImpl{
   800  				instruction:       VMOV,
   801  				srcReg:            RegR12,
   802  				srcReg2:           RegR8,
   803  				dstReg:            RegV11,
   804  				vectorArrangement: VectorArrangementB,
   805  			},
   806  			exp: []byte{0x8b, 0x69, 0x68, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   807  		},
   808  		{
   809  			name: "ldr h11, [x30, x0]",
   810  			n: &nodeImpl{
   811  				instruction:       VMOV,
   812  				srcReg:            RegR30,
   813  				srcReg2:           RegR0,
   814  				dstReg:            RegV11,
   815  				vectorArrangement: VectorArrangementH,
   816  			},
   817  			exp: []byte{0xcb, 0x6b, 0x60, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   818  		},
   819  		{
   820  			name: "ldr s11, [x0, x30]",
   821  			n: &nodeImpl{
   822  				instruction:       VMOV,
   823  				srcReg:            RegR0,
   824  				srcReg2:           RegR30,
   825  				dstReg:            RegV11,
   826  				vectorArrangement: VectorArrangementS,
   827  			},
   828  			exp: []byte{0xb, 0x68, 0x7e, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   829  		},
   830  		{
   831  			name: "ldr d11, [x15, x15]",
   832  			n: &nodeImpl{
   833  				instruction:       VMOV,
   834  				srcReg:            RegR15,
   835  				srcReg2:           RegR15,
   836  				dstReg:            RegV11,
   837  				vectorArrangement: VectorArrangementD,
   838  			},
   839  			exp: []byte{0xeb, 0x69, 0x6f, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   840  		},
   841  		{
   842  			name: "ldr q30, [x0, x0]",
   843  			n: &nodeImpl{
   844  				instruction:       VMOV,
   845  				srcReg:            RegR0,
   846  				srcReg2:           RegR0,
   847  				dstReg:            RegV30,
   848  				vectorArrangement: VectorArrangementQ,
   849  			},
   850  			exp: []byte{0x1e, 0x68, 0xe0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   851  		},
   852  		// ldr Constant offset cases.
   853  		{
   854  			name: "ldr b11, [x12, #0x7b]",
   855  			n: &nodeImpl{
   856  				instruction:       VMOV,
   857  				srcReg:            RegR12,
   858  				srcConst:          0x7b,
   859  				dstReg:            RegV11,
   860  				vectorArrangement: VectorArrangementB,
   861  			},
   862  			exp: []byte{0x8b, 0xed, 0x41, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   863  		},
   864  		{
   865  			name: "str h11, [x12, w30, uxtw]",
   866  			n: &nodeImpl{
   867  				instruction:       VMOV,
   868  				dstReg:            RegV11,
   869  				srcReg:            RegR12,
   870  				vectorArrangement: VectorArrangementH,
   871  			},
   872  			exp: []byte{0x8b, 0x1, 0x40, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   873  		},
   874  		{
   875  			name: "ldr w10, #0xc ; ldr s11, [x12, x10]",
   876  			n: &nodeImpl{
   877  				instruction:       VMOV,
   878  				dstReg:            RegV11,
   879  				srcReg:            RegR12,
   880  				srcConst:          1 << 28,
   881  				vectorArrangement: VectorArrangementS,
   882  			},
   883  			exp: []byte{0x6a, 0x0, 0x0, 0x18, 0x8b, 0x69, 0x6a, 0xbc, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x10},
   884  		},
   885  		{
   886  			name: "ldr w10, #0xc ; ldr d11, [x12, x10]",
   887  			n: &nodeImpl{
   888  				instruction:       VMOV,
   889  				dstReg:            RegV11,
   890  				srcReg:            RegR12,
   891  				srcConst:          1<<29 + 4,
   892  				vectorArrangement: VectorArrangementD,
   893  			},
   894  			exp: []byte{0x6a, 0x0, 0x0, 0x18, 0x8b, 0x69, 0x6a, 0xfc, 0x0, 0x0, 0x0, 0x14, 0x4, 0x0, 0x0, 0x20},
   895  		},
   896  		{
   897  			name: "ldr w10, #0xc ; ldr q1, [x30, x10]",
   898  			n: &nodeImpl{
   899  				instruction:       VMOV,
   900  				dstReg:            RegV1,
   901  				srcReg:            RegR30,
   902  				srcConst:          1<<17 + 4,
   903  				vectorArrangement: VectorArrangementQ,
   904  			},
   905  			exp: []byte{0x6a, 0x0, 0x0, 0x18, 0xc1, 0x6b, 0xea, 0x3c, 0x0, 0x0, 0x0, 0x14, 0x4, 0x0, 0x2, 0x0},
   906  		},
   907  		{
   908  			name: "ld1r {v11.8b}, [x12]",
   909  			n: &nodeImpl{
   910  				instruction:       LD1R,
   911  				srcReg:            RegR12,
   912  				dstReg:            RegV11,
   913  				vectorArrangement: VectorArrangement8B,
   914  			},
   915  			exp: []byte{0x8b, 0xc1, 0x40, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   916  		},
   917  		{
   918  			name: "ld1r {v11.16b}, [x12]",
   919  			n: &nodeImpl{
   920  				instruction:       LD1R,
   921  				srcReg:            RegR12,
   922  				dstReg:            RegV11,
   923  				vectorArrangement: VectorArrangement16B,
   924  			},
   925  			exp: []byte{0x8b, 0xc1, 0x40, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   926  		},
   927  		{
   928  			name: "ld1r {v11.4h}, [x12]",
   929  			n: &nodeImpl{
   930  				instruction:       LD1R,
   931  				srcReg:            RegR12,
   932  				dstReg:            RegV11,
   933  				vectorArrangement: VectorArrangement4H,
   934  			},
   935  			exp: []byte{0x8b, 0xc5, 0x40, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   936  		},
   937  		{
   938  			name: "ld1r {v9.8h}, [x0]",
   939  			n: &nodeImpl{
   940  				instruction:       LD1R,
   941  				srcReg:            RegR0,
   942  				dstReg:            RegV0,
   943  				vectorArrangement: VectorArrangement8H,
   944  			},
   945  			exp: []byte{0x0, 0xc4, 0x40, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   946  		},
   947  		{
   948  			name: "ld1r {v11.2s}, [x12]",
   949  			n: &nodeImpl{
   950  				instruction:       LD1R,
   951  				srcReg:            RegR12,
   952  				dstReg:            RegV11,
   953  				vectorArrangement: VectorArrangement2S,
   954  			},
   955  			exp: []byte{0x8b, 0xc9, 0x40, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   956  		},
   957  		{
   958  			name: "ld1r {v0.4s}, [x0]",
   959  			n: &nodeImpl{
   960  				instruction:       LD1R,
   961  				srcReg:            RegR0,
   962  				dstReg:            RegV0,
   963  				vectorArrangement: VectorArrangement4S,
   964  			},
   965  			exp: []byte{0x0, 0xc8, 0x40, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   966  		},
   967  		{
   968  			name: "ld1r {v11.1d}, [x12]",
   969  			n: &nodeImpl{
   970  				instruction:       LD1R,
   971  				srcReg:            RegR12,
   972  				dstReg:            RegV11,
   973  				vectorArrangement: VectorArrangement1D,
   974  			},
   975  			exp: []byte{0x8b, 0xcd, 0x40, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   976  		},
   977  		{
   978  			name: "ld1r {v0.2d}, [x0]",
   979  			n: &nodeImpl{
   980  				instruction:       LD1R,
   981  				srcReg:            RegR0,
   982  				dstReg:            RegV0,
   983  				vectorArrangement: VectorArrangement2D,
   984  			},
   985  			exp: []byte{0x0, 0xcc, 0x40, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   986  		},
   987  	}
   988  
   989  	for _, tt := range tests {
   990  		tc := tt
   991  		t.Run(tc.name, func(t *testing.T) {
   992  			a := NewAssembler(RegR10)
   993  			err := a.encodeMemoryToVectorRegister(tc.n)
   994  			require.NoError(t, err)
   995  
   996  			a.maybeFlushConstPool(true)
   997  
   998  			actual, err := a.Assemble()
   999  			require.NoError(t, err)
  1000  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  1001  		})
  1002  	}
  1003  }
  1004  
  1005  func TestAssemblerImpl_EncodeVectorRegisterToVectorRegister(t *testing.T) {
  1006  	tests := []struct {
  1007  		name               string
  1008  		x1, x2             asm.Register
  1009  		inst               asm.Instruction
  1010  		c                  asm.ConstantValue
  1011  		arr                VectorArrangement
  1012  		srcIndex, dstIndex VectorIndex
  1013  		exp                []byte
  1014  	}{
  1015  		{
  1016  			inst: XTN,
  1017  			name: "xtn v10.2s, v2.2d",
  1018  			x1:   RegV2,
  1019  			x2:   RegV10,
  1020  			arr:  VectorArrangement2D,
  1021  			exp:  []byte{0x4a, 0x28, 0xa1, 0xe},
  1022  		},
  1023  		{
  1024  			inst: XTN,
  1025  			name: "xtn v10.4h, v2.4s",
  1026  			x1:   RegV2,
  1027  			x2:   RegV10,
  1028  			arr:  VectorArrangement4S,
  1029  			exp:  []byte{0x4a, 0x28, 0x61, 0xe},
  1030  		},
  1031  		{
  1032  			inst: XTN,
  1033  			name: "xtn v10.8b, v2.8h",
  1034  			x1:   RegV2,
  1035  			x2:   RegV10,
  1036  			arr:  VectorArrangement8H,
  1037  			exp:  []byte{0x4a, 0x28, 0x21, 0xe},
  1038  		},
  1039  		{
  1040  			inst: REV64,
  1041  			name: "rev64 v10.16b, v2.16b",
  1042  			x1:   RegV2,
  1043  			x2:   RegV10,
  1044  			arr:  VectorArrangement16B,
  1045  			exp:  []byte{0x4a, 0x8, 0x20, 0x4e},
  1046  		},
  1047  		{
  1048  			inst: REV64,
  1049  			name: "rev64 v10.4s, v2.4s",
  1050  			x1:   RegV2,
  1051  			x2:   RegV10,
  1052  			arr:  VectorArrangement4S,
  1053  			exp:  []byte{0x4a, 0x8, 0xa0, 0x4e},
  1054  		},
  1055  		{
  1056  			inst: VCNT,
  1057  			name: "cnt v10.16b, v2.16b",
  1058  			x1:   RegV2,
  1059  			x2:   RegV10,
  1060  			arr:  VectorArrangement16B,
  1061  			exp:  []byte{0x4a, 0x58, 0x20, 0x4e},
  1062  		},
  1063  		{
  1064  			inst: VCNT,
  1065  			name: "cnt v10.8b, v2.8b",
  1066  			x1:   RegV2,
  1067  			x2:   RegV10,
  1068  			arr:  VectorArrangement8B,
  1069  			exp:  []byte{0x4a, 0x58, 0x20, 0xe},
  1070  		},
  1071  		{
  1072  			inst: VNEG,
  1073  			name: "neg v10.16b, v2.16b",
  1074  			x1:   RegV2,
  1075  			x2:   RegV10,
  1076  			arr:  VectorArrangement16B,
  1077  			exp:  []byte{0x4a, 0xb8, 0x20, 0x6e},
  1078  		},
  1079  		{
  1080  			inst: VNEG,
  1081  			name: "neg v10.8h, v2.18h",
  1082  			x1:   RegV2,
  1083  			x2:   RegV10,
  1084  			arr:  VectorArrangement8H,
  1085  			exp:  []byte{0x4a, 0xb8, 0x60, 0x6e},
  1086  		},
  1087  		{
  1088  			inst: VNEG,
  1089  			name: "neg v10.4s, v2.4s",
  1090  			x1:   RegV2,
  1091  			x2:   RegV10,
  1092  			arr:  VectorArrangement4S,
  1093  			exp:  []byte{0x4a, 0xb8, 0xa0, 0x6e},
  1094  		},
  1095  		{
  1096  			inst: VNEG,
  1097  			name: "neg v10.2d, v2.2d",
  1098  			x1:   RegV2,
  1099  			x2:   RegV10,
  1100  			arr:  VectorArrangement2D,
  1101  			exp:  []byte{0x4a, 0xb8, 0xe0, 0x6e},
  1102  		},
  1103  		{
  1104  			inst: VABS,
  1105  			name: "abs v10.16b, v2.16b",
  1106  			x1:   RegV2,
  1107  			x2:   RegV10,
  1108  			arr:  VectorArrangement16B,
  1109  			exp:  []byte{0x4a, 0xb8, 0x20, 0x4e},
  1110  		},
  1111  		{
  1112  			inst: VABS,
  1113  			name: "abs v10.8h, v2.18h",
  1114  			x1:   RegV2,
  1115  			x2:   RegV10,
  1116  			arr:  VectorArrangement8H,
  1117  			exp:  []byte{0x4a, 0xb8, 0x60, 0x4e},
  1118  		},
  1119  		{
  1120  			inst: VABS,
  1121  			name: "abs v10.4s, v2.4s",
  1122  			x1:   RegV2,
  1123  			x2:   RegV10,
  1124  			arr:  VectorArrangement4S,
  1125  			exp:  []byte{0x4a, 0xb8, 0xa0, 0x4e},
  1126  		},
  1127  		{
  1128  			inst: VABS,
  1129  			name: "abs v10.2d, v2.2d",
  1130  			x1:   RegV2,
  1131  			x2:   RegV10,
  1132  			arr:  VectorArrangement2D,
  1133  			exp:  []byte{0x4a, 0xb8, 0xe0, 0x4e},
  1134  		},
  1135  		{
  1136  			inst: ZIP1,
  1137  			name: "zip1 v10.16b, v10.16b, v2.16b",
  1138  			x1:   RegV2,
  1139  			x2:   RegV10,
  1140  			arr:  VectorArrangement16B,
  1141  			exp:  []byte{0x4a, 0x39, 0x2, 0x4e},
  1142  		},
  1143  		{
  1144  			inst: ADDV,
  1145  			name: "addv b10, v2.16b",
  1146  			x1:   RegV2,
  1147  			x2:   RegV10,
  1148  			arr:  VectorArrangement16B,
  1149  			exp:  []byte{0x4a, 0xb8, 0x31, 0x4e},
  1150  		},
  1151  		{
  1152  			inst: VORR,
  1153  			name: "orr v10.16b, v10.16b, v2.16b",
  1154  			x1:   RegV2,
  1155  			x2:   RegV10,
  1156  			arr:  VectorArrangement16B,
  1157  			exp:  []byte{0x4a, 0x1d, 0xa2, 0x4e},
  1158  		},
  1159  		{
  1160  			inst: VORR,
  1161  			name: "orr v10.8b, v10.8b, v2.8b",
  1162  			x1:   RegV2,
  1163  			x2:   RegV10,
  1164  			arr:  VectorArrangement8B,
  1165  			exp:  []byte{0x4a, 0x1d, 0xa2, 0xe},
  1166  		},
  1167  		{
  1168  			name: "fadd v10.2d, v10.2d, v2.2d",
  1169  			x1:   RegV2,
  1170  			x2:   RegV10,
  1171  			inst: VFADDD,
  1172  			arr:  VectorArrangement2D,
  1173  			exp:  []byte{0x4a, 0xd5, 0x62, 0x4e},
  1174  		},
  1175  		{
  1176  			name: "fadd v10.4s, v10.4s, v2.4s",
  1177  			x1:   RegV2,
  1178  			x2:   RegV10,
  1179  			inst: VFADDS,
  1180  			arr:  VectorArrangement4S,
  1181  			exp:  []byte{0x4a, 0xd5, 0x22, 0x4e},
  1182  		},
  1183  		{
  1184  			name: "fsub v10.2d, v10.2d, v2.2d",
  1185  			x1:   RegV2,
  1186  			x2:   RegV10,
  1187  			inst: VFSUBD,
  1188  			arr:  VectorArrangement2D,
  1189  			exp:  []byte{0x4a, 0xd5, 0xe2, 0x4e},
  1190  		},
  1191  		{
  1192  			name: "fsub v10.4s, v10.4s, v2.4s",
  1193  			x1:   RegV2,
  1194  			x2:   RegV10,
  1195  			inst: VFSUBS,
  1196  			arr:  VectorArrangement4S,
  1197  			exp:  []byte{0x4a, 0xd5, 0xa2, 0x4e},
  1198  		},
  1199  		{
  1200  			name: "ushll v10.8h, v2.8b, #0",
  1201  			x1:   RegV2,
  1202  			x2:   RegV10,
  1203  			inst: USHLL,
  1204  			exp:  []byte{0x4a, 0xa4, 0x8, 0x2f},
  1205  			arr:  VectorArrangement8B,
  1206  		},
  1207  		{
  1208  			name: "ushll v10.8h, v2.8b, #7",
  1209  			x1:   RegV2,
  1210  			x2:   RegV10,
  1211  			inst: USHLL,
  1212  			exp:  []byte{0x4a, 0xa4, 0xf, 0x2f},
  1213  			arr:  VectorArrangement8B,
  1214  			c:    7,
  1215  		},
  1216  		{
  1217  			name: "10.8h, v2.8b, #0",
  1218  			x1:   RegV2,
  1219  			x2:   RegV10,
  1220  			inst: SSHR,
  1221  			exp:  []byte{0x4a, 0x4, 0x8, 0x4f},
  1222  			arr:  VectorArrangement16B,
  1223  			c:    8,
  1224  		},
  1225  		{
  1226  			name: "sshr v10.16b, v2.16b, #3",
  1227  			x1:   RegV2,
  1228  			x2:   RegV10,
  1229  			inst: SSHR,
  1230  			exp:  []byte{0x4a, 0x4, 0xd, 0x4f},
  1231  			arr:  VectorArrangement16B,
  1232  			c:    3,
  1233  		},
  1234  		{
  1235  			name: "sshr v10.16b, v2.16b, #1",
  1236  			x1:   RegV2,
  1237  			x2:   RegV10,
  1238  			inst: SSHR,
  1239  			exp:  []byte{0x4a, 0x4, 0xf, 0x4f},
  1240  			arr:  VectorArrangement16B,
  1241  			c:    1,
  1242  		},
  1243  		{
  1244  			name: "sshr v10.8b, v2.8b, #3",
  1245  			x1:   RegV2,
  1246  			x2:   RegV10,
  1247  			inst: SSHR,
  1248  			exp:  []byte{0x4a, 0x4, 0xd, 0xf},
  1249  			arr:  VectorArrangement8B,
  1250  			c:    3,
  1251  		},
  1252  		{
  1253  			name: "sshr v10.8h, v2.8h, #0x10",
  1254  			x1:   RegV2,
  1255  			x2:   RegV10,
  1256  			inst: SSHR,
  1257  			exp:  []byte{0x4a, 0x4, 0x10, 0x4f},
  1258  			arr:  VectorArrangement8H,
  1259  			c:    16,
  1260  		},
  1261  		{
  1262  			name: "sshr v10.8h, v2.8h, #0xf",
  1263  			x1:   RegV2,
  1264  			x2:   RegV10,
  1265  			inst: SSHR,
  1266  			exp:  []byte{0x4a, 0x4, 0x11, 0x4f},
  1267  			arr:  VectorArrangement8H,
  1268  			c:    15,
  1269  		},
  1270  		{
  1271  			name: "sshr v10.8h, v2.8h, #3",
  1272  			x1:   RegV2,
  1273  			x2:   RegV10,
  1274  			inst: SSHR,
  1275  			exp:  []byte{0x4a, 0x4, 0x1d, 0x4f},
  1276  			arr:  VectorArrangement8H,
  1277  			c:    3,
  1278  		},
  1279  		{
  1280  			name: "sshr v10.4h, v2.4h, #0xf",
  1281  			x1:   RegV2,
  1282  			x2:   RegV10,
  1283  			inst: SSHR,
  1284  			exp:  []byte{0x4a, 0x4, 0x11, 0xf},
  1285  			arr:  VectorArrangement4H,
  1286  			c:    15,
  1287  		},
  1288  		{
  1289  			name: "sshr v10.2s, v2.2s, #0x20",
  1290  			x1:   RegV2,
  1291  			x2:   RegV10,
  1292  			inst: SSHR,
  1293  			exp:  []byte{0x4a, 0x4, 0x20, 0xf},
  1294  			arr:  VectorArrangement2S,
  1295  			c:    32,
  1296  		},
  1297  		{
  1298  			name: "sshr v10.2s, v2.2s, #0x1f",
  1299  			x1:   RegV2,
  1300  			x2:   RegV10,
  1301  			inst: SSHR,
  1302  			exp:  []byte{0x4a, 0x4, 0x21, 0xf},
  1303  			arr:  VectorArrangement2S,
  1304  			c:    31,
  1305  		},
  1306  		{
  1307  			name: "sshr v10.2s, v2.2s, #7",
  1308  			x1:   RegV2,
  1309  			x2:   RegV10,
  1310  			inst: SSHR,
  1311  			exp:  []byte{0x4a, 0x4, 0x39, 0xf},
  1312  			arr:  VectorArrangement2S,
  1313  			c:    7,
  1314  		},
  1315  		{
  1316  			name: "sshr v10.4s, v2.4s, #7",
  1317  			x1:   RegV2,
  1318  			x2:   RegV10,
  1319  			inst: SSHR,
  1320  			exp:  []byte{0x4a, 0x4, 0x39, 0x4f},
  1321  			arr:  VectorArrangement4S,
  1322  			c:    7,
  1323  		},
  1324  		{
  1325  			name: "sshr v10.2d, v2.2d, #0x3f",
  1326  			x1:   RegV2,
  1327  			x2:   RegV10,
  1328  			inst: SSHR,
  1329  			exp:  []byte{0x4a, 0x4, 0x41, 0x4f},
  1330  			arr:  VectorArrangement2D,
  1331  			c:    63,
  1332  		},
  1333  		{
  1334  			name: "sshr v10.2d, v2.2d, #0x21",
  1335  			x1:   RegV2,
  1336  			x2:   RegV10,
  1337  			inst: SSHR,
  1338  			exp:  []byte{0x4a, 0x4, 0x5f, 0x4f},
  1339  			arr:  VectorArrangement2D,
  1340  			c:    33,
  1341  		},
  1342  		{
  1343  			name: "sshr v10.2d, v2.2d, #1",
  1344  			x1:   RegV2,
  1345  			x2:   RegV10,
  1346  			inst: SSHR,
  1347  			exp:  []byte{0x4a, 0x4, 0x7f, 0x4f},
  1348  			arr:  VectorArrangement2D,
  1349  			c:    1,
  1350  		},
  1351  		{
  1352  			name: "sshll v10.8h, v2.8b, #7",
  1353  			x1:   RegV2,
  1354  			x2:   RegV10,
  1355  			inst: SSHLL, exp: []byte{0x4a, 0xa4, 0xf, 0xf},
  1356  			arr: VectorArrangement8B,
  1357  			c:   7,
  1358  		},
  1359  		{
  1360  			name: "sshll v10.4s, v2.4h, #0",
  1361  			x1:   RegV2,
  1362  			x2:   RegV10,
  1363  			inst: SSHLL,
  1364  			exp:  []byte{0x4a, 0xa4, 0x10, 0xf},
  1365  			arr:  VectorArrangement4H,
  1366  		},
  1367  		{
  1368  			name: "sshll v10.4s, v2.4h, #0xf",
  1369  			x1:   RegV2,
  1370  			x2:   RegV10,
  1371  			inst: SSHLL,
  1372  			exp:  []byte{0x4a, 0xa4, 0x1f, 0xf},
  1373  			arr:  VectorArrangement4H,
  1374  			c:    15,
  1375  		},
  1376  		{
  1377  			name: "sshll v10.2d, v2.2s, #0",
  1378  			x1:   RegV2,
  1379  			x2:   RegV10,
  1380  			inst: SSHLL,
  1381  			exp:  []byte{0x4a, 0xa4, 0x20, 0xf},
  1382  			arr:  VectorArrangement2S,
  1383  		},
  1384  		{
  1385  			name: "sshll v10.2d, v2.2s, #0x1f",
  1386  			x1:   RegV2,
  1387  			x2:   RegV10,
  1388  			inst: SSHLL,
  1389  			exp:  []byte{0x4a, 0xa4, 0x3f, 0xf},
  1390  			arr:  VectorArrangement2S,
  1391  			c:    31,
  1392  		},
  1393  		{
  1394  			x1:       RegV2,
  1395  			x2:       RegV10,
  1396  			name:     "ins v10.s[2], v2.s[1]",
  1397  			inst:     INSELEM,
  1398  			exp:      []byte{0x4a, 0x24, 0x14, 0x6e},
  1399  			arr:      VectorArrangementS,
  1400  			srcIndex: 1,
  1401  			dstIndex: 2,
  1402  		},
  1403  		{
  1404  			x1:       RegV2,
  1405  			x2:       RegV10,
  1406  			name:     "ins v10.s[0], v2.s[3]",
  1407  			inst:     INSELEM,
  1408  			exp:      []byte{0x4a, 0x64, 0x4, 0x6e},
  1409  			arr:      VectorArrangementS,
  1410  			srcIndex: 3,
  1411  			dstIndex: 0,
  1412  		},
  1413  		{
  1414  			x1:       RegV2,
  1415  			x2:       RegV10,
  1416  			name:     "ins v10.b[0], v2.b[0xf]",
  1417  			inst:     INSELEM,
  1418  			exp:      []byte{0x4a, 0x7c, 0x1, 0x6e},
  1419  			arr:      VectorArrangementB,
  1420  			srcIndex: 15,
  1421  			dstIndex: 0,
  1422  		},
  1423  		{
  1424  			x1:       RegV2,
  1425  			x2:       RegV10,
  1426  			name:     "ins v10.d[1], v2.d[0]",
  1427  			inst:     INSELEM,
  1428  			exp:      []byte{0x4a, 0x4, 0x18, 0x6e},
  1429  			arr:      VectorArrangementD,
  1430  			srcIndex: 0,
  1431  			dstIndex: 1,
  1432  		},
  1433  		{
  1434  			x1:       RegV2,
  1435  			x2:       RegV10,
  1436  			name:     "dup v10.2d, v2.d[0]",
  1437  			inst:     DUPELEM,
  1438  			exp:      []byte{0x4a, 0x4, 0x8, 0x4e},
  1439  			arr:      VectorArrangementD,
  1440  			srcIndex: 0,
  1441  		},
  1442  		{
  1443  			x1:       RegV2,
  1444  			x2:       RegV10,
  1445  			name:     "dup v10.2d, v2.d[1]",
  1446  			inst:     DUPELEM,
  1447  			exp:      []byte{0x4a, 0x4, 0x18, 0x4e},
  1448  			arr:      VectorArrangementD,
  1449  			srcIndex: 1,
  1450  		},
  1451  		{
  1452  			x1:       RegV2,
  1453  			x2:       RegV10,
  1454  			name:     "dup v10.4s, v2.s[3]",
  1455  			inst:     DUPELEM,
  1456  			exp:      []byte{0x4a, 0x4, 0x1c, 0x4e},
  1457  			arr:      VectorArrangementS,
  1458  			srcIndex: 3,
  1459  		},
  1460  		{
  1461  			x1:       RegV2,
  1462  			x2:       RegV10,
  1463  			name:     "dup v10.8h, v2.h[7]",
  1464  			inst:     DUPELEM,
  1465  			exp:      []byte{0x4a, 0x4, 0x1e, 0x4e},
  1466  			arr:      VectorArrangementH,
  1467  			srcIndex: 7,
  1468  		},
  1469  		{
  1470  			x1:       RegV2,
  1471  			x2:       RegV10,
  1472  			name:     "dup v10.16b, v2.b[0xf]",
  1473  			inst:     DUPELEM,
  1474  			exp:      []byte{0x4a, 0x4, 0x1f, 0x4e},
  1475  			arr:      VectorArrangementB,
  1476  			srcIndex: 15,
  1477  		},
  1478  		{
  1479  			x1:   RegV2,
  1480  			x2:   RegV10,
  1481  			name: "umaxp v10.16b, v10.16b, v2.16b",
  1482  			inst: UMAXP,
  1483  			exp:  []byte{0x4a, 0xa5, 0x22, 0x6e},
  1484  			arr:  VectorArrangement16B,
  1485  		},
  1486  		{
  1487  			x1:   RegV2,
  1488  			x2:   RegV10,
  1489  			name: "umaxp v10.8h, v10.8h, v2.8h",
  1490  			inst: UMAXP,
  1491  			exp:  []byte{0x4a, 0xa5, 0x62, 0x6e},
  1492  			arr:  VectorArrangement8H,
  1493  		},
  1494  		{
  1495  			x1:   RegV2,
  1496  			x2:   RegV10,
  1497  			name: "umaxp v10.4s, v10.4s, v2.4s",
  1498  			inst: UMAXP,
  1499  			exp:  []byte{0x4a, 0xa5, 0xa2, 0x6e},
  1500  			arr:  VectorArrangement4S,
  1501  		},
  1502  		{
  1503  			x1:   RegV11,
  1504  			x2:   RegV11,
  1505  			name: "addp d11, v11.2d",
  1506  			inst: ADDP,
  1507  			arr:  VectorArrangement2D,
  1508  			exp:  []byte{0x6b, 0xb9, 0xf1, 0x5e},
  1509  		},
  1510  		{
  1511  			x1:   RegV2,
  1512  			x2:   RegV10,
  1513  			name: "addp v10.16b, v10.16b, v2.16b",
  1514  			inst: VADDP,
  1515  			exp:  []byte{0x4a, 0xbd, 0x22, 0x4e},
  1516  			arr:  VectorArrangement16B,
  1517  		},
  1518  		{
  1519  			x1:   RegV2,
  1520  			x2:   RegV10,
  1521  			name: "addp v10.8h, v10.8h, v2.8h",
  1522  			inst: VADDP,
  1523  			exp:  []byte{0x4a, 0xbd, 0x62, 0x4e},
  1524  			arr:  VectorArrangement8H,
  1525  		},
  1526  		{
  1527  			x1:   RegV2,
  1528  			x2:   RegV10,
  1529  			name: "addp v10.4s, v10.4s, v2.4s",
  1530  			inst: VADDP,
  1531  			exp:  []byte{0x4a, 0xbd, 0xa2, 0x4e},
  1532  			arr:  VectorArrangement4S,
  1533  		},
  1534  		{
  1535  			x1:   RegV2,
  1536  			x2:   RegV10,
  1537  			name: "uminv b10, v2.16b",
  1538  			inst: UMINV,
  1539  			exp:  []byte{0x4a, 0xa8, 0x31, 0x6e},
  1540  			arr:  VectorArrangement16B,
  1541  		},
  1542  		{
  1543  			x1:   RegV2,
  1544  			x2:   RegV10,
  1545  			name: "uminv h10, v2.8h",
  1546  			inst: UMINV,
  1547  			exp:  []byte{0x4a, 0xa8, 0x71, 0x6e},
  1548  			arr:  VectorArrangement8H,
  1549  		},
  1550  		{
  1551  			x1:   RegV2,
  1552  			x2:   RegV10,
  1553  			name: "uminv s10, v2.4s",
  1554  			inst: UMINV,
  1555  			exp:  []byte{0x4a, 0xa8, 0xb1, 0x6e},
  1556  			arr:  VectorArrangement4S,
  1557  		},
  1558  		{
  1559  			x1:   RegV2,
  1560  			x2:   RegV10,
  1561  			name: "cmeq v10.2d, v10.2d, v2.2d",
  1562  			arr:  VectorArrangement2D,
  1563  			inst: CMEQ,
  1564  			exp:  []byte{0x4a, 0x8d, 0xe2, 0x6e},
  1565  		},
  1566  		{
  1567  			x1:   RegRZR,
  1568  			x2:   RegV12,
  1569  			name: "cmeq v12.2d, v12.2d, #0",
  1570  			inst: CMEQZERO,
  1571  			arr:  VectorArrangement2D,
  1572  			exp:  []byte{0x8c, 0x99, 0xe0, 0x4e},
  1573  		},
  1574  		{
  1575  			name: "tbl v1.8b, {v0.16b}, v1.8b",
  1576  			x1:   RegV0,
  1577  			x2:   RegV1,
  1578  			inst: TBL1,
  1579  			arr:  VectorArrangement8B,
  1580  			exp:  []byte{0x1, 0x0, 0x1, 0xe},
  1581  		},
  1582  		{
  1583  			name: "tbl v1.16b, {v0.16b}, v1.16b",
  1584  			x1:   RegV0,
  1585  			x2:   RegV1,
  1586  			inst: TBL1,
  1587  			arr:  VectorArrangement16B,
  1588  			exp:  []byte{0x1, 0x0, 0x1, 0x4e},
  1589  		},
  1590  		{
  1591  			name: "tbl v30.8b, {v0.16b, v1.16b}, v30.8b",
  1592  			x1:   RegV0,
  1593  			x2:   RegV30,
  1594  			inst: TBL2,
  1595  			arr:  VectorArrangement8B,
  1596  			exp:  []byte{0x1e, 0x20, 0x1e, 0xe},
  1597  		},
  1598  		{
  1599  			name: "tbl v1.16b, {v31.16b, v0.16b}, v1.16b",
  1600  			x1:   RegV31,
  1601  			x2:   RegV1,
  1602  			inst: TBL2,
  1603  			arr:  VectorArrangement16B,
  1604  			exp:  []byte{0xe1, 0x23, 0x1, 0x4e},
  1605  		},
  1606  		{
  1607  			x1:   RegV2,
  1608  			x2:   RegV10,
  1609  			name: "add v10.4s, v10.4s, v2.4s",
  1610  			inst: VADD,
  1611  			exp:  []byte{0x4a, 0x85, 0xa2, 0x4e},
  1612  			arr:  VectorArrangement4S,
  1613  		},
  1614  		{
  1615  			x1:   RegV2,
  1616  			x2:   RegV10,
  1617  			name: "add v10.2d, v10.2d, v2.2d",
  1618  			inst: VADD,
  1619  			exp:  []byte{0x4a, 0x85, 0xe2, 0x4e},
  1620  			arr:  VectorArrangement2D,
  1621  		},
  1622  		{
  1623  			x1:   RegV2,
  1624  			x2:   RegV10,
  1625  			name: "sub v10.8h, v10.8h, v2.8h",
  1626  			inst: VSUB,
  1627  			exp:  []byte{0x4a, 0x85, 0x62, 0x6e},
  1628  			arr:  VectorArrangement8H,
  1629  		},
  1630  		{
  1631  			x1:   RegV29,
  1632  			x2:   RegV30,
  1633  			name: "sub v30.16b, v30.16b, v29.16b",
  1634  			inst: VSUB,
  1635  			exp:  []byte{0xde, 0x87, 0x3d, 0x6e},
  1636  			arr:  VectorArrangement16B,
  1637  		},
  1638  		{
  1639  			name: "bic v10.16b, v10.16b, v2.16b",
  1640  			x1:   RegV2,
  1641  			x2:   RegV10,
  1642  			inst: BIC,
  1643  			arr:  VectorArrangement16B,
  1644  			exp:  []byte{0x4a, 0x1d, 0x62, 0x4e},
  1645  		},
  1646  		{
  1647  			name: "eor v10.16b, v10.16b, v2.16b",
  1648  			x1:   RegV2,
  1649  			x2:   RegV10,
  1650  			inst: EOR,
  1651  			arr:  VectorArrangement16B,
  1652  			exp:  []byte{0x4a, 0x1d, 0x22, 0x6e},
  1653  		},
  1654  		{
  1655  			name: "bsl v10.16b, v10.16b, v2.16b",
  1656  			x1:   RegV2,
  1657  			x2:   RegV10,
  1658  			inst: BSL,
  1659  			arr:  VectorArrangement16B,
  1660  			exp:  []byte{0x4a, 0x1d, 0x62, 0x6e},
  1661  		},
  1662  		{
  1663  			name: "bsl v10.16b, v10.16b, v2.16b",
  1664  			x1:   RegV2,
  1665  			x2:   RegV10,
  1666  			inst: BSL,
  1667  			arr:  VectorArrangement16B,
  1668  			exp:  []byte{0x4a, 0x1d, 0x62, 0x6e},
  1669  		},
  1670  		{
  1671  			name: "and v10.16b, v10.16b, v2.16b",
  1672  			x1:   RegV2,
  1673  			x2:   RegV10,
  1674  			inst: VAND,
  1675  			arr:  VectorArrangement16B,
  1676  			exp:  []byte{0x4a, 0x1d, 0x22, 0x4e},
  1677  		},
  1678  		{
  1679  			// mvn is an alias of NOT: https://developer.arm.com/documentation/ddi0596/2020-12/SIMD-FP-Instructions/MVN--Bitwise-NOT--vector---an-alias-of-NOT-?lang=en
  1680  			name: "mvn v10.16b, v2.16b",
  1681  			x1:   RegV2,
  1682  			x2:   RegV10,
  1683  			inst: NOT,
  1684  			arr:  VectorArrangement16B,
  1685  			exp:  []byte{0x4a, 0x58, 0x20, 0x6e},
  1686  		},
  1687  		{
  1688  			name: "fneg v10.2d, v2.2d",
  1689  			x1:   RegV2,
  1690  			x2:   RegV10,
  1691  			inst: VFNEG,
  1692  			arr:  VectorArrangement2D,
  1693  			exp:  []byte{0x4a, 0xf8, 0xe0, 0x6e},
  1694  		},
  1695  		{
  1696  			name: "fneg v10.4s, v2.4s",
  1697  			x1:   RegV2,
  1698  			x2:   RegV10,
  1699  			inst: VFNEG,
  1700  			arr:  VectorArrangement4S,
  1701  			exp:  []byte{0x4a, 0xf8, 0xa0, 0x6e},
  1702  		},
  1703  		{
  1704  			x1:   RegV2,
  1705  			x2:   RegV10,
  1706  			name: "sshl v10.2d, v10.2d, v2.2d",
  1707  			inst: SSHL,
  1708  			exp:  []byte{0x4a, 0x45, 0xe2, 0x4e},
  1709  			arr:  VectorArrangement2D,
  1710  		},
  1711  		{
  1712  			x1:   RegV25,
  1713  			x2:   RegV30,
  1714  			name: "sshl v30.4s, v30.4s, v25.4s",
  1715  			inst: SSHL,
  1716  			exp:  []byte{0xde, 0x47, 0xb9, 0x4e},
  1717  			arr:  VectorArrangement4S,
  1718  		},
  1719  		{
  1720  			x1:   RegV2,
  1721  			x2:   RegV10,
  1722  			name: "ushl v10.8h, v10.8h, v2.8h",
  1723  			inst: USHL,
  1724  			exp:  []byte{0x4a, 0x45, 0x62, 0x6e},
  1725  			arr:  VectorArrangement8H,
  1726  		},
  1727  		{
  1728  			x1:   RegV25,
  1729  			x2:   RegV30,
  1730  			name: "ushl v30.16b, v30.16b, v25.16b",
  1731  			inst: USHL,
  1732  			exp:  []byte{0xde, 0x47, 0x39, 0x6e},
  1733  			arr:  VectorArrangement16B,
  1734  		},
  1735  		{
  1736  			x1:   RegV25,
  1737  			x2:   RegV30,
  1738  			name: "fabs v30.4s, v25.4s",
  1739  			inst: VFABS,
  1740  			exp:  []byte{0x3e, 0xfb, 0xa0, 0x4e},
  1741  			arr:  VectorArrangement4S,
  1742  		},
  1743  		{
  1744  			x1:   RegV25,
  1745  			x2:   RegV30,
  1746  			name: "fabs v30.2s, v25.2s",
  1747  			inst: VFABS,
  1748  			exp:  []byte{0x3e, 0xfb, 0xa0, 0xe},
  1749  			arr:  VectorArrangement2S,
  1750  		},
  1751  		{
  1752  			x1:   RegV25,
  1753  			x2:   RegV30,
  1754  			name: "fabs v30.2d, v25.2d",
  1755  			inst: VFABS,
  1756  			exp:  []byte{0x3e, 0xfb, 0xe0, 0x4e},
  1757  			arr:  VectorArrangement2D,
  1758  		},
  1759  		{
  1760  			x1:   RegV25,
  1761  			x2:   RegV30,
  1762  			name: "fsqrt v30.4s, v25.4s",
  1763  			inst: VFSQRT,
  1764  			exp:  []byte{0x3e, 0xfb, 0xa1, 0x6e},
  1765  			arr:  VectorArrangement4S,
  1766  		},
  1767  		{
  1768  			x1:   RegV25,
  1769  			x2:   RegV30,
  1770  			name: "fsqrt v30.2s, v25.2s",
  1771  			inst: VFSQRT,
  1772  			exp:  []byte{0x3e, 0xfb, 0xa1, 0x2e},
  1773  			arr:  VectorArrangement2S,
  1774  		},
  1775  		{
  1776  			x1:   RegV25,
  1777  			x2:   RegV30,
  1778  			name: "fsqrt v30.2d, v25.2d",
  1779  			inst: VFSQRT,
  1780  			exp:  []byte{0x3e, 0xfb, 0xe1, 0x6e},
  1781  			arr:  VectorArrangement2D,
  1782  		},
  1783  		{
  1784  			x1:   RegV25,
  1785  			x2:   RegV30,
  1786  			name: "frintm v30.4s, v25.4s",
  1787  			inst: VFRINTM,
  1788  			exp:  []byte{0x3e, 0x9b, 0x21, 0x4e},
  1789  			arr:  VectorArrangement4S,
  1790  		},
  1791  		{
  1792  			x1:   RegV25,
  1793  			x2:   RegV30,
  1794  			name: "frintm v30.2s, v25.2s",
  1795  			inst: VFRINTM,
  1796  			exp:  []byte{0x3e, 0x9b, 0x21, 0xe},
  1797  			arr:  VectorArrangement2S,
  1798  		},
  1799  		{
  1800  			x1:   RegV25,
  1801  			x2:   RegV30,
  1802  			name: "frintm v30.2d, v25.2d",
  1803  			inst: VFRINTM,
  1804  			exp:  []byte{0x3e, 0x9b, 0x61, 0x4e},
  1805  			arr:  VectorArrangement2D,
  1806  		},
  1807  		{
  1808  			x1:   RegV25,
  1809  			x2:   RegV30,
  1810  			name: "frintn v30.4s, v25.4s",
  1811  			inst: VFRINTN,
  1812  			exp:  []byte{0x3e, 0x8b, 0x21, 0x4e},
  1813  			arr:  VectorArrangement4S,
  1814  		},
  1815  		{
  1816  			x1:   RegV25,
  1817  			x2:   RegV30,
  1818  			name: "frintn v30.2s, v25.2s",
  1819  			inst: VFRINTN,
  1820  			exp:  []byte{0x3e, 0x8b, 0x21, 0xe},
  1821  			arr:  VectorArrangement2S,
  1822  		},
  1823  		{
  1824  			x1:   RegV25,
  1825  			x2:   RegV30,
  1826  			name: "frintn v30.2d, v25.2d",
  1827  			inst: VFRINTN,
  1828  			exp:  []byte{0x3e, 0x8b, 0x61, 0x4e},
  1829  			arr:  VectorArrangement2D,
  1830  		},
  1831  		{
  1832  			x1:   RegV25,
  1833  			x2:   RegV30,
  1834  			name: "frintp v30.4s, v25.4s",
  1835  			inst: VFRINTP,
  1836  			exp:  []byte{0x3e, 0x8b, 0xa1, 0x4e},
  1837  			arr:  VectorArrangement4S,
  1838  		},
  1839  		{
  1840  			x1:   RegV25,
  1841  			x2:   RegV30,
  1842  			name: "frintp v30.2s, v25.2s",
  1843  			inst: VFRINTP,
  1844  			exp:  []byte{0x3e, 0x8b, 0xa1, 0xe},
  1845  			arr:  VectorArrangement2S,
  1846  		},
  1847  		{
  1848  			x1:   RegV25,
  1849  			x2:   RegV30,
  1850  			name: "frintp v30.2d, v25.2d",
  1851  			inst: VFRINTP,
  1852  			exp:  []byte{0x3e, 0x8b, 0xe1, 0x4e},
  1853  			arr:  VectorArrangement2D,
  1854  		},
  1855  		{
  1856  			x1:   RegV25,
  1857  			x2:   RegV30,
  1858  			name: "frintp v30.4s, v25.4s",
  1859  			inst: VFRINTN,
  1860  			exp:  []byte{0x3e, 0x8b, 0x21, 0x4e},
  1861  			arr:  VectorArrangement4S,
  1862  		},
  1863  		{
  1864  			x1:   RegV25,
  1865  			x2:   RegV30,
  1866  			name: "frintp v30.2s, v25.2s",
  1867  			inst: VFRINTN,
  1868  			exp:  []byte{0x3e, 0x8b, 0x21, 0xe},
  1869  			arr:  VectorArrangement2S,
  1870  		},
  1871  		{
  1872  			x1:   RegV25,
  1873  			x2:   RegV30,
  1874  			name: "frintp v30.2d, v25.2d",
  1875  			inst: VFRINTN,
  1876  			exp:  []byte{0x3e, 0x8b, 0x61, 0x4e},
  1877  			arr:  VectorArrangement2D,
  1878  		},
  1879  		{
  1880  			x1:   RegV25,
  1881  			x2:   RegV30,
  1882  			name: "shll v30.8h, v25.8b, #8",
  1883  			inst: SHLL,
  1884  			exp:  []byte{0x3e, 0x3b, 0x21, 0x2e},
  1885  			arr:  VectorArrangement8B,
  1886  		},
  1887  		{
  1888  			x1:   RegV25,
  1889  			x2:   RegV30,
  1890  			name: "shll v30.4s, v25.4h, #16",
  1891  			inst: SHLL,
  1892  			exp:  []byte{0x3e, 0x3b, 0x61, 0x2e},
  1893  			arr:  VectorArrangement4H,
  1894  		},
  1895  		{
  1896  			x1:   RegV25,
  1897  			x2:   RegV30,
  1898  			name: "shll v30.2d, v25.2s, #32",
  1899  			inst: SHLL,
  1900  			exp:  []byte{0x3e, 0x3b, 0xa1, 0x2e},
  1901  			arr:  VectorArrangement2S,
  1902  		},
  1903  		{
  1904  			x1:   RegV25,
  1905  			x2:   RegV30,
  1906  			name: "uaddlv h30, v25.16b",
  1907  			inst: UADDLV,
  1908  			exp:  []byte{0x3e, 0x3b, 0x30, 0x6e},
  1909  			arr:  VectorArrangement16B,
  1910  		},
  1911  		{
  1912  			x1:   RegV25,
  1913  			x2:   RegV30,
  1914  			name: "uaddlv s30, v25.8h",
  1915  			inst: UADDLV,
  1916  			exp:  []byte{0x3e, 0x3b, 0x70, 0x6e},
  1917  			arr:  VectorArrangement8H,
  1918  		},
  1919  		{
  1920  			x1:   RegV25,
  1921  			x2:   RegV30,
  1922  			name: "uaddlv d30, v25.4s",
  1923  			inst: UADDLV,
  1924  			exp:  []byte{0x3e, 0x3b, 0xb0, 0x6e},
  1925  			arr:  VectorArrangement4S,
  1926  		},
  1927  		{
  1928  			x1:   RegV25,
  1929  			x2:   RegV30,
  1930  			name: "saddlp v30.2d, v25.4s",
  1931  			inst: SADDLP,
  1932  			exp:  []byte{0x3e, 0x2b, 0xa0, 0x4e},
  1933  			arr:  VectorArrangement4S,
  1934  		},
  1935  		{
  1936  			x1:   RegV25,
  1937  			x2:   RegV30,
  1938  			name: "saddlp v30.4s, v25.8h",
  1939  			inst: SADDLP,
  1940  			exp:  []byte{0x3e, 0x2b, 0x60, 0x4e},
  1941  			arr:  VectorArrangement8H,
  1942  		},
  1943  		{
  1944  			x1:   RegV25,
  1945  			x2:   RegV30,
  1946  			name: "uaddlp v30.2d, v25.4s",
  1947  			inst: UADDLP,
  1948  			exp:  []byte{0x3e, 0x2b, 0xa0, 0x6e},
  1949  			arr:  VectorArrangement4S,
  1950  		},
  1951  		{
  1952  			x1:   RegV25,
  1953  			x2:   RegV30,
  1954  			name: "uaddlp v30.4s, v25.8h",
  1955  			inst: UADDLP,
  1956  			exp:  []byte{0x3e, 0x2b, 0x60, 0x6e},
  1957  			arr:  VectorArrangement8H,
  1958  		},
  1959  		{
  1960  			name: "sshll2 v10.8h, v2.16b, #7",
  1961  			x1:   RegV2,
  1962  			x2:   RegV10,
  1963  			inst: SSHLL2,
  1964  			exp:  []byte{0x4a, 0xa4, 0xf, 0x4f},
  1965  			arr:  VectorArrangement16B,
  1966  			c:    7,
  1967  		},
  1968  		{
  1969  			name: "sshll2 v10.4s, v2.8h, #0",
  1970  			x1:   RegV2,
  1971  			x2:   RegV10,
  1972  			inst: SSHLL2,
  1973  			exp:  []byte{0x4a, 0xa4, 0x10, 0x4f},
  1974  			arr:  VectorArrangement8H,
  1975  		},
  1976  		{
  1977  			name: "sshll2 v10.2d, v2.4s, #0x15",
  1978  			x1:   RegV2,
  1979  			x2:   RegV10,
  1980  			inst: SSHLL2,
  1981  			exp:  []byte{0x4a, 0xa4, 0x35, 0x4f},
  1982  			arr:  VectorArrangement4S,
  1983  			c:    21,
  1984  		},
  1985  		{
  1986  			name: "ushll2 v10.8h, v2.16b, #7",
  1987  			x1:   RegV2,
  1988  			x2:   RegV10,
  1989  			inst: USHLL2,
  1990  			exp:  []byte{0x4a, 0xa4, 0xf, 0x6f},
  1991  			arr:  VectorArrangement16B,
  1992  			c:    7,
  1993  		},
  1994  		{
  1995  			name: "ushll2 v10.4s, v2.8h, #0",
  1996  			x1:   RegV2,
  1997  			x2:   RegV10,
  1998  			inst: USHLL2,
  1999  			exp:  []byte{0x4a, 0xa4, 0x10, 0x6f},
  2000  			arr:  VectorArrangement8H,
  2001  		},
  2002  		{
  2003  			name: "ushll2 v10.2d, v2.4s, #0x15",
  2004  			x1:   RegV2,
  2005  			x2:   RegV10,
  2006  			inst: USHLL2,
  2007  			exp:  []byte{0x4a, 0xa4, 0x35, 0x6f},
  2008  			arr:  VectorArrangement4S,
  2009  			c:    21,
  2010  		},
  2011  		{
  2012  			x1:   RegV25,
  2013  			x2:   RegV30,
  2014  			name: "fcvtzs v30.4s, v25.4s",
  2015  			inst: VFCVTZS,
  2016  			exp:  []byte{0x3e, 0xbb, 0xa1, 0x4e},
  2017  			arr:  VectorArrangement4S,
  2018  		},
  2019  		{
  2020  			x1:   RegV25,
  2021  			x2:   RegV30,
  2022  			name: "fcvtzs v30.2s, v25.2s",
  2023  			inst: VFCVTZS,
  2024  			exp:  []byte{0x3e, 0xbb, 0xa1, 0xe},
  2025  			arr:  VectorArrangement2S,
  2026  		},
  2027  		{
  2028  			x1:   RegV25,
  2029  			x2:   RegV30,
  2030  			name: "fcvtzs v30.2d, v25.2d",
  2031  			inst: VFCVTZS,
  2032  			exp:  []byte{0x3e, 0xbb, 0xe1, 0x4e},
  2033  			arr:  VectorArrangement2D,
  2034  		},
  2035  		{
  2036  			x1:   RegV25,
  2037  			x2:   RegV30,
  2038  			name: "fcvtzu v30.4s, v25.4s",
  2039  			inst: VFCVTZU,
  2040  			exp:  []byte{0x3e, 0xbb, 0xa1, 0x6e},
  2041  			arr:  VectorArrangement4S,
  2042  		},
  2043  		{
  2044  			x1:   RegV25,
  2045  			x2:   RegV30,
  2046  			name: "fcvtzu v30.2s, v25.2s",
  2047  			inst: VFCVTZU,
  2048  			exp:  []byte{0x3e, 0xbb, 0xa1, 0x2e},
  2049  			arr:  VectorArrangement2S,
  2050  		},
  2051  		{
  2052  			x1:   RegV25,
  2053  			x2:   RegV30,
  2054  			name: "fcvtzu v30.2d, v25.2d",
  2055  			inst: VFCVTZU,
  2056  			exp:  []byte{0x3e, 0xbb, 0xe1, 0x6e},
  2057  			arr:  VectorArrangement2D,
  2058  		},
  2059  		{
  2060  			x1:   RegV25,
  2061  			x2:   RegV30,
  2062  			name: "sqxtn v30.2s, v25.2d",
  2063  			inst: SQXTN,
  2064  			exp:  []byte{0x3e, 0x4b, 0xa1, 0xe},
  2065  			arr:  VectorArrangement2S,
  2066  		},
  2067  		{
  2068  			x1:   RegV25,
  2069  			x2:   RegV30,
  2070  			name: "sqxtn v30.4h, v25.4s",
  2071  			inst: SQXTN,
  2072  			exp:  []byte{0x3e, 0x4b, 0x61, 0xe},
  2073  			arr:  VectorArrangement4H,
  2074  		},
  2075  		{
  2076  			x1:   RegV25,
  2077  			x2:   RegV30,
  2078  			name: "uqxtn v30.2s, v25.2d",
  2079  			inst: UQXTN,
  2080  			exp:  []byte{0x3e, 0x4b, 0xa1, 0x2e},
  2081  			arr:  VectorArrangement2S,
  2082  		},
  2083  		{
  2084  			x1:   RegV25,
  2085  			x2:   RegV30,
  2086  			name: "uqxtn v30.4h, v25.4s",
  2087  			inst: UQXTN,
  2088  			exp:  []byte{0x3e, 0x4b, 0x61, 0x2e},
  2089  			arr:  VectorArrangement4H,
  2090  		},
  2091  		{
  2092  			x1:   RegV25,
  2093  			x2:   RegV30,
  2094  			name: "sqxtn2 v30.16b, v25.8h",
  2095  			inst: SQXTN2,
  2096  			exp:  []byte{0x3e, 0x4b, 0x21, 0x4e},
  2097  			arr:  VectorArrangement16B,
  2098  		},
  2099  		{
  2100  			x1:   RegV25,
  2101  			x2:   RegV30,
  2102  			name: "sqxtn2 v30.8h, v25.4s",
  2103  			inst: SQXTN2,
  2104  			exp:  []byte{0x3e, 0x4b, 0x61, 0x4e},
  2105  			arr:  VectorArrangement8H,
  2106  		},
  2107  		{
  2108  			x1:   RegV25,
  2109  			x2:   RegV30,
  2110  			name: "sqxtn2 v30.4s, v25.2d",
  2111  			inst: SQXTN2,
  2112  			exp:  []byte{0x3e, 0x4b, 0xa1, 0x4e},
  2113  			arr:  VectorArrangement4S,
  2114  		},
  2115  		{
  2116  			x1:   RegV25,
  2117  			x2:   RegV30,
  2118  			name: "sqxtun v30.8b, v25.8h",
  2119  			inst: SQXTUN,
  2120  			exp:  []byte{0x3e, 0x2b, 0x21, 0x2e},
  2121  			arr:  VectorArrangement8B,
  2122  		},
  2123  		{
  2124  			x1:   RegV25,
  2125  			x2:   RegV30,
  2126  			name: "sqxtun v30.4h, v25.4s",
  2127  			inst: SQXTUN,
  2128  			exp:  []byte{0x3e, 0x2b, 0x61, 0x2e},
  2129  			arr:  VectorArrangement4H,
  2130  		},
  2131  		{
  2132  			x1:   RegV25,
  2133  			x2:   RegV30,
  2134  			name: "sqxtun v30.2s, v25.2d",
  2135  			inst: SQXTUN,
  2136  			exp:  []byte{0x3e, 0x2b, 0xa1, 0x2e},
  2137  			arr:  VectorArrangement2S,
  2138  		},
  2139  		{
  2140  			x1:   RegV25,
  2141  			x2:   RegV30,
  2142  			name: "sqxtun2 v30.16b, v25.8h",
  2143  			inst: SQXTUN2,
  2144  			exp:  []byte{0x3e, 0x2b, 0x21, 0x6e},
  2145  			arr:  VectorArrangement16B,
  2146  		},
  2147  		{
  2148  			x1:   RegV25,
  2149  			x2:   RegV30,
  2150  			name: "sqxtun2 v30.8h, v25.4s",
  2151  			inst: SQXTUN2,
  2152  			exp:  []byte{0x3e, 0x2b, 0x61, 0x6e},
  2153  			arr:  VectorArrangement8H,
  2154  		},
  2155  		{
  2156  			x1:   RegV25,
  2157  			x2:   RegV30,
  2158  			name: "sqxtun2 v30.4s, v25.2d",
  2159  			inst: SQXTUN2,
  2160  			exp:  []byte{0x3e, 0x2b, 0xa1, 0x6e},
  2161  			arr:  VectorArrangement4S,
  2162  		},
  2163  		{
  2164  			x1:   RegV25,
  2165  			x2:   RegV30,
  2166  			name: "scvtf v30.2d, v25.2d",
  2167  			inst: VSCVTF,
  2168  			exp:  []byte{0x3e, 0xdb, 0x61, 0x4e},
  2169  			arr:  VectorArrangement2D,
  2170  		},
  2171  		{
  2172  			x1:   RegV25,
  2173  			x2:   RegV30,
  2174  			name: "scvtf v30.4s, v25.4s",
  2175  			inst: VSCVTF,
  2176  			exp:  []byte{0x3e, 0xdb, 0x21, 0x4e},
  2177  			arr:  VectorArrangement4S,
  2178  		},
  2179  		{
  2180  			x1:   RegV25,
  2181  			x2:   RegV30,
  2182  			name: "ucvtf v30.2d, v25.2d",
  2183  			inst: VUCVTF,
  2184  			exp:  []byte{0x3e, 0xdb, 0x61, 0x6e},
  2185  			arr:  VectorArrangement2D,
  2186  		},
  2187  		{
  2188  			x1:   RegV25,
  2189  			x2:   RegV30,
  2190  			name: "ucvtf v30.4s, v25.4s",
  2191  			inst: VUCVTF,
  2192  			exp:  []byte{0x3e, 0xdb, 0x21, 0x6e},
  2193  			arr:  VectorArrangement4S,
  2194  		},
  2195  		{
  2196  			x1:   RegV25,
  2197  			x2:   RegV30,
  2198  			name: "fcvtl v30.2d, v25.2s",
  2199  			inst: FCVTL,
  2200  			exp:  []byte{0x3e, 0x7b, 0x61, 0xe},
  2201  			arr:  VectorArrangement2S,
  2202  		},
  2203  		{
  2204  			x1:   RegV25,
  2205  			x2:   RegV30,
  2206  			name: "fcvtl v30.4s, v25.4h",
  2207  			inst: FCVTL,
  2208  			exp:  []byte{0x3e, 0x7b, 0x21, 0xe},
  2209  			arr:  VectorArrangement4H,
  2210  		},
  2211  		{
  2212  			x1:   RegV25,
  2213  			x2:   RegV30,
  2214  			name: "fcvtn v30.2s, v25.2d",
  2215  			inst: FCVTN,
  2216  			exp:  []byte{0x3e, 0x6b, 0x61, 0xe},
  2217  			arr:  VectorArrangement2S,
  2218  		},
  2219  		{
  2220  			x1:   RegV25,
  2221  			x2:   RegV30,
  2222  			name: "fcvtn v30.4h, v25.4s",
  2223  			inst: FCVTN,
  2224  			exp:  []byte{0x3e, 0x6b, 0x21, 0xe},
  2225  			arr:  VectorArrangement4H,
  2226  		},
  2227  	}
  2228  
  2229  	for _, tt := range tests {
  2230  		tc := tt
  2231  		t.Run(tc.name, func(t *testing.T) {
  2232  			a := NewAssembler(asm.NilRegister)
  2233  			err := a.encodeVectorRegisterToVectorRegister(&nodeImpl{
  2234  				instruction:       tc.inst,
  2235  				srcReg:            tc.x1,
  2236  				srcConst:          tc.c,
  2237  				dstReg:            tc.x2,
  2238  				vectorArrangement: tc.arr,
  2239  				srcVectorIndex:    tc.srcIndex,
  2240  				dstVectorIndex:    tc.dstIndex,
  2241  			})
  2242  			require.NoError(t, err)
  2243  			actual := a.Buf.Bytes()
  2244  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  2245  		})
  2246  	}
  2247  }
  2248  
  2249  func TestAssemblerImpl_EncodeVectorRegisterToRegister(t *testing.T) {
  2250  	tests := []struct {
  2251  		name string
  2252  		n    *nodeImpl
  2253  		exp  []byte
  2254  	}{
  2255  		{
  2256  			name: "umov w10, v0.b[0xf]",
  2257  			n: &nodeImpl{
  2258  				instruction:       UMOV,
  2259  				srcReg:            RegV0,
  2260  				dstReg:            RegR10,
  2261  				vectorArrangement: VectorArrangementB,
  2262  				srcVectorIndex:    15,
  2263  			},
  2264  			exp: []byte{0xa, 0x3c, 0x1f, 0xe},
  2265  		},
  2266  		{
  2267  			name: "mov w10, v0.s[3]",
  2268  			n: &nodeImpl{
  2269  				instruction:       UMOV,
  2270  				srcReg:            RegV0,
  2271  				dstReg:            RegR10,
  2272  				vectorArrangement: VectorArrangementS,
  2273  				srcVectorIndex:    3,
  2274  			},
  2275  			exp: []byte{0xa, 0x3c, 0x1c, 0xe},
  2276  		},
  2277  		{
  2278  			name: "mov x5, v30.d[1]",
  2279  			n: &nodeImpl{
  2280  				instruction:       UMOV,
  2281  				srcReg:            RegV30,
  2282  				dstReg:            RegR5,
  2283  				vectorArrangement: VectorArrangementD,
  2284  				srcVectorIndex:    1,
  2285  			},
  2286  			exp: []byte{0xc5, 0x3f, 0x18, 0x4e},
  2287  		},
  2288  		{
  2289  			name: "smov w10, v0.b[0xf]",
  2290  			n: &nodeImpl{
  2291  				instruction:       SMOV32,
  2292  				srcReg:            RegV0,
  2293  				dstReg:            RegR10,
  2294  				vectorArrangement: VectorArrangementB,
  2295  				srcVectorIndex:    15,
  2296  			},
  2297  			exp: []byte{0xa, 0x2c, 0x1f, 0xe},
  2298  		},
  2299  		{
  2300  			name: "smov w10, v0.b[0]",
  2301  			n: &nodeImpl{
  2302  				instruction:       SMOV32,
  2303  				srcReg:            RegV0,
  2304  				dstReg:            RegR10,
  2305  				vectorArrangement: VectorArrangementB,
  2306  				srcVectorIndex:    0,
  2307  			},
  2308  			exp: []byte{0xa, 0x2c, 0x1, 0xe},
  2309  		},
  2310  		{
  2311  			name: "smov w1, v30.h[7]",
  2312  			n: &nodeImpl{
  2313  				instruction:       SMOV32,
  2314  				srcReg:            RegV30,
  2315  				dstReg:            RegR1,
  2316  				vectorArrangement: VectorArrangementH,
  2317  				srcVectorIndex:    7,
  2318  			},
  2319  			exp: []byte{0xc1, 0x2f, 0x1e, 0xe},
  2320  		},
  2321  		{
  2322  			name: "smov w1, v30.h[0]",
  2323  			n: &nodeImpl{
  2324  				instruction:       SMOV32,
  2325  				srcReg:            RegV30,
  2326  				dstReg:            RegR1,
  2327  				vectorArrangement: VectorArrangementH,
  2328  				srcVectorIndex:    0,
  2329  			},
  2330  			exp: []byte{0xc1, 0x2f, 0x2, 0xe},
  2331  		},
  2332  	}
  2333  
  2334  	for _, tt := range tests {
  2335  		tc := tt
  2336  		t.Run(tc.name, func(t *testing.T) {
  2337  			a := NewAssembler(asm.NilRegister)
  2338  			err := a.encodeVectorRegisterToRegister(tc.n)
  2339  			require.NoError(t, err)
  2340  
  2341  			actual := a.Buf.Bytes()
  2342  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  2343  		})
  2344  	}
  2345  }
  2346  
  2347  func TestAssemblerImpl_EncodeLeftShiftedRegisterToRegister(t *testing.T) {
  2348  	t.Run("error", func(t *testing.T) {
  2349  		tests := []struct {
  2350  			n      *nodeImpl
  2351  			expErr string
  2352  		}{
  2353  			{
  2354  				n: &nodeImpl{
  2355  					instruction: SUB, types: operandTypesLeftShiftedRegisterToRegister,
  2356  					srcReg: RegR0, srcReg2: RegR0, dstReg: RegR0,
  2357  				},
  2358  				expErr: "SUB is unsupported for from:left-shifted-register,to:register type",
  2359  			},
  2360  			{
  2361  				n: &nodeImpl{
  2362  					instruction: ADD,
  2363  					srcConst:    -1, srcReg: RegR0, srcReg2: RegR0, dstReg: RegR0,
  2364  				},
  2365  				expErr: "shift amount must fit in unsigned 6-bit integer (0-64) but got -1",
  2366  			},
  2367  			{
  2368  				n: &nodeImpl{
  2369  					instruction: ADD,
  2370  					srcConst:    -1, srcReg: RegV0, srcReg2: RegR0, dstReg: RegR0,
  2371  				},
  2372  				expErr: "V0 is not integer",
  2373  			},
  2374  			{
  2375  				n: &nodeImpl{
  2376  					instruction: ADD,
  2377  					srcConst:    -1, srcReg: RegR0, srcReg2: RegV0, dstReg: RegR0,
  2378  				},
  2379  				expErr: "V0 is not integer",
  2380  			},
  2381  			{
  2382  				n: &nodeImpl{
  2383  					instruction: ADD,
  2384  					srcConst:    -1, srcReg: RegR0, srcReg2: RegR0, dstReg: RegV0,
  2385  				},
  2386  				expErr: "V0 is not integer",
  2387  			},
  2388  		}
  2389  
  2390  		for _, tt := range tests {
  2391  			tc := tt
  2392  			a := NewAssembler(asm.NilRegister)
  2393  			err := a.encodeLeftShiftedRegisterToRegister(tc.n)
  2394  			require.EqualError(t, err, tc.expErr)
  2395  		}
  2396  	})
  2397  
  2398  	tests := []struct {
  2399  		name string
  2400  		n    *nodeImpl
  2401  		exp  []byte
  2402  	}{
  2403  		{
  2404  			name: "ADD",
  2405  			n: &nodeImpl{
  2406  				instruction:       ADD,
  2407  				srcReg:            RegR0,
  2408  				srcReg2:           RegR29,
  2409  				srcConst:          1,
  2410  				dstReg:            RegR21,
  2411  				vectorArrangement: VectorArrangementH,
  2412  				srcVectorIndex:    0,
  2413  			},
  2414  			exp: []byte{0x15, 0x4, 0x1d, 0x8b},
  2415  		},
  2416  		{
  2417  			name: "ADD",
  2418  			n: &nodeImpl{
  2419  				instruction:       ADD,
  2420  				srcReg:            RegR0,
  2421  				srcReg2:           RegR29,
  2422  				srcConst:          2,
  2423  				dstReg:            RegR21,
  2424  				vectorArrangement: VectorArrangementH,
  2425  				srcVectorIndex:    0,
  2426  			},
  2427  			exp: []byte{0x15, 0x8, 0x1d, 0x8b},
  2428  		},
  2429  		{
  2430  			name: "ADD",
  2431  			n: &nodeImpl{
  2432  				instruction:       ADD,
  2433  				srcReg:            RegR0,
  2434  				srcReg2:           RegR29,
  2435  				srcConst:          8,
  2436  				dstReg:            RegR21,
  2437  				vectorArrangement: VectorArrangementH,
  2438  				srcVectorIndex:    0,
  2439  			},
  2440  			exp: []byte{0x15, 0x20, 0x1d, 0x8b},
  2441  		},
  2442  		{
  2443  			name: "ADD",
  2444  			n: &nodeImpl{
  2445  				instruction:       ADD,
  2446  				srcReg:            RegR29,
  2447  				srcReg2:           RegR0,
  2448  				srcConst:          16,
  2449  				dstReg:            RegR21,
  2450  				vectorArrangement: VectorArrangementH,
  2451  				srcVectorIndex:    0,
  2452  			},
  2453  			exp: []byte{0xb5, 0x43, 0x0, 0x8b},
  2454  		},
  2455  		{
  2456  			name: "ADD",
  2457  			n: &nodeImpl{
  2458  				instruction:       ADD,
  2459  				srcReg:            RegR29,
  2460  				srcReg2:           RegR0,
  2461  				srcConst:          64,
  2462  				dstReg:            RegR21,
  2463  				vectorArrangement: VectorArrangementH,
  2464  				srcVectorIndex:    0,
  2465  			},
  2466  			exp: []byte{0xb5, 0x3, 0x0, 0x8b},
  2467  		},
  2468  		{
  2469  			name: "ADD",
  2470  			n: &nodeImpl{
  2471  				instruction:       ADD,
  2472  				srcReg:            RegRZR,
  2473  				srcReg2:           RegR0,
  2474  				srcConst:          64,
  2475  				dstReg:            RegR21,
  2476  				vectorArrangement: VectorArrangementH,
  2477  				srcVectorIndex:    0,
  2478  			},
  2479  			exp: []byte{0xf5, 0x3, 0x0, 0x8b},
  2480  		},
  2481  		{
  2482  			name: "ADD",
  2483  			n: &nodeImpl{
  2484  				instruction:       ADD,
  2485  				srcReg:            RegRZR,
  2486  				srcReg2:           RegRZR,
  2487  				srcConst:          64,
  2488  				dstReg:            RegR21,
  2489  				vectorArrangement: VectorArrangementH,
  2490  				srcVectorIndex:    0,
  2491  			},
  2492  			exp: []byte{0xf5, 0x3, 0x1f, 0x8b},
  2493  		},
  2494  		{
  2495  			name: "ADD",
  2496  			n: &nodeImpl{
  2497  				instruction:       ADD,
  2498  				srcReg:            RegRZR,
  2499  				srcReg2:           RegRZR,
  2500  				srcConst:          64,
  2501  				dstReg:            RegRZR,
  2502  				vectorArrangement: VectorArrangementH,
  2503  				srcVectorIndex:    0,
  2504  			},
  2505  			exp: []byte{0xff, 0x3, 0x1f, 0x8b},
  2506  		},
  2507  	}
  2508  
  2509  	for _, tt := range tests {
  2510  		tc := tt
  2511  		t.Run(tc.name, func(t *testing.T) {
  2512  			a := NewAssembler(asm.NilRegister)
  2513  			err := a.encodeLeftShiftedRegisterToRegister(tc.n)
  2514  			require.NoError(t, err)
  2515  
  2516  			actual := a.Buf.Bytes()
  2517  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  2518  		})
  2519  	}
  2520  }
  2521  
  2522  func TestAssemblerImpl_encodeTwoRegistersToNone(t *testing.T) {
  2523  	t.Run("error", func(t *testing.T) {
  2524  		tests := []struct {
  2525  			n      *nodeImpl
  2526  			expErr string
  2527  		}{
  2528  			{
  2529  				n: &nodeImpl{
  2530  					instruction: SUB, types: operandTypesTwoRegistersToNone,
  2531  					srcReg: RegR0, srcReg2: RegR0, dstReg: RegR0,
  2532  				},
  2533  				expErr: "SUB is unsupported for from:two-registers,to:none type",
  2534  			},
  2535  			{
  2536  				n: &nodeImpl{
  2537  					instruction: CMP,
  2538  					srcReg:      RegR0, srcReg2: RegV0,
  2539  				},
  2540  				expErr: "V0 is not integer",
  2541  			},
  2542  			{
  2543  				n: &nodeImpl{
  2544  					instruction: FCMPS,
  2545  					srcReg:      RegR0, srcReg2: RegV0,
  2546  				},
  2547  				expErr: "R0 is not vector",
  2548  			},
  2549  		}
  2550  
  2551  		for _, tt := range tests {
  2552  			tc := tt
  2553  			a := NewAssembler(asm.NilRegister)
  2554  			err := a.encodeTwoRegistersToNone(tc.n)
  2555  			require.EqualError(t, err, tc.expErr)
  2556  		}
  2557  	})
  2558  
  2559  	tests := []struct {
  2560  		name string
  2561  		n    *nodeImpl
  2562  		exp  []byte
  2563  	}{
  2564  		{
  2565  			name: "CMP",
  2566  			n: &nodeImpl{
  2567  				instruction:       CMP,
  2568  				srcReg:            RegRZR,
  2569  				srcReg2:           RegRZR,
  2570  				vectorArrangement: VectorArrangementH,
  2571  				srcVectorIndex:    0,
  2572  			},
  2573  			exp: []byte{0xff, 0x3, 0x1f, 0xeb},
  2574  		},
  2575  		{
  2576  			name: "CMP",
  2577  			n: &nodeImpl{
  2578  				instruction:       CMP,
  2579  				srcReg:            RegRZR,
  2580  				srcReg2:           RegR30,
  2581  				vectorArrangement: VectorArrangementH,
  2582  				srcVectorIndex:    0,
  2583  			},
  2584  			exp: []byte{0xdf, 0x3, 0x1f, 0xeb},
  2585  		},
  2586  		{
  2587  			name: "CMP",
  2588  			n: &nodeImpl{
  2589  				instruction:       CMP,
  2590  				srcReg:            RegR30,
  2591  				srcReg2:           RegRZR,
  2592  				vectorArrangement: VectorArrangementH,
  2593  				srcVectorIndex:    0,
  2594  			},
  2595  			exp: []byte{0xff, 0x3, 0x1e, 0xeb},
  2596  		},
  2597  		{
  2598  			name: "CMP",
  2599  			n: &nodeImpl{
  2600  				instruction:       CMP,
  2601  				srcReg:            RegR30,
  2602  				srcReg2:           RegR30,
  2603  				vectorArrangement: VectorArrangementH,
  2604  				srcVectorIndex:    0,
  2605  			},
  2606  			exp: []byte{0xdf, 0x3, 0x1e, 0xeb},
  2607  		},
  2608  		{
  2609  			name: "CMPW",
  2610  			n: &nodeImpl{
  2611  				instruction:       CMPW,
  2612  				srcReg:            RegRZR,
  2613  				srcReg2:           RegRZR,
  2614  				vectorArrangement: VectorArrangementH,
  2615  				srcVectorIndex:    0,
  2616  			},
  2617  			exp: []byte{0xff, 0x3, 0x1f, 0x6b},
  2618  		},
  2619  		{
  2620  			name: "CMPW",
  2621  			n: &nodeImpl{
  2622  				instruction:       CMPW,
  2623  				srcReg:            RegRZR,
  2624  				srcReg2:           RegR30,
  2625  				vectorArrangement: VectorArrangementH,
  2626  				srcVectorIndex:    0,
  2627  			},
  2628  			exp: []byte{0xdf, 0x3, 0x1f, 0x6b},
  2629  		},
  2630  		{
  2631  			name: "CMPW",
  2632  			n: &nodeImpl{
  2633  				instruction:       CMPW,
  2634  				srcReg:            RegR30,
  2635  				srcReg2:           RegRZR,
  2636  				vectorArrangement: VectorArrangementH,
  2637  				srcVectorIndex:    0,
  2638  			},
  2639  			exp: []byte{0xff, 0x3, 0x1e, 0x6b},
  2640  		},
  2641  		{
  2642  			name: "CMPW",
  2643  			n: &nodeImpl{
  2644  				instruction:       CMPW,
  2645  				srcReg:            RegR30,
  2646  				srcReg2:           RegR30,
  2647  				vectorArrangement: VectorArrangementH,
  2648  				srcVectorIndex:    0,
  2649  			},
  2650  			exp: []byte{0xdf, 0x3, 0x1e, 0x6b},
  2651  		},
  2652  		{
  2653  			name: "FCMPD",
  2654  			n: &nodeImpl{
  2655  				instruction:       FCMPD,
  2656  				srcReg:            RegV0,
  2657  				srcReg2:           RegV0,
  2658  				vectorArrangement: VectorArrangementH,
  2659  				srcVectorIndex:    0,
  2660  			},
  2661  			exp: []byte{0x0, 0x20, 0x60, 0x1e},
  2662  		},
  2663  		{
  2664  			name: "FCMPD",
  2665  			n: &nodeImpl{
  2666  				instruction:       FCMPD,
  2667  				srcReg:            RegV0,
  2668  				srcReg2:           RegV31,
  2669  				vectorArrangement: VectorArrangementH,
  2670  				srcVectorIndex:    0,
  2671  			},
  2672  			exp: []byte{0xe0, 0x23, 0x60, 0x1e},
  2673  		},
  2674  		{
  2675  			name: "FCMPD",
  2676  			n: &nodeImpl{
  2677  				instruction:       FCMPD,
  2678  				srcReg:            RegV31,
  2679  				srcReg2:           RegV0,
  2680  				vectorArrangement: VectorArrangementH,
  2681  				srcVectorIndex:    0,
  2682  			},
  2683  			exp: []byte{0x0, 0x20, 0x7f, 0x1e},
  2684  		},
  2685  		{
  2686  			name: "FCMPD",
  2687  			n: &nodeImpl{
  2688  				instruction:       FCMPD,
  2689  				srcReg:            RegV31,
  2690  				srcReg2:           RegV31,
  2691  				vectorArrangement: VectorArrangementH,
  2692  				srcVectorIndex:    0,
  2693  			},
  2694  			exp: []byte{0xe0, 0x23, 0x7f, 0x1e},
  2695  		},
  2696  		{
  2697  			name: "FCMPS",
  2698  			n: &nodeImpl{
  2699  				instruction:       FCMPS,
  2700  				srcReg:            RegV0,
  2701  				srcReg2:           RegV0,
  2702  				vectorArrangement: VectorArrangementH,
  2703  				srcVectorIndex:    0,
  2704  			},
  2705  			exp: []byte{0x0, 0x20, 0x20, 0x1e},
  2706  		},
  2707  		{
  2708  			name: "FCMPS",
  2709  			n: &nodeImpl{
  2710  				instruction:       FCMPS,
  2711  				srcReg:            RegV0,
  2712  				srcReg2:           RegV31,
  2713  				vectorArrangement: VectorArrangementH,
  2714  				srcVectorIndex:    0,
  2715  			},
  2716  			exp: []byte{0xe0, 0x23, 0x20, 0x1e},
  2717  		},
  2718  		{
  2719  			name: "FCMPS",
  2720  			n: &nodeImpl{
  2721  				instruction:       FCMPS,
  2722  				srcReg:            RegV31,
  2723  				srcReg2:           RegV0,
  2724  				vectorArrangement: VectorArrangementH,
  2725  				srcVectorIndex:    0,
  2726  			},
  2727  			exp: []byte{0x0, 0x20, 0x3f, 0x1e},
  2728  		},
  2729  		{
  2730  			name: "FCMPS",
  2731  			n: &nodeImpl{
  2732  				instruction:       FCMPS,
  2733  				srcReg:            RegV31,
  2734  				srcReg2:           RegV31,
  2735  				vectorArrangement: VectorArrangementH,
  2736  				srcVectorIndex:    0,
  2737  			},
  2738  			exp: []byte{0xe0, 0x23, 0x3f, 0x1e},
  2739  		},
  2740  	}
  2741  
  2742  	for _, tt := range tests {
  2743  		tc := tt
  2744  		t.Run(tc.name, func(t *testing.T) {
  2745  			a := NewAssembler(asm.NilRegister)
  2746  			err := a.encodeTwoRegistersToNone(tc.n)
  2747  			require.NoError(t, err)
  2748  
  2749  			actual := a.Buf.Bytes()
  2750  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  2751  		})
  2752  	}
  2753  }
  2754  
  2755  func TestAssemblerImpl_EncodeThreeRegistersToRegister(t *testing.T) {
  2756  	const src1, src2, src3, dst = RegR1, RegR10, RegR30, RegR11
  2757  
  2758  	tests := []struct {
  2759  		name string
  2760  		inst asm.Instruction
  2761  		exp  []byte
  2762  	}{
  2763  		{
  2764  			name: "MSUB/src1=R1,src2=R10,src3=R30,dst=R11",
  2765  			inst: MSUB,
  2766  			exp:  []byte{0xcb, 0xab, 0x1, 0x9b},
  2767  		},
  2768  		{
  2769  			name: "MSUBW/src1=R1,src2=R10,src3=R30,dst=R11",
  2770  			inst: MSUBW,
  2771  			exp:  []byte{0xcb, 0xab, 0x1, 0x1b},
  2772  		},
  2773  	}
  2774  
  2775  	for _, tc := range tests {
  2776  		t.Run(tc.name, func(t *testing.T) {
  2777  			a := NewAssembler(asm.NilRegister)
  2778  			err := a.encodeThreeRegistersToRegister(&nodeImpl{
  2779  				instruction: tc.inst, srcReg: src1, srcReg2: src2, dstReg: src3, dstReg2: dst,
  2780  			})
  2781  			require.NoError(t, err)
  2782  
  2783  			actual := a.bytes()
  2784  			require.Equal(t, tc.exp, actual[:4])
  2785  		})
  2786  	}
  2787  }
  2788  
  2789  func TestAssemblerImpl_encodeTwoVectorRegistersToVectorRegister(t *testing.T) {
  2790  	tests := []struct {
  2791  		name string
  2792  		n    *nodeImpl
  2793  		exp  []byte
  2794  	}{
  2795  		{
  2796  			name: "orr v30.16b, v10.16b, v1.16b",
  2797  			n: &nodeImpl{
  2798  				instruction:       VORR,
  2799  				dstReg:            RegV30,
  2800  				srcReg:            RegV1,
  2801  				srcReg2:           RegV10,
  2802  				vectorArrangement: VectorArrangement16B,
  2803  			},
  2804  			exp: []byte{0x5e, 0x1d, 0xa1, 0x4e},
  2805  		},
  2806  		{
  2807  			name: "orr v30.8b, v10.8b, v1.8b",
  2808  			n: &nodeImpl{
  2809  				instruction:       VORR,
  2810  				dstReg:            RegV30,
  2811  				srcReg:            RegV1,
  2812  				srcReg2:           RegV10,
  2813  				vectorArrangement: VectorArrangement8B,
  2814  			},
  2815  			exp: []byte{0x5e, 0x1d, 0xa1, 0xe},
  2816  		},
  2817  		{
  2818  			name: "bsl v0.8b, v15.8b, v1.8b",
  2819  			n: &nodeImpl{
  2820  				instruction:       BSL,
  2821  				dstReg:            RegV0,
  2822  				srcReg:            RegV1,
  2823  				srcReg2:           RegV15,
  2824  				vectorArrangement: VectorArrangement8B,
  2825  			},
  2826  			exp: []byte{0xe0, 0x1d, 0x61, 0x2e},
  2827  		},
  2828  		{
  2829  			name: "zip1 v0.4s, v15.4s, v1.4s",
  2830  			n: &nodeImpl{
  2831  				instruction:       ZIP1,
  2832  				dstReg:            RegV0,
  2833  				srcReg:            RegV1,
  2834  				srcReg2:           RegV15,
  2835  				vectorArrangement: VectorArrangement4S,
  2836  			},
  2837  			exp: []byte{0xe0, 0x39, 0x81, 0x4e},
  2838  		},
  2839  		{
  2840  			name: "zip1 v0.2d, v15.2d, v1.2d",
  2841  			n: &nodeImpl{
  2842  				instruction:       ZIP1,
  2843  				dstReg:            RegV0,
  2844  				srcReg:            RegV1,
  2845  				srcReg2:           RegV15,
  2846  				vectorArrangement: VectorArrangement2D,
  2847  			},
  2848  			exp: []byte{0xe0, 0x39, 0xc1, 0x4e},
  2849  		},
  2850  		{
  2851  			name: "ext v0.16b, v15.16b, v1.16b, #0xf",
  2852  			n: &nodeImpl{
  2853  				instruction:       EXT,
  2854  				dstReg:            RegV0,
  2855  				srcReg:            RegV1,
  2856  				srcReg2:           RegV15,
  2857  				srcConst:          0xf,
  2858  				vectorArrangement: VectorArrangement16B,
  2859  			},
  2860  			exp: []byte{0xe0, 0x79, 0x1, 0x6e},
  2861  		},
  2862  		{
  2863  			name: "ext v0.16b, v15.16b, v1.16b, #8",
  2864  			n: &nodeImpl{
  2865  				instruction:       EXT,
  2866  				dstReg:            RegV0,
  2867  				srcReg:            RegV1,
  2868  				srcReg2:           RegV15,
  2869  				srcConst:          8,
  2870  				vectorArrangement: VectorArrangement16B,
  2871  			},
  2872  			exp: []byte{0xe0, 0x41, 0x1, 0x6e},
  2873  		},
  2874  		{
  2875  			name: "ext v0.16b, v15.16b, v1.16b, #0",
  2876  			n: &nodeImpl{
  2877  				instruction:       EXT,
  2878  				dstReg:            RegV0,
  2879  				srcReg:            RegV1,
  2880  				srcReg2:           RegV15,
  2881  				srcConst:          0,
  2882  				vectorArrangement: VectorArrangement16B,
  2883  			},
  2884  			exp: []byte{0xe0, 0x1, 0x1, 0x6e},
  2885  		},
  2886  		{
  2887  			name: "ext v0.8b, v15.8b, v1.8b, #7",
  2888  			n: &nodeImpl{
  2889  				instruction:       EXT,
  2890  				dstReg:            RegV0,
  2891  				srcReg:            RegV1,
  2892  				srcReg2:           RegV15,
  2893  				srcConst:          7,
  2894  				vectorArrangement: VectorArrangement8B,
  2895  			},
  2896  			exp: []byte{0xe0, 0x39, 0x1, 0x2e},
  2897  		},
  2898  		{
  2899  			name: "cmeq v0.8b, v15.8b, v1.8b",
  2900  			n: &nodeImpl{
  2901  				instruction:       CMEQ,
  2902  				dstReg:            RegV0,
  2903  				srcReg:            RegV1,
  2904  				srcReg2:           RegV15,
  2905  				vectorArrangement: VectorArrangement8B,
  2906  			},
  2907  			exp: []byte{0xe0, 0x8d, 0x21, 0x2e},
  2908  		},
  2909  		{
  2910  			name: "cmgt v0.16b, v15.16b, v1.16b",
  2911  			n: &nodeImpl{
  2912  				instruction:       CMGT,
  2913  				dstReg:            RegV0,
  2914  				srcReg:            RegV1,
  2915  				srcReg2:           RegV15,
  2916  				vectorArrangement: VectorArrangement16B,
  2917  			},
  2918  			exp: []byte{0xe0, 0x35, 0x21, 0x4e},
  2919  		},
  2920  		{
  2921  			name: "cmhi v0.8h, v15.8h, v1.8h",
  2922  			n: &nodeImpl{
  2923  				instruction:       CMHI,
  2924  				dstReg:            RegV0,
  2925  				srcReg:            RegV1,
  2926  				srcReg2:           RegV15,
  2927  				vectorArrangement: VectorArrangement8H,
  2928  			},
  2929  			exp: []byte{0xe0, 0x35, 0x61, 0x6e},
  2930  		},
  2931  		{
  2932  			name: "cmhi v0.4h, v15.4h, v1.4h",
  2933  			n: &nodeImpl{
  2934  				instruction:       CMHI,
  2935  				dstReg:            RegV0,
  2936  				srcReg:            RegV1,
  2937  				srcReg2:           RegV15,
  2938  				vectorArrangement: VectorArrangement4H,
  2939  			},
  2940  			exp: []byte{0xe0, 0x35, 0x61, 0x2e},
  2941  		},
  2942  		{
  2943  			name: "cmge v0.4s, v15.4s, v1.4s",
  2944  			n: &nodeImpl{
  2945  				instruction:       CMGE,
  2946  				dstReg:            RegV0,
  2947  				srcReg:            RegV1,
  2948  				srcReg2:           RegV15,
  2949  				vectorArrangement: VectorArrangement4S,
  2950  			},
  2951  			exp: []byte{0xe0, 0x3d, 0xa1, 0x4e},
  2952  		},
  2953  		{
  2954  			name: "cmge v0.2s, v15.2s, v1.2s",
  2955  			n: &nodeImpl{
  2956  				instruction:       CMGE,
  2957  				dstReg:            RegV0,
  2958  				srcReg:            RegV1,
  2959  				srcReg2:           RegV15,
  2960  				vectorArrangement: VectorArrangement2S,
  2961  			},
  2962  			exp: []byte{0xe0, 0x3d, 0xa1, 0xe},
  2963  		},
  2964  		{
  2965  			name: "cmhs v30.2d, v4.2d, v11.2d",
  2966  			n: &nodeImpl{
  2967  				instruction:       CMHS,
  2968  				dstReg:            RegV30,
  2969  				srcReg:            RegV11,
  2970  				srcReg2:           RegV4,
  2971  				vectorArrangement: VectorArrangement2D,
  2972  			},
  2973  			exp: []byte{0x9e, 0x3c, 0xeb, 0x6e},
  2974  		},
  2975  		{
  2976  			name: "fcmeq v30.2d, v4.2d, v11.2d",
  2977  			n: &nodeImpl{
  2978  				instruction:       FCMEQ,
  2979  				dstReg:            RegV30,
  2980  				srcReg:            RegV11,
  2981  				srcReg2:           RegV4,
  2982  				vectorArrangement: VectorArrangement2D,
  2983  			},
  2984  			exp: []byte{0x9e, 0xe4, 0x6b, 0x4e},
  2985  		},
  2986  		{
  2987  			name: "fcmeq v30.4s, v4.4s, v11.4s",
  2988  			n: &nodeImpl{
  2989  				instruction:       FCMEQ,
  2990  				dstReg:            RegV30,
  2991  				srcReg:            RegV11,
  2992  				srcReg2:           RegV4,
  2993  				vectorArrangement: VectorArrangement4S,
  2994  			},
  2995  			exp: []byte{0x9e, 0xe4, 0x2b, 0x4e},
  2996  		},
  2997  		{
  2998  			name: "fcmeq v30.2s, v4.2s, v11.2s",
  2999  			n: &nodeImpl{
  3000  				instruction:       FCMEQ,
  3001  				dstReg:            RegV30,
  3002  				srcReg:            RegV11,
  3003  				srcReg2:           RegV4,
  3004  				vectorArrangement: VectorArrangement2S,
  3005  			},
  3006  			exp: []byte{0x9e, 0xe4, 0x2b, 0xe},
  3007  		},
  3008  		{
  3009  			name: "fcmgt v30.2d, v4.2d, v11.2d",
  3010  			n: &nodeImpl{
  3011  				instruction:       FCMGT,
  3012  				dstReg:            RegV30,
  3013  				srcReg:            RegV11,
  3014  				srcReg2:           RegV4,
  3015  				vectorArrangement: VectorArrangement2D,
  3016  			},
  3017  			exp: []byte{0x9e, 0xe4, 0xeb, 0x6e},
  3018  		},
  3019  		{
  3020  			name: "fcmgt v30.4s, v4.4s, v11.4s",
  3021  			n: &nodeImpl{
  3022  				instruction:       FCMGT,
  3023  				dstReg:            RegV30,
  3024  				srcReg:            RegV11,
  3025  				srcReg2:           RegV4,
  3026  				vectorArrangement: VectorArrangement4S,
  3027  			},
  3028  			exp: []byte{0x9e, 0xe4, 0xab, 0x6e},
  3029  		},
  3030  		{
  3031  			name: "fcmgt v30.2s, v4.2s, v11.2s",
  3032  			n: &nodeImpl{
  3033  				instruction:       FCMGT,
  3034  				dstReg:            RegV30,
  3035  				srcReg:            RegV11,
  3036  				srcReg2:           RegV4,
  3037  				vectorArrangement: VectorArrangement2S,
  3038  			},
  3039  			exp: []byte{0x9e, 0xe4, 0xab, 0x2e},
  3040  		},
  3041  		{
  3042  			name: "fcmge v30.2d, v4.2d, v11.2d",
  3043  			n: &nodeImpl{
  3044  				instruction:       FCMGE,
  3045  				dstReg:            RegV30,
  3046  				srcReg:            RegV11,
  3047  				srcReg2:           RegV4,
  3048  				vectorArrangement: VectorArrangement2D,
  3049  			},
  3050  			exp: []byte{0x9e, 0xe4, 0x6b, 0x6e},
  3051  		},
  3052  		{
  3053  			name: "fcmge v30.4s, v4.4s, v11.4s",
  3054  			n: &nodeImpl{
  3055  				instruction:       FCMGE,
  3056  				dstReg:            RegV30,
  3057  				srcReg:            RegV11,
  3058  				srcReg2:           RegV4,
  3059  				vectorArrangement: VectorArrangement4S,
  3060  			},
  3061  			exp: []byte{0x9e, 0xe4, 0x2b, 0x6e},
  3062  		},
  3063  		{
  3064  			name: "fcmge v30.2s, v4.2s, v11.2s",
  3065  			n: &nodeImpl{
  3066  				instruction:       FCMGE,
  3067  				dstReg:            RegV30,
  3068  				srcReg:            RegV11,
  3069  				srcReg2:           RegV4,
  3070  				vectorArrangement: VectorArrangement2S,
  3071  			},
  3072  			exp: []byte{0x9e, 0xe4, 0x2b, 0x2e},
  3073  		},
  3074  		{
  3075  			name: "fdiv v30.4s, v4.4s, v11.4s",
  3076  			n: &nodeImpl{
  3077  				instruction:       VFDIV,
  3078  				dstReg:            RegV30,
  3079  				srcReg:            RegV11,
  3080  				srcReg2:           RegV4,
  3081  				vectorArrangement: VectorArrangement4S,
  3082  			},
  3083  			exp: []byte{0x9e, 0xfc, 0x2b, 0x6e},
  3084  		},
  3085  		{
  3086  			name: "fdiv v30.2s, v4.2s, v11.2s",
  3087  			n: &nodeImpl{
  3088  				instruction:       VFDIV,
  3089  				dstReg:            RegV30,
  3090  				srcReg:            RegV11,
  3091  				srcReg2:           RegV4,
  3092  				vectorArrangement: VectorArrangement2S,
  3093  			},
  3094  			exp: []byte{0x9e, 0xfc, 0x2b, 0x2e},
  3095  		},
  3096  		{
  3097  			name: "fdiv v30.2d, v4.2d, v11.2d",
  3098  			n: &nodeImpl{
  3099  				instruction:       VFDIV,
  3100  				dstReg:            RegV30,
  3101  				srcReg:            RegV11,
  3102  				srcReg2:           RegV4,
  3103  				vectorArrangement: VectorArrangement2D,
  3104  			},
  3105  			exp: []byte{0x9e, 0xfc, 0x6b, 0x6e},
  3106  		},
  3107  		{
  3108  			name: "fmul v30.4s, v4.4s, v11.4s",
  3109  			n: &nodeImpl{
  3110  				instruction:       VFMUL,
  3111  				dstReg:            RegV30,
  3112  				srcReg:            RegV11,
  3113  				srcReg2:           RegV4,
  3114  				vectorArrangement: VectorArrangement4S,
  3115  			},
  3116  			exp: []byte{0x9e, 0xdc, 0x2b, 0x6e},
  3117  		},
  3118  		{
  3119  			name: "fmul v30.2s, v4.2s, v11.2s",
  3120  			n: &nodeImpl{
  3121  				instruction:       VFMUL,
  3122  				dstReg:            RegV30,
  3123  				srcReg:            RegV11,
  3124  				srcReg2:           RegV4,
  3125  				vectorArrangement: VectorArrangement2S,
  3126  			},
  3127  			exp: []byte{0x9e, 0xdc, 0x2b, 0x2e},
  3128  		},
  3129  		{
  3130  			name: "fmul v30.2d, v4.2d, v11.2d",
  3131  			n: &nodeImpl{
  3132  				instruction:       VFMUL,
  3133  				dstReg:            RegV30,
  3134  				srcReg:            RegV11,
  3135  				srcReg2:           RegV4,
  3136  				vectorArrangement: VectorArrangement2D,
  3137  			},
  3138  			exp: []byte{0x9e, 0xdc, 0x6b, 0x6e},
  3139  		},
  3140  		{
  3141  			name: "fmin v30.4s, v4.4s, v11.4s",
  3142  			n: &nodeImpl{
  3143  				instruction:       VFMIN,
  3144  				dstReg:            RegV30,
  3145  				srcReg:            RegV11,
  3146  				srcReg2:           RegV4,
  3147  				vectorArrangement: VectorArrangement4S,
  3148  			},
  3149  			exp: []byte{0x9e, 0xf4, 0xab, 0x4e},
  3150  		},
  3151  		{
  3152  			name: "fmin v30.2s, v4.2s, v11.2s",
  3153  			n: &nodeImpl{
  3154  				instruction:       VFMIN,
  3155  				dstReg:            RegV30,
  3156  				srcReg:            RegV11,
  3157  				srcReg2:           RegV4,
  3158  				vectorArrangement: VectorArrangement2S,
  3159  			},
  3160  			exp: []byte{0x9e, 0xf4, 0xab, 0xe},
  3161  		},
  3162  		{
  3163  			name: "fmin v30.2d, v4.2d, v11.2d",
  3164  			n: &nodeImpl{
  3165  				instruction:       VFMIN,
  3166  				dstReg:            RegV30,
  3167  				srcReg:            RegV11,
  3168  				srcReg2:           RegV4,
  3169  				vectorArrangement: VectorArrangement2D,
  3170  			},
  3171  			exp: []byte{0x9e, 0xf4, 0xeb, 0x4e},
  3172  		},
  3173  		{
  3174  			name: "fmax v30.4s, v4.4s, v11.4s",
  3175  			n: &nodeImpl{
  3176  				instruction:       VFMAX,
  3177  				dstReg:            RegV30,
  3178  				srcReg:            RegV11,
  3179  				srcReg2:           RegV4,
  3180  				vectorArrangement: VectorArrangement4S,
  3181  			},
  3182  			exp: []byte{0x9e, 0xf4, 0x2b, 0x4e},
  3183  		},
  3184  		{
  3185  			name: "fmax v30.2s, v4.2s, v11.2s",
  3186  			n: &nodeImpl{
  3187  				instruction:       VFMAX,
  3188  				dstReg:            RegV30,
  3189  				srcReg:            RegV11,
  3190  				srcReg2:           RegV4,
  3191  				vectorArrangement: VectorArrangement2S,
  3192  			},
  3193  			exp: []byte{0x9e, 0xf4, 0x2b, 0xe},
  3194  		},
  3195  		{
  3196  			name: "fmax v30.2d, v4.2d, v11.2d",
  3197  			n: &nodeImpl{
  3198  				instruction:       VFMAX,
  3199  				dstReg:            RegV30,
  3200  				srcReg:            RegV11,
  3201  				srcReg2:           RegV4,
  3202  				vectorArrangement: VectorArrangement2D,
  3203  			},
  3204  			exp: []byte{0x9e, 0xf4, 0x6b, 0x4e},
  3205  		},
  3206  		{
  3207  			name: "mul v30.4s, v4.4s, v11.4s",
  3208  			n: &nodeImpl{
  3209  				instruction:       VMUL,
  3210  				dstReg:            RegV30,
  3211  				srcReg:            RegV11,
  3212  				srcReg2:           RegV4,
  3213  				vectorArrangement: VectorArrangement4S,
  3214  			},
  3215  			exp: []byte{0x9e, 0x9c, 0xab, 0x4e},
  3216  		},
  3217  		{
  3218  			name: "mul v30.16b, v4.16b, v11.16b",
  3219  			n: &nodeImpl{
  3220  				instruction:       VMUL,
  3221  				dstReg:            RegV30,
  3222  				srcReg:            RegV11,
  3223  				srcReg2:           RegV4,
  3224  				vectorArrangement: VectorArrangement16B,
  3225  			},
  3226  			exp: []byte{0x9e, 0x9c, 0x2b, 0x4e},
  3227  		},
  3228  		{
  3229  			name: "sqadd v30.2d, v4.2d, v11.2d",
  3230  			n: &nodeImpl{
  3231  				instruction:       VSQADD,
  3232  				dstReg:            RegV30,
  3233  				srcReg:            RegV11,
  3234  				srcReg2:           RegV4,
  3235  				vectorArrangement: VectorArrangement2D,
  3236  			},
  3237  			exp: []byte{0x9e, 0xc, 0xeb, 0x4e},
  3238  		},
  3239  		{
  3240  			name: "sqadd v30.8h, v4.8h, v11.8h",
  3241  			n: &nodeImpl{
  3242  				instruction:       VSQADD,
  3243  				dstReg:            RegV30,
  3244  				srcReg:            RegV11,
  3245  				srcReg2:           RegV4,
  3246  				vectorArrangement: VectorArrangement8H,
  3247  			},
  3248  			exp: []byte{0x9e, 0xc, 0x6b, 0x4e},
  3249  		},
  3250  		{
  3251  			name: "uqadd v30.4s, v4.4s, v11.4s",
  3252  			n: &nodeImpl{
  3253  				instruction:       VUQADD,
  3254  				dstReg:            RegV30,
  3255  				srcReg:            RegV11,
  3256  				srcReg2:           RegV4,
  3257  				vectorArrangement: VectorArrangement4S,
  3258  			},
  3259  			exp: []byte{0x9e, 0xc, 0xab, 0x6e},
  3260  		},
  3261  		{
  3262  			name: "uqadd v30.8h, v4.8h, v11.8h",
  3263  			n: &nodeImpl{
  3264  				instruction:       VUQADD,
  3265  				dstReg:            RegV30,
  3266  				srcReg:            RegV11,
  3267  				srcReg2:           RegV4,
  3268  				vectorArrangement: VectorArrangement8H,
  3269  			},
  3270  			exp: []byte{0x9e, 0xc, 0x6b, 0x6e},
  3271  		},
  3272  		{
  3273  			name: "smax v30.4s, v4.4s, v11.4s",
  3274  			n: &nodeImpl{
  3275  				instruction:       SMAX,
  3276  				dstReg:            RegV30,
  3277  				srcReg:            RegV11,
  3278  				srcReg2:           RegV4,
  3279  				vectorArrangement: VectorArrangement4S,
  3280  			},
  3281  			exp: []byte{0x9e, 0x64, 0xab, 0x4e},
  3282  		},
  3283  		{
  3284  			name: "smax v30.8h, v4.8h, v11.8h",
  3285  			n: &nodeImpl{
  3286  				instruction:       SMAX,
  3287  				dstReg:            RegV30,
  3288  				srcReg:            RegV11,
  3289  				srcReg2:           RegV4,
  3290  				vectorArrangement: VectorArrangement8H,
  3291  			},
  3292  			exp: []byte{0x9e, 0x64, 0x6b, 0x4e},
  3293  		},
  3294  		{
  3295  			name: "smin v30.16b, v4.16b, v11.16b",
  3296  			n: &nodeImpl{
  3297  				instruction:       SMIN,
  3298  				dstReg:            RegV30,
  3299  				srcReg:            RegV11,
  3300  				srcReg2:           RegV4,
  3301  				vectorArrangement: VectorArrangement16B,
  3302  			},
  3303  			exp: []byte{0x9e, 0x6c, 0x2b, 0x4e},
  3304  		},
  3305  		{
  3306  			name: "smin v30.4s, v4.4s, v11.4s",
  3307  			n: &nodeImpl{
  3308  				instruction:       SMIN,
  3309  				dstReg:            RegV30,
  3310  				srcReg:            RegV11,
  3311  				srcReg2:           RegV4,
  3312  				vectorArrangement: VectorArrangement4S,
  3313  			},
  3314  			exp: []byte{0x9e, 0x6c, 0xab, 0x4e},
  3315  		},
  3316  		{
  3317  			name: "umin v30.16b, v4.16b, v11.16b",
  3318  			n: &nodeImpl{
  3319  				instruction:       UMIN,
  3320  				dstReg:            RegV30,
  3321  				srcReg:            RegV11,
  3322  				srcReg2:           RegV4,
  3323  				vectorArrangement: VectorArrangement16B,
  3324  			},
  3325  			exp: []byte{0x9e, 0x6c, 0x2b, 0x6e},
  3326  		},
  3327  		{
  3328  			name: "umin v30.4s, v4.4s, v11.4s",
  3329  			n: &nodeImpl{
  3330  				instruction:       UMIN,
  3331  				dstReg:            RegV30,
  3332  				srcReg:            RegV11,
  3333  				srcReg2:           RegV4,
  3334  				vectorArrangement: VectorArrangement4S,
  3335  			},
  3336  			exp: []byte{0x9e, 0x6c, 0xab, 0x6e},
  3337  		},
  3338  		{
  3339  			name: "umax v30.4s, v4.4s, v11.4s",
  3340  			n: &nodeImpl{
  3341  				instruction:       UMAX,
  3342  				dstReg:            RegV30,
  3343  				srcReg:            RegV11,
  3344  				srcReg2:           RegV4,
  3345  				vectorArrangement: VectorArrangement4S,
  3346  			},
  3347  			exp: []byte{0x9e, 0x64, 0xab, 0x6e},
  3348  		},
  3349  		{
  3350  			name: "umax v30.8h, v4.8h, v11.8h",
  3351  			n: &nodeImpl{
  3352  				instruction:       UMAX,
  3353  				dstReg:            RegV30,
  3354  				srcReg:            RegV11,
  3355  				srcReg2:           RegV4,
  3356  				vectorArrangement: VectorArrangement8H,
  3357  			},
  3358  			exp: []byte{0x9e, 0x64, 0x6b, 0x6e},
  3359  		},
  3360  		{
  3361  			name: "umax v30.8h, v4.8h, v11.8h",
  3362  			n: &nodeImpl{
  3363  				instruction:       URHADD,
  3364  				dstReg:            RegV30,
  3365  				srcReg:            RegV11,
  3366  				srcReg2:           RegV4,
  3367  				vectorArrangement: VectorArrangement8H,
  3368  			},
  3369  			exp: []byte{0x9e, 0x14, 0x6b, 0x6e},
  3370  		},
  3371  		{
  3372  			name: "umax v30.16b, v4.16b, v11.16b",
  3373  			n: &nodeImpl{
  3374  				instruction:       URHADD,
  3375  				dstReg:            RegV30,
  3376  				srcReg:            RegV11,
  3377  				srcReg2:           RegV4,
  3378  				vectorArrangement: VectorArrangement16B,
  3379  			},
  3380  			exp: []byte{0x9e, 0x14, 0x2b, 0x6e},
  3381  		},
  3382  		{
  3383  			name: "sqsub v30.16b, v4.16b, v11.16b",
  3384  			n: &nodeImpl{
  3385  				instruction:       VSQSUB,
  3386  				dstReg:            RegV30,
  3387  				srcReg:            RegV11,
  3388  				srcReg2:           RegV4,
  3389  				vectorArrangement: VectorArrangement16B,
  3390  			},
  3391  			exp: []byte{0x9e, 0x2c, 0x2b, 0x4e},
  3392  		},
  3393  		{
  3394  			name: "sqsub v308hb, v4.8h, v11.8h",
  3395  			n: &nodeImpl{
  3396  				instruction:       VSQSUB,
  3397  				dstReg:            RegV30,
  3398  				srcReg:            RegV11,
  3399  				srcReg2:           RegV4,
  3400  				vectorArrangement: VectorArrangement8H,
  3401  			},
  3402  			exp: []byte{0x9e, 0x2c, 0x6b, 0x4e},
  3403  		},
  3404  		{
  3405  			name: "uqsub v30.16b, v4.16b, v11.16b",
  3406  			n: &nodeImpl{
  3407  				instruction:       VUQSUB,
  3408  				dstReg:            RegV30,
  3409  				srcReg:            RegV11,
  3410  				srcReg2:           RegV4,
  3411  				vectorArrangement: VectorArrangement16B,
  3412  			},
  3413  			exp: []byte{0x9e, 0x2c, 0x2b, 0x6e},
  3414  		},
  3415  		{
  3416  			name: "uqsub v308hb, v4.8h, v11.8h",
  3417  			n: &nodeImpl{
  3418  				instruction:       VUQSUB,
  3419  				dstReg:            RegV30,
  3420  				srcReg:            RegV11,
  3421  				srcReg2:           RegV4,
  3422  				vectorArrangement: VectorArrangement8H,
  3423  			},
  3424  			exp: []byte{0x9e, 0x2c, 0x6b, 0x6e},
  3425  		},
  3426  		{
  3427  			name: "umlal v0.2d, v6.2s, v2.2s",
  3428  			n: &nodeImpl{
  3429  				instruction:       VUMLAL,
  3430  				dstReg:            RegV0,
  3431  				srcReg:            RegV2,
  3432  				srcReg2:           RegV6,
  3433  				vectorArrangement: VectorArrangement2S,
  3434  			},
  3435  			exp: []byte{0xc0, 0x80, 0xa2, 0x2e},
  3436  		},
  3437  		{
  3438  			name: "umlal v0.4s, v6.4h, v2.4h",
  3439  			n: &nodeImpl{
  3440  				instruction:       VUMLAL,
  3441  				dstReg:            RegV0,
  3442  				srcReg:            RegV2,
  3443  				srcReg2:           RegV6,
  3444  				vectorArrangement: VectorArrangement4H,
  3445  			},
  3446  			exp: []byte{0xc0, 0x80, 0x62, 0x2e},
  3447  		},
  3448  		{
  3449  			name: "umlal v0.8h, v6.8b, v2.8b",
  3450  			n: &nodeImpl{
  3451  				instruction:       VUMLAL,
  3452  				dstReg:            RegV0,
  3453  				srcReg:            RegV2,
  3454  				srcReg2:           RegV6,
  3455  				vectorArrangement: VectorArrangement8B,
  3456  			},
  3457  			exp: []byte{0xc0, 0x80, 0x22, 0x2e},
  3458  		},
  3459  		{
  3460  			name: "bit v30.16b, v4.16b, v11.16b",
  3461  			n: &nodeImpl{
  3462  				instruction:       VBIT,
  3463  				dstReg:            RegV30,
  3464  				srcReg:            RegV11,
  3465  				srcReg2:           RegV4,
  3466  				vectorArrangement: VectorArrangement16B,
  3467  			},
  3468  			exp: []byte{0x9e, 0x1c, 0xab, 0x6e},
  3469  		},
  3470  		{
  3471  			name: "bit v30.8b, v4.8b, v11.8b",
  3472  			n: &nodeImpl{
  3473  				instruction:       VBIT,
  3474  				dstReg:            RegV30,
  3475  				srcReg:            RegV11,
  3476  				srcReg2:           RegV4,
  3477  				vectorArrangement: VectorArrangement8B,
  3478  			},
  3479  			exp: []byte{0x9e, 0x1c, 0xab, 0x2e},
  3480  		},
  3481  		{
  3482  			name: "sqrdmulh v30.8h, v4.8h, v11.8h",
  3483  			n: &nodeImpl{
  3484  				instruction:       SQRDMULH,
  3485  				dstReg:            RegV30,
  3486  				srcReg:            RegV11,
  3487  				srcReg2:           RegV4,
  3488  				vectorArrangement: VectorArrangement8H,
  3489  			},
  3490  			exp: []byte{0x9e, 0xb4, 0x6b, 0x6e},
  3491  		},
  3492  		{
  3493  			name: "sqrdmulh v30.4s, v4.4s, v11.4s",
  3494  			n: &nodeImpl{
  3495  				instruction:       SQRDMULH,
  3496  				dstReg:            RegV30,
  3497  				srcReg:            RegV11,
  3498  				srcReg2:           RegV4,
  3499  				vectorArrangement: VectorArrangement4S,
  3500  			},
  3501  			exp: []byte{0x9e, 0xb4, 0xab, 0x6e},
  3502  		},
  3503  		{
  3504  			name: "smull v30.8h, v4.8b, v11.8b",
  3505  			n: &nodeImpl{
  3506  				instruction:       SMULL,
  3507  				dstReg:            RegV30,
  3508  				srcReg:            RegV11,
  3509  				srcReg2:           RegV4,
  3510  				vectorArrangement: VectorArrangement8B,
  3511  			},
  3512  			exp: []byte{0x9e, 0xc0, 0x2b, 0xe},
  3513  		},
  3514  		{
  3515  			name: "smull v30.4s, v4.4h, v11.4h",
  3516  			n: &nodeImpl{
  3517  				instruction:       SMULL,
  3518  				dstReg:            RegV30,
  3519  				srcReg:            RegV11,
  3520  				srcReg2:           RegV4,
  3521  				vectorArrangement: VectorArrangement4H,
  3522  			},
  3523  			exp: []byte{0x9e, 0xc0, 0x6b, 0xe},
  3524  		},
  3525  		{
  3526  			name: "smull v30.2d, v4.2s, v11.2s",
  3527  			n: &nodeImpl{
  3528  				instruction:       SMULL,
  3529  				dstReg:            RegV30,
  3530  				srcReg:            RegV11,
  3531  				srcReg2:           RegV4,
  3532  				vectorArrangement: VectorArrangement2S,
  3533  			},
  3534  			exp: []byte{0x9e, 0xc0, 0xab, 0xe},
  3535  		},
  3536  		{
  3537  			name: "smull2 v30.8h, v4.16b, v11.16b",
  3538  			n: &nodeImpl{
  3539  				instruction:       SMULL2,
  3540  				dstReg:            RegV30,
  3541  				srcReg:            RegV11,
  3542  				srcReg2:           RegV4,
  3543  				vectorArrangement: VectorArrangement16B,
  3544  			},
  3545  			exp: []byte{0x9e, 0xc0, 0x2b, 0x4e},
  3546  		},
  3547  		{
  3548  			name: "smull2 v30.4s, v4.8h, v11.8h",
  3549  			n: &nodeImpl{
  3550  				instruction:       SMULL2,
  3551  				dstReg:            RegV30,
  3552  				srcReg:            RegV11,
  3553  				srcReg2:           RegV4,
  3554  				vectorArrangement: VectorArrangement8H,
  3555  			},
  3556  			exp: []byte{0x9e, 0xc0, 0x6b, 0x4e},
  3557  		},
  3558  		{
  3559  			name: "smull2 v30.2d, v4.4s, v11.4s",
  3560  			n: &nodeImpl{
  3561  				instruction:       SMULL2,
  3562  				dstReg:            RegV30,
  3563  				srcReg:            RegV11,
  3564  				srcReg2:           RegV4,
  3565  				vectorArrangement: VectorArrangement4S,
  3566  			},
  3567  			exp: []byte{0x9e, 0xc0, 0xab, 0x4e},
  3568  		},
  3569  
  3570  		//////////////////////
  3571  
  3572  		{
  3573  			name: "umull v30.8h, v4.8b, v11.8b",
  3574  			n: &nodeImpl{
  3575  				instruction:       UMULL,
  3576  				dstReg:            RegV30,
  3577  				srcReg:            RegV11,
  3578  				srcReg2:           RegV4,
  3579  				vectorArrangement: VectorArrangement8B,
  3580  			},
  3581  			exp: []byte{0x9e, 0xc0, 0x2b, 0x2e},
  3582  		},
  3583  		{
  3584  			name: "umull v30.4s, v4.4h, v11.4h",
  3585  			n: &nodeImpl{
  3586  				instruction:       UMULL,
  3587  				dstReg:            RegV30,
  3588  				srcReg:            RegV11,
  3589  				srcReg2:           RegV4,
  3590  				vectorArrangement: VectorArrangement4H,
  3591  			},
  3592  			exp: []byte{0x9e, 0xc0, 0x6b, 0x2e},
  3593  		},
  3594  		{
  3595  			name: "umull v30.2d, v4.2s, v11.2s",
  3596  			n: &nodeImpl{
  3597  				instruction:       UMULL,
  3598  				dstReg:            RegV30,
  3599  				srcReg:            RegV11,
  3600  				srcReg2:           RegV4,
  3601  				vectorArrangement: VectorArrangement2S,
  3602  			},
  3603  			exp: []byte{0x9e, 0xc0, 0xab, 0x2e},
  3604  		},
  3605  		{
  3606  			name: "umull2 v30.8h, v4.16b, v11.16b",
  3607  			n: &nodeImpl{
  3608  				instruction:       UMULL2,
  3609  				dstReg:            RegV30,
  3610  				srcReg:            RegV11,
  3611  				srcReg2:           RegV4,
  3612  				vectorArrangement: VectorArrangement16B,
  3613  			},
  3614  			exp: []byte{0x9e, 0xc0, 0x2b, 0x6e},
  3615  		},
  3616  		{
  3617  			name: "umull2 v30.4s, v4.8h, v11.8h",
  3618  			n: &nodeImpl{
  3619  				instruction:       UMULL2,
  3620  				dstReg:            RegV30,
  3621  				srcReg:            RegV11,
  3622  				srcReg2:           RegV4,
  3623  				vectorArrangement: VectorArrangement8H,
  3624  			},
  3625  			exp: []byte{0x9e, 0xc0, 0x6b, 0x6e},
  3626  		},
  3627  		{
  3628  			name: "umull2 v30.2d, v4.4s, v11.4s",
  3629  			n: &nodeImpl{
  3630  				instruction:       UMULL2,
  3631  				dstReg:            RegV30,
  3632  				srcReg:            RegV11,
  3633  				srcReg2:           RegV4,
  3634  				vectorArrangement: VectorArrangement4S,
  3635  			},
  3636  			exp: []byte{0x9e, 0xc0, 0xab, 0x6e},
  3637  		},
  3638  	}
  3639  
  3640  	for _, tt := range tests {
  3641  		tc := tt
  3642  		t.Run(tc.name, func(t *testing.T) {
  3643  			a := NewAssembler(asm.NilRegister)
  3644  			err := a.encodeTwoVectorRegistersToVectorRegister(tc.n)
  3645  			require.NoError(t, err)
  3646  
  3647  			actual := a.Buf.Bytes()
  3648  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  3649  		})
  3650  	}
  3651  }
  3652  
  3653  func TestAssemblerImpl_EncodeRegisterToVectorRegister(t *testing.T) {
  3654  	tests := []struct {
  3655  		name string
  3656  		n    *nodeImpl
  3657  		exp  []byte
  3658  	}{
  3659  		{
  3660  			name: "ins v10.d[0], x10",
  3661  			n: &nodeImpl{
  3662  				instruction:       INSGEN,
  3663  				dstReg:            RegV10,
  3664  				srcReg:            RegR10,
  3665  				vectorArrangement: VectorArrangementD,
  3666  			},
  3667  			exp: []byte{0x4a, 0x1d, 0x8, 0x4e},
  3668  		},
  3669  		{
  3670  			name: "ins v10.d[1], x10",
  3671  			n: &nodeImpl{
  3672  				instruction:       INSGEN,
  3673  				dstReg:            RegV10,
  3674  				srcReg:            RegR10,
  3675  				vectorArrangement: VectorArrangementD,
  3676  				dstVectorIndex:    1,
  3677  			},
  3678  			exp: []byte{0x4a, 0x1d, 0x18, 0x4e},
  3679  		},
  3680  		{
  3681  			name: "dup v10.2d, x10",
  3682  			n: &nodeImpl{
  3683  				instruction:       DUPGEN,
  3684  				srcReg:            RegR10,
  3685  				dstReg:            RegV10,
  3686  				vectorArrangement: VectorArrangement2D,
  3687  			},
  3688  			exp: []byte{0x4a, 0xd, 0x8, 0x4e},
  3689  		},
  3690  		{
  3691  			name: "dup v1.4s, w30",
  3692  			n: &nodeImpl{
  3693  				instruction:       DUPGEN,
  3694  				srcReg:            RegR30,
  3695  				dstReg:            RegV1,
  3696  				vectorArrangement: VectorArrangement4S,
  3697  			},
  3698  			exp: []byte{0xc1, 0xf, 0x4, 0x4e},
  3699  		},
  3700  		{
  3701  			name: "dup v30.8h, w1",
  3702  			n: &nodeImpl{
  3703  				instruction:       DUPGEN,
  3704  				srcReg:            RegR1,
  3705  				dstReg:            RegV30,
  3706  				vectorArrangement: VectorArrangement8H,
  3707  			},
  3708  			exp: []byte{0x3e, 0xc, 0x2, 0x4e},
  3709  		},
  3710  		{
  3711  			name: "dup v30.16b, w1",
  3712  			n: &nodeImpl{
  3713  				instruction:       DUPGEN,
  3714  				srcReg:            RegR1,
  3715  				dstReg:            RegV30,
  3716  				vectorArrangement: VectorArrangement16B,
  3717  			},
  3718  			exp: []byte{0x3e, 0xc, 0x1, 0x4e},
  3719  		},
  3720  	}
  3721  
  3722  	for _, tt := range tests {
  3723  		tc := tt
  3724  		t.Run(tc.name, func(t *testing.T) {
  3725  			a := NewAssembler(asm.NilRegister)
  3726  			err := a.encodeRegisterToVectorRegister(tc.n)
  3727  			require.NoError(t, err)
  3728  
  3729  			actual := a.Buf.Bytes()
  3730  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  3731  		})
  3732  	}
  3733  }
  3734  
  3735  func TestAssemblerImpl_maybeFlushConstPool(t *testing.T) {
  3736  	tests := []struct {
  3737  		name string
  3738  		c    []byte
  3739  		exp  []byte
  3740  	}{
  3741  		{
  3742  			name: "1 byte consts",
  3743  			c:    []byte{1},
  3744  			exp: []byte{
  3745  				// 0x0:
  3746  				// b #0x8
  3747  				0x2, 0x0, 0x0, 0x14,
  3748  				// 0x4:
  3749  				0x1,
  3750  				0x0, 0x0, 0x0, // padding to be 4-byte aligned.
  3751  				// 0x8: <- branch dst.
  3752  			},
  3753  		},
  3754  		{
  3755  			name: "2 byte consts",
  3756  			c:    []byte{0xff, 0xfe},
  3757  			exp: []byte{
  3758  				// 0x0:
  3759  				// b #0x8
  3760  				0x2, 0x0, 0x0, 0x14,
  3761  				// 0x4:
  3762  				0xff, 0xfe,
  3763  				0x0, 0x0, // padding to be 4-byte aligned.
  3764  				// 0x8: <- branch dst.
  3765  			},
  3766  		},
  3767  		{
  3768  			name: "3 byte consts",
  3769  			c:    []byte{0xff, 0xfe, 0xa},
  3770  			exp: []byte{
  3771  				// 0x0:
  3772  				// b #0x8
  3773  				0x2, 0x0, 0x0, 0x14,
  3774  				// 0x4:
  3775  				0xff, 0xfe, 0xa,
  3776  				0x0, // padding to be 4-byte aligned.
  3777  				// 0x8: <- branch dst.
  3778  			},
  3779  		},
  3780  		{
  3781  			name: "4 byte consts",
  3782  			c:    []byte{1, 2, 3, 4},
  3783  			exp: []byte{
  3784  				// 0x0:
  3785  				// b #0x8
  3786  				0x2, 0x0, 0x0, 0x14,
  3787  				// 0x4:
  3788  				0x1, 0x2, 0x3, 0x4,
  3789  				// 0x8: <- branch dst.
  3790  			},
  3791  		},
  3792  		{
  3793  			name: "12 byte consts",
  3794  			c:    []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
  3795  			exp: []byte{
  3796  				// 0x0:
  3797  				// b #0x10
  3798  				0x4, 0x0, 0x0, 0x14,
  3799  				// 0x4:
  3800  				1, 2, 3, 4,
  3801  				5, 6, 7, 8,
  3802  				9, 10, 11, 12,
  3803  				// 0x10: <- branch dst.
  3804  			},
  3805  		},
  3806  		{
  3807  			name: "16 byte consts",
  3808  			c:    []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
  3809  			exp: []byte{
  3810  				// 0x0:
  3811  				// b #0x14
  3812  				0x5, 0x0, 0x0, 0x14,
  3813  				// 0x04:
  3814  				0x1, 0x2, 0x3, 0x4,
  3815  				0x5, 0x6, 0x7, 0x8,
  3816  				0x9, 0xa, 0xb, 0xc,
  3817  				0xd, 0xe, 0xf, 0x10,
  3818  				// 0x14: <- branch dst.
  3819  			},
  3820  		},
  3821  	}
  3822  
  3823  	for _, tc := range tests {
  3824  		tc := tc
  3825  		t.Run(tc.name, func(t *testing.T) {
  3826  			a := NewAssembler(asm.NilRegister)
  3827  			sc := asm.NewStaticConst(tc.c)
  3828  			a.pool.AddConst(sc, 0)
  3829  
  3830  			var called bool
  3831  			sc.AddOffsetFinalizedCallback(func(uint64) {
  3832  				called = true
  3833  			})
  3834  
  3835  			a.MaxDisplacementForConstantPool = 0
  3836  			a.maybeFlushConstPool(false)
  3837  			require.True(t, called)
  3838  
  3839  			actual := a.Buf.Bytes()
  3840  			require.Equal(t, tc.exp, actual)
  3841  		})
  3842  	}
  3843  }
  3844  
  3845  func TestAssemblerImpl_EncodeStaticConstToVectorRegister(t *testing.T) {
  3846  	tests := []struct {
  3847  		name string
  3848  		n    *nodeImpl
  3849  		exp  []byte
  3850  	}{
  3851  		{
  3852  			name: "ldr q8, #8",
  3853  			n: &nodeImpl{
  3854  				instruction:       VMOV,
  3855  				dstReg:            RegV8,
  3856  				vectorArrangement: VectorArrangementQ,
  3857  				staticConst:       asm.NewStaticConst([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}),
  3858  			},
  3859  			exp: []byte{
  3860  				// 0x0: ldr q8, #8
  3861  				0x48, 0x0, 0x0, 0x9c,
  3862  				// Emitted after the end of function.
  3863  				// 0x4: br #4  (See AssemblerImpl.maybeFlushConstPool)
  3864  				0x0, 0x0, 0x0, 0x14,
  3865  				// 0x8: consts.
  3866  				0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
  3867  				0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  3868  			},
  3869  		},
  3870  		{
  3871  			name: "ldr d30, #8",
  3872  			n: &nodeImpl{
  3873  				instruction:       VMOV,
  3874  				dstReg:            RegV30,
  3875  				vectorArrangement: VectorArrangementD,
  3876  				staticConst:       asm.NewStaticConst([]byte{1, 2, 3, 4, 5, 6, 7, 8}),
  3877  			},
  3878  			exp: []byte{
  3879  				// 0x0: ldr d30, #8
  3880  				0x5e, 0x0, 0x0, 0x5c,
  3881  				// Emitted after the end of function.
  3882  				// 0x4: br #4  (See AssemblerImpl.maybeFlushConstPool)
  3883  				0x0, 0x0, 0x0, 0x14,
  3884  				// 0x8: consts.
  3885  				0x1, 0x2, 0x3, 0x4,
  3886  				0x5, 0x6, 0x7, 0x8,
  3887  			},
  3888  		},
  3889  		{
  3890  			name: "ldr s8, #8",
  3891  			n: &nodeImpl{
  3892  				instruction:       VMOV,
  3893  				dstReg:            RegV8,
  3894  				vectorArrangement: VectorArrangementS,
  3895  				staticConst:       asm.NewStaticConst([]byte{1, 2, 3, 4}),
  3896  			},
  3897  			exp: []byte{
  3898  				// 0x0: ldr s8, #8
  3899  				0x48, 0x0, 0x0, 0x1c,
  3900  				// Emitted after the end of function.
  3901  				// 0x4: br #4  (See AssemblerImpl.maybeFlushConstPool)
  3902  				0x0, 0x0, 0x0, 0x14,
  3903  				// 0x8: consts.
  3904  				0x1, 0x2, 0x3, 0x4,
  3905  				0x0, 0x0, 0x0, 0x0,
  3906  			},
  3907  		},
  3908  	}
  3909  
  3910  	for _, tc := range tests {
  3911  		tc := tc
  3912  		t.Run(tc.name, func(t *testing.T) {
  3913  			a := NewAssembler(asm.NilRegister)
  3914  			err := a.encodeStaticConstToVectorRegister(tc.n)
  3915  			require.NoError(t, err)
  3916  			a.maybeFlushConstPool(true)
  3917  
  3918  			actual, err := a.Assemble()
  3919  			require.NoError(t, err)
  3920  
  3921  			require.Equal(t, tc.exp, actual, hex.EncodeToString(actual))
  3922  		})
  3923  	}
  3924  }
  3925  
  3926  func TestAssemblerImpl_encodeADR_staticConst(t *testing.T) {
  3927  	const beforeADRByteNum uint64 = 2
  3928  
  3929  	tests := []struct {
  3930  		name                   string
  3931  		reg                    asm.Register
  3932  		offsetOfConstInBinary  uint64
  3933  		expADRInstructionBytes []byte
  3934  	}{
  3935  		{
  3936  			// #8 = offsetOfConstInBinary - beforeADRByteNum.
  3937  			name:                   "adr x12, #8",
  3938  			reg:                    RegR12,
  3939  			offsetOfConstInBinary:  10,
  3940  			expADRInstructionBytes: []byte{0x4c, 0x0, 0x0, 0x10},
  3941  		},
  3942  		{
  3943  			// #0x7fffd = offsetOfConstInBinary - beforeADRByteNum.
  3944  			name:                   "adr x12, #0x7fffd",
  3945  			reg:                    RegR12,
  3946  			offsetOfConstInBinary:  0x7ffff,
  3947  			expADRInstructionBytes: []byte{0xec, 0xff, 0x3f, 0x30},
  3948  		},
  3949  	}
  3950  
  3951  	for _, tc := range tests {
  3952  		tc := tc
  3953  		t.Run(tc.name, func(t *testing.T) {
  3954  			sc := asm.NewStaticConst([]byte{1, 2, 3, 4}) // Arbitrary data is fine.
  3955  
  3956  			a := NewAssembler(asm.NilRegister)
  3957  
  3958  			a.Buf.Write(make([]byte, beforeADRByteNum))
  3959  
  3960  			err := a.encodeADR(&nodeImpl{instruction: ADR, dstReg: tc.reg, staticConst: sc})
  3961  			require.NoError(t, err)
  3962  
  3963  			require.Equal(t, 1, len(a.pool.Consts))
  3964  			require.Equal(t, sc, a.pool.Consts[0])
  3965  
  3966  			require.Equal(t, beforeADRByteNum, *a.pool.FirstUseOffsetInBinary)
  3967  
  3968  			// Finalize the ADR instruction bytes.
  3969  			sc.SetOffsetInBinary(tc.offsetOfConstInBinary)
  3970  
  3971  			actualBytes := a.Buf.Bytes()[beforeADRByteNum : beforeADRByteNum+4]
  3972  			require.Equal(t, tc.expADRInstructionBytes, actualBytes, hex.EncodeToString(actualBytes))
  3973  		})
  3974  	}
  3975  }