Commit 3c8ef0e0 authored by Michael Munday's avatar Michael Munday Committed by Brad Fitzpatrick

cmd/compile: allow 64-bit multiplication with immediates on s390x

MGHI (16-bit signed immediate) is now used where possible for both
MULLW and MULLD. MGHI is 2-bytes shorter than MSGFI.

Change-Id: I5d0648934f28b3403b1126913fd703d8f62b9e9f
Reviewed-on: https://go-review.googlesource.com/22398
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBill O'Farrell <billotosyr@gmail.com>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 5fe1b35e
......@@ -59,8 +59,12 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
SUBC R2, R3, R4 // b9eb2043
MULLW R6, R7 // b91c0076
MULLW R6, R7, R8 // b9040087b91c0086
MULLW $8192, R6 // c26000002000
MULLW $8192, R6, R7 // b9040076c27000002000
MULLW $8192, R6 // a76d2000
MULLW $8192, R6, R7 // b9040076a77d2000
MULLW $-65537, R8 // c280fffeffff
MULLW $-65537, R8, R9 // b9040098c290fffeffff
MULLD $-2147483648, R1 // c21080000000
MULLD $-2147483648, R1, R2 // b9040021c22080000000
MULHD R9, R8 // b90400b8b98600a9ebb9003f000ab98000b8b90900abebb8003f000ab98000b9b9e9b08a
MULHD R7, R2, R1 // b90400b2b98600a7ebb7003f000ab98000b2b90900abebb2003f000ab98000b7b9e9b01a
MULHDU R3, R4 // b90400b4b98600a3b904004a
......
......@@ -54,7 +54,7 @@ func ginscon(as obj.As, c int64, n2 *gc.Node) {
gc.Nodconst(&n1, gc.Types[gc.TINT64], c)
if as != s390x.AMOVD && (c < -s390x.BIG || c > s390x.BIG) || n2.Op != gc.OREGISTER || as == s390x.AMULLD {
if as != s390x.AMOVD && (c < -s390x.BIG || c > s390x.BIG) || n2.Op != gc.OREGISTER {
// cannot have more than 16-bit of immediate in ADD, etc.
// instead, MOV into register first.
var ntmp gc.Node
......@@ -562,11 +562,6 @@ func rawgins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
switch as {
// Bad things the front end has done to us. Crash to find call stack.
case s390x.AMULLD:
if p.From.Type == obj.TYPE_CONST {
gc.Debug['h'] = 1
gc.Fatalf("bad inst: %v", p)
}
case s390x.ACMP, s390x.ACMPU:
if p.From.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_MEM {
gc.Debug['h'] = 1
......
......@@ -142,14 +142,6 @@ var optab = []Optab{
Optab{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
Optab{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 0},
Optab{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
Optab{AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 0},
Optab{AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
Optab{AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 0},
Optab{AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
Optab{AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 0},
Optab{AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
Optab{AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 0},
Optab{AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
Optab{AMULHD, C_REG, C_NONE, C_NONE, C_REG, 4, 0},
Optab{AMULHD, C_REG, C_REG, C_NONE, C_REG, 4, 0},
Optab{ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 0},
......@@ -792,9 +784,12 @@ func buildop(ctxt *obj.Link) {
// opset() aliases optab ranges for similar instructions, to reduce the number of optabs in the array.
// oprange[] is used by oplook() to find the Optab entry that applies to a given Prog.
switch r {
case AADD:
opset(AADDC, r)
opset(AMULLD, r)
opset(AMULLW, r)
case ADIVW:
opset(AADDE, r)
opset(AMULLD, r)
opset(ADIVD, r)
opset(ADIVDU, r)
opset(ADIVWU, r)
......@@ -2935,12 +2930,16 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
}
zRIL(_a, op_ALGFI, uint32(p.To.Reg), uint32(v), asm)
case AMULLW:
case AMULLW, AMULLD:
if r != p.To.Reg {
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
}
if int64(int16(v)) == v {
zRI(op_MGHI, uint32(p.To.Reg), uint32(v), asm)
} else {
zRIL(_a, op_MSGFI, uint32(p.To.Reg), uint32(v), asm)
}
}
case 23: // logical op $constant [reg] reg
v := vregoff(ctxt, &p.From)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment