]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize math.Float64(32)bits and math.Float64(32)frombits on mips64x
authorJunxian Zhu <zhujunxian@oss.cipunited.com>
Tue, 9 May 2023 09:40:06 +0000 (17:40 +0800)
committerM Zhuo <mzh@golangcn.org>
Wed, 24 May 2023 03:36:31 +0000 (03:36 +0000)
This CL use MFC1/MTC1 instructions to move data between GPR and FPR instead of stores and loads to move float/int values.

goos: linux
goarch: mips64le
pkg: math
                      │   oldmath    │              newmath               │
                      │    sec/op    │   sec/op     vs base               │
Acos-4                   258.2n ± 0%   258.2n ± 0%        ~ (p=0.859 n=8)
Acosh-4                  378.7n ± 0%   323.9n ± 0%  -14.47% (p=0.000 n=8)
Asin-4                   255.1n ± 2%   255.5n ± 0%   +0.16% (p=0.002 n=8)
Asinh-4                  407.1n ± 0%   348.7n ± 0%  -14.35% (p=0.000 n=8)
Atan-4                   189.5n ± 0%   189.9n ± 3%        ~ (p=0.205 n=8)
Atanh-4                  355.6n ± 0%   323.4n ± 2%   -9.03% (p=0.000 n=8)
Atan2-4                  284.1n ± 7%   280.1n ± 4%        ~ (p=0.313 n=8)
Cbrt-4                   314.3n ± 0%   236.4n ± 0%  -24.79% (p=0.000 n=8)
Ceil-4                   144.3n ± 3%   139.6n ± 0%        ~ (p=0.069 n=8)
Compare-4               21.100n ± 0%   7.035n ± 0%  -66.66% (p=0.000 n=8)
Compare32-4             20.100n ± 0%   6.030n ± 0%  -70.00% (p=0.000 n=8)
Copysign-4              34.970n ± 0%   6.221n ± 0%  -82.21% (p=0.000 n=8)
Cos-4                    183.4n ± 3%   184.1n ± 5%        ~ (p=0.159 n=8)
Cosh-4                   487.9n ± 2%   419.6n ± 0%  -14.00% (p=0.000 n=8)
Erf-4                    160.6n ± 0%   157.9n ± 0%   -1.68% (p=0.009 n=8)
Erfc-4                   183.7n ± 4%   169.8n ± 0%   -7.54% (p=0.000 n=8)
Erfinv-4                 191.5n ± 4%   183.6n ± 0%   -4.13% (p=0.023 n=8)
Erfcinv-4                192.0n ± 7%   184.3n ± 0%        ~ (p=0.425 n=8)
Exp-4                    398.2n ± 0%   340.1n ± 4%  -14.58% (p=0.000 n=8)
ExpGo-4                  383.3n ± 0%   327.3n ± 0%  -14.62% (p=0.000 n=8)
Expm1-4                  248.7n ± 5%   216.0n ± 0%  -13.11% (p=0.000 n=8)
Exp2-4                   372.8n ± 0%   316.9n ± 3%  -14.98% (p=0.000 n=8)
Exp2Go-4                 374.1n ± 0%   320.5n ± 0%  -14.33% (p=0.000 n=8)
Abs-4                    3.013n ± 0%   3.016n ± 0%   +0.10% (p=0.020 n=8)
Dim-4                    5.021n ± 0%   5.022n ± 0%        ~ (p=0.270 n=8)
Floor-4                  127.5n ± 4%   126.2n ± 3%        ~ (p=0.186 n=8)
Max-4                    72.32n ± 0%   61.33n ± 0%  -15.20% (p=0.000 n=8)
Min-4                    83.33n ± 1%   61.36n ± 0%  -26.37% (p=0.000 n=8)
Mod-4                    690.7n ± 0%   454.5n ± 0%  -34.20% (p=0.000 n=8)
Frexp-4                 116.30n ± 1%   71.80n ± 1%  -38.26% (p=0.000 n=8)
Gamma-4                  389.0n ± 0%   355.9n ± 1%   -8.48% (p=0.000 n=8)
Hypot-4                 102.40n ± 0%   83.90n ± 0%  -18.07% (p=0.000 n=8)
HypotGo-4               105.45n ± 4%   84.82n ± 2%  -19.56% (p=0.000 n=8)
Ilogb-4                  99.13n ± 4%   63.71n ± 2%  -35.73% (p=0.000 n=8)
J0-4                     859.7n ± 0%   854.8n ± 0%   -0.57% (p=0.000 n=8)
J1-4                     873.9n ± 0%   875.7n ± 0%   +0.21% (p=0.007 n=8)
Jn-4                     1.855µ ± 0%   1.867µ ± 0%   +0.65% (p=0.000 n=8)
Ldexp-4                 130.50n ± 2%   64.35n ± 0%  -50.69% (p=0.000 n=8)
Lgamma-4                 208.8n ± 0%   200.9n ± 0%   -3.78% (p=0.000 n=8)
Log-4                    294.1n ± 0%   255.2n ± 3%  -13.22% (p=0.000 n=8)
Logb-4                  105.45n ± 1%   66.81n ± 1%  -36.64% (p=0.000 n=8)
Log1p-4                  268.2n ± 0%   211.3n ± 0%  -21.21% (p=0.000 n=8)
Log10-4                  295.4n ± 0%   255.2n ± 2%  -13.59% (p=0.000 n=8)
Log2-4                   152.9n ± 1%   127.5n ± 0%  -16.61% (p=0.000 n=8)
Modf-4                  103.40n ± 0%   75.36n ± 0%  -27.12% (p=0.000 n=8)
Nextafter32-4           121.20n ± 1%   78.40n ± 0%  -35.31% (p=0.000 n=8)
Nextafter64-4           110.40n ± 1%   64.91n ± 0%  -41.20% (p=0.000 n=8)
PowInt-4                 509.8n ± 1%   369.3n ± 1%  -27.56% (p=0.000 n=8)
PowFrac-4               1189.0n ± 0%   947.8n ± 0%  -20.29% (p=0.000 n=8)
Pow10Pos-4               15.07n ± 0%   15.07n ± 0%        ~ (p=0.733 n=8)
Pow10Neg-4               20.10n ± 0%   20.10n ± 0%        ~ (p=0.576 n=8)
Round-4                  44.22n ± 0%   26.12n ± 0%  -40.92% (p=0.000 n=8)
RoundToEven-4            46.22n ± 0%   27.12n ± 0%  -41.31% (p=0.000 n=8)
Remainder-4              539.0n ± 1%   417.1n ± 1%  -22.62% (p=0.000 n=8)
Signbit-4               17.985n ± 0%   5.694n ± 0%  -68.34% (p=0.000 n=8)
Sin-4                    185.7n ± 5%   172.9n ± 0%   -6.89% (p=0.001 n=8)
Sincos-4                 176.6n ± 0%   200.9n ± 0%  +13.76% (p=0.000 n=8)
Sinh-4                   495.8n ± 0%   435.9n ± 0%  -12.09% (p=0.000 n=8)
SqrtIndirect-4           5.022n ± 0%   5.024n ± 0%        ~ (p=0.083 n=8)
SqrtLatency-4            8.038n ± 0%   8.044n ± 0%        ~ (p=0.524 n=8)
SqrtIndirectLatency-4    8.035n ± 0%   8.039n ± 0%   +0.06% (p=0.017 n=8)
SqrtGoLatency-4          340.1n ± 0%   278.3n ± 0%  -18.19% (p=0.000 n=8)
SqrtPrime-4              5.381µ ± 0%   5.386µ ± 0%        ~ (p=0.662 n=8)
Tan-4                    198.6n ± 1%   183.1n ± 0%   -7.85% (p=0.000 n=8)
Tanh-4                   491.3n ± 1%   440.8n ± 1%  -10.29% (p=0.000 n=8)
Trunc-4                  121.7n ± 0%   121.7n ± 0%        ~ (p=0.769 n=8)
Y0-4                     855.1n ± 0%   859.8n ± 0%   +0.54% (p=0.007 n=8)
Y1-4                     862.3n ± 0%   865.1n ± 0%   +0.32% (p=0.007 n=8)
Yn-4                     1.830µ ± 0%   1.837µ ± 0%   +0.36% (p=0.011 n=8)
Float64bits-4           13.060n ± 0%   3.016n ± 0%  -76.91% (p=0.000 n=8)
Float64frombits-4       13.060n ± 0%   3.018n ± 0%  -76.90% (p=0.000 n=8)
Float32bits-4           13.060n ± 0%   3.016n ± 0%  -76.91% (p=0.000 n=8)
Float32frombits-4       13.070n ± 0%   3.013n ± 0%  -76.94% (p=0.000 n=8)
FMA-4                    446.0n ± 0%   413.1n ± 1%   -7.38% (p=0.000 n=8)
geomean                  143.4n        108.3n       -24.49%

Change-Id: I2067f7a5ae1126ada7ab3fb2083710e8212535e9
Reviewed-on: https://go-review.googlesource.com/c/go/+/493815
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>

src/cmd/compile/internal/mips64/ssa.go
src/cmd/compile/internal/ssa/_gen/MIPS64.rules
src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteMIPS64.go
test/codegen/math.go

index f22ac15650656f779835506c8c3ae149e2186b52..0c0dc6e4955c1e7d6cef033564f22267da14d6e3 100644 (file)
@@ -356,6 +356,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                ssa.OpMIPS64TRUNCDV,
                ssa.OpMIPS64MOVFD,
                ssa.OpMIPS64MOVDF,
+               ssa.OpMIPS64MOVWfpgp,
+               ssa.OpMIPS64MOVWgpfp,
+               ssa.OpMIPS64MOVVfpgp,
+               ssa.OpMIPS64MOVVgpfp,
                ssa.OpMIPS64NEGF,
                ssa.OpMIPS64NEGD,
                ssa.OpMIPS64ABSD,
index 360a5c0905e7facf4636d32c2287a86f79f4cc42..4628e2a02422edd45584cc23b9204439d4cb2c96 100644 (file)
                (MOVVstore [8] dst (MOVVload [8] src mem)
                        (MOVVstore dst (MOVVload src mem) mem)))
 
+// float <=> int register moves, with no conversion.
+// These come up when compiling math.{Float64bits, Float64frombits, Float32bits, Float32frombits}.
+(MOVVload  [off] {sym} ptr (MOVDstore [off] {sym} ptr val _)) => (MOVVfpgp val)
+(MOVDload  [off] {sym} ptr (MOVVstore [off] {sym} ptr val _)) => (MOVVgpfp val)
+(MOVWUload [off] {sym} ptr (MOVFstore [off] {sym} ptr val _)) => (ZeroExt32to64 (MOVWfpgp <typ.Float32> val))
+(MOVFload  [off] {sym} ptr (MOVWstore [off] {sym} ptr val _)) => (MOVWgpfp val)
+
+// Similarly for stores, if we see a store after FPR <=> GPR move, then redirect store to use the other register set.
+(MOVVstore [off] {sym} ptr (MOVVfpgp val) mem) => (MOVDstore [off] {sym} ptr val mem)
+(MOVDstore [off] {sym} ptr (MOVVgpfp val) mem) => (MOVVstore [off] {sym} ptr val mem)
+(MOVWstore [off] {sym} ptr (MOVWfpgp val) mem) => (MOVFstore [off] {sym} ptr val mem)
+(MOVFstore [off] {sym} ptr (MOVWgpfp val) mem) => (MOVWstore [off] {sym} ptr val mem)
+
 // medium move uses a duff device
 (Move [s] {t} dst src mem)
        && s%8 == 0 && s >= 24 && s <= 8*128 && t.Alignment()%8 == 0
index a5253d8667fe8faef413cdf6cc7ed118bee8f409..08cab89d5db9110f21fce7079cc8efa893d62c73 100644 (file)
@@ -156,8 +156,8 @@ func init() {
                fp01     = regInfo{inputs: nil, outputs: []regMask{fp}}
                fp11     = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
                //fp1flags  = regInfo{inputs: []regMask{fp}}
-               //fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
-               //gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
+               fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
+               gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
                fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
                fp2flags  = regInfo{inputs: []regMask{fp, fp}}
                fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
@@ -250,6 +250,12 @@ func init() {
                {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.
 
+               // 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
+               {name: "MOVWgpfp", argLength: 1, reg: gpfp, asm: "MOVW"}, // move int32 to float32 (no conversion). MIPS64 will perform sign-extend to 64-bit by default
+               {name: "MOVVfpgp", argLength: 1, reg: fpgp, asm: "MOVV"}, // move float64 to int64 (no conversion).
+               {name: "MOVVgpfp", argLength: 1, reg: gpfp, asm: "MOVV"}, // move int64 to float64 (no conversion).
+
                // conversions
                {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
                {name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
index e429d0de53f478fc229e4c39c476f18b49bd2aea..6d8bef7ed97ec710c15918f9aa2054ff15aa7b1b 100644 (file)
@@ -2027,6 +2027,10 @@ const (
        OpMIPS64MOVHstorezero
        OpMIPS64MOVWstorezero
        OpMIPS64MOVVstorezero
+       OpMIPS64MOVWfpgp
+       OpMIPS64MOVWgpfp
+       OpMIPS64MOVVfpgp
+       OpMIPS64MOVVgpfp
        OpMIPS64MOVBreg
        OpMIPS64MOVBUreg
        OpMIPS64MOVHreg
@@ -27148,6 +27152,58 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "MOVWfpgp",
+               argLen: 1,
+               asm:    mips.AMOVW,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1152921504338411520}, // F0 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 F27 F28 F29 F30 F31
+                       },
+                       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
+                       },
+               },
+       },
+       {
+               name:   "MOVWgpfp",
+               argLen: 1,
+               asm:    mips.AMOVW,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {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
+                       },
+                       outputs: []outputInfo{
+                               {0, 1152921504338411520}, // F0 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 F27 F28 F29 F30 F31
+                       },
+               },
+       },
+       {
+               name:   "MOVVfpgp",
+               argLen: 1,
+               asm:    mips.AMOVV,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1152921504338411520}, // F0 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 F27 F28 F29 F30 F31
+                       },
+                       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
+                       },
+               },
+       },
+       {
+               name:   "MOVVgpfp",
+               argLen: 1,
+               asm:    mips.AMOVV,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {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
+                       },
+                       outputs: []outputInfo{
+                               {0, 1152921504338411520}, // F0 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 F27 F28 F29 F30 F31
+                       },
+               },
+       },
        {
                name:   "MOVBreg",
                argLen: 1,
index 89deaf746d4fdef76cf3fc4153cbd65096b43245..de316e9678e58fb1466ec3fc24442a7d15bf2c7b 100644 (file)
@@ -3167,6 +3167,23 @@ func rewriteValueMIPS64_OpMIPS64MOVDload(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MOVDload [off] {sym} ptr (MOVVstore [off] {sym} ptr val _))
+       // result: (MOVVgpfp val)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVVstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
+                       break
+               }
+               val := v_1.Args[1]
+               if ptr != v_1.Args[0] {
+                       break
+               }
+               v.reset(OpMIPS64MOVVgpfp)
+               v.AddArg(val)
+               return true
+       }
        // match: (MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVDload [off1+int32(off2)] {sym} ptr mem)
@@ -3218,6 +3235,23 @@ func rewriteValueMIPS64_OpMIPS64MOVDstore(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MOVDstore [off] {sym} ptr (MOVVgpfp val) mem)
+       // result: (MOVVstore [off] {sym} ptr val mem)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVVgpfp {
+                       break
+               }
+               val := v_1.Args[0]
+               mem := v_2
+               v.reset(OpMIPS64MOVVstore)
+               v.AuxInt = int32ToAuxInt(off)
+               v.Aux = symToAux(sym)
+               v.AddArg3(ptr, val, mem)
+               return true
+       }
        // match: (MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
@@ -3270,6 +3304,23 @@ func rewriteValueMIPS64_OpMIPS64MOVFload(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MOVFload [off] {sym} ptr (MOVWstore [off] {sym} ptr val _))
+       // result: (MOVWgpfp val)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVWstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
+                       break
+               }
+               val := v_1.Args[1]
+               if ptr != v_1.Args[0] {
+                       break
+               }
+               v.reset(OpMIPS64MOVWgpfp)
+               v.AddArg(val)
+               return true
+       }
        // match: (MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVFload [off1+int32(off2)] {sym} ptr mem)
@@ -3321,6 +3372,23 @@ func rewriteValueMIPS64_OpMIPS64MOVFstore(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MOVFstore [off] {sym} ptr (MOVWgpfp val) mem)
+       // result: (MOVWstore [off] {sym} ptr val mem)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVWgpfp {
+                       break
+               }
+               val := v_1.Args[0]
+               mem := v_2
+               v.reset(OpMIPS64MOVWstore)
+               v.AuxInt = int32ToAuxInt(off)
+               v.Aux = symToAux(sym)
+               v.AddArg3(ptr, val, mem)
+               return true
+       }
        // match: (MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVFstore [off1+int32(off2)] {sym} ptr val mem)
@@ -3813,6 +3881,23 @@ func rewriteValueMIPS64_OpMIPS64MOVVload(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MOVVload [off] {sym} ptr (MOVDstore [off] {sym} ptr val _))
+       // result: (MOVVfpgp val)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVDstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
+                       break
+               }
+               val := v_1.Args[1]
+               if ptr != v_1.Args[0] {
+                       break
+               }
+               v.reset(OpMIPS64MOVVfpgp)
+               v.AddArg(val)
+               return true
+       }
        // match: (MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVVload [off1+int32(off2)] {sym} ptr mem)
@@ -3919,6 +4004,23 @@ func rewriteValueMIPS64_OpMIPS64MOVVstore(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MOVVstore [off] {sym} ptr (MOVVfpgp val) mem)
+       // result: (MOVDstore [off] {sym} ptr val mem)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVVfpgp {
+                       break
+               }
+               val := v_1.Args[0]
+               mem := v_2
+               v.reset(OpMIPS64MOVDstore)
+               v.AuxInt = int32ToAuxInt(off)
+               v.Aux = symToAux(sym)
+               v.AddArg3(ptr, val, mem)
+               return true
+       }
        // match: (MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVVstore [off1+int32(off2)] {sym} ptr val mem)
@@ -4037,6 +4139,26 @@ func rewriteValueMIPS64_OpMIPS64MOVWUload(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       typ := &b.Func.Config.Types
+       // match: (MOVWUload [off] {sym} ptr (MOVFstore [off] {sym} ptr val _))
+       // result: (ZeroExt32to64 (MOVWfpgp <typ.Float32> val))
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVFstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
+                       break
+               }
+               val := v_1.Args[1]
+               if ptr != v_1.Args[0] {
+                       break
+               }
+               v.reset(OpZeroExt32to64)
+               v0 := b.NewValue0(v_1.Pos, OpMIPS64MOVWfpgp, typ.Float32)
+               v0.AddArg(val)
+               v.AddArg(v0)
+               return true
+       }
        // match: (MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVWUload [off1+int32(off2)] {sym} ptr mem)
@@ -4346,6 +4468,23 @@ func rewriteValueMIPS64_OpMIPS64MOVWstore(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        config := b.Func.Config
+       // match: (MOVWstore [off] {sym} ptr (MOVWfpgp val) mem)
+       // result: (MOVFstore [off] {sym} ptr val mem)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpMIPS64MOVWfpgp {
+                       break
+               }
+               val := v_1.Args[0]
+               mem := v_2
+               v.reset(OpMIPS64MOVFstore)
+               v.AuxInt = int32ToAuxInt(off)
+               v.Aux = symToAux(sym)
+               v.AddArg3(ptr, val, mem)
+               return true
+       }
        // match: (MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem)
        // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
        // result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
index 6b592754625b6afc93971edb27edcc39378a898e..e630530965e8dca18dd5cc5531db99bdc0d71d52 100644 (file)
@@ -155,12 +155,14 @@ func fromFloat64(f64 float64) uint64 {
        // amd64:"MOVQ\tX.*, [^X].*"
        // arm64:"FMOVD\tF.*, R.*"
        // ppc64x:"MFVSRD"
+       // mips64/hardfloat:"MOVV\tF.*, R.*"
        return math.Float64bits(f64+1) + 1
 }
 
 func fromFloat32(f32 float32) uint32 {
        // amd64:"MOVL\tX.*, [^X].*"
        // arm64:"FMOVS\tF.*, R.*"
+       // mips64/hardfloat:"MOVW\tF.*, R.*"
        return math.Float32bits(f32+1) + 1
 }
 
@@ -168,12 +170,14 @@ func toFloat64(u64 uint64) float64 {
        // amd64:"MOVQ\t[^X].*, X.*"
        // arm64:"FMOVD\tR.*, F.*"
        // ppc64x:"MTVSRD"
+       // mips64/hardfloat:"MOVV\tR.*, F.*"
        return math.Float64frombits(u64+1) + 1
 }
 
 func toFloat32(u32 uint32) float32 {
        // amd64:"MOVL\t[^X].*, X.*"
        // arm64:"FMOVS\tR.*, F.*"
+       // mips64/hardfloat:"MOVW\tR.*, F.*"
        return math.Float32frombits(u32+1) + 1
 }