VSTRCZBS V18, V20, V22, V24 // e78240306f8a
VSTRCZHS V18, V20, V22, V24 // e78241306f8a
VSTRCZFS V18, V20, V22, V24 // e78242306f8a
+ VFMAXSB $1, V2, V3, V4 // e742301020ef
+ WFMAXSB $2, V5, V6, V7 // e775602820ef
+ WFMAXSB $2, F5, F6, F7 // e775602820ef
+ VFMAXDB $3, V8, V9, V10 // e7a8903030ef
+ WFMAXDB $4, V11, V12, V13 // e7dbc04830ef
+ WFMAXDB $4, F11, F12, F13 // e7dbc04830ef
+ VFMINSB $7, V14, V15, V16 // e70ef07028ee
+ WFMINSB $8, V17, V18, V19 // e73120882eee
+ WFMINSB $8, F1, F2, F3 // e731208820ee
+ VFMINDB $9, V20, V21, V22 // e76450903eee
+ WFMINDB $10, V23, V24, V25 // e79780a83eee
+ WFMINDB $10, F7, F8, F9 // e79780a830ee
RET
RET foo(SB)
case ssa.OpS390XCPSDR:
p := opregreg(s, v.Op.Asm(), v.Reg(), v.Args[1].Reg())
p.Reg = v.Args[0].Reg()
+ case ssa.OpS390XWFMAXDB, ssa.OpS390XWFMAXSB,
+ ssa.OpS390XWFMINDB, ssa.OpS390XWFMINSB:
+ p := opregregimm(s, v.Op.Asm(), v.Reg(), v.Args[0].Reg(), 1 /* Java Math.Max() */)
+ p.AddRestSource(obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()})
case ssa.OpS390XDIVD, ssa.OpS390XDIVW,
ssa.OpS390XDIVDU, ssa.OpS390XDIVWU,
ssa.OpS390XMODD, ssa.OpS390XMODW,
(Sqrt32 ...) => (FSQRTS ...)
+(Max(64|32)F ...) => (WFMAX(D|S)B ...)
+(Min(64|32)F ...) => (WFMIN(D|S)B ...)
+
// Atomic loads and stores.
// The SYNC instruction (fast-BCR-serialization) prevents store-load
// reordering. Other sequences of memory operations (load-load,
{name: "LNDFR", argLength: 1, reg: fp11, asm: "LNDFR"}, // fp64/fp32 clear sign bit
{name: "CPSDR", argLength: 2, reg: fp21, asm: "CPSDR"}, // fp64/fp32 copy arg1 sign bit to arg0
+ // Single element vector floating point min / max instructions
+ {name: "WFMAXDB", argLength: 2, reg: fp21, asm: "WFMAXDB", typ: "Float64"}, // max[float64](arg0, arg1)
+ {name: "WFMAXSB", argLength: 2, reg: fp21, asm: "WFMAXSB", typ: "Float32"}, // max[float32](arg0, arg1)
+ {name: "WFMINDB", argLength: 2, reg: fp21, asm: "WFMINDB", typ: "Float64"}, // min[float64](arg0, arg1)
+ {name: "WFMINSB", argLength: 2, reg: fp21, asm: "WFMINSB", typ: "Float32"}, // min[float32](arg0, arg1)
+
// Round to integer, float64 only.
//
// aux | rounding mode
OpS390XLPDFR
OpS390XLNDFR
OpS390XCPSDR
+ OpS390XWFMAXDB
+ OpS390XWFMAXSB
+ OpS390XWFMINDB
+ OpS390XWFMINSB
OpS390XFIDBR
OpS390XFMOVSload
OpS390XFMOVDload
},
},
},
+ {
+ name: "WFMAXDB",
+ argLen: 2,
+ asm: s390x.AWFMAXDB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
+ {
+ name: "WFMAXSB",
+ argLen: 2,
+ asm: s390x.AWFMAXSB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
+ {
+ name: "WFMINDB",
+ argLen: 2,
+ asm: s390x.AWFMINDB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
+ {
+ name: "WFMINSB",
+ argLen: 2,
+ asm: s390x.AWFMINSB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
{
name: "FIDBR",
auxType: auxInt8,
return rewriteValueS390X_OpLsh8x64(v)
case OpLsh8x8:
return rewriteValueS390X_OpLsh8x8(v)
+ case OpMax32F:
+ v.Op = OpS390XWFMAXSB
+ return true
+ case OpMax64F:
+ v.Op = OpS390XWFMAXDB
+ return true
+ case OpMin32F:
+ v.Op = OpS390XWFMINSB
+ return true
+ case OpMin64F:
+ v.Op = OpS390XWFMINDB
+ return true
case OpMod16:
return rewriteValueS390X_OpMod16(v)
case OpMod16u:
if typ.IsFloat() {
hasIntrinsic := false
switch Arch.LinkArch.Family {
- case sys.AMD64, sys.ARM64, sys.Loong64, sys.RISCV64:
+ case sys.AMD64, sys.ARM64, sys.Loong64, sys.RISCV64, sys.S390X:
hasIntrinsic = true
case sys.PPC64:
hasIntrinsic = buildcfg.GOPPC64 >= 9
AWFLNDB
AVFLPDB
AWFLPDB
+ AVFMAXDB
+ AWFMAXDB
+ AVFMAXSB
+ AWFMAXSB
+ AVFMINDB
+ AWFMINDB
+ AVFMINSB
+ AWFMINSB
AVFSQ
AVFSQDB
AWFSQDB
"WFLNDB",
"VFLPDB",
"WFLPDB",
+ "VFMAXDB",
+ "WFMAXDB",
+ "VFMAXSB",
+ "WFMAXSB",
+ "VFMINDB",
+ "WFMINDB",
+ "VFMINSB",
+ "WFMINSB",
"VFSQ",
"VFSQDB",
"WFSQDB",
{i: 119, as: AVERLLVG, a1: C_VREG, a2: C_VREG, a6: C_VREG},
{i: 119, as: AVERLLVG, a1: C_VREG, a6: C_VREG},
+ // VRR-c floating point min/max
+ {i: 128, as: AVFMAXDB, a1: C_SCON, a2: C_VREG, a3: C_VREG, a6: C_VREG},
+ {i: 128, as: AWFMAXDB, a1: C_SCON, a2: C_VREG, a3: C_VREG, a6: C_VREG},
+ {i: 128, as: AWFMAXDB, a1: C_SCON, a2: C_FREG, a3: C_FREG, a6: C_FREG},
+
// VRR-d
{i: 120, as: AVACQ, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG},
opset(AVFMSDB, r)
opset(AWFMSDB, r)
opset(AVPERM, r)
+ case AVFMAXDB:
+ opset(AVFMAXSB, r)
+ opset(AVFMINDB, r)
+ opset(AVFMINSB, r)
+ case AWFMAXDB:
+ opset(AWFMAXSB, r)
+ opset(AWFMINDB, r)
+ opset(AWFMINSB, r)
case AKM:
opset(AKMC, r)
opset(AKLMD, r)
op_VUPLL uint32 = 0xE7D4 // VRR-a VECTOR UNPACK LOGICAL LOW
op_VUPL uint32 = 0xE7D6 // VRR-a VECTOR UNPACK LOW
op_VMSL uint32 = 0xE7B8 // VRR-d VECTOR MULTIPLY SUM LOGICAL
+ op_VFMAX uint32 = 0xE7EF // VRR-c VECTOR FP MAXIMUM
+ op_VFMIN uint32 = 0xE7EE // VRR-c VECTOR FP MINIMUM
// added in z15
op_KDSA uint32 = 0xB93A // FORMAT_RRE COMPUTE DIGITAL SIGNATURE AUTHENTICATION (KDSA)
c.ctxt.Diag("padding byte register cannot be same as input or output register %v", p)
}
zRS(op_MVCLE, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), uint32(d2), asm)
+
+ case 128: // VRR-c floating point max/min
+ op, m4, _ := vop(p.As)
+ m5 := singleElementMask(p.As)
+ m6 := uint32(c.vregoff(&p.From))
+ zVRRc(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), m6, m5, m4, asm)
}
}
return op_VUPL, 1, 0
case AVUPLF:
return op_VUPL, 2, 0
+ case AVFMAXDB:
+ return op_VFMAX, 3, 0
+ case AWFMAXDB:
+ return op_VFMAX, 3, 0
+ case AVFMAXSB:
+ return op_VFMAX, 2, 0
+ case AWFMAXSB:
+ return op_VFMAX, 2, 0
+ case AVFMINDB:
+ return op_VFMIN, 3, 0
+ case AWFMINDB:
+ return op_VFMIN, 3, 0
+ case AVFMINSB:
+ return op_VFMIN, 2, 0
+ case AWFMINSB:
+ return op_VFMIN, 2, 0
}
}
AWFSQDB,
AWFSDB,
AWFTCIDB,
- AWFIDB:
+ AWFIDB,
+ AWFMAXDB,
+ AWFMAXSB,
+ AWFMINDB,
+ AWFMINSB:
return 8
}
return 0
// riscv64:"FMIN"
// ppc64/power9:"XSMINJDP"
// ppc64/power10:"XSMINJDP"
+ // s390x: "WFMINDB"
return min(a, b)
}
// riscv64:"FMAX"
// ppc64/power9:"XSMAXJDP"
// ppc64/power10:"XSMAXJDP"
+ // s390x: "WFMAXDB"
return max(a, b)
}
// riscv64:"FMINS"
// ppc64/power9:"XSMINJDP"
// ppc64/power10:"XSMINJDP"
+ // s390x: "WFMINSB"
return min(a, b)
}
// riscv64:"FMAXS"
// ppc64/power9:"XSMAXJDP"
// ppc64/power10:"XSMAXJDP"
+ // s390x: "WFMAXSB"
return max(a, b)
}