(OffPtr [off] ptr) => (ADD (MOVDconst [off]) ptr)
(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
-(Const32F [val]) => (FMVSX (MOVDconst [int64(math.Float32bits(val))]))
-(Const64F [val]) => (FMVDX (MOVDconst [int64(math.Float64bits(val))]))
+(Const(64|32)F ...) => (FMOV(D|F)const ...)
(ConstNil) => (MOVDconst [0])
(ConstBool [val]) => (MOVDconst [int64(b2i(val))])
(F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)
// Test for -∞ (bit 0) using 64 bit classify instruction.
-(FLTD x (FMVDX (MOVDconst [int64(math.Float64bits(-math.MaxFloat64))]))) => (ANDI [1] (FCLASSD x))
-(FLED (FMVDX (MOVDconst [int64(math.Float64bits(-math.MaxFloat64))])) x) => (SNEZ (ANDI <typ.Int64> [0xff &^ 1] (FCLASSD x)))
-(FEQD x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(-1)))]))) => (ANDI [1] (FCLASSD x))
-(FNED x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(-1)))]))) => (SEQZ (ANDI <typ.Int64> [1] (FCLASSD x)))
+(FLTD x (FMOVDconst [c])) && float64ExactBits(c, -math.MaxFloat64) => (ANDI [1] (FCLASSD x))
+(FLED (FMOVDconst [c]) x) && float64ExactBits(c, -math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [0xff &^ 1] (FCLASSD x)))
+(FEQD x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(-1)) => (ANDI [1] (FCLASSD x))
+(FNED x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(-1)) => (SEQZ (ANDI <typ.Int64> [1] (FCLASSD x)))
// Test for +∞ (bit 7) using 64 bit classify instruction.
-(FLTD (FMVDX (MOVDconst [int64(math.Float64bits(math.MaxFloat64))])) x) => (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
-(FLED x (FMVDX (MOVDconst [int64(math.Float64bits(math.MaxFloat64))]))) => (SNEZ (ANDI <typ.Int64> [0xff &^ (1<<7)] (FCLASSD x)))
-(FEQD x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(1)))]))) => (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
-(FNED x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(1)))]))) => (SEQZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
+(FLTD (FMOVDconst [c]) x) && float64ExactBits(c, math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
+(FLED x (FMOVDconst [c])) && float64ExactBits(c, math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [0xff &^ (1<<7)] (FCLASSD x)))
+(FEQD x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(1)) => (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
+(FNED x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(1)) => (SEQZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
//
// Optimisations for rva22u64 and above.
gpcas = regInfo{inputs: []regMask{gpspsbgMask, gpgMask, gpgMask}, outputs: []regMask{gpMask}}
gpatomic = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}}
+ fp01 = regInfo{outputs: []regMask{fpMask}}
fp11 = regInfo{inputs: []regMask{fpMask}, outputs: []regMask{fpMask}}
fp21 = regInfo{inputs: []regMask{fpMask, fpMask}, outputs: []regMask{fpMask}}
fp31 = regInfo{inputs: []regMask{fpMask, fpMask, fpMask}, outputs: []regMask{fpMask}}
{name: "MOVaddr", argLength: 1, reg: gp11sb, asm: "MOV", aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
- {name: "MOVDconst", reg: gp01, asm: "MOV", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
+ {name: "MOVDconst", reg: gp01, asm: "MOV", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
+ {name: "FMOVDconst", reg: fp01, asm: "MOVD", typ: "Float64", aux: "Float64", rematerializeable: true}, // auxint
+ {name: "FMOVFconst", reg: fp01, asm: "MOVF", typ: "Float32", aux: "Float32", rematerializeable: true}, // auxint
// Loads: load <size> bits from arg0+auxint+aux and extend to 64 bits; arg1=mem
{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"}, // 8 bits, sign extend
case OpConst32:
return rewriteValueRISCV64_OpConst32(v)
case OpConst32F:
- return rewriteValueRISCV64_OpConst32F(v)
+ v.Op = OpRISCV64FMOVFconst
+ return true
case OpConst64:
return rewriteValueRISCV64_OpConst64(v)
case OpConst64F:
- return rewriteValueRISCV64_OpConst64F(v)
+ v.Op = OpRISCV64FMOVDconst
+ return true
case OpConst8:
return rewriteValueRISCV64_OpConst8(v)
case OpConstBool:
return true
}
}
-func rewriteValueRISCV64_OpConst32F(v *Value) bool {
- b := v.Block
- typ := &b.Func.Config.Types
- // match: (Const32F [val])
- // result: (FMVSX (MOVDconst [int64(math.Float32bits(val))]))
- for {
- val := auxIntToFloat32(v.AuxInt)
- v.reset(OpRISCV64FMVSX)
- v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
- v0.AuxInt = int64ToAuxInt(int64(math.Float32bits(val)))
- v.AddArg(v0)
- return true
- }
-}
func rewriteValueRISCV64_OpConst64(v *Value) bool {
// match: (Const64 [val])
// result: (MOVDconst [int64(val)])
return true
}
}
-func rewriteValueRISCV64_OpConst64F(v *Value) bool {
- b := v.Block
- typ := &b.Func.Config.Types
- // match: (Const64F [val])
- // result: (FMVDX (MOVDconst [int64(math.Float64bits(val))]))
- for {
- val := auxIntToFloat64(v.AuxInt)
- v.reset(OpRISCV64FMVDX)
- v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
- v0.AuxInt = int64ToAuxInt(int64(math.Float64bits(val)))
- v.AddArg(v0)
- return true
- }
-}
func rewriteValueRISCV64_OpConst8(v *Value) bool {
// match: (Const8 [val])
// result: (MOVDconst [int64(val)])
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
- // match: (FEQD x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(-1)))])))
+ // match: (FEQD x (FMOVDconst [c]))
+ // cond: float64ExactBits(c, math.Inf(-1))
// result: (ANDI [1] (FCLASSD x))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
- if v_1.Op != OpRISCV64FMVDX {
+ if v_1.Op != OpRISCV64FMOVDconst {
continue
}
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != int64(math.Float64bits(math.Inf(-1))) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(float64ExactBits(c, math.Inf(-1))) {
continue
}
v.reset(OpRISCV64ANDI)
}
break
}
- // match: (FEQD x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(1)))])))
+ // match: (FEQD x (FMOVDconst [c]))
+ // cond: float64ExactBits(c, math.Inf(1))
// result: (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
- if v_1.Op != OpRISCV64FMVDX {
+ if v_1.Op != OpRISCV64FMOVDconst {
continue
}
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != int64(math.Float64bits(math.Inf(1))) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(float64ExactBits(c, math.Inf(1))) {
continue
}
v.reset(OpRISCV64SNEZ)
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
- // match: (FLED (FMVDX (MOVDconst [int64(math.Float64bits(-math.MaxFloat64))])) x)
+ // match: (FLED (FMOVDconst [c]) x)
+ // cond: float64ExactBits(c, -math.MaxFloat64)
// result: (SNEZ (ANDI <typ.Int64> [0xff &^ 1] (FCLASSD x)))
for {
- if v_0.Op != OpRISCV64FMVDX {
+ if v_0.Op != OpRISCV64FMOVDconst {
break
}
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_0_0.AuxInt) != int64(math.Float64bits(-math.MaxFloat64)) {
+ c := auxIntToFloat64(v_0.AuxInt)
+ x := v_1
+ if !(float64ExactBits(c, -math.MaxFloat64)) {
break
}
- x := v_1
v.reset(OpRISCV64SNEZ)
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
v0.AuxInt = int64ToAuxInt(0xff &^ 1)
v.AddArg(v0)
return true
}
- // match: (FLED x (FMVDX (MOVDconst [int64(math.Float64bits(math.MaxFloat64))])))
+ // match: (FLED x (FMOVDconst [c]))
+ // cond: float64ExactBits(c, math.MaxFloat64)
// result: (SNEZ (ANDI <typ.Int64> [0xff &^ (1<<7)] (FCLASSD x)))
for {
x := v_0
- if v_1.Op != OpRISCV64FMVDX {
+ if v_1.Op != OpRISCV64FMOVDconst {
break
}
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != int64(math.Float64bits(math.MaxFloat64)) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(float64ExactBits(c, math.MaxFloat64)) {
break
}
v.reset(OpRISCV64SNEZ)
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
- // match: (FLTD x (FMVDX (MOVDconst [int64(math.Float64bits(-math.MaxFloat64))])))
+ // match: (FLTD x (FMOVDconst [c]))
+ // cond: float64ExactBits(c, -math.MaxFloat64)
// result: (ANDI [1] (FCLASSD x))
for {
x := v_0
- if v_1.Op != OpRISCV64FMVDX {
+ if v_1.Op != OpRISCV64FMOVDconst {
break
}
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != int64(math.Float64bits(-math.MaxFloat64)) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(float64ExactBits(c, -math.MaxFloat64)) {
break
}
v.reset(OpRISCV64ANDI)
v.AddArg(v0)
return true
}
- // match: (FLTD (FMVDX (MOVDconst [int64(math.Float64bits(math.MaxFloat64))])) x)
+ // match: (FLTD (FMOVDconst [c]) x)
+ // cond: float64ExactBits(c, math.MaxFloat64)
// result: (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
for {
- if v_0.Op != OpRISCV64FMVDX {
+ if v_0.Op != OpRISCV64FMOVDconst {
break
}
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_0_0.AuxInt) != int64(math.Float64bits(math.MaxFloat64)) {
+ c := auxIntToFloat64(v_0.AuxInt)
+ x := v_1
+ if !(float64ExactBits(c, math.MaxFloat64)) {
break
}
- x := v_1
v.reset(OpRISCV64SNEZ)
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
v0.AuxInt = int64ToAuxInt(1 << 7)
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
- // match: (FNED x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(-1)))])))
+ // match: (FNED x (FMOVDconst [c]))
+ // cond: float64ExactBits(c, math.Inf(-1))
// result: (SEQZ (ANDI <typ.Int64> [1] (FCLASSD x)))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
- if v_1.Op != OpRISCV64FMVDX {
+ if v_1.Op != OpRISCV64FMOVDconst {
continue
}
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != int64(math.Float64bits(math.Inf(-1))) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(float64ExactBits(c, math.Inf(-1))) {
continue
}
v.reset(OpRISCV64SEQZ)
}
break
}
- // match: (FNED x (FMVDX (MOVDconst [int64(math.Float64bits(math.Inf(1)))])))
+ // match: (FNED x (FMOVDconst [c]))
+ // cond: float64ExactBits(c, math.Inf(1))
// result: (SEQZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
- if v_1.Op != OpRISCV64FMVDX {
+ if v_1.Op != OpRISCV64FMOVDconst {
continue
}
- v_1_0 := v_1.Args[0]
- if v_1_0.Op != OpRISCV64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != int64(math.Float64bits(math.Inf(1))) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(float64ExactBits(c, math.Inf(1))) {
continue
}
v.reset(OpRISCV64SEQZ)