summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gops/internal/obj/arm64
diff options
context:
space:
mode:
authorWim <wim@42.be>2018-08-06 21:47:05 +0200
committerWim <wim@42.be>2018-08-06 21:47:05 +0200
commit51062863a5c34d81e296cf15c61140911037cf3b (patch)
tree9b5e044672486326c7a0ca8fb26430f37bf4d83c /vendor/github.com/google/gops/internal/obj/arm64
parent4fb4b7aa6c02a54db8ad8dd98e4d321396926c0d (diff)
downloadmatterbridge-msglm-51062863a5c34d81e296cf15c61140911037cf3b.tar.gz
matterbridge-msglm-51062863a5c34d81e296cf15c61140911037cf3b.tar.bz2
matterbridge-msglm-51062863a5c34d81e296cf15c61140911037cf3b.zip
Use mod vendor for vendored directory (backwards compatible)
Diffstat (limited to 'vendor/github.com/google/gops/internal/obj/arm64')
-rw-r--r--vendor/github.com/google/gops/internal/obj/arm64/a.out.go719
-rw-r--r--vendor/github.com/google/gops/internal/obj/arm64/anames.go370
-rw-r--r--vendor/github.com/google/gops/internal/obj/arm64/anames7.go70
-rw-r--r--vendor/github.com/google/gops/internal/obj/arm64/asm7.go4374
-rw-r--r--vendor/github.com/google/gops/internal/obj/arm64/list7.go115
-rw-r--r--vendor/github.com/google/gops/internal/obj/arm64/obj7.go1005
6 files changed, 0 insertions, 6653 deletions
diff --git a/vendor/github.com/google/gops/internal/obj/arm64/a.out.go b/vendor/github.com/google/gops/internal/obj/arm64/a.out.go
deleted file mode 100644
index b3a27d43..00000000
--- a/vendor/github.com/google/gops/internal/obj/arm64/a.out.go
+++ /dev/null
@@ -1,719 +0,0 @@
-// cmd/7c/7.out.h from Vita Nuova.
-// https://code.google.com/p/ken-cc/source/browse/src/cmd/7c/7.out.h
-//
-// 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-2007 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-2007 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 arm64
-
-import "github.com/google/gops/internal/obj"
-
-const (
- NSNAME = 8
- NSYM = 50
- NREG = 32 /* number of general registers */
- NFREG = 32 /* number of floating point registers */
-)
-
-// General purpose registers, kept in the low bits of Prog.Reg.
-const (
- // integer
- REG_R0 = obj.RBaseARM64 + 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
- REG_R16
- REG_R17
- REG_R18
- REG_R19
- REG_R20
- REG_R21
- REG_R22
- REG_R23
- REG_R24
- REG_R25
- REG_R26
- REG_R27
- REG_R28
- REG_R29
- REG_R30
- REG_R31
-
- // scalar floating point
- 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
- REG_F16
- REG_F17
- REG_F18
- REG_F19
- REG_F20
- REG_F21
- REG_F22
- REG_F23
- REG_F24
- REG_F25
- REG_F26
- REG_F27
- REG_F28
- REG_F29
- REG_F30
- REG_F31
-
- // SIMD
- 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
-
- // The EQ in
- // CSET EQ, R0
- // is encoded as TYPE_REG, even though it's not really a register.
- COND_EQ
- COND_NE
- COND_HS
- COND_LO
- COND_MI
- COND_PL
- COND_VS
- COND_VC
- COND_HI
- COND_LS
- COND_GE
- COND_LT
- COND_GT
- COND_LE
- COND_AL
- COND_NV
-
- REG_RSP = REG_V31 + 32 // to differentiate ZR/SP, REG_RSP&0x1f = 31
-)
-
-// Not registers, but flags that can be combined with regular register
-// constants to indicate extended register conversion. When checking,
-// you should subtract obj.RBaseARM64 first. From this difference, bit 11
-// indicates extended register, bits 8-10 select the conversion mode.
-const REG_EXT = obj.RBaseARM64 + 1<<11
-
-const (
- REG_UXTB = REG_EXT + iota<<8
- REG_UXTH
- REG_UXTW
- REG_UXTX
- REG_SXTB
- REG_SXTH
- REG_SXTW
- REG_SXTX
-)
-
-// Special registers, after subtracting obj.RBaseARM64, bit 12 indicates
-// a special register and the low bits select the register.
-const (
- REG_SPECIAL = obj.RBaseARM64 + 1<<12 + iota
- REG_DAIF
- REG_NZCV
- REG_FPSR
- REG_FPCR
- REG_SPSR_EL1
- REG_ELR_EL1
- REG_SPSR_EL2
- REG_ELR_EL2
- REG_CurrentEL
- REG_SP_EL0
- REG_SPSel
- REG_DAIFSet
- REG_DAIFClr
-)
-
-// Register assignments:
-//
-// compiler allocates R0 up as temps
-// compiler allocates register variables R7-R25
-// compiler allocates external registers R26 down
-//
-// compiler allocates register variables F7-F26
-// compiler allocates external registers F26 down
-const (
- REGMIN = REG_R7 // register variables allocated from here to REGMAX
- REGRT1 = REG_R16 // ARM64 IP0, for external linker, runtime, duffzero and duffcopy
- REGRT2 = REG_R17 // ARM64 IP1, for external linker, runtime, duffcopy
- REGPR = REG_R18 // ARM64 platform register, unused in the Go toolchain
- REGMAX = REG_R25
-
- REGCTXT = REG_R26 // environment for closures
- REGTMP = REG_R27 // reserved for liblink
- REGG = REG_R28 // G
- REGFP = REG_R29 // frame pointer, unused in the Go toolchain
- REGLINK = REG_R30
-
- // ARM64 uses R31 as both stack pointer and zero register,
- // depending on the instruction. To differentiate RSP from ZR,
- // we use a different numeric value for REGZERO and REGSP.
- REGZERO = REG_R31
- REGSP = REG_RSP
-
- FREGRET = REG_F0
- FREGMIN = REG_F7 // first register variable
- FREGMAX = REG_F26 // last register variable for 7g only
- FREGEXT = REG_F26 // first external register
-)
-
-const (
- BIG = 2048 - 8
-)
-
-const (
- /* mark flags */
- LABEL = 1 << iota
- LEAF
- FLOAT
- BRANCH
- LOAD
- FCMP
- SYNC
- LIST
- FOLL
- NOSCHED
-)
-
-const (
- C_NONE = iota
- C_REG // R0..R30
- C_RSP // R0..R30, RSP
- C_FREG // F0..F31
- C_VREG // V0..V31
- C_PAIR // (Rn, Rm)
- C_SHIFT // Rn<<2
- C_EXTREG // Rn.UXTB<<3
- C_SPR // REG_NZCV
- C_COND // EQ, NE, etc
-
- C_ZCON // $0 or ZR
- C_ADDCON0 // 12-bit unsigned, unshifted
- C_ADDCON // 12-bit unsigned, shifted left by 0 or 12
- C_MOVCON // generated by a 16-bit constant, optionally inverted and/or shifted by multiple of 16
- C_BITCON // bitfield and logical immediate masks
- C_ABCON0 // could be C_ADDCON0 or C_BITCON
- C_ABCON // could be C_ADDCON or C_BITCON
- C_MBCON // could be C_MOVCON or C_BITCON
- C_LCON // 32-bit constant
- C_VCON // 64-bit constant
- C_FCON // floating-point constant
- C_VCONADDR // 64-bit memory address
-
- C_AACON // ADDCON offset in auto constant $a(FP)
- C_LACON // 32-bit offset in auto constant $a(FP)
- C_AECON // ADDCON offset in extern constant $e(SB)
-
- // TODO(aram): only one branch class should be enough
- C_SBRA // for TYPE_BRANCH
- C_LBRA
-
- C_NPAUTO // -512 <= x < 0, 0 mod 8
- C_NSAUTO // -256 <= x < 0
- C_PSAUTO // 0 to 255
- C_PPAUTO // 0 to 504, 0 mod 8
- C_UAUTO4K // 0 to 4095
- C_UAUTO8K // 0 to 8190, 0 mod 2
- C_UAUTO16K // 0 to 16380, 0 mod 4
- C_UAUTO32K // 0 to 32760, 0 mod 8
- C_UAUTO64K // 0 to 65520, 0 mod 16
- C_LAUTO // any other 32-bit constant
-
- C_SEXT1 // 0 to 4095, direct
- C_SEXT2 // 0 to 8190
- C_SEXT4 // 0 to 16380
- C_SEXT8 // 0 to 32760
- C_SEXT16 // 0 to 65520
- C_LEXT
-
- // TODO(aram): s/AUTO/INDIR/
- C_ZOREG // 0(R)
- C_NPOREG // mirror NPAUTO, etc
- C_NSOREG
- C_PSOREG
- C_PPOREG
- C_UOREG4K
- C_UOREG8K
- C_UOREG16K
- C_UOREG32K
- C_UOREG64K
- C_LOREG
-
- C_ADDR // TODO(aram): explain difference from C_VCONADDR
-
- // The GOT slot for a symbol in -dynlink mode.
- C_GOTADDR
-
- // TLS "var" in local exec mode: will become a constant offset from
- // thread local base that is ultimately chosen by the program linker.
- C_TLS_LE
-
- // TLS "var" in initial exec mode: will become a memory address (chosen
- // by the program linker) that the dynamic linker will fill with the
- // offset from the thread local base.
- C_TLS_IE
-
- C_ROFF // register offset (including register extended)
-
- C_GOK
- C_TEXTSIZE
- C_NCLASS // must be last
-)
-
-const (
- C_XPRE = 1 << 6 // match arm.C_WBIT, so Prog.String know how to print it
- C_XPOST = 1 << 5 // match arm.C_PBIT, so Prog.String know how to print it
-)
-
-//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm64
-
-const (
- AADC = obj.ABaseARM64 + obj.A_ARCHSPECIFIC + iota
- AADCS
- AADCSW
- AADCW
- AADD
- AADDS
- AADDSW
- AADDW
- AADR
- AADRP
- AAND
- AANDS
- AANDSW
- AANDW
- AASR
- AASRW
- AAT
- ABFI
- ABFIW
- ABFM
- ABFMW
- ABFXIL
- ABFXILW
- ABIC
- ABICS
- ABICSW
- ABICW
- ABRK
- ACBNZ
- ACBNZW
- ACBZ
- ACBZW
- ACCMN
- ACCMNW
- ACCMP
- ACCMPW
- ACINC
- ACINCW
- ACINV
- ACINVW
- ACLREX
- ACLS
- ACLSW
- ACLZ
- ACLZW
- ACMN
- ACMNW
- ACMP
- ACMPW
- ACNEG
- ACNEGW
- ACRC32B
- ACRC32CB
- ACRC32CH
- ACRC32CW
- ACRC32CX
- ACRC32H
- ACRC32W
- ACRC32X
- ACSEL
- ACSELW
- ACSET
- ACSETM
- ACSETMW
- ACSETW
- ACSINC
- ACSINCW
- ACSINV
- ACSINVW
- ACSNEG
- ACSNEGW
- ADC
- ADCPS1
- ADCPS2
- ADCPS3
- ADMB
- ADRPS
- ADSB
- AEON
- AEONW
- AEOR
- AEORW
- AERET
- AEXTR
- AEXTRW
- AHINT
- AHLT
- AHVC
- AIC
- AISB
- ALDAR
- ALDARB
- ALDARH
- ALDARW
- ALDAXP
- ALDAXPW
- ALDAXR
- ALDAXRB
- ALDAXRH
- ALDAXRW
- ALDP
- ALDXR
- ALDXRB
- ALDXRH
- ALDXRW
- ALDXP
- ALDXPW
- ALSL
- ALSLW
- ALSR
- ALSRW
- AMADD
- AMADDW
- AMNEG
- AMNEGW
- AMOVK
- AMOVKW
- AMOVN
- AMOVNW
- AMOVZ
- AMOVZW
- AMRS
- AMSR
- AMSUB
- AMSUBW
- AMUL
- AMULW
- AMVN
- AMVNW
- ANEG
- ANEGS
- ANEGSW
- ANEGW
- ANGC
- ANGCS
- ANGCSW
- ANGCW
- AORN
- AORNW
- AORR
- AORRW
- APRFM
- APRFUM
- ARBIT
- ARBITW
- AREM
- AREMW
- AREV
- AREV16
- AREV16W
- AREV32
- AREVW
- AROR
- ARORW
- ASBC
- ASBCS
- ASBCSW
- ASBCW
- ASBFIZ
- ASBFIZW
- ASBFM
- ASBFMW
- ASBFX
- ASBFXW
- ASDIV
- ASDIVW
- ASEV
- ASEVL
- ASMADDL
- ASMC
- ASMNEGL
- ASMSUBL
- ASMULH
- ASMULL
- ASTXR
- ASTXRB
- ASTXRH
- ASTXP
- ASTXPW
- ASTXRW
- ASTLP
- ASTLPW
- ASTLR
- ASTLRB
- ASTLRH
- ASTLRW
- ASTLXP
- ASTLXPW
- ASTLXR
- ASTLXRB
- ASTLXRH
- ASTLXRW
- ASTP
- ASUB
- ASUBS
- ASUBSW
- ASUBW
- ASVC
- ASXTB
- ASXTBW
- ASXTH
- ASXTHW
- ASXTW
- ASYS
- ASYSL
- ATBNZ
- ATBZ
- ATLBI
- ATST
- ATSTW
- AUBFIZ
- AUBFIZW
- AUBFM
- AUBFMW
- AUBFX
- AUBFXW
- AUDIV
- AUDIVW
- AUMADDL
- AUMNEGL
- AUMSUBL
- AUMULH
- AUMULL
- AUREM
- AUREMW
- AUXTB
- AUXTH
- AUXTW
- AUXTBW
- AUXTHW
- AWFE
- AWFI
- AYIELD
- AMOVB
- AMOVBU
- AMOVH
- AMOVHU
- AMOVW
- AMOVWU
- AMOVD
- AMOVNP
- AMOVNPW
- AMOVP
- AMOVPD
- AMOVPQ
- AMOVPS
- AMOVPSW
- AMOVPW
- ABEQ
- ABNE
- ABCS
- ABHS
- ABCC
- ABLO
- ABMI
- ABPL
- ABVS
- ABVC
- ABHI
- ABLS
- ABGE
- ABLT
- ABGT
- ABLE
- AFABSD
- AFABSS
- AFADDD
- AFADDS
- AFCCMPD
- AFCCMPED
- AFCCMPS
- AFCCMPES
- AFCMPD
- AFCMPED
- AFCMPES
- AFCMPS
- AFCVTSD
- AFCVTDS
- AFCVTZSD
- AFCVTZSDW
- AFCVTZSS
- AFCVTZSSW
- AFCVTZUD
- AFCVTZUDW
- AFCVTZUS
- AFCVTZUSW
- AFDIVD
- AFDIVS
- AFMOVD
- AFMOVS
- AFMULD
- AFMULS
- AFNEGD
- AFNEGS
- AFSQRTD
- AFSQRTS
- AFSUBD
- AFSUBS
- ASCVTFD
- ASCVTFS
- ASCVTFWD
- ASCVTFWS
- AUCVTFD
- AUCVTFS
- AUCVTFWD
- AUCVTFWS
- AWORD
- ADWORD
- AFCSELS
- AFCSELD
- AFMAXS
- AFMINS
- AFMAXD
- AFMIND
- AFMAXNMS
- AFMAXNMD
- AFNMULS
- AFNMULD
- AFRINTNS
- AFRINTND
- AFRINTPS
- AFRINTPD
- AFRINTMS
- AFRINTMD
- AFRINTZS
- AFRINTZD
- AFRINTAS
- AFRINTAD
- AFRINTXS
- AFRINTXD
- AFRINTIS
- AFRINTID
- AFMADDS
- AFMADDD
- AFMSUBS
- AFMSUBD
- AFNMADDS
- AFNMADDD
- AFNMSUBS
- AFNMSUBD
- AFMINNMS
- AFMINNMD
- AFCVTDH
- AFCVTHS
- AFCVTHD
- AFCVTSH
- AAESD
- AAESE
- AAESIMC
- AAESMC
- ASHA1C
- ASHA1H
- ASHA1M
- ASHA1P
- ASHA1SU0
- ASHA1SU1
- ASHA256H
- ASHA256H2
- ASHA256SU0
- ASHA256SU1
- ALAST
- AB = obj.AJMP
- ABL = obj.ACALL
-)
-
-const (
- // shift types
- SHIFT_LL = 0 << 22
- SHIFT_LR = 1 << 22
- SHIFT_AR = 2 << 22
-)
diff --git a/vendor/github.com/google/gops/internal/obj/arm64/anames.go b/vendor/github.com/google/gops/internal/obj/arm64/anames.go
deleted file mode 100644
index d1334596..00000000
--- a/vendor/github.com/google/gops/internal/obj/arm64/anames.go
+++ /dev/null
@@ -1,370 +0,0 @@
-// Generated by stringer -i a.out.go -o anames.go -p arm64
-// Do not edit.
-
-package arm64
-
-import "github.com/google/gops/internal/obj"
-
-var Anames = []string{
- obj.A_ARCHSPECIFIC: "ADC",
- "ADCS",
- "ADCSW",
- "ADCW",
- "ADD",
- "ADDS",
- "ADDSW",
- "ADDW",
- "ADR",
- "ADRP",
- "AND",
- "ANDS",
- "ANDSW",
- "ANDW",
- "ASR",
- "ASRW",
- "AT",
- "BFI",
- "BFIW",
- "BFM",
- "BFMW",
- "BFXIL",
- "BFXILW",
- "BIC",
- "BICS",
- "BICSW",
- "BICW",
- "BRK",
- "CBNZ",
- "CBNZW",
- "CBZ",
- "CBZW",
- "CCMN",
- "CCMNW",
- "CCMP",
- "CCMPW",
- "CINC",
- "CINCW",
- "CINV",
- "CINVW",
- "CLREX",
- "CLS",
- "CLSW",
- "CLZ",
- "CLZW",
- "CMN",
- "CMNW",
- "CMP",
- "CMPW",
- "CNEG",
- "CNEGW",
- "CRC32B",
- "CRC32CB",
- "CRC32CH",
- "CRC32CW",
- "CRC32CX",
- "CRC32H",
- "CRC32W",
- "CRC32X",
- "CSEL",
- "CSELW",
- "CSET",
- "CSETM",
- "CSETMW",
- "CSETW",
- "CSINC",
- "CSINCW",
- "CSINV",
- "CSINVW",
- "CSNEG",
- "CSNEGW",
- "DC",
- "DCPS1",
- "DCPS2",
- "DCPS3",
- "DMB",
- "DRPS",
- "DSB",
- "EON",
- "EONW",
- "EOR",
- "EORW",
- "ERET",
- "EXTR",
- "EXTRW",
- "HINT",
- "HLT",
- "HVC",
- "IC",
- "ISB",
- "LDAR",
- "LDARB",
- "LDARH",
- "LDARW",
- "LDAXP",
- "LDAXPW",
- "LDAXR",
- "LDAXRB",
- "LDAXRH",
- "LDAXRW",
- "LDP",
- "LDXR",
- "LDXRB",
- "LDXRH",
- "LDXRW",
- "LDXP",
- "LDXPW",
- "LSL",
- "LSLW",
- "LSR",
- "LSRW",
- "MADD",
- "MADDW",
- "MNEG",
- "MNEGW",
- "MOVK",
- "MOVKW",
- "MOVN",
- "MOVNW",
- "MOVZ",
- "MOVZW",
- "MRS",
- "MSR",
- "MSUB",
- "MSUBW",
- "MUL",
- "MULW",
- "MVN",
- "MVNW",
- "NEG",
- "NEGS",
- "NEGSW",
- "NEGW",
- "NGC",
- "NGCS",
- "NGCSW",
- "NGCW",
- "ORN",
- "ORNW",
- "ORR",
- "ORRW",
- "PRFM",
- "PRFUM",
- "RBIT",
- "RBITW",
- "REM",
- "REMW",
- "REV",
- "REV16",
- "REV16W",
- "REV32",
- "REVW",
- "ROR",
- "RORW",
- "SBC",
- "SBCS",
- "SBCSW",
- "SBCW",
- "SBFIZ",
- "SBFIZW",
- "SBFM",
- "SBFMW",
- "SBFX",
- "SBFXW",
- "SDIV",
- "SDIVW",
- "SEV",
- "SEVL",
- "SMADDL",
- "SMC",
- "SMNEGL",
- "SMSUBL",
- "SMULH",
- "SMULL",
- "STXR",
- "STXRB",
- "STXRH",
- "STXP",
- "STXPW",
- "STXRW",
- "STLP",
- "STLPW",
- "STLR",
- "STLRB",
- "STLRH",
- "STLRW",
- "STLXP",
- "STLXPW",
- "STLXR",
- "STLXRB",
- "STLXRH",
- "STLXRW",
- "STP",
- "SUB",
- "SUBS",
- "SUBSW",
- "SUBW",
- "SVC",
- "SXTB",
- "SXTBW",
- "SXTH",
- "SXTHW",
- "SXTW",
- "SYS",
- "SYSL",
- "TBNZ",
- "TBZ",
- "TLBI",
- "TST",
- "TSTW",
- "UBFIZ",
- "UBFIZW",
- "UBFM",
- "UBFMW",
- "UBFX",
- "UBFXW",
- "UDIV",
- "UDIVW",
- "UMADDL",
- "UMNEGL",
- "UMSUBL",
- "UMULH",
- "UMULL",
- "UREM",
- "UREMW",
- "UXTB",
- "UXTH",
- "UXTW",
- "UXTBW",
- "UXTHW",
- "WFE",
- "WFI",
- "YIELD",
- "MOVB",
- "MOVBU",
- "MOVH",
- "MOVHU",
- "MOVW",
- "MOVWU",
- "MOVD",
- "MOVNP",
- "MOVNPW",
- "MOVP",
- "MOVPD",
- "MOVPQ",
- "MOVPS",
- "MOVPSW",
- "MOVPW",
- "BEQ",
- "BNE",
- "BCS",
- "BHS",
- "BCC",
- "BLO",
- "BMI",
- "BPL",
- "BVS",
- "BVC",
- "BHI",
- "BLS",
- "BGE",
- "BLT",
- "BGT",
- "BLE",
- "FABSD",
- "FABSS",
- "FADDD",
- "FADDS",
- "FCCMPD",
- "FCCMPED",
- "FCCMPS",
- "FCCMPES",
- "FCMPD",
- "FCMPED",
- "FCMPES",
- "FCMPS",
- "FCVTSD",
- "FCVTDS",
- "FCVTZSD",
- "FCVTZSDW",
- "FCVTZSS",
- "FCVTZSSW",
- "FCVTZUD",
- "FCVTZUDW",
- "FCVTZUS",
- "FCVTZUSW",
- "FDIVD",
- "FDIVS",
- "FMOVD",
- "FMOVS",
- "FMULD",
- "FMULS",
- "FNEGD",
- "FNEGS",
- "FSQRTD",
- "FSQRTS",
- "FSUBD",
- "FSUBS",
- "SCVTFD",
- "SCVTFS",
- "SCVTFWD",
- "SCVTFWS",
- "UCVTFD",
- "UCVTFS",
- "UCVTFWD",
- "UCVTFWS",
- "WORD",
- "DWORD",
- "FCSELS",
- "FCSELD",
- "FMAXS",
- "FMINS",
- "FMAXD",
- "FMIND",
- "FMAXNMS",
- "FMAXNMD",
- "FNMULS",
- "FNMULD",
- "FRINTNS",
- "FRINTND",
- "FRINTPS",
- "FRINTPD",
- "FRINTMS",
- "FRINTMD",
- "FRINTZS",
- "FRINTZD",
- "FRINTAS",
- "FRINTAD",
- "FRINTXS",
- "FRINTXD",
- "FRINTIS",
- "FRINTID",
- "FMADDS",
- "FMADDD",
- "FMSUBS",
- "FMSUBD",
- "FNMADDS",
- "FNMADDD",
- "FNMSUBS",
- "FNMSUBD",
- "FMINNMS",
- "FMINNMD",
- "FCVTDH",
- "FCVTHS",
- "FCVTHD",
- "FCVTSH",
- "AESD",
- "AESE",
- "AESIMC",
- "AESMC",
- "SHA1C",
- "SHA1H",
- "SHA1M",
- "SHA1P",
- "SHA1SU0",
- "SHA1SU1",
- "SHA256H",
- "SHA256H2",
- "SHA256SU0",
- "SHA256SU1",
- "LAST",
-}
diff --git a/vendor/github.com/google/gops/internal/obj/arm64/anames7.go b/vendor/github.com/google/gops/internal/obj/arm64/anames7.go
deleted file mode 100644
index d55b34f9..00000000
--- a/vendor/github.com/google/gops/internal/obj/arm64/anames7.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2015 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 arm64
-
-var cnames7 = []string{
- "NONE",
- "REG",
- "RSP",
- "FREG",
- "VREG",
- "PAIR",
- "SHIFT",
- "EXTREG",
- "SPR",
- "COND",
- "ZCON",
- "ADDCON0",
- "ADDCON",
- "MOVCON",
- "BITCON",
- "ABCON0",
- "ABCON",
- "MBCON",
- "LCON",
- "VCON",
- "FCON",
- "VCONADDR",
- "AACON",
- "LACON",
- "AECON",
- "SBRA",
- "LBRA",
- "NPAUTO",
- "NSAUTO",
- "PSAUTO",
- "PPAUTO",
- "UAUTO4K",
- "UAUTO8K",
- "UAUTO16K",
- "UAUTO32K",
- "UAUTO64K",
- "LAUTO",
- "SEXT1",
- "SEXT2",
- "SEXT4",
- "SEXT8",
- "SEXT16",
- "LEXT",
- "ZOREG",
- "NPOREG",
- "NSOREG",
- "PSOREG",
- "PPOREG",
- "UOREG4K",
- "UOREG8K",
- "UOREG16K",
- "UOREG32K",
- "UOREG64K",
- "LOREG",
- "ADDR",
- "GOTADDR",
- "TLS_LE",
- "TLS_IE",
- "ROFF",
- "GOK",
- "TEXTSIZE",
- "NCLASS",
-}
diff --git a/vendor/github.com/google/gops/internal/obj/arm64/asm7.go b/vendor/github.com/google/gops/internal/obj/arm64/asm7.go
deleted file mode 100644
index a6dae2e4..00000000
--- a/vendor/github.com/google/gops/internal/obj/arm64/asm7.go
+++ /dev/null
@@ -1,4374 +0,0 @@
-// cmd/7l/asm.c, cmd/7l/asmout.c, cmd/7l/optab.c, cmd/7l/span.c, cmd/ld/sub.c, cmd/ld/mod.c, from Vita Nuova.
-// https://code.google.com/p/ken-cc/source/browse/
-//
-// 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-2007 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-2007 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 arm64
-
-import (
- "fmt"
- "log"
- "math"
- "sort"
-
- "github.com/google/gops/internal/obj"
-)
-
-const (
- funcAlign = 16
-)
-
-const (
- REGFROM = 1
-)
-
-type Optab struct {
- as obj.As
- a1 uint8
- a2 uint8
- a3 uint8
- type_ int8
- size int8
- param int16
- flag int8
- scond uint16
-}
-
-var oprange [ALAST & obj.AMask][]Optab
-
-var xcmp [C_NCLASS][C_NCLASS]bool
-
-const (
- S32 = 0 << 31
- S64 = 1 << 31
- Sbit = 1 << 29
- LSL0_32 = 2 << 13
- LSL0_64 = 3 << 13
-)
-
-func OPDP2(x uint32) uint32 {
- return 0<<30 | 0<<29 | 0xd6<<21 | x<<10
-}
-
-func OPDP3(sf uint32, op54 uint32, op31 uint32, o0 uint32) uint32 {
- return sf<<31 | op54<<29 | 0x1B<<24 | op31<<21 | o0<<15
-}
-
-func OPBcc(x uint32) uint32 {
- return 0x2A<<25 | 0<<24 | 0<<4 | x&15
-}
-
-func OPBLR(x uint32) uint32 {
- /* x=0, JMP; 1, CALL; 2, RET */
- return 0x6B<<25 | 0<<23 | x<<21 | 0x1F<<16 | 0<<10
-}
-
-func SYSOP(l uint32, op0 uint32, op1 uint32, crn uint32, crm uint32, op2 uint32, rt uint32) uint32 {
- return 0x354<<22 | l<<21 | op0<<19 | op1<<16 | crn&15<<12 | crm&15<<8 | op2<<5 | rt
-}
-
-func SYSHINT(x uint32) uint32 {
- return SYSOP(0, 0, 3, 2, 0, x, 0x1F)
-}
-
-func LDSTR12U(sz uint32, v uint32, opc uint32) uint32 {
- return sz<<30 | 7<<27 | v<<26 | 1<<24 | opc<<22
-}
-
-func LDSTR9S(sz uint32, v uint32, opc uint32) uint32 {
- return sz<<30 | 7<<27 | v<<26 | 0<<24 | opc<<22
-}
-
-func LD2STR(o uint32) uint32 {
- return o &^ (3 << 22)
-}
-
-func LDSTX(sz uint32, o2 uint32, l uint32, o1 uint32, o0 uint32) uint32 {
- return sz<<30 | 0x8<<24 | o2<<23 | l<<22 | o1<<21 | o0<<15
-}
-
-func FPCMP(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 {
- return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<14 | 8<<10 | op2
-}
-
-func FPCCMP(m uint32, s uint32, type_ uint32, op uint32) uint32 {
- return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | 1<<10 | op<<4
-}
-
-func FPOP1S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
- return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<15 | 0x10<<10
-}
-
-func FPOP2S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
- return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<12 | 2<<10
-}
-
-func FPCVTI(sf uint32, s uint32, type_ uint32, rmode uint32, op uint32) uint32 {
- return sf<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | rmode<<19 | op<<16 | 0<<10
-}
-
-func ADR(p uint32, o uint32, rt uint32) uint32 {
- return p<<31 | (o&3)<<29 | 0x10<<24 | ((o>>2)&0x7FFFF)<<5 | rt&31
-}
-
-func OPBIT(x uint32) uint32 {
- return 1<<30 | 0<<29 | 0xD6<<21 | 0<<16 | x<<10
-}
-
-const (
- LFROM = 1 << 0
- LTO = 1 << 1
-)
-
-var optab = []Optab{
- /* struct Optab:
- OPCODE, from, prog->reg, to, type,size,param,flag,scond */
- {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0},
-
- /* arithmetic operations */
- {AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
- {AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
- {AADC, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
- {AADC, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
- {ANEG, C_REG, C_NONE, C_REG, 25, 4, 0, 0, 0},
- {ANEG, C_NONE, C_NONE, C_REG, 25, 4, 0, 0, 0},
- {ANGC, C_REG, C_NONE, C_REG, 17, 4, 0, 0, 0},
- {ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0},
- {AADD, C_ADDCON, C_RSP, C_RSP, 2, 4, 0, 0, 0},
- {AADD, C_ADDCON, C_NONE, C_RSP, 2, 4, 0, 0, 0},
- {ACMP, C_ADDCON, C_RSP, C_NONE, 2, 4, 0, 0, 0},
- {AADD, C_MOVCON, C_RSP, C_RSP, 62, 8, 0, 0, 0},
- {AADD, C_MOVCON, C_NONE, C_RSP, 62, 8, 0, 0, 0},
- {ACMP, C_MOVCON, C_RSP, C_NONE, 62, 8, 0, 0, 0},
- {AADD, C_BITCON, C_RSP, C_RSP, 62, 8, 0, 0, 0},
- {AADD, C_BITCON, C_NONE, C_RSP, 62, 8, 0, 0, 0},
- {ACMP, C_BITCON, C_RSP, C_NONE, 62, 8, 0, 0, 0},
- {AADD, C_VCON, C_RSP, C_RSP, 13, 8, 0, LFROM, 0},
- {AADD, C_VCON, C_NONE, C_RSP, 13, 8, 0, LFROM, 0},
- {ACMP, C_VCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0},
- {AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
- {AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
- {AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
- {ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0},
- {ANEG, C_SHIFT, C_NONE, C_REG, 26, 4, 0, 0, 0},
- {AADD, C_REG, C_RSP, C_RSP, 27, 4, 0, 0, 0},
- {AADD, C_REG, C_NONE, C_RSP, 27, 4, 0, 0, 0},
- {ACMP, C_REG, C_RSP, C_NONE, 27, 4, 0, 0, 0},
- {AADD, C_EXTREG, C_RSP, C_RSP, 27, 4, 0, 0, 0},
- {AADD, C_EXTREG, C_NONE, C_RSP, 27, 4, 0, 0, 0},
- {AMVN, C_EXTREG, C_NONE, C_RSP, 27, 4, 0, 0, 0},
- {ACMP, C_EXTREG, C_RSP, C_NONE, 27, 4, 0, 0, 0},
- {AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
- {AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-
- /* logical operations */
- {AAND, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
- {AAND, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
- {ABIC, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
- {ABIC, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
- {AAND, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0},
- {AAND, C_BITCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
- {ABIC, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0},
- {ABIC, C_BITCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
- {AAND, C_MOVCON, C_REG, C_REG, 62, 8, 0, 0, 0},
- {AAND, C_MOVCON, C_NONE, C_REG, 62, 8, 0, 0, 0},
- {ABIC, C_MOVCON, C_REG, C_REG, 62, 8, 0, 0, 0},
- {ABIC, C_MOVCON, C_NONE, C_REG, 62, 8, 0, 0, 0},
- {AAND, C_VCON, C_REG, C_REG, 28, 8, 0, LFROM, 0},
- {AAND, C_VCON, C_NONE, C_REG, 28, 8, 0, LFROM, 0},
- {ABIC, C_VCON, C_REG, C_REG, 28, 8, 0, LFROM, 0},
- {ABIC, C_VCON, C_NONE, C_REG, 28, 8, 0, LFROM, 0},
- {AAND, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
- {AAND, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
- {ABIC, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
- {ABIC, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
- {AMOVD, C_RSP, C_NONE, C_RSP, 24, 4, 0, 0, 0},
- {AMVN, C_REG, C_NONE, C_REG, 24, 4, 0, 0, 0},
- {AMOVB, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0},
- {AMOVH, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVHU */
- {AMOVW, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVWU */
- /* TODO: MVN C_SHIFT */
-
- /* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
- {AMOVW, C_MOVCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
- {AMOVD, C_MOVCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
-
- // TODO: these don't work properly.
- // { AMOVW, C_ADDCON, C_NONE, C_REG, 2, 4, 0 , 0},
- // { AMOVD, C_ADDCON, C_NONE, C_REG, 2, 4, 0 , 0},
- {AMOVW, C_BITCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
- {AMOVD, C_BITCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
-
- {AMOVK, C_VCON, C_NONE, C_REG, 33, 4, 0, 0, 0},
- {AMOVD, C_AACON, C_NONE, C_REG, 4, 4, REGFROM, 0, 0},
- {ASDIV, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
- {ASDIV, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
- {AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
- {ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
- {AB, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
- {ABL, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0},
- {ABL, C_REG, C_NONE, C_REG, 6, 4, 0, 0, 0},
- {ABL, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
- {obj.ARET, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0},
- {obj.ARET, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
- {AADRP, C_SBRA, C_NONE, C_REG, 60, 4, 0, 0, 0},
- {AADR, C_SBRA, C_NONE, C_REG, 61, 4, 0, 0, 0},
- {ABFM, C_VCON, C_REG, C_REG, 42, 4, 0, 0, 0},
- {ABFI, C_VCON, C_REG, C_REG, 43, 4, 0, 0, 0},
- {AEXTR, C_VCON, C_REG, C_REG, 44, 4, 0, 0, 0},
- {ASXTB, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0},
- {ACLS, C_REG, C_NONE, C_REG, 46, 4, 0, 0, 0},
- {ABEQ, C_NONE, C_NONE, C_SBRA, 7, 4, 0, 0, 0},
- {ALSL, C_VCON, C_REG, C_REG, 8, 4, 0, 0, 0},
- {ALSL, C_VCON, C_NONE, C_REG, 8, 4, 0, 0, 0},
- {ALSL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
- {ALSL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0},
- {ASVC, C_NONE, C_NONE, C_VCON, 10, 4, 0, 0, 0},
- {ASVC, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
- {ADWORD, C_NONE, C_NONE, C_VCON, 11, 8, 0, 0, 0},
- {ADWORD, C_NONE, C_NONE, C_LEXT, 11, 8, 0, 0, 0},
- {ADWORD, C_NONE, C_NONE, C_ADDR, 11, 8, 0, 0, 0},
- {ADWORD, C_NONE, C_NONE, C_LACON, 11, 8, 0, 0, 0},
- {AWORD, C_NONE, C_NONE, C_LCON, 14, 4, 0, 0, 0},
- {AWORD, C_NONE, C_NONE, C_LEXT, 14, 4, 0, 0, 0},
- {AWORD, C_NONE, C_NONE, C_ADDR, 14, 4, 0, 0, 0},
- {AMOVW, C_VCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
- {AMOVW, C_VCONADDR, C_NONE, C_REG, 68, 8, 0, 0, 0},
- {AMOVD, C_VCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
- {AMOVD, C_VCONADDR, C_NONE, C_REG, 68, 8, 0, 0, 0},
- {AMOVB, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
- {AMOVH, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
- {AMOVW, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
- {AMOVD, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
- {AMOVB, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
- {AMOVBU, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
- {AMOVH, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
- {AMOVW, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
- {AMOVD, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
- {AMOVD, C_GOTADDR, C_NONE, C_REG, 71, 8, 0, 0, 0},
- {AMOVD, C_TLS_LE, C_NONE, C_REG, 69, 4, 0, 0, 0},
- {AMOVD, C_TLS_IE, C_NONE, C_REG, 70, 8, 0, 0, 0},
- {AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
- {AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0},
- {AMADD, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
- {AREM, C_REG, C_REG, C_REG, 16, 8, 0, 0, 0},
- {AREM, C_REG, C_NONE, C_REG, 16, 8, 0, 0, 0},
- {ACSEL, C_COND, C_REG, C_REG, 18, 4, 0, 0, 0}, /* from3 optional */
- {ACSET, C_COND, C_NONE, C_REG, 18, 4, 0, 0, 0},
- {ACCMN, C_COND, C_REG, C_VCON, 19, 4, 0, 0, 0}, /* from3 either C_REG or C_VCON */
-
- /* scaled 12-bit unsigned displacement store */
- {AMOVB, C_REG, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
- {AMOVB, C_REG, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
-
- {AMOVH, C_REG, C_NONE, C_UAUTO8K, 20, 4, REGSP, 0, 0},
- {AMOVH, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
- {AMOVH, C_REG, C_NONE, C_UOREG8K, 20, 4, 0, 0, 0},
-
- {AMOVW, C_REG, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
- {AMOVW, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
- {AMOVW, C_REG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
-
- /* unscaled 9-bit signed displacement store */
- {AMOVB, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
- {AMOVB, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
-
- {AMOVH, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
- {AMOVH, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
- {AMOVW, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
- {AMOVW, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
-
- {AMOVD, C_REG, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0},
- {AMOVD, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
- {AMOVD, C_REG, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0},
- {AMOVD, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
- {AMOVD, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
-
- /* short displacement load */
- {AMOVB, C_UAUTO4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVB, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVB, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
- {AMOVB, C_UOREG4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVB, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-
- {AMOVBU, C_UAUTO4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVBU, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVBU, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
- {AMOVBU, C_UOREG4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVBU, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-
- {AMOVH, C_UAUTO8K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVH, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVH, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
- {AMOVH, C_UOREG8K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVH, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-
- {AMOVW, C_UAUTO16K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVW, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVW, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
- {AMOVW, C_UOREG16K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVW, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-
- {AMOVD, C_UAUTO32K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVD, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVD, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
- {AMOVD, C_UOREG32K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
- {AMOVD, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-
- /* long displacement store */
- {AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
- {AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
- {AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
- {AMOVH, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
- {AMOVH, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
- {AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
- {AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
- {AMOVD, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
- {AMOVD, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
-
- /* long displacement load */
- {AMOVB, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
- {AMOVB, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVB, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
- {AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVH, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
- {AMOVH, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVH, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
- {AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVD, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
- {AMOVD, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
- {AMOVD, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
-
- /* load long effective stack address (load int32 offset and add) */
- {AMOVD, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0},
-
- /* pre/post-indexed load (unscaled, signed 9-bit offset) */
- {AMOVD, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
- {AMOVW, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
- {AMOVH, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
- {AMOVB, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
- {AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
- {AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
- {AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
- {AMOVD, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
- {AMOVW, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
- {AMOVH, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
- {AMOVB, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
- {AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
- {AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
- {AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
-
- /* pre/post-indexed store (unscaled, signed 9-bit offset) */
- {AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
- {AMOVW, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
- {AMOVH, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
- {AMOVB, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
- {AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
- {AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
- {AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
- {AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
- {AMOVW, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
- {AMOVH, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
- {AMOVB, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
- {AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
- {AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
- {AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
-
- /* pre/post-indexed load/store register pair
- (unscaled, signed 10-bit quad-aligned offset) */
- {ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
- {ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
- {ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPRE},
- {ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPOST},
-
- /* special */
- {AMOVD, C_SPR, C_NONE, C_REG, 35, 4, 0, 0, 0},
- {AMRS, C_SPR, C_NONE, C_REG, 35, 4, 0, 0, 0},
- {AMOVD, C_REG, C_NONE, C_SPR, 36, 4, 0, 0, 0},
- {AMSR, C_REG, C_NONE, C_SPR, 36, 4, 0, 0, 0},
- {AMOVD, C_VCON, C_NONE, C_SPR, 37, 4, 0, 0, 0},
- {AMSR, C_VCON, C_NONE, C_SPR, 37, 4, 0, 0, 0},
- {AERET, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
- {AFMOVS, C_UAUTO16K, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
- {AFMOVS, C_NSAUTO, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
- {AFMOVS, C_ZOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
- {AFMOVS, C_UOREG16K, C_NONE, C_FREG, 21, 4, 0, 0, 0},
- {AFMOVS, C_NSOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
- {AFMOVD, C_UAUTO32K, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
- {AFMOVD, C_NSAUTO, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
- {AFMOVD, C_ZOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
- {AFMOVD, C_UOREG32K, C_NONE, C_FREG, 21, 4, 0, 0, 0},
- {AFMOVD, C_NSOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
- {AFMOVS, C_FREG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
- {AFMOVD, C_FREG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
- {AFMOVD, C_FREG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
- {AFMOVS, C_LAUTO, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0},
- {AFMOVS, C_LOREG, C_NONE, C_FREG, 31, 8, 0, LFROM, 0},
- {AFMOVD, C_LAUTO, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0},
- {AFMOVD, C_LOREG, C_NONE, C_FREG, 31, 8, 0, LFROM, 0},
- {AFMOVS, C_FREG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
- {AFMOVS, C_ADDR, C_NONE, C_FREG, 65, 12, 0, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
- {AFMOVD, C_ADDR, C_NONE, C_FREG, 65, 12, 0, 0, 0},
- {AFADDS, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
- {AFADDS, C_FREG, C_FREG, C_FREG, 54, 4, 0, 0, 0},
- {AFADDS, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0},
- {AFADDS, C_FCON, C_FREG, C_FREG, 54, 4, 0, 0, 0},
- {AFMOVS, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
- {AFMOVD, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
- {AFCVTZSD, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0},
- {ASCVTFD, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
- {AFMOVS, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
- {AFMOVS, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0},
- {AFMOVD, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
- {AFMOVD, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0},
- {AFCMPS, C_FREG, C_FREG, C_NONE, 56, 4, 0, 0, 0},
- {AFCMPS, C_FCON, C_FREG, C_NONE, 56, 4, 0, 0, 0},
- {AFCCMPS, C_COND, C_REG, C_VCON, 57, 4, 0, 0, 0},
- {AFCSELD, C_COND, C_REG, C_FREG, 18, 4, 0, 0, 0},
- {AFCVTSD, C_FREG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
- {ACLREX, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0},
- {ACLREX, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0},
- {ACBZ, C_REG, C_NONE, C_SBRA, 39, 4, 0, 0, 0},
- {ATBZ, C_VCON, C_REG, C_SBRA, 40, 4, 0, 0, 0},
- {ASYS, C_VCON, C_NONE, C_NONE, 50, 4, 0, 0, 0},
- {ASYS, C_VCON, C_REG, C_NONE, 50, 4, 0, 0, 0},
- {ASYSL, C_VCON, C_NONE, C_REG, 50, 4, 0, 0, 0},
- {ADMB, C_VCON, C_NONE, C_NONE, 51, 4, 0, 0, 0},
- {AHINT, C_VCON, C_NONE, C_NONE, 52, 4, 0, 0, 0},
- {ALDAR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
- {ALDXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
- {ALDAXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
- {ALDXP, C_ZOREG, C_REG, C_REG, 58, 4, 0, 0, 0},
- {ASTLR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_NONE
- {ASTXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG
- {ASTLXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG
-
- // { ASTXP, C_REG, C_NONE, C_ZOREG, 59, 4, 0 , 0}, // TODO(aram):
-
- {AAESD, C_VREG, C_NONE, C_VREG, 29, 4, 0, 0, 0},
- {ASHA1C, C_VREG, C_REG, C_VREG, 1, 4, 0, 0, 0},
-
- {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0},
- {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0},
- {obj.APCDATA, C_VCON, C_NONE, C_VCON, 0, 0, 0, 0, 0},
- {obj.AFUNCDATA, C_VCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
- {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
- {obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL
- {obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL
-
- {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0},
-}
-
-/*
- * valid pstate field values, and value to use in instruction
- */
-var pstatefield = []struct {
- a uint32
- b uint32
-}{
- {REG_SPSel, 0<<16 | 4<<12 | 5<<5},
- {REG_DAIFSet, 3<<16 | 4<<12 | 6<<5},
- {REG_DAIFClr, 3<<16 | 4<<12 | 7<<5},
-}
-
-var pool struct {
- start uint32
- size uint32
-}
-
-func prasm(p *obj.Prog) {
- fmt.Printf("%v\n", p)
-}
-
-func span7(ctxt *obj.Link, cursym *obj.LSym) {
- p := cursym.Text
- if p == nil || p.Link == nil { // handle external functions and ELF section symbols
- return
- }
- ctxt.Cursym = cursym
- ctxt.Autosize = int32(p.To.Offset&0xffffffff) + 8
-
- if oprange[AAND&obj.AMask] == nil {
- buildop(ctxt)
- }
-
- bflag := 1
- c := int64(0)
- p.Pc = c
- var m int
- var o *Optab
- for p = p.Link; p != nil; p = p.Link {
- ctxt.Curp = p
- if p.As == ADWORD && (c&7) != 0 {
- c += 4
- }
- p.Pc = c
- o = oplook(ctxt, p)
- m = int(o.size)
- if m == 0 {
- if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
- ctxt.Diag("zero-width instruction\n%v", p)
- }
- continue
- }
-
- switch o.flag & (LFROM | LTO) {
- case LFROM:
- addpool(ctxt, p, &p.From)
-
- case LTO:
- addpool(ctxt, p, &p.To)
- break
- }
-
- if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */
- checkpool(ctxt, p, 0)
- }
- c += int64(m)
- if ctxt.Blitrl != nil {
- checkpool(ctxt, p, 1)
- }
- }
-
- cursym.Size = c
-
- /*
- * if any procedure is large enough to
- * generate a large SBRA branch, then
- * generate extra passes putting branches
- * around jmps to fix. this is rare.
- */
- for bflag != 0 {
- if ctxt.Debugvlog != 0 {
- ctxt.Logf("%5.2f span1\n", obj.Cputime())
- }
- bflag = 0
- c = 0
- for p = cursym.Text.Link; p != nil; p = p.Link {
- if p.As == ADWORD && (c&7) != 0 {
- c += 4
- }
- p.Pc = c
- o = oplook(ctxt, p)
-
- /* very large branches */
- if o.type_ == 7 && p.Pcond != nil {
- otxt := p.Pcond.Pc - c
- if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 {
- q := ctxt.NewProg()
- q.Link = p.Link
- p.Link = q
- q.As = AB
- q.To.Type = obj.TYPE_BRANCH
- q.Pcond = p.Pcond
- p.Pcond = q
- q = ctxt.NewProg()
- q.Link = p.Link
- p.Link = q
- q.As = AB
- q.To.Type = obj.TYPE_BRANCH
- q.Pcond = q.Link.Link
- bflag = 1
- }
- }
- m = int(o.size)
-
- if m == 0 {
- if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
- ctxt.Diag("zero-width instruction\n%v", p)
- }
- continue
- }
-
- c += int64(m)
- }
- }
-
- c += -c & (funcAlign - 1)
- cursym.Size = c
-
- /*
- * lay out the code, emitting code and data relocations.
- */
- cursym.Grow(cursym.Size)
- bp := cursym.P
- psz := int32(0)
- var i int
- var out [6]uint32
- for p := cursym.Text.Link; p != nil; p = p.Link {
- ctxt.Pc = p.Pc
- ctxt.Curp = p
- o = oplook(ctxt, p)
-
- // need to align DWORDs on 8-byte boundary. The ISA doesn't
- // require it, but the various 64-bit loads we generate assume it.
- if o.as == ADWORD && psz%8 != 0 {
- bp[3] = 0
- bp[2] = bp[3]
- bp[1] = bp[2]
- bp[0] = bp[1]
- bp = bp[4:]
- psz += 4
- }
-
- if int(o.size) > 4*len(out) {
- log.Fatalf("out array in span7 is too small, need at least %d for %v", o.size/4, p)
- }
- asmout(ctxt, p, o, out[:])
- for i = 0; i < int(o.size/4); i++ {
- ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
- bp = bp[4:]
- psz += 4
- }
- }
-}
-
-/*
- * when the first reference to the literal pool threatens
- * to go out of range of a 1Mb PC-relative offset
- * drop the pool now, and branch round it.
- */
-func checkpool(ctxt *obj.Link, p *obj.Prog, skip int) {
- if pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(pool.size)-int64(pool.start)+8)) {
- flushpool(ctxt, p, skip)
- } else if p.Link == nil {
- flushpool(ctxt, p, 2)
- }
-}
-
-func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) {
- if ctxt.Blitrl != nil {
- if skip != 0 {
- if ctxt.Debugvlog != 0 && skip == 1 {
- fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start)
- }
- q := ctxt.NewProg()
- q.As = AB
- q.To.Type = obj.TYPE_BRANCH
- q.Pcond = p.Link
- q.Link = ctxt.Blitrl
- q.Lineno = p.Lineno
- ctxt.Blitrl = q
- } else if p.Pc+int64(pool.size)-int64(pool.start) < maxPCDisp {
- return
- }
-
- // The line number for constant pool entries doesn't really matter.
- // We set it to the line number of the preceding instruction so that
- // there are no deltas to encode in the pc-line tables.
- for q := ctxt.Blitrl; q != nil; q = q.Link {
- q.Lineno = p.Lineno
- }
-
- ctxt.Elitrl.Link = p.Link
- p.Link = ctxt.Blitrl
-
- ctxt.Blitrl = nil /* BUG: should refer back to values until out-of-range */
- ctxt.Elitrl = nil
- pool.size = 0
- pool.start = 0
- }
-}
-
-/*
- * TODO: hash
- */
-func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
- c := aclass(ctxt, a)
- lit := ctxt.Instoffset
- t := *ctxt.NewProg()
- t.As = AWORD
- sz := 4
-
- // MOVD foo(SB), R is actually
- // MOVD addr, REGTMP
- // MOVD REGTMP, R
- // where addr is the address of the DWORD containing the address of foo.
- if p.As == AMOVD || c == C_ADDR || c == C_VCON || int64(lit) != int64(int32(lit)) || uint64(lit) != uint64(uint32(lit)) {
- // conservative: don't know if we want signed or unsigned extension.
- // in case of ambiguity, store 64-bit
- t.As = ADWORD
- sz = 8
- }
-
- switch c {
- // TODO(aram): remove.
- default:
- if a.Name != obj.NAME_EXTERN {
- fmt.Printf("addpool: %v in %v shouldn't go to default case\n", DRconv(c), p)
- }
-
- t.To.Offset = a.Offset
- t.To.Sym = a.Sym
- t.To.Type = a.Type
- t.To.Name = a.Name
-
- /* This is here because MOV uint12<<12, R is disabled in optab.
- Because of this, we need to load the constant from memory. */
- case C_ADDCON:
- fallthrough
-
- case C_PSAUTO,
- C_PPAUTO,
- C_UAUTO4K,
- C_UAUTO8K,
- C_UAUTO16K,
- C_UAUTO32K,
- C_UAUTO64K,
- C_NSAUTO,
- C_NPAUTO,
- C_LAUTO,
- C_PPOREG,
- C_PSOREG,
- C_UOREG4K,
- C_UOREG8K,
- C_UOREG16K,
- C_UOREG32K,
- C_UOREG64K,
- C_NSOREG,
- C_NPOREG,
- C_LOREG,
- C_LACON,
- C_LCON,
- C_VCON:
- if a.Name == obj.NAME_EXTERN {
- fmt.Printf("addpool: %v in %v needs reloc\n", DRconv(c), p)
- }
-
- t.To.Type = obj.TYPE_CONST
- t.To.Offset = lit
- break
- }
-
- for q := ctxt.Blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
- if q.To == t.To {
- p.Pcond = q
- return
- }
- }
-
- q := ctxt.NewProg()
- *q = t
- q.Pc = int64(pool.size)
- if ctxt.Blitrl == nil {
- ctxt.Blitrl = q
- pool.start = uint32(p.Pc)
- } else {
- ctxt.Elitrl.Link = q
- }
- ctxt.Elitrl = q
- pool.size = -pool.size & (funcAlign - 1)
- pool.size += uint32(sz)
- p.Pcond = q
-}
-
-func regoff(ctxt *obj.Link, a *obj.Addr) uint32 {
- ctxt.Instoffset = 0
- aclass(ctxt, a)
- return uint32(ctxt.Instoffset)
-}
-
-// Maximum PC-relative displacement.
-// The actual limit is ±2²⁰, but we are conservative
-// to avoid needing to recompute the literal pool flush points
-// as span-dependent jumps are enlarged.
-const maxPCDisp = 512 * 1024
-
-// ispcdisp reports whether v is a valid PC-relative displacement.
-func ispcdisp(v int32) bool {
- return -maxPCDisp < v && v < maxPCDisp && v&3 == 0
-}
-
-func isaddcon(v int64) bool {
- /* uimm12 or uimm24? */
- if v < 0 {
- return false
- }
- if (v & 0xFFF) == 0 {
- v >>= 12
- }
- return v <= 0xFFF
-}
-
-// isbitcon returns whether a constant can be encoded into a logical instruction.
-// bitcon has a binary form of repetition of a bit sequence of length 2, 4, 8, 16, 32, or 64,
-// which itself is a rotate (w.r.t. the length of the unit) of a sequence of ones.
-// special cases: 0 and -1 are not bitcon.
-// this function needs to run against virtually all the constants, so it needs to be fast.
-// for this reason, bitcon testing and bitcon encoding are separate functions.
-func isbitcon(x uint64) bool {
- if x == 1<<64-1 || x == 0 {
- return false
- }
- // determine the period and sign-extend a unit to 64 bits
- switch {
- case x != x>>32|x<<32:
- // period is 64
- // nothing to do
- case x != x>>16|x<<48:
- // period is 32
- x = uint64(int64(int32(x)))
- case x != x>>8|x<<56:
- // period is 16
- x = uint64(int64(int16(x)))
- case x != x>>4|x<<60:
- // period is 8
- x = uint64(int64(int8(x)))
- default:
- // period is 4 or 2, always true
- // 0001, 0010, 0100, 1000 -- 0001 rotate
- // 0011, 0110, 1100, 1001 -- 0011 rotate
- // 0111, 1011, 1101, 1110 -- 0111 rotate
- // 0101, 1010 -- 01 rotate, repeat
- return true
- }
- return sequenceOfOnes(x) || sequenceOfOnes(^x)
-}
-
-// sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros
-func sequenceOfOnes(x uint64) bool {
- y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2
- y += x
- return (y-1)&y == 0
-}
-
-// bitconEncode returns the encoding of a bitcon used in logical instructions
-// x is known to be a bitcon
-// a bitcon is a sequence of n ones at low bits (i.e. 1<<n-1), right rotated
-// by R bits, and repeated with period of 64, 32, 16, 8, 4, or 2.
-// it is encoded in logical instructions with 3 bitfields
-// N (1 bit) : R (6 bits) : S (6 bits), where
-// N=1 -- period=64
-// N=0, S=0xxxxx -- period=32
-// N=0, S=10xxxx -- period=16
-// N=0, S=110xxx -- period=8
-// N=0, S=1110xx -- period=4
-// N=0, S=11110x -- period=2
-// R is the shift amount, low bits of S = n-1
-func bitconEncode(x uint64, mode int) uint32 {
- var period uint32
- // determine the period and sign-extend a unit to 64 bits
- switch {
- case x != x>>32|x<<32:
- period = 64
- case x != x>>16|x<<48:
- period = 32
- x = uint64(int64(int32(x)))
- case x != x>>8|x<<56:
- period = 16
- x = uint64(int64(int16(x)))
- case x != x>>4|x<<60:
- period = 8
- x = uint64(int64(int8(x)))
- case x != x>>2|x<<62:
- period = 4
- x = uint64(int64(x<<60) >> 60)
- default:
- period = 2
- x = uint64(int64(x<<62) >> 62)
- }
- neg := false
- if int64(x) < 0 {
- x = ^x
- neg = true
- }
- y := x & -x // lowest set bit of x.
- s := log2(y)
- n := log2(x+y) - s // x (or ^x) is a sequence of n ones left shifted by s bits
- if neg {
- // ^x is a sequence of n ones left shifted by s bits
- // adjust n, s for x
- s = n + s
- n = period - n
- }
-
- N := uint32(0)
- if mode == 64 && period == 64 {
- N = 1
- }
- R := (period - s) & (period - 1) & uint32(mode-1) // shift amount of right rotate
- S := (n - 1) | 63&^(period<<1-1) // low bits = #ones - 1, high bits encodes period
- return N<<22 | R<<16 | S<<10
-}
-
-func log2(x uint64) uint32 {
- if x == 0 {
- panic("log2 of 0")
- }
- n := uint32(0)
- if x >= 1<<32 {
- x >>= 32
- n += 32
- }
- if x >= 1<<16 {
- x >>= 16
- n += 16
- }
- if x >= 1<<8 {
- x >>= 8
- n += 8
- }
- if x >= 1<<4 {
- x >>= 4
- n += 4
- }
- if x >= 1<<2 {
- x >>= 2
- n += 2
- }
- if x >= 1<<1 {
- x >>= 1
- n += 1
- }
- return n
-}
-
-func autoclass(l int64) int {
- if l < 0 {
- if l >= -256 {
- return C_NSAUTO
- }
- if l >= -512 && (l&7) == 0 {
- return C_NPAUTO
- }
- return C_LAUTO
- }
-
- if l <= 255 {
- return C_PSAUTO
- }
- if l <= 504 && (l&7) == 0 {
- return C_PPAUTO
- }
- if l <= 4095 {
- return C_UAUTO4K
- }
- if l <= 8190 && (l&1) == 0 {
- return C_UAUTO8K
- }
- if l <= 16380 && (l&3) == 0 {
- return C_UAUTO16K
- }
- if l <= 32760 && (l&7) == 0 {
- return C_UAUTO32K
- }
- if l <= 65520 && (l&0xF) == 0 {
- return C_UAUTO64K
- }
- return C_LAUTO
-}
-
-func oregclass(l int64) int {
- if l == 0 {
- return C_ZOREG
- }
- return autoclass(l) - C_NPAUTO + C_NPOREG
-}
-
-/*
- * given an offset v and a class c (see above)
- * return the offset value to use in the instruction,
- * scaled if necessary
- */
-func offsetshift(ctxt *obj.Link, v int64, c int) int64 {
- s := 0
- if c >= C_SEXT1 && c <= C_SEXT16 {
- s = c - C_SEXT1
- } else if c >= C_UAUTO4K && c <= C_UAUTO64K {
- s = c - C_UAUTO4K
- } else if c >= C_UOREG4K && c <= C_UOREG64K {
- s = c - C_UOREG4K
- }
- vs := v >> uint(s)
- if vs<<uint(s) != v {
- ctxt.Diag("odd offset: %d\n%v", v, ctxt.Curp)
- }
- return vs
-}
-
-/*
- * if v contains a single 16-bit value aligned
- * on a 16-bit field, and thus suitable for movk/movn,
- * return the field index 0 to 3; otherwise return -1
- */
-func movcon(v int64) int {
- for s := 0; s < 64; s += 16 {
- if (uint64(v) &^ (uint64(0xFFFF) << uint(s))) == 0 {
- return s / 16
- }
- }
- return -1
-}
-
-func rclass(r int16) int {
- switch {
- case REG_R0 <= r && r <= REG_R30: // not 31
- return C_REG
- case r == REGZERO:
- return C_ZCON
- case REG_F0 <= r && r <= REG_F31:
- return C_FREG
- case REG_V0 <= r && r <= REG_V31:
- return C_VREG
- case COND_EQ <= r && r <= COND_NV:
- return C_COND
- case r == REGSP:
- return C_RSP
- case r&REG_EXT != 0:
- return C_EXTREG
- case r >= REG_SPECIAL:
- return C_SPR
- }
- return C_GOK
-}
-
-func aclass(ctxt *obj.Link, a *obj.Addr) int {
- switch a.Type {
- case obj.TYPE_NONE:
- return C_NONE
-
- case obj.TYPE_REG:
- return rclass(a.Reg)
-
- case obj.TYPE_REGREG:
- return C_PAIR
-
- case obj.TYPE_SHIFT:
- return C_SHIFT
-
- case obj.TYPE_MEM:
- switch a.Name {
- case obj.NAME_EXTERN, obj.NAME_STATIC:
- if a.Sym == nil {
- break
- }
- ctxt.Instoffset = a.Offset
- if a.Sym != nil { // use relocation
- if a.Sym.Type == obj.STLSBSS {
- if ctxt.Flag_shared {
- return C_TLS_IE
- } else {
- return C_TLS_LE
- }
- }
- return C_ADDR
- }
- return C_LEXT
-
- case obj.NAME_GOTREF:
- return C_GOTADDR
-
- case obj.NAME_AUTO:
- ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
- return autoclass(ctxt.Instoffset)
-
- case obj.NAME_PARAM:
- ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
- return autoclass(ctxt.Instoffset)
-
- case obj.NAME_NONE:
- ctxt.Instoffset = a.Offset
- return oregclass(ctxt.Instoffset)
- }
- return C_GOK
-
- case obj.TYPE_FCONST:
- return C_FCON
-
- case obj.TYPE_TEXTSIZE:
- return C_TEXTSIZE
-
- case obj.TYPE_CONST, obj.TYPE_ADDR:
- switch a.Name {
- case obj.NAME_NONE:
- ctxt.Instoffset = a.Offset
- if a.Reg != 0 && a.Reg != REGZERO {
- goto aconsize
- }
- v := ctxt.Instoffset
- if v == 0 {
- return C_ZCON
- }
- if isaddcon(v) {
- if v <= 0xFFF {
- if isbitcon(uint64(v)) {
- return C_ABCON0
- }
- return C_ADDCON0
- }
- if isbitcon(uint64(v)) {
- return C_ABCON
- }
- return C_ADDCON
- }
-
- t := movcon(v)
- if t >= 0 {
- if isbitcon(uint64(v)) {
- return C_MBCON
- }
- return C_MOVCON
- }
-
- t = movcon(^v)
- if t >= 0 {
- if isbitcon(uint64(v)) {
- return C_MBCON
- }
- return C_MOVCON
- }
-
- if isbitcon(uint64(v)) {
- return C_BITCON
- }
-
- if uint64(v) == uint64(uint32(v)) || v == int64(int32(v)) {
- return C_LCON
- }
- return C_VCON
-
- case obj.NAME_EXTERN, obj.NAME_STATIC:
- if a.Sym == nil {
- break
- }
- if a.Sym.Type == obj.STLSBSS {
- ctxt.Diag("taking address of TLS variable is not supported")
- }
- ctxt.Instoffset = a.Offset
- return C_VCONADDR
-
- case obj.NAME_AUTO:
- ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
- goto aconsize
-
- case obj.NAME_PARAM:
- ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
- goto aconsize
- }
- return C_GOK
-
- aconsize:
- if isaddcon(ctxt.Instoffset) {
- return C_AACON
- }
- return C_LACON
-
- case obj.TYPE_BRANCH:
- return C_SBRA
- }
-
- return C_GOK
-}
-
-func oclass(a *obj.Addr) int {
- return int(a.Class) - 1
-}
-
-func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
- a1 := int(p.Optab)
- if a1 != 0 {
- return &optab[a1-1]
- }
- a1 = int(p.From.Class)
- if a1 == 0 {
- a1 = aclass(ctxt, &p.From) + 1
- p.From.Class = int8(a1)
- }
-
- a1--
- a3 := int(p.To.Class)
- if a3 == 0 {
- a3 = aclass(ctxt, &p.To) + 1
- p.To.Class = int8(a3)
- }
-
- a3--
- a2 := C_NONE
- if p.Reg != 0 {
- a2 = rclass(p.Reg)
- }
-
- if false {
- fmt.Printf("oplook %v %d %d %d\n", p.As, a1, a2, a3)
- fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type)
- }
-
- ops := oprange[p.As&obj.AMask]
- c1 := &xcmp[a1]
- c2 := &xcmp[a2]
- c3 := &xcmp[a3]
- c4 := &xcmp[p.Scond>>5]
- for i := range ops {
- op := &ops[i]
- if (int(op.a2) == a2 || c2[op.a2]) && c4[op.scond>>5] && c1[op.a1] && c3[op.a3] {
- p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
- return op
- }
- }
-
- ctxt.Diag("illegal combination %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type)
- prasm(p)
- if ops == nil {
- ops = optab
- }
- return &ops[0]
-}
-
-func cmp(a int, b int) bool {
- if a == b {
- return true
- }
- switch a {
- case C_RSP:
- if b == C_REG {
- return true
- }
-
- case C_REG:
- if b == C_ZCON {
- return true
- }
-
- case C_ADDCON0:
- if b == C_ZCON || b == C_ABCON0 {
- return true
- }
-
- case C_ADDCON:
- if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON {
- return true
- }
-
- case C_BITCON:
- if b == C_ABCON0 || b == C_ABCON || b == C_MBCON {
- return true
- }
-
- case C_MOVCON:
- if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 {
- return true
- }
-
- case C_LCON:
- if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON {
- return true
- }
-
- case C_VCON:
- return cmp(C_LCON, b)
-
- case C_LACON:
- if b == C_AACON {
- return true
- }
-
- case C_SEXT2:
- if b == C_SEXT1 {
- return true
- }
-
- case C_SEXT4:
- if b == C_SEXT1 || b == C_SEXT2 {
- return true
- }
-
- case C_SEXT8:
- if b >= C_SEXT1 && b <= C_SEXT4 {
- return true
- }
-
- case C_SEXT16:
- if b >= C_SEXT1 && b <= C_SEXT8 {
- return true
- }
-
- case C_LEXT:
- if b >= C_SEXT1 && b <= C_SEXT16 {
- return true
- }
-
- case C_PPAUTO:
- if b == C_PSAUTO {
- return true
- }
-
- case C_UAUTO4K:
- if b == C_PSAUTO || b == C_PPAUTO {
- return true
- }
-
- case C_UAUTO8K:
- return cmp(C_UAUTO4K, b)
-
- case C_UAUTO16K:
- return cmp(C_UAUTO8K, b)
-
- case C_UAUTO32K:
- return cmp(C_UAUTO16K, b)
-
- case C_UAUTO64K:
- return cmp(C_UAUTO32K, b)
-
- case C_NPAUTO:
- return cmp(C_NSAUTO, b)
-
- case C_LAUTO:
- return cmp(C_NPAUTO, b) || cmp(C_UAUTO64K, b)
-
- case C_PSOREG:
- if b == C_ZOREG {
- return true
- }
-
- case C_PPOREG:
- if b == C_ZOREG || b == C_PSOREG {
- return true
- }
-
- case C_UOREG4K:
- if b == C_ZOREG || b == C_PSAUTO || b == C_PSOREG || b == C_PPAUTO || b == C_PPOREG {
- return true
- }
-
- case C_UOREG8K:
- return cmp(C_UOREG4K, b)
-
- case C_UOREG16K:
- return cmp(C_UOREG8K, b)
-
- case C_UOREG32K:
- return cmp(C_UOREG16K, b)
-
- case C_UOREG64K:
- return cmp(C_UOREG32K, b)
-
- case C_NPOREG:
- return cmp(C_NSOREG, b)
-
- case C_LOREG:
- return cmp(C_NPOREG, b) || cmp(C_UOREG64K, b)
-
- case C_LBRA:
- if b == C_SBRA {
- return true
- }
- }
-
- return false
-}
-
-type ocmp []Optab
-
-func (x ocmp) Len() int {
- return len(x)
-}
-
-func (x ocmp) Swap(i, j int) {
- x[i], x[j] = x[j], x[i]
-}
-
-func (x ocmp) Less(i, j int) bool {
- p1 := &x[i]
- p2 := &x[j]
- if p1.as != p2.as {
- return p1.as < p2.as
- }
- if p1.a1 != p2.a1 {
- return p1.a1 < p2.a1
- }
- if p1.a2 != p2.a2 {
- return p1.a2 < p2.a2
- }
- if p1.a3 != p2.a3 {
- return p1.a3 < p2.a3
- }
- if p1.scond != p2.scond {
- return p1.scond < p2.scond
- }
- return false
-}
-
-func oprangeset(a obj.As, t []Optab) {
- oprange[a&obj.AMask] = t
-}
-
-func buildop(ctxt *obj.Link) {
- var n int
- for i := 0; i < C_GOK; i++ {
- for n = 0; n < C_GOK; n++ {
- if cmp(n, i) {
- xcmp[i][n] = true
- }
- }
- }
- for n = 0; optab[n].as != obj.AXXX; n++ {
- }
- sort.Sort(ocmp(optab[:n]))
- for i := 0; i < n; i++ {
- r := optab[i].as
- start := i
- for optab[i].as == r {
- i++
- }
- t := optab[start:i]
- i--
- oprangeset(r, t)
- switch r {
- default:
- ctxt.Diag("unknown op in build: %v", r)
- log.Fatalf("bad code")
-
- case AADD:
- oprangeset(AADDS, t)
- oprangeset(ASUB, t)
- oprangeset(ASUBS, t)
- oprangeset(AADDW, t)
- oprangeset(AADDSW, t)
- oprangeset(ASUBW, t)
- oprangeset(ASUBSW, t)
-
- case AAND: /* logical immediate, logical shifted register */
- oprangeset(AANDS, t)
-
- oprangeset(AANDSW, t)
- oprangeset(AANDW, t)
- oprangeset(AEOR, t)
- oprangeset(AEORW, t)
- oprangeset(AORR, t)
- oprangeset(AORRW, t)
-
- case ABIC: /* only logical shifted register */
- oprangeset(ABICS, t)
-
- oprangeset(ABICSW, t)
- oprangeset(ABICW, t)
- oprangeset(AEON, t)
- oprangeset(AEONW, t)
- oprangeset(AORN, t)
- oprangeset(AORNW, t)
-
- case ANEG:
- oprangeset(ANEGS, t)
- oprangeset(ANEGSW, t)
- oprangeset(ANEGW, t)
-
- case AADC: /* rn=Rd */
- oprangeset(AADCW, t)
-
- oprangeset(AADCS, t)
- oprangeset(AADCSW, t)
- oprangeset(ASBC, t)
- oprangeset(ASBCW, t)
- oprangeset(ASBCS, t)
- oprangeset(ASBCSW, t)
-
- case ANGC: /* rn=REGZERO */
- oprangeset(ANGCW, t)
-
- oprangeset(ANGCS, t)
- oprangeset(ANGCSW, t)
-
- case ACMP:
- oprangeset(ACMPW, t)
- oprangeset(ACMN, t)
- oprangeset(ACMNW, t)
-
- case ATST:
- oprangeset(ATSTW, t)
-
- /* register/register, and shifted */
- case AMVN:
- oprangeset(AMVNW, t)
-
- case AMOVK:
- oprangeset(AMOVKW, t)
- oprangeset(AMOVN, t)
- oprangeset(AMOVNW, t)
- oprangeset(AMOVZ, t)
- oprangeset(AMOVZW, t)
-
- case ABEQ:
- oprangeset(ABNE, t)
- oprangeset(ABCS, t)
- oprangeset(ABHS, t)
- oprangeset(ABCC, t)
- oprangeset(ABLO, t)
- oprangeset(ABMI, t)
- oprangeset(ABPL, t)
- oprangeset(ABVS, t)
- oprangeset(ABVC, t)
- oprangeset(ABHI, t)
- oprangeset(ABLS, t)
- oprangeset(ABGE, t)
- oprangeset(ABLT, t)
- oprangeset(ABGT, t)
- oprangeset(ABLE, t)
-
- case ALSL:
- oprangeset(ALSLW, t)
- oprangeset(ALSR, t)
- oprangeset(ALSRW, t)
- oprangeset(AASR, t)
- oprangeset(AASRW, t)
- oprangeset(AROR, t)
- oprangeset(ARORW, t)
-
- case ACLS:
- oprangeset(ACLSW, t)
- oprangeset(ACLZ, t)
- oprangeset(ACLZW, t)
- oprangeset(ARBIT, t)
- oprangeset(ARBITW, t)
- oprangeset(AREV, t)
- oprangeset(AREVW, t)
- oprangeset(AREV16, t)
- oprangeset(AREV16W, t)
- oprangeset(AREV32, t)
-
- case ASDIV:
- oprangeset(ASDIVW, t)
- oprangeset(AUDIV, t)
- oprangeset(AUDIVW, t)
- oprangeset(ACRC32B, t)
- oprangeset(ACRC32CB, t)
- oprangeset(ACRC32CH, t)
- oprangeset(ACRC32CW, t)
- oprangeset(ACRC32CX, t)
- oprangeset(ACRC32H, t)
- oprangeset(ACRC32W, t)
- oprangeset(ACRC32X, t)
-
- case AMADD:
- oprangeset(AMADDW, t)
- oprangeset(AMSUB, t)
- oprangeset(AMSUBW, t)
- oprangeset(ASMADDL, t)
- oprangeset(ASMSUBL, t)
- oprangeset(AUMADDL, t)
- oprangeset(AUMSUBL, t)
-
- case AREM:
- oprangeset(AREMW, t)
- oprangeset(AUREM, t)
- oprangeset(AUREMW, t)
-
- case AMUL:
- oprangeset(AMULW, t)
- oprangeset(AMNEG, t)
- oprangeset(AMNEGW, t)
- oprangeset(ASMNEGL, t)
- oprangeset(ASMULL, t)
- oprangeset(ASMULH, t)
- oprangeset(AUMNEGL, t)
- oprangeset(AUMULH, t)
- oprangeset(AUMULL, t)
-
- case AMOVB:
- oprangeset(AMOVBU, t)
-
- case AMOVH:
- oprangeset(AMOVHU, t)
-
- case AMOVW:
- oprangeset(AMOVWU, t)
-
- case ABFM:
- oprangeset(ABFMW, t)
- oprangeset(ASBFM, t)
- oprangeset(ASBFMW, t)
- oprangeset(AUBFM, t)
- oprangeset(AUBFMW, t)
-
- case ABFI:
- oprangeset(ABFIW, t)
- oprangeset(ABFXIL, t)
- oprangeset(ABFXILW, t)
- oprangeset(ASBFIZ, t)
- oprangeset(ASBFIZW, t)
- oprangeset(ASBFX, t)
- oprangeset(ASBFXW, t)
- oprangeset(AUBFIZ, t)
- oprangeset(AUBFIZW, t)
- oprangeset(AUBFX, t)
- oprangeset(AUBFXW, t)
-
- case AEXTR:
- oprangeset(AEXTRW, t)
-
- case ASXTB:
- oprangeset(ASXTBW, t)
- oprangeset(ASXTH, t)
- oprangeset(ASXTHW, t)
- oprangeset(ASXTW, t)
- oprangeset(AUXTB, t)
- oprangeset(AUXTH, t)
- oprangeset(AUXTW, t)
- oprangeset(AUXTBW, t)
- oprangeset(AUXTHW, t)
-
- case ACCMN:
- oprangeset(ACCMNW, t)
- oprangeset(ACCMP, t)
- oprangeset(ACCMPW, t)
-
- case ACSEL:
- oprangeset(ACSELW, t)
- oprangeset(ACSINC, t)
- oprangeset(ACSINCW, t)
- oprangeset(ACSINV, t)
- oprangeset(ACSINVW, t)
- oprangeset(ACSNEG, t)
- oprangeset(ACSNEGW, t)
-
- // aliases Rm=Rn, !cond
- oprangeset(ACINC, t)
-
- oprangeset(ACINCW, t)
- oprangeset(ACINV, t)
- oprangeset(ACINVW, t)
- oprangeset(ACNEG, t)
- oprangeset(ACNEGW, t)
-
- // aliases, Rm=Rn=REGZERO, !cond
- case ACSET:
- oprangeset(ACSETW, t)
-
- oprangeset(ACSETM, t)
- oprangeset(ACSETMW, t)
-
- case AMOVD,
- AMOVBU,
- AB,
- ABL,
- AWORD,
- ADWORD,
- obj.ARET,
- obj.ATEXT,
- ASTP,
- ALDP:
- break
-
- case AERET:
- oprangeset(AWFE, t)
- oprangeset(AWFI, t)
- oprangeset(AYIELD, t)
- oprangeset(ASEV, t)
- oprangeset(ASEVL, t)
- oprangeset(ADRPS, t)
-
- case ACBZ:
- oprangeset(ACBZW, t)
- oprangeset(ACBNZ, t)
- oprangeset(ACBNZW, t)
-
- case ATBZ:
- oprangeset(ATBNZ, t)
-
- case AADR, AADRP:
- break
-
- case ACLREX:
- break
-
- case ASVC:
- oprangeset(AHLT, t)
- oprangeset(AHVC, t)
- oprangeset(ASMC, t)
- oprangeset(ABRK, t)
- oprangeset(ADCPS1, t)
- oprangeset(ADCPS2, t)
- oprangeset(ADCPS3, t)
-
- case AFADDS:
- oprangeset(AFADDD, t)
- oprangeset(AFSUBS, t)
- oprangeset(AFSUBD, t)
- oprangeset(AFMULS, t)
- oprangeset(AFMULD, t)
- oprangeset(AFNMULS, t)
- oprangeset(AFNMULD, t)
- oprangeset(AFDIVS, t)
- oprangeset(AFMAXD, t)
- oprangeset(AFMAXS, t)
- oprangeset(AFMIND, t)
- oprangeset(AFMINS, t)
- oprangeset(AFMAXNMD, t)
- oprangeset(AFMAXNMS, t)
- oprangeset(AFMINNMD, t)
- oprangeset(AFMINNMS, t)
- oprangeset(AFDIVD, t)
-
- case AFCVTSD:
- oprangeset(AFCVTDS, t)
- oprangeset(AFABSD, t)
- oprangeset(AFABSS, t)
- oprangeset(AFNEGD, t)
- oprangeset(AFNEGS, t)
- oprangeset(AFSQRTD, t)
- oprangeset(AFSQRTS, t)
- oprangeset(AFRINTNS, t)
- oprangeset(AFRINTND, t)
- oprangeset(AFRINTPS, t)
- oprangeset(AFRINTPD, t)
- oprangeset(AFRINTMS, t)
- oprangeset(AFRINTMD, t)
- oprangeset(AFRINTZS, t)
- oprangeset(AFRINTZD, t)
- oprangeset(AFRINTAS, t)
- oprangeset(AFRINTAD, t)
- oprangeset(AFRINTXS, t)
- oprangeset(AFRINTXD, t)
- oprangeset(AFRINTIS, t)
- oprangeset(AFRINTID, t)
- oprangeset(AFCVTDH, t)
- oprangeset(AFCVTHS, t)
- oprangeset(AFCVTHD, t)
- oprangeset(AFCVTSH, t)
-
- case AFCMPS:
- oprangeset(AFCMPD, t)
- oprangeset(AFCMPES, t)
- oprangeset(AFCMPED, t)
-
- case AFCCMPS:
- oprangeset(AFCCMPD, t)
- oprangeset(AFCCMPES, t)
- oprangeset(AFCCMPED, t)
-
- case AFCSELD:
- oprangeset(AFCSELS, t)
-
- case AFMOVS, AFMOVD:
- break
-
- case AFCVTZSD:
- oprangeset(AFCVTZSDW, t)
- oprangeset(AFCVTZSS, t)
- oprangeset(AFCVTZSSW, t)
- oprangeset(AFCVTZUD, t)
- oprangeset(AFCVTZUDW, t)
- oprangeset(AFCVTZUS, t)
- oprangeset(AFCVTZUSW, t)
-
- case ASCVTFD:
- oprangeset(ASCVTFS, t)
- oprangeset(ASCVTFWD, t)
- oprangeset(ASCVTFWS, t)
- oprangeset(AUCVTFD, t)
- oprangeset(AUCVTFS, t)
- oprangeset(AUCVTFWD, t)
- oprangeset(AUCVTFWS, t)
-
- case ASYS:
- oprangeset(AAT, t)
- oprangeset(ADC, t)
- oprangeset(AIC, t)
- oprangeset(ATLBI, t)
-
- case ASYSL, AHINT:
- break
-
- case ADMB:
- oprangeset(ADSB, t)
- oprangeset(AISB, t)
-
- case AMRS, AMSR:
- break
-
- case ALDAR:
- oprangeset(ALDARW, t)
- fallthrough
-
- case ALDXR:
- oprangeset(ALDXRB, t)
- oprangeset(ALDXRH, t)
- oprangeset(ALDXRW, t)
-
- case ALDAXR:
- oprangeset(ALDAXRB, t)
- oprangeset(ALDAXRH, t)
- oprangeset(ALDAXRW, t)
-
- case ALDXP:
- oprangeset(ALDXPW, t)
-
- case ASTLR:
- oprangeset(ASTLRW, t)
-
- case ASTXR:
- oprangeset(ASTXRB, t)
- oprangeset(ASTXRH, t)
- oprangeset(ASTXRW, t)
-
- case ASTLXR:
- oprangeset(ASTLXRB, t)
- oprangeset(ASTLXRH, t)
- oprangeset(ASTLXRW, t)
-
- case ASTXP:
- oprangeset(ASTXPW, t)
-
- case AAESD:
- oprangeset(AAESE, t)
- oprangeset(AAESMC, t)
- oprangeset(AAESIMC, t)
- oprangeset(ASHA1H, t)
- oprangeset(ASHA1SU1, t)
- oprangeset(ASHA256SU0, t)
-
- case ASHA1C:
- oprangeset(ASHA1P, t)
- oprangeset(ASHA1M, t)
- oprangeset(ASHA1SU0, t)
- oprangeset(ASHA256H, t)
- oprangeset(ASHA256H2, t)
- oprangeset(ASHA256SU1, t)
-
- case obj.ANOP,
- obj.AUNDEF,
- obj.AUSEFIELD,
- obj.AFUNCDATA,
- obj.APCDATA,
- obj.ADUFFZERO,
- obj.ADUFFCOPY:
- break
- }
- }
-}
-
-func chipfloat7(ctxt *obj.Link, e float64) int {
- ei := math.Float64bits(e)
- l := uint32(int32(ei))
- h := uint32(int32(ei >> 32))
-
- if l != 0 || h&0xffff != 0 {
- return -1
- }
- h1 := h & 0x7fc00000
- if h1 != 0x40000000 && h1 != 0x3fc00000 {
- return -1
- }
- n := 0
-
- // sign bit (a)
- if h&0x80000000 != 0 {
- n |= 1 << 7
- }
-
- // exp sign bit (b)
- if h1 == 0x3fc00000 {
- n |= 1 << 6
- }
-
- // rest of exp and mantissa (cd-efgh)
- n |= int((h >> 16) & 0x3f)
-
- //print("match %.8lux %.8lux %d\n", l, h, n);
- return n
-}
-
-/* form offset parameter to SYS; special register number */
-func SYSARG5(op0 int, op1 int, Cn int, Cm int, op2 int) int {
- return op0<<19 | op1<<16 | Cn<<12 | Cm<<8 | op2<<5
-}
-
-func SYSARG4(op1 int, Cn int, Cm int, op2 int) int {
- return SYSARG5(0, op1, Cn, Cm, op2)
-}
-
-func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
- o1 := uint32(0)
- o2 := uint32(0)
- o3 := uint32(0)
- o4 := uint32(0)
- o5 := uint32(0)
- if false { /*debug['P']*/
- fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_)
- }
- switch o.type_ {
- default:
- ctxt.Diag("unknown asm %d", o.type_)
- prasm(p)
-
- case 0: /* pseudo ops */
- break
-
- case 1: /* op Rm,[Rn],Rd; default Rn=Rd -> op Rm<<0,[Rn,]Rd (shifted register) */
- o1 = oprrr(ctxt, p.As)
-
- rf := int(p.From.Reg)
- rt := int(p.To.Reg)
- r := int(p.Reg)
- if p.To.Type == obj.TYPE_NONE {
- rt = REGZERO
- }
- if r == 0 {
- r = rt
- }
- o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
-
- case 2: /* add/sub $(uimm12|uimm24)[,R],R; cmp $(uimm12|uimm24),R */
- o1 = opirr(ctxt, p.As)
-
- rt := int(p.To.Reg)
- if p.To.Type == obj.TYPE_NONE {
- if (o1 & Sbit) == 0 {
- ctxt.Diag("ineffective ZR destination\n%v", p)
- }
- rt = REGZERO
- }
-
- r := int(p.Reg)
- if r == 0 {
- r = rt
- }
- v := int32(regoff(ctxt, &p.From))
- o1 = oaddi(ctxt, int32(o1), v, r, rt)
-
- case 3: /* op R<<n[,R],R (shifted register) */
- o1 = oprrr(ctxt, p.As)
-
- o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
- rt := int(p.To.Reg)
- if p.To.Type == obj.TYPE_NONE {
- rt = REGZERO
- }
- r := int(p.Reg)
- if p.As == AMVN || p.As == AMVNW {
- r = REGZERO
- } else if r == 0 {
- r = rt
- }
- o1 |= (uint32(r&31) << 5) | uint32(rt&31)
-
- case 4: /* mov $addcon, R; mov $recon, R; mov $racon, R */
- o1 = opirr(ctxt, p.As)
-
- rt := int(p.To.Reg)
- r := int(o.param)
- if r == 0 {
- r = REGZERO
- } else if r == REGFROM {
- r = int(p.From.Reg)
- }
- if r == 0 {
- r = REGSP
- }
- v := int32(regoff(ctxt, &p.From))
- if (v & 0xFFF000) != 0 {
- v >>= 12
- o1 |= 1 << 22 /* shift, by 12 */
- }
-
- o1 |= ((uint32(v) & 0xFFF) << 10) | (uint32(r&31) << 5) | uint32(rt&31)
-
- case 5: /* b s; bl s */
- o1 = opbra(ctxt, p.As)
-
- if p.To.Sym == nil {
- o1 |= uint32(brdist(ctxt, p, 0, 26, 2))
- break
- }
-
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 4
- rel.Sym = p.To.Sym
- rel.Add = p.To.Offset
- rel.Type = obj.R_CALLARM64
-
- case 6: /* b ,O(R); bl ,O(R) */
- o1 = opbrr(ctxt, p.As)
-
- o1 |= uint32(p.To.Reg&31) << 5
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 0
- rel.Type = obj.R_CALLIND
-
- case 7: /* beq s */
- o1 = opbra(ctxt, p.As)
-
- o1 |= uint32(brdist(ctxt, p, 0, 19, 2) << 5)
-
- case 8: /* lsl $c,[R],R -> ubfm $(W-1)-c,$(-c MOD (W-1)),Rn,Rd */
- rt := int(p.To.Reg)
-
- rf := int(p.Reg)
- if rf == 0 {
- rf = rt
- }
- v := int32(p.From.Offset)
- switch p.As {
- case AASR:
- o1 = opbfm(ctxt, ASBFM, int(v), 63, rf, rt)
-
- case AASRW:
- o1 = opbfm(ctxt, ASBFMW, int(v), 31, rf, rt)
-
- case ALSL:
- o1 = opbfm(ctxt, AUBFM, int((64-v)&63), int(63-v), rf, rt)
-
- case ALSLW:
- o1 = opbfm(ctxt, AUBFMW, int((32-v)&31), int(31-v), rf, rt)
-
- case ALSR:
- o1 = opbfm(ctxt, AUBFM, int(v), 63, rf, rt)
-
- case ALSRW:
- o1 = opbfm(ctxt, AUBFMW, int(v), 31, rf, rt)
-
- case AROR:
- o1 = opextr(ctxt, AEXTR, v, rf, rf, rt)
-
- case ARORW:
- o1 = opextr(ctxt, AEXTRW, v, rf, rf, rt)
-
- default:
- ctxt.Diag("bad shift $con\n%v", ctxt.Curp)
- break
- }
-
- case 9: /* lsl Rm,[Rn],Rd -> lslv Rm, Rn, Rd */
- o1 = oprrr(ctxt, p.As)
-
- r := int(p.Reg)
- if r == 0 {
- r = int(p.To.Reg)
- }
- o1 |= (uint32(p.From.Reg&31) << 16) | (uint32(r&31) << 5) | uint32(p.To.Reg&31)
-
- case 10: /* brk/hvc/.../svc [$con] */
- o1 = opimm(ctxt, p.As)
-
- if p.To.Type != obj.TYPE_NONE {
- o1 |= uint32((p.To.Offset & 0xffff) << 5)
- }
-
- case 11: /* dword */
- aclass(ctxt, &p.To)
-
- o1 = uint32(ctxt.Instoffset)
- o2 = uint32(ctxt.Instoffset >> 32)
- if p.To.Sym != nil {
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 8
- rel.Sym = p.To.Sym
- rel.Add = p.To.Offset
- rel.Type = obj.R_ADDR
- o2 = 0
- o1 = o2
- }
-
- case 12: /* movT $vcon, reg */
- o1 = omovlit(ctxt, p.As, p, &p.From, int(p.To.Reg))
-
- case 13: /* addop $vcon, [R], R (64 bit literal); cmp $lcon,R -> addop $lcon,R, ZR */
- o1 = omovlit(ctxt, AMOVD, p, &p.From, REGTMP)
-
- if !(o1 != 0) {
- break
- }
- rt := int(p.To.Reg)
- if p.To.Type == obj.TYPE_NONE {
- rt = REGZERO
- }
- r := int(p.Reg)
- if r == 0 {
- r = rt
- }
- if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
- o2 = opxrrr(ctxt, p.As)
- o2 |= REGTMP & 31 << 16
- o2 |= LSL0_64
- } else {
- o2 = oprrr(ctxt, p.As)
- o2 |= REGTMP & 31 << 16 /* shift is 0 */
- }
-
- o2 |= uint32(r&31) << 5
- o2 |= uint32(rt & 31)
-
- case 14: /* word */
- if aclass(ctxt, &p.To) == C_ADDR {
- ctxt.Diag("address constant needs DWORD\n%v", p)
- }
- o1 = uint32(ctxt.Instoffset)
- if p.To.Sym != nil {
- // This case happens with words generated
- // in the PC stream as part of the literal pool.
- rel := obj.Addrel(ctxt.Cursym)
-
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 4
- rel.Sym = p.To.Sym
- rel.Add = p.To.Offset
- rel.Type = obj.R_ADDR
- o1 = 0
- }
-
- case 15: /* mul/mneg/umulh/umull r,[r,]r; madd/msub Rm,Rn,Ra,Rd */
- o1 = oprrr(ctxt, p.As)
-
- rf := int(p.From.Reg)
- rt := int(p.To.Reg)
- var r int
- var ra int
- if p.From3Type() == obj.TYPE_REG {
- r = int(p.From3.Reg)
- ra = int(p.Reg)
- if ra == 0 {
- ra = REGZERO
- }
- } else {
- r = int(p.Reg)
- if r == 0 {
- r = rt
- }
- ra = REGZERO
- }
-
- o1 |= (uint32(rf&31) << 16) | (uint32(ra&31) << 10) | (uint32(r&31) << 5) | uint32(rt&31)
-
- case 16: /* XremY R[,R],R -> XdivY; XmsubY */
- o1 = oprrr(ctxt, p.As)
-
- rf := int(p.From.Reg)
- rt := int(p.To.Reg)
- r := int(p.Reg)
- if r == 0 {
- r = rt
- }
- o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | REGTMP&31
- o2 = oprrr(ctxt, AMSUBW)
- o2 |= o1 & (1 << 31) /* same size */
- o2 |= (uint32(rf&31) << 16) | (uint32(r&31) << 10) | (REGTMP & 31 << 5) | uint32(rt&31)
-
- case 17: /* op Rm,[Rn],Rd; default Rn=ZR */
- o1 = oprrr(ctxt, p.As)
-
- rf := int(p.From.Reg)
- rt := int(p.To.Reg)
- r := int(p.Reg)
- if p.To.Type == obj.TYPE_NONE {
- rt = REGZERO
- }
- if r == 0 {
- r = REGZERO
- }
- o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
-
- case 18: /* csel cond,Rn,Rm,Rd; cinc/cinv/cneg cond,Rn,Rd; cset cond,Rd */
- o1 = oprrr(ctxt, p.As)
-
- cond := int(p.From.Reg)
- r := int(p.Reg)
- var rf int
- if r != 0 {
- if p.From3Type() == obj.TYPE_NONE {
- /* CINC/CINV/CNEG */
- rf = r
-
- cond ^= 1
- } else {
- rf = int(p.From3.Reg) /* CSEL */
- }
- } else {
- /* CSET */
- if p.From3Type() != obj.TYPE_NONE {
- ctxt.Diag("invalid combination\n%v", p)
- }
- rf = REGZERO
- r = rf
- cond ^= 1
- }
-
- rt := int(p.To.Reg)
- o1 |= (uint32(rf&31) << 16) | (uint32(cond&31) << 12) | (uint32(r&31) << 5) | uint32(rt&31)
-
- case 19: /* CCMN cond, (Rm|uimm5),Rn, uimm4 -> ccmn Rn,Rm,uimm4,cond */
- nzcv := int(p.To.Offset)
-
- cond := int(p.From.Reg)
- var rf int
- if p.From3.Type == obj.TYPE_REG {
- o1 = oprrr(ctxt, p.As)
- rf = int(p.From3.Reg) /* Rm */
- } else {
- o1 = opirr(ctxt, p.As)
- rf = int(p.From3.Offset & 0x1F)
- }
-
- o1 |= (uint32(rf&31) << 16) | (uint32(cond) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv)
-
- case 20: /* movT R,O(R) -> strT */
- v := int32(regoff(ctxt, &p.To))
- sz := int32(1 << uint(movesize(p.As)))
-
- r := int(p.To.Reg)
- if r == 0 {
- r = int(o.param)
- }
- if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
- o1 = olsr9s(ctxt, int32(opstr9(ctxt, p.As)), v, r, int(p.From.Reg))
- } else {
- v = int32(offsetshift(ctxt, int64(v), int(o.a3)))
- o1 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), v, r, int(p.From.Reg))
- }
-
- case 21: /* movT O(R),R -> ldrT */
- v := int32(regoff(ctxt, &p.From))
- sz := int32(1 << uint(movesize(p.As)))
-
- r := int(p.From.Reg)
- if r == 0 {
- r = int(o.param)
- }
- if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
- o1 = olsr9s(ctxt, int32(opldr9(ctxt, p.As)), v, r, int(p.To.Reg))
- } else {
- v = int32(offsetshift(ctxt, int64(v), int(o.a1)))
- //print("offset=%lld v=%ld a1=%d\n", instoffset, v, o->a1);
- o1 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), v, r, int(p.To.Reg))
- }
-
- case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */
- v := int32(p.From.Offset)
-
- if v < -256 || v > 255 {
- ctxt.Diag("offset out of range\n%v", p)
- }
- o1 = opldrpp(ctxt, p.As)
- if o.scond == C_XPOST {
- o1 |= 1 << 10
- } else {
- o1 |= 3 << 10
- }
- o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31)
-
- case 23: /* movT R,(R)O!; movT O(R)!, R -> strT */
- v := int32(p.To.Offset)
-
- if v < -256 || v > 255 {
- ctxt.Diag("offset out of range\n%v", p)
- }
- o1 = LD2STR(opldrpp(ctxt, p.As))
- if o.scond == C_XPOST {
- o1 |= 1 << 10
- } else {
- o1 |= 3 << 10
- }
- o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.To.Reg&31) << 5) | uint32(p.From.Reg&31)
-
- case 24: /* mov/mvn Rs,Rd -> add $0,Rs,Rd or orr Rs,ZR,Rd */
- rf := int(p.From.Reg)
- rt := int(p.To.Reg)
- s := rf == REGSP || rt == REGSP
- if p.As == AMVN || p.As == AMVNW {
- if s {
- ctxt.Diag("illegal SP reference\n%v", p)
- }
- o1 = oprrr(ctxt, p.As)
- o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
- } else if s {
- o1 = opirr(ctxt, p.As)
- o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
- } else {
- o1 = oprrr(ctxt, p.As)
- o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
- }
-
- case 25: /* negX Rs, Rd -> subX Rs<<0, ZR, Rd */
- o1 = oprrr(ctxt, p.As)
-
- rf := int(p.From.Reg)
- if rf == C_NONE {
- rf = int(p.To.Reg)
- }
- rt := int(p.To.Reg)
- o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
-
- case 26: /* negX Rm<<s, Rd -> subX Rm<<s, ZR, Rd */
- o1 = oprrr(ctxt, p.As)
-
- o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
- rt := int(p.To.Reg)
- o1 |= (REGZERO & 31 << 5) | uint32(rt&31)
-
- case 27: /* op Rm<<n[,Rn],Rd (extended register) */
- o1 = opxrrr(ctxt, p.As)
-
- if (p.From.Reg-obj.RBaseARM64)&REG_EXT != 0 {
- ctxt.Diag("extended register not implemented\n%v", p)
- // o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
- } else {
- o1 |= uint32(p.From.Reg&31) << 16
- }
- rt := int(p.To.Reg)
- if p.To.Type == obj.TYPE_NONE {
- rt = REGZERO
- }
- r := int(p.Reg)
- if r == 0 {
- r = rt
- }
- o1 |= (uint32(r&31) << 5) | uint32(rt&31)
-
- case 28: /* logop $vcon, [R], R (64 bit literal) */
- o1 = omovlit(ctxt, AMOVD, p, &p.From, REGTMP)
-
- if !(o1 != 0) {
- break
- }
- r := int(p.Reg)
- if r == 0 {
- r = int(p.To.Reg)
- }
- o2 = oprrr(ctxt, p.As)
- o2 |= REGTMP & 31 << 16 /* shift is 0 */
- o2 |= uint32(r&31) << 5
- o2 |= uint32(p.To.Reg & 31)
-
- case 29: /* op Rn, Rd */
- fc := aclass(ctxt, &p.From)
- tc := aclass(ctxt, &p.To)
- if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZCON || tc == C_REG || tc == C_ZCON) {
- // FMOV Rx, Fy or FMOV Fy, Rx
- o1 = FPCVTI(0, 0, 0, 0, 6)
- if p.As == AFMOVD {
- o1 |= 1<<31 | 1<<22 // 64-bit
- }
- if fc == C_REG || fc == C_ZCON {
- o1 |= 1 << 16 // FMOV Rx, Fy
- }
- } else {
- o1 = oprrr(ctxt, p.As)
- }
- o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31)
-
- case 30: /* movT R,L(R) -> strT */
- s := movesize(o.as)
-
- if s < 0 {
- ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
- }
- v := int32(regoff(ctxt, &p.To))
- if v < 0 {
- ctxt.Diag("negative large offset\n%v", p)
- }
- if (v & ((1 << uint(s)) - 1)) != 0 {
- ctxt.Diag("misaligned offset\n%v", p)
- }
- hi := v - (v & (0xFFF << uint(s)))
- if (hi & 0xFFF) != 0 {
- ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p)
- }
-
- //fprint(2, "v=%ld (%#lux) s=%d hi=%ld (%#lux) v'=%ld (%#lux)\n", v, v, s, hi, hi, ((v-hi)>>s)&0xFFF, ((v-hi)>>s)&0xFFF);
- r := int(p.To.Reg)
-
- if r == 0 {
- r = int(o.param)
- }
- o1 = oaddi(ctxt, int32(opirr(ctxt, AADD)), hi, r, REGTMP)
- o2 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.From.Reg))
-
- case 31: /* movT L(R), R -> ldrT */
- s := movesize(o.as)
-
- if s < 0 {
- ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
- }
- v := int32(regoff(ctxt, &p.From))
- if v < 0 {
- ctxt.Diag("negative large offset\n%v", p)
- }
- if (v & ((1 << uint(s)) - 1)) != 0 {
- ctxt.Diag("misaligned offset\n%v", p)
- }
- hi := v - (v & (0xFFF << uint(s)))
- if (hi & 0xFFF) != 0 {
- ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p)
- }
-
- //fprint(2, "v=%ld (%#lux) s=%d hi=%ld (%#lux) v'=%ld (%#lux)\n", v, v, s, hi, hi, ((v-hi)>>s)&0xFFF, ((v-hi)>>s)&0xFFF);
- r := int(p.From.Reg)
-
- if r == 0 {
- r = int(o.param)
- }
- o1 = oaddi(ctxt, int32(opirr(ctxt, AADD)), hi, r, REGTMP)
- o2 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.To.Reg))
-
- case 32: /* mov $con, R -> movz/movn */
- o1 = omovconst(ctxt, p.As, p, &p.From, int(p.To.Reg))
-
- case 33: /* movk $uimm16 << pos */
- o1 = opirr(ctxt, p.As)
-
- d := p.From.Offset
- if (d >> 16) != 0 {
- ctxt.Diag("requires uimm16\n%v", p)
- }
- s := 0
- if p.From3Type() != obj.TYPE_NONE {
- if p.From3.Type != obj.TYPE_CONST {
- ctxt.Diag("missing bit position\n%v", p)
- }
- s = int(p.From3.Offset / 16)
- if (s*16&0xF) != 0 || s >= 4 || (o1&S64) == 0 && s >= 2 {
- ctxt.Diag("illegal bit position\n%v", p)
- }
- }
-
- rt := int(p.To.Reg)
- o1 |= uint32(((d & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
-
- case 34: /* mov $lacon,R */
- o1 = omovlit(ctxt, AMOVD, p, &p.From, REGTMP)
-
- if !(o1 != 0) {
- break
- }
- o2 = opxrrr(ctxt, AADD)
- o2 |= REGTMP & 31 << 16
- o2 |= LSL0_64
- r := int(p.From.Reg)
- if r == 0 {
- r = int(o.param)
- }
- o2 |= uint32(r&31) << 5
- o2 |= uint32(p.To.Reg & 31)
-
- case 35: /* mov SPR,R -> mrs */
- o1 = oprrr(ctxt, AMRS)
-
- v := int32(p.From.Offset)
- if (o1 & uint32(v&^(3<<19))) != 0 {
- ctxt.Diag("MRS register value overlap\n%v", p)
- }
- o1 |= uint32(v)
- o1 |= uint32(p.To.Reg & 31)
-
- case 36: /* mov R,SPR */
- o1 = oprrr(ctxt, AMSR)
-
- v := int32(p.To.Offset)
- if (o1 & uint32(v&^(3<<19))) != 0 {
- ctxt.Diag("MSR register value overlap\n%v", p)
- }
- o1 |= uint32(v)
- o1 |= uint32(p.From.Reg & 31)
-
- case 37: /* mov $con,PSTATEfield -> MSR [immediate] */
- if (uint64(p.From.Offset) &^ uint64(0xF)) != 0 {
- ctxt.Diag("illegal immediate for PSTATE field\n%v", p)
- }
- o1 = opirr(ctxt, AMSR)
- o1 |= uint32((p.From.Offset & 0xF) << 8) /* Crm */
- v := int32(0)
- for i := 0; i < len(pstatefield); i++ {
- if int64(pstatefield[i].a) == p.To.Offset {
- v = int32(pstatefield[i].b)
- break
- }
- }
-
- if v == 0 {
- ctxt.Diag("illegal PSTATE field for immediate move\n%v", p)
- }
- o1 |= uint32(v)
-
- case 38: /* clrex [$imm] */
- o1 = opimm(ctxt, p.As)
-
- if p.To.Type == obj.TYPE_NONE {
- o1 |= 0xF << 8
- } else {
- o1 |= uint32((p.To.Offset & 0xF) << 8)
- }
-
- case 39: /* cbz R, rel */
- o1 = opirr(ctxt, p.As)
-
- o1 |= uint32(p.From.Reg & 31)
- o1 |= uint32(brdist(ctxt, p, 0, 19, 2) << 5)
-
- case 40: /* tbz */
- o1 = opirr(ctxt, p.As)
-
- v := int32(p.From.Offset)
- if v < 0 || v > 63 {
- ctxt.Diag("illegal bit number\n%v", p)
- }
- o1 |= ((uint32(v) & 0x20) << (31 - 5)) | ((uint32(v) & 0x1F) << 19)
- o1 |= uint32(brdist(ctxt, p, 0, 14, 2) << 5)
- o1 |= uint32(p.Reg)
-
- case 41: /* eret, nop, others with no operands */
- o1 = op0(ctxt, p.As)
-
- case 42: /* bfm R,r,s,R */
- o1 = opbfm(ctxt, p.As, int(p.From.Offset), int(p.From3.Offset), int(p.Reg), int(p.To.Reg))
-
- case 43: /* bfm aliases */
- r := int(p.From.Offset)
-
- s := int(p.From3.Offset)
- rf := int(p.Reg)
- rt := int(p.To.Reg)
- if rf == 0 {
- rf = rt
- }
- switch p.As {
- case ABFI:
- o1 = opbfm(ctxt, ABFM, 64-r, s-1, rf, rt)
-
- case ABFIW:
- o1 = opbfm(ctxt, ABFMW, 32-r, s-1, rf, rt)
-
- case ABFXIL:
- o1 = opbfm(ctxt, ABFM, r, r+s-1, rf, rt)
-
- case ABFXILW:
- o1 = opbfm(ctxt, ABFMW, r, r+s-1, rf, rt)
-
- case ASBFIZ:
- o1 = opbfm(ctxt, ASBFM, 64-r, s-1, rf, rt)
-
- case ASBFIZW:
- o1 = opbfm(ctxt, ASBFMW, 32-r, s-1, rf, rt)
-
- case ASBFX:
- o1 = opbfm(ctxt, ASBFM, r, r+s-1, rf, rt)
-
- case ASBFXW:
- o1 = opbfm(ctxt, ASBFMW, r, r+s-1, rf, rt)
-
- case AUBFIZ:
- o1 = opbfm(ctxt, AUBFM, 64-r, s-1, rf, rt)
-
- case AUBFIZW:
- o1 = opbfm(ctxt, AUBFMW, 32-r, s-1, rf, rt)
-
- case AUBFX:
- o1 = opbfm(ctxt, AUBFM, r, r+s-1, rf, rt)
-
- case AUBFXW:
- o1 = opbfm(ctxt, AUBFMW, r, r+s-1, rf, rt)
-
- default:
- ctxt.Diag("bad bfm alias\n%v", ctxt.Curp)
- break
- }
-
- case 44: /* extr $b, Rn, Rm, Rd */
- o1 = opextr(ctxt, p.As, int32(p.From.Offset), int(p.From3.Reg), int(p.Reg), int(p.To.Reg))
-
- case 45: /* sxt/uxt[bhw] R,R; movT R,R -> sxtT R,R */
- rf := int(p.From.Reg)
-
- rt := int(p.To.Reg)
- as := p.As
- if rf == REGZERO {
- as = AMOVWU /* clearer in disassembly */
- }
- switch as {
- case AMOVB, ASXTB:
- o1 = opbfm(ctxt, ASBFM, 0, 7, rf, rt)
-
- case AMOVH, ASXTH:
- o1 = opbfm(ctxt, ASBFM, 0, 15, rf, rt)
-
- case AMOVW, ASXTW:
- o1 = opbfm(ctxt, ASBFM, 0, 31, rf, rt)
-
- case AMOVBU, AUXTB:
- o1 = opbfm(ctxt, AUBFM, 0, 7, rf, rt)
-
- case AMOVHU, AUXTH:
- o1 = opbfm(ctxt, AUBFM, 0, 15, rf, rt)
-
- case AMOVWU:
- o1 = oprrr(ctxt, as) | (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
-
- case AUXTW:
- o1 = opbfm(ctxt, AUBFM, 0, 31, rf, rt)
-
- case ASXTBW:
- o1 = opbfm(ctxt, ASBFMW, 0, 7, rf, rt)
-
- case ASXTHW:
- o1 = opbfm(ctxt, ASBFMW, 0, 15, rf, rt)
-
- case AUXTBW:
- o1 = opbfm(ctxt, AUBFMW, 0, 7, rf, rt)
-
- case AUXTHW:
- o1 = opbfm(ctxt, AUBFMW, 0, 15, rf, rt)
-
- default:
- ctxt.Diag("bad sxt %v", as)
- break
- }
-
- case 46: /* cls */
- o1 = opbit(ctxt, p.As)
-
- o1 |= uint32(p.From.Reg&31) << 5
- o1 |= uint32(p.To.Reg & 31)
-
- case 47: /* movT R,V(R) -> strT (huge offset) */
- o1 = omovlit(ctxt, AMOVW, p, &p.To, REGTMP)
-
- if !(o1 != 0) {
- break
- }
- r := int(p.To.Reg)
- if r == 0 {
- r = int(o.param)
- }
- o2 = olsxrr(ctxt, p.As, REGTMP, r, int(p.From.Reg))
-
- case 48: /* movT V(R), R -> ldrT (huge offset) */
- o1 = omovlit(ctxt, AMOVW, p, &p.From, REGTMP)
-
- if !(o1 != 0) {
- break
- }
- r := int(p.From.Reg)
- if r == 0 {
- r = int(o.param)
- }
- o2 = olsxrr(ctxt, p.As, REGTMP, r, int(p.To.Reg))
-
- case 50: /* sys/sysl */
- o1 = opirr(ctxt, p.As)
-
- if (p.From.Offset &^ int64(SYSARG4(0x7, 0xF, 0xF, 0x7))) != 0 {
- ctxt.Diag("illegal SYS argument\n%v", p)
- }
- o1 |= uint32(p.From.Offset)
- if p.To.Type == obj.TYPE_REG {
- o1 |= uint32(p.To.Reg & 31)
- } else if p.Reg != 0 {
- o1 |= uint32(p.Reg & 31)
- } else {
- o1 |= 0x1F
- }
-
- case 51: /* dmb */
- o1 = opirr(ctxt, p.As)
-
- if p.From.Type == obj.TYPE_CONST {
- o1 |= uint32((p.From.Offset & 0xF) << 8)
- }
-
- case 52: /* hint */
- o1 = opirr(ctxt, p.As)
-
- o1 |= uint32((p.From.Offset & 0x7F) << 5)
-
- case 53: /* and/or/eor/bic/... $bitcon, Rn, Rd */
- a := p.As
- rt := int(p.To.Reg)
- r := int(p.Reg)
- if r == 0 {
- r = rt
- }
- mode := 64
- v := uint64(p.From.Offset)
- switch p.As {
- case AANDW, AORRW, AEORW, AANDSW:
- mode = 32
- case ABIC, AORN, AEON, ABICS:
- v = ^v
- case ABICW, AORNW, AEONW, ABICSW:
- v = ^v
- mode = 32
- }
- o1 = opirr(ctxt, a)
- o1 |= bitconEncode(v, mode) | uint32(r&31)<<5 | uint32(rt&31)
-
- case 54: /* floating point arith */
- o1 = oprrr(ctxt, p.As)
-
- var rf int
- if p.From.Type == obj.TYPE_CONST {
- rf = chipfloat7(ctxt, p.From.Val.(float64))
- if rf < 0 || true {
- ctxt.Diag("invalid floating-point immediate\n%v", p)
- rf = 0
- }
-
- rf |= (1 << 3)
- } else {
- rf = int(p.From.Reg)
- }
- rt := int(p.To.Reg)
- r := int(p.Reg)
- if (o1&(0x1F<<24)) == (0x1E<<24) && (o1&(1<<11)) == 0 { /* monadic */
- r = rf
- rf = 0
- } else if r == 0 {
- r = rt
- }
- o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
-
- case 56: /* floating point compare */
- o1 = oprrr(ctxt, p.As)
-
- var rf int
- if p.From.Type == obj.TYPE_CONST {
- o1 |= 8 /* zero */
- rf = 0
- } else {
- rf = int(p.From.Reg)
- }
- rt := int(p.Reg)
- o1 |= uint32(rf&31)<<16 | uint32(rt&31)<<5
-
- case 57: /* floating point conditional compare */
- o1 = oprrr(ctxt, p.As)
-
- cond := int(p.From.Reg)
- nzcv := int(p.To.Offset)
- if nzcv&^0xF != 0 {
- ctxt.Diag("implausible condition\n%v", p)
- }
- rf := int(p.Reg)
- if p.From3 == nil || p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 {
- ctxt.Diag("illegal FCCMP\n%v", p)
- break
- }
- rt := int(p.From3.Reg)
- o1 |= uint32(rf&31)<<16 | uint32(cond)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
-
- case 58: /* ldar/ldxr/ldaxr */
- o1 = opload(ctxt, p.As)
-
- o1 |= 0x1F << 16
- o1 |= uint32(p.From.Reg) << 5
- if p.Reg != 0 {
- o1 |= uint32(p.Reg) << 10
- } else {
- o1 |= 0x1F << 10
- }
- o1 |= uint32(p.To.Reg & 31)
-
- case 59: /* stxr/stlxr */
- o1 = opstore(ctxt, p.As)
-
- if p.RegTo2 != obj.REG_NONE {
- o1 |= uint32(p.RegTo2&31) << 16
- } else {
- o1 |= 0x1F << 16
- }
-
- // TODO(aram): add support for STXP
- o1 |= uint32(p.To.Reg&31) << 5
-
- o1 |= uint32(p.From.Reg & 31)
-
- case 60: /* adrp label,r */
- d := brdist(ctxt, p, 12, 21, 0)
-
- o1 = ADR(1, uint32(d), uint32(p.To.Reg))
-
- case 61: /* adr label, r */
- d := brdist(ctxt, p, 0, 21, 0)
-
- o1 = ADR(0, uint32(d), uint32(p.To.Reg))
-
- case 62: /* op $movcon, [R], R -> mov $movcon, REGTMP + op REGTMP, [R], R */
- if p.Reg == REGTMP {
- ctxt.Diag("cannot use REGTMP as source: %v\n", p)
- }
- o1 = omovconst(ctxt, AMOVD, p, &p.From, REGTMP)
-
- rt := int(p.To.Reg)
- if p.To.Type == obj.TYPE_NONE {
- rt = REGZERO
- }
- r := int(p.Reg)
- if r == 0 {
- r = rt
- }
- if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
- o2 = opxrrr(ctxt, p.As)
- o2 |= REGTMP & 31 << 16
- o2 |= LSL0_64
- } else {
- o2 = oprrr(ctxt, p.As)
- o2 |= REGTMP & 31 << 16 /* shift is 0 */
- }
- o2 |= uint32(r&31) << 5
- o2 |= uint32(rt & 31)
-
- /* reloc ops */
- case 64: /* movT R,addr -> adrp + add + movT R, (REGTMP) */
- o1 = ADR(1, 0, REGTMP)
- o2 = opirr(ctxt, AADD) | REGTMP&31<<5 | REGTMP&31
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 8
- rel.Sym = p.To.Sym
- rel.Add = p.To.Offset
- rel.Type = obj.R_ADDRARM64
- o3 = olsr12u(ctxt, int32(opstr12(ctxt, p.As)), 0, REGTMP, int(p.From.Reg))
-
- case 65: /* movT addr,R -> adrp + add + movT (REGTMP), R */
- o1 = ADR(1, 0, REGTMP)
- o2 = opirr(ctxt, AADD) | REGTMP&31<<5 | REGTMP&31
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 8
- rel.Sym = p.From.Sym
- rel.Add = p.From.Offset
- rel.Type = obj.R_ADDRARM64
- o3 = olsr12u(ctxt, int32(opldr12(ctxt, p.As)), 0, REGTMP, int(p.To.Reg))
-
- case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */
- v := int32(p.From.Offset)
-
- if v < -512 || v > 504 {
- ctxt.Diag("offset out of range\n%v", p)
- }
- if o.scond == C_XPOST {
- o1 |= 1 << 23
- } else {
- o1 |= 3 << 23
- }
- o1 |= 1 << 22
- o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.To.Offset<<10 | int64(uint32(p.From.Reg&31)<<5) | int64(p.To.Reg&31))
-
- case 67: /* stp (r1, r2), O(R)!; stp (r1, r2), (R)O! */
- v := int32(p.To.Offset)
-
- if v < -512 || v > 504 {
- ctxt.Diag("offset out of range\n%v", p)
- }
- if o.scond == C_XPOST {
- o1 |= 1 << 23
- } else {
- o1 |= 3 << 23
- }
- o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.From.Offset<<10 | int64(uint32(p.To.Reg&31)<<5) | int64(p.From.Reg&31))
-
- case 68: /* movT $vconaddr(SB), reg -> adrp + add + reloc */
- if p.As == AMOVW {
- ctxt.Diag("invalid load of 32-bit address: %v", p)
- }
- o1 = ADR(1, 0, uint32(p.To.Reg))
- o2 = opirr(ctxt, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31)
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 8
- rel.Sym = p.From.Sym
- rel.Add = p.From.Offset
- rel.Type = obj.R_ADDRARM64
-
- case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */
- o1 = opirr(ctxt, AMOVZ)
- o1 |= uint32(p.To.Reg & 31)
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 4
- rel.Sym = p.From.Sym
- rel.Type = obj.R_ARM64_TLS_LE
- if p.From.Offset != 0 {
- ctxt.Diag("invalid offset on MOVW $tlsvar")
- }
-
- case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */
- o1 = ADR(1, 0, REGTMP)
- o2 = olsr12u(ctxt, int32(opldr12(ctxt, AMOVD)), 0, REGTMP, int(p.To.Reg))
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 8
- rel.Sym = p.From.Sym
- rel.Add = 0
- rel.Type = obj.R_ARM64_TLS_IE
- if p.From.Offset != 0 {
- ctxt.Diag("invalid offset on MOVW $tlsvar")
- }
-
- case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */
- o1 = ADR(1, 0, REGTMP)
- o2 = olsr12u(ctxt, int32(opldr12(ctxt, AMOVD)), 0, REGTMP, int(p.To.Reg))
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 8
- rel.Sym = p.From.Sym
- rel.Add = 0
- rel.Type = obj.R_ARM64_GOTPCREL
-
- // This is supposed to be something that stops execution.
- // It's not supposed to be reached, ever, but if it is, we'd
- // like to be able to tell how we got there. Assemble as
- // 0xbea71700 which is guaranteed to raise undefined instruction
- // exception.
- case 90:
- o1 = 0xbea71700
-
- break
- }
-
- out[0] = o1
- out[1] = o2
- out[2] = o3
- out[3] = o4
- out[4] = o5
- return
-}
-
-/*
- * basic Rm op Rn -> Rd (using shifted register with 0)
- * also op Rn -> Rt
- * also Rm*Rn op Ra -> Rd
- */
-func oprrr(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case AADC:
- return S64 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
-
- case AADCW:
- return S32 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
-
- case AADCS:
- return S64 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
-
- case AADCSW:
- return S32 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
-
- case ANGC, ASBC:
- return S64 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
-
- case ANGCS, ASBCS:
- return S64 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
-
- case ANGCW, ASBCW:
- return S32 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
-
- case ANGCSW, ASBCSW:
- return S32 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
-
- case AADD:
- return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case AADDW:
- return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case ACMN, AADDS:
- return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case ACMNW, AADDSW:
- return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case ASUB:
- return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case ASUBW:
- return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case ACMP, ASUBS:
- return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case ACMPW, ASUBSW:
- return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
-
- case AAND:
- return S64 | 0<<29 | 0xA<<24
-
- case AANDW:
- return S32 | 0<<29 | 0xA<<24
-
- case AMOVD, AORR:
- return S64 | 1<<29 | 0xA<<24
-
- // case AMOVW:
- case AMOVWU, AORRW:
- return S32 | 1<<29 | 0xA<<24
-
- case AEOR:
- return S64 | 2<<29 | 0xA<<24
-
- case AEORW:
- return S32 | 2<<29 | 0xA<<24
-
- case AANDS:
- return S64 | 3<<29 | 0xA<<24
-
- case AANDSW:
- return S32 | 3<<29 | 0xA<<24
-
- case ABIC:
- return S64 | 0<<29 | 0xA<<24 | 1<<21
-
- case ABICW:
- return S32 | 0<<29 | 0xA<<24 | 1<<21
-
- case ABICS:
- return S64 | 3<<29 | 0xA<<24 | 1<<21
-
- case ABICSW:
- return S32 | 3<<29 | 0xA<<24 | 1<<21
-
- case AEON:
- return S64 | 2<<29 | 0xA<<24 | 1<<21
-
- case AEONW:
- return S32 | 2<<29 | 0xA<<24 | 1<<21
-
- case AMVN, AORN:
- return S64 | 1<<29 | 0xA<<24 | 1<<21
-
- case AMVNW, AORNW:
- return S32 | 1<<29 | 0xA<<24 | 1<<21
-
- case AASR:
- return S64 | OPDP2(10) /* also ASRV */
-
- case AASRW:
- return S32 | OPDP2(10)
-
- case ALSL:
- return S64 | OPDP2(8)
-
- case ALSLW:
- return S32 | OPDP2(8)
-
- case ALSR:
- return S64 | OPDP2(9)
-
- case ALSRW:
- return S32 | OPDP2(9)
-
- case AROR:
- return S64 | OPDP2(11)
-
- case ARORW:
- return S32 | OPDP2(11)
-
- case ACCMN:
- return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* cond<<12 | nzcv<<0 */
-
- case ACCMNW:
- return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
-
- case ACCMP:
- return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
-
- case ACCMPW:
- return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
-
- case ACRC32B:
- return S32 | OPDP2(16)
-
- case ACRC32H:
- return S32 | OPDP2(17)
-
- case ACRC32W:
- return S32 | OPDP2(18)
-
- case ACRC32X:
- return S64 | OPDP2(19)
-
- case ACRC32CB:
- return S32 | OPDP2(20)
-
- case ACRC32CH:
- return S32 | OPDP2(21)
-
- case ACRC32CW:
- return S32 | OPDP2(22)
-
- case ACRC32CX:
- return S64 | OPDP2(23)
-
- case ACSEL:
- return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
-
- case ACSELW:
- return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
-
- case ACSET:
- return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
-
- case ACSETW:
- return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
-
- case ACSETM:
- return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
-
- case ACSETMW:
- return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
-
- case ACINC, ACSINC:
- return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
-
- case ACINCW, ACSINCW:
- return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
-
- case ACINV, ACSINV:
- return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
-
- case ACINVW, ACSINVW:
- return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
-
- case ACNEG, ACSNEG:
- return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
-
- case ACNEGW, ACSNEGW:
- return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
-
- case AMUL, AMADD:
- return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
-
- case AMULW, AMADDW:
- return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
-
- case AMNEG, AMSUB:
- return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
-
- case AMNEGW, AMSUBW:
- return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
-
- case AMRS:
- return SYSOP(1, 2, 0, 0, 0, 0, 0)
-
- case AMSR:
- return SYSOP(0, 2, 0, 0, 0, 0, 0)
-
- case ANEG:
- return S64 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
-
- case ANEGW:
- return S32 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
-
- case ANEGS:
- return S64 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
-
- case ANEGSW:
- return S32 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
-
- case AREM, ASDIV:
- return S64 | OPDP2(3)
-
- case AREMW, ASDIVW:
- return S32 | OPDP2(3)
-
- case ASMULL, ASMADDL:
- return OPDP3(1, 0, 1, 0)
-
- case ASMNEGL, ASMSUBL:
- return OPDP3(1, 0, 1, 1)
-
- case ASMULH:
- return OPDP3(1, 0, 2, 0)
-
- case AUMULL, AUMADDL:
- return OPDP3(1, 0, 5, 0)
-
- case AUMNEGL, AUMSUBL:
- return OPDP3(1, 0, 5, 1)
-
- case AUMULH:
- return OPDP3(1, 0, 6, 0)
-
- case AUREM, AUDIV:
- return S64 | OPDP2(2)
-
- case AUREMW, AUDIVW:
- return S32 | OPDP2(2)
-
- case AAESE:
- return 0x4E<<24 | 2<<20 | 8<<16 | 4<<12 | 2<<10
-
- case AAESD:
- return 0x4E<<24 | 2<<20 | 8<<16 | 5<<12 | 2<<10
-
- case AAESMC:
- return 0x4E<<24 | 2<<20 | 8<<16 | 6<<12 | 2<<10
-
- case AAESIMC:
- return 0x4E<<24 | 2<<20 | 8<<16 | 7<<12 | 2<<10
-
- case ASHA1C:
- return 0x5E<<24 | 0<<12
-
- case ASHA1P:
- return 0x5E<<24 | 1<<12
-
- case ASHA1M:
- return 0x5E<<24 | 2<<12
-
- case ASHA1SU0:
- return 0x5E<<24 | 3<<12
-
- case ASHA256H:
- return 0x5E<<24 | 4<<12
-
- case ASHA256H2:
- return 0x5E<<24 | 5<<12
-
- case ASHA256SU1:
- return 0x5E<<24 | 6<<12
-
- case ASHA1H:
- return 0x5E<<24 | 2<<20 | 8<<16 | 0<<12 | 2<<10
-
- case ASHA1SU1:
- return 0x5E<<24 | 2<<20 | 8<<16 | 1<<12 | 2<<10
-
- case ASHA256SU0:
- return 0x5E<<24 | 2<<20 | 8<<16 | 2<<12 | 2<<10
-
- case AFCVTZSD:
- return FPCVTI(1, 0, 1, 3, 0)
-
- case AFCVTZSDW:
- return FPCVTI(0, 0, 1, 3, 0)
-
- case AFCVTZSS:
- return FPCVTI(1, 0, 0, 3, 0)
-
- case AFCVTZSSW:
- return FPCVTI(0, 0, 0, 3, 0)
-
- case AFCVTZUD:
- return FPCVTI(1, 0, 1, 3, 1)
-
- case AFCVTZUDW:
- return FPCVTI(0, 0, 1, 3, 1)
-
- case AFCVTZUS:
- return FPCVTI(1, 0, 0, 3, 1)
-
- case AFCVTZUSW:
- return FPCVTI(0, 0, 0, 3, 1)
-
- case ASCVTFD:
- return FPCVTI(1, 0, 1, 0, 2)
-
- case ASCVTFS:
- return FPCVTI(1, 0, 0, 0, 2)
-
- case ASCVTFWD:
- return FPCVTI(0, 0, 1, 0, 2)
-
- case ASCVTFWS:
- return FPCVTI(0, 0, 0, 0, 2)
-
- case AUCVTFD:
- return FPCVTI(1, 0, 1, 0, 3)
-
- case AUCVTFS:
- return FPCVTI(1, 0, 0, 0, 3)
-
- case AUCVTFWD:
- return FPCVTI(0, 0, 1, 0, 3)
-
- case AUCVTFWS:
- return FPCVTI(0, 0, 0, 0, 3)
-
- case AFADDS:
- return FPOP2S(0, 0, 0, 2)
-
- case AFADDD:
- return FPOP2S(0, 0, 1, 2)
-
- case AFSUBS:
- return FPOP2S(0, 0, 0, 3)
-
- case AFSUBD:
- return FPOP2S(0, 0, 1, 3)
-
- case AFMULS:
- return FPOP2S(0, 0, 0, 0)
-
- case AFMULD:
- return FPOP2S(0, 0, 1, 0)
-
- case AFDIVS:
- return FPOP2S(0, 0, 0, 1)
-
- case AFDIVD:
- return FPOP2S(0, 0, 1, 1)
-
- case AFMAXS:
- return FPOP2S(0, 0, 0, 4)
-
- case AFMINS:
- return FPOP2S(0, 0, 0, 5)
-
- case AFMAXD:
- return FPOP2S(0, 0, 1, 4)
-
- case AFMIND:
- return FPOP2S(0, 0, 1, 5)
-
- case AFMAXNMS:
- return FPOP2S(0, 0, 0, 6)
-
- case AFMAXNMD:
- return FPOP2S(0, 0, 1, 6)
-
- case AFMINNMS:
- return FPOP2S(0, 0, 0, 7)
-
- case AFMINNMD:
- return FPOP2S(0, 0, 1, 7)
-
- case AFNMULS:
- return FPOP2S(0, 0, 0, 8)
-
- case AFNMULD:
- return FPOP2S(0, 0, 1, 8)
-
- case AFCMPS:
- return FPCMP(0, 0, 0, 0, 0)
-
- case AFCMPD:
- return FPCMP(0, 0, 1, 0, 0)
-
- case AFCMPES:
- return FPCMP(0, 0, 0, 0, 16)
-
- case AFCMPED:
- return FPCMP(0, 0, 1, 0, 16)
-
- case AFCCMPS:
- return FPCCMP(0, 0, 0, 0)
-
- case AFCCMPD:
- return FPCCMP(0, 0, 1, 0)
-
- case AFCCMPES:
- return FPCCMP(0, 0, 0, 1)
-
- case AFCCMPED:
- return FPCCMP(0, 0, 1, 1)
-
- case AFCSELS:
- return 0x1E<<24 | 0<<22 | 1<<21 | 3<<10
-
- case AFCSELD:
- return 0x1E<<24 | 1<<22 | 1<<21 | 3<<10
-
- case AFMOVS:
- return FPOP1S(0, 0, 0, 0)
-
- case AFABSS:
- return FPOP1S(0, 0, 0, 1)
-
- case AFNEGS:
- return FPOP1S(0, 0, 0, 2)
-
- case AFSQRTS:
- return FPOP1S(0, 0, 0, 3)
-
- case AFCVTSD:
- return FPOP1S(0, 0, 0, 5)
-
- case AFCVTSH:
- return FPOP1S(0, 0, 0, 7)
-
- case AFRINTNS:
- return FPOP1S(0, 0, 0, 8)
-
- case AFRINTPS:
- return FPOP1S(0, 0, 0, 9)
-
- case AFRINTMS:
- return FPOP1S(0, 0, 0, 10)
-
- case AFRINTZS:
- return FPOP1S(0, 0, 0, 11)
-
- case AFRINTAS:
- return FPOP1S(0, 0, 0, 12)
-
- case AFRINTXS:
- return FPOP1S(0, 0, 0, 14)
-
- case AFRINTIS:
- return FPOP1S(0, 0, 0, 15)
-
- case AFMOVD:
- return FPOP1S(0, 0, 1, 0)
-
- case AFABSD:
- return FPOP1S(0, 0, 1, 1)
-
- case AFNEGD:
- return FPOP1S(0, 0, 1, 2)
-
- case AFSQRTD:
- return FPOP1S(0, 0, 1, 3)
-
- case AFCVTDS:
- return FPOP1S(0, 0, 1, 4)
-
- case AFCVTDH:
- return FPOP1S(0, 0, 1, 7)
-
- case AFRINTND:
- return FPOP1S(0, 0, 1, 8)
-
- case AFRINTPD:
- return FPOP1S(0, 0, 1, 9)
-
- case AFRINTMD:
- return FPOP1S(0, 0, 1, 10)
-
- case AFRINTZD:
- return FPOP1S(0, 0, 1, 11)
-
- case AFRINTAD:
- return FPOP1S(0, 0, 1, 12)
-
- case AFRINTXD:
- return FPOP1S(0, 0, 1, 14)
-
- case AFRINTID:
- return FPOP1S(0, 0, 1, 15)
-
- case AFCVTHS:
- return FPOP1S(0, 0, 3, 4)
-
- case AFCVTHD:
- return FPOP1S(0, 0, 3, 5)
- }
-
- ctxt.Diag("bad rrr %d %v", a, a)
- prasm(ctxt.Curp)
- return 0
-}
-
-/*
- * imm -> Rd
- * imm op Rn -> Rd
- */
-func opirr(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- /* op $addcon, Rn, Rd */
- case AMOVD, AADD:
- return S64 | 0<<30 | 0<<29 | 0x11<<24
-
- case ACMN, AADDS:
- return S64 | 0<<30 | 1<<29 | 0x11<<24
-
- case AMOVW, AADDW:
- return S32 | 0<<30 | 0<<29 | 0x11<<24
-
- case ACMNW, AADDSW:
- return S32 | 0<<30 | 1<<29 | 0x11<<24
-
- case ASUB:
- return S64 | 1<<30 | 0<<29 | 0x11<<24
-
- case ACMP, ASUBS:
- return S64 | 1<<30 | 1<<29 | 0x11<<24
-
- case ASUBW:
- return S32 | 1<<30 | 0<<29 | 0x11<<24
-
- case ACMPW, ASUBSW:
- return S32 | 1<<30 | 1<<29 | 0x11<<24
-
- /* op $imm(SB), Rd; op label, Rd */
- case AADR:
- return 0<<31 | 0x10<<24
-
- case AADRP:
- return 1<<31 | 0x10<<24
-
- /* op $bimm, Rn, Rd */
- case AAND, ABIC:
- return S64 | 0<<29 | 0x24<<23
-
- case AANDW, ABICW:
- return S32 | 0<<29 | 0x24<<23 | 0<<22
-
- case AORR, AORN:
- return S64 | 1<<29 | 0x24<<23
-
- case AORRW, AORNW:
- return S32 | 1<<29 | 0x24<<23 | 0<<22
-
- case AEOR, AEON:
- return S64 | 2<<29 | 0x24<<23
-
- case AEORW, AEONW:
- return S32 | 2<<29 | 0x24<<23 | 0<<22
-
- case AANDS, ABICS:
- return S64 | 3<<29 | 0x24<<23
-
- case AANDSW, ABICSW:
- return S32 | 3<<29 | 0x24<<23 | 0<<22
-
- case AASR:
- return S64 | 0<<29 | 0x26<<23 /* alias of SBFM */
-
- case AASRW:
- return S32 | 0<<29 | 0x26<<23 | 0<<22
-
- /* op $width, $lsb, Rn, Rd */
- case ABFI:
- return S64 | 2<<29 | 0x26<<23 | 1<<22
- /* alias of BFM */
-
- case ABFIW:
- return S32 | 2<<29 | 0x26<<23 | 0<<22
-
- /* op $imms, $immr, Rn, Rd */
- case ABFM:
- return S64 | 1<<29 | 0x26<<23 | 1<<22
-
- case ABFMW:
- return S32 | 1<<29 | 0x26<<23 | 0<<22
-
- case ASBFM:
- return S64 | 0<<29 | 0x26<<23 | 1<<22
-
- case ASBFMW:
- return S32 | 0<<29 | 0x26<<23 | 0<<22
-
- case AUBFM:
- return S64 | 2<<29 | 0x26<<23 | 1<<22
-
- case AUBFMW:
- return S32 | 2<<29 | 0x26<<23 | 0<<22
-
- case ABFXIL:
- return S64 | 1<<29 | 0x26<<23 | 1<<22 /* alias of BFM */
-
- case ABFXILW:
- return S32 | 1<<29 | 0x26<<23 | 0<<22
-
- case AEXTR:
- return S64 | 0<<29 | 0x27<<23 | 1<<22 | 0<<21
-
- case AEXTRW:
- return S32 | 0<<29 | 0x27<<23 | 0<<22 | 0<<21
-
- case ACBNZ:
- return S64 | 0x1A<<25 | 1<<24
-
- case ACBNZW:
- return S32 | 0x1A<<25 | 1<<24
-
- case ACBZ:
- return S64 | 0x1A<<25 | 0<<24
-
- case ACBZW:
- return S32 | 0x1A<<25 | 0<<24
-
- case ACCMN:
- return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
-
- case ACCMNW:
- return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
-
- case ACCMP:
- return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
-
- case ACCMPW:
- return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
-
- case AMOVK:
- return S64 | 3<<29 | 0x25<<23
-
- case AMOVKW:
- return S32 | 3<<29 | 0x25<<23
-
- case AMOVN:
- return S64 | 0<<29 | 0x25<<23
-
- case AMOVNW:
- return S32 | 0<<29 | 0x25<<23
-
- case AMOVZ:
- return S64 | 2<<29 | 0x25<<23
-
- case AMOVZW:
- return S32 | 2<<29 | 0x25<<23
-
- case AMSR:
- return SYSOP(0, 0, 0, 4, 0, 0, 0x1F) /* MSR (immediate) */
-
- case AAT,
- ADC,
- AIC,
- ATLBI,
- ASYS:
- return SYSOP(0, 1, 0, 0, 0, 0, 0)
-
- case ASYSL:
- return SYSOP(1, 1, 0, 0, 0, 0, 0)
-
- case ATBZ:
- return 0x36 << 24
-
- case ATBNZ:
- return 0x37 << 24
-
- case ADSB:
- return SYSOP(0, 0, 3, 3, 0, 4, 0x1F)
-
- case ADMB:
- return SYSOP(0, 0, 3, 3, 0, 5, 0x1F)
-
- case AISB:
- return SYSOP(0, 0, 3, 3, 0, 6, 0x1F)
-
- case AHINT:
- return SYSOP(0, 0, 3, 2, 0, 0, 0x1F)
- }
-
- ctxt.Diag("bad irr %v", a)
- prasm(ctxt.Curp)
- return 0
-}
-
-func opbit(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case ACLS:
- return S64 | OPBIT(5)
-
- case ACLSW:
- return S32 | OPBIT(5)
-
- case ACLZ:
- return S64 | OPBIT(4)
-
- case ACLZW:
- return S32 | OPBIT(4)
-
- case ARBIT:
- return S64 | OPBIT(0)
-
- case ARBITW:
- return S32 | OPBIT(0)
-
- case AREV:
- return S64 | OPBIT(3)
-
- case AREVW:
- return S32 | OPBIT(2)
-
- case AREV16:
- return S64 | OPBIT(1)
-
- case AREV16W:
- return S32 | OPBIT(1)
-
- case AREV32:
- return S64 | OPBIT(2)
-
- default:
- ctxt.Diag("bad bit op\n%v", ctxt.Curp)
- return 0
- }
-}
-
-/*
- * add/subtract extended register
- */
-func opxrrr(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case AADD:
- return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
-
- case AADDW:
- return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
-
- case ACMN, AADDS:
- return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
-
- case ACMNW, AADDSW:
- return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
-
- case ASUB:
- return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
-
- case ASUBW:
- return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
-
- case ACMP, ASUBS:
- return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
-
- case ACMPW, ASUBSW:
- return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
- }
-
- ctxt.Diag("bad opxrrr %v\n%v", a, ctxt.Curp)
- return 0
-}
-
-func opimm(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case ASVC:
- return 0xD4<<24 | 0<<21 | 1 /* imm16<<5 */
-
- case AHVC:
- return 0xD4<<24 | 0<<21 | 2
-
- case ASMC:
- return 0xD4<<24 | 0<<21 | 3
-
- case ABRK:
- return 0xD4<<24 | 1<<21 | 0
-
- case AHLT:
- return 0xD4<<24 | 2<<21 | 0
-
- case ADCPS1:
- return 0xD4<<24 | 5<<21 | 1
-
- case ADCPS2:
- return 0xD4<<24 | 5<<21 | 2
-
- case ADCPS3:
- return 0xD4<<24 | 5<<21 | 3
-
- case ACLREX:
- return SYSOP(0, 0, 3, 3, 0, 2, 0x1F)
- }
-
- ctxt.Diag("bad imm %v", a)
- prasm(ctxt.Curp)
- return 0
-}
-
-func brdist(ctxt *obj.Link, p *obj.Prog, preshift int, flen int, shift int) int64 {
- v := int64(0)
- t := int64(0)
- if p.Pcond != nil {
- v = (p.Pcond.Pc >> uint(preshift)) - (ctxt.Pc >> uint(preshift))
- if (v & ((1 << uint(shift)) - 1)) != 0 {
- ctxt.Diag("misaligned label\n%v", p)
- }
- v >>= uint(shift)
- t = int64(1) << uint(flen-1)
- if v < -t || v >= t {
- ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, ctxt.Blitrl, p, p.Pcond)
- panic("branch too far")
- }
- }
-
- return v & ((t << 1) - 1)
-}
-
-/*
- * pc-relative branches
- */
-func opbra(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case ABEQ:
- return OPBcc(0x0)
-
- case ABNE:
- return OPBcc(0x1)
-
- case ABCS:
- return OPBcc(0x2)
-
- case ABHS:
- return OPBcc(0x2)
-
- case ABCC:
- return OPBcc(0x3)
-
- case ABLO:
- return OPBcc(0x3)
-
- case ABMI:
- return OPBcc(0x4)
-
- case ABPL:
- return OPBcc(0x5)
-
- case ABVS:
- return OPBcc(0x6)
-
- case ABVC:
- return OPBcc(0x7)
-
- case ABHI:
- return OPBcc(0x8)
-
- case ABLS:
- return OPBcc(0x9)
-
- case ABGE:
- return OPBcc(0xa)
-
- case ABLT:
- return OPBcc(0xb)
-
- case ABGT:
- return OPBcc(0xc)
-
- case ABLE:
- return OPBcc(0xd) /* imm19<<5 | cond */
-
- case AB:
- return 0<<31 | 5<<26 /* imm26 */
-
- case obj.ADUFFZERO, obj.ADUFFCOPY, ABL:
- return 1<<31 | 5<<26
- }
-
- ctxt.Diag("bad bra %v", a)
- prasm(ctxt.Curp)
- return 0
-}
-
-func opbrr(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case ABL:
- return OPBLR(1) /* BLR */
-
- case AB:
- return OPBLR(0) /* BR */
-
- case obj.ARET:
- return OPBLR(2) /* RET */
- }
-
- ctxt.Diag("bad brr %v", a)
- prasm(ctxt.Curp)
- return 0
-}
-
-func op0(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case ADRPS:
- return 0x6B<<25 | 5<<21 | 0x1F<<16 | 0x1F<<5
-
- case AERET:
- return 0x6B<<25 | 4<<21 | 0x1F<<16 | 0<<10 | 0x1F<<5
-
- // case ANOP:
- // return SYSHINT(0)
-
- case AYIELD:
- return SYSHINT(1)
-
- case AWFE:
- return SYSHINT(2)
-
- case AWFI:
- return SYSHINT(3)
-
- case ASEV:
- return SYSHINT(4)
-
- case ASEVL:
- return SYSHINT(5)
- }
-
- ctxt.Diag("bad op0 %v", a)
- prasm(ctxt.Curp)
- return 0
-}
-
-/*
- * register offset
- */
-func opload(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case ALDAR:
- return LDSTX(3, 1, 1, 0, 1) | 0x1F<<10
-
- case ALDARW:
- return LDSTX(2, 1, 1, 0, 1) | 0x1F<<10
-
- case ALDARB:
- return LDSTX(0, 1, 1, 0, 1) | 0x1F<<10
-
- case ALDARH:
- return LDSTX(1, 1, 1, 0, 1) | 0x1F<<10
-
- case ALDAXP:
- return LDSTX(3, 0, 1, 1, 1)
-
- case ALDAXPW:
- return LDSTX(2, 0, 1, 1, 1)
-
- case ALDAXR:
- return LDSTX(3, 0, 1, 0, 1) | 0x1F<<10
-
- case ALDAXRW:
- return LDSTX(2, 0, 1, 0, 1) | 0x1F<<10
-
- case ALDAXRB:
- return LDSTX(0, 0, 1, 0, 1) | 0x1F<<10
-
- case ALDAXRH:
- return LDSTX(1, 0, 1, 0, 1) | 0x1F<<10
-
- case ALDXR:
- return LDSTX(3, 0, 1, 0, 0) | 0x1F<<10
-
- case ALDXRB:
- return LDSTX(0, 0, 1, 0, 0) | 0x1F<<10
-
- case ALDXRH:
- return LDSTX(1, 0, 1, 0, 0) | 0x1F<<10
-
- case ALDXRW:
- return LDSTX(2, 0, 1, 0, 0) | 0x1F<<10
-
- case ALDXP:
- return LDSTX(3, 0, 1, 1, 0)
-
- case ALDXPW:
- return LDSTX(2, 0, 1, 1, 0)
-
- case AMOVNP:
- return S64 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
-
- case AMOVNPW:
- return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
- }
-
- ctxt.Diag("bad opload %v\n%v", a, ctxt.Curp)
- return 0
-}
-
-func opstore(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case ASTLR:
- return LDSTX(3, 1, 0, 0, 1) | 0x1F<<10
-
- case ASTLRB:
- return LDSTX(0, 1, 0, 0, 1) | 0x1F<<10
-
- case ASTLRH:
- return LDSTX(1, 1, 0, 0, 1) | 0x1F<<10
-
- case ASTLP:
- return LDSTX(3, 0, 0, 1, 1)
-
- case ASTLPW:
- return LDSTX(2, 0, 0, 1, 1)
-
- case ASTLRW:
- return LDSTX(2, 1, 0, 0, 1) | 0x1F<<10
-
- case ASTLXP:
- return LDSTX(2, 0, 0, 1, 1)
-
- case ASTLXPW:
- return LDSTX(3, 0, 0, 1, 1)
-
- case ASTLXR:
- return LDSTX(3, 0, 0, 0, 1) | 0x1F<<10
-
- case ASTLXRB:
- return LDSTX(0, 0, 0, 0, 1) | 0x1F<<10
-
- case ASTLXRH:
- return LDSTX(1, 0, 0, 0, 1) | 0x1F<<10
-
- case ASTLXRW:
- return LDSTX(2, 0, 0, 0, 1) | 0x1F<<10
-
- case ASTXR:
- return LDSTX(3, 0, 0, 0, 0) | 0x1F<<10
-
- case ASTXRB:
- return LDSTX(0, 0, 0, 0, 0) | 0x1F<<10
-
- case ASTXRH:
- return LDSTX(1, 0, 0, 0, 0) | 0x1F<<10
-
- case ASTXP:
- return LDSTX(3, 0, 0, 1, 0)
-
- case ASTXPW:
- return LDSTX(2, 0, 0, 1, 0)
-
- case ASTXRW:
- return LDSTX(2, 0, 0, 0, 0) | 0x1F<<10
-
- case AMOVNP:
- return S64 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
-
- case AMOVNPW:
- return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
- }
-
- ctxt.Diag("bad opstore %v\n%v", a, ctxt.Curp)
- return 0
-}
-
-/*
- * load/store register (unsigned immediate) C3.3.13
- * these produce 64-bit values (when there's an option)
- */
-func olsr12u(ctxt *obj.Link, o int32, v int32, b int, r int) uint32 {
- if v < 0 || v >= (1<<12) {
- ctxt.Diag("offset out of range: %d\n%v", v, ctxt.Curp)
- }
- o |= (v & 0xFFF) << 10
- o |= int32(b&31) << 5
- o |= int32(r & 31)
- return uint32(o)
-}
-
-func opldr12(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case AMOVD:
- return LDSTR12U(3, 0, 1) /* imm12<<10 | Rn<<5 | Rt */
-
- case AMOVW:
- return LDSTR12U(2, 0, 2)
-
- case AMOVWU:
- return LDSTR12U(2, 0, 1)
-
- case AMOVH:
- return LDSTR12U(1, 0, 2)
-
- case AMOVHU:
- return LDSTR12U(1, 0, 1)
-
- case AMOVB:
- return LDSTR12U(0, 0, 2)
-
- case AMOVBU:
- return LDSTR12U(0, 0, 1)
-
- case AFMOVS:
- return LDSTR12U(2, 1, 1)
-
- case AFMOVD:
- return LDSTR12U(3, 1, 1)
- }
-
- ctxt.Diag("bad opldr12 %v\n%v", a, ctxt.Curp)
- return 0
-}
-
-func opstr12(ctxt *obj.Link, a obj.As) uint32 {
- return LD2STR(opldr12(ctxt, a))
-}
-
-/*
- * load/store register (unscaled immediate) C3.3.12
- */
-func olsr9s(ctxt *obj.Link, o int32, v int32, b int, r int) uint32 {
- if v < -256 || v > 255 {
- ctxt.Diag("offset out of range: %d\n%v", v, ctxt.Curp)
- }
- o |= (v & 0x1FF) << 12
- o |= int32(b&31) << 5
- o |= int32(r & 31)
- return uint32(o)
-}
-
-func opldr9(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case AMOVD:
- return LDSTR9S(3, 0, 1) /* simm9<<12 | Rn<<5 | Rt */
-
- case AMOVW:
- return LDSTR9S(2, 0, 2)
-
- case AMOVWU:
- return LDSTR9S(2, 0, 1)
-
- case AMOVH:
- return LDSTR9S(1, 0, 2)
-
- case AMOVHU:
- return LDSTR9S(1, 0, 1)
-
- case AMOVB:
- return LDSTR9S(0, 0, 2)
-
- case AMOVBU:
- return LDSTR9S(0, 0, 1)
-
- case AFMOVS:
- return LDSTR9S(2, 1, 1)
-
- case AFMOVD:
- return LDSTR9S(3, 1, 1)
- }
-
- ctxt.Diag("bad opldr9 %v\n%v", a, ctxt.Curp)
- return 0
-}
-
-func opstr9(ctxt *obj.Link, a obj.As) uint32 {
- return LD2STR(opldr9(ctxt, a))
-}
-
-func opldrpp(ctxt *obj.Link, a obj.As) uint32 {
- switch a {
- case AMOVD:
- return 3<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 /* simm9<<12 | Rn<<5 | Rt */
-
- case AMOVW:
- return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22
-
- case AMOVWU:
- return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
-
- case AMOVH:
- return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22
-
- case AMOVHU:
- return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
-
- case AMOVB:
- return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22
-
- case AMOVBU:
- return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
- }
-
- ctxt.Diag("bad opldr %v\n%v", a, ctxt.Curp)
- return 0
-}
-
-/*
- * load/store register (extended register)
- */
-func olsxrr(ctxt *obj.Link, as obj.As, rt int, r1 int, r2 int) uint32 {
- ctxt.Diag("need load/store extended register\n%v", ctxt.Curp)
- return 0xffffffff
-}
-
-func oaddi(ctxt *obj.Link, o1 int32, v int32, r int, rt int) uint32 {
- if (v & 0xFFF000) != 0 {
- if v&0xFFF != 0 {
- ctxt.Diag("%v misuses oaddi", ctxt.Curp)
- }
- v >>= 12
- o1 |= 1 << 22
- }
-
- o1 |= ((v & 0xFFF) << 10) | (int32(r&31) << 5) | int32(rt&31)
- return uint32(o1)
-}
-
-/*
- * load a a literal value into dr
- */
-func omovlit(ctxt *obj.Link, as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
- var o1 int32
- if p.Pcond == nil { /* not in literal pool */
- aclass(ctxt, a)
- ctxt.Logf("omovlit add %d (%#x)\n", ctxt.Instoffset, uint64(ctxt.Instoffset))
-
- /* TODO: could be clever, and use general constant builder */
- o1 = int32(opirr(ctxt, AADD))
-
- v := int32(ctxt.Instoffset)
- if v != 0 && (v&0xFFF) == 0 {
- v >>= 12
- o1 |= 1 << 22 /* shift, by 12 */
- }
-
- o1 |= ((v & 0xFFF) << 10) | (REGZERO & 31 << 5) | int32(dr&31)
- } else {
- fp := 0
- w := 0 /* default: 32 bit, unsigned */
- switch as {
- case AFMOVS:
- fp = 1
-
- case AFMOVD:
- fp = 1
- w = 1 /* 64 bit simd&fp */
-
- case AMOVD:
- if p.Pcond.As == ADWORD {
- w = 1 /* 64 bit */
- } else if p.Pcond.To.Offset < 0 {
- w = 2 /* sign extend */
- }
-
- case AMOVB, AMOVH, AMOVW:
- w = 2 /* 32 bit, sign-extended to 64 */
- break
- }
-
- v := int32(brdist(ctxt, p, 0, 19, 2))
- o1 = (int32(w) << 30) | (int32(fp) << 26) | (3 << 27)
- o1 |= (v & 0x7FFFF) << 5
- o1 |= int32(dr & 31)
- }
-
- return uint32(o1)
-}
-
-// load a constant (MOVCON or BITCON) in a into rt
-func omovconst(ctxt *obj.Link, as obj.As, p *obj.Prog, a *obj.Addr, rt int) (o1 uint32) {
- if c := oclass(a); c == C_BITCON || c == C_ABCON || c == C_ABCON0 {
- // or $bitcon, REGZERO, rt
- mode := 64
- var as1 obj.As
- switch as {
- case AMOVW:
- as1 = AORRW
- mode = 32
- case AMOVD:
- as1 = AORR
- }
- o1 = opirr(ctxt, as1)
- o1 |= bitconEncode(uint64(a.Offset), mode) | uint32(REGZERO&31)<<5 | uint32(rt&31)
- return o1
- }
-
- r := 32
- if as == AMOVD {
- r = 64
- }
- d := a.Offset
- s := movcon(d)
- if s < 0 || s >= r {
- d = ^d
- s = movcon(d)
- if s < 0 || s >= r {
- ctxt.Diag("impossible move wide: %#x\n%v", uint64(a.Offset), p)
- }
- if as == AMOVD {
- o1 = opirr(ctxt, AMOVN)
- } else {
- o1 = opirr(ctxt, AMOVNW)
- }
- } else {
- if as == AMOVD {
- o1 = opirr(ctxt, AMOVZ)
- } else {
- o1 = opirr(ctxt, AMOVZW)
- }
- }
- o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
- return o1
-}
-
-func opbfm(ctxt *obj.Link, a obj.As, r int, s int, rf int, rt int) uint32 {
- var c uint32
- o := opirr(ctxt, a)
- if (o & (1 << 31)) == 0 {
- c = 32
- } else {
- c = 64
- }
- if r < 0 || uint32(r) >= c {
- ctxt.Diag("illegal bit number\n%v", ctxt.Curp)
- }
- o |= (uint32(r) & 0x3F) << 16
- if s < 0 || uint32(s) >= c {
- ctxt.Diag("illegal bit number\n%v", ctxt.Curp)
- }
- o |= (uint32(s) & 0x3F) << 10
- o |= (uint32(rf&31) << 5) | uint32(rt&31)
- return o
-}
-
-func opextr(ctxt *obj.Link, a obj.As, v int32, rn int, rm int, rt int) uint32 {
- var c uint32
- o := opirr(ctxt, a)
- if (o & (1 << 31)) != 0 {
- c = 63
- } else {
- c = 31
- }
- if v < 0 || uint32(v) > c {
- ctxt.Diag("illegal bit number\n%v", ctxt.Curp)
- }
- o |= uint32(v) << 10
- o |= uint32(rn&31) << 5
- o |= uint32(rm&31) << 16
- o |= uint32(rt & 31)
- return o
-}
-
-/*
- * size in log2(bytes)
- */
-func movesize(a obj.As) int {
- switch a {
- case AMOVD:
- return 3
-
- case AMOVW, AMOVWU:
- return 2
-
- case AMOVH, AMOVHU:
- return 1
-
- case AMOVB, AMOVBU:
- return 0
-
- case AFMOVS:
- return 2
-
- case AFMOVD:
- return 3
-
- default:
- return -1
- }
-}
diff --git a/vendor/github.com/google/gops/internal/obj/arm64/list7.go b/vendor/github.com/google/gops/internal/obj/arm64/list7.go
deleted file mode 100644
index 01971b85..00000000
--- a/vendor/github.com/google/gops/internal/obj/arm64/list7.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// cmd/7l/list.c and cmd/7l/sub.c from Vita Nuova.
-// https://code.google.com/p/ken-cc/source/browse/
-//
-// 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-2007 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-2007 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 arm64
-
-import (
- "fmt"
-
- "github.com/google/gops/internal/obj"
-)
-
-var strcond = [16]string{
- "EQ",
- "NE",
- "HS",
- "LO",
- "MI",
- "PL",
- "VS",
- "VC",
- "HI",
- "LS",
- "GE",
- "LT",
- "GT",
- "LE",
- "AL",
- "NV",
-}
-
-func init() {
- obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, Rconv)
- obj.RegisterOpcode(obj.ABaseARM64, Anames)
-}
-
-func Rconv(r int) string {
- if r == REGG {
- return "g"
- }
- switch {
- case REG_R0 <= r && r <= REG_R30:
- return fmt.Sprintf("R%d", r-REG_R0)
- case r == REG_R31:
- return "ZR"
- case REG_F0 <= r && r <= REG_F31:
- return fmt.Sprintf("F%d", r-REG_F0)
- case REG_V0 <= r && r <= REG_V31:
- return fmt.Sprintf("V%d", r-REG_V0)
- case COND_EQ <= r && r <= COND_NV:
- return strcond[r-COND_EQ]
- case r == REGSP:
- return "RSP"
- case r == REG_DAIF:
- return "DAIF"
- case r == REG_NZCV:
- return "NZCV"
- case r == REG_FPSR:
- return "FPSR"
- case r == REG_FPCR:
- return "FPCR"
- case r == REG_SPSR_EL1:
- return "SPSR_EL1"
- case r == REG_ELR_EL1:
- return "ELR_EL1"
- case r == REG_SPSR_EL2:
- return "SPSR_EL2"
- case r == REG_ELR_EL2:
- return "ELR_EL2"
- case r == REG_CurrentEL:
- return "CurrentEL"
- case r == REG_SP_EL0:
- return "SP_EL0"
- case r == REG_SPSel:
- return "SPSel"
- case r == REG_DAIFSet:
- return "DAIFSet"
- case r == REG_DAIFClr:
- return "DAIFClr"
- }
- return fmt.Sprintf("badreg(%d)", r)
-}
-
-func DRconv(a int) string {
- if a >= C_NONE && a <= C_NCLASS {
- return cnames7[a]
- }
- return "C_??"
-}
diff --git a/vendor/github.com/google/gops/internal/obj/arm64/obj7.go b/vendor/github.com/google/gops/internal/obj/arm64/obj7.go
deleted file mode 100644
index 2d9d1aa7..00000000
--- a/vendor/github.com/google/gops/internal/obj/arm64/obj7.go
+++ /dev/null
@@ -1,1005 +0,0 @@
-// cmd/7l/noop.c, cmd/7l/obj.c, cmd/ld/pass.c from Vita Nuova.
-// https://code.google.com/p/ken-cc/source/browse/
-//
-// 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-2007 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-2007 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 arm64
-
-import (
- "fmt"
- "log"
- "math"
-
- "github.com/google/gops/internal/obj"
- "github.com/google/gops/internal/sys"
-)
-
-var complements = []obj.As{
- AADD: ASUB,
- AADDW: ASUBW,
- ASUB: AADD,
- ASUBW: AADDW,
- ACMP: ACMN,
- ACMPW: ACMNW,
- ACMN: ACMP,
- ACMNW: ACMPW,
-}
-
-func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
- // MOV g_stackguard(g), R1
- 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_R1
-
- q := (*obj.Prog)(nil)
- if framesize <= obj.StackSmall {
- // small stack: SP < stackguard
- // MOV SP, R2
- // CMP stackguard, R2
- p = obj.Appendp(ctxt, p)
-
- p.As = AMOVD
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REGSP
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_R2
-
- p = obj.Appendp(ctxt, p)
- p.As = ACMP
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REG_R1
- p.Reg = REG_R2
- } else if framesize <= obj.StackBig {
- // large stack: SP-framesize < stackguard-StackSmall
- // SUB $framesize, SP, R2
- // CMP stackguard, R2
- p = obj.Appendp(ctxt, p)
-
- p.As = ASUB
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = int64(framesize)
- p.Reg = REGSP
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_R2
-
- p = obj.Appendp(ctxt, p)
- p.As = ACMP
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REG_R1
- p.Reg = REG_R2
- } 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.
- // CMP $StackPreempt, R1
- // BEQ label_of_call_to_morestack
- // ADD $StackGuard, SP, R2
- // SUB R1, R2
- // MOV $(framesize+(StackGuard-StackSmall)), R3
- // CMP R3, R2
- p = obj.Appendp(ctxt, p)
-
- p.As = ACMP
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = obj.StackPreempt
- p.Reg = REG_R1
-
- 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_R2
-
- p = obj.Appendp(ctxt, p)
- p.As = ASUB
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REG_R1
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_R2
-
- 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 = REG_R3
-
- p = obj.Appendp(ctxt, p)
- p.As = ACMP
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REG_R3
- p.Reg = REG_R2
- }
-
- // BLS do-morestack
- bls := obj.Appendp(ctxt, p)
- bls.As = ABLS
- bls.To.Type = obj.TYPE_BRANCH
-
- var last *obj.Prog
- for last = ctxt.Cursym.Text; last.Link != nil; last = last.Link {
- }
-
- // Now we are at the end of the function, but logically
- // we are still in function prologue. We need to fix the
- // SP data and PCDATA.
- spfix := obj.Appendp(ctxt, last)
- spfix.As = obj.ANOP
- spfix.Spadj = -framesize
-
- pcdata := obj.Appendp(ctxt, spfix)
- pcdata.Lineno = ctxt.Cursym.Text.Lineno
- pcdata.Mode = ctxt.Cursym.Text.Mode
- pcdata.As = obj.APCDATA
- pcdata.From.Type = obj.TYPE_CONST
- pcdata.From.Offset = obj.PCDATA_StackMapIndex
- pcdata.To.Type = obj.TYPE_CONST
- pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
-
- // MOV LR, R3
- movlr := obj.Appendp(ctxt, pcdata)
- movlr.As = AMOVD
- movlr.From.Type = obj.TYPE_REG
- movlr.From.Reg = REGLINK
- movlr.To.Type = obj.TYPE_REG
- movlr.To.Reg = REG_R3
- if q != nil {
- q.Pcond = movlr
- }
- bls.Pcond = movlr
-
- debug := movlr
- if false {
- debug = obj.Appendp(ctxt, debug)
- debug.As = AMOVD
- debug.From.Type = obj.TYPE_CONST
- debug.From.Offset = int64(framesize)
- debug.To.Type = obj.TYPE_REG
- debug.To.Reg = REGTMP
- }
-
- // BL runtime.morestack(SB)
- call := obj.Appendp(ctxt, debug)
- call.As = ABL
- call.To.Type = obj.TYPE_BRANCH
- morestack := "runtime.morestack"
- switch {
- case ctxt.Cursym.CFunc():
- morestack = "runtime.morestackc"
- case ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
- morestack = "runtime.morestack_noctxt"
- }
- call.To.Sym = obj.Linklookup(ctxt, morestack, 0)
-
- // B start
- jmp := obj.Appendp(ctxt, call)
- jmp.As = AB
- jmp.To.Type = obj.TYPE_BRANCH
- jmp.Pcond = ctxt.Cursym.Text.Link
- jmp.Spadj = +framesize
-
- // placeholder for bls's jump target
- // p = obj.Appendp(ctxt, p)
- // p.As = obj.ANOP
-
- return bls
-}
-
-func progedit(ctxt *obj.Link, p *obj.Prog) {
- p.From.Class = 0
- p.To.Class = 0
-
- // $0 results in C_ZCON, which matches both C_REG and various
- // C_xCON, however the C_REG cases in asmout don't expect a
- // constant, so they will use the register fields and assemble
- // a R0. To prevent that, rewrite $0 as ZR.
- if p.From.Type == obj.TYPE_CONST && p.From.Offset == 0 {
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REGZERO
- }
- if p.To.Type == obj.TYPE_CONST && p.To.Offset == 0 {
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REGZERO
- }
-
- // Rewrite BR/BL to symbol as TYPE_BRANCH.
- switch p.As {
- case AB,
- ABL,
- obj.ARET,
- obj.ADUFFZERO,
- obj.ADUFFCOPY:
- if p.To.Sym != nil {
- p.To.Type = obj.TYPE_BRANCH
- }
- break
- }
-
- // Rewrite float constants to values stored in memory.
- 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 {
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REGZERO
- 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.Set(obj.AttrLocal, 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 {
- p.From.Type = obj.TYPE_REG
- p.From.Reg = REGZERO
- 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.Set(obj.AttrLocal, true)
- p.From.Name = obj.NAME_EXTERN
- p.From.Offset = 0
- }
-
- break
- }
-
- // Rewrite negative immediates as positive immediates with
- // complementary instruction.
- switch p.As {
- case AADD, ASUB, ACMP, ACMN:
- if p.From.Type == obj.TYPE_CONST && p.From.Offset < 0 && p.From.Offset != -1<<63 {
- p.From.Offset = -p.From.Offset
- p.As = complements[p.As]
- }
- case AADDW, ASUBW, ACMPW, ACMNW:
- if p.From.Type == obj.TYPE_CONST && p.From.Offset < 0 && int32(p.From.Offset) != -1<<31 {
- p.From.Offset = -p.From.Offset
- p.As = complements[p.As]
- }
- }
-
- // For 32-bit logical instruction with constant,
- // rewrite the high 32-bit to be a repetition of
- // the low 32-bit, so that the BITCON test can be
- // shared for both 32-bit and 64-bit. 32-bit ops
- // will zero the high 32-bit of the destination
- // register anyway.
- switch p.As {
- case AANDW, AORRW, AEORW, AANDSW:
- if p.From.Type == obj.TYPE_CONST {
- v := p.From.Offset & 0xffffffff
- p.From.Offset = v | v<<32
- }
- }
-
- 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) {
- if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
- // ADUFFxxx $offset
- // becomes
- // MOVD runtime.duffxxx@GOT, REGTMP
- // ADD $offset, REGTMP
- // CALL REGTMP
- var sym *obj.LSym
- if p.As == obj.ADUFFZERO {
- sym = obj.Linklookup(ctxt, "runtime.duffzero", 0)
- } else {
- sym = obj.Linklookup(ctxt, "runtime.duffcopy", 0)
- }
- offset := p.To.Offset
- p.As = AMOVD
- p.From.Type = obj.TYPE_MEM
- p.From.Name = obj.NAME_GOTREF
- p.From.Sym = sym
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REGTMP
- p.To.Name = obj.NAME_NONE
- p.To.Offset = 0
- p.To.Sym = nil
- p1 := obj.Appendp(ctxt, p)
- p1.As = AADD
- p1.From.Type = obj.TYPE_CONST
- p1.From.Offset = offset
- p1.To.Type = obj.TYPE_REG
- p1.To.Reg = REGTMP
- p2 := obj.Appendp(ctxt, p1)
- p2.As = obj.ACALL
- p2.To.Type = obj.TYPE_REG
- p2.To.Reg = REGTMP
- }
-
- // 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.As != AMOVD {
- ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p)
- }
- if p.To.Type != obj.TYPE_REG {
- ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p)
- }
- p.From.Type = obj.TYPE_MEM
- p.From.Name = obj.NAME_GOTREF
- 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
- // MOVx sym, Ry becomes MOVD sym@GOT, REGTMP; MOVx (REGTMP), Ry
- // MOVx 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 follow(ctxt *obj.Link, s *obj.LSym) {
- ctxt.Cursym = s
-
- 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 ABCS:
- return ABCC
- case ABHS:
- return ABLO
- case ABCC:
- return ABCS
- case ABLO:
- return ABHS
- case ABMI:
- return ABPL
- case ABPL:
- return ABMI
- case ABVS:
- return ABVC
- case ABVC:
- return ABVS
- case ABHI:
- return ABLS
- case ABLS:
- return ABHI
- case ABGE:
- return ABLT
- case ABLT:
- return ABGE
- case ABGT:
- return ABLE
- case ABLE:
- return ABGT
- case ACBZ:
- return ACBNZ
- case ACBNZ:
- return ACBZ
- case ACBZW:
- return ACBNZW
- case ACBNZW:
- return ACBZW
- }
-
- log.Fatalf("unknown relation: %s", Anames[a-obj.ABaseARM64])
- return 0
-}
-
-func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
- var q *obj.Prog
- var r *obj.Prog
- var i int
-
-loop:
- if p == nil {
- return
- }
- a := p.As
- if a == AB {
- q = p.Pcond
- if q != nil {
- p.Mark |= FOLL
- p = q
- if !(p.Mark&FOLL != 0) {
- goto loop
- }
- }
- }
-
- if p.Mark&FOLL != 0 {
- i = 0
- q = p
- for ; i < 4; i, q = i+1, q.Link {
- if q == *last || q == nil {
- break
- }
- a = q.As
- if a == obj.ANOP {
- i--
- continue
- }
-
- if a == AB || a == obj.ARET || a == AERET {
- goto copy
- }
- if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
- continue
- }
- if a != ABEQ && a != ABNE {
- continue
- }
-
- copy:
- for {
- r = ctxt.NewProg()
- *r = *p
- if !(r.Mark&FOLL != 0) {
- fmt.Printf("can't happen 1\n")
- }
- r.Mark |= FOLL
- if p != q {
- p = p.Link
- (*last).Link = r
- *last = r
- continue
- }
-
- (*last).Link = r
- *last = r
- if a == AB || a == obj.ARET || a == AERET {
- return
- }
- if a == ABNE {
- r.As = ABEQ
- } else {
- r.As = ABNE
- }
- 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("can't happen 2\n")
- }
- return
- }
- }
-
- a = AB
- 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
- if a == AB || a == obj.ARET || a == AERET {
- return
- }
- if p.Pcond != nil {
- if a != ABL && p.Link != nil {
- q = obj.Brchain(ctxt, p.Link)
- if a != obj.ATEXT {
- if q != nil && (q.Mark&FOLL != 0) {
- p.As = relinv(a)
- p.Link = p.Pcond
- p.Pcond = q
- }
- }
-
- xfol(ctxt, p.Link, last)
- q = obj.Brchain(ctxt, p.Pcond)
- if q == nil {
- q = p.Pcond
- }
- if q.Mark&FOLL != 0 {
- p.Pcond = q
- return
- }
-
- p = q
- goto loop
- }
- }
-
- p = p.Link
- goto loop
-}
-
-func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
- ctxt.Cursym = cursym
-
- if cursym.Text == nil || cursym.Text.Link == nil {
- return
- }
-
- p := cursym.Text
- textstksiz := p.To.Offset
- aoffset := int32(textstksiz)
-
- cursym.Args = p.To.Val.(int32)
- cursym.Locals = int32(textstksiz)
-
- /*
- * find leaf subroutines
- * strip NOPs
- * expand RET
- */
- q := (*obj.Prog)(nil)
- var q1 *obj.Prog
- for p := cursym.Text; p != nil; p = p.Link {
- switch p.As {
- case obj.ATEXT:
- p.Mark |= LEAF
-
- case obj.ARET:
- break
-
- case obj.ANOP:
- q1 = p.Link
- q.Link = q1 /* q is non-nop */
- q1.Mark |= p.Mark
- continue
-
- case ABL,
- obj.ADUFFZERO,
- obj.ADUFFCOPY:
- cursym.Text.Mark &^= LEAF
- fallthrough
-
- case ACBNZ,
- ACBZ,
- ACBNZW,
- ACBZW,
- ATBZ,
- ATBNZ,
- AB,
- ABEQ,
- ABNE,
- ABCS,
- ABHS,
- ABCC,
- ABLO,
- ABMI,
- ABPL,
- ABVS,
- ABVC,
- ABHI,
- ABLS,
- ABGE,
- ABLT,
- ABGT,
- ABLE,
- AADR, /* strange */
- AADRP:
- q1 = p.Pcond
-
- if q1 != nil {
- for q1.As == obj.ANOP {
- q1 = q1.Link
- p.Pcond = q1
- }
- }
-
- break
- }
-
- q = p
- }
-
- var q2 *obj.Prog
- var retjmp *obj.LSym
- for p := cursym.Text; p != nil; p = p.Link {
- o := p.As
- switch o {
- case obj.ATEXT:
- cursym.Text = p
- if textstksiz < 0 {
- ctxt.Autosize = 0
- } else {
- ctxt.Autosize = int32(textstksiz + 8)
- }
- if (cursym.Text.Mark&LEAF != 0) && ctxt.Autosize <= 8 {
- ctxt.Autosize = 0
- } else if ctxt.Autosize&(16-1) != 0 {
- // The frame includes an LR.
- // If the frame size is 8, it's only an LR,
- // so there's no potential for breaking references to
- // local variables by growing the frame size,
- // because there are no local variables.
- // But otherwise, if there is a non-empty locals section,
- // the author of the code is responsible for making sure
- // that the frame size is 8 mod 16.
- if ctxt.Autosize == 8 {
- ctxt.Autosize += 8
- cursym.Locals += 8
- } else {
- ctxt.Diag("%v: unaligned frame size %d - must be 8 mod 16 (or 0)", p, ctxt.Autosize-8)
- }
- }
- p.To.Offset = int64(ctxt.Autosize) - 8
- if ctxt.Autosize == 0 && !(cursym.Text.Mark&LEAF != 0) {
- if ctxt.Debugvlog != 0 {
- ctxt.Logf("save suppressed in: %s\n", cursym.Text.From.Sym.Name)
- }
- cursym.Text.Mark |= LEAF
- }
-
- if !(p.From3.Offset&obj.NOSPLIT != 0) {
- p = stacksplit(ctxt, p, ctxt.Autosize) // emit split check
- }
-
- aoffset = ctxt.Autosize
- if aoffset > 0xF0 {
- aoffset = 0xF0
- }
- if cursym.Text.Mark&LEAF != 0 {
- cursym.Set(obj.AttrLeaf, true)
- if ctxt.Autosize == 0 {
- break
- }
- }
-
- // Frame is non-empty. Make sure to save link register, even if
- // it is a leaf function, so that traceback works.
- q = p
- if ctxt.Autosize > aoffset {
- // Frame size is too large for a MOVD.W instruction.
- // Store link register before decrementing SP, so if a signal comes
- // during the execution of the function prologue, the traceback
- // code will not see a half-updated stack frame.
- q = obj.Appendp(ctxt, q)
- q.Lineno = p.Lineno
- q.As = ASUB
- q.From.Type = obj.TYPE_CONST
- q.From.Offset = int64(ctxt.Autosize)
- q.Reg = REGSP
- q.To.Type = obj.TYPE_REG
- q.To.Reg = REGTMP
-
- q = obj.Appendp(ctxt, q)
- q.Lineno = p.Lineno
- q.As = AMOVD
- q.From.Type = obj.TYPE_REG
- q.From.Reg = REGLINK
- q.To.Type = obj.TYPE_MEM
- q.To.Reg = REGTMP
-
- q1 = obj.Appendp(ctxt, q)
- q1.Lineno = p.Lineno
- q1.As = AMOVD
- q1.From.Type = obj.TYPE_REG
- q1.From.Reg = REGTMP
- q1.To.Type = obj.TYPE_REG
- q1.To.Reg = REGSP
- q1.Spadj = ctxt.Autosize
- } else {
- // small frame, update SP and save LR in a single MOVD.W instruction
- q1 = obj.Appendp(ctxt, q)
- q1.As = AMOVD
- q1.Lineno = p.Lineno
- q1.From.Type = obj.TYPE_REG
- q1.From.Reg = REGLINK
- q1.To.Type = obj.TYPE_MEM
- q1.Scond = C_XPRE
- q1.To.Offset = int64(-aoffset)
- q1.To.Reg = REGSP
- q1.Spadj = aoffset
- }
-
- if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
- // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
- //
- // MOV g_panic(g), R1
- // CMP ZR, R1
- // BEQ end
- // MOV panic_argp(R1), R2
- // ADD $(autosize+8), RSP, R3
- // CMP R2, R3
- // BNE end
- // ADD $8, RSP, R4
- // MOVD R4, panic_argp(R1)
- // end:
- // NOP
- //
- // The NOP is needed to give the jumps somewhere to land.
- // It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes.
- q = q1
-
- 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_R1
-
- q = obj.Appendp(ctxt, q)
- q.As = ACMP
- q.From.Type = obj.TYPE_REG
- q.From.Reg = REGZERO
- q.Reg = REG_R1
-
- q = obj.Appendp(ctxt, q)
- q.As = ABEQ
- q.To.Type = obj.TYPE_BRANCH
- q1 = q
-
- q = obj.Appendp(ctxt, q)
- q.As = AMOVD
- q.From.Type = obj.TYPE_MEM
- q.From.Reg = REG_R1
- q.From.Offset = 0 // Panic.argp
- q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R2
-
- q = obj.Appendp(ctxt, q)
- q.As = AADD
- q.From.Type = obj.TYPE_CONST
- q.From.Offset = int64(ctxt.Autosize) + 8
- q.Reg = REGSP
- 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_R2
- q.Reg = REG_R3
-
- q = obj.Appendp(ctxt, q)
- q.As = ABNE
- q.To.Type = obj.TYPE_BRANCH
- q2 = q
-
- q = obj.Appendp(ctxt, q)
- q.As = AADD
- q.From.Type = obj.TYPE_CONST
- q.From.Offset = 8
- q.Reg = REGSP
- q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R4
-
- q = obj.Appendp(ctxt, q)
- q.As = AMOVD
- q.From.Type = obj.TYPE_REG
- q.From.Reg = REG_R4
- q.To.Type = obj.TYPE_MEM
- q.To.Reg = REG_R1
- q.To.Offset = 0 // Panic.argp
-
- q = obj.Appendp(ctxt, q)
-
- q.As = obj.ANOP
- q1.Pcond = q
- q2.Pcond = q
- }
-
- case obj.ARET:
- nocache(p)
- if p.From.Type == obj.TYPE_CONST {
- ctxt.Diag("using BECOME (%v) is not supported!", p)
- break
- }
-
- retjmp = p.To.Sym
- p.To = obj.Addr{}
- if cursym.Text.Mark&LEAF != 0 {
- if ctxt.Autosize != 0 {
- p.As = AADD
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = int64(ctxt.Autosize)
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REGSP
- p.Spadj = -ctxt.Autosize
- }
- } else {
- /* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
- aoffset = ctxt.Autosize
-
- if aoffset > 0xF0 {
- aoffset = 0xF0
- }
- p.As = AMOVD
- p.From.Type = obj.TYPE_MEM
- p.Scond = C_XPOST
- p.From.Offset = int64(aoffset)
- p.From.Reg = REGSP
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REGLINK
- p.Spadj = -aoffset
- if ctxt.Autosize > aoffset {
- q = ctxt.NewProg()
- q.As = AADD
- q.From.Type = obj.TYPE_CONST
- q.From.Offset = int64(ctxt.Autosize) - int64(aoffset)
- q.To.Type = obj.TYPE_REG
- q.To.Reg = REGSP
- q.Link = p.Link
- q.Spadj = int32(-q.From.Offset)
- q.Lineno = p.Lineno
- p.Link = q
- p = q
- }
- }
-
- if p.As != obj.ARET {
- q = ctxt.NewProg()
- q.Lineno = p.Lineno
- q.Link = p.Link
- p.Link = q
- p = q
- }
-
- if retjmp != nil { // retjmp
- p.As = AB
- p.To.Type = obj.TYPE_BRANCH
- p.To.Sym = retjmp
- p.Spadj = +ctxt.Autosize
- break
- }
-
- p.As = obj.ARET
- p.To.Type = obj.TYPE_MEM
- p.To.Offset = 0
- p.To.Reg = REGLINK
- p.Spadj = +ctxt.Autosize
-
- case AADD, ASUB:
- if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
- if p.As == AADD {
- p.Spadj = int32(-p.From.Offset)
- } else {
- p.Spadj = int32(+p.From.Offset)
- }
- }
- break
- }
- }
-}
-
-func nocache(p *obj.Prog) {
- p.Optab = 0
- p.From.Class = 0
- p.To.Class = 0
-}
-
-var unaryDst = map[obj.As]bool{
- AWORD: true,
- ADWORD: true,
- ABL: true,
- AB: true,
- ASVC: true,
-}
-
-var Linkarm64 = obj.LinkArch{
- Arch: sys.ArchARM64,
- Preprocess: preprocess,
- Assemble: span7,
- Follow: follow,
- Progedit: progedit,
- UnaryDst: unaryDst,
-}