...

Source file src/pkg/cmd/internal/obj/arm64/list7.go

     1	// cmd/7l/list.c and cmd/7l/sub.c from Vita Nuova.
     2	// https://code.google.com/p/ken-cc/source/browse/
     3	//
     4	// 	Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
     5	// 	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6	// 	Portions Copyright © 1997-1999 Vita Nuova Limited
     7	// 	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8	// 	Portions Copyright © 2004,2006 Bruce Ellis
     9	// 	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10	// 	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11	// 	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12	//
    13	// Permission is hereby granted, free of charge, to any person obtaining a copy
    14	// of this software and associated documentation files (the "Software"), to deal
    15	// in the Software without restriction, including without limitation the rights
    16	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17	// copies of the Software, and to permit persons to whom the Software is
    18	// furnished to do so, subject to the following conditions:
    19	//
    20	// The above copyright notice and this permission notice shall be included in
    21	// all copies or substantial portions of the Software.
    22	//
    23	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29	// THE SOFTWARE.
    30	
    31	package arm64
    32	
    33	import (
    34		"cmd/internal/obj"
    35		"fmt"
    36	)
    37	
    38	var strcond = [16]string{
    39		"EQ",
    40		"NE",
    41		"HS",
    42		"LO",
    43		"MI",
    44		"PL",
    45		"VS",
    46		"VC",
    47		"HI",
    48		"LS",
    49		"GE",
    50		"LT",
    51		"GT",
    52		"LE",
    53		"AL",
    54		"NV",
    55	}
    56	
    57	func init() {
    58		obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, rconv)
    59		obj.RegisterOpcode(obj.ABaseARM64, Anames)
    60		obj.RegisterRegisterList(obj.RegListARM64Lo, obj.RegListARM64Hi, rlconv)
    61		obj.RegisterOpSuffix("arm64", obj.CConvARM)
    62	}
    63	
    64	func arrange(a int) string {
    65		switch a {
    66		case ARNG_8B:
    67			return "B8"
    68		case ARNG_16B:
    69			return "B16"
    70		case ARNG_4H:
    71			return "H4"
    72		case ARNG_8H:
    73			return "H8"
    74		case ARNG_2S:
    75			return "S2"
    76		case ARNG_4S:
    77			return "S4"
    78		case ARNG_1D:
    79			return "D1"
    80		case ARNG_2D:
    81			return "D2"
    82		case ARNG_B:
    83			return "B"
    84		case ARNG_H:
    85			return "H"
    86		case ARNG_S:
    87			return "S"
    88		case ARNG_D:
    89			return "D"
    90		case ARNG_1Q:
    91			return "Q1"
    92		default:
    93			return ""
    94		}
    95	}
    96	
    97	func rconv(r int) string {
    98		ext := (r >> 5) & 7
    99		if r == REGG {
   100			return "g"
   101		}
   102		switch {
   103		case REG_R0 <= r && r <= REG_R30:
   104			return fmt.Sprintf("R%d", r-REG_R0)
   105		case r == REG_R31:
   106			return "ZR"
   107		case REG_F0 <= r && r <= REG_F31:
   108			return fmt.Sprintf("F%d", r-REG_F0)
   109		case REG_V0 <= r && r <= REG_V31:
   110			return fmt.Sprintf("V%d", r-REG_V0)
   111		case COND_EQ <= r && r <= COND_NV:
   112			return strcond[r-COND_EQ]
   113		case r == REGSP:
   114			return "RSP"
   115		case r == REG_DAIF:
   116			return "DAIF"
   117		case r == REG_NZCV:
   118			return "NZCV"
   119		case r == REG_FPSR:
   120			return "FPSR"
   121		case r == REG_FPCR:
   122			return "FPCR"
   123		case r == REG_SPSR_EL1:
   124			return "SPSR_EL1"
   125		case r == REG_ELR_EL1:
   126			return "ELR_EL1"
   127		case r == REG_SPSR_EL2:
   128			return "SPSR_EL2"
   129		case r == REG_ELR_EL2:
   130			return "ELR_EL2"
   131		case r == REG_CurrentEL:
   132			return "CurrentEL"
   133		case r == REG_SP_EL0:
   134			return "SP_EL0"
   135		case r == REG_SPSel:
   136			return "SPSel"
   137		case r == REG_DAIFSet:
   138			return "DAIFSet"
   139		case r == REG_DAIFClr:
   140			return "DAIFClr"
   141		case r == REG_DCZID_EL0:
   142			return "DCZID_EL0"
   143		case r == REG_PLDL1KEEP:
   144			return "PLDL1KEEP"
   145		case r == REG_PLDL1STRM:
   146			return "PLDL1STRM"
   147		case r == REG_PLDL2KEEP:
   148			return "PLDL2KEEP"
   149		case r == REG_PLDL2STRM:
   150			return "PLDL2STRM"
   151		case r == REG_PLDL3KEEP:
   152			return "PLDL3KEEP"
   153		case r == REG_PLDL3STRM:
   154			return "PLDL3STRM"
   155		case r == REG_PLIL1KEEP:
   156			return "PLIL1KEEP"
   157		case r == REG_PLIL1STRM:
   158			return "PLIL1STRM"
   159		case r == REG_PLIL2KEEP:
   160			return "PLIL2KEEP"
   161		case r == REG_PLIL2STRM:
   162			return "PLIL2STRM"
   163		case r == REG_PLIL3KEEP:
   164			return "PLIL3KEEP"
   165		case r == REG_PLIL3STRM:
   166			return "PLIL3STRM"
   167		case r == REG_PSTL1KEEP:
   168			return "PSTL1KEEP"
   169		case r == REG_PSTL1STRM:
   170			return "PSTL1STRM"
   171		case r == REG_PSTL2KEEP:
   172			return "PSTL2KEEP"
   173		case r == REG_PSTL2STRM:
   174			return "PSTL2STRM"
   175		case r == REG_PSTL3KEEP:
   176			return "PSTL3KEEP"
   177		case r == REG_PSTL3STRM:
   178			return "PSTL3STRM"
   179		case REG_UXTB <= r && r < REG_UXTH:
   180			if ext != 0 {
   181				return fmt.Sprintf("%s.UXTB<<%d", regname(r), ext)
   182			} else {
   183				return fmt.Sprintf("%s.UXTB", regname(r))
   184			}
   185		case REG_UXTH <= r && r < REG_UXTW:
   186			if ext != 0 {
   187				return fmt.Sprintf("%s.UXTH<<%d", regname(r), ext)
   188			} else {
   189				return fmt.Sprintf("%s.UXTH", regname(r))
   190			}
   191		case REG_UXTW <= r && r < REG_UXTX:
   192			if ext != 0 {
   193				return fmt.Sprintf("%s.UXTW<<%d", regname(r), ext)
   194			} else {
   195				return fmt.Sprintf("%s.UXTW", regname(r))
   196			}
   197		case REG_UXTX <= r && r < REG_SXTB:
   198			if ext != 0 {
   199				return fmt.Sprintf("%s.UXTX<<%d", regname(r), ext)
   200			} else {
   201				return fmt.Sprintf("%s.UXTX", regname(r))
   202			}
   203		case REG_SXTB <= r && r < REG_SXTH:
   204			if ext != 0 {
   205				return fmt.Sprintf("%s.SXTB<<%d", regname(r), ext)
   206			} else {
   207				return fmt.Sprintf("%s.SXTB", regname(r))
   208			}
   209		case REG_SXTH <= r && r < REG_SXTW:
   210			if ext != 0 {
   211				return fmt.Sprintf("%s.SXTH<<%d", regname(r), ext)
   212			} else {
   213				return fmt.Sprintf("%s.SXTH", regname(r))
   214			}
   215		case REG_SXTW <= r && r < REG_SXTX:
   216			if ext != 0 {
   217				return fmt.Sprintf("%s.SXTW<<%d", regname(r), ext)
   218			} else {
   219				return fmt.Sprintf("%s.SXTW", regname(r))
   220			}
   221		case REG_SXTX <= r && r < REG_SPECIAL:
   222			if ext != 0 {
   223				return fmt.Sprintf("%s.SXTX<<%d", regname(r), ext)
   224			} else {
   225				return fmt.Sprintf("%s.SXTX", regname(r))
   226			}
   227		// bits 0-4 indicate register, bits 5-7 indicate shift amount, bit 8 equals to 0.
   228		case REG_LSL <= r && r < (REG_LSL+1<<8):
   229			return fmt.Sprintf("R%d<<%d", r&31, (r>>5)&7)
   230		case REG_ARNG <= r && r < REG_ELEM:
   231			return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
   232		case REG_ELEM <= r && r < REG_ELEM_END:
   233			return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
   234		}
   235		return fmt.Sprintf("badreg(%d)", r)
   236	}
   237	
   238	func DRconv(a int) string {
   239		if a >= C_NONE && a <= C_NCLASS {
   240			return cnames7[a]
   241		}
   242		return "C_??"
   243	}
   244	
   245	func rlconv(list int64) string {
   246		str := ""
   247	
   248		// ARM64 register list follows ARM64 instruction decode schema
   249		// | 31 | 30 | ... | 15 - 12 | 11 - 10 | ... |
   250		// +----+----+-----+---------+---------+-----+
   251		// |    | Q  | ... | opcode  |   size  | ... |
   252	
   253		firstReg := int(list & 31)
   254		opcode := (list >> 12) & 15
   255		var regCnt int
   256		var t string
   257		switch opcode {
   258		case 0x7:
   259			regCnt = 1
   260		case 0xa:
   261			regCnt = 2
   262		case 0x6:
   263			regCnt = 3
   264		case 0x2:
   265			regCnt = 4
   266		default:
   267			regCnt = -1
   268		}
   269		// Q:size
   270		arng := ((list>>30)&1)<<2 | (list>>10)&3
   271		switch arng {
   272		case 0:
   273			t = "B8"
   274		case 4:
   275			t = "B16"
   276		case 1:
   277			t = "H4"
   278		case 5:
   279			t = "H8"
   280		case 2:
   281			t = "S2"
   282		case 6:
   283			t = "S4"
   284		case 3:
   285			t = "D1"
   286		case 7:
   287			t = "D2"
   288		}
   289		for i := 0; i < regCnt; i++ {
   290			if str == "" {
   291				str += "["
   292			} else {
   293				str += ","
   294			}
   295			str += fmt.Sprintf("V%d.", (firstReg+i)&31)
   296			str += t
   297		}
   298		str += "]"
   299		return str
   300	}
   301	
   302	func regname(r int) string {
   303		if r&31 == 31 {
   304			return "ZR"
   305		}
   306		return fmt.Sprintf("R%d", r&31)
   307	}
   308	

View as plain text