github.com/zxy12/go_duplicate_1_12@v0.0.0-20200217043740-b1636fc0368b/src/cmd/internal/obj/arm64/list7.go (about) 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 }