aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/ppc64/asm9.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/internal/obj/ppc64/asm9.go')
-rw-r--r--src/cmd/internal/obj/ppc64/asm9.go85
1 files changed, 25 insertions, 60 deletions
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index e642413590..1d92c4866f 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -428,15 +428,13 @@ var optab = []Optab{
{as: ASTXSIWX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
/* VSX move from VSR */
- {as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4}, /* vsx move from vsr, xx1-form */
+ {as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4},
{as: AMFVSRD, a1: C_FREG, a6: C_REG, type_: 88, size: 4},
- {as: AMFVSRD, a1: C_VREG, a6: C_REG, type_: 88, size: 4},
/* VSX move to VSR */
- {as: AMTVSRD, a1: C_REG, a6: C_VSREG, type_: 88, size: 4}, /* vsx move to vsr, xx1-form */
- {as: AMTVSRD, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 88, size: 4},
- {as: AMTVSRD, a1: C_REG, a6: C_FREG, type_: 88, size: 4},
- {as: AMTVSRD, a1: C_REG, a6: C_VREG, type_: 88, size: 4},
+ {as: AMTVSRD, a1: C_REG, a6: C_VSREG, type_: 104, size: 4},
+ {as: AMTVSRD, a1: C_REG, a6: C_FREG, type_: 104, size: 4},
+ {as: AMTVSRDD, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 104, size: 4},
/* VSX logical */
{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 {
// c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4, a5, a6)
ops := oprange[p.As&obj.AMask]
c1 := &xcmp[a1]
+ c2 := &xcmp[a2]
c3 := &xcmp[a3]
c4 := &xcmp[a4]
c5 := &xcmp[a5]
c6 := &xcmp[a6]
for i := range ops {
op := &ops[i]
- if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] && c5[op.a5] && c6[op.a6] {
+ if c1[op.a1] && c2[op.a2] && c3[op.a3] && c4[op.a4] && c5[op.a5] && c6[op.a6] {
p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
return op
}
@@ -1116,6 +1115,12 @@ func cmp(a int, b int) bool {
return r0iszero != 0 /*TypeKind(100016)*/
}
+ case C_VSREG:
+ /* Allow any VR argument as a VSR operand. */
+ if b == C_VREG {
+ return true
+ }
+
case C_ANY:
return true
}
@@ -1594,7 +1599,6 @@ func buildop(ctxt *obj.Link) {
opset(AMTVRD, r0)
opset(AMTVSRWA, r0)
opset(AMTVSRWZ, r0)
- opset(AMTVSRDD, r0)
opset(AMTVSRWS, r0)
case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
@@ -1977,6 +1981,7 @@ func buildop(ctxt *obj.Link) {
ACMPEQB,
AECIWX,
ACLRLSLWI,
+ AMTVSRDD,
obj.ANOP,
obj.ATEXT,
obj.AUNDEF,
@@ -2075,50 +2080,32 @@ func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
}
/* XX1-form 3-register operands, 1 VSR operand */
-func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 {
- /* For the XX-form encodings, we need the VSX register number to be exactly */
- /* between 0-63, so we can properly set the rightmost bits. */
- r := d - REG_VS0
+func AOP_XX1(op uint32, r uint32, a uint32, b uint32) uint32 {
return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5
}
/* XX2-form 3-register operands, 2 VSR operands */
-func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 {
- xt := d - REG_VS0
- xb := b - REG_VS0
+func AOP_XX2(op uint32, xt uint32, a uint32, xb uint32) uint32 {
return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5
}
/* XX3-form 3 VSR operands */
-func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 {
- xt := d - REG_VS0
- xa := a - REG_VS0
- xb := b - REG_VS0
+func AOP_XX3(op uint32, xt uint32, xa uint32, xb uint32) uint32 {
return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
}
/* XX3-form 3 VSR operands + immediate */
-func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
- xt := d - REG_VS0
- xa := a - REG_VS0
- xb := b - REG_VS0
+func AOP_XX3I(op uint32, xt uint32, xa uint32, xb uint32, c uint32) uint32 {
return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
}
/* XX4-form, 4 VSR operands */
-func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
- xt := d - REG_VS0
- xa := a - REG_VS0
- xb := b - REG_VS0
- xc := c - REG_VS0
+func AOP_XX4(op uint32, xt uint32, xa uint32, xb uint32, xc uint32) uint32 {
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
}
/* DQ-form, VSR register, register + offset operands */
-func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {
- /* For the DQ-form encodings, we need the VSX register number to be exactly */
- /* between 0-63, so we can properly set the SX bit. */
- r := d - REG_VS0
+func AOP_DQ(op uint32, xt uint32, a uint32, b uint32) uint32 {
/* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
/* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
/* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
@@ -2126,7 +2113,7 @@ func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {
/* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
/* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
dq := b >> 4
- return op | (r&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (r&32)>>2
+ return op | (xt&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (xt&32)>>2
}
/* Z23-form, 3-register operands + CY field */
@@ -3586,33 +3573,8 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
/* 3-register operand order: (RB)(RA*1), XT */
o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
- case 88: /* VSX instructions, XX1-form */
- /* reg reg none OR reg reg reg */
- /* 3-register operand order: RA, RB, XT */
- /* 2-register operand order: XS, RA or RA, XT */
- xt := int32(p.To.Reg)
- xs := int32(p.From.Reg)
- /* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */
- if REG_V0 <= xt && xt <= REG_V31 {
- /* Convert V0-V31 to VS32-VS63 */
- xt = xt + 64
- o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
- } else if REG_F0 <= xt && xt <= REG_F31 {
- /* Convert F0-F31 to VS0-VS31 */
- xt = xt + 64
- o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
- } else if REG_VS0 <= xt && xt <= REG_VS63 {
- o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
- } else if REG_V0 <= xs && xs <= REG_V31 {
- /* Likewise for XS */
- xs = xs + 64
- o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
- } else if REG_F0 <= xs && xs <= REG_F31 {
- xs = xs + 64
- o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
- } else if REG_VS0 <= xs && xs <= REG_VS63 {
- o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
- }
+ case 88: /* VSX mfvsr* instructions, XX1-form XS,RA */
+ o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
case 89: /* VSX instructions, XX2-form */
/* reg none reg OR reg imm reg */
@@ -3743,6 +3705,9 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
mb := uint32(c.regoff(&p.RestArgs[0].Addr))
me := uint32(c.regoff(&p.RestArgs[1].Addr))
o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
+
+ case 104: /* VSX mtvsr* instructions, XX1-form RA,RB,XT */
+ o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
}
out[0] = o1