mirror of
https://github.com/golang/go
synced 2024-11-05 18:26:10 -07:00
cmd/asm, cmd/internal/obj/s390x: add new s390x instructions for SSA
This commit adds the following instructions to support the new SSA backend for s390x: 32-bit operations: ADDW SUBW NEGW FNEGS Conditional moves: MOVDEQ MOVDGE MOVDGT MOVDLE MOVDLT MOVDNE Unordered branches (for floating point comparisons): BLEU BLTU Modulo operations: MODW MODWU MODD MODDU The modulo operations might be removed in a future commit because I'd like to change DIV to produce a tuple once the old backend is removed. This commit also removes uses of REGZERO from the assembler. They aren't necessary and R0 will be used as a GPR by SSA. Change-Id: I05756c1cbb74bf4a35fc492f8f0cd34b50763dc9 Reviewed-on: https://go-review.googlesource.com/29075 Run-TryBot: Michael Munday <munday@ca.ibm.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
dfc56a4cd3
commit
43bdfa9337
35
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
35
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
@ -13,6 +13,13 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
|
|||||||
MOVDBR R1, R2 // b90f0021
|
MOVDBR R1, R2 // b90f0021
|
||||||
MOVWBR R3, R4 // b91f0043
|
MOVWBR R3, R4 // b91f0043
|
||||||
|
|
||||||
|
MOVDEQ R0, R1 // b9e28010
|
||||||
|
MOVDGE R2, R3 // b9e2a032
|
||||||
|
MOVDGT R4, R5 // b9e22054
|
||||||
|
MOVDLE R6, R7 // b9e2c076
|
||||||
|
MOVDLT R8, R9 // b9e24098
|
||||||
|
MOVDNE R10, R11 // b9e270ba
|
||||||
|
|
||||||
MOVD (R15), R1 // e310f0000004
|
MOVD (R15), R1 // e310f0000004
|
||||||
MOVW (R15), R2 // e320f0000014
|
MOVW (R15), R2 // e320f0000014
|
||||||
MOVH (R15), R3 // e330f0000015
|
MOVH (R15), R3 // e330f0000015
|
||||||
@ -50,6 +57,10 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
|
|||||||
ADDC R1, R2 // b9ea1022
|
ADDC R1, R2 // b9ea1022
|
||||||
ADDC $1, R1, R2 // b9040021c22a00000001
|
ADDC $1, R1, R2 // b9040021c22a00000001
|
||||||
ADDC R1, R2, R3 // b9ea1032
|
ADDC R1, R2, R3 // b9ea1032
|
||||||
|
ADDW R1, R2 // 1a21
|
||||||
|
ADDW R1, R2, R3 // b9f81032
|
||||||
|
ADDW $8192, R1 // c21900002000
|
||||||
|
ADDW $8192, R1, R2 // ec21200000d8
|
||||||
SUB R3, R4 // b9090043
|
SUB R3, R4 // b9090043
|
||||||
SUB R3, R4, R5 // b9e93054
|
SUB R3, R4, R5 // b9e93054
|
||||||
SUB $8192, R3 // c238ffffe000
|
SUB $8192, R3 // c238ffffe000
|
||||||
@ -57,6 +68,10 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
|
|||||||
SUBC R1, R2 // b90b0021
|
SUBC R1, R2 // b90b0021
|
||||||
SUBC $1, R1, R2 // b9040021c22affffffff
|
SUBC $1, R1, R2 // b9040021c22affffffff
|
||||||
SUBC R2, R3, R4 // b9eb2043
|
SUBC R2, R3, R4 // b9eb2043
|
||||||
|
SUBW R3, R4 // 1b43
|
||||||
|
SUBW R3, R4, R5 // b9f93054
|
||||||
|
SUBW $8192, R1 // c21500002000
|
||||||
|
SUBW $8192, R1, R2 // 1821c22500002000
|
||||||
MULLW R6, R7 // b91c0076
|
MULLW R6, R7 // b91c0076
|
||||||
MULLW R6, R7, R8 // b9040087b91c0086
|
MULLW R6, R7, R8 // b9040087b91c0086
|
||||||
MULLW $8192, R6 // a76d2000
|
MULLW $8192, R6 // a76d2000
|
||||||
@ -73,10 +88,22 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
|
|||||||
DIVD R1, R2, R3 // b90400b2b90d00a1b904003b
|
DIVD R1, R2, R3 // b90400b2b90d00a1b904003b
|
||||||
DIVW R4, R5 // b90400b5b91d00a4b904005b
|
DIVW R4, R5 // b90400b5b91d00a4b904005b
|
||||||
DIVW R4, R5, R6 // b90400b5b91d00a4b904006b
|
DIVW R4, R5, R6 // b90400b5b91d00a4b904006b
|
||||||
DIVDU R7, R8 // b90400a0b90400b8b98700a7b904008b
|
DIVDU R7, R8 // a7a90000b90400b8b98700a7b904008b
|
||||||
DIVDU R7, R8, R9 // b90400a0b90400b8b98700a7b904009b
|
DIVDU R7, R8, R9 // a7a90000b90400b8b98700a7b904009b
|
||||||
DIVWU R1, R2 // b90400a0b90400b2b99700a1b904002b
|
DIVWU R1, R2 // a7a90000b90400b2b99700a1b904002b
|
||||||
DIVWU R1, R2, R3 // b90400a0b90400b2b99700a1b904003b
|
DIVWU R1, R2, R3 // a7a90000b90400b2b99700a1b904003b
|
||||||
|
MODD R1, R2 // b90400b2b90d00a1b904002a
|
||||||
|
MODD R1, R2, R3 // b90400b2b90d00a1b904003a
|
||||||
|
MODW R4, R5 // b90400b5b91d00a4b904005a
|
||||||
|
MODW R4, R5, R6 // b90400b5b91d00a4b904006a
|
||||||
|
MODDU R7, R8 // a7a90000b90400b8b98700a7b904008a
|
||||||
|
MODDU R7, R8, R9 // a7a90000b90400b8b98700a7b904009a
|
||||||
|
MODWU R1, R2 // a7a90000b90400b2b99700a1b904002a
|
||||||
|
MODWU R1, R2, R3 // a7a90000b90400b2b99700a1b904003a
|
||||||
|
NEG R1 // b9030011
|
||||||
|
NEG R1, R2 // b9030021
|
||||||
|
NEGW R1 // b9130011
|
||||||
|
NEGW R1, R2 // b9130021
|
||||||
|
|
||||||
LAA R1, R2, 524287(R3) // eb213fff7ff8
|
LAA R1, R2, 524287(R3) // eb213fff7ff8
|
||||||
LAAG R4, R5, -524288(R6) // eb54600080e8
|
LAAG R4, R5, -524288(R6) // eb54600080e8
|
||||||
|
@ -212,10 +212,15 @@ const (
|
|||||||
AADDME
|
AADDME
|
||||||
AADDE
|
AADDE
|
||||||
AADDZE
|
AADDZE
|
||||||
|
AADDW
|
||||||
ADIVW
|
ADIVW
|
||||||
ADIVWU
|
ADIVWU
|
||||||
ADIVD
|
ADIVD
|
||||||
ADIVDU
|
ADIVDU
|
||||||
|
AMODW
|
||||||
|
AMODWU
|
||||||
|
AMODD
|
||||||
|
AMODDU
|
||||||
AMULLW
|
AMULLW
|
||||||
AMULLD
|
AMULLD
|
||||||
AMULHD
|
AMULHD
|
||||||
@ -226,7 +231,9 @@ const (
|
|||||||
ASUBV
|
ASUBV
|
||||||
ASUBE
|
ASUBE
|
||||||
ASUBZE
|
ASUBZE
|
||||||
|
ASUBW
|
||||||
ANEG
|
ANEG
|
||||||
|
ANEGW
|
||||||
|
|
||||||
// integer moves
|
// integer moves
|
||||||
AMOVWBR
|
AMOVWBR
|
||||||
@ -240,6 +247,14 @@ const (
|
|||||||
AMOVD
|
AMOVD
|
||||||
AMOVDBR
|
AMOVDBR
|
||||||
|
|
||||||
|
// conditional moves
|
||||||
|
AMOVDEQ
|
||||||
|
AMOVDGE
|
||||||
|
AMOVDGT
|
||||||
|
AMOVDLE
|
||||||
|
AMOVDLT
|
||||||
|
AMOVDNE
|
||||||
|
|
||||||
// integer bitwise
|
// integer bitwise
|
||||||
AAND
|
AAND
|
||||||
AANDN
|
AANDN
|
||||||
@ -276,6 +291,7 @@ const (
|
|||||||
AFMULS
|
AFMULS
|
||||||
AFNABS
|
AFNABS
|
||||||
AFNEG
|
AFNEG
|
||||||
|
AFNEGS
|
||||||
AFNMADD
|
AFNMADD
|
||||||
AFNMADDS
|
AFNMADDS
|
||||||
AFNMSUB
|
AFNMSUB
|
||||||
@ -334,6 +350,8 @@ const (
|
|||||||
ABGT
|
ABGT
|
||||||
ABLE
|
ABLE
|
||||||
ABLT
|
ABLT
|
||||||
|
ABLEU
|
||||||
|
ABLTU
|
||||||
ABNE
|
ABNE
|
||||||
ABVC
|
ABVC
|
||||||
ABVS
|
ABVS
|
||||||
|
@ -11,10 +11,15 @@ var Anames = []string{
|
|||||||
"ADDME",
|
"ADDME",
|
||||||
"ADDE",
|
"ADDE",
|
||||||
"ADDZE",
|
"ADDZE",
|
||||||
|
"ADDW",
|
||||||
"DIVW",
|
"DIVW",
|
||||||
"DIVWU",
|
"DIVWU",
|
||||||
"DIVD",
|
"DIVD",
|
||||||
"DIVDU",
|
"DIVDU",
|
||||||
|
"MODW",
|
||||||
|
"MODWU",
|
||||||
|
"MODD",
|
||||||
|
"MODDU",
|
||||||
"MULLW",
|
"MULLW",
|
||||||
"MULLD",
|
"MULLD",
|
||||||
"MULHD",
|
"MULHD",
|
||||||
@ -25,7 +30,9 @@ var Anames = []string{
|
|||||||
"SUBV",
|
"SUBV",
|
||||||
"SUBE",
|
"SUBE",
|
||||||
"SUBZE",
|
"SUBZE",
|
||||||
|
"SUBW",
|
||||||
"NEG",
|
"NEG",
|
||||||
|
"NEGW",
|
||||||
"MOVWBR",
|
"MOVWBR",
|
||||||
"MOVB",
|
"MOVB",
|
||||||
"MOVBZ",
|
"MOVBZ",
|
||||||
@ -36,6 +43,12 @@ var Anames = []string{
|
|||||||
"MOVWZ",
|
"MOVWZ",
|
||||||
"MOVD",
|
"MOVD",
|
||||||
"MOVDBR",
|
"MOVDBR",
|
||||||
|
"MOVDEQ",
|
||||||
|
"MOVDGE",
|
||||||
|
"MOVDGT",
|
||||||
|
"MOVDLE",
|
||||||
|
"MOVDLT",
|
||||||
|
"MOVDNE",
|
||||||
"AND",
|
"AND",
|
||||||
"ANDN",
|
"ANDN",
|
||||||
"NAND",
|
"NAND",
|
||||||
@ -69,6 +82,7 @@ var Anames = []string{
|
|||||||
"FMULS",
|
"FMULS",
|
||||||
"FNABS",
|
"FNABS",
|
||||||
"FNEG",
|
"FNEG",
|
||||||
|
"FNEGS",
|
||||||
"FNMADD",
|
"FNMADD",
|
||||||
"FNMADDS",
|
"FNMADDS",
|
||||||
"FNMSUB",
|
"FNMSUB",
|
||||||
@ -111,6 +125,8 @@ var Anames = []string{
|
|||||||
"BGT",
|
"BGT",
|
||||||
"BLE",
|
"BLE",
|
||||||
"BLT",
|
"BLT",
|
||||||
|
"BLEU",
|
||||||
|
"BLTU",
|
||||||
"BNE",
|
"BNE",
|
||||||
"BVC",
|
"BVC",
|
||||||
"BVS",
|
"BVS",
|
||||||
|
@ -145,10 +145,10 @@ var optab = []Optab{
|
|||||||
Optab{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
|
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_REG, C_NONE, C_REG, 22, 0},
|
||||||
Optab{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
|
Optab{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
|
||||||
|
Optab{ASUB, C_LCON, C_REG, C_NONE, C_REG, 22, 0},
|
||||||
|
Optab{ASUB, 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_NONE, C_NONE, C_REG, 4, 0},
|
||||||
Optab{AMULHD, C_REG, C_REG, 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},
|
|
||||||
Optab{ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 0},
|
|
||||||
Optab{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 0},
|
Optab{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 0},
|
||||||
Optab{ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
|
Optab{ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
|
||||||
Optab{ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 0},
|
Optab{ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 0},
|
||||||
@ -217,6 +217,9 @@ var optab = []Optab{
|
|||||||
Optab{ACMPUBEQ, C_REG, C_REG, C_NONE, C_SBRA, 89, 0},
|
Optab{ACMPUBEQ, C_REG, C_REG, C_NONE, C_SBRA, 89, 0},
|
||||||
Optab{ACMPUBEQ, C_REG, C_NONE, C_ANDCON, C_SBRA, 90, 0},
|
Optab{ACMPUBEQ, C_REG, C_NONE, C_ANDCON, C_SBRA, 90, 0},
|
||||||
|
|
||||||
|
// move on condition
|
||||||
|
Optab{AMOVDEQ, C_REG, C_NONE, C_NONE, C_REG, 17, 0},
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
Optab{ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 0},
|
Optab{ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 0},
|
||||||
Optab{ACMP, C_REG, C_NONE, C_NONE, C_LCON, 71, 0},
|
Optab{ACMP, C_REG, C_NONE, C_NONE, C_LCON, 71, 0},
|
||||||
@ -790,6 +793,7 @@ func buildop(ctxt *obj.Link) {
|
|||||||
switch r {
|
switch r {
|
||||||
case AADD:
|
case AADD:
|
||||||
opset(AADDC, r)
|
opset(AADDC, r)
|
||||||
|
opset(AADDW, r)
|
||||||
opset(AMULLD, r)
|
opset(AMULLD, r)
|
||||||
opset(AMULLW, r)
|
opset(AMULLW, r)
|
||||||
case ADIVW:
|
case ADIVW:
|
||||||
@ -797,6 +801,10 @@ func buildop(ctxt *obj.Link) {
|
|||||||
opset(ADIVD, r)
|
opset(ADIVD, r)
|
||||||
opset(ADIVDU, r)
|
opset(ADIVDU, r)
|
||||||
opset(ADIVWU, r)
|
opset(ADIVWU, r)
|
||||||
|
opset(AMODD, r)
|
||||||
|
opset(AMODDU, r)
|
||||||
|
opset(AMODW, r)
|
||||||
|
opset(AMODWU, r)
|
||||||
case AMULHD:
|
case AMULHD:
|
||||||
opset(AMULHDU, r)
|
opset(AMULHDU, r)
|
||||||
case AMOVBZ:
|
case AMOVBZ:
|
||||||
@ -844,6 +852,8 @@ func buildop(ctxt *obj.Link) {
|
|||||||
opset(ABNE, r)
|
opset(ABNE, r)
|
||||||
opset(ABVC, r)
|
opset(ABVC, r)
|
||||||
opset(ABVS, r)
|
opset(ABVS, r)
|
||||||
|
opset(ABLEU, r)
|
||||||
|
opset(ABLTU, r)
|
||||||
case ABR:
|
case ABR:
|
||||||
opset(ABL, r)
|
opset(ABL, r)
|
||||||
case ABC:
|
case ABC:
|
||||||
@ -851,6 +861,7 @@ func buildop(ctxt *obj.Link) {
|
|||||||
case AFABS:
|
case AFABS:
|
||||||
opset(AFNABS, r)
|
opset(AFNABS, r)
|
||||||
opset(AFNEG, r)
|
opset(AFNEG, r)
|
||||||
|
opset(AFNEGS, r)
|
||||||
opset(ALEDBR, r)
|
opset(ALEDBR, r)
|
||||||
opset(ALDEBR, r)
|
opset(ALDEBR, r)
|
||||||
opset(AFSQRT, r)
|
opset(AFSQRT, r)
|
||||||
@ -889,6 +900,9 @@ func buildop(ctxt *obj.Link) {
|
|||||||
case ASUB:
|
case ASUB:
|
||||||
opset(ASUBC, r)
|
opset(ASUBC, r)
|
||||||
opset(ASUBE, r)
|
opset(ASUBE, r)
|
||||||
|
opset(ASUBW, r)
|
||||||
|
case ANEG:
|
||||||
|
opset(ANEGW, r)
|
||||||
case AFMOVD:
|
case AFMOVD:
|
||||||
opset(AFMOVS, r)
|
opset(AFMOVS, r)
|
||||||
case AMOVDBR:
|
case AMOVDBR:
|
||||||
@ -927,6 +941,12 @@ func buildop(ctxt *obj.Link) {
|
|||||||
opset(ACMPUBLE, r)
|
opset(ACMPUBLE, r)
|
||||||
opset(ACMPUBLT, r)
|
opset(ACMPUBLT, r)
|
||||||
opset(ACMPUBNE, r)
|
opset(ACMPUBNE, r)
|
||||||
|
case AMOVDEQ:
|
||||||
|
opset(AMOVDGE, r)
|
||||||
|
opset(AMOVDGT, r)
|
||||||
|
opset(AMOVDLE, r)
|
||||||
|
opset(AMOVDLT, r)
|
||||||
|
opset(AMOVDNE, r)
|
||||||
case AVL:
|
case AVL:
|
||||||
opset(AVLLEZB, r)
|
opset(AVLLEZB, r)
|
||||||
opset(AVLLEZH, r)
|
opset(AVLLEZH, r)
|
||||||
@ -2510,22 +2530,26 @@ func addcallreloc(ctxt *obj.Link, sym *obj.LSym, add int64) *obj.Reloc {
|
|||||||
|
|
||||||
func branchMask(ctxt *obj.Link, p *obj.Prog) uint32 {
|
func branchMask(ctxt *obj.Link, p *obj.Prog) uint32 {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ABEQ, ACMPBEQ, ACMPUBEQ:
|
case ABEQ, ACMPBEQ, ACMPUBEQ, AMOVDEQ:
|
||||||
return 0x8
|
return 0x8
|
||||||
case ABGE, ACMPBGE, ACMPUBGE:
|
case ABGE, ACMPBGE, ACMPUBGE, AMOVDGE:
|
||||||
return 0xA
|
return 0xA
|
||||||
case ABGT, ACMPBGT, ACMPUBGT:
|
case ABGT, ACMPBGT, ACMPUBGT, AMOVDGT:
|
||||||
return 0x2
|
return 0x2
|
||||||
case ABLE, ACMPBLE, ACMPUBLE:
|
case ABLE, ACMPBLE, ACMPUBLE, AMOVDLE:
|
||||||
return 0xC
|
return 0xC
|
||||||
case ABLT, ACMPBLT, ACMPUBLT:
|
case ABLT, ACMPBLT, ACMPUBLT, AMOVDLT:
|
||||||
return 0x4
|
return 0x4
|
||||||
case ABNE, ACMPBNE, ACMPUBNE:
|
case ABNE, ACMPBNE, ACMPUBNE, AMOVDNE:
|
||||||
return 0x7
|
return 0x7
|
||||||
|
case ABLEU: // LE or unordered
|
||||||
|
return 0xD
|
||||||
|
case ABLTU: // LT or unordered
|
||||||
|
return 0x5
|
||||||
case ABVC:
|
case ABVC:
|
||||||
return 0x0 // needs extra instruction
|
return 0x0 // needs extra instruction
|
||||||
case ABVS:
|
case ABVS:
|
||||||
return 0x1
|
return 0x1 // unordered
|
||||||
}
|
}
|
||||||
ctxt.Diag("unknown conditional branch %v", p.As)
|
ctxt.Diag("unknown conditional branch %v", p.As)
|
||||||
return 0xF
|
return 0xF
|
||||||
@ -2574,9 +2598,9 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 2: // arithmetic op reg [reg] reg
|
case 2: // arithmetic op reg [reg] reg
|
||||||
r := int(p.Reg)
|
r := p.Reg
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = p.To.Reg
|
||||||
}
|
}
|
||||||
|
|
||||||
var opcode uint32
|
var opcode uint32
|
||||||
@ -2590,17 +2614,19 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
opcode = op_ALGRK
|
opcode = op_ALGRK
|
||||||
case AADDE:
|
case AADDE:
|
||||||
opcode = op_ALCGR
|
opcode = op_ALCGR
|
||||||
|
case AADDW:
|
||||||
|
opcode = op_ARK
|
||||||
case AMULLW:
|
case AMULLW:
|
||||||
opcode = op_MSGFR
|
opcode = op_MSGFR
|
||||||
case AMULLD:
|
case AMULLD:
|
||||||
opcode = op_MSGR
|
opcode = op_MSGR
|
||||||
case ADIVW:
|
case ADIVW, AMODW:
|
||||||
opcode = op_DSGFR
|
opcode = op_DSGFR
|
||||||
case ADIVWU:
|
case ADIVWU, AMODWU:
|
||||||
opcode = op_DLR
|
opcode = op_DLR
|
||||||
case ADIVD:
|
case ADIVD, AMODD:
|
||||||
opcode = op_DSGR
|
opcode = op_DSGR
|
||||||
case ADIVDU:
|
case ADIVDU, AMODDU:
|
||||||
opcode = op_DLGR
|
opcode = op_DLGR
|
||||||
case AFADD:
|
case AFADD:
|
||||||
opcode = op_ADBR
|
opcode = op_ADBR
|
||||||
@ -2619,11 +2645,15 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
switch p.As {
|
switch p.As {
|
||||||
default:
|
default:
|
||||||
|
|
||||||
case AADD, AADDC:
|
case AADD, AADDC, AADDW:
|
||||||
|
if p.As == AADDW && r == p.To.Reg {
|
||||||
|
zRR(op_AR, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
||||||
|
} else {
|
||||||
zRRF(opcode, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm)
|
zRRF(opcode, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
}
|
||||||
|
|
||||||
case AADDE, AMULLW, AMULLD:
|
case AADDE, AMULLW, AMULLD:
|
||||||
if r == int(p.To.Reg) {
|
if r == p.To.Reg {
|
||||||
zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
||||||
} else if p.From.Reg == p.To.Reg {
|
} else if p.From.Reg == p.To.Reg {
|
||||||
zRRE(opcode, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(opcode, uint32(p.To.Reg), uint32(r), asm)
|
||||||
@ -2634,14 +2664,22 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
|
|
||||||
case ADIVW, ADIVWU, ADIVD, ADIVDU:
|
case ADIVW, ADIVWU, ADIVD, ADIVDU:
|
||||||
if p.As == ADIVWU || p.As == ADIVDU {
|
if p.As == ADIVWU || p.As == ADIVDU {
|
||||||
zRRE(op_LGR, REGTMP, REGZERO, asm)
|
zRI(op_LGHI, REGTMP, 0, asm)
|
||||||
}
|
}
|
||||||
zRRE(op_LGR, REGTMP2, uint32(r), asm)
|
zRRE(op_LGR, REGTMP2, uint32(r), asm)
|
||||||
zRRE(opcode, REGTMP, uint32(p.From.Reg), asm)
|
zRRE(opcode, REGTMP, uint32(p.From.Reg), asm)
|
||||||
zRRE(op_LGR, uint32(p.To.Reg), REGTMP2, asm)
|
zRRE(op_LGR, uint32(p.To.Reg), REGTMP2, asm)
|
||||||
|
|
||||||
|
case AMODW, AMODWU, AMODD, AMODDU:
|
||||||
|
if p.As == AMODWU || p.As == AMODDU {
|
||||||
|
zRI(op_LGHI, REGTMP, 0, asm)
|
||||||
|
}
|
||||||
|
zRRE(op_LGR, REGTMP2, uint32(r), asm)
|
||||||
|
zRRE(opcode, REGTMP, uint32(p.From.Reg), asm)
|
||||||
|
zRRE(op_LGR, uint32(p.To.Reg), REGTMP, asm)
|
||||||
|
|
||||||
case AFADD, AFADDS:
|
case AFADD, AFADDS:
|
||||||
if r == int(p.To.Reg) {
|
if r == p.To.Reg {
|
||||||
zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
||||||
} else if p.From.Reg == p.To.Reg {
|
} else if p.From.Reg == p.To.Reg {
|
||||||
zRRE(opcode, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(opcode, uint32(p.To.Reg), uint32(r), asm)
|
||||||
@ -2651,7 +2689,7 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case AFSUB, AFSUBS, AFDIV, AFDIVS:
|
case AFSUB, AFSUBS, AFDIV, AFDIVS:
|
||||||
if r == int(p.To.Reg) {
|
if r == p.To.Reg {
|
||||||
zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
||||||
} else if p.From.Reg == p.To.Reg {
|
} else if p.From.Reg == p.To.Reg {
|
||||||
zRRE(op_LGDR, REGTMP, uint32(r), asm)
|
zRRE(op_LGDR, REGTMP, uint32(r), asm)
|
||||||
@ -2681,16 +2719,14 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
case AMOVW:
|
case AMOVW:
|
||||||
v = int64(int32(v))
|
v = int64(int32(v))
|
||||||
}
|
}
|
||||||
if v&0xffff == v {
|
if int64(int16(v)) == v {
|
||||||
zRI(op_LLILL, uint32(p.To.Reg), uint32(v), asm)
|
zRI(op_LGHI, uint32(p.To.Reg), uint32(v), asm)
|
||||||
} else if v&0xffff0000 == v {
|
} else if v&0xffff0000 == v {
|
||||||
zRI(op_LLILH, uint32(p.To.Reg), uint32(v>>16), asm)
|
zRI(op_LLILH, uint32(p.To.Reg), uint32(v>>16), asm)
|
||||||
} else if v&0xffff00000000 == v {
|
} else if v&0xffff00000000 == v {
|
||||||
zRI(op_LLIHL, uint32(p.To.Reg), uint32(v>>32), asm)
|
zRI(op_LLIHL, uint32(p.To.Reg), uint32(v>>32), asm)
|
||||||
} else if uint64(v)&0xffff000000000000 == uint64(v) {
|
} else if uint64(v)&0xffff000000000000 == uint64(v) {
|
||||||
zRI(op_LLIHH, uint32(p.To.Reg), uint32(v>>48), asm)
|
zRI(op_LLIHH, uint32(p.To.Reg), uint32(v>>48), asm)
|
||||||
} else if int64(int16(v)) == v {
|
|
||||||
zRI(op_LGHI, uint32(p.To.Reg), uint32(v), asm)
|
|
||||||
} else if int64(int32(v)) == v {
|
} else if int64(int32(v)) == v {
|
||||||
zRIL(_a, op_LGFI, uint32(p.To.Reg), uint32(v), asm)
|
zRIL(_a, op_LGFI, uint32(p.To.Reg), uint32(v), asm)
|
||||||
} else if int64(uint32(v)) == v {
|
} else if int64(uint32(v)) == v {
|
||||||
@ -2845,7 +2881,6 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
} else {
|
} else {
|
||||||
zRRF(op_SLGRK, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm)
|
zRRF(op_SLGRK, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASUBE:
|
case ASUBE:
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
@ -2860,6 +2895,12 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
zRRE(op_SLBGR, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
zRRE(op_SLBGR, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
||||||
}
|
}
|
||||||
|
case ASUBW:
|
||||||
|
if r == 0 {
|
||||||
|
zRR(op_SR, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
||||||
|
} else {
|
||||||
|
zRRF(op_SRK, uint32(p.From.Reg), 0, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case 11: // br/bl
|
case 11: // br/bl
|
||||||
@ -2905,6 +2946,10 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
addrilreloc(ctxt, p.To.Sym, p.To.Offset)
|
addrilreloc(ctxt, p.To.Sym, p.To.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 17: // move on condition
|
||||||
|
m3 := branchMask(ctxt, p)
|
||||||
|
zRRF(op_LOCGR, m3, 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
|
||||||
|
|
||||||
case 18: // br/bl reg
|
case 18: // br/bl reg
|
||||||
if p.As == ABL {
|
if p.As == ABL {
|
||||||
zRR(op_BASR, uint32(REG_LR), uint32(p.To.Reg), asm)
|
zRR(op_BASR, uint32(REG_LR), uint32(p.To.Reg), asm)
|
||||||
@ -2946,6 +2991,29 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
}
|
}
|
||||||
zRIL(_a, op_ALGFI, uint32(p.To.Reg), uint32(v), asm)
|
zRIL(_a, op_ALGFI, uint32(p.To.Reg), uint32(v), asm)
|
||||||
|
case AADDW:
|
||||||
|
i2 := int32(v)
|
||||||
|
if r == p.To.Reg {
|
||||||
|
zRIL(_a, op_AFI, uint32(p.To.Reg), uint32(i2), asm)
|
||||||
|
} else if int32(int16(i2)) == i2 {
|
||||||
|
zRIE(_d, op_AHIK, uint32(p.To.Reg), uint32(r), uint32(i2), 0, 0, 0, 0, asm)
|
||||||
|
} else {
|
||||||
|
zRR(op_LR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
zRIL(_a, op_AFI, uint32(p.To.Reg), uint32(i2), asm)
|
||||||
|
}
|
||||||
|
case ASUB:
|
||||||
|
zRIL(_a, op_LGFI, uint32(REGTMP), uint32(v), asm)
|
||||||
|
zRRF(op_SLGRK, uint32(REGTMP), 0, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
case ASUBC:
|
||||||
|
if r != p.To.Reg {
|
||||||
|
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
}
|
||||||
|
zRIL(_a, op_SLGFI, uint32(p.To.Reg), uint32(v), asm)
|
||||||
|
case ASUBW:
|
||||||
|
if r != p.To.Reg {
|
||||||
|
zRR(op_LR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
}
|
||||||
|
zRIL(_a, op_SLFI, uint32(p.To.Reg), uint32(v), asm)
|
||||||
case AMULLW, AMULLD:
|
case AMULLW, AMULLD:
|
||||||
if r != p.To.Reg {
|
if r != p.To.Reg {
|
||||||
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_LGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
@ -3009,19 +3077,20 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
zRRF(opcode, uint32(r), 0, uint32(p.To.Reg), REGTMP, asm)
|
zRRF(opcode, uint32(r), 0, uint32(p.To.Reg), REGTMP, asm)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 26: // mov $addr/sym reg
|
case 26: // MOVD $offset(base)(index), reg
|
||||||
v := regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
r := p.From.Reg
|
r := p.From.Reg
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = o.param
|
r = o.param
|
||||||
}
|
}
|
||||||
|
i := p.From.Index
|
||||||
if v >= 0 && v < DISP12 {
|
if v >= 0 && v < DISP12 {
|
||||||
zRX(op_LA, uint32(p.To.Reg), uint32(r), 0, uint32(v), asm)
|
zRX(op_LA, uint32(p.To.Reg), uint32(r), uint32(i), uint32(v), asm)
|
||||||
} else if v >= -DISP20/2 && v < DISP20/2 {
|
} else if v >= -DISP20/2 && v < DISP20/2 {
|
||||||
zRXY(op_LAY, uint32(p.To.Reg), uint32(r), 0, uint32(v), asm)
|
zRXY(op_LAY, uint32(p.To.Reg), uint32(r), uint32(i), uint32(v), asm)
|
||||||
} else {
|
} else {
|
||||||
zRIL(_a, op_LGFI, REGTMP, uint32(v), asm)
|
zRIL(_a, op_LGFI, REGTMP, uint32(v), asm)
|
||||||
zRX(op_LA, uint32(p.To.Reg), uint32(r), REGTMP, 0, asm)
|
zRX(op_LA, uint32(p.To.Reg), uint32(r), REGTMP, uint32(i), asm)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 31: // dword
|
case 31: // dword
|
||||||
@ -3076,6 +3145,8 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
opcode = op_LNDBR
|
opcode = op_LNDBR
|
||||||
case AFNEG:
|
case AFNEG:
|
||||||
opcode = op_LCDFR
|
opcode = op_LCDFR
|
||||||
|
case AFNEGS:
|
||||||
|
opcode = op_LCEBR
|
||||||
case ALEDBR:
|
case ALEDBR:
|
||||||
opcode = op_LEDBR
|
opcode = op_LEDBR
|
||||||
case ALDEBR:
|
case ALDEBR:
|
||||||
@ -3161,51 +3232,49 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 47: // arithmetic op (carry) reg [reg] reg
|
case 47: // arithmetic op (carry) reg [reg] reg
|
||||||
|
r := p.From.Reg
|
||||||
switch p.As {
|
switch p.As {
|
||||||
default:
|
default:
|
||||||
|
|
||||||
case AADDME:
|
case AADDME:
|
||||||
r := int(p.From.Reg)
|
|
||||||
if p.To.Reg == p.From.Reg {
|
if p.To.Reg == p.From.Reg {
|
||||||
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
||||||
r = REGTMP
|
r = REGTMP
|
||||||
}
|
}
|
||||||
zRIL(_a, op_LGFI, uint32(p.To.Reg), 0xffffffff, asm) // p.To.Reg <- -1
|
zRIL(_a, op_LGFI, uint32(p.To.Reg), 0xffffffff, asm) // p.To.Reg <- -1
|
||||||
zRRE(op_ALCGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_ALCGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
|
||||||
case AADDZE:
|
case AADDZE:
|
||||||
r := int(p.From.Reg)
|
|
||||||
if p.To.Reg == p.From.Reg {
|
if p.To.Reg == p.From.Reg {
|
||||||
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
||||||
r = REGTMP
|
r = REGTMP
|
||||||
}
|
}
|
||||||
zRRE(op_LGR, uint32(p.To.Reg), REGZERO, asm) // p.To.Reg <- 0
|
zRI(op_LGHI, uint32(p.To.Reg), 0, asm)
|
||||||
zRRE(op_ALCGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_ALCGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
|
||||||
case ASUBME:
|
case ASUBME:
|
||||||
r := int(p.From.Reg)
|
|
||||||
if p.To.Reg == p.From.Reg {
|
if p.To.Reg == p.From.Reg {
|
||||||
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
||||||
r = REGTMP
|
r = REGTMP
|
||||||
}
|
}
|
||||||
zRIL(_a, op_LGFI, uint32(p.To.Reg), 0xffffffff, asm) // p.To.Reg <- -1
|
zRIL(_a, op_LGFI, uint32(p.To.Reg), 0xffffffff, asm) // p.To.Reg <- -1
|
||||||
zRRE(op_SLBGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_SLBGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
|
||||||
case ASUBZE:
|
case ASUBZE:
|
||||||
r := int(p.From.Reg)
|
|
||||||
if p.To.Reg == p.From.Reg {
|
if p.To.Reg == p.From.Reg {
|
||||||
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
zRRE(op_LGR, REGTMP, uint32(p.From.Reg), asm)
|
||||||
r = REGTMP
|
r = REGTMP
|
||||||
}
|
}
|
||||||
zRRE(op_LGR, uint32(p.To.Reg), REGZERO, asm) // p.To.Reg <- 0
|
zRI(op_LGHI, uint32(p.To.Reg), 0, asm)
|
||||||
zRRE(op_SLBGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_SLBGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
|
||||||
case ANEG:
|
case ANEG:
|
||||||
r := int(p.From.Reg)
|
r := p.From.Reg
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = p.To.Reg
|
||||||
}
|
}
|
||||||
zRRE(op_LCGR, uint32(p.To.Reg), uint32(r), asm)
|
zRRE(op_LCGR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
|
case ANEGW:
|
||||||
|
r := p.From.Reg
|
||||||
|
if r == 0 {
|
||||||
|
r = p.To.Reg
|
||||||
|
}
|
||||||
|
zRRE(op_LCGFR, uint32(p.To.Reg), uint32(r), asm)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 48: // floating-point round to integer
|
case 48: // floating-point round to integer
|
||||||
|
@ -109,13 +109,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
// Rewrite SUB constants into ADD.
|
// Rewrite SUB constants into ADD.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ASUBC:
|
case ASUBC:
|
||||||
if p.From.Type == obj.TYPE_CONST {
|
if p.From.Type == obj.TYPE_CONST && isint32(-p.From.Offset) {
|
||||||
p.From.Offset = -p.From.Offset
|
p.From.Offset = -p.From.Offset
|
||||||
p.As = AADDC
|
p.As = AADDC
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASUB:
|
case ASUB:
|
||||||
if p.From.Type == obj.TYPE_CONST {
|
if p.From.Type == obj.TYPE_CONST && isint32(-p.From.Offset) {
|
||||||
p.From.Offset = -p.From.Offset
|
p.From.Offset = -p.From.Offset
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
}
|
}
|
||||||
@ -258,14 +258,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
p.Link.Mark |= LABEL
|
p.Link.Mark |= LABEL
|
||||||
}
|
}
|
||||||
|
|
||||||
case ANOR:
|
|
||||||
q = p
|
|
||||||
if p.To.Type == obj.TYPE_REG {
|
|
||||||
if p.To.Reg == REGZERO {
|
|
||||||
p.Mark |= LABEL | SYNC
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case ASYNC,
|
case ASYNC,
|
||||||
AWORD:
|
AWORD:
|
||||||
q = p
|
q = p
|
||||||
@ -312,6 +304,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
ABGT,
|
ABGT,
|
||||||
ABLE,
|
ABLE,
|
||||||
ABLT,
|
ABLT,
|
||||||
|
ABLEU,
|
||||||
|
ABLTU,
|
||||||
ABNE,
|
ABNE,
|
||||||
ABR,
|
ABR,
|
||||||
ABVC,
|
ABVC,
|
||||||
@ -401,7 +395,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
|
|
||||||
q = p
|
q = p
|
||||||
|
|
||||||
if p.From3.Offset&obj.NOSPLIT == 0 {
|
if p.From3.Offset&obj.NOSPLIT == 0 && p.From3.Offset&obj.NOFRAME == 0 {
|
||||||
p, pPreempt = stacksplitPre(ctxt, p, autosize) // emit pre part of split check
|
p, pPreempt = stacksplitPre(ctxt, p, autosize) // emit pre part of split check
|
||||||
pPre = p
|
pPre = p
|
||||||
wasSplit = true //need post part of split
|
wasSplit = true //need post part of split
|
||||||
@ -440,7 +434,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||||
//
|
//
|
||||||
// MOVD g_panic(g), R3
|
// MOVD g_panic(g), R3
|
||||||
// CMP R0, R3
|
// CMP R3, $0
|
||||||
// BEQ end
|
// BEQ end
|
||||||
// MOVD panic_argp(R3), R4
|
// MOVD panic_argp(R3), R4
|
||||||
// ADD $(autosize+8), R1, R5
|
// ADD $(autosize+8), R1, R5
|
||||||
@ -466,9 +460,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
|||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = ACMP
|
q.As = ACMP
|
||||||
q.From.Type = obj.TYPE_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REG_R0
|
q.From.Reg = REG_R3
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_CONST
|
||||||
q.To.Reg = REG_R3
|
q.To.Offset = 0
|
||||||
|
|
||||||
q = obj.Appendp(ctxt, q)
|
q = obj.Appendp(ctxt, q)
|
||||||
q.As = ABEQ
|
q.As = ABEQ
|
||||||
@ -993,6 +987,7 @@ var unaryDst = map[obj.As]bool{
|
|||||||
ASTCKE: true,
|
ASTCKE: true,
|
||||||
ASTCKF: true,
|
ASTCKF: true,
|
||||||
ANEG: true,
|
ANEG: true,
|
||||||
|
ANEGW: true,
|
||||||
AVONE: true,
|
AVONE: true,
|
||||||
AVZERO: true,
|
AVZERO: true,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user