github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/src/cmd/asm/internal/arch/arch.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package arch 6 7 import ( 8 "cmd/internal/obj" 9 "cmd/internal/obj/arm" 10 "cmd/internal/obj/arm64" 11 "cmd/internal/obj/ppc64" 12 "cmd/internal/obj/x86" 13 "fmt" 14 "strings" 15 ) 16 17 // Pseudo-registers whose names are the constant name without the leading R. 18 const ( 19 RFP = -(iota + 1) 20 RSB 21 RSP 22 RPC 23 ) 24 25 // Arch wraps the link architecture object with more architecture-specific information. 26 type Arch struct { 27 *obj.LinkArch 28 // Map of instruction names to enumeration. 29 Instructions map[string]int 30 // Map of register names to enumeration. 31 Register map[string]int16 32 // Table of register prefix names. These are things like R for R(0) and SPR for SPR(268). 33 RegisterPrefix map[string]bool 34 // RegisterNumber converts R(10) into arm.REG_R10. 35 RegisterNumber func(string, int16) (int16, bool) 36 // Instruction is a jump. 37 IsJump func(word string) bool 38 } 39 40 // nilRegisterNumber is the register number function for architectures 41 // that do not accept the R(N) notation. It always returns failure. 42 func nilRegisterNumber(name string, n int16) (int16, bool) { 43 return 0, false 44 } 45 46 var Pseudos = map[string]int{ 47 "DATA": obj.ADATA, 48 "FUNCDATA": obj.AFUNCDATA, 49 "GLOBL": obj.AGLOBL, 50 "PCDATA": obj.APCDATA, 51 "TEXT": obj.ATEXT, 52 } 53 54 // Set configures the architecture specified by GOARCH and returns its representation. 55 // It returns nil if GOARCH is not recognized. 56 func Set(GOARCH string) *Arch { 57 switch GOARCH { 58 case "386": 59 return archX86(&x86.Link386) 60 case "amd64": 61 return archX86(&x86.Linkamd64) 62 case "amd64p32": 63 return archX86(&x86.Linkamd64p32) 64 case "arm": 65 return archArm() 66 case "arm64": 67 return archArm64() 68 case "ppc64": 69 a := archPPC64() 70 a.LinkArch = &ppc64.Linkppc64 71 return a 72 case "ppc64le": 73 a := archPPC64() 74 a.LinkArch = &ppc64.Linkppc64le 75 return a 76 } 77 return nil 78 } 79 80 func jumpX86(word string) bool { 81 return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") 82 } 83 84 func archX86(linkArch *obj.LinkArch) *Arch { 85 register := make(map[string]int16) 86 // Create maps for easy lookup of instruction names etc. 87 for i, s := range x86.Register { 88 register[s] = int16(i + x86.REG_AL) 89 } 90 // Pseudo-registers. 91 register["SB"] = RSB 92 register["FP"] = RFP 93 register["PC"] = RPC 94 // Register prefix not used on this architecture. 95 96 instructions := make(map[string]int) 97 for i, s := range obj.Anames { 98 instructions[s] = i 99 } 100 for i, s := range x86.Anames { 101 if i >= obj.A_ARCHSPECIFIC { 102 instructions[s] = i + obj.ABaseAMD64 103 } 104 } 105 // Annoying aliases. 106 instructions["JA"] = x86.AJHI /* alternate */ 107 instructions["JAE"] = x86.AJCC /* alternate */ 108 instructions["JB"] = x86.AJCS /* alternate */ 109 instructions["JBE"] = x86.AJLS /* alternate */ 110 instructions["JC"] = x86.AJCS /* alternate */ 111 instructions["JCC"] = x86.AJCC /* carry clear (CF = 0) */ 112 instructions["JCS"] = x86.AJCS /* carry set (CF = 1) */ 113 instructions["JE"] = x86.AJEQ /* alternate */ 114 instructions["JEQ"] = x86.AJEQ /* equal (ZF = 1) */ 115 instructions["JG"] = x86.AJGT /* alternate */ 116 instructions["JGE"] = x86.AJGE /* greater than or equal (signed) (SF = OF) */ 117 instructions["JGT"] = x86.AJGT /* greater than (signed) (ZF = 0 && SF = OF) */ 118 instructions["JHI"] = x86.AJHI /* higher (unsigned) (CF = 0 && ZF = 0) */ 119 instructions["JHS"] = x86.AJCC /* alternate */ 120 instructions["JL"] = x86.AJLT /* alternate */ 121 instructions["JLE"] = x86.AJLE /* less than or equal (signed) (ZF = 1 || SF != OF) */ 122 instructions["JLO"] = x86.AJCS /* alternate */ 123 instructions["JLS"] = x86.AJLS /* lower or same (unsigned) (CF = 1 || ZF = 1) */ 124 instructions["JLT"] = x86.AJLT /* less than (signed) (SF != OF) */ 125 instructions["JMI"] = x86.AJMI /* negative (minus) (SF = 1) */ 126 instructions["JNA"] = x86.AJLS /* alternate */ 127 instructions["JNAE"] = x86.AJCS /* alternate */ 128 instructions["JNB"] = x86.AJCC /* alternate */ 129 instructions["JNBE"] = x86.AJHI /* alternate */ 130 instructions["JNC"] = x86.AJCC /* alternate */ 131 instructions["JNE"] = x86.AJNE /* not equal (ZF = 0) */ 132 instructions["JNG"] = x86.AJLE /* alternate */ 133 instructions["JNGE"] = x86.AJLT /* alternate */ 134 instructions["JNL"] = x86.AJGE /* alternate */ 135 instructions["JNLE"] = x86.AJGT /* alternate */ 136 instructions["JNO"] = x86.AJOC /* alternate */ 137 instructions["JNP"] = x86.AJPC /* alternate */ 138 instructions["JNS"] = x86.AJPL /* alternate */ 139 instructions["JNZ"] = x86.AJNE /* alternate */ 140 instructions["JO"] = x86.AJOS /* alternate */ 141 instructions["JOC"] = x86.AJOC /* overflow clear (OF = 0) */ 142 instructions["JOS"] = x86.AJOS /* overflow set (OF = 1) */ 143 instructions["JP"] = x86.AJPS /* alternate */ 144 instructions["JPC"] = x86.AJPC /* parity clear (PF = 0) */ 145 instructions["JPE"] = x86.AJPS /* alternate */ 146 instructions["JPL"] = x86.AJPL /* non-negative (plus) (SF = 0) */ 147 instructions["JPO"] = x86.AJPC /* alternate */ 148 instructions["JPS"] = x86.AJPS /* parity set (PF = 1) */ 149 instructions["JS"] = x86.AJMI /* alternate */ 150 instructions["JZ"] = x86.AJEQ /* alternate */ 151 instructions["MASKMOVDQU"] = x86.AMASKMOVOU 152 instructions["MOVD"] = x86.AMOVQ 153 instructions["MOVDQ2Q"] = x86.AMOVQ 154 instructions["MOVNTDQ"] = x86.AMOVNTO 155 instructions["MOVOA"] = x86.AMOVO 156 instructions["MOVOA"] = x86.AMOVO 157 instructions["PF2ID"] = x86.APF2IL 158 instructions["PI2FD"] = x86.API2FL 159 instructions["PSLLDQ"] = x86.APSLLO 160 instructions["PSRLDQ"] = x86.APSRLO 161 162 return &Arch{ 163 LinkArch: linkArch, 164 Instructions: instructions, 165 Register: register, 166 RegisterPrefix: nil, 167 RegisterNumber: nilRegisterNumber, 168 IsJump: jumpX86, 169 } 170 } 171 172 func archArm() *Arch { 173 register := make(map[string]int16) 174 // Create maps for easy lookup of instruction names etc. 175 // Note that there is no list of names as there is for x86. 176 for i := arm.REG_R0; i < arm.REG_SPSR; i++ { 177 register[obj.Rconv(i)] = int16(i) 178 } 179 // Avoid unintentionally clobbering g using R10. 180 delete(register, "R10") 181 register["g"] = arm.REG_R10 182 for i := 0; i < 16; i++ { 183 register[fmt.Sprintf("C%d", i)] = int16(i) 184 } 185 186 // Pseudo-registers. 187 register["SB"] = RSB 188 register["FP"] = RFP 189 register["PC"] = RPC 190 register["SP"] = RSP 191 registerPrefix := map[string]bool{ 192 "F": true, 193 "R": true, 194 } 195 196 instructions := make(map[string]int) 197 for i, s := range obj.Anames { 198 instructions[s] = i 199 } 200 for i, s := range arm.Anames { 201 if i >= obj.A_ARCHSPECIFIC { 202 instructions[s] = i + obj.ABaseARM 203 } 204 } 205 // Annoying aliases. 206 instructions["B"] = obj.AJMP 207 instructions["BL"] = obj.ACALL 208 // MCR differs from MRC by the way fields of the word are encoded. 209 // (Details in arm.go). Here we add the instruction so parse will find 210 // it, but give it an opcode number known only to us. 211 instructions["MCR"] = aMCR 212 213 return &Arch{ 214 LinkArch: &arm.Linkarm, 215 Instructions: instructions, 216 Register: register, 217 RegisterPrefix: registerPrefix, 218 RegisterNumber: armRegisterNumber, 219 IsJump: jumpArm, 220 } 221 } 222 223 func archArm64() *Arch { 224 register := make(map[string]int16) 225 // Create maps for easy lookup of instruction names etc. 226 // Note that there is no list of names as there is for 386 and amd64. 227 register[arm64.Rconv(arm64.REGSP)] = int16(arm64.REGSP) 228 for i := arm64.REG_R0; i <= arm64.REG_R31; i++ { 229 register[arm64.Rconv(i)] = int16(i) 230 } 231 for i := arm64.REG_F0; i <= arm64.REG_F31; i++ { 232 register[arm64.Rconv(i)] = int16(i) 233 } 234 for i := arm64.REG_V0; i <= arm64.REG_V31; i++ { 235 register[arm64.Rconv(i)] = int16(i) 236 } 237 register["LR"] = arm64.REGLINK 238 register["DAIF"] = arm64.REG_DAIF 239 register["NZCV"] = arm64.REG_NZCV 240 register["FPSR"] = arm64.REG_FPSR 241 register["FPCR"] = arm64.REG_FPCR 242 register["SPSR_EL1"] = arm64.REG_SPSR_EL1 243 register["ELR_EL1"] = arm64.REG_ELR_EL1 244 register["SPSR_EL2"] = arm64.REG_SPSR_EL2 245 register["ELR_EL2"] = arm64.REG_ELR_EL2 246 register["CurrentEL"] = arm64.REG_CurrentEL 247 register["SP_EL0"] = arm64.REG_SP_EL0 248 register["SPSel"] = arm64.REG_SPSel 249 register["DAIFSet"] = arm64.REG_DAIFSet 250 register["DAIFClr"] = arm64.REG_DAIFClr 251 // Conditional operators, like EQ, NE, etc. 252 register["EQ"] = arm64.COND_EQ 253 register["NE"] = arm64.COND_NE 254 register["HS"] = arm64.COND_HS 255 register["CS"] = arm64.COND_HS 256 register["LO"] = arm64.COND_LO 257 register["CC"] = arm64.COND_LO 258 register["MI"] = arm64.COND_MI 259 register["PL"] = arm64.COND_PL 260 register["VS"] = arm64.COND_VS 261 register["VC"] = arm64.COND_VC 262 register["HI"] = arm64.COND_HI 263 register["LS"] = arm64.COND_LS 264 register["GE"] = arm64.COND_GE 265 register["LT"] = arm64.COND_LT 266 register["GT"] = arm64.COND_GT 267 register["LE"] = arm64.COND_LE 268 register["AL"] = arm64.COND_AL 269 register["NV"] = arm64.COND_NV 270 // Pseudo-registers. 271 register["SB"] = RSB 272 register["FP"] = RFP 273 register["PC"] = RPC 274 register["SP"] = RSP 275 // Avoid unintentionally clobbering g using R28. 276 delete(register, "R28") 277 register["g"] = arm64.REG_R28 278 registerPrefix := map[string]bool{ 279 "F": true, 280 "R": true, 281 "V": true, 282 } 283 284 instructions := make(map[string]int) 285 for i, s := range obj.Anames { 286 instructions[s] = i 287 } 288 for i, s := range arm64.Anames { 289 if i >= obj.A_ARCHSPECIFIC { 290 instructions[s] = i + obj.ABaseARM64 291 } 292 } 293 // Annoying aliases. 294 instructions["B"] = arm64.AB 295 instructions["BL"] = arm64.ABL 296 297 return &Arch{ 298 LinkArch: &arm64.Linkarm64, 299 Instructions: instructions, 300 Register: register, 301 RegisterPrefix: registerPrefix, 302 RegisterNumber: arm64RegisterNumber, 303 IsJump: jumpArm64, 304 } 305 306 } 307 308 func archPPC64() *Arch { 309 register := make(map[string]int16) 310 // Create maps for easy lookup of instruction names etc. 311 // Note that there is no list of names as there is for x86. 312 for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ { 313 register[obj.Rconv(i)] = int16(i) 314 } 315 for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ { 316 register[obj.Rconv(i)] = int16(i) 317 } 318 for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ { 319 register[obj.Rconv(i)] = int16(i) 320 } 321 for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ { 322 register[obj.Rconv(i)] = int16(i) 323 } 324 register["CR"] = ppc64.REG_CR 325 register["XER"] = ppc64.REG_XER 326 register["LR"] = ppc64.REG_LR 327 register["CTR"] = ppc64.REG_CTR 328 register["FPSCR"] = ppc64.REG_FPSCR 329 register["MSR"] = ppc64.REG_MSR 330 // Pseudo-registers. 331 register["SB"] = RSB 332 register["FP"] = RFP 333 register["PC"] = RPC 334 // Avoid unintentionally clobbering g using R30. 335 delete(register, "R30") 336 register["g"] = ppc64.REG_R30 337 registerPrefix := map[string]bool{ 338 "CR": true, 339 "F": true, 340 "R": true, 341 "SPR": true, 342 } 343 344 instructions := make(map[string]int) 345 for i, s := range obj.Anames { 346 instructions[s] = i 347 } 348 for i, s := range ppc64.Anames { 349 if i >= obj.A_ARCHSPECIFIC { 350 instructions[s] = i + obj.ABasePPC64 351 } 352 } 353 // Annoying aliases. 354 instructions["BR"] = ppc64.ABR 355 instructions["BL"] = ppc64.ABL 356 357 return &Arch{ 358 LinkArch: &ppc64.Linkppc64, 359 Instructions: instructions, 360 Register: register, 361 RegisterPrefix: registerPrefix, 362 RegisterNumber: ppc64RegisterNumber, 363 IsJump: jumpPPC64, 364 } 365 }