Commit 13f97ea4 authored by Michael Munday's avatar Michael Munday Committed by Brad Fitzpatrick

cmd/internal/obj/s390x: add s390x support

Based on the ppc64 port.

s390x supports 2, 4 and 6 byte instructions and Go assembly
instructions sometimes map to several s390x instructions. The
assembler loops until a fixed point is reached in order to use
branch instructions that can only handle a short offset in a
similar way to other ports.

Change-Id: I4278bf46aca35a96ca9cea0857e6229643c9c1e3
Reviewed-on: https://go-review.googlesource.com/20942Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 7fc56219
......@@ -44,6 +44,7 @@ var bootstrapDirs = []string{
"internal/obj/arm64",
"internal/obj/mips",
"internal/obj/ppc64",
"internal/obj/s390x",
"internal/obj/x86",
"link",
"link/internal/amd64",
......
// Based on cmd/internal/obj/ppc64/a.out.go.
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package s390x
import "cmd/internal/obj"
//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p s390x
const (
NSNAME = 8
NSYM = 50
NREG = 16 // number of general purpose registers
NFREG = 16 // number of floating point registers
)
const (
// General purpose registers (GPRs).
REG_R0 = obj.RBaseS390X + iota
REG_R1
REG_R2
REG_R3
REG_R4
REG_R5
REG_R6
REG_R7
REG_R8
REG_R9
REG_R10
REG_R11
REG_R12
REG_R13
REG_R14
REG_R15
// Floating point registers (FPRs).
REG_F0
REG_F1
REG_F2
REG_F3
REG_F4
REG_F5
REG_F6
REG_F7
REG_F8
REG_F9
REG_F10
REG_F11
REG_F12
REG_F13
REG_F14
REG_F15
// Vector registers (VRs) - only available when the vector
// facility is installed.
// V0-V15 are aliases for F0-F15.
// We keep them in a separate space to make printing etc. easier
// If the code generator ever emits vector instructions it will
// need to take into account the aliasing.
REG_V0
REG_V1
REG_V2
REG_V3
REG_V4
REG_V5
REG_V6
REG_V7
REG_V8
REG_V9
REG_V10
REG_V11
REG_V12
REG_V13
REG_V14
REG_V15
REG_V16
REG_V17
REG_V18
REG_V19
REG_V20
REG_V21
REG_V22
REG_V23
REG_V24
REG_V25
REG_V26
REG_V27
REG_V28
REG_V29
REG_V30
REG_V31
// Access registers (ARs).
// The thread pointer is typically stored in the register pair
// AR0 and AR1.
REG_AR0
REG_AR1
REG_AR2
REG_AR3
REG_AR4
REG_AR5
REG_AR6
REG_AR7
REG_AR8
REG_AR9
REG_AR10
REG_AR11
REG_AR12
REG_AR13
REG_AR14
REG_AR15
REG_RESERVED // end of allocated registers
REGZERO = REG_R0 // set to zero
REGARG = -1 // -1 disables passing the first argument in register
REGRT1 = REG_R3 // used during zeroing of the stack - not reserved
REGRT2 = REG_R4 // used during zeroing of the stack - not reserved
REGTMP = REG_R10 // scratch register used in the assembler and linker
REGTMP2 = REG_R11 // scratch register used in the assembler and linker
REGCTXT = REG_R12 // context for closures
REGG = REG_R13 // G
REG_LR = REG_R14 // link register
REGSP = REG_R15 // stack pointer
)
const (
BIG = 32768 - 8
DISP12 = 4096
DISP16 = 65536
DISP20 = 1048576
)
const (
// mark flags
LABEL = 1 << 0
LEAF = 1 << 1
FLOAT = 1 << 2
BRANCH = 1 << 3
LOAD = 1 << 4
FCMP = 1 << 5
SYNC = 1 << 6
LIST = 1 << 7
FOLL = 1 << 8
NOSCHED = 1 << 9
)
const ( // comments from func aclass in asmz.go
C_NONE = iota
C_REG // general-purpose register (64-bit)
C_FREG // floating-point register (64-bit)
C_VREG // vector register (128-bit)
C_AREG // access register (32-bit)
C_ZCON // constant == 0
C_SCON // 0 <= constant <= 0x7fff (positive int16)
C_UCON // constant & 0xffff == 0 (int16 or uint16)
C_ADDCON // 0 > constant >= -0x8000 (negative int16)
C_ANDCON // constant <= 0xffff
C_LCON // constant (int32 or uint32)
C_DCON // constant (int64 or uint64)
C_SACON // computed address, 16-bit displacement, possibly SP-relative
C_LACON // computed address, 32-bit displacement, possibly SP-relative
C_DACON // computed address, 64-bit displacment?
C_SBRA // short branch
C_LBRA // long branch
C_SAUTO // short auto
C_LAUTO // long auto
C_ZOREG // heap address, register-based, displacement == 0
C_SOREG // heap address, register-based, int16 displacement
C_LOREG // heap address, register-based, int32 displacement
C_TLS_LE // TLS - local exec model (for executables)
C_TLS_IE // TLS - initial exec model (for shared libraries loaded at program startup)
C_GOK // general address
C_ADDR // relocation for extern or static symbols (loads and stores)
C_SYMADDR // relocation for extern or static symbols (address taking)
C_GOTADDR // GOT slot for a symbol in -dynlink mode
C_TEXTSIZE // text size
C_ANY
C_NCLASS // must be the last
)
const (
// integer arithmetic
AADD = obj.ABaseS390X + obj.A_ARCHSPECIFIC + iota
AADDC
AADDME
AADDE
AADDZE
ADIVW
ADIVWU
ADIVD
ADIVDU
AMULLW
AMULLD
AMULHDU
ASUB
ASUBC
ASUBME
ASUBV
ASUBE
ASUBZE
ANEG
// integer moves
AMOVWBR
AMOVB
AMOVBZ
AMOVH
AMOVHBR
AMOVHZ
AMOVW
AMOVWZ
AMOVD
AMOVDBR
// integer bitwise
AAND
AANDN
ANAND
ANOR
AOR
AORN
AXOR
ASLW
ASLD
ASRW
ASRAW
ASRD
ASRAD
ARLL
ARLLG
// floating point
AFABS
AFADD
AFADDS
AFCMPO
AFCMPU
ACEBR
AFDIV
AFDIVS
AFMADD
AFMADDS
AFMOVD
AFMOVS
AFMSUB
AFMSUBS
AFMUL
AFMULS
AFNABS
AFNEG
AFNMADD
AFNMADDS
AFNMSUB
AFNMSUBS
ALEDBR
ALDEBR
AFSUB
AFSUBS
AFSQRT
AFSQRTS
// convert from int32/int64 to float/float64
ACEFBRA
ACDFBRA
ACEGBRA
ACDGBRA
// convert from float/float64 to int32/int64
ACFEBRA
ACFDBRA
ACGEBRA
ACGDBRA
// convert from uint32/uint64 to float/float64
ACELFBR
ACDLFBR
ACELGBR
ACDLGBR
// convert from float/float64 to uint32/uint64
ACLFEBR
ACLFDBR
ACLGEBR
ACLGDBR
// compare
ACMP
ACMPU
ACMPW
ACMPWU
// compare and swap
ACS
ACSG
// serialize
ASYNC
// branch
ABC
ABCL
ABEQ
ABGE
ABGT
ABLE
ABLT
ABNE
ABVC
ABVS
ASYSCALL
// compare and branch
ACMPBEQ
ACMPBGE
ACMPBGT
ACMPBLE
ACMPBLT
ACMPBNE
ACMPUBEQ
ACMPUBGE
ACMPUBGT
ACMPUBLE
ACMPUBLT
ACMPUBNE
// storage-and-storage
AMVC
ACLC
AXC
AOC
ANC
// load
AEXRL
ALARL
ALA
ALAY
// load/store multiple
ALMY
ALMG
ASTMY
ASTMG
// store clock
ASTCK
ASTCKC
ASTCKE
ASTCKF
// macros
ACLEAR
// vector
AVA
AVAB
AVAH
AVAF
AVAG
AVAQ
AVACC
AVACCB
AVACCH
AVACCF
AVACCG
AVACCQ
AVAC
AVACQ
AVACCC
AVACCCQ
AVN
AVNC
AVAVG
AVAVGB
AVAVGH
AVAVGF
AVAVGG
AVAVGL
AVAVGLB
AVAVGLH
AVAVGLF
AVAVGLG
AVCKSM
AVCEQ
AVCEQB
AVCEQH
AVCEQF
AVCEQG
AVCEQBS
AVCEQHS
AVCEQFS
AVCEQGS
AVCH
AVCHB
AVCHH
AVCHF
AVCHG
AVCHBS
AVCHHS
AVCHFS
AVCHGS
AVCHL
AVCHLB
AVCHLH
AVCHLF
AVCHLG
AVCHLBS
AVCHLHS
AVCHLFS
AVCHLGS
AVCLZ
AVCLZB
AVCLZH
AVCLZF
AVCLZG
AVCTZ
AVCTZB
AVCTZH
AVCTZF
AVCTZG
AVEC
AVECB
AVECH
AVECF
AVECG
AVECL
AVECLB
AVECLH
AVECLF
AVECLG
AVERIM
AVERIMB
AVERIMH
AVERIMF
AVERIMG
AVERLL
AVERLLB
AVERLLH
AVERLLF
AVERLLG
AVERLLV
AVERLLVB
AVERLLVH
AVERLLVF
AVERLLVG
AVESLV
AVESLVB
AVESLVH
AVESLVF
AVESLVG
AVESL
AVESLB
AVESLH
AVESLF
AVESLG
AVESRA
AVESRAB
AVESRAH
AVESRAF
AVESRAG
AVESRAV
AVESRAVB
AVESRAVH
AVESRAVF
AVESRAVG
AVESRL
AVESRLB
AVESRLH
AVESRLF
AVESRLG
AVESRLV
AVESRLVB
AVESRLVH
AVESRLVF
AVESRLVG
AVX
AVFAE
AVFAEB
AVFAEH
AVFAEF
AVFAEBS
AVFAEHS
AVFAEFS
AVFAEZB
AVFAEZH
AVFAEZF
AVFAEZBS
AVFAEZHS
AVFAEZFS
AVFEE
AVFEEB
AVFEEH
AVFEEF
AVFEEBS
AVFEEHS
AVFEEFS
AVFEEZB
AVFEEZH
AVFEEZF
AVFEEZBS
AVFEEZHS
AVFEEZFS
AVFENE
AVFENEB
AVFENEH
AVFENEF
AVFENEBS
AVFENEHS
AVFENEFS
AVFENEZB
AVFENEZH
AVFENEZF
AVFENEZBS
AVFENEZHS
AVFENEZFS
AVFA
AVFADB
AWFADB
AWFK
AWFKDB
AVFCE
AVFCEDB
AVFCEDBS
AWFCEDB
AWFCEDBS
AVFCH
AVFCHDB
AVFCHDBS
AWFCHDB
AWFCHDBS
AVFCHE
AVFCHEDB
AVFCHEDBS
AWFCHEDB
AWFCHEDBS
AWFC
AWFCDB
AVCDG
AVCDGB
AWCDGB
AVCDLG
AVCDLGB
AWCDLGB
AVCGD
AVCGDB
AWCGDB
AVCLGD
AVCLGDB
AWCLGDB
AVFD
AVFDDB
AWFDDB
AVLDE
AVLDEB
AWLDEB
AVLED
AVLEDB
AWLEDB
AVFM
AVFMDB
AWFMDB
AVFMA
AVFMADB
AWFMADB
AVFMS
AVFMSDB
AWFMSDB
AVFPSO
AVFPSODB
AWFPSODB
AVFLCDB
AWFLCDB
AVFLNDB
AWFLNDB
AVFLPDB
AWFLPDB
AVFSQ
AVFSQDB
AWFSQDB
AVFS
AVFSDB
AWFSDB
AVFTCI
AVFTCIDB
AWFTCIDB
AVGFM
AVGFMB
AVGFMH
AVGFMF
AVGFMG
AVGFMA
AVGFMAB
AVGFMAH
AVGFMAF
AVGFMAG
AVGEF
AVGEG
AVGBM
AVZERO
AVONE
AVGM
AVGMB
AVGMH
AVGMF
AVGMG
AVISTR
AVISTRB
AVISTRH
AVISTRF
AVISTRBS
AVISTRHS
AVISTRFS
AVL
AVLR
AVLREP
AVLREPB
AVLREPH
AVLREPF
AVLREPG
AVLC
AVLCB
AVLCH
AVLCF
AVLCG
AVLEH
AVLEF
AVLEG
AVLEB
AVLEIH
AVLEIF
AVLEIG
AVLEIB
AVFI
AVFIDB
AWFIDB
AVLGV
AVLGVB
AVLGVH
AVLGVF
AVLGVG
AVLLEZ
AVLLEZB
AVLLEZH
AVLLEZF
AVLLEZG
AVLM
AVLP
AVLPB
AVLPH
AVLPF
AVLPG
AVLBB
AVLVG
AVLVGB
AVLVGH
AVLVGF
AVLVGG
AVLVGP
AVLL
AVMX
AVMXB
AVMXH
AVMXF
AVMXG
AVMXL
AVMXLB
AVMXLH
AVMXLF
AVMXLG
AVMRH
AVMRHB
AVMRHH
AVMRHF
AVMRHG
AVMRL
AVMRLB
AVMRLH
AVMRLF
AVMRLG
AVMN
AVMNB
AVMNH
AVMNF
AVMNG
AVMNL
AVMNLB
AVMNLH
AVMNLF
AVMNLG
AVMAE
AVMAEB
AVMAEH
AVMAEF
AVMAH
AVMAHB
AVMAHH
AVMAHF
AVMALE
AVMALEB
AVMALEH
AVMALEF
AVMALH
AVMALHB
AVMALHH
AVMALHF
AVMALO
AVMALOB
AVMALOH
AVMALOF
AVMAL
AVMALB
AVMALHW
AVMALF
AVMAO
AVMAOB
AVMAOH
AVMAOF
AVME
AVMEB
AVMEH
AVMEF
AVMH
AVMHB
AVMHH
AVMHF
AVMLE
AVMLEB
AVMLEH
AVMLEF
AVMLH
AVMLHB
AVMLHH
AVMLHF
AVMLO
AVMLOB
AVMLOH
AVMLOF
AVML
AVMLB
AVMLHW
AVMLF
AVMO
AVMOB
AVMOH
AVMOF
AVNO
AVNOT
AVO
AVPK
AVPKH
AVPKF
AVPKG
AVPKLS
AVPKLSH
AVPKLSF
AVPKLSG
AVPKLSHS
AVPKLSFS
AVPKLSGS
AVPKS
AVPKSH
AVPKSF
AVPKSG
AVPKSHS
AVPKSFS
AVPKSGS
AVPERM
AVPDI
AVPOPCT
AVREP
AVREPB
AVREPH
AVREPF
AVREPG
AVREPI
AVREPIB
AVREPIH
AVREPIF
AVREPIG
AVSCEF
AVSCEG
AVSEL
AVSL
AVSLB
AVSLDB
AVSRA
AVSRAB
AVSRL
AVSRLB
AVSEG
AVSEGB
AVSEGH
AVSEGF
AVST
AVSTEH
AVSTEF
AVSTEG
AVSTEB
AVSTM
AVSTL
AVSTRC
AVSTRCB
AVSTRCH
AVSTRCF
AVSTRCBS
AVSTRCHS
AVSTRCFS
AVSTRCZB
AVSTRCZH
AVSTRCZF
AVSTRCZBS
AVSTRCZHS
AVSTRCZFS
AVS
AVSB
AVSH
AVSF
AVSG
AVSQ
AVSCBI
AVSCBIB
AVSCBIH
AVSCBIF
AVSCBIG
AVSCBIQ
AVSBCBI
AVSBCBIQ
AVSBI
AVSBIQ
AVSUMG
AVSUMGH
AVSUMGF
AVSUMQ
AVSUMQF
AVSUMQG
AVSUM
AVSUMB
AVSUMH
AVTM
AVUPH
AVUPHB
AVUPHH
AVUPHF
AVUPLH
AVUPLHB
AVUPLHH
AVUPLHF
AVUPLL
AVUPLLB
AVUPLLH
AVUPLLF
AVUPL
AVUPLB
AVUPLHW
AVUPLF
// binary
ABYTE
AWORD
ADWORD
// end marker
ALAST
// aliases
ABR = obj.AJMP
ABL = obj.ACALL
)
// Generated by stringer -i a.out.go -o anames.go -p s390x
// Do not edit.
package s390x
import "cmd/internal/obj"
var Anames = []string{
obj.A_ARCHSPECIFIC: "ADD",
"ADDC",
"ADDME",
"ADDE",
"ADDZE",
"DIVW",
"DIVWU",
"DIVD",
"DIVDU",
"MULLW",
"MULLD",
"MULHDU",
"SUB",
"SUBC",
"SUBME",
"SUBV",
"SUBE",
"SUBZE",
"NEG",
"MOVWBR",
"MOVB",
"MOVBZ",
"MOVH",
"MOVHBR",
"MOVHZ",
"MOVW",
"MOVWZ",
"MOVD",
"MOVDBR",
"AND",
"ANDN",
"NAND",
"NOR",
"OR",
"ORN",
"XOR",
"SLW",
"SLD",
"SRW",
"SRAW",
"SRD",
"SRAD",
"RLL",
"RLLG",
"FABS",
"FADD",
"FADDS",
"FCMPO",
"FCMPU",
"CEBR",
"FDIV",
"FDIVS",
"FMADD",
"FMADDS",
"FMOVD",
"FMOVS",
"FMSUB",
"FMSUBS",
"FMUL",
"FMULS",
"FNABS",
"FNEG",
"FNMADD",
"FNMADDS",
"FNMSUB",
"FNMSUBS",
"LEDBR",
"LDEBR",
"FSUB",
"FSUBS",
"FSQRT",
"FSQRTS",
"CEFBRA",
"CDFBRA",
"CEGBRA",
"CDGBRA",
"CFEBRA",
"CFDBRA",
"CGEBRA",
"CGDBRA",
"CELFBR",
"CDLFBR",
"CELGBR",
"CDLGBR",
"CLFEBR",
"CLFDBR",
"CLGEBR",
"CLGDBR",
"CMP",
"CMPU",
"CMPW",
"CMPWU",
"CS",
"CSG",
"SYNC",
"BC",
"BCL",
"BEQ",
"BGE",
"BGT",
"BLE",
"BLT",
"BNE",
"BVC",
"BVS",
"SYSCALL",
"CMPBEQ",
"CMPBGE",
"CMPBGT",
"CMPBLE",
"CMPBLT",
"CMPBNE",
"CMPUBEQ",
"CMPUBGE",
"CMPUBGT",
"CMPUBLE",
"CMPUBLT",
"CMPUBNE",
"MVC",
"CLC",
"XC",
"OC",
"NC",
"EXRL",
"LARL",
"LA",
"LAY",
"LMY",
"LMG",
"STMY",
"STMG",
"STCK",
"STCKC",
"STCKE",
"STCKF",
"CLEAR",
"VA",
"VAB",
"VAH",
"VAF",
"VAG",
"VAQ",
"VACC",
"VACCB",
"VACCH",
"VACCF",
"VACCG",
"VACCQ",
"VAC",
"VACQ",
"VACCC",
"VACCCQ",
"VN",
"VNC",
"VAVG",
"VAVGB",
"VAVGH",
"VAVGF",
"VAVGG",
"VAVGL",
"VAVGLB",
"VAVGLH",
"VAVGLF",
"VAVGLG",
"VCKSM",
"VCEQ",
"VCEQB",
"VCEQH",
"VCEQF",
"VCEQG",
"VCEQBS",
"VCEQHS",
"VCEQFS",
"VCEQGS",
"VCH",
"VCHB",
"VCHH",
"VCHF",
"VCHG",
"VCHBS",
"VCHHS",
"VCHFS",
"VCHGS",
"VCHL",
"VCHLB",
"VCHLH",
"VCHLF",
"VCHLG",
"VCHLBS",
"VCHLHS",
"VCHLFS",
"VCHLGS",
"VCLZ",
"VCLZB",
"VCLZH",
"VCLZF",
"VCLZG",
"VCTZ",
"VCTZB",
"VCTZH",
"VCTZF",
"VCTZG",
"VEC",
"VECB",
"VECH",
"VECF",
"VECG",
"VECL",
"VECLB",
"VECLH",
"VECLF",
"VECLG",
"VERIM",
"VERIMB",
"VERIMH",
"VERIMF",
"VERIMG",
"VERLL",
"VERLLB",
"VERLLH",
"VERLLF",
"VERLLG",
"VERLLV",
"VERLLVB",
"VERLLVH",
"VERLLVF",
"VERLLVG",
"VESLV",
"VESLVB",
"VESLVH",
"VESLVF",
"VESLVG",
"VESL",
"VESLB",
"VESLH",
"VESLF",
"VESLG",
"VESRA",
"VESRAB",
"VESRAH",
"VESRAF",
"VESRAG",
"VESRAV",
"VESRAVB",
"VESRAVH",
"VESRAVF",
"VESRAVG",
"VESRL",
"VESRLB",
"VESRLH",
"VESRLF",
"VESRLG",
"VESRLV",
"VESRLVB",
"VESRLVH",
"VESRLVF",
"VESRLVG",
"VX",
"VFAE",
"VFAEB",
"VFAEH",
"VFAEF",
"VFAEBS",
"VFAEHS",
"VFAEFS",
"VFAEZB",
"VFAEZH",
"VFAEZF",
"VFAEZBS",
"VFAEZHS",
"VFAEZFS",
"VFEE",
"VFEEB",
"VFEEH",
"VFEEF",
"VFEEBS",
"VFEEHS",
"VFEEFS",
"VFEEZB",
"VFEEZH",
"VFEEZF",
"VFEEZBS",
"VFEEZHS",
"VFEEZFS",
"VFENE",
"VFENEB",
"VFENEH",
"VFENEF",
"VFENEBS",
"VFENEHS",
"VFENEFS",
"VFENEZB",
"VFENEZH",
"VFENEZF",
"VFENEZBS",
"VFENEZHS",
"VFENEZFS",
"VFA",
"VFADB",
"WFADB",
"WFK",
"WFKDB",
"VFCE",
"VFCEDB",
"VFCEDBS",
"WFCEDB",
"WFCEDBS",
"VFCH",
"VFCHDB",
"VFCHDBS",
"WFCHDB",
"WFCHDBS",
"VFCHE",
"VFCHEDB",
"VFCHEDBS",
"WFCHEDB",
"WFCHEDBS",
"WFC",
"WFCDB",
"VCDG",
"VCDGB",
"WCDGB",
"VCDLG",
"VCDLGB",
"WCDLGB",
"VCGD",
"VCGDB",
"WCGDB",
"VCLGD",
"VCLGDB",
"WCLGDB",
"VFD",
"VFDDB",
"WFDDB",
"VLDE",
"VLDEB",
"WLDEB",
"VLED",
"VLEDB",
"WLEDB",
"VFM",
"VFMDB",
"WFMDB",
"VFMA",
"VFMADB",
"WFMADB",
"VFMS",
"VFMSDB",
"WFMSDB",
"VFPSO",
"VFPSODB",
"WFPSODB",
"VFLCDB",
"WFLCDB",
"VFLNDB",
"WFLNDB",
"VFLPDB",
"WFLPDB",
"VFSQ",
"VFSQDB",
"WFSQDB",
"VFS",
"VFSDB",
"WFSDB",
"VFTCI",
"VFTCIDB",
"WFTCIDB",
"VGFM",
"VGFMB",
"VGFMH",
"VGFMF",
"VGFMG",
"VGFMA",
"VGFMAB",
"VGFMAH",
"VGFMAF",
"VGFMAG",
"VGEF",
"VGEG",
"VGBM",
"VZERO",
"VONE",
"VGM",
"VGMB",
"VGMH",
"VGMF",
"VGMG",
"VISTR",
"VISTRB",
"VISTRH",
"VISTRF",
"VISTRBS",
"VISTRHS",
"VISTRFS",
"VL",
"VLR",
"VLREP",
"VLREPB",
"VLREPH",
"VLREPF",
"VLREPG",
"VLC",
"VLCB",
"VLCH",
"VLCF",
"VLCG",
"VLEH",
"VLEF",
"VLEG",
"VLEB",
"VLEIH",
"VLEIF",
"VLEIG",
"VLEIB",
"VFI",
"VFIDB",
"WFIDB",
"VLGV",
"VLGVB",
"VLGVH",
"VLGVF",
"VLGVG",
"VLLEZ",
"VLLEZB",
"VLLEZH",
"VLLEZF",
"VLLEZG",
"VLM",
"VLP",
"VLPB",
"VLPH",
"VLPF",
"VLPG",
"VLBB",
"VLVG",
"VLVGB",
"VLVGH",
"VLVGF",
"VLVGG",
"VLVGP",
"VLL",
"VMX",
"VMXB",
"VMXH",
"VMXF",
"VMXG",
"VMXL",
"VMXLB",
"VMXLH",
"VMXLF",
"VMXLG",
"VMRH",
"VMRHB",
"VMRHH",
"VMRHF",
"VMRHG",
"VMRL",
"VMRLB",
"VMRLH",
"VMRLF",
"VMRLG",
"VMN",
"VMNB",
"VMNH",
"VMNF",
"VMNG",
"VMNL",
"VMNLB",
"VMNLH",
"VMNLF",
"VMNLG",
"VMAE",
"VMAEB",
"VMAEH",
"VMAEF",
"VMAH",
"VMAHB",
"VMAHH",
"VMAHF",
"VMALE",
"VMALEB",
"VMALEH",
"VMALEF",
"VMALH",
"VMALHB",
"VMALHH",
"VMALHF",
"VMALO",
"VMALOB",
"VMALOH",
"VMALOF",
"VMAL",
"VMALB",
"VMALHW",
"VMALF",
"VMAO",
"VMAOB",
"VMAOH",
"VMAOF",
"VME",
"VMEB",
"VMEH",
"VMEF",
"VMH",
"VMHB",
"VMHH",
"VMHF",
"VMLE",
"VMLEB",
"VMLEH",
"VMLEF",
"VMLH",
"VMLHB",
"VMLHH",
"VMLHF",
"VMLO",
"VMLOB",
"VMLOH",
"VMLOF",
"VML",
"VMLB",
"VMLHW",
"VMLF",
"VMO",
"VMOB",
"VMOH",
"VMOF",
"VNO",
"VNOT",
"VO",
"VPK",
"VPKH",
"VPKF",
"VPKG",
"VPKLS",
"VPKLSH",
"VPKLSF",
"VPKLSG",
"VPKLSHS",
"VPKLSFS",
"VPKLSGS",
"VPKS",
"VPKSH",
"VPKSF",
"VPKSG",
"VPKSHS",
"VPKSFS",
"VPKSGS",
"VPERM",
"VPDI",
"VPOPCT",
"VREP",
"VREPB",
"VREPH",
"VREPF",
"VREPG",
"VREPI",
"VREPIB",
"VREPIH",
"VREPIF",
"VREPIG",
"VSCEF",
"VSCEG",
"VSEL",
"VSL",
"VSLB",
"VSLDB",
"VSRA",
"VSRAB",
"VSRL",
"VSRLB",
"VSEG",
"VSEGB",
"VSEGH",
"VSEGF",
"VST",
"VSTEH",
"VSTEF",
"VSTEG",
"VSTEB",
"VSTM",
"VSTL",
"VSTRC",
"VSTRCB",
"VSTRCH",
"VSTRCF",
"VSTRCBS",
"VSTRCHS",
"VSTRCFS",
"VSTRCZB",
"VSTRCZH",
"VSTRCZF",
"VSTRCZBS",
"VSTRCZHS",
"VSTRCZFS",
"VS",
"VSB",
"VSH",
"VSF",
"VSG",
"VSQ",
"VSCBI",
"VSCBIB",
"VSCBIH",
"VSCBIF",
"VSCBIG",
"VSCBIQ",
"VSBCBI",
"VSBCBIQ",
"VSBI",
"VSBIQ",
"VSUMG",
"VSUMGH",
"VSUMGF",
"VSUMQ",
"VSUMQF",
"VSUMQG",
"VSUM",
"VSUMB",
"VSUMH",
"VTM",
"VUPH",
"VUPHB",
"VUPHH",
"VUPHF",
"VUPLH",
"VUPLHB",
"VUPLHH",
"VUPLHF",
"VUPLL",
"VUPLLB",
"VUPLLH",
"VUPLLF",
"VUPL",
"VUPLB",
"VUPLHW",
"VUPLF",
"BYTE",
"WORD",
"DWORD",
"LAST",
}
// 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.
package s390x
var cnamesz = []string{
"NONE",
"REG",
"FREG",
"VREG",
"AREG",
"ZCON",
"SCON",
"UCON",
"ADDCON",
"ANDCON",
"LCON",
"DCON",
"SACON",
"LACON",
"DACON",
"SBRA",
"LBRA",
"SAUTO",
"LAUTO",
"ZOREG",
"SOREG",
"LOREG",
"TLS_LE",
"TLS_IE",
"GOK",
"ADDR",
"SYMADDR",
"GOTADDR",
"TEXTSIZE",
"ANY",
"NCLASS",
}
This source diff could not be displayed because it is too large. You can view the blob instead.
// Based on cmd/internal/obj/ppc64/list9.go.
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package s390x
import (
"cmd/internal/obj"
"fmt"
)
func init() {
obj.RegisterRegister(obj.RBaseS390X, REG_R0+1024, Rconv)
obj.RegisterOpcode(obj.ABaseS390X, Anames)
}
func Rconv(r int) string {
if r == 0 {
return "NONE"
}
if r == REGG {
// Special case.
return "g"
}
if REG_R0 <= r && r <= REG_R15 {
return fmt.Sprintf("R%d", r-REG_R0)
}
if REG_F0 <= r && r <= REG_F15 {
return fmt.Sprintf("F%d", r-REG_F0)
}
if REG_AR0 <= r && r <= REG_AR15 {
return fmt.Sprintf("AR%d", r-REG_AR0)
}
if REG_V0 <= r && r <= REG_V31 {
return fmt.Sprintf("V%d", r-REG_V0)
}
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseS390X)
}
func DRconv(a int) string {
s := "C_??"
if a >= C_NONE && a <= C_NCLASS {
s = cnamesz[a]
}
var fp string
fp += s
return fp
}
// Based on cmd/internal/obj/ppc64/obj9.go.
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package s390x
import (
"cmd/internal/obj"
"encoding/binary"
"fmt"
"math"
)
func progedit(ctxt *obj.Link, p *obj.Prog) {
p.From.Class = 0
p.To.Class = 0
// Rewrite BR/BL to symbol as TYPE_BRANCH.
switch p.As {
case ABR,
ABL,
obj.ARET,
obj.ADUFFZERO,
obj.ADUFFCOPY:
if p.To.Sym != nil {
p.To.Type = obj.TYPE_BRANCH
}
}
// Rewrite float constants to values stored in memory unless they are +0.
switch p.As {
case AFMOVS:
if p.From.Type == obj.TYPE_FCONST {
f32 := float32(p.From.Val.(float64))
i32 := math.Float32bits(f32)
if i32 == 0 { // +0
break
}
literal := fmt.Sprintf("$f32.%08x", i32)
s := obj.Linklookup(ctxt, literal, 0)
s.Size = 4
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Sym.Local = true
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
case AFMOVD:
if p.From.Type == obj.TYPE_FCONST {
i64 := math.Float64bits(p.From.Val.(float64))
if i64 == 0 { // +0
break
}
literal := fmt.Sprintf("$f64.%016x", i64)
s := obj.Linklookup(ctxt, literal, 0)
s.Size = 8
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Sym.Local = true
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
// put constants not loadable by LOAD IMMEDIATE into memory
case AMOVD:
if p.From.Type == obj.TYPE_CONST {
val := p.From.Offset
if int64(int32(val)) != val &&
int64(uint32(val)) != val &&
int64(uint64(val)&(0xffffffff<<32)) != val {
literal := fmt.Sprintf("$i64.%016x", uint64(p.From.Offset))
s := obj.Linklookup(ctxt, literal, 0)
s.Size = 8
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Sym.Local = true
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
}
}
// Rewrite SUB constants into ADD.
switch p.As {
case ASUBC:
if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset
p.As = AADDC
}
case ASUB:
if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset
p.As = AADD
}
}
if ctxt.Flag_dynlink {
rewriteToUseGot(ctxt, p)
}
}
// Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
// At the moment EXRL instructions are not emitted by the compiler and only reference local symbols in
// assembly code.
if p.As == AEXRL {
return
}
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
if p.To.Type != obj.TYPE_REG || p.As != AMOVD {
ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
}
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF
q := p
if p.From.Offset != 0 {
q = obj.Appendp(ctxt, p)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset
q.To = p.To
p.From.Offset = 0
}
}
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
var source *obj.Addr
// MOVD sym, Ry becomes MOVD sym@GOT, REGTMP; MOVD (REGTMP), Ry
// MOVD Ry, sym becomes MOVD sym@GOT, REGTMP; MOVD Ry, (REGTMP)
// An addition may be inserted between the two MOVs if there is an offset.
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
source = &p.To
} else {
return
}
if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
return
}
if source.Sym.Type == obj.STLSBSS {
return
}
if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
p1 := obj.Appendp(ctxt, p)
p2 := obj.Appendp(ctxt, p1)
p1.As = AMOVD
p1.From.Type = obj.TYPE_MEM
p1.From.Sym = source.Sym
p1.From.Name = obj.NAME_GOTREF
p1.To.Type = obj.TYPE_REG
p1.To.Reg = REGTMP
p2.As = p.As
p2.From = p.From
p2.To = p.To
if p.From.Name == obj.NAME_EXTERN {
p2.From.Reg = REGTMP
p2.From.Name = obj.NAME_NONE
p2.From.Sym = nil
} else if p.To.Name == obj.NAME_EXTERN {
p2.To.Reg = REGTMP
p2.To.Name = obj.NAME_NONE
p2.To.Sym = nil
} else {
return
}
obj.Nopout(p)
}
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// TODO(minux): add morestack short-cuts with small fixed frame-size.
ctxt.Cursym = cursym
if cursym.Text == nil || cursym.Text.Link == nil {
return
}
p := cursym.Text
textstksiz := p.To.Offset
if textstksiz == -8 {
// Compatibility hack.
p.From3.Offset |= obj.NOFRAME
textstksiz = 0
}
if textstksiz%8 != 0 {
ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
}
if p.From3.Offset&obj.NOFRAME != 0 {
if textstksiz != 0 {
ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
}
}
cursym.Args = p.To.Val.(int32)
cursym.Locals = int32(textstksiz)
/*
* find leaf subroutines
* strip NOPs
* expand RET
* expand BECOME pseudo
*/
if ctxt.Debugvlog != 0 {
fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime())
}
ctxt.Bso.Flush()
var q *obj.Prog
var q1 *obj.Prog
for p := cursym.Text; p != nil; p = p.Link {
switch p.As {
/* too hard, just leave alone */
case obj.ATEXT:
q = p
p.Mark |= LABEL | LEAF | SYNC
if p.Link != nil {
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,
AWORD:
q = p
p.Mark |= LABEL | SYNC
continue
case AMOVW, AMOVWZ, AMOVD:
q = p
if p.From.Reg >= REG_RESERVED || p.To.Reg >= REG_RESERVED {
p.Mark |= LABEL | SYNC
}
continue
case AFABS,
AFADD,
AFDIV,
AFMADD,
AFMOVD,
AFMOVS,
AFMSUB,
AFMUL,
AFNABS,
AFNEG,
AFNMADD,
AFNMSUB,
ALEDBR,
ALDEBR,
AFSUB:
q = p
p.Mark |= FLOAT
continue
case ABL,
ABCL,
obj.ADUFFZERO,
obj.ADUFFCOPY:
cursym.Text.Mark &^= LEAF
fallthrough
case ABC,
ABEQ,
ABGE,
ABGT,
ABLE,
ABLT,
ABNE,
ABR,
ABVC,
ABVS,
ACMPBEQ,
ACMPBGE,
ACMPBGT,
ACMPBLE,
ACMPBLT,
ACMPBNE,
ACMPUBEQ,
ACMPUBGE,
ACMPUBGT,
ACMPUBLE,
ACMPUBLT,
ACMPUBNE:
p.Mark |= BRANCH
q = p
q1 = p.Pcond
if q1 != nil {
for q1.As == obj.ANOP {
q1 = q1.Link
p.Pcond = q1
}
if q1.Mark&LEAF == 0 {
q1.Mark |= LABEL
}
} else {
p.Mark |= LABEL
}
q1 = p.Link
if q1 != nil {
q1.Mark |= LABEL
}
continue
case AFCMPO, AFCMPU:
q = p
p.Mark |= FCMP | FLOAT
continue
case obj.ARET:
q = p
if p.Link != nil {
p.Link.Mark |= LABEL
}
continue
case obj.ANOP:
q1 = p.Link
q.Link = q1 /* q is non-nop */
q1.Mark |= p.Mark
continue
default:
q = p
continue
}
}
autosize := int32(0)
var p1 *obj.Prog
var p2 *obj.Prog
var pLast *obj.Prog
var pPre *obj.Prog
var pPreempt *obj.Prog
wasSplit := false
for p := cursym.Text; p != nil; p = p.Link {
pLast = p
switch p.As {
case obj.ATEXT:
autosize = int32(textstksiz)
if p.Mark&LEAF != 0 && autosize == 0 && p.From3.Offset&obj.NOFRAME == 0 {
// A leaf function with no locals has no frame.
p.From3.Offset |= obj.NOFRAME
}
if p.From3.Offset&obj.NOFRAME == 0 {
// If there is a stack frame at all, it includes
// space to save the LR.
autosize += int32(ctxt.FixedFrameSize())
}
p.To.Offset = int64(autosize)
q = p
if p.From3.Offset&obj.NOSPLIT == 0 {
p, pPreempt = stacksplitPre(ctxt, p, autosize) // emit pre part of split check
pPre = p
wasSplit = true //need post part of split
}
if autosize != 0 {
q = obj.Appendp(ctxt, p)
q.As = AMOVD
q.From.Type = obj.TYPE_ADDR
q.From.Offset = int64(-autosize)
q.From.Reg = REGSP // not actually needed - REGSP is assumed if no reg is provided
q.To.Type = obj.TYPE_REG
q.To.Reg = REGSP
q.Spadj = autosize
} else if cursym.Text.Mark&LEAF == 0 {
// A very few functions that do not return to their caller
// (e.g. gogo) are not identified as leaves but still have
// no frame.
cursym.Text.Mark |= LEAF
}
if cursym.Text.Mark&LEAF != 0 {
cursym.Leaf = true
break
}
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_LR
q.To.Type = obj.TYPE_MEM
q.To.Reg = REGSP
q.To.Offset = 0
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
//
// MOVD g_panic(g), R3
// CMP R0, R3
// BEQ end
// MOVD panic_argp(R3), R4
// ADD $(autosize+8), R1, R5
// CMP R4, R5
// BNE end
// ADD $8, R1, R6
// MOVD R6, panic_argp(R3)
// end:
// NOP
//
// The NOP is needed to give the jumps somewhere to land.
// It is a liblink NOP, not a s390x NOP: it encodes to 0 instruction bytes.
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q)
q.As = ACMP
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R0
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q)
q.As = ABEQ
q.To.Type = obj.TYPE_BRANCH
p1 = q
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R3
q.From.Offset = 0 // Panic.argp
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R4
q = obj.Appendp(ctxt, q)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
q.Reg = REGSP
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q)
q.As = ACMP
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R4
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q)
q.As = ABNE
q.To.Type = obj.TYPE_BRANCH
p2 = q
q = obj.Appendp(ctxt, q)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = ctxt.FixedFrameSize()
q.Reg = REGSP
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R6
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R6
q.To.Type = obj.TYPE_MEM
q.To.Reg = REG_R3
q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q)
q.As = obj.ANOP
p1.Pcond = q
p2.Pcond = q
}
case obj.ARET:
if p.From.Type == obj.TYPE_CONST {
ctxt.Diag("using BECOME (%v) is not supported!", p)
break
}
retTarget := p.To.Sym
if cursym.Text.Mark&LEAF != 0 {
if autosize == 0 {
p.As = ABR
p.From = obj.Addr{}
if retTarget == nil {
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_LR
} else {
p.To.Type = obj.TYPE_BRANCH
p.To.Sym = retTarget
}
p.Mark |= BRANCH
break
}
p.As = AADD
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize)
p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP
p.Spadj = -autosize
q = obj.Appendp(ctxt, p)
q.As = ABR
q.From = obj.Addr{}
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_LR
q.Mark |= BRANCH
q.Spadj = autosize
break
}
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGSP
p.From.Offset = 0
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_LR
q = p
if autosize != 0 {
q = obj.Appendp(ctxt, q)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize)
q.To.Type = obj.TYPE_REG
q.To.Reg = REGSP
q.Spadj = -autosize
}
q = obj.Appendp(ctxt, q)
q.As = ABR
q.From = obj.Addr{}
if retTarget == nil {
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_LR
} else {
q.To.Type = obj.TYPE_BRANCH
q.To.Sym = retTarget
}
q.Mark |= BRANCH
q.Spadj = autosize
case AADD:
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
p.Spadj = int32(-p.From.Offset)
}
}
}
if wasSplit {
pLast = stacksplitPost(ctxt, pLast, pPre, pPreempt) // emit post part of split check
}
}
/*
// instruction scheduling
if(debug['Q'] == 0)
return;
curtext = nil;
q = nil; // p - 1
q1 = firstp; // top of block
o = 0; // count of instructions
for(p = firstp; p != nil; p = p1) {
p1 = p->link;
o++;
if(p->mark & NOSCHED){
if(q1 != p){
sched(q1, q);
}
for(; p != nil; p = p->link){
if(!(p->mark & NOSCHED))
break;
q = p;
}
p1 = p;
q1 = p;
o = 0;
continue;
}
if(p->mark & (LABEL|SYNC)) {
if(q1 != p)
sched(q1, q);
q1 = p;
o = 1;
}
if(p->mark & (BRANCH|SYNC)) {
sched(q1, p);
q1 = p1;
o = 0;
}
if(o >= NSCHED) {
sched(q1, p);
q1 = p1;
o = 0;
}
q = p;
}
*/
func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *obj.Prog) {
var q *obj.Prog
// MOVD g_stackguard(g), R3
p = obj.Appendp(ctxt, p)
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
q = nil
if framesize <= obj.StackSmall {
// small stack: SP < stackguard
// CMP stackguard, SP
//p.To.Type = obj.TYPE_REG
//p.To.Reg = REGSP
// q1: BLT done
p = obj.Appendp(ctxt, p)
//q1 = p
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.Reg = REGSP
p.As = ACMPUBGE
p.To.Type = obj.TYPE_BRANCH
//p = obj.Appendp(ctxt, p)
//p.As = ACMPU
//p.From.Type = obj.TYPE_REG
//p.From.Reg = REG_R3
//p.To.Type = obj.TYPE_REG
//p.To.Reg = REGSP
//p = obj.Appendp(ctxt, p)
//p.As = ABGE
//p.To.Type = obj.TYPE_BRANCH
} else if framesize <= obj.StackBig {
// large stack: SP-framesize < stackguard-StackSmall
// ADD $-framesize, SP, R4
// CMP stackguard, R4
p = obj.Appendp(ctxt, p)
p.As = AADD
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-framesize)
p.Reg = REGSP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p)
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.Reg = REG_R4
p.As = ACMPUBGE
p.To.Type = obj.TYPE_BRANCH
} else {
// Such a large stack we need to protect against wraparound.
// If SP is close to zero:
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
// The +StackGuard on both sides is required to keep the left side positive:
// SP is allowed to be slightly below stackguard. See stack.h.
//
// Preemption sets stackguard to StackPreempt, a very large value.
// That breaks the math above, so we have to check for that explicitly.
// // stackguard is R3
// CMP R3, $StackPreempt
// BEQ label-of-call-to-morestack
// ADD $StackGuard, SP, R4
// SUB R3, R4
// MOVD $(framesize+(StackGuard-StackSmall)), TEMP
// CMPUBGE TEMP, R4
p = obj.Appendp(ctxt, p)
p.As = ACMP
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_CONST
p.To.Offset = obj.StackPreempt
p = obj.Appendp(ctxt, p)
q = p
p.As = ABEQ
p.To.Type = obj.TYPE_BRANCH
p = obj.Appendp(ctxt, p)
p.As = AADD
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard
p.Reg = REGSP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p)
p.As = ASUB
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p)
p.As = AMOVD
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP
p = obj.Appendp(ctxt, p)
p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP
p.Reg = REG_R4
p.As = ACMPUBGE
p.To.Type = obj.TYPE_BRANCH
}
return p, q
}
func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog) *obj.Prog {
// MOVD LR, R5
p = obj.Appendp(ctxt, p)
pPre.Pcond = p
p.As = AMOVD
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_LR
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R5
if pPreempt != nil {
pPreempt.Pcond = p
}
// BL runtime.morestack(SB)
p = obj.Appendp(ctxt, p)
p.As = ABL
p.To.Type = obj.TYPE_BRANCH
if ctxt.Cursym.Cfunc {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
} else {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack", 0)
}
// BR start
p = obj.Appendp(ctxt, p)
p.As = ABR
p.To.Type = obj.TYPE_BRANCH
p.Pcond = ctxt.Cursym.Text.Link
return p
}
var pc_cnt int64
func follow(ctxt *obj.Link, s *obj.LSym) {
ctxt.Cursym = s
pc_cnt = 0
firstp := ctxt.NewProg()
lastp := firstp
xfol(ctxt, s.Text, &lastp)
lastp.Link = nil
s.Text = firstp.Link
}
func relinv(a obj.As) obj.As {
switch a {
case ABEQ:
return ABNE
case ABNE:
return ABEQ
case ABGE:
return ABLT
case ABLT:
return ABGE
case ABGT:
return ABLE
case ABLE:
return ABGT
case ABVC:
return ABVS
case ABVS:
return ABVC
}
return 0
}
func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
var q *obj.Prog
var r *obj.Prog
var b obj.As
for p != nil {
a := p.As
if a == ABR {
q = p.Pcond
if (p.Mark&NOSCHED != 0) || q != nil && (q.Mark&NOSCHED != 0) {
p.Mark |= FOLL
(*last).Link = p
*last = p
(*last).Pc = pc_cnt
pc_cnt += 1
p = p.Link
xfol(ctxt, p, last)
p = q
if p != nil && p.Mark&FOLL == 0 {
continue
}
return
}
if q != nil {
p.Mark |= FOLL
p = q
if p.Mark&FOLL == 0 {
continue
}
}
}
if p.Mark&FOLL != 0 {
q = p
for i := 0; i < 4; i, q = i+1, q.Link {
if q == *last || (q.Mark&NOSCHED != 0) {
break
}
b = 0 /* set */
a = q.As
if a == obj.ANOP {
i--
continue
}
if a != ABR && a != obj.ARET {
if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
continue
}
b = relinv(a)
if b == 0 {
continue
}
}
for {
r = ctxt.NewProg()
*r = *p
if r.Mark&FOLL == 0 {
fmt.Printf("cant happen 1\n")
}
r.Mark |= FOLL
if p != q {
p = p.Link
(*last).Link = r
*last = r
(*last).Pc = pc_cnt
pc_cnt += 1
continue
}
(*last).Link = r
*last = r
(*last).Pc = pc_cnt
pc_cnt += 1
if a == ABR || a == obj.ARET {
return
}
r.As = b
r.Pcond = p.Link
r.Link = p.Pcond
if r.Link.Mark&FOLL == 0 {
xfol(ctxt, r.Link, last)
}
if r.Pcond.Mark&FOLL == 0 {
fmt.Printf("cant happen 2\n")
}
return
}
}
a = ABR
q = ctxt.NewProg()
q.As = a
q.Lineno = p.Lineno
q.To.Type = obj.TYPE_BRANCH
q.To.Offset = p.Pc
q.Pcond = p
p = q
}
p.Mark |= FOLL
(*last).Link = p
*last = p
(*last).Pc = pc_cnt
pc_cnt += 1
if a == ABR || a == obj.ARET {
if p.Mark&NOSCHED != 0 {
p = p.Link
continue
}
return
}
if p.Pcond != nil {
if a != ABL && p.Link != nil {
xfol(ctxt, p.Link, last)
p = p.Pcond
if p == nil || (p.Mark&FOLL != 0) {
return
}
continue
}
}
p = p.Link
}
}
var unaryDst = map[obj.As]bool{
ASTCK: true,
ASTCKC: true,
ASTCKE: true,
ASTCKF: true,
ANEG: true,
AVONE: true,
AVZERO: true,
}
var Links390x = obj.LinkArch{
ByteOrder: binary.BigEndian,
Name: "s390x",
Thechar: 'z',
Preprocess: preprocess,
Assemble: spanz,
Follow: follow,
Progedit: progedit,
UnaryDst: unaryDst,
Minlc: 2,
Ptrsize: 8,
Regsize: 8,
}
// 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.
package s390x
import (
"cmd/internal/obj"
)
// This file contains utility functions for use when
// assembling vector instructions.
// vop returns the opcode, element size and condition
// setting for the given (possibly extended) mnemonic.
func vop(as obj.As) (opcode, es, cs uint32) {
switch as {
default:
return 0, 0, 0
case AVA:
return op_VA, 0, 0
case AVAB:
return op_VA, 0, 0
case AVAH:
return op_VA, 1, 0
case AVAF:
return op_VA, 2, 0
case AVAG:
return op_VA, 3, 0
case AVAQ:
return op_VA, 4, 0
case AVACC:
return op_VACC, 0, 0
case AVACCB:
return op_VACC, 0, 0
case AVACCH:
return op_VACC, 1, 0
case AVACCF:
return op_VACC, 2, 0
case AVACCG:
return op_VACC, 3, 0
case AVACCQ:
return op_VACC, 4, 0
case AVAC:
return op_VAC, 0, 0
case AVACQ:
return op_VAC, 4, 0
case AVACCC:
return op_VACCC, 0, 0
case AVACCCQ:
return op_VACCC, 4, 0
case AVN:
return op_VN, 0, 0
case AVNC:
return op_VNC, 0, 0
case AVAVG:
return op_VAVG, 0, 0
case AVAVGB:
return op_VAVG, 0, 0
case AVAVGH:
return op_VAVG, 1, 0
case AVAVGF:
return op_VAVG, 2, 0
case AVAVGG:
return op_VAVG, 3, 0
case AVAVGL:
return op_VAVGL, 0, 0
case AVAVGLB:
return op_VAVGL, 0, 0
case AVAVGLH:
return op_VAVGL, 1, 0
case AVAVGLF:
return op_VAVGL, 2, 0
case AVAVGLG:
return op_VAVGL, 3, 0
case AVCKSM:
return op_VCKSM, 0, 0
case AVCEQ:
return op_VCEQ, 0, 0
case AVCEQB:
return op_VCEQ, 0, 0
case AVCEQH:
return op_VCEQ, 1, 0
case AVCEQF:
return op_VCEQ, 2, 0
case AVCEQG:
return op_VCEQ, 3, 0
case AVCEQBS:
return op_VCEQ, 0, 1
case AVCEQHS:
return op_VCEQ, 1, 1
case AVCEQFS:
return op_VCEQ, 2, 1
case AVCEQGS:
return op_VCEQ, 3, 1
case AVCH:
return op_VCH, 0, 0
case AVCHB:
return op_VCH, 0, 0
case AVCHH:
return op_VCH, 1, 0
case AVCHF:
return op_VCH, 2, 0
case AVCHG:
return op_VCH, 3, 0
case AVCHBS:
return op_VCH, 0, 1
case AVCHHS:
return op_VCH, 1, 1
case AVCHFS:
return op_VCH, 2, 1
case AVCHGS:
return op_VCH, 3, 1
case AVCHL:
return op_VCHL, 0, 0
case AVCHLB:
return op_VCHL, 0, 0
case AVCHLH:
return op_VCHL, 1, 0
case AVCHLF:
return op_VCHL, 2, 0
case AVCHLG:
return op_VCHL, 3, 0
case AVCHLBS:
return op_VCHL, 0, 1
case AVCHLHS:
return op_VCHL, 1, 1
case AVCHLFS:
return op_VCHL, 2, 1
case AVCHLGS:
return op_VCHL, 3, 1
case AVCLZ:
return op_VCLZ, 0, 0
case AVCLZB:
return op_VCLZ, 0, 0
case AVCLZH:
return op_VCLZ, 1, 0
case AVCLZF:
return op_VCLZ, 2, 0
case AVCLZG:
return op_VCLZ, 3, 0
case AVCTZ:
return op_VCTZ, 0, 0
case AVCTZB:
return op_VCTZ, 0, 0
case AVCTZH:
return op_VCTZ, 1, 0
case AVCTZF:
return op_VCTZ, 2, 0
case AVCTZG:
return op_VCTZ, 3, 0
case AVEC:
return op_VEC, 0, 0
case AVECB:
return op_VEC, 0, 0
case AVECH:
return op_VEC, 1, 0
case AVECF:
return op_VEC, 2, 0
case AVECG:
return op_VEC, 3, 0
case AVECL:
return op_VECL, 0, 0
case AVECLB:
return op_VECL, 0, 0
case AVECLH:
return op_VECL, 1, 0
case AVECLF:
return op_VECL, 2, 0
case AVECLG:
return op_VECL, 3, 0
case AVERIM:
return op_VERIM, 0, 0
case AVERIMB:
return op_VERIM, 0, 0
case AVERIMH:
return op_VERIM, 1, 0
case AVERIMF:
return op_VERIM, 2, 0
case AVERIMG:
return op_VERIM, 3, 0
case AVERLL:
return op_VERLL, 0, 0
case AVERLLB:
return op_VERLL, 0, 0
case AVERLLH:
return op_VERLL, 1, 0
case AVERLLF:
return op_VERLL, 2, 0
case AVERLLG:
return op_VERLL, 3, 0
case AVERLLV:
return op_VERLLV, 0, 0
case AVERLLVB:
return op_VERLLV, 0, 0
case AVERLLVH:
return op_VERLLV, 1, 0
case AVERLLVF:
return op_VERLLV, 2, 0
case AVERLLVG:
return op_VERLLV, 3, 0
case AVESLV:
return op_VESLV, 0, 0
case AVESLVB:
return op_VESLV, 0, 0
case AVESLVH:
return op_VESLV, 1, 0
case AVESLVF:
return op_VESLV, 2, 0
case AVESLVG:
return op_VESLV, 3, 0
case AVESL:
return op_VESL, 0, 0
case AVESLB:
return op_VESL, 0, 0
case AVESLH:
return op_VESL, 1, 0
case AVESLF:
return op_VESL, 2, 0
case AVESLG:
return op_VESL, 3, 0
case AVESRA:
return op_VESRA, 0, 0
case AVESRAB:
return op_VESRA, 0, 0
case AVESRAH:
return op_VESRA, 1, 0
case AVESRAF:
return op_VESRA, 2, 0
case AVESRAG:
return op_VESRA, 3, 0
case AVESRAV:
return op_VESRAV, 0, 0
case AVESRAVB:
return op_VESRAV, 0, 0
case AVESRAVH:
return op_VESRAV, 1, 0
case AVESRAVF:
return op_VESRAV, 2, 0
case AVESRAVG:
return op_VESRAV, 3, 0
case AVESRL:
return op_VESRL, 0, 0
case AVESRLB:
return op_VESRL, 0, 0
case AVESRLH:
return op_VESRL, 1, 0
case AVESRLF:
return op_VESRL, 2, 0
case AVESRLG:
return op_VESRL, 3, 0
case AVESRLV:
return op_VESRLV, 0, 0
case AVESRLVB:
return op_VESRLV, 0, 0
case AVESRLVH:
return op_VESRLV, 1, 0
case AVESRLVF:
return op_VESRLV, 2, 0
case AVESRLVG:
return op_VESRLV, 3, 0
case AVX:
return op_VX, 0, 0
case AVFAE:
return op_VFAE, 0, 0
case AVFAEB:
return op_VFAE, 0, 0
case AVFAEH:
return op_VFAE, 1, 0
case AVFAEF:
return op_VFAE, 2, 0
case AVFAEBS:
return op_VFAE, 0, 1
case AVFAEHS:
return op_VFAE, 1, 1
case AVFAEFS:
return op_VFAE, 2, 1
case AVFAEZB:
return op_VFAE, 0, 2
case AVFAEZH:
return op_VFAE, 1, 2
case AVFAEZF:
return op_VFAE, 2, 2
case AVFAEZBS:
return op_VFAE, 0, 3
case AVFAEZHS:
return op_VFAE, 1, 3
case AVFAEZFS:
return op_VFAE, 2, 3
case AVFEE:
return op_VFEE, 0, 0
case AVFEEB:
return op_VFEE, 0, 0
case AVFEEH:
return op_VFEE, 1, 0
case AVFEEF:
return op_VFEE, 2, 0
case AVFEEBS:
return op_VFEE, 0, 1
case AVFEEHS:
return op_VFEE, 1, 1
case AVFEEFS:
return op_VFEE, 2, 1
case AVFEEZB:
return op_VFEE, 0, 2
case AVFEEZH:
return op_VFEE, 1, 2
case AVFEEZF:
return op_VFEE, 2, 2
case AVFEEZBS:
return op_VFEE, 0, 3
case AVFEEZHS:
return op_VFEE, 1, 3
case AVFEEZFS:
return op_VFEE, 2, 3
case AVFENE:
return op_VFENE, 0, 0
case AVFENEB:
return op_VFENE, 0, 0
case AVFENEH:
return op_VFENE, 1, 0
case AVFENEF:
return op_VFENE, 2, 0
case AVFENEBS:
return op_VFENE, 0, 1
case AVFENEHS:
return op_VFENE, 1, 1
case AVFENEFS:
return op_VFENE, 2, 1
case AVFENEZB:
return op_VFENE, 0, 2
case AVFENEZH:
return op_VFENE, 1, 2
case AVFENEZF:
return op_VFENE, 2, 2
case AVFENEZBS:
return op_VFENE, 0, 3
case AVFENEZHS:
return op_VFENE, 1, 3
case AVFENEZFS:
return op_VFENE, 2, 3
case AVFA:
return op_VFA, 0, 0
case AVFADB:
return op_VFA, 3, 0
case AWFADB:
return op_VFA, 3, 0
case AWFK:
return op_WFK, 0, 0
case AWFKDB:
return op_WFK, 3, 0
case AVFCE:
return op_VFCE, 0, 0
case AVFCEDB:
return op_VFCE, 3, 0
case AVFCEDBS:
return op_VFCE, 3, 1
case AWFCEDB:
return op_VFCE, 3, 0
case AWFCEDBS:
return op_VFCE, 3, 1
case AVFCH:
return op_VFCH, 0, 0
case AVFCHDB:
return op_VFCH, 3, 0
case AVFCHDBS:
return op_VFCH, 3, 1
case AWFCHDB:
return op_VFCH, 3, 0
case AWFCHDBS:
return op_VFCH, 3, 1
case AVFCHE:
return op_VFCHE, 0, 0
case AVFCHEDB:
return op_VFCHE, 3, 0
case AVFCHEDBS:
return op_VFCHE, 3, 1
case AWFCHEDB:
return op_VFCHE, 3, 0
case AWFCHEDBS:
return op_VFCHE, 3, 1
case AWFC:
return op_WFC, 0, 0
case AWFCDB:
return op_WFC, 3, 0
case AVCDG:
return op_VCDG, 0, 0
case AVCDGB:
return op_VCDG, 3, 0
case AWCDGB:
return op_VCDG, 3, 0
case AVCDLG:
return op_VCDLG, 0, 0
case AVCDLGB:
return op_VCDLG, 3, 0
case AWCDLGB:
return op_VCDLG, 3, 0
case AVCGD:
return op_VCGD, 0, 0
case AVCGDB:
return op_VCGD, 3, 0
case AWCGDB:
return op_VCGD, 3, 0
case AVCLGD:
return op_VCLGD, 0, 0
case AVCLGDB:
return op_VCLGD, 3, 0
case AWCLGDB:
return op_VCLGD, 3, 0
case AVFD:
return op_VFD, 0, 0
case AVFDDB:
return op_VFD, 3, 0
case AWFDDB:
return op_VFD, 3, 0
case AVLDE:
return op_VLDE, 0, 0
case AVLDEB:
return op_VLDE, 2, 0
case AWLDEB:
return op_VLDE, 2, 0
case AVLED:
return op_VLED, 0, 0
case AVLEDB:
return op_VLED, 3, 0
case AWLEDB:
return op_VLED, 3, 0
case AVFM:
return op_VFM, 0, 0
case AVFMDB:
return op_VFM, 3, 0
case AWFMDB:
return op_VFM, 3, 0
case AVFMA:
return op_VFMA, 0, 0
case AVFMADB:
return op_VFMA, 3, 0
case AWFMADB:
return op_VFMA, 3, 0
case AVFMS:
return op_VFMS, 0, 0
case AVFMSDB:
return op_VFMS, 3, 0
case AWFMSDB:
return op_VFMS, 3, 0
case AVFPSO:
return op_VFPSO, 0, 0
case AVFPSODB:
return op_VFPSO, 3, 0
case AWFPSODB:
return op_VFPSO, 3, 0
case AVFLCDB:
return op_VFPSO, 3, 0
case AWFLCDB:
return op_VFPSO, 3, 0
case AVFLNDB:
return op_VFPSO, 3, 1
case AWFLNDB:
return op_VFPSO, 3, 1
case AVFLPDB:
return op_VFPSO, 3, 2
case AWFLPDB:
return op_VFPSO, 3, 2
case AVFSQ:
return op_VFSQ, 0, 0
case AVFSQDB:
return op_VFSQ, 3, 0
case AWFSQDB:
return op_VFSQ, 3, 0
case AVFS:
return op_VFS, 0, 0
case AVFSDB:
return op_VFS, 3, 0
case AWFSDB:
return op_VFS, 3, 0
case AVFTCI:
return op_VFTCI, 0, 0
case AVFTCIDB:
return op_VFTCI, 3, 0
case AWFTCIDB:
return op_VFTCI, 3, 0
case AVGFM:
return op_VGFM, 0, 0
case AVGFMB:
return op_VGFM, 0, 0
case AVGFMH:
return op_VGFM, 1, 0
case AVGFMF:
return op_VGFM, 2, 0
case AVGFMG:
return op_VGFM, 3, 0
case AVGFMA:
return op_VGFMA, 0, 0
case AVGFMAB:
return op_VGFMA, 0, 0
case AVGFMAH:
return op_VGFMA, 1, 0
case AVGFMAF:
return op_VGFMA, 2, 0
case AVGFMAG:
return op_VGFMA, 3, 0
case AVGEF:
return op_VGEF, 0, 0
case AVGEG:
return op_VGEG, 0, 0
case AVGBM:
return op_VGBM, 0, 0
case AVZERO:
return op_VGBM, 0, 0
case AVONE:
return op_VGBM, 0, 0
case AVGM:
return op_VGM, 0, 0
case AVGMB:
return op_VGM, 0, 0
case AVGMH:
return op_VGM, 1, 0
case AVGMF:
return op_VGM, 2, 0
case AVGMG:
return op_VGM, 3, 0
case AVISTR:
return op_VISTR, 0, 0
case AVISTRB:
return op_VISTR, 0, 0
case AVISTRH:
return op_VISTR, 1, 0
case AVISTRF:
return op_VISTR, 2, 0
case AVISTRBS:
return op_VISTR, 0, 1
case AVISTRHS:
return op_VISTR, 1, 1
case AVISTRFS:
return op_VISTR, 2, 1
case AVL:
return op_VL, 0, 0
case AVLR:
return op_VLR, 0, 0
case AVLREP:
return op_VLREP, 0, 0
case AVLREPB:
return op_VLREP, 0, 0
case AVLREPH:
return op_VLREP, 1, 0
case AVLREPF:
return op_VLREP, 2, 0
case AVLREPG:
return op_VLREP, 3, 0
case AVLC:
return op_VLC, 0, 0
case AVLCB:
return op_VLC, 0, 0
case AVLCH:
return op_VLC, 1, 0
case AVLCF:
return op_VLC, 2, 0
case AVLCG:
return op_VLC, 3, 0
case AVLEH:
return op_VLEH, 0, 0
case AVLEF:
return op_VLEF, 0, 0
case AVLEG:
return op_VLEG, 0, 0
case AVLEB:
return op_VLEB, 0, 0
case AVLEIH:
return op_VLEIH, 0, 0
case AVLEIF:
return op_VLEIF, 0, 0
case AVLEIG:
return op_VLEIG, 0, 0
case AVLEIB:
return op_VLEIB, 0, 0
case AVFI:
return op_VFI, 0, 0
case AVFIDB:
return op_VFI, 3, 0
case AWFIDB:
return op_VFI, 3, 0
case AVLGV:
return op_VLGV, 0, 0
case AVLGVB:
return op_VLGV, 0, 0
case AVLGVH:
return op_VLGV, 1, 0
case AVLGVF:
return op_VLGV, 2, 0
case AVLGVG:
return op_VLGV, 3, 0
case AVLLEZ:
return op_VLLEZ, 0, 0
case AVLLEZB:
return op_VLLEZ, 0, 0
case AVLLEZH:
return op_VLLEZ, 1, 0
case AVLLEZF:
return op_VLLEZ, 2, 0
case AVLLEZG:
return op_VLLEZ, 3, 0
case AVLM:
return op_VLM, 0, 0
case AVLP:
return op_VLP, 0, 0
case AVLPB:
return op_VLP, 0, 0
case AVLPH:
return op_VLP, 1, 0
case AVLPF:
return op_VLP, 2, 0
case AVLPG:
return op_VLP, 3, 0
case AVLBB:
return op_VLBB, 0, 0
case AVLVG:
return op_VLVG, 0, 0
case AVLVGB:
return op_VLVG, 0, 0
case AVLVGH:
return op_VLVG, 1, 0
case AVLVGF:
return op_VLVG, 2, 0
case AVLVGG:
return op_VLVG, 3, 0
case AVLVGP:
return op_VLVGP, 0, 0
case AVLL:
return op_VLL, 0, 0
case AVMX:
return op_VMX, 0, 0
case AVMXB:
return op_VMX, 0, 0
case AVMXH:
return op_VMX, 1, 0
case AVMXF:
return op_VMX, 2, 0
case AVMXG:
return op_VMX, 3, 0
case AVMXL:
return op_VMXL, 0, 0
case AVMXLB:
return op_VMXL, 0, 0
case AVMXLH:
return op_VMXL, 1, 0
case AVMXLF:
return op_VMXL, 2, 0
case AVMXLG:
return op_VMXL, 3, 0
case AVMRH:
return op_VMRH, 0, 0
case AVMRHB:
return op_VMRH, 0, 0
case AVMRHH:
return op_VMRH, 1, 0
case AVMRHF:
return op_VMRH, 2, 0
case AVMRHG:
return op_VMRH, 3, 0
case AVMRL:
return op_VMRL, 0, 0
case AVMRLB:
return op_VMRL, 0, 0
case AVMRLH:
return op_VMRL, 1, 0
case AVMRLF:
return op_VMRL, 2, 0
case AVMRLG:
return op_VMRL, 3, 0
case AVMN:
return op_VMN, 0, 0
case AVMNB:
return op_VMN, 0, 0
case AVMNH:
return op_VMN, 1, 0
case AVMNF:
return op_VMN, 2, 0
case AVMNG:
return op_VMN, 3, 0
case AVMNL:
return op_VMNL, 0, 0
case AVMNLB:
return op_VMNL, 0, 0
case AVMNLH:
return op_VMNL, 1, 0
case AVMNLF:
return op_VMNL, 2, 0
case AVMNLG:
return op_VMNL, 3, 0
case AVMAE:
return op_VMAE, 0, 0
case AVMAEB:
return op_VMAE, 0, 0
case AVMAEH:
return op_VMAE, 1, 0
case AVMAEF:
return op_VMAE, 2, 0
case AVMAH:
return op_VMAH, 0, 0
case AVMAHB:
return op_VMAH, 0, 0
case AVMAHH:
return op_VMAH, 1, 0
case AVMAHF:
return op_VMAH, 2, 0
case AVMALE:
return op_VMALE, 0, 0
case AVMALEB:
return op_VMALE, 0, 0
case AVMALEH:
return op_VMALE, 1, 0
case AVMALEF:
return op_VMALE, 2, 0
case AVMALH:
return op_VMALH, 0, 0
case AVMALHB:
return op_VMALH, 0, 0
case AVMALHH:
return op_VMALH, 1, 0
case AVMALHF:
return op_VMALH, 2, 0
case AVMALO:
return op_VMALO, 0, 0
case AVMALOB:
return op_VMALO, 0, 0
case AVMALOH:
return op_VMALO, 1, 0
case AVMALOF:
return op_VMALO, 2, 0
case AVMAL:
return op_VMAL, 0, 0
case AVMALB:
return op_VMAL, 0, 0
case AVMALHW:
return op_VMAL, 1, 0
case AVMALF:
return op_VMAL, 2, 0
case AVMAO:
return op_VMAO, 0, 0
case AVMAOB:
return op_VMAO, 0, 0
case AVMAOH:
return op_VMAO, 1, 0
case AVMAOF:
return op_VMAO, 2, 0
case AVME:
return op_VME, 0, 0
case AVMEB:
return op_VME, 0, 0
case AVMEH:
return op_VME, 1, 0
case AVMEF:
return op_VME, 2, 0
case AVMH:
return op_VMH, 0, 0
case AVMHB:
return op_VMH, 0, 0
case AVMHH:
return op_VMH, 1, 0
case AVMHF:
return op_VMH, 2, 0
case AVMLE:
return op_VMLE, 0, 0
case AVMLEB:
return op_VMLE, 0, 0
case AVMLEH:
return op_VMLE, 1, 0
case AVMLEF:
return op_VMLE, 2, 0
case AVMLH:
return op_VMLH, 0, 0
case AVMLHB:
return op_VMLH, 0, 0
case AVMLHH:
return op_VMLH, 1, 0
case AVMLHF:
return op_VMLH, 2, 0
case AVMLO:
return op_VMLO, 0, 0
case AVMLOB:
return op_VMLO, 0, 0
case AVMLOH:
return op_VMLO, 1, 0
case AVMLOF:
return op_VMLO, 2, 0
case AVML:
return op_VML, 0, 0
case AVMLB:
return op_VML, 0, 0
case AVMLHW:
return op_VML, 1, 0
case AVMLF:
return op_VML, 2, 0
case AVMO:
return op_VMO, 0, 0
case AVMOB:
return op_VMO, 0, 0
case AVMOH:
return op_VMO, 1, 0
case AVMOF:
return op_VMO, 2, 0
case AVNO:
return op_VNO, 0, 0
case AVNOT:
return op_VNO, 0, 0
case AVO:
return op_VO, 0, 0
case AVPK:
return op_VPK, 0, 0
case AVPKH:
return op_VPK, 1, 0
case AVPKF:
return op_VPK, 2, 0
case AVPKG:
return op_VPK, 3, 0
case AVPKLS:
return op_VPKLS, 0, 0
case AVPKLSH:
return op_VPKLS, 1, 0
case AVPKLSF:
return op_VPKLS, 2, 0
case AVPKLSG:
return op_VPKLS, 3, 0
case AVPKLSHS:
return op_VPKLS, 1, 1
case AVPKLSFS:
return op_VPKLS, 2, 1
case AVPKLSGS:
return op_VPKLS, 3, 1
case AVPKS:
return op_VPKS, 0, 0
case AVPKSH:
return op_VPKS, 1, 0
case AVPKSF:
return op_VPKS, 2, 0
case AVPKSG:
return op_VPKS, 3, 0
case AVPKSHS:
return op_VPKS, 1, 1
case AVPKSFS:
return op_VPKS, 2, 1
case AVPKSGS:
return op_VPKS, 3, 1
case AVPERM:
return op_VPERM, 0, 0
case AVPDI:
return op_VPDI, 0, 0
case AVPOPCT:
return op_VPOPCT, 0, 0
case AVREP:
return op_VREP, 0, 0
case AVREPB:
return op_VREP, 0, 0
case AVREPH:
return op_VREP, 1, 0
case AVREPF:
return op_VREP, 2, 0
case AVREPG:
return op_VREP, 3, 0
case AVREPI:
return op_VREPI, 0, 0
case AVREPIB:
return op_VREPI, 0, 0
case AVREPIH:
return op_VREPI, 1, 0
case AVREPIF:
return op_VREPI, 2, 0
case AVREPIG:
return op_VREPI, 3, 0
case AVSCEF:
return op_VSCEF, 0, 0
case AVSCEG:
return op_VSCEG, 0, 0
case AVSEL:
return op_VSEL, 0, 0
case AVSL:
return op_VSL, 0, 0
case AVSLB:
return op_VSLB, 0, 0
case AVSLDB:
return op_VSLDB, 0, 0
case AVSRA:
return op_VSRA, 0, 0
case AVSRAB:
return op_VSRAB, 0, 0
case AVSRL:
return op_VSRL, 0, 0
case AVSRLB:
return op_VSRLB, 0, 0
case AVSEG:
return op_VSEG, 0, 0
case AVSEGB:
return op_VSEG, 0, 0
case AVSEGH:
return op_VSEG, 1, 0
case AVSEGF:
return op_VSEG, 2, 0
case AVST:
return op_VST, 0, 0
case AVSTEH:
return op_VSTEH, 0, 0
case AVSTEF:
return op_VSTEF, 0, 0
case AVSTEG:
return op_VSTEG, 0, 0
case AVSTEB:
return op_VSTEB, 0, 0
case AVSTM:
return op_VSTM, 0, 0
case AVSTL:
return op_VSTL, 0, 0
case AVSTRC:
return op_VSTRC, 0, 0
case AVSTRCB:
return op_VSTRC, 0, 0
case AVSTRCH:
return op_VSTRC, 1, 0
case AVSTRCF:
return op_VSTRC, 2, 0
case AVSTRCBS:
return op_VSTRC, 0, 1
case AVSTRCHS:
return op_VSTRC, 1, 1
case AVSTRCFS:
return op_VSTRC, 2, 1
case AVSTRCZB:
return op_VSTRC, 0, 2
case AVSTRCZH:
return op_VSTRC, 1, 2
case AVSTRCZF:
return op_VSTRC, 2, 2
case AVSTRCZBS:
return op_VSTRC, 0, 3
case AVSTRCZHS:
return op_VSTRC, 1, 3
case AVSTRCZFS:
return op_VSTRC, 2, 3
case AVS:
return op_VS, 0, 0
case AVSB:
return op_VS, 0, 0
case AVSH:
return op_VS, 1, 0
case AVSF:
return op_VS, 2, 0
case AVSG:
return op_VS, 3, 0
case AVSQ:
return op_VS, 4, 0
case AVSCBI:
return op_VSCBI, 0, 0
case AVSCBIB:
return op_VSCBI, 0, 0
case AVSCBIH:
return op_VSCBI, 1, 0
case AVSCBIF:
return op_VSCBI, 2, 0
case AVSCBIG:
return op_VSCBI, 3, 0
case AVSCBIQ:
return op_VSCBI, 4, 0
case AVSBCBI:
return op_VSBCBI, 0, 0
case AVSBCBIQ:
return op_VSBCBI, 4, 0
case AVSBI:
return op_VSBI, 0, 0
case AVSBIQ:
return op_VSBI, 4, 0
case AVSUMG:
return op_VSUMG, 0, 0
case AVSUMGH:
return op_VSUMG, 1, 0
case AVSUMGF:
return op_VSUMG, 2, 0
case AVSUMQ:
return op_VSUMQ, 0, 0
case AVSUMQF:
return op_VSUMQ, 1, 0
case AVSUMQG:
return op_VSUMQ, 2, 0
case AVSUM:
return op_VSUM, 0, 0
case AVSUMB:
return op_VSUM, 0, 0
case AVSUMH:
return op_VSUM, 1, 0
case AVTM:
return op_VTM, 0, 0
case AVUPH:
return op_VUPH, 0, 0
case AVUPHB:
return op_VUPH, 0, 0
case AVUPHH:
return op_VUPH, 1, 0
case AVUPHF:
return op_VUPH, 2, 0
case AVUPLH:
return op_VUPLH, 0, 0
case AVUPLHB:
return op_VUPLH, 0, 0
case AVUPLHH:
return op_VUPLH, 1, 0
case AVUPLHF:
return op_VUPLH, 2, 0
case AVUPLL:
return op_VUPLL, 0, 0
case AVUPLLB:
return op_VUPLL, 0, 0
case AVUPLLH:
return op_VUPLL, 1, 0
case AVUPLLF:
return op_VUPLL, 2, 0
case AVUPL:
return op_VUPL, 0, 0
case AVUPLB:
return op_VUPL, 0, 0
case AVUPLHW:
return op_VUPL, 1, 0
case AVUPLF:
return op_VUPL, 2, 0
}
}
// singleElementMask returns the single element mask bits required for the
// given instruction.
func singleElementMask(as obj.As) uint32 {
switch as {
case AWFADB,
AWFK,
AWFKDB,
AWFCEDB,
AWFCEDBS,
AWFCHDB,
AWFCHDBS,
AWFCHEDB,
AWFCHEDBS,
AWFC,
AWFCDB,
AWCDGB,
AWCDLGB,
AWCGDB,
AWCLGDB,
AWFDDB,
AWLDEB,
AWLEDB,
AWFMDB,
AWFMADB,
AWFMSDB,
AWFPSODB,
AWFLCDB,
AWFLNDB,
AWFLPDB,
AWFSQDB,
AWFSDB,
AWFTCIDB,
AWFIDB:
return 8
}
return 0
}
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