@@ -2362,7 +2362,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
2362
2362
r = rt
2363
2363
}
2364
2364
if p .To .Type != obj .TYPE_NONE && (p .To .Reg == REGSP || r == REGSP ) {
2365
- o2 = c .opxrrr (p , p .As )
2365
+ o2 = c .opxrrr (p , p .As , false )
2366
2366
o2 |= REGTMP & 31 << 16
2367
2367
o2 |= LSL0_64
2368
2368
} else {
@@ -2591,11 +2591,16 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
2591
2591
o1 |= (REGZERO & 31 << 5 ) | uint32 (rt & 31 )
2592
2592
2593
2593
case 27 : /* op Rm<<n[,Rn],Rd (extended register) */
2594
- o1 = c .opxrrr (p , p .As )
2595
2594
2596
2595
if (p .From .Reg - obj .RBaseARM64 )& REG_EXT != 0 {
2596
+ amount := (p .From .Reg >> 5 ) & 7
2597
+ if amount > 4 {
2598
+ c .ctxt .Diag ("shift amount out of range 0 to 4: %v" , p )
2599
+ }
2600
+ o1 = c .opxrrr (p , p .As , true )
2597
2601
o1 |= uint32 (p .From .Offset ) /* includes reg, op, etc */
2598
2602
} else {
2603
+ o1 = c .opxrrr (p , p .As , false )
2599
2604
o1 |= uint32 (p .From .Reg & 31 ) << 16
2600
2605
}
2601
2606
rt := int (p .To .Reg )
@@ -2755,7 +2760,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
2755
2760
if ! (o1 != 0 ) {
2756
2761
break
2757
2762
}
2758
- o2 = c .opxrrr (p , AADD )
2763
+ o2 = c .opxrrr (p , AADD , false )
2759
2764
o2 |= REGTMP & 31 << 16
2760
2765
o2 |= LSL0_64
2761
2766
r := int (p .From .Reg )
@@ -3122,7 +3127,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
3122
3127
r = rt
3123
3128
}
3124
3129
if p .To .Type != obj .TYPE_NONE && (p .To .Reg == REGSP || r == REGSP ) {
3125
- o2 = c .opxrrr (p , p .As )
3130
+ o2 = c .opxrrr (p , p .As , false )
3126
3131
o2 |= REGTMP & 31 << 16
3127
3132
o2 |= LSL0_64
3128
3133
} else {
@@ -3373,7 +3378,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
3373
3378
}
3374
3379
3375
3380
o1 = c .omovlit (AMOVD , p , & p .From , REGTMP )
3376
- o2 = c .opxrrr (p , AADD )
3381
+ o2 = c .opxrrr (p , AADD , false )
3377
3382
o2 |= (REGTMP & 31 ) << 16
3378
3383
o2 |= uint32 (r & 31 ) << 5
3379
3384
o2 |= uint32 (REGTMP & 31 )
@@ -3426,7 +3431,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
3426
3431
o3 |= 2 << 23
3427
3432
}
3428
3433
o1 = c .omovlit (AMOVD , p , & p .To , REGTMP )
3429
- o2 = c .opxrrr (p , AADD )
3434
+ o2 = c .opxrrr (p , AADD , false )
3430
3435
o2 |= REGTMP & 31 << 16
3431
3436
o2 |= uint32 (r & 31 ) << 5
3432
3437
o2 |= uint32 (REGTMP & 31 )
@@ -4518,33 +4523,44 @@ func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 {
4518
4523
}
4519
4524
4520
4525
/*
4521
- * add/subtract extended register
4526
+ * add/subtract sign or zero- extended register
4522
4527
*/
4523
- func (c * ctxt7 ) opxrrr (p * obj.Prog , a obj.As ) uint32 {
4528
+ func (c * ctxt7 ) opxrrr (p * obj.Prog , a obj.As , extend bool ) uint32 {
4529
+ extension := uint32 (0 )
4530
+ if ! extend {
4531
+ switch a {
4532
+ case AADD , ACMN , AADDS , ASUB , ACMP , ASUBS :
4533
+ extension = LSL0_64
4534
+
4535
+ case AADDW , ACMNW , AADDSW , ASUBW , ACMPW , ASUBSW :
4536
+ extension = LSL0_32
4537
+ }
4538
+ }
4539
+
4524
4540
switch a {
4525
4541
case AADD :
4526
- return S64 | 0 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_64
4542
+ return S64 | 0 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4527
4543
4528
4544
case AADDW :
4529
- return S32 | 0 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_32
4545
+ return S32 | 0 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4530
4546
4531
4547
case ACMN , AADDS :
4532
- return S64 | 0 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_64
4548
+ return S64 | 0 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4533
4549
4534
4550
case ACMNW , AADDSW :
4535
- return S32 | 0 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_32
4551
+ return S32 | 0 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4536
4552
4537
4553
case ASUB :
4538
- return S64 | 1 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_64
4554
+ return S64 | 1 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4539
4555
4540
4556
case ASUBW :
4541
- return S32 | 1 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_32
4557
+ return S32 | 1 << 30 | 0 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4542
4558
4543
4559
case ACMP , ASUBS :
4544
- return S64 | 1 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_64
4560
+ return S64 | 1 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4545
4561
4546
4562
case ACMPW , ASUBSW :
4547
- return S32 | 1 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | LSL0_32
4563
+ return S32 | 1 << 30 | 1 << 29 | 0x0b << 24 | 0 << 22 | 1 << 21 | extension
4548
4564
}
4549
4565
4550
4566
c .ctxt .Diag ("bad opxrrr %v\n %v" , a , p )
0 commit comments