Refer to CL 633075, mips64x has a constant zero register that can be used to do this.
Change-Id: I7b60f9a9fe0015299f48b9219ba0eddd3c02e07a
Reviewed-on: https://go-review.googlesource.com/c/go/+/700935
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
p.To.Type = obj.TYPE_REG
p.To.Reg = y
}
- case ssa.OpMIPS64MOVVnop:
+ case ssa.OpMIPS64MOVVnop, ssa.OpMIPS64ZERO:
// nothing to do
case ssa.OpLoadReg:
if v.Type.IsFlags() {
p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg()
ssagen.AddAux(&p.To, v)
- case ssa.OpMIPS64MOVBstorezero,
- ssa.OpMIPS64MOVHstorezero,
- ssa.OpMIPS64MOVWstorezero,
- ssa.OpMIPS64MOVVstorezero:
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_REG
- p.From.Reg = mips.REGZERO
- p.To.Type = obj.TYPE_MEM
- p.To.Reg = v.Args[0].Reg()
- ssagen.AddAux(&p.To, v)
case ssa.OpMIPS64MOVBreg,
ssa.OpMIPS64MOVBUreg,
ssa.OpMIPS64MOVHreg,
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem)
(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem)
(MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
- (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
- (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
- (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
- && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
- (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-
-// store zero
-(MOVBstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
-(MOVVstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVVstorezero [off] {sym} ptr mem)
// don't extend after proper load
(MOVBreg x:(MOVBload _ _)) => (MOVVreg x)
// so that regmask stays within int64
// Be careful when hand coding regmasks.
var regNamesMIPS64 = []string{
- "R0", // constant 0
+ "ZERO", // constant 0
"R1",
"R2",
"R3",
hi = buildReg("HI")
callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
first16 = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16")
+ rz = buildReg("ZERO")
)
// Common regInfo
var (
gp01 = regInfo{inputs: nil, outputs: []regMask{gp}}
gp11 = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
gp11sp = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
- gp21 = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
+ gp21 = regInfo{inputs: []regMask{gpg, gpg | rz}, outputs: []regMask{gp}}
gp2hilo = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{hi, lo}}
gpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
- gpstore = regInfo{inputs: []regMask{gpspsbg, gpg}}
+ gpstore = regInfo{inputs: []regMask{gpspsbg, gpg | rz}}
gpstore0 = regInfo{inputs: []regMask{gpspsbg}}
gpxchg = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
gpcas = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux. arg2=mem.
{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux. arg2=mem.
- {name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux. arg1=mem.
- {name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux. arg1=mem.
- {name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux. arg1=mem.
- {name: "MOVVstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux. ar12=mem.
+ {name: "ZERO", zeroWidth: true, fixedReg: true},
// moves (no conversion)
{name: "MOVWfpgp", argLength: 1, reg: fpgp, asm: "MOVW"}, // move float32 to int32 (no conversion). MIPS64 will perform sign-extend to 64-bit by default
--- /dev/null
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// use zero register
+(MOVVconst [0]) => (ZERO)
c.RegSize = 8
c.lowerBlock = rewriteBlockMIPS64
c.lowerValue = rewriteValueMIPS64
+ c.lateLowerBlock = rewriteBlockMIPS64latelower
+ c.lateLowerValue = rewriteValueMIPS64latelower
c.registers = registersMIPS64[:]
c.gpRegMask = gpRegMaskMIPS64
c.fpRegMask = fpRegMaskMIPS64
OpMIPS64MOVVstore
OpMIPS64MOVFstore
OpMIPS64MOVDstore
- OpMIPS64MOVBstorezero
- OpMIPS64MOVHstorezero
- OpMIPS64MOVWstorezero
- OpMIPS64MOVVstorezero
+ OpMIPS64ZERO
OpMIPS64MOVWfpgp
OpMIPS64MOVWgpfp
OpMIPS64MOVVfpgp
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
reg: regInfo{
inputs: []inputInfo{
{0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
},
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
asm: mips.AMOVB,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
asm: mips.AMOVH,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
asm: mips.AMOVW,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
asm: mips.AMOVV,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
},
},
{
- name: "MOVBstorezero",
- auxType: auxSymOff,
- argLen: 2,
- faultOnNilArg0: true,
- symEffect: SymWrite,
- asm: mips.AMOVB,
- reg: regInfo{
- inputs: []inputInfo{
- {0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
- },
- },
- },
- {
- name: "MOVHstorezero",
- auxType: auxSymOff,
- argLen: 2,
- faultOnNilArg0: true,
- symEffect: SymWrite,
- asm: mips.AMOVH,
- reg: regInfo{
- inputs: []inputInfo{
- {0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
- },
- },
- },
- {
- name: "MOVWstorezero",
- auxType: auxSymOff,
- argLen: 2,
- faultOnNilArg0: true,
- symEffect: SymWrite,
- asm: mips.AMOVW,
- reg: regInfo{
- inputs: []inputInfo{
- {0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
- },
- },
- },
- {
- name: "MOVVstorezero",
- auxType: auxSymOff,
- argLen: 2,
- faultOnNilArg0: true,
- symEffect: SymWrite,
- asm: mips.AMOVV,
- reg: regInfo{
- inputs: []inputInfo{
- {0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
- },
- },
+ name: "ZERO",
+ argLen: 0,
+ zeroWidth: true,
+ fixedReg: true,
+ reg: regInfo{},
},
{
name: "MOVWfpgp",
asm: mips.AAND,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
asm: mips.AOR,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
hasSideEffects: true,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
hasSideEffects: true,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
hasSideEffects: true,
reg: regInfo{
inputs: []inputInfo{
- {1, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
+ {1, 234881023}, // ZERO R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
{0, 4611686018695823358}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 SP g R31 SB
},
},
var framepointerRegMIPS = int8(-1)
var linkRegMIPS = int8(28)
var registersMIPS64 = [...]Register{
- {0, mips.REG_R0, "R0"},
+ {0, mips.REGZERO, "ZERO"},
{1, mips.REG_R1, "R1"},
{2, mips.REG_R2, "R2"},
{3, mips.REG_R3, "R3"},
case OpSB:
s.assignReg(s.SBReg, v, v)
s.sb = v.ID
- case OpARM64ZERO, OpLOONG64ZERO:
+ case OpARM64ZERO, OpLOONG64ZERO, OpMIPS64ZERO:
s.assignReg(s.ZeroIntReg, v, v)
default:
f.Fatalf("unknown fixed-register op %s", v)
return rewriteValueMIPS64_OpMIPS64MOVBreg(v)
case OpMIPS64MOVBstore:
return rewriteValueMIPS64_OpMIPS64MOVBstore(v)
- case OpMIPS64MOVBstorezero:
- return rewriteValueMIPS64_OpMIPS64MOVBstorezero(v)
case OpMIPS64MOVDload:
return rewriteValueMIPS64_OpMIPS64MOVDload(v)
case OpMIPS64MOVDstore:
return rewriteValueMIPS64_OpMIPS64MOVHreg(v)
case OpMIPS64MOVHstore:
return rewriteValueMIPS64_OpMIPS64MOVHstore(v)
- case OpMIPS64MOVHstorezero:
- return rewriteValueMIPS64_OpMIPS64MOVHstorezero(v)
case OpMIPS64MOVVload:
return rewriteValueMIPS64_OpMIPS64MOVVload(v)
case OpMIPS64MOVVnop:
return rewriteValueMIPS64_OpMIPS64MOVVreg(v)
case OpMIPS64MOVVstore:
return rewriteValueMIPS64_OpMIPS64MOVVstore(v)
- case OpMIPS64MOVVstorezero:
- return rewriteValueMIPS64_OpMIPS64MOVVstorezero(v)
case OpMIPS64MOVWUload:
return rewriteValueMIPS64_OpMIPS64MOVWUload(v)
case OpMIPS64MOVWUreg:
return rewriteValueMIPS64_OpMIPS64MOVWreg(v)
case OpMIPS64MOVWstore:
return rewriteValueMIPS64_OpMIPS64MOVWstore(v)
- case OpMIPS64MOVWstorezero:
- return rewriteValueMIPS64_OpMIPS64MOVWstorezero(v)
case OpMIPS64NEGV:
return rewriteValueMIPS64_OpMIPS64NEGV(v)
case OpMIPS64NOR:
v.AddArg3(ptr, val, mem)
return true
}
- // match: (MOVBstore [off] {sym} ptr (MOVVconst [0]) mem)
- // result: (MOVBstorezero [off] {sym} ptr mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- ptr := v_0
- if v_1.Op != OpMIPS64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 {
- break
- }
- mem := v_2
- v.reset(OpMIPS64MOVBstorezero)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
// match: (MOVBstore [off] {sym} ptr (MOVBreg x) mem)
// result: (MOVBstore [off] {sym} ptr x mem)
for {
}
return false
}
-func rewriteValueMIPS64_OpMIPS64MOVBstorezero(v *Value) bool {
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- b := v.Block
- config := b.Func.Config
- // match: (MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem)
- // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64ADDVconst {
- break
- }
- off2 := auxIntToInt64(v_0.AuxInt)
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVBstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
- // match: (MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym1 := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64MOVVaddr {
- break
- }
- off2 := auxIntToInt32(v_0.AuxInt)
- sym2 := auxToSym(v_0.Aux)
- ptr := v_0.Args[0]
- mem := v_1
- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVBstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(mergeSym(sym1, sym2))
- v.AddArg2(ptr, mem)
- return true
- }
- return false
-}
func rewriteValueMIPS64_OpMIPS64MOVDload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
v.AddArg3(ptr, val, mem)
return true
}
- // match: (MOVHstore [off] {sym} ptr (MOVVconst [0]) mem)
- // result: (MOVHstorezero [off] {sym} ptr mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- ptr := v_0
- if v_1.Op != OpMIPS64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 {
- break
- }
- mem := v_2
- v.reset(OpMIPS64MOVHstorezero)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
// match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem)
// result: (MOVHstore [off] {sym} ptr x mem)
for {
}
return false
}
-func rewriteValueMIPS64_OpMIPS64MOVHstorezero(v *Value) bool {
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- b := v.Block
- config := b.Func.Config
- // match: (MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem)
- // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64ADDVconst {
- break
- }
- off2 := auxIntToInt64(v_0.AuxInt)
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVHstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
- // match: (MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym1 := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64MOVVaddr {
- break
- }
- off2 := auxIntToInt32(v_0.AuxInt)
- sym2 := auxToSym(v_0.Aux)
- ptr := v_0.Args[0]
- mem := v_1
- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVHstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(mergeSym(sym1, sym2))
- v.AddArg2(ptr, mem)
- return true
- }
- return false
-}
func rewriteValueMIPS64_OpMIPS64MOVVload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
v.AddArg3(ptr, val, mem)
return true
}
- // match: (MOVVstore [off] {sym} ptr (MOVVconst [0]) mem)
- // result: (MOVVstorezero [off] {sym} ptr mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- ptr := v_0
- if v_1.Op != OpMIPS64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 {
- break
- }
- mem := v_2
- v.reset(OpMIPS64MOVVstorezero)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
- return false
-}
-func rewriteValueMIPS64_OpMIPS64MOVVstorezero(v *Value) bool {
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- b := v.Block
- config := b.Func.Config
- // match: (MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem)
- // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVVstorezero [off1+int32(off2)] {sym} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64ADDVconst {
- break
- }
- off2 := auxIntToInt64(v_0.AuxInt)
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVVstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
- // match: (MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym1 := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64MOVVaddr {
- break
- }
- off2 := auxIntToInt32(v_0.AuxInt)
- sym2 := auxToSym(v_0.Aux)
- ptr := v_0.Args[0]
- mem := v_1
- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVVstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(mergeSym(sym1, sym2))
- v.AddArg2(ptr, mem)
- return true
- }
return false
}
func rewriteValueMIPS64_OpMIPS64MOVWUload(v *Value) bool {
v.AddArg3(ptr, val, mem)
return true
}
- // match: (MOVWstore [off] {sym} ptr (MOVVconst [0]) mem)
- // result: (MOVWstorezero [off] {sym} ptr mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- ptr := v_0
- if v_1.Op != OpMIPS64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 {
- break
- }
- mem := v_2
- v.reset(OpMIPS64MOVWstorezero)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
// match: (MOVWstore [off] {sym} ptr (MOVWreg x) mem)
// result: (MOVWstore [off] {sym} ptr x mem)
for {
}
return false
}
-func rewriteValueMIPS64_OpMIPS64MOVWstorezero(v *Value) bool {
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- b := v.Block
- config := b.Func.Config
- // match: (MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem)
- // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64ADDVconst {
- break
- }
- off2 := auxIntToInt64(v_0.AuxInt)
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVWstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(sym)
- v.AddArg2(ptr, mem)
- return true
- }
- // match: (MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
- // result: (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
- for {
- off1 := auxIntToInt32(v.AuxInt)
- sym1 := auxToSym(v.Aux)
- if v_0.Op != OpMIPS64MOVVaddr {
- break
- }
- off2 := auxIntToInt32(v_0.AuxInt)
- sym2 := auxToSym(v_0.Aux)
- ptr := v_0.Args[0]
- mem := v_1
- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
- break
- }
- v.reset(OpMIPS64MOVWstorezero)
- v.AuxInt = int32ToAuxInt(off1 + int32(off2))
- v.Aux = symToAux(mergeSym(sym1, sym2))
- v.AddArg2(ptr, mem)
- return true
- }
- return false
-}
func rewriteValueMIPS64_OpMIPS64NEGV(v *Value) bool {
v_0 := v.Args[0]
// match: (NEGV (SUBV x y))
--- /dev/null
+// Code generated from _gen/MIPS64latelower.rules using 'go generate'; DO NOT EDIT.
+
+package ssa
+
+func rewriteValueMIPS64latelower(v *Value) bool {
+ switch v.Op {
+ case OpMIPS64MOVVconst:
+ return rewriteValueMIPS64latelower_OpMIPS64MOVVconst(v)
+ }
+ return false
+}
+func rewriteValueMIPS64latelower_OpMIPS64MOVVconst(v *Value) bool {
+ // match: (MOVVconst [0])
+ // result: (ZERO)
+ for {
+ if auxIntToInt64(v.AuxInt) != 0 {
+ break
+ }
+ v.reset(OpMIPS64ZERO)
+ return true
+ }
+ return false
+}
+func rewriteBlockMIPS64latelower(b *Block) bool {
+ return false
+}