From f0d575c2662229b6e4c51f2d0483b56542ae7661 Mon Sep 17 00:00:00 2001 From: Junxian Zhu Date: Tue, 9 May 2023 17:40:06 +0800 Subject: [PATCH] cmd/compile: optimize math.Float64(32)bits and math.Float64(32)frombits on mips64x MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Keith Randall TryBot-Result: Gopher Robot Reviewed-by: Keith Randall Run-TryBot: Dmitri Shuralyov --- src/cmd/compile/internal/mips64/ssa.go | 4 + .../compile/internal/ssa/_gen/MIPS64.rules | 13 ++ .../compile/internal/ssa/_gen/MIPS64Ops.go | 10 +- src/cmd/compile/internal/ssa/opGen.go | 56 +++++++ src/cmd/compile/internal/ssa/rewriteMIPS64.go | 139 ++++++++++++++++++ test/codegen/math.go | 4 + 6 files changed, 224 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/mips64/ssa.go b/src/cmd/compile/internal/mips64/ssa.go index f22ac15650..0c0dc6e495 100644 --- a/src/cmd/compile/internal/mips64/ssa.go +++ b/src/cmd/compile/internal/mips64/ssa.go @@ -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, diff --git a/src/cmd/compile/internal/ssa/_gen/MIPS64.rules b/src/cmd/compile/internal/ssa/_gen/MIPS64.rules index 360a5c0905..4628e2a024 100644 --- a/src/cmd/compile/internal/ssa/_gen/MIPS64.rules +++ b/src/cmd/compile/internal/ssa/_gen/MIPS64.rules @@ -358,6 +358,19 @@ (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 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 diff --git a/src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go index a5253d8667..08cab89d5d 100644 --- a/src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go @@ -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 diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index e429d0de53..6d8bef7ed9 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -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, diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go index 89deaf746d..de316e9678 100644 --- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go +++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go @@ -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 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) diff --git a/test/codegen/math.go b/test/codegen/math.go index 6b59275462..e630530965 100644 --- a/test/codegen/math.go +++ b/test/codegen/math.go @@ -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 } -- 2.50.0