@@ -428,15 +428,13 @@ var optab = []Optab{
428
428
{as : ASTXSIWX , a1 : C_VSREG , a6 : C_SOREG , type_ : 86 , size : 4 }, /* vsx scalar as integer store, xx1-form */
429
429
430
430
/* VSX move from VSR */
431
- {as : AMFVSRD , a1 : C_VSREG , a6 : C_REG , type_ : 88 , size : 4 }, /* vsx move from vsr, xx1-form */
431
+ {as : AMFVSRD , a1 : C_VSREG , a6 : C_REG , type_ : 88 , size : 4 },
432
432
{as : AMFVSRD , a1 : C_FREG , a6 : C_REG , type_ : 88 , size : 4 },
433
- {as : AMFVSRD , a1 : C_VREG , a6 : C_REG , type_ : 88 , size : 4 },
434
433
435
434
/* VSX move to VSR */
436
- {as : AMTVSRD , a1 : C_REG , a6 : C_VSREG , type_ : 88 , size : 4 }, /* vsx move to vsr, xx1-form */
437
- {as : AMTVSRD , a1 : C_REG , a2 : C_REG , a6 : C_VSREG , type_ : 88 , size : 4 },
438
- {as : AMTVSRD , a1 : C_REG , a6 : C_FREG , type_ : 88 , size : 4 },
439
- {as : AMTVSRD , a1 : C_REG , a6 : C_VREG , type_ : 88 , size : 4 },
435
+ {as : AMTVSRD , a1 : C_REG , a6 : C_VSREG , type_ : 104 , size : 4 },
436
+ {as : AMTVSRD , a1 : C_REG , a6 : C_FREG , type_ : 104 , size : 4 },
437
+ {as : AMTVSRDD , a1 : C_REG , a2 : C_REG , a6 : C_VSREG , type_ : 104 , size : 4 },
440
438
441
439
/* VSX logical */
442
440
{as : AXXLAND , a1 : C_VSREG , a2 : C_VSREG , a6 : C_VSREG , type_ : 90 , size : 4 }, /* vsx and, xx3-form */
@@ -1036,13 +1034,14 @@ func (c *ctxt9) oplook(p *obj.Prog) *Optab {
1036
1034
// c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4, a5, a6)
1037
1035
ops := oprange [p .As & obj .AMask ]
1038
1036
c1 := & xcmp [a1 ]
1037
+ c2 := & xcmp [a2 ]
1039
1038
c3 := & xcmp [a3 ]
1040
1039
c4 := & xcmp [a4 ]
1041
1040
c5 := & xcmp [a5 ]
1042
1041
c6 := & xcmp [a6 ]
1043
1042
for i := range ops {
1044
1043
op := & ops [i ]
1045
- if int ( op .a2 ) == a2 && c1 [op .a1 ] && c3 [op .a3 ] && c4 [op .a4 ] && c5 [op .a5 ] && c6 [op .a6 ] {
1044
+ if c1 [ op .a1 ] && c2 [op .a2 ] && c3 [op .a3 ] && c4 [op .a4 ] && c5 [op .a5 ] && c6 [op .a6 ] {
1046
1045
p .Optab = uint16 (cap (optab ) - cap (ops ) + i + 1 )
1047
1046
return op
1048
1047
}
@@ -1116,6 +1115,12 @@ func cmp(a int, b int) bool {
1116
1115
return r0iszero != 0 /*TypeKind(100016)*/
1117
1116
}
1118
1117
1118
+ case C_VSREG :
1119
+ /* Allow any VR argument as a VSR operand. */
1120
+ if b == C_VREG {
1121
+ return true
1122
+ }
1123
+
1119
1124
case C_ANY :
1120
1125
return true
1121
1126
}
@@ -1594,7 +1599,6 @@ func buildop(ctxt *obj.Link) {
1594
1599
opset (AMTVRD , r0 )
1595
1600
opset (AMTVSRWA , r0 )
1596
1601
opset (AMTVSRWZ , r0 )
1597
- opset (AMTVSRDD , r0 )
1598
1602
opset (AMTVSRWS , r0 )
1599
1603
1600
1604
case AXXLAND : /* xxland, xxlandc, xxleqv, xxlnand */
@@ -1977,6 +1981,7 @@ func buildop(ctxt *obj.Link) {
1977
1981
ACMPEQB ,
1978
1982
AECIWX ,
1979
1983
ACLRLSLWI ,
1984
+ AMTVSRDD ,
1980
1985
obj .ANOP ,
1981
1986
obj .ATEXT ,
1982
1987
obj .AUNDEF ,
@@ -2075,58 +2080,40 @@ func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
2075
2080
}
2076
2081
2077
2082
/* XX1-form 3-register operands, 1 VSR operand */
2078
- func AOP_XX1 (op uint32 , d uint32 , a uint32 , b uint32 ) uint32 {
2079
- /* For the XX-form encodings, we need the VSX register number to be exactly */
2080
- /* between 0-63, so we can properly set the rightmost bits. */
2081
- r := d - REG_VS0
2083
+ func AOP_XX1 (op uint32 , r uint32 , a uint32 , b uint32 ) uint32 {
2082
2084
return op | (r & 31 )<< 21 | (a & 31 )<< 16 | (b & 31 )<< 11 | (r & 32 )>> 5
2083
2085
}
2084
2086
2085
2087
/* XX2-form 3-register operands, 2 VSR operands */
2086
- func AOP_XX2 (op uint32 , d uint32 , a uint32 , b uint32 ) uint32 {
2087
- xt := d - REG_VS0
2088
- xb := b - REG_VS0
2088
+ func AOP_XX2 (op uint32 , xt uint32 , a uint32 , xb uint32 ) uint32 {
2089
2089
return op | (xt & 31 )<< 21 | (a & 3 )<< 16 | (xb & 31 )<< 11 | (xb & 32 )>> 4 | (xt & 32 )>> 5
2090
2090
}
2091
2091
2092
2092
/* XX3-form 3 VSR operands */
2093
- func AOP_XX3 (op uint32 , d uint32 , a uint32 , b uint32 ) uint32 {
2094
- xt := d - REG_VS0
2095
- xa := a - REG_VS0
2096
- xb := b - REG_VS0
2093
+ func AOP_XX3 (op uint32 , xt uint32 , xa uint32 , xb uint32 ) uint32 {
2097
2094
return op | (xt & 31 )<< 21 | (xa & 31 )<< 16 | (xb & 31 )<< 11 | (xa & 32 )>> 3 | (xb & 32 )>> 4 | (xt & 32 )>> 5
2098
2095
}
2099
2096
2100
2097
/* XX3-form 3 VSR operands + immediate */
2101
- func AOP_XX3I (op uint32 , d uint32 , a uint32 , b uint32 , c uint32 ) uint32 {
2102
- xt := d - REG_VS0
2103
- xa := a - REG_VS0
2104
- xb := b - REG_VS0
2098
+ func AOP_XX3I (op uint32 , xt uint32 , xa uint32 , xb uint32 , c uint32 ) uint32 {
2105
2099
return op | (xt & 31 )<< 21 | (xa & 31 )<< 16 | (xb & 31 )<< 11 | (c & 3 )<< 8 | (xa & 32 )>> 3 | (xb & 32 )>> 4 | (xt & 32 )>> 5
2106
2100
}
2107
2101
2108
2102
/* XX4-form, 4 VSR operands */
2109
- func AOP_XX4 (op uint32 , d uint32 , a uint32 , b uint32 , c uint32 ) uint32 {
2110
- xt := d - REG_VS0
2111
- xa := a - REG_VS0
2112
- xb := b - REG_VS0
2113
- xc := c - REG_VS0
2103
+ func AOP_XX4 (op uint32 , xt uint32 , xa uint32 , xb uint32 , xc uint32 ) uint32 {
2114
2104
return op | (xt & 31 )<< 21 | (xa & 31 )<< 16 | (xb & 31 )<< 11 | (xc & 31 )<< 6 | (xc & 32 )>> 2 | (xa & 32 )>> 3 | (xb & 32 )>> 4 | (xt & 32 )>> 5
2115
2105
}
2116
2106
2117
2107
/* DQ-form, VSR register, register + offset operands */
2118
- func AOP_DQ (op uint32 , d uint32 , a uint32 , b uint32 ) uint32 {
2119
- /* For the DQ-form encodings, we need the VSX register number to be exactly */
2120
- /* between 0-63, so we can properly set the SX bit. */
2121
- r := d - REG_VS0
2108
+ func AOP_DQ (op uint32 , xt uint32 , a uint32 , b uint32 ) uint32 {
2122
2109
/* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
2123
2110
/* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
2124
2111
/* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
2125
2112
/* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */
2126
2113
/* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
2127
2114
/* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
2128
2115
dq := b >> 4
2129
- return op | (r & 31 )<< 21 | (a & 31 )<< 16 | (dq & 4095 )<< 4 | (r & 32 )>> 2
2116
+ return op | (xt & 31 )<< 21 | (a & 31 )<< 16 | (dq & 4095 )<< 4 | (xt & 32 )>> 2
2130
2117
}
2131
2118
2132
2119
/* Z23-form, 3-register operands + CY field */
@@ -3586,33 +3573,8 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
3586
3573
/* 3-register operand order: (RB)(RA*1), XT */
3587
3574
o1 = AOP_XX1 (c .oploadx (p .As ), uint32 (p .To .Reg ), uint32 (p .From .Index ), uint32 (p .From .Reg ))
3588
3575
3589
- case 88 : /* VSX instructions, XX1-form */
3590
- /* reg reg none OR reg reg reg */
3591
- /* 3-register operand order: RA, RB, XT */
3592
- /* 2-register operand order: XS, RA or RA, XT */
3593
- xt := int32 (p .To .Reg )
3594
- xs := int32 (p .From .Reg )
3595
- /* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */
3596
- if REG_V0 <= xt && xt <= REG_V31 {
3597
- /* Convert V0-V31 to VS32-VS63 */
3598
- xt = xt + 64
3599
- o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (xt ), uint32 (p .From .Reg ), uint32 (p .Reg ))
3600
- } else if REG_F0 <= xt && xt <= REG_F31 {
3601
- /* Convert F0-F31 to VS0-VS31 */
3602
- xt = xt + 64
3603
- o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (xt ), uint32 (p .From .Reg ), uint32 (p .Reg ))
3604
- } else if REG_VS0 <= xt && xt <= REG_VS63 {
3605
- o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (xt ), uint32 (p .From .Reg ), uint32 (p .Reg ))
3606
- } else if REG_V0 <= xs && xs <= REG_V31 {
3607
- /* Likewise for XS */
3608
- xs = xs + 64
3609
- o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (xs ), uint32 (p .To .Reg ), uint32 (p .Reg ))
3610
- } else if REG_F0 <= xs && xs <= REG_F31 {
3611
- xs = xs + 64
3612
- o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (xs ), uint32 (p .To .Reg ), uint32 (p .Reg ))
3613
- } else if REG_VS0 <= xs && xs <= REG_VS63 {
3614
- o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (xs ), uint32 (p .To .Reg ), uint32 (p .Reg ))
3615
- }
3576
+ case 88 : /* VSX mfvsr* instructions, XX1-form XS,RA */
3577
+ o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (p .From .Reg ), uint32 (p .To .Reg ), uint32 (p .Reg ))
3616
3578
3617
3579
case 89 : /* VSX instructions, XX2-form */
3618
3580
/* reg none reg OR reg imm reg */
@@ -3743,6 +3705,9 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
3743
3705
mb := uint32 (c .regoff (& p .RestArgs [0 ].Addr ))
3744
3706
me := uint32 (c .regoff (& p .RestArgs [1 ].Addr ))
3745
3707
o1 = OP_RLW (c .oprrr (p .As ), uint32 (p .To .Reg ), uint32 (p .Reg ), uint32 (p .From .Reg ), mb , me )
3708
+
3709
+ case 104 : /* VSX mtvsr* instructions, XX1-form RA,RB,XT */
3710
+ o1 = AOP_XX1 (c .oprrr (p .As ), uint32 (p .To .Reg ), uint32 (p .From .Reg ), uint32 (p .Reg ))
3746
3711
}
3747
3712
3748
3713
out [0 ] = o1
0 commit comments