Commit b6946fb1 authored by Lynn Boger's avatar Lynn Boger Committed by David Chase

cmd/asm: ppc64le support for ISEL for use by SSA

This adds the support for the ppc64le isel instruction so
it can be used by SSA.

Fixed #16771

Change-Id: Ia2517f0834ff5e7ad927e218b84493e0106ab4a7
Reviewed-on: https://go-review.googlesource.com/28611Reviewed-by: default avatarDavid Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 07b80113
...@@ -39,6 +39,10 @@ func IsPPC64RLD(op obj.As) bool { ...@@ -39,6 +39,10 @@ func IsPPC64RLD(op obj.As) bool {
return false return false
} }
func IsPPC64ISEL(op obj.As) bool {
return op == ppc64.AISEL
}
// IsPPC64CMP reports whether the op (as defined by an ppc64.A* constant) is // IsPPC64CMP reports whether the op (as defined by an ppc64.A* constant) is
// one of the CMP instructions that require special handling. // one of the CMP instructions that require special handling.
func IsPPC64CMP(op obj.As) bool { func IsPPC64CMP(op obj.As) bool {
......
...@@ -673,7 +673,8 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { ...@@ -673,7 +673,8 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.To = a[3] prog.To = a[3]
break break
} }
if p.arch.Family == sys.PPC64 && arch.IsPPC64RLD(op) { if p.arch.Family == sys.PPC64 {
if arch.IsPPC64RLD(op) {
// 2nd operand must always be a register. // 2nd operand must always be a register.
// TODO: Do we need to guard this with the instruction type? // TODO: Do we need to guard this with the instruction type?
// That is, are there 4-operand instructions without this property? // That is, are there 4-operand instructions without this property?
...@@ -682,6 +683,14 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { ...@@ -682,6 +683,14 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.From3 = newAddr(a[2]) prog.From3 = newAddr(a[2])
prog.To = a[3] prog.To = a[3]
break break
} else if arch.IsPPC64ISEL(op) {
// ISEL BC,RB,RA,RT becomes isel rt,ra,rb,bc
prog.From3 = newAddr(a[2]) // ra
prog.From = a[0] // bc
prog.Reg = p.getRegister(prog, op, &a[1]) // rb
prog.To = a[3] // rt
break
}
} }
if p.arch.Family == sys.S390X { if p.arch.Family == sys.S390X {
prog.From = a[1] prog.From = a[1]
......
...@@ -347,6 +347,7 @@ const ( ...@@ -347,6 +347,7 @@ const (
AFSUBCC AFSUBCC
AFSUBS AFSUBS
AFSUBSCC AFSUBSCC
AISEL
AMOVMW AMOVMW
ALBAR ALBAR
ALSW ALSW
......
...@@ -119,6 +119,7 @@ var Anames = []string{ ...@@ -119,6 +119,7 @@ var Anames = []string{
"FSUBCC", "FSUBCC",
"FSUBS", "FSUBS",
"FSUBSCC", "FSUBSCC",
"ISEL",
"MOVMW", "MOVMW",
"LBAR", "LBAR",
"LSW", "LSW",
......
...@@ -323,6 +323,8 @@ var optab = []Optab{ ...@@ -323,6 +323,8 @@ var optab = []Optab{
{AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0}, {AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
{AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0}, {AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},
{AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0}, {AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},
{AISEL, C_LCON, C_REG, C_REG, C_REG, 84, 4, 0},
{AISEL, C_ZCON, C_REG, C_REG, C_REG, 84, 4, 0},
{ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0}, {ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
{ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0}, {ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},
{AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0}, {AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},
...@@ -1167,6 +1169,9 @@ func buildop(ctxt *obj.Link) { ...@@ -1167,6 +1169,9 @@ func buildop(ctxt *obj.Link) {
case AFCMPO: case AFCMPO:
opset(AFCMPU, r0) opset(AFCMPU, r0)
case AISEL:
opset(AISEL, r0)
case AMTFSB0: case AMTFSB0:
opset(AMTFSB0CC, r0) opset(AMTFSB0CC, r0)
opset(AMTFSB1, r0) opset(AMTFSB1, r0)
...@@ -1350,6 +1355,10 @@ func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint ...@@ -1350,6 +1355,10 @@ func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint
return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
} }
func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {
return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6
}
const ( const (
/* each rhs is OPVCC(_, _, _, _) */ /* each rhs is OPVCC(_, _, _, _) */
OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0 OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
...@@ -1359,6 +1368,7 @@ const ( ...@@ -1359,6 +1368,7 @@ const (
OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0 OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0
OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0 OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0
OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0 OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0
OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0
OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0 OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0
OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0 OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0
OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0 OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0
...@@ -2522,6 +2532,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -2522,6 +2532,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
rel.Siz = 8 rel.Siz = 8
rel.Sym = p.From.Sym rel.Sym = p.From.Sym
rel.Type = obj.R_ADDRPOWER_GOT rel.Type = obj.R_ADDRPOWER_GOT
case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
bc := vregoff(ctxt, &p.From)
// rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), uint32(bc))
} }
out[0] = o1 out[0] = o1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment