@@ -393,6 +393,11 @@ var optab = []Optab{
393
393
{AMOVK , C_VCON , C_NONE , C_NONE , C_REG , 33 , 4 , 0 , 0 , 0 },
394
394
{AMOVD , C_AACON , C_NONE , C_NONE , C_REG , 4 , 4 , REGFROM , 0 , 0 },
395
395
396
+ // Move a large constant to a Vn.
397
+ {AFMOVQ , C_VCON , C_NONE , C_NONE , C_VREG , 101 , 4 , 0 , LFROM , 0 },
398
+ {AFMOVD , C_VCON , C_NONE , C_NONE , C_VREG , 101 , 4 , 0 , LFROM , 0 },
399
+ {AFMOVS , C_LCON , C_NONE , C_NONE , C_VREG , 101 , 4 , 0 , LFROM , 0 },
400
+
396
401
/* jump operations */
397
402
{AB , C_NONE , C_NONE , C_NONE , C_SBRA , 5 , 4 , 0 , 0 , 0 },
398
403
{ABL , C_NONE , C_NONE , C_NONE , C_SBRA , 5 , 4 , 0 , 0 , 0 },
@@ -403,12 +408,14 @@ var optab = []Optab{
403
408
{obj .ARET , C_NONE , C_NONE , C_NONE , C_REG , 6 , 4 , 0 , 0 , 0 },
404
409
{obj .ARET , C_NONE , C_NONE , C_NONE , C_ZOREG , 6 , 4 , 0 , 0 , 0 },
405
410
{ABEQ , C_NONE , C_NONE , C_NONE , C_SBRA , 7 , 4 , 0 , 0 , 0 },
406
- {AADRP , C_SBRA , C_NONE , C_NONE , C_REG , 60 , 4 , 0 , 0 , 0 },
407
- {AADR , C_SBRA , C_NONE , C_NONE , C_REG , 61 , 4 , 0 , 0 , 0 },
408
411
{ACBZ , C_REG , C_NONE , C_NONE , C_SBRA , 39 , 4 , 0 , 0 , 0 },
409
412
{ATBZ , C_VCON , C_REG , C_NONE , C_SBRA , 40 , 4 , 0 , 0 , 0 },
410
413
{AERET , C_NONE , C_NONE , C_NONE , C_NONE , 41 , 4 , 0 , 0 , 0 },
411
414
415
+ // get a PC-relative address
416
+ {AADRP , C_SBRA , C_NONE , C_NONE , C_REG , 60 , 4 , 0 , 0 , 0 },
417
+ {AADR , C_SBRA , C_NONE , C_NONE , C_REG , 61 , 4 , 0 , 0 , 0 },
418
+
412
419
{ACLREX , C_NONE , C_NONE , C_NONE , C_VCON , 38 , 4 , 0 , 0 , 0 },
413
420
{ACLREX , C_NONE , C_NONE , C_NONE , C_NONE , 38 , 4 , 0 , 0 , 0 },
414
421
{ABFM , C_VCON , C_REG , C_VCON , C_REG , 42 , 4 , 0 , 0 , 0 },
@@ -473,6 +480,7 @@ var optab = []Optab{
473
480
{AVTBL , C_ARNG , C_NONE , C_LIST , C_ARNG , 100 , 4 , 0 , 0 , 0 },
474
481
{AVUSHR , C_VCON , C_ARNG , C_NONE , C_ARNG , 95 , 4 , 0 , 0 , 0 },
475
482
{AVZIP1 , C_ARNG , C_ARNG , C_NONE , C_ARNG , 72 , 4 , 0 , 0 , 0 },
483
+ {AVUXTL , C_ARNG , C_NONE , C_NONE , C_ARNG , 102 , 4 , 0 , 0 , 0 },
476
484
477
485
/* conditional operations */
478
486
{ACSEL , C_COND , C_REG , C_REG , C_REG , 18 , 4 , 0 , 0 , 0 },
@@ -2657,7 +2665,7 @@ func buildop(ctxt *obj.Link) {
2657
2665
case AFCSELD :
2658
2666
oprangeset (AFCSELS , t )
2659
2667
2660
- case AFMOVS , AFMOVD :
2668
+ case AFMOVS , AFMOVD , AFMOVQ :
2661
2669
break
2662
2670
2663
2671
case AFCVTZSD :
@@ -2740,6 +2748,9 @@ func buildop(ctxt *obj.Link) {
2740
2748
oprangeset (AVCMEQ , t )
2741
2749
oprangeset (AVORR , t )
2742
2750
oprangeset (AVEOR , t )
2751
+ oprangeset (AVBSL , t )
2752
+ oprangeset (AVBIT , t )
2753
+ oprangeset (AVCMTST , t )
2743
2754
2744
2755
case AVADD :
2745
2756
oprangeset (AVSUB , t )
@@ -2787,6 +2798,9 @@ func buildop(ctxt *obj.Link) {
2787
2798
case AVZIP1 :
2788
2799
oprangeset (AVZIP2 , t )
2789
2800
2801
+ case AVUXTL :
2802
+ oprangeset (AVUXTL2 , t )
2803
+
2790
2804
case AVLD1R :
2791
2805
oprangeset (AVLD2 , t )
2792
2806
oprangeset (AVLD2R , t )
@@ -4163,7 +4177,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
4163
4177
rel .Add = 0
4164
4178
rel .Type = objabi .R_ARM64_GOTPCREL
4165
4179
4166
- case 72 : /* vaddp/vand/vcmeq/vorr/vadd/veor/vfmla/vfmls Vm.<T>, Vn.<T>, Vd.<T> */
4180
+ case 72 : /* vaddp/vand/vcmeq/vorr/vadd/veor/vfmla/vfmls/vbit/vbsl/vcmtst/vsub Vm.<T>, Vn.<T>, Vd.<T> */
4167
4181
af := int ((p .From .Reg >> 5 ) & 15 )
4168
4182
af3 := int ((p .Reg >> 5 ) & 15 )
4169
4183
at := int ((p .To .Reg >> 5 ) & 15 )
@@ -4204,17 +4218,24 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
4204
4218
c .ctxt .Diag ("invalid arrangement: %v" , p )
4205
4219
}
4206
4220
4207
- if (p .As == AVORR || p .As == AVAND || p .As == AVEOR ) &&
4208
- (af != ARNG_16B && af != ARNG_8B ) {
4209
- c .ctxt .Diag ("invalid arrangement: %v" , p )
4210
- } else if (p .As == AVFMLA || p .As == AVFMLS ) &&
4211
- (af != ARNG_2D && af != ARNG_2S && af != ARNG_4S ) {
4212
- c .ctxt .Diag ("invalid arrangement: %v" , p )
4213
- } else if p .As == AVORR {
4214
- size = 2
4215
- } else if p .As == AVAND || p .As == AVEOR {
4221
+ switch p .As {
4222
+ case AVORR , AVAND , AVEOR , AVBIT , AVBSL :
4223
+ if af != ARNG_16B && af != ARNG_8B {
4224
+ c .ctxt .Diag ("invalid arrangement: %v" , p )
4225
+ }
4226
+ case AVFMLA , AVFMLS :
4227
+ if af != ARNG_2D && af != ARNG_2S && af != ARNG_4S {
4228
+ c .ctxt .Diag ("invalid arrangement: %v" , p )
4229
+ }
4230
+ }
4231
+ switch p .As {
4232
+ case AVAND , AVEOR :
4216
4233
size = 0
4217
- } else if p .As == AVFMLA || p .As == AVFMLS {
4234
+ case AVBSL :
4235
+ size = 1
4236
+ case AVORR , AVBIT :
4237
+ size = 2
4238
+ case AVFMLA , AVFMLS :
4218
4239
if af == ARNG_2D {
4219
4240
size = 1
4220
4241
} else {
@@ -5096,6 +5117,59 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
5096
5117
o1 = q << 30 | 0xe << 24 | len << 13
5097
5118
o1 |= (uint32 (rf & 31 ) << 16 ) | uint32 (offset & 31 )<< 5 | uint32 (rt & 31 )
5098
5119
5120
+ case 101 : // FOMVQ/FMOVD $vcon, Vd -> load from constant pool.
5121
+ o1 = c .omovlit (p .As , p , & p .From , int (p .To .Reg ))
5122
+
5123
+ case 102 : // VUXTL{2} Vn.<Tb>, Vd.<Ta>
5124
+ af := int ((p .From .Reg >> 5 ) & 15 )
5125
+ at := int ((p .To .Reg >> 5 ) & 15 )
5126
+ var Q , immh uint32
5127
+ switch at {
5128
+ case ARNG_8H :
5129
+ if af == ARNG_8B {
5130
+ immh = 1
5131
+ Q = 0
5132
+ } else if af == ARNG_16B {
5133
+ immh = 1
5134
+ Q = 1
5135
+ } else {
5136
+ c .ctxt .Diag ("operand mismatch: %v\n " , p )
5137
+ }
5138
+ case ARNG_4S :
5139
+ if af == ARNG_4H {
5140
+ immh = 2
5141
+ Q = 0
5142
+ } else if af == ARNG_8H {
5143
+ immh = 2
5144
+ Q = 1
5145
+ } else {
5146
+ c .ctxt .Diag ("operand mismatch: %v\n " , p )
5147
+ }
5148
+ case ARNG_2D :
5149
+ if af == ARNG_2S {
5150
+ immh = 4
5151
+ Q = 0
5152
+ } else if af == ARNG_4S {
5153
+ immh = 4
5154
+ Q = 1
5155
+ } else {
5156
+ c .ctxt .Diag ("operand mismatch: %v\n " , p )
5157
+ }
5158
+ default :
5159
+ c .ctxt .Diag ("operand mismatch: %v\n " , p )
5160
+ }
5161
+
5162
+ if p .As == AVUXTL && Q == 1 {
5163
+ c .ctxt .Diag ("operand mismatch: %v\n " , p )
5164
+ }
5165
+ if p .As == AVUXTL2 && Q == 0 {
5166
+ c .ctxt .Diag ("operand mismatch: %v\n " , p )
5167
+ }
5168
+
5169
+ o1 = c .oprrr (p , p .As )
5170
+ rf := int ((p .From .Reg ) & 31 )
5171
+ rt := int ((p .To .Reg ) & 31 )
5172
+ o1 |= Q << 30 | immh << 19 | uint32 ((rf & 31 )<< 5 ) | uint32 (rt & 31 )
5099
5173
}
5100
5174
out [0 ] = o1
5101
5175
out [1 ] = o2
@@ -5662,6 +5736,9 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 {
5662
5736
case AVADD :
5663
5737
return 7 << 25 | 1 << 21 | 1 << 15 | 1 << 10
5664
5738
5739
+ case AVSUB :
5740
+ return 0x17 << 25 | 1 << 21 | 1 << 15 | 1 << 10
5741
+
5665
5742
case AVADDP :
5666
5743
return 7 << 25 | 1 << 21 | 1 << 15 | 15 << 10
5667
5744
@@ -5724,6 +5801,18 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 {
5724
5801
5725
5802
case AVLD2R , AVLD4R :
5726
5803
return 0xD << 24 | 3 << 21
5804
+
5805
+ case AVBIT :
5806
+ return 1 << 29 | 0x75 << 21 | 7 << 10
5807
+
5808
+ case AVBSL :
5809
+ return 1 << 29 | 0x73 << 21 | 7 << 10
5810
+
5811
+ case AVCMTST :
5812
+ return 0xE << 24 | 1 << 21 | 0x23 << 10
5813
+
5814
+ case AVUXTL , AVUXTL2 :
5815
+ return 0x5e << 23 | 0x29 << 10
5727
5816
}
5728
5817
5729
5818
c .ctxt .Diag ("%v: bad rrr %d %v" , p , a , a )
@@ -6566,6 +6655,10 @@ func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
6566
6655
fp = 1
6567
6656
w = 1 /* 64-bit SIMD/FP */
6568
6657
6658
+ case AFMOVQ :
6659
+ fp = 1
6660
+ w = 2 /* 128-bit SIMD/FP */
6661
+
6569
6662
case AMOVD :
6570
6663
if p .Pool .As == ADWORD {
6571
6664
w = 1 /* 64-bit */
0 commit comments