// ftsqrt BF, FRB
FTSQRT F2,$7
+// FCFID
+// FCFIDS
+
+ FCFID F2,F3
+ FCFIDCC F3,F3
+ FCFIDS F2,F3
+ FCFIDSCC F2,F3
+
//
// CMP
//
p.To.Reg = y
}
- case ssa.OpPPC64Xf2i64:
- {
- x := v.Args[0].Reg()
- y := v.Reg()
-
- p := s.Prog(ppc64.AMFVSRD)
- p.From.Type = obj.TYPE_REG
- p.From.Reg = x
- p.To.Type = obj.TYPE_REG
- p.To.Reg = y
- }
- case ssa.OpPPC64Xi2f64:
- {
- x := v.Args[0].Reg()
- y := v.Reg()
-
- p := s.Prog(ppc64.AMTVSRD)
- p.From.Type = obj.TYPE_REG
- p.From.Reg = x
- p.To.Type = obj.TYPE_REG
- p.To.Reg = y
- }
-
case ssa.OpPPC64LoweredAtomicAnd8,
ssa.OpPPC64LoweredAtomicOr8:
// SYNC
p.To.Type = obj.TYPE_REG
p.To.Reg = ppc64.REGTMP // Ignored; this is for the carry effect.
- case ssa.OpPPC64NEG, ssa.OpPPC64FNEG, ssa.OpPPC64FSQRT, ssa.OpPPC64FSQRTS, ssa.OpPPC64FFLOOR, ssa.OpPPC64FTRUNC, ssa.OpPPC64FCEIL, ssa.OpPPC64FCTIDZ, ssa.OpPPC64FCTIWZ, ssa.OpPPC64FCFID, ssa.OpPPC64FRSP, ssa.OpPPC64CNTLZD, ssa.OpPPC64CNTLZW, ssa.OpPPC64POPCNTD, ssa.OpPPC64POPCNTW, ssa.OpPPC64POPCNTB:
+ case ssa.OpPPC64NEG, ssa.OpPPC64FNEG, ssa.OpPPC64FSQRT, ssa.OpPPC64FSQRTS, ssa.OpPPC64FFLOOR, ssa.OpPPC64FTRUNC, ssa.OpPPC64FCEIL, ssa.OpPPC64FCTIDZ, ssa.OpPPC64FCTIWZ, ssa.OpPPC64FCFID, ssa.OpPPC64FCFIDS, ssa.OpPPC64FRSP, ssa.OpPPC64CNTLZD, ssa.OpPPC64CNTLZW, ssa.OpPPC64POPCNTD, ssa.OpPPC64POPCNTW, ssa.OpPPC64POPCNTB, ssa.OpPPC64MFVSRD, ssa.OpPPC64MTVSRD:
r := v.Reg()
p := s.Prog(v.Op.Asm())
p.To.Type = obj.TYPE_REG
(Div64F x y) -> (FDIV x y)
// Lowering float <-> int
-(Cvt32to32F x) -> (FRSP (FCFID (Xi2f64 (SignExt32to64 x))))
-(Cvt32to64F x) -> (FCFID (Xi2f64 (SignExt32to64 x)))
-(Cvt64to32F x) -> (FRSP (FCFID (Xi2f64 x)))
-(Cvt64to64F x) -> (FCFID (Xi2f64 x))
+(Cvt32to32F x) -> (FCFIDS (MTVSRD (SignExt32to64 x)))
+(Cvt32to64F x) -> (FCFID (MTVSRD (SignExt32to64 x)))
+(Cvt64to32F x) -> (FCFIDS (MTVSRD x))
+(Cvt64to64F x) -> (FCFID (MTVSRD x))
-(Cvt32Fto32 x) -> (Xf2i64 (FCTIWZ x))
-(Cvt32Fto64 x) -> (Xf2i64 (FCTIDZ x))
-(Cvt64Fto32 x) -> (Xf2i64 (FCTIWZ x))
-(Cvt64Fto64 x) -> (Xf2i64 (FCTIDZ x))
+(Cvt32Fto32 x) -> (MFVSRD (FCTIWZ x))
+(Cvt32Fto64 x) -> (MFVSRD (FCTIDZ x))
+(Cvt64Fto32 x) -> (MFVSRD (FCTIWZ x))
+(Cvt64Fto64 x) -> (MFVSRD (FCTIDZ x))
(Cvt32Fto64F x) -> x // Note x will have the wrong type for patterns dependent on Float32/Float64
(Cvt64Fto32F x) -> (FRSP x)
+(MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr x _)) -> (MFVSRD x)
+(FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr x _)) -> (MTVSRD x)
+
+(FMOVDstore [off] {sym} ptr (MTVSRD x) mem) -> (MOVDstore [off] {sym} ptr x mem)
+(MOVDstore [off] {sym} ptr (MFVSRD x) mem) -> (FMOVDstore [off] {sym} ptr x mem)
+
(Round32F x) -> (LoweredRound32F x)
(Round64F x) -> (LoweredRound64F x)
{name: "FCTIDZ", argLength: 1, reg: fp11, asm: "FCTIDZ", typ: "Float64"}, // convert float to 64-bit int round towards zero
{name: "FCTIWZ", argLength: 1, reg: fp11, asm: "FCTIWZ", typ: "Float64"}, // convert float to 32-bit int round towards zero
{name: "FCFID", argLength: 1, reg: fp11, asm: "FCFID", typ: "Float64"}, // convert 64-bit integer to float
+ {name: "FCFIDS", argLength: 1, reg: fp11, asm: "FCFIDS", typ: "Float32"}, // convert 32-bit integer to float
{name: "FRSP", argLength: 1, reg: fp11, asm: "FRSP", typ: "Float64"}, // round float to 32-bit value
// Movement between float and integer registers with no change in bits; accomplished with stores+loads on PPC.
// There are optimizations that should apply -- (Xi2f64 (MOVWload (not-ADD-ptr+offset) ) ) could use
// the word-load instructions. (Xi2f64 (MOVDload ptr )) can be (FMOVDload ptr)
- {name: "Xf2i64", argLength: 1, reg: fpgp, typ: "Int64"}, // move 64 bits of F register into G register
- {name: "Xi2f64", argLength: 1, reg: gpfp, typ: "Float64"}, // move 64 bits of G register into F register
+ {name: "MFVSRD", argLength: 1, reg: fpgp, asm: "MFVSRD", typ: "Int64"}, // move 64 bits of F register into G register
+ {name: "MTVSRD", argLength: 1, reg: gpfp, asm: "MTVSRD", typ: "Float64"}, // move 64 bits of G register into F register
{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0&arg1
{name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"}, // arg0&^arg1
OpPPC64FCTIDZ
OpPPC64FCTIWZ
OpPPC64FCFID
+ OpPPC64FCFIDS
OpPPC64FRSP
- OpPPC64Xf2i64
- OpPPC64Xi2f64
+ OpPPC64MFVSRD
+ OpPPC64MTVSRD
OpPPC64AND
OpPPC64ANDN
OpPPC64OR
},
},
},
+ {
+ name: "FCFIDS",
+ argLen: 1,
+ asm: ppc64.AFCFIDS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 576460743713488896}, // 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
+ },
+ outputs: []outputInfo{
+ {0, 576460743713488896}, // 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
+ },
+ },
+ },
{
name: "FRSP",
argLen: 1,
},
},
{
- name: "Xf2i64",
+ name: "MFVSRD",
argLen: 1,
+ asm: ppc64.AMFVSRD,
reg: regInfo{
inputs: []inputInfo{
{0, 576460743713488896}, // 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
},
},
{
- name: "Xi2f64",
+ name: "MTVSRD",
argLen: 1,
+ asm: ppc64.AMTVSRD,
reg: regInfo{
inputs: []inputInfo{
{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
_ = typ
// match: (Cvt32Fto32 x)
// cond:
- // result: (Xf2i64 (FCTIWZ x))
+ // result: (MFVSRD (FCTIWZ x))
for {
x := v.Args[0]
- v.reset(OpPPC64Xf2i64)
+ v.reset(OpPPC64MFVSRD)
v0 := b.NewValue0(v.Pos, OpPPC64FCTIWZ, typ.Float64)
v0.AddArg(x)
v.AddArg(v0)
_ = typ
// match: (Cvt32Fto64 x)
// cond:
- // result: (Xf2i64 (FCTIDZ x))
+ // result: (MFVSRD (FCTIDZ x))
for {
x := v.Args[0]
- v.reset(OpPPC64Xf2i64)
+ v.reset(OpPPC64MFVSRD)
v0 := b.NewValue0(v.Pos, OpPPC64FCTIDZ, typ.Float64)
v0.AddArg(x)
v.AddArg(v0)
_ = typ
// match: (Cvt32to32F x)
// cond:
- // result: (FRSP (FCFID (Xi2f64 (SignExt32to64 x))))
+ // result: (FCFIDS (MTVSRD (SignExt32to64 x)))
for {
x := v.Args[0]
- v.reset(OpPPC64FRSP)
- v0 := b.NewValue0(v.Pos, OpPPC64FCFID, typ.Float64)
- v1 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
- v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
- v2.AddArg(x)
- v1.AddArg(v2)
+ v.reset(OpPPC64FCFIDS)
+ v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
+ v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+ v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0)
return true
_ = typ
// match: (Cvt32to64F x)
// cond:
- // result: (FCFID (Xi2f64 (SignExt32to64 x)))
+ // result: (FCFID (MTVSRD (SignExt32to64 x)))
for {
x := v.Args[0]
v.reset(OpPPC64FCFID)
- v0 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
+ v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
v1.AddArg(x)
v0.AddArg(v1)
_ = typ
// match: (Cvt64Fto32 x)
// cond:
- // result: (Xf2i64 (FCTIWZ x))
+ // result: (MFVSRD (FCTIWZ x))
for {
x := v.Args[0]
- v.reset(OpPPC64Xf2i64)
+ v.reset(OpPPC64MFVSRD)
v0 := b.NewValue0(v.Pos, OpPPC64FCTIWZ, typ.Float64)
v0.AddArg(x)
v.AddArg(v0)
_ = typ
// match: (Cvt64Fto64 x)
// cond:
- // result: (Xf2i64 (FCTIDZ x))
+ // result: (MFVSRD (FCTIDZ x))
for {
x := v.Args[0]
- v.reset(OpPPC64Xf2i64)
+ v.reset(OpPPC64MFVSRD)
v0 := b.NewValue0(v.Pos, OpPPC64FCTIDZ, typ.Float64)
v0.AddArg(x)
v.AddArg(v0)
_ = typ
// match: (Cvt64to32F x)
// cond:
- // result: (FRSP (FCFID (Xi2f64 x)))
+ // result: (FCFIDS (MTVSRD x))
for {
x := v.Args[0]
- v.reset(OpPPC64FRSP)
- v0 := b.NewValue0(v.Pos, OpPPC64FCFID, typ.Float64)
- v1 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
- v1.AddArg(x)
- v0.AddArg(v1)
+ v.reset(OpPPC64FCFIDS)
+ v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
+ v0.AddArg(x)
v.AddArg(v0)
return true
}
_ = typ
// match: (Cvt64to64F x)
// cond:
- // result: (FCFID (Xi2f64 x))
+ // result: (FCFID (MTVSRD x))
for {
x := v.Args[0]
v.reset(OpPPC64FCFID)
- v0 := b.NewValue0(v.Pos, OpPPC64Xi2f64, typ.Float64)
+ v0 := b.NewValue0(v.Pos, OpPPC64MTVSRD, typ.Float64)
v0.AddArg(x)
v.AddArg(v0)
return true
return false
}
func rewriteValuePPC64_OpPPC64FMOVDload_0(v *Value) bool {
+ // match: (FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr x _))
+ // cond:
+ // result: (MTVSRD x)
+ for {
+ off := v.AuxInt
+ sym := v.Aux
+ _ = v.Args[1]
+ ptr := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpPPC64MOVDstore {
+ break
+ }
+ if v_1.AuxInt != off {
+ break
+ }
+ if v_1.Aux != sym {
+ break
+ }
+ _ = v_1.Args[2]
+ if ptr != v_1.Args[0] {
+ break
+ }
+ x := v_1.Args[1]
+ v.reset(OpPPC64MTVSRD)
+ v.AddArg(x)
+ return true
+ }
// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2)
// result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
return false
}
func rewriteValuePPC64_OpPPC64FMOVDstore_0(v *Value) bool {
+ // match: (FMOVDstore [off] {sym} ptr (MTVSRD x) mem)
+ // cond:
+ // result: (MOVDstore [off] {sym} ptr x mem)
+ for {
+ off := v.AuxInt
+ sym := v.Aux
+ _ = v.Args[2]
+ ptr := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpPPC64MTVSRD {
+ break
+ }
+ x := v_1.Args[0]
+ mem := v.Args[2]
+ v.reset(OpPPC64MOVDstore)
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
// match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is16Bit(off1+off2)
// result: (FMOVDstore [off1+off2] {sym} ptr val mem)
return false
}
func rewriteValuePPC64_OpPPC64MOVDload_0(v *Value) bool {
+ // match: (MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr x _))
+ // cond:
+ // result: (MFVSRD x)
+ for {
+ off := v.AuxInt
+ sym := v.Aux
+ _ = v.Args[1]
+ ptr := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpPPC64FMOVDstore {
+ break
+ }
+ if v_1.AuxInt != off {
+ break
+ }
+ if v_1.Aux != sym {
+ break
+ }
+ _ = v_1.Args[2]
+ if ptr != v_1.Args[0] {
+ break
+ }
+ x := v_1.Args[1]
+ v.reset(OpPPC64MFVSRD)
+ v.AddArg(x)
+ return true
+ }
// match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2)
// result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
return false
}
func rewriteValuePPC64_OpPPC64MOVDstore_0(v *Value) bool {
+ // match: (MOVDstore [off] {sym} ptr (MFVSRD x) mem)
+ // cond:
+ // result: (FMOVDstore [off] {sym} ptr x mem)
+ for {
+ off := v.AuxInt
+ sym := v.Aux
+ _ = v.Args[2]
+ ptr := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpPPC64MFVSRD {
+ break
+ }
+ x := v_1.Args[0]
+ mem := v.Args[2]
+ v.reset(OpPPC64FMOVDstore)
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
// match: (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem)
// cond: is16Bit(off1+off2)
// result: (MOVDstore [off1+off2] {sym} x val mem)
AFCFIDCC
AFCFIDU
AFCFIDUCC
+ AFCFIDS
+ AFCFIDSCC
AFCTID
AFCTIDCC
AFCTIDZ
"FCFIDCC",
"FCFIDU",
"FCFIDUCC",
+ "FCFIDS",
+ "FCFIDSCC",
"FCTID",
"FCTIDCC",
"FCTIDZ",
opset(AFCFIDCC, r0)
opset(AFCFIDU, r0)
opset(AFCFIDUCC, r0)
+ opset(AFCFIDS, r0)
+ opset(AFCFIDSCC, r0)
opset(AFRES, r0)
opset(AFRESCC, r0)
opset(AFRIM, r0)
return OPVCC(63, 974, 0, 0)
case AFCFIDUCC:
return OPVCC(63, 974, 0, 1)
+ case AFCFIDS:
+ return OPVCC(59, 846, 0, 0)
+ case AFCFIDSCC:
+ return OPVCC(59, 846, 0, 1)
case AFCTIW:
return OPVCC(63, 14, 0, 0)
case AFCTIWCC: