diff --git a/src/cmd/compile/internal/mips/ssa.go b/src/cmd/compile/internal/mips/ssa.go index 13736d12b4d087..7d8910ac94006a 100644 --- a/src/cmd/compile/internal/mips/ssa.go +++ b/src/cmd/compile/internal/mips/ssa.go @@ -168,7 +168,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpMIPSMULD, ssa.OpMIPSDIVF, ssa.OpMIPSDIVD, - ssa.OpMIPSMUL: + ssa.OpMIPSMUL, + ssa.OpMIPSROTR: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_REG p.From.Reg = v.Args[1].Reg() @@ -201,7 +202,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpMIPSSRLconst, ssa.OpMIPSSRAconst, ssa.OpMIPSSGTconst, - ssa.OpMIPSSGTUconst: + ssa.OpMIPSSGTUconst, + ssa.OpMIPSROTRconst: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_CONST p.From.Offset = v.AuxInt diff --git a/src/cmd/compile/internal/mips64/ssa.go b/src/cmd/compile/internal/mips64/ssa.go index c5a3ca305afaff..0315827388f112 100644 --- a/src/cmd/compile/internal/mips64/ssa.go +++ b/src/cmd/compile/internal/mips64/ssa.go @@ -170,7 +170,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpMIPS64MULF, ssa.OpMIPS64MULD, ssa.OpMIPS64DIVF, - ssa.OpMIPS64DIVD: + ssa.OpMIPS64DIVD, + ssa.OpMIPS64ROTR: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_REG p.From.Reg = v.Args[1].Reg() @@ -195,7 +196,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpMIPS64SRLVconst, ssa.OpMIPS64SRAVconst, ssa.OpMIPS64SGTconst, - ssa.OpMIPS64SGTUconst: + ssa.OpMIPS64SGTUconst, + ssa.OpMIPS64ROTRconst: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_CONST p.From.Offset = v.AuxInt diff --git a/src/cmd/compile/internal/ssa/gen/MIPS.rules b/src/cmd/compile/internal/ssa/gen/MIPS.rules index 6b59555cbee70b..4ef939b929ac49 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPS.rules +++ b/src/cmd/compile/internal/ssa/gen/MIPS.rules @@ -111,7 +111,8 @@ // rotates (RotateLeft8 x (MOVWconst [c])) => (Or8 (Lsh8x32 x (MOVWconst [c&7])) (Rsh8Ux32 x (MOVWconst [-c&7]))) (RotateLeft16 x (MOVWconst [c])) => (Or16 (Lsh16x32 x (MOVWconst [c&15])) (Rsh16Ux32 x (MOVWconst [-c&15]))) -(RotateLeft32 x (MOVWconst [c])) => (Or32 (Lsh32x32 x (MOVWconst [c&31])) (Rsh32Ux32 x (MOVWconst [-c&31]))) +(RotateLeft32 x (MOVWconst [c])) => (ROTRconst x [-c&31]) +(RotateLeft32 x y) => (ROTR x (NEG y)) (RotateLeft64 x (MOVWconst [c])) => (Or64 (Lsh64x32 x (MOVWconst [c&63])) (Rsh64Ux32 x (MOVWconst [-c&63]))) // unary ops diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64.rules b/src/cmd/compile/internal/ssa/gen/MIPS64.rules index bc51a0d53de798..12bc96ca8f5946 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPS64.rules +++ b/src/cmd/compile/internal/ssa/gen/MIPS64.rules @@ -111,7 +111,8 @@ // rotates (RotateLeft8 x (MOVVconst [c])) => (Or8 (Lsh8x64 x (MOVVconst [c&7])) (Rsh8Ux64 x (MOVVconst [-c&7]))) (RotateLeft16 x (MOVVconst [c])) => (Or16 (Lsh16x64 x (MOVVconst [c&15])) (Rsh16Ux64 x (MOVVconst [-c&15]))) -(RotateLeft32 x (MOVVconst [c])) => (Or32 (Lsh32x64 x (MOVVconst [c&31])) (Rsh32Ux64 x (MOVVconst [-c&31]))) +(RotateLeft32 x (MOVVconst [c])) => (ROTRconst x [int32(-c&31)]) +(RotateLeft32 x y) => (ROTR x (NEGV y)) (RotateLeft64 x (MOVVconst [c])) => (Or64 (Lsh64x64 x (MOVVconst [c&63])) (Rsh64Ux64 x (MOVVconst [-c&63]))) // unary ops diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go index 77f251c0d3f920..150b684eb901f5 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go @@ -208,6 +208,8 @@ func init() { {name: "SRLVconst", argLength: 1, reg: gp11, asm: "SRLV", aux: "Int64"}, // arg0 >> auxInt, unsigned {name: "SRAV", argLength: 2, reg: gp21, asm: "SRAV"}, // arg0 >> arg1, signed, shift amount is mod 64 {name: "SRAVconst", argLength: 1, reg: gp11, asm: "SRAV", aux: "Int64"}, // arg0 >> auxInt, signed + {name: "ROTR", argLength: 2, reg: gp21, asm: "ROTR"}, // arg0 right rotate by (arg1 mod 32) bits + {name: "ROTRconst", argLength: 1, reg: gp11, asm: "ROTR", aux: "Int32"}, // arg0 right rotate by auxInt bits // comparisons {name: "SGT", argLength: 2, reg: gp21, asm: "SGT", typ: "Bool"}, // 1 if arg0 > arg1 (signed), 0 otherwise diff --git a/src/cmd/compile/internal/ssa/gen/MIPSOps.go b/src/cmd/compile/internal/ssa/gen/MIPSOps.go index b92e8cb9f1ee64..c02aadc1342cbb 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPSOps.go +++ b/src/cmd/compile/internal/ssa/gen/MIPSOps.go @@ -192,6 +192,9 @@ func init() { {name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 32 {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, shift amount must be 0 through 31 inclusive + {name: "ROTR", argLength: 2, reg: gp21, asm: "ROTR"}, // arg0 right rotate by (arg1 mod 32) bits + {name: "ROTRconst", argLength: 1, reg: gp11, asm: "ROTR", aux: "Int32"}, // arg0 right rotate by auxInt bits + {name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"}, // comparisons diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 322e1c228322ed..c5de29fb78c541 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1654,6 +1654,8 @@ const ( OpMIPSSRLconst OpMIPSSRA OpMIPSSRAconst + OpMIPSROTR + OpMIPSROTRconst OpMIPSCLZ OpMIPSSGT OpMIPSSGTconst @@ -1765,6 +1767,8 @@ const ( OpMIPS64SRLVconst OpMIPS64SRAV OpMIPS64SRAVconst + OpMIPS64ROTR + OpMIPS64ROTRconst OpMIPS64SGT OpMIPS64SGTconst OpMIPS64SGTU @@ -22074,6 +22078,34 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "ROTR", + argLen: 2, + asm: mips.AROTR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31 + {1, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31 + }, + outputs: []outputInfo{ + {0, 335544318}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31 + }, + }, + }, + { + name: "ROTRconst", + auxType: auxInt32, + argLen: 1, + asm: mips.AROTR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31 + }, + outputs: []outputInfo{ + {0, 335544318}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31 + }, + }, + }, { name: "CLZ", argLen: 1, @@ -23566,6 +23598,34 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "ROTR", + argLen: 2, + asm: mips.AROTR, + 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 + }, + 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: "ROTRconst", + auxType: auxInt32, + argLen: 1, + asm: mips.AROTR, + 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 + }, + 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: "SGT", argLen: 2, diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS.go b/src/cmd/compile/internal/ssa/rewriteMIPS.go index fdf329cbd05f2f..b7ae266aec05f0 100644 --- a/src/cmd/compile/internal/ssa/rewriteMIPS.go +++ b/src/cmd/compile/internal/ssa/rewriteMIPS.go @@ -5510,29 +5510,30 @@ func rewriteValueMIPS_OpRotateLeft32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types - // match: (RotateLeft32 x (MOVWconst [c])) - // result: (Or32 (Lsh32x32 x (MOVWconst [c&31])) (Rsh32Ux32 x (MOVWconst [-c&31]))) + // match: (RotateLeft32 x (MOVWconst [c])) + // result: (ROTRconst x [-c&31]) for { - t := v.Type x := v_0 if v_1.Op != OpMIPSMOVWconst { break } c := auxIntToInt32(v_1.AuxInt) - v.reset(OpOr32) - v0 := b.NewValue0(v.Pos, OpLsh32x32, t) - v1 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v1.AuxInt = int32ToAuxInt(c & 31) - v0.AddArg2(x, v1) - v2 := b.NewValue0(v.Pos, OpRsh32Ux32, t) - v3 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v3.AuxInt = int32ToAuxInt(-c & 31) - v2.AddArg2(x, v3) - v.AddArg2(v0, v2) + v.reset(OpMIPSROTRconst) + v.AuxInt = int32ToAuxInt(-c & 31) + v.AddArg(x) + return true + } + // match: (RotateLeft32 x y) + // result: (ROTR x (NEG y)) + for { + x := v_0 + y := v_1 + v.reset(OpMIPSROTR) + v0 := b.NewValue0(v.Pos, OpMIPSNEG, y.Type) + v0.AddArg(y) + v.AddArg2(x, v0) return true } - return false } func rewriteValueMIPS_OpRotateLeft64(v *Value) bool { v_1 := v.Args[1] diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go index 541bdd694a7550..8ddafd4cf359fa 100644 --- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go +++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go @@ -5906,29 +5906,30 @@ func rewriteValueMIPS64_OpRotateLeft32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types - // match: (RotateLeft32 x (MOVVconst [c])) - // result: (Or32 (Lsh32x64 x (MOVVconst [c&31])) (Rsh32Ux64 x (MOVVconst [-c&31]))) + // match: (RotateLeft32 x (MOVVconst [c])) + // result: (ROTRconst x [int32(-c&31)]) for { - t := v.Type x := v_0 if v_1.Op != OpMIPS64MOVVconst { break } c := auxIntToInt64(v_1.AuxInt) - v.reset(OpOr32) - v0 := b.NewValue0(v.Pos, OpLsh32x64, t) - v1 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64) - v1.AuxInt = int64ToAuxInt(c & 31) - v0.AddArg2(x, v1) - v2 := b.NewValue0(v.Pos, OpRsh32Ux64, t) - v3 := b.NewValue0(v.Pos, OpMIPS64MOVVconst, typ.UInt64) - v3.AuxInt = int64ToAuxInt(-c & 31) - v2.AddArg2(x, v3) - v.AddArg2(v0, v2) + v.reset(OpMIPS64ROTRconst) + v.AuxInt = int32ToAuxInt(int32(-c & 31)) + v.AddArg(x) + return true + } + // match: (RotateLeft32 x y) + // result: (ROTR x (NEGV y)) + for { + x := v_0 + y := v_1 + v.reset(OpMIPS64ROTR) + v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, y.Type) + v0.AddArg(y) + v.AddArg2(x, v0) return true } - return false } func rewriteValueMIPS64_OpRotateLeft64(v *Value) bool { v_1 := v.Args[1] diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go index 00295589638c2f..ad836c64485a4f 100644 --- a/src/cmd/compile/internal/ssagen/ssa.go +++ b/src/cmd/compile/internal/ssagen/ssa.go @@ -4394,7 +4394,7 @@ func InitTables() { func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return s.newValue2(ssa.OpRotateLeft32, types.Types[types.TUINT32], args[0], args[1]) }, - sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm) + sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm, sys.MIPS, sys.MIPS64) addF("math/bits", "RotateLeft64", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return s.newValue2(ssa.OpRotateLeft64, types.Types[types.TUINT64], args[0], args[1]) diff --git a/src/cmd/internal/obj/mips/a.out.go b/src/cmd/internal/obj/mips/a.out.go index ddd048a17f4df3..57439b950ee8d6 100644 --- a/src/cmd/internal/obj/mips/a.out.go +++ b/src/cmd/internal/obj/mips/a.out.go @@ -390,6 +390,7 @@ const ( AREM AREMU ARFE + AROTR ASC ASCV ASGT diff --git a/src/cmd/internal/obj/mips/anames.go b/src/cmd/internal/obj/mips/anames.go index 2a44e4ca705196..e399827d87f4fd 100644 --- a/src/cmd/internal/obj/mips/anames.go +++ b/src/cmd/internal/obj/mips/anames.go @@ -78,6 +78,7 @@ var Anames = []string{ "REM", "REMU", "RFE", + "ROTR", "SC", "SCV", "SGT", diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go index fd29f9fa213446..4d63d68b657704 100644 --- a/src/cmd/internal/obj/mips/asm0.go +++ b/src/cmd/internal/obj/mips/asm0.go @@ -107,6 +107,11 @@ var optab = []Optab{ {ASLLV, C_REG, C_REG, C_REG, 9, 4, 0, sys.MIPS64, 0}, {ACLO, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0}, + {AROTR, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0}, + {AROTR, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0}, + {AROTR, C_SCON, C_REG, C_REG, 16, 4, 0, 0, 0}, + {AROTR, C_SCON, C_NONE, C_REG, 16, 4, 0, 0, 0}, + {AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0, 0, 0}, {AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0, 0, 0}, {ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0, 0, 0}, @@ -1079,6 +1084,7 @@ func buildop(ctxt *obj.Link) { ANEGW, ANEGV, AWORD, + AROTR, obj.ANOP, obj.ATEXT, obj.AUNDEF, @@ -1730,6 +1736,8 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { return OP(0, 4) case ASRL: return OP(0, 6) + case AROTR: + return OP(0, 6) | (1 << 6) case ASRA: return OP(0, 7) case ASLLV: @@ -1914,6 +1922,8 @@ func (c *ctxt0) opirr(a obj.As) uint32 { return OP(0, 0) case ASRL: return OP(0, 2) + case AROTR: + return OP(0, 2) | (1 << 21) case ASRA: return OP(0, 3) case AADDV: