mirror of
https://github.com/golang/go.git
synced 2025-05-28 19:02:22 +00:00
s390x doesn't introduce any new assembly syntax. There are a few instructions which require the operands to be reordered, notably the storage-storage instructions that put the length into From3 so that the memory operands can be put into From and To. The assembly test currently covers a subset of instructions but tries to hit edge cases as much as possible. Unlike the other ports it can be linked as an executable to make disassembling it easy. It would be nice to autogenerate it at some point in the future. Change-Id: I7615ac6ecf239e3f347fad9ae1f8eede91742859 Reviewed-on: https://go-review.googlesource.com/20934 Run-TryBot: Rob Pike <r@golang.org> Reviewed-by: Rob Pike <r@golang.org>
140 lines
2.9 KiB
Go
140 lines
2.9 KiB
Go
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// This file encapsulates some of the odd characteristics of the
|
|
// s390x instruction set, to minimize its interaction
|
|
// with the core of the assembler.
|
|
|
|
package arch
|
|
|
|
import (
|
|
"cmd/internal/obj"
|
|
"cmd/internal/obj/s390x"
|
|
)
|
|
|
|
func jumpS390x(word string) bool {
|
|
switch word {
|
|
case "BC",
|
|
"BCL",
|
|
"BEQ",
|
|
"BGE",
|
|
"BGT",
|
|
"BL",
|
|
"BLE",
|
|
"BLT",
|
|
"BNE",
|
|
"BR",
|
|
"BVC",
|
|
"BVS",
|
|
"CMPBEQ",
|
|
"CMPBGE",
|
|
"CMPBGT",
|
|
"CMPBLE",
|
|
"CMPBLT",
|
|
"CMPBNE",
|
|
"CMPUBEQ",
|
|
"CMPUBGE",
|
|
"CMPUBGT",
|
|
"CMPUBLE",
|
|
"CMPUBLT",
|
|
"CMPUBNE",
|
|
"CALL",
|
|
"JMP":
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsS390xRLD reports whether the op (as defined by an s390x.A* constant) is
|
|
// one of the RLD-like instructions that require special handling.
|
|
// The FMADD-like instructions behave similarly.
|
|
func IsS390xRLD(op obj.As) bool {
|
|
switch op {
|
|
case s390x.AFMADD,
|
|
s390x.AFMADDS,
|
|
s390x.AFMSUB,
|
|
s390x.AFMSUBS,
|
|
s390x.AFNMADD,
|
|
s390x.AFNMADDS,
|
|
s390x.AFNMSUB,
|
|
s390x.AFNMSUBS:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsS390xCMP reports whether the op (as defined by an s390x.A* constant) is
|
|
// one of the CMP instructions that require special handling.
|
|
func IsS390xCMP(op obj.As) bool {
|
|
switch op {
|
|
case s390x.ACMP, s390x.ACMPU, s390x.ACMPW, s390x.ACMPWU:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsS390xNEG reports whether the op (as defined by an s390x.A* constant) is
|
|
// one of the NEG-like instructions that require special handling.
|
|
func IsS390xNEG(op obj.As) bool {
|
|
switch op {
|
|
case s390x.AADDME,
|
|
s390x.AADDZE,
|
|
s390x.ANEG,
|
|
s390x.ASUBME,
|
|
s390x.ASUBZE:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsS390xWithLength reports whether the op (as defined by an s390x.A* constant)
|
|
// refers to an instruction which takes a length as its first argument.
|
|
func IsS390xWithLength(op obj.As) bool {
|
|
switch op {
|
|
case s390x.AMVC, s390x.ACLC, s390x.AXC, s390x.AOC, s390x.ANC:
|
|
return true
|
|
case s390x.AVLL, s390x.AVSTL:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsS390xWithIndex reports whether the op (as defined by an s390x.A* constant)
|
|
// refers to an instruction which takes an index as its first argument.
|
|
func IsS390xWithIndex(op obj.As) bool {
|
|
switch op {
|
|
case s390x.AVSCEG, s390x.AVSCEF, s390x.AVGEG, s390x.AVGEF:
|
|
return true
|
|
case s390x.AVGMG, s390x.AVGMF, s390x.AVGMH, s390x.AVGMB:
|
|
return true
|
|
case s390x.AVLEIG, s390x.AVLEIF, s390x.AVLEIH, s390x.AVLEIB:
|
|
return true
|
|
case s390x.AVPDI:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func s390xRegisterNumber(name string, n int16) (int16, bool) {
|
|
switch name {
|
|
case "AR":
|
|
if 0 <= n && n <= 15 {
|
|
return s390x.REG_AR0 + n, true
|
|
}
|
|
case "F":
|
|
if 0 <= n && n <= 15 {
|
|
return s390x.REG_F0 + n, true
|
|
}
|
|
case "R":
|
|
if 0 <= n && n <= 15 {
|
|
return s390x.REG_R0 + n, true
|
|
}
|
|
case "V":
|
|
if 0 <= n && n <= 31 {
|
|
return s390x.REG_V0 + n, true
|
|
}
|
|
}
|
|
return 0, false
|
|
}
|