summaryrefslogtreecommitdiff
path: root/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go')
-rw-r--r--vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go288
1 files changed, 288 insertions, 0 deletions
diff --git a/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go b/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go
new file mode 100644
index 000000000..1906c5fb9
--- /dev/null
+++ b/vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go
@@ -0,0 +1,288 @@
+// 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 (
+ "github.com/twitchyliquid64/golang-asm/obj"
+ "fmt"
+)
+
+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)
+ obj.RegisterRegisterList(obj.RegListARM64Lo, obj.RegListARM64Hi, rlconv)
+ obj.RegisterOpSuffix("arm64", obj.CConvARM)
+}
+
+func arrange(a int) string {
+ switch a {
+ case ARNG_8B:
+ return "B8"
+ case ARNG_16B:
+ return "B16"
+ case ARNG_4H:
+ return "H4"
+ case ARNG_8H:
+ return "H8"
+ case ARNG_2S:
+ return "S2"
+ case ARNG_4S:
+ return "S4"
+ case ARNG_1D:
+ return "D1"
+ case ARNG_2D:
+ return "D2"
+ case ARNG_B:
+ return "B"
+ case ARNG_H:
+ return "H"
+ case ARNG_S:
+ return "S"
+ case ARNG_D:
+ return "D"
+ case ARNG_1Q:
+ return "Q1"
+ default:
+ return ""
+ }
+}
+
+func rconv(r int) string {
+ ext := (r >> 5) & 7
+ 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_DAIFSet:
+ return "DAIFSet"
+ case r == REG_DAIFClr:
+ return "DAIFClr"
+ case r == REG_PLDL1KEEP:
+ return "PLDL1KEEP"
+ case r == REG_PLDL1STRM:
+ return "PLDL1STRM"
+ case r == REG_PLDL2KEEP:
+ return "PLDL2KEEP"
+ case r == REG_PLDL2STRM:
+ return "PLDL2STRM"
+ case r == REG_PLDL3KEEP:
+ return "PLDL3KEEP"
+ case r == REG_PLDL3STRM:
+ return "PLDL3STRM"
+ case r == REG_PLIL1KEEP:
+ return "PLIL1KEEP"
+ case r == REG_PLIL1STRM:
+ return "PLIL1STRM"
+ case r == REG_PLIL2KEEP:
+ return "PLIL2KEEP"
+ case r == REG_PLIL2STRM:
+ return "PLIL2STRM"
+ case r == REG_PLIL3KEEP:
+ return "PLIL3KEEP"
+ case r == REG_PLIL3STRM:
+ return "PLIL3STRM"
+ case r == REG_PSTL1KEEP:
+ return "PSTL1KEEP"
+ case r == REG_PSTL1STRM:
+ return "PSTL1STRM"
+ case r == REG_PSTL2KEEP:
+ return "PSTL2KEEP"
+ case r == REG_PSTL2STRM:
+ return "PSTL2STRM"
+ case r == REG_PSTL3KEEP:
+ return "PSTL3KEEP"
+ case r == REG_PSTL3STRM:
+ return "PSTL3STRM"
+ case REG_UXTB <= r && r < REG_UXTH:
+ if ext != 0 {
+ return fmt.Sprintf("%s.UXTB<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.UXTB", regname(r))
+ }
+ case REG_UXTH <= r && r < REG_UXTW:
+ if ext != 0 {
+ return fmt.Sprintf("%s.UXTH<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.UXTH", regname(r))
+ }
+ case REG_UXTW <= r && r < REG_UXTX:
+ if ext != 0 {
+ return fmt.Sprintf("%s.UXTW<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.UXTW", regname(r))
+ }
+ case REG_UXTX <= r && r < REG_SXTB:
+ if ext != 0 {
+ return fmt.Sprintf("%s.UXTX<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.UXTX", regname(r))
+ }
+ case REG_SXTB <= r && r < REG_SXTH:
+ if ext != 0 {
+ return fmt.Sprintf("%s.SXTB<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.SXTB", regname(r))
+ }
+ case REG_SXTH <= r && r < REG_SXTW:
+ if ext != 0 {
+ return fmt.Sprintf("%s.SXTH<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.SXTH", regname(r))
+ }
+ case REG_SXTW <= r && r < REG_SXTX:
+ if ext != 0 {
+ return fmt.Sprintf("%s.SXTW<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.SXTW", regname(r))
+ }
+ case REG_SXTX <= r && r < REG_SPECIAL:
+ if ext != 0 {
+ return fmt.Sprintf("%s.SXTX<<%d", regname(r), ext)
+ } else {
+ return fmt.Sprintf("%s.SXTX", regname(r))
+ }
+ // bits 0-4 indicate register, bits 5-7 indicate shift amount, bit 8 equals to 0.
+ case REG_LSL <= r && r < (REG_LSL+1<<8):
+ return fmt.Sprintf("R%d<<%d", r&31, (r>>5)&7)
+ case REG_ARNG <= r && r < REG_ELEM:
+ return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
+ case REG_ELEM <= r && r < REG_ELEM_END:
+ return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
+ }
+ // Return system register name.
+ name, _, _ := SysRegEnc(int16(r))
+ if name != "" {
+ return name
+ }
+ return fmt.Sprintf("badreg(%d)", r)
+}
+
+func DRconv(a int) string {
+ if a >= C_NONE && a <= C_NCLASS {
+ return cnames7[a]
+ }
+ return "C_??"
+}
+
+func rlconv(list int64) string {
+ str := ""
+
+ // ARM64 register list follows ARM64 instruction decode schema
+ // | 31 | 30 | ... | 15 - 12 | 11 - 10 | ... |
+ // +----+----+-----+---------+---------+-----+
+ // | | Q | ... | opcode | size | ... |
+
+ firstReg := int(list & 31)
+ opcode := (list >> 12) & 15
+ var regCnt int
+ var t string
+ switch opcode {
+ case 0x7:
+ regCnt = 1
+ case 0xa:
+ regCnt = 2
+ case 0x6:
+ regCnt = 3
+ case 0x2:
+ regCnt = 4
+ default:
+ regCnt = -1
+ }
+ // Q:size
+ arng := ((list>>30)&1)<<2 | (list>>10)&3
+ switch arng {
+ case 0:
+ t = "B8"
+ case 4:
+ t = "B16"
+ case 1:
+ t = "H4"
+ case 5:
+ t = "H8"
+ case 2:
+ t = "S2"
+ case 6:
+ t = "S4"
+ case 3:
+ t = "D1"
+ case 7:
+ t = "D2"
+ }
+ for i := 0; i < regCnt; i++ {
+ if str == "" {
+ str += "["
+ } else {
+ str += ","
+ }
+ str += fmt.Sprintf("V%d.", (firstReg+i)&31)
+ str += t
+ }
+ str += "]"
+ return str
+}
+
+func regname(r int) string {
+ if r&31 == 31 {
+ return "ZR"
+ }
+ return fmt.Sprintf("R%d", r&31)
+}