diff options
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.go | 288 |
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) +} |