Commit 7bca2c59 authored by David Chase's avatar David Chase

[dev.ssa] cmd/compile: some improvements to PPC codegen

Runs fibonacci for all integer types.
Fold addressing arithmetic into stores.

Updates #16010.

Change-Id: I257982c82c00c80b00679757c3da345045968022
Reviewed-on: https://go-review.googlesource.com/25103Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
Run-TryBot: David Chase <drchase@google.com>
parent df2f813b
...@@ -162,6 +162,39 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -162,6 +162,39 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
} }
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v) p.To.Reg = gc.SSARegNum(v)
case ssa.OpPPC64MOVDaddr:
p := gc.Prog(ppc64.AMOVD)
p.From.Type = obj.TYPE_ADDR
p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v)
var wantreg string
// Suspect comment, copied from ARM code
// MOVD $sym+off(base), R
// the assembler expands it as the following:
// - base is SP: add constant offset to SP
// when constant is large, tmp register (R11) may be used
// - base is SB: load external address from constant pool (use relocation)
switch v.Aux.(type) {
default:
v.Fatalf("aux is of unknown type %T", v.Aux)
case *ssa.ExternSymbol:
wantreg = "SB"
gc.AddAux(&p.From, v)
case *ssa.ArgSymbol, *ssa.AutoSymbol:
wantreg = "SP"
gc.AddAux(&p.From, v)
case nil:
// No sym, just MOVD $off(SP), R
wantreg = "SP"
p.From.Reg = ppc64.REGSP
p.From.Offset = v.AuxInt
}
if reg := gc.SSAReg(v.Args[0]); reg.Name() != wantreg {
v.Fatalf("bad reg %s for symbol type %T, want %s", reg.Name(), v.Aux, wantreg)
}
case ssa.OpPPC64MOVDconst, ssa.OpPPC64MOVWconst, ssa.OpPPC64MOVHconst, ssa.OpPPC64MOVBconst, ssa.OpPPC64FMOVDconst, ssa.OpPPC64FMOVSconst: case ssa.OpPPC64MOVDconst, ssa.OpPPC64MOVWconst, ssa.OpPPC64MOVHconst, ssa.OpPPC64MOVBconst, ssa.OpPPC64FMOVDconst, ssa.OpPPC64FMOVSconst:
p := gc.Prog(v.Op.Asm()) p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
...@@ -169,32 +202,26 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -169,32 +202,26 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v) p.To.Reg = gc.SSARegNum(v)
case ssa.OpPPC64FCMPU: case ssa.OpPPC64FCMPU, ssa.OpPPC64CMP, ssa.OpPPC64CMPW, ssa.OpPPC64CMPU, ssa.OpPPC64CMPWU:
p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG
p.From.Reg = gc.SSARegNum(v.Args[1])
p.Reg = gc.SSARegNum(v.Args[0])
case ssa.OpPPC64CMP, ssa.OpPPC64CMPW, ssa.OpPPC64CMPU, ssa.OpPPC64CMPWU:
p := gc.Prog(v.Op.Asm()) p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = gc.SSARegNum(v.Args[1]) p.From.Reg = gc.SSARegNum(v.Args[0])
p.Reg = gc.SSARegNum(v.Args[0])
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v.Args[0]) p.To.Reg = gc.SSARegNum(v.Args[1])
case ssa.OpPPC64CMPconst: case ssa.OpPPC64CMPconst:
p := gc.Prog(v.Op.Asm()) p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_REG
p.From.Offset = v.AuxInt p.From.Reg = gc.SSARegNum(v.Args[0])
p.Reg = gc.SSARegNum(v.Args[0]) p.To.Type = obj.TYPE_CONST
p.To.Offset = v.AuxInt
case ssa.OpPPC64MOVBreg, ssa.OpPPC64MOVBZreg, ssa.OpPPC64MOVHreg, ssa.OpPPC64MOVHZreg, ssa.OpPPC64MOVWreg, ssa.OpPPC64MOVWZreg: case ssa.OpPPC64MOVBreg, ssa.OpPPC64MOVBZreg, ssa.OpPPC64MOVHreg, ssa.OpPPC64MOVHZreg, ssa.OpPPC64MOVWreg, ssa.OpPPC64MOVWZreg:
// Shift in register to required size // Shift in register to required size
p := gc.Prog(v.Op.Asm()) p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = gc.SSARegNum(v.Args[0]) p.From.Reg = gc.SSARegNum(v.Args[0])
p.To.Reg = gc.SSARegNum(v.Args[0]) p.To.Reg = gc.SSARegNum(v)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
case ssa.OpPPC64MOVDload, ssa.OpPPC64MOVWload, ssa.OpPPC64MOVBload, ssa.OpPPC64MOVHload, ssa.OpPPC64MOVWZload, ssa.OpPPC64MOVBZload, ssa.OpPPC64MOVHZload: case ssa.OpPPC64MOVDload, ssa.OpPPC64MOVWload, ssa.OpPPC64MOVBload, ssa.OpPPC64MOVHload, ssa.OpPPC64MOVWZload, ssa.OpPPC64MOVBZload, ssa.OpPPC64MOVHZload:
...@@ -212,6 +239,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -212,6 +239,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v) p.To.Reg = gc.SSARegNum(v)
case ssa.OpPPC64MOVDstoreconst, ssa.OpPPC64MOVWstoreconst, ssa.OpPPC64MOVHstoreconst, ssa.OpPPC64MOVBstoreconst: case ssa.OpPPC64MOVDstoreconst, ssa.OpPPC64MOVWstoreconst, ssa.OpPPC64MOVHstoreconst, ssa.OpPPC64MOVBstoreconst:
// TODO: pretty sure this is bogus, PPC has no such instruction unless constant is zero.
p := gc.Prog(v.Op.Asm()) p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
sc := v.AuxValAndOff() sc := v.AuxValAndOff()
...@@ -219,6 +247,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -219,6 +247,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM p.To.Type = obj.TYPE_MEM
p.To.Reg = gc.SSARegNum(v.Args[0]) p.To.Reg = gc.SSARegNum(v.Args[0])
gc.AddAux2(&p.To, v, sc.Off()) gc.AddAux2(&p.To, v, sc.Off())
case ssa.OpPPC64MOVDstore, ssa.OpPPC64MOVWstore, ssa.OpPPC64MOVHstore, ssa.OpPPC64MOVBstore: case ssa.OpPPC64MOVDstore, ssa.OpPPC64MOVWstore, ssa.OpPPC64MOVHstore, ssa.OpPPC64MOVBstore:
p := gc.Prog(v.Op.Asm()) p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -272,17 +301,79 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -272,17 +301,79 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
} }
} }
var blockJump = [...]struct {
asm, invasm obj.As
}{
ssa.BlockPPC64EQ: {ppc64.ABEQ, ppc64.ABNE},
ssa.BlockPPC64NE: {ppc64.ABNE, ppc64.ABEQ},
ssa.BlockPPC64LT: {ppc64.ABLT, ppc64.ABGE},
ssa.BlockPPC64GE: {ppc64.ABGE, ppc64.ABLT},
ssa.BlockPPC64LE: {ppc64.ABLE, ppc64.ABGT},
ssa.BlockPPC64GT: {ppc64.ABGT, ppc64.ABLE},
ssa.BlockPPC64ULT: {ppc64.ABLT, ppc64.ABGE},
ssa.BlockPPC64UGE: {ppc64.ABGE, ppc64.ABLT},
ssa.BlockPPC64ULE: {ppc64.ABLE, ppc64.ABGT},
ssa.BlockPPC64UGT: {ppc64.ABGT, ppc64.ABLE},
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) { func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
s.SetLineno(b.Line) s.SetLineno(b.Line)
switch b.Kind { switch b.Kind {
case ssa.BlockCall: case ssa.BlockPlain, ssa.BlockCall, ssa.BlockCheck:
if b.Succs[0].Block() != next { if b.Succs[0].Block() != next {
p := gc.Prog(obj.AJMP) p := gc.Prog(obj.AJMP)
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()}) s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
} }
case ssa.BlockExit:
gc.Prog(obj.AUNDEF) // tell plive.go that we never reach here
case ssa.BlockRet: case ssa.BlockRet:
gc.Prog(obj.ARET) gc.Prog(obj.ARET)
case ssa.BlockPPC64EQ, ssa.BlockPPC64NE,
ssa.BlockPPC64LT, ssa.BlockPPC64GE,
ssa.BlockPPC64LE, ssa.BlockPPC64GT,
ssa.BlockPPC64ULT, ssa.BlockPPC64UGT,
ssa.BlockPPC64ULE, ssa.BlockPPC64UGE:
jmp := blockJump[b.Kind]
likely := b.Likely
var p *obj.Prog
switch next {
case b.Succs[0].Block():
p = gc.Prog(jmp.invasm)
likely *= -1
p.To.Type = obj.TYPE_BRANCH
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
case b.Succs[1].Block():
p = gc.Prog(jmp.asm)
p.To.Type = obj.TYPE_BRANCH
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
default:
p = gc.Prog(jmp.asm)
p.To.Type = obj.TYPE_BRANCH
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
q := gc.Prog(obj.AJMP)
q.To.Type = obj.TYPE_BRANCH
s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
}
// liblink reorders the instruction stream as it sees fit.
// Pass along what we know so liblink can make use of it.
// TODO: Once we've fully switched to SSA,
// make liblink leave our output alone.
//switch likely {
//case ssa.BranchUnlikely:
// p.From.Type = obj.TYPE_CONST
// p.From.Offset = 0
//case ssa.BranchLikely:
// p.From.Type = obj.TYPE_CONST
// p.From.Offset = 1
//}
default:
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
} }
} }
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
(ConstNil) -> (MOVDconst [0]) (ConstNil) -> (MOVDconst [0])
(ConstBool [b]) -> (MOVBconst [b]) (ConstBool [b]) -> (MOVBconst [b])
(Addr {sym} base) -> (ADDconst {sym} base) (Addr {sym} base) -> (MOVDaddr {sym} base)
// (Addr {sym} base) -> (ADDconst {sym} base)
(OffPtr [off] ptr) -> (ADD (MOVDconst <config.Frontend().TypeInt64()> [off]) ptr) (OffPtr [off] ptr) -> (ADD (MOVDconst <config.Frontend().TypeInt64()> [off]) ptr)
(StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem) (StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem)
...@@ -148,7 +149,7 @@ ...@@ -148,7 +149,7 @@
(Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) -> (MOVWZload ptr mem) (Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) -> (MOVWZload ptr mem)
(Load <t> ptr mem) && is16BitInt(t) && isSigned(t) -> (MOVHload ptr mem) (Load <t> ptr mem) && is16BitInt(t) && isSigned(t) -> (MOVHload ptr mem)
(Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) -> (MOVHZload ptr mem) (Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) -> (MOVHZload ptr mem)
(Load <t> ptr mem) && (t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) -> (MOVBload ptr mem) (Load <t> ptr mem) && (t.IsBoolean() || (is8BitInt(t) && isSigned(t))) -> (MOVBload ptr mem)
(Load <t> ptr mem) && is8BitInt(t) && !isSigned(t) -> (MOVBZload ptr mem) (Load <t> ptr mem) && is8BitInt(t) && !isSigned(t) -> (MOVBZload ptr mem)
(Load <t> ptr mem) && is32BitFloat(t) -> (FMOVSload ptr mem) (Load <t> ptr mem) && is32BitFloat(t) -> (FMOVSload ptr mem)
(Load <t> ptr mem) && is64BitFloat(t) -> (FMOVDload ptr mem) (Load <t> ptr mem) && is64BitFloat(t) -> (FMOVDload ptr mem)
...@@ -210,6 +211,14 @@ ...@@ -210,6 +211,14 @@
(ADD (MOVDconst [c]) x) -> (ADDconst [c] x) (ADD (MOVDconst [c]) x) -> (ADDconst [c] x)
(ADD x (MOVDconst [c])) -> (ADDconst [c] x) (ADD x (MOVDconst [c])) -> (ADDconst [c] x)
(MOVDstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVDstore [off1+off2] {sym} x val mem)
(MOVWstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVWstore [off1+off2] {sym} x val mem)
(MOVHstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVHstore [off1+off2] {sym} x val mem)
(MOVBstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVBstore [off1+off2] {sym} x val mem)
// TODO MOV*storeconst is wrong for PPC
// (MOVDstore ptr (MOVDconst [c]) mem) && c == 0 -> (MOVDstoreconst [c] ptr mem)
// Lowering extension // Lowering extension
// Note: we always extend to 64 bits even though some ops don't need that many result bits. // Note: we always extend to 64 bits even though some ops don't need that many result bits.
(SignExt8to16 x) -> (MOVBreg x) (SignExt8to16 x) -> (MOVBreg x)
......
...@@ -96,27 +96,27 @@ func init() { ...@@ -96,27 +96,27 @@ func init() {
gp = buildReg("R3 R4 R5 R6 R7 R8 R9 R10 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29") gp = buildReg("R3 R4 R5 R6 R7 R8 R9 R10 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29")
fp = buildReg("F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26") fp = buildReg("F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26")
sp = buildReg("SP") sp = buildReg("SP")
// sb = buildReg("SB") sb = buildReg("SB")
// gg = buildReg("R30") // gg = buildReg("R30")
cr = buildReg("CR") cr = buildReg("CR")
// tmp = buildReg("R31") // tmp = buildReg("R31")
// ctxt = buildReg("R11") // ctxt = buildReg("R11")
// tls = buildReg("R13") // tls = buildReg("R13")
gp01 = regInfo{inputs: []regMask{}, outputs: []regMask{gp}} gp01 = regInfo{inputs: []regMask{}, outputs: []regMask{gp}}
gp11 = regInfo{inputs: []regMask{gp | sp}, outputs: []regMask{gp}} gp11 = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
gp21 = regInfo{inputs: []regMask{gp | sp, gp | sp}, outputs: []regMask{gp}} gp21 = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}}
gp1cr = regInfo{inputs: []regMask{gp | sp}, outputs: []regMask{cr}} gp1cr = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{cr}}
gp2cr = regInfo{inputs: []regMask{gp | sp, gp | sp}, outputs: []regMask{cr}} gp2cr = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{cr}}
crgp = regInfo{inputs: []regMask{cr}, outputs: []regMask{gp}} crgp = regInfo{inputs: []regMask{cr}, outputs: []regMask{gp}}
gpload = regInfo{inputs: []regMask{gp | sp}, outputs: []regMask{gp}} gpload = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
gpstore = regInfo{inputs: []regMask{gp | sp, gp | sp}, outputs: []regMask{}} gpstore = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{}}
gpstoreconst = regInfo{inputs: []regMask{gp | sp, 0}, outputs: []regMask{}} gpstoreconst = regInfo{inputs: []regMask{gp | sp | sb, 0}, outputs: []regMask{}}
fp01 = regInfo{inputs: []regMask{}, outputs: []regMask{fp}} fp01 = regInfo{inputs: []regMask{}, outputs: []regMask{fp}}
// fp11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}} // fp11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}} fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
fp2cr = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{cr}} fp2cr = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{cr}}
fpload = regInfo{inputs: []regMask{gp | sp}, outputs: []regMask{fp}} fpload = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{fp}}
fpstore = regInfo{inputs: []regMask{fp, gp | sp}, outputs: []regMask{}} fpstore = regInfo{inputs: []regMask{gp | sp | sb, fp}, outputs: []regMask{}}
callerSave = regMask(gp | fp) callerSave = regMask(gp | fp)
) )
ops := []opData{ ops := []opData{
...@@ -167,6 +167,8 @@ func init() { ...@@ -167,6 +167,8 @@ func init() {
{name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem"}, // store low 4 bytes of ... {name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem"}, // store low 4 bytes of ...
{name: "MOVDstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVD", aux: "SymValAndOff", typ: "Mem"}, // store 8 bytes of ... {name: "MOVDstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVD", aux: "SymValAndOff", typ: "Mem"}, // store 8 bytes of ...
{name: "MOVDaddr", argLength: 1, reg: regInfo{inputs: []regMask{sp | sb}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVD", rematerializeable: true}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
{name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", rematerializeable: true}, // {name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", rematerializeable: true}, //
{name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", rematerializeable: true}, // 32 low bits of auxint {name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", rematerializeable: true}, // 32 low bits of auxint
{name: "MOVHconst", argLength: 0, reg: gp01, aux: "Int16", asm: "MOVH", rematerializeable: true}, // 16 low bits of auxint {name: "MOVHconst", argLength: 0, reg: gp01, aux: "Int16", asm: "MOVH", rematerializeable: true}, // 16 low bits of auxint
......
This diff is collapsed.
...@@ -205,6 +205,11 @@ func is32Bit(n int64) bool { ...@@ -205,6 +205,11 @@ func is32Bit(n int64) bool {
return n == int64(int32(n)) return n == int64(int32(n))
} }
// is16Bit reports whether n can be represented as a signed 16 bit integer.
func is16Bit(n int64) bool {
return n == int64(int16(n))
}
// b2i translates a boolean value to 0 or 1 for assigning to auxInt. // b2i translates a boolean value to 0 or 1 for assigning to auxInt.
func b2i(b bool) int64 { func b2i(b bool) int64 {
if b { if b {
......
...@@ -136,6 +136,14 @@ func rewriteValuePPC64(v *Value, config *Config) bool { ...@@ -136,6 +136,14 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
return rewriteValuePPC64_OpLess8U(v, config) return rewriteValuePPC64_OpLess8U(v, config)
case OpLoad: case OpLoad:
return rewriteValuePPC64_OpLoad(v, config) return rewriteValuePPC64_OpLoad(v, config)
case OpPPC64MOVBstore:
return rewriteValuePPC64_OpPPC64MOVBstore(v, config)
case OpPPC64MOVDstore:
return rewriteValuePPC64_OpPPC64MOVDstore(v, config)
case OpPPC64MOVHstore:
return rewriteValuePPC64_OpPPC64MOVHstore(v, config)
case OpPPC64MOVWstore:
return rewriteValuePPC64_OpPPC64MOVWstore(v, config)
case OpMul16: case OpMul16:
return rewriteValuePPC64_OpMul16(v, config) return rewriteValuePPC64_OpMul16(v, config)
case OpMul32: case OpMul32:
...@@ -402,11 +410,11 @@ func rewriteValuePPC64_OpAddr(v *Value, config *Config) bool { ...@@ -402,11 +410,11 @@ func rewriteValuePPC64_OpAddr(v *Value, config *Config) bool {
_ = b _ = b
// match: (Addr {sym} base) // match: (Addr {sym} base)
// cond: // cond:
// result: (ADDconst {sym} base) // result: (MOVDaddr {sym} base)
for { for {
sym := v.Aux sym := v.Aux
base := v.Args[0] base := v.Args[0]
v.reset(OpPPC64ADDconst) v.reset(OpPPC64MOVDaddr)
v.Aux = sym v.Aux = sym
v.AddArg(base) v.AddArg(base)
return true return true
...@@ -1448,13 +1456,13 @@ func rewriteValuePPC64_OpLoad(v *Value, config *Config) bool { ...@@ -1448,13 +1456,13 @@ func rewriteValuePPC64_OpLoad(v *Value, config *Config) bool {
return true return true
} }
// match: (Load <t> ptr mem) // match: (Load <t> ptr mem)
// cond: (t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) // cond: (t.IsBoolean() || (is8BitInt(t) && isSigned(t)))
// result: (MOVBload ptr mem) // result: (MOVBload ptr mem)
for { for {
t := v.Type t := v.Type
ptr := v.Args[0] ptr := v.Args[0]
mem := v.Args[1] mem := v.Args[1]
if !(t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) { if !(t.IsBoolean() || (is8BitInt(t) && isSigned(t))) {
break break
} }
v.reset(OpPPC64MOVBload) v.reset(OpPPC64MOVBload)
...@@ -1509,6 +1517,126 @@ func rewriteValuePPC64_OpLoad(v *Value, config *Config) bool { ...@@ -1509,6 +1517,126 @@ func rewriteValuePPC64_OpLoad(v *Value, config *Config) bool {
} }
return false return false
} }
func rewriteValuePPC64_OpPPC64MOVBstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVBstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(off1+off2)
// result: (MOVBstore [off1+off2] {sym} x val mem)
for {
off1 := v.AuxInt
sym := v.Aux
v_0 := v.Args[0]
if v_0.Op != OpPPC64ADDconst {
break
}
off2 := v_0.AuxInt
x := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
if !(is16Bit(off1 + off2)) {
break
}
v.reset(OpPPC64MOVBstore)
v.AuxInt = off1 + off2
v.Aux = sym
v.AddArg(x)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false
}
func rewriteValuePPC64_OpPPC64MOVDstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(off1+off2)
// result: (MOVDstore [off1+off2] {sym} x val mem)
for {
off1 := v.AuxInt
sym := v.Aux
v_0 := v.Args[0]
if v_0.Op != OpPPC64ADDconst {
break
}
off2 := v_0.AuxInt
x := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
if !(is16Bit(off1 + off2)) {
break
}
v.reset(OpPPC64MOVDstore)
v.AuxInt = off1 + off2
v.Aux = sym
v.AddArg(x)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false
}
func rewriteValuePPC64_OpPPC64MOVHstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVHstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(off1+off2)
// result: (MOVHstore [off1+off2] {sym} x val mem)
for {
off1 := v.AuxInt
sym := v.Aux
v_0 := v.Args[0]
if v_0.Op != OpPPC64ADDconst {
break
}
off2 := v_0.AuxInt
x := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
if !(is16Bit(off1 + off2)) {
break
}
v.reset(OpPPC64MOVHstore)
v.AuxInt = off1 + off2
v.Aux = sym
v.AddArg(x)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false
}
func rewriteValuePPC64_OpPPC64MOVWstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVWstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(off1+off2)
// result: (MOVWstore [off1+off2] {sym} x val mem)
for {
off1 := v.AuxInt
sym := v.Aux
v_0 := v.Args[0]
if v_0.Op != OpPPC64ADDconst {
break
}
off2 := v_0.AuxInt
x := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
if !(is16Bit(off1 + off2)) {
break
}
v.reset(OpPPC64MOVWstore)
v.AuxInt = off1 + off2
v.Aux = sym
v.AddArg(x)
v.AddArg(val)
v.AddArg(mem)
return true
}
return false
}
func rewriteValuePPC64_OpMul16(v *Value, config *Config) bool { func rewriteValuePPC64_OpMul16(v *Value, config *Config) bool {
b := v.Block b := v.Block
_ = b _ = b
......
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