github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/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 defines architecture-specific information and support functions. 6 package arch 7 8 import ( 9 "github.com/gagliardetto/golang-go/cmd/internal/obj" 10 "github.com/gagliardetto/golang-go/cmd/internal/obj/arm" 11 "github.com/gagliardetto/golang-go/cmd/internal/obj/arm64" 12 "github.com/gagliardetto/golang-go/cmd/internal/obj/mips" 13 "github.com/gagliardetto/golang-go/cmd/internal/obj/ppc64" 14 "github.com/gagliardetto/golang-go/cmd/internal/obj/riscv" 15 "github.com/gagliardetto/golang-go/cmd/internal/obj/s390x" 16 "github.com/gagliardetto/golang-go/cmd/internal/obj/wasm" 17 "github.com/gagliardetto/golang-go/cmd/internal/obj/x86" 18 "fmt" 19 "strings" 20 ) 21 22 // Pseudo-registers whose names are the constant name without the leading R. 23 const ( 24 RFP = -(iota + 1) 25 RSB 26 RSP 27 RPC 28 ) 29 30 // Arch wraps the link architecture object with more architecture-specific information. 31 type Arch struct { 32 *obj.LinkArch 33 // Map of instruction names to enumeration. 34 Instructions map[string]obj.As 35 // Map of register names to enumeration. 36 Register map[string]int16 37 // Table of register prefix names. These are things like R for R(0) and SPR for SPR(268). 38 RegisterPrefix map[string]bool 39 // RegisterNumber converts R(10) into arm.REG_R10. 40 RegisterNumber func(string, int16) (int16, bool) 41 // Instruction is a jump. 42 IsJump func(word string) bool 43 } 44 45 // nilRegisterNumber is the register number function for architectures 46 // that do not accept the R(N) notation. It always returns failure. 47 func nilRegisterNumber(name string, n int16) (int16, bool) { 48 return 0, false 49 } 50 51 // Set configures the architecture specified by GOARCH and returns its representation. 52 // It returns nil if GOARCH is not recognized. 53 func Set(GOARCH string) *Arch { 54 switch GOARCH { 55 case "386": 56 return archX86(&x86.Link386) 57 case "amd64": 58 return archX86(&x86.Linkamd64) 59 case "arm": 60 return archArm() 61 case "arm64": 62 return archArm64() 63 case "mips": 64 return archMips(&mips.Linkmips) 65 case "mipsle": 66 return archMips(&mips.Linkmipsle) 67 case "mips64": 68 return archMips64(&mips.Linkmips64) 69 case "mips64le": 70 return archMips64(&mips.Linkmips64le) 71 case "ppc64": 72 return archPPC64(&ppc64.Linkppc64) 73 case "ppc64le": 74 return archPPC64(&ppc64.Linkppc64le) 75 case "riscv64": 76 return archRISCV64() 77 case "s390x": 78 return archS390x() 79 case "wasm": 80 return archWasm() 81 } 82 return nil 83 } 84 85 func jumpX86(word string) bool { 86 return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN" 87 } 88 89 func jumpRISCV(word string) bool { 90 switch word { 91 case "BEQ", "BNE", "BLT", "BGE", "BLTU", "BGEU", "CALL", "JAL", "JALR", "JMP": 92 return true 93 } 94 return false 95 } 96 97 func jumpWasm(word string) bool { 98 return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf" 99 } 100 101 func archX86(linkArch *obj.LinkArch) *Arch { 102 register := make(map[string]int16) 103 // Create maps for easy lookup of instruction names etc. 104 for i, s := range x86.Register { 105 register[s] = int16(i + x86.REG_AL) 106 } 107 // Pseudo-registers. 108 register["SB"] = RSB 109 register["FP"] = RFP 110 register["PC"] = RPC 111 // Register prefix not used on this architecture. 112 113 instructions := make(map[string]obj.As) 114 for i, s := range obj.Anames { 115 instructions[s] = obj.As(i) 116 } 117 for i, s := range x86.Anames { 118 if obj.As(i) >= obj.A_ARCHSPECIFIC { 119 instructions[s] = obj.As(i) + obj.ABaseAMD64 120 } 121 } 122 // Annoying aliases. 123 instructions["JA"] = x86.AJHI /* alternate */ 124 instructions["JAE"] = x86.AJCC /* alternate */ 125 instructions["JB"] = x86.AJCS /* alternate */ 126 instructions["JBE"] = x86.AJLS /* alternate */ 127 instructions["JC"] = x86.AJCS /* alternate */ 128 instructions["JCC"] = x86.AJCC /* carry clear (CF = 0) */ 129 instructions["JCS"] = x86.AJCS /* carry set (CF = 1) */ 130 instructions["JE"] = x86.AJEQ /* alternate */ 131 instructions["JEQ"] = x86.AJEQ /* equal (ZF = 1) */ 132 instructions["JG"] = x86.AJGT /* alternate */ 133 instructions["JGE"] = x86.AJGE /* greater than or equal (signed) (SF = OF) */ 134 instructions["JGT"] = x86.AJGT /* greater than (signed) (ZF = 0 && SF = OF) */ 135 instructions["JHI"] = x86.AJHI /* higher (unsigned) (CF = 0 && ZF = 0) */ 136 instructions["JHS"] = x86.AJCC /* alternate */ 137 instructions["JL"] = x86.AJLT /* alternate */ 138 instructions["JLE"] = x86.AJLE /* less than or equal (signed) (ZF = 1 || SF != OF) */ 139 instructions["JLO"] = x86.AJCS /* alternate */ 140 instructions["JLS"] = x86.AJLS /* lower or same (unsigned) (CF = 1 || ZF = 1) */ 141 instructions["JLT"] = x86.AJLT /* less than (signed) (SF != OF) */ 142 instructions["JMI"] = x86.AJMI /* negative (minus) (SF = 1) */ 143 instructions["JNA"] = x86.AJLS /* alternate */ 144 instructions["JNAE"] = x86.AJCS /* alternate */ 145 instructions["JNB"] = x86.AJCC /* alternate */ 146 instructions["JNBE"] = x86.AJHI /* alternate */ 147 instructions["JNC"] = x86.AJCC /* alternate */ 148 instructions["JNE"] = x86.AJNE /* not equal (ZF = 0) */ 149 instructions["JNG"] = x86.AJLE /* alternate */ 150 instructions["JNGE"] = x86.AJLT /* alternate */ 151 instructions["JNL"] = x86.AJGE /* alternate */ 152 instructions["JNLE"] = x86.AJGT /* alternate */ 153 instructions["JNO"] = x86.AJOC /* alternate */ 154 instructions["JNP"] = x86.AJPC /* alternate */ 155 instructions["JNS"] = x86.AJPL /* alternate */ 156 instructions["JNZ"] = x86.AJNE /* alternate */ 157 instructions["JO"] = x86.AJOS /* alternate */ 158 instructions["JOC"] = x86.AJOC /* overflow clear (OF = 0) */ 159 instructions["JOS"] = x86.AJOS /* overflow set (OF = 1) */ 160 instructions["JP"] = x86.AJPS /* alternate */ 161 instructions["JPC"] = x86.AJPC /* parity clear (PF = 0) */ 162 instructions["JPE"] = x86.AJPS /* alternate */ 163 instructions["JPL"] = x86.AJPL /* non-negative (plus) (SF = 0) */ 164 instructions["JPO"] = x86.AJPC /* alternate */ 165 instructions["JPS"] = x86.AJPS /* parity set (PF = 1) */ 166 instructions["JS"] = x86.AJMI /* alternate */ 167 instructions["JZ"] = x86.AJEQ /* alternate */ 168 instructions["MASKMOVDQU"] = x86.AMASKMOVOU 169 instructions["MOVD"] = x86.AMOVQ 170 instructions["MOVDQ2Q"] = x86.AMOVQ 171 instructions["MOVNTDQ"] = x86.AMOVNTO 172 instructions["MOVOA"] = x86.AMOVO 173 instructions["PSLLDQ"] = x86.APSLLO 174 instructions["PSRLDQ"] = x86.APSRLO 175 instructions["PADDD"] = x86.APADDL 176 177 return &Arch{ 178 LinkArch: linkArch, 179 Instructions: instructions, 180 Register: register, 181 RegisterPrefix: nil, 182 RegisterNumber: nilRegisterNumber, 183 IsJump: jumpX86, 184 } 185 } 186 187 func archArm() *Arch { 188 register := make(map[string]int16) 189 // Create maps for easy lookup of instruction names etc. 190 // Note that there is no list of names as there is for x86. 191 for i := arm.REG_R0; i < arm.REG_SPSR; i++ { 192 register[obj.Rconv(i)] = int16(i) 193 } 194 // Avoid unintentionally clobbering g using R10. 195 delete(register, "R10") 196 register["g"] = arm.REG_R10 197 for i := 0; i < 16; i++ { 198 register[fmt.Sprintf("C%d", i)] = int16(i) 199 } 200 201 // Pseudo-registers. 202 register["SB"] = RSB 203 register["FP"] = RFP 204 register["PC"] = RPC 205 register["SP"] = RSP 206 registerPrefix := map[string]bool{ 207 "F": true, 208 "R": true, 209 } 210 211 // special operands for DMB/DSB instructions 212 register["MB_SY"] = arm.REG_MB_SY 213 register["MB_ST"] = arm.REG_MB_ST 214 register["MB_ISH"] = arm.REG_MB_ISH 215 register["MB_ISHST"] = arm.REG_MB_ISHST 216 register["MB_NSH"] = arm.REG_MB_NSH 217 register["MB_NSHST"] = arm.REG_MB_NSHST 218 register["MB_OSH"] = arm.REG_MB_OSH 219 register["MB_OSHST"] = arm.REG_MB_OSHST 220 221 instructions := make(map[string]obj.As) 222 for i, s := range obj.Anames { 223 instructions[s] = obj.As(i) 224 } 225 for i, s := range arm.Anames { 226 if obj.As(i) >= obj.A_ARCHSPECIFIC { 227 instructions[s] = obj.As(i) + obj.ABaseARM 228 } 229 } 230 // Annoying aliases. 231 instructions["B"] = obj.AJMP 232 instructions["BL"] = obj.ACALL 233 // MCR differs from MRC by the way fields of the word are encoded. 234 // (Details in arm.go). Here we add the instruction so parse will find 235 // it, but give it an opcode number known only to us. 236 instructions["MCR"] = aMCR 237 238 return &Arch{ 239 LinkArch: &arm.Linkarm, 240 Instructions: instructions, 241 Register: register, 242 RegisterPrefix: registerPrefix, 243 RegisterNumber: armRegisterNumber, 244 IsJump: jumpArm, 245 } 246 } 247 248 func archArm64() *Arch { 249 register := make(map[string]int16) 250 // Create maps for easy lookup of instruction names etc. 251 // Note that there is no list of names as there is for 386 and amd64. 252 register[obj.Rconv(arm64.REGSP)] = int16(arm64.REGSP) 253 for i := arm64.REG_R0; i <= arm64.REG_R31; i++ { 254 register[obj.Rconv(i)] = int16(i) 255 } 256 // Rename R18 to R18_PLATFORM to avoid accidental use. 257 register["R18_PLATFORM"] = register["R18"] 258 delete(register, "R18") 259 for i := arm64.REG_F0; i <= arm64.REG_F31; i++ { 260 register[obj.Rconv(i)] = int16(i) 261 } 262 for i := arm64.REG_V0; i <= arm64.REG_V31; i++ { 263 register[obj.Rconv(i)] = int16(i) 264 } 265 266 // System registers. 267 for i := 0; i < len(arm64.SystemReg); i++ { 268 register[arm64.SystemReg[i].Name] = arm64.SystemReg[i].Reg 269 } 270 271 register["LR"] = arm64.REGLINK 272 register["DAIFSet"] = arm64.REG_DAIFSet 273 register["DAIFClr"] = arm64.REG_DAIFClr 274 register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP 275 register["PLDL1STRM"] = arm64.REG_PLDL1STRM 276 register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP 277 register["PLDL2STRM"] = arm64.REG_PLDL2STRM 278 register["PLDL3KEEP"] = arm64.REG_PLDL3KEEP 279 register["PLDL3STRM"] = arm64.REG_PLDL3STRM 280 register["PLIL1KEEP"] = arm64.REG_PLIL1KEEP 281 register["PLIL1STRM"] = arm64.REG_PLIL1STRM 282 register["PLIL2KEEP"] = arm64.REG_PLIL2KEEP 283 register["PLIL2STRM"] = arm64.REG_PLIL2STRM 284 register["PLIL3KEEP"] = arm64.REG_PLIL3KEEP 285 register["PLIL3STRM"] = arm64.REG_PLIL3STRM 286 register["PSTL1KEEP"] = arm64.REG_PSTL1KEEP 287 register["PSTL1STRM"] = arm64.REG_PSTL1STRM 288 register["PSTL2KEEP"] = arm64.REG_PSTL2KEEP 289 register["PSTL2STRM"] = arm64.REG_PSTL2STRM 290 register["PSTL3KEEP"] = arm64.REG_PSTL3KEEP 291 register["PSTL3STRM"] = arm64.REG_PSTL3STRM 292 293 // Conditional operators, like EQ, NE, etc. 294 register["EQ"] = arm64.COND_EQ 295 register["NE"] = arm64.COND_NE 296 register["HS"] = arm64.COND_HS 297 register["CS"] = arm64.COND_HS 298 register["LO"] = arm64.COND_LO 299 register["CC"] = arm64.COND_LO 300 register["MI"] = arm64.COND_MI 301 register["PL"] = arm64.COND_PL 302 register["VS"] = arm64.COND_VS 303 register["VC"] = arm64.COND_VC 304 register["HI"] = arm64.COND_HI 305 register["LS"] = arm64.COND_LS 306 register["GE"] = arm64.COND_GE 307 register["LT"] = arm64.COND_LT 308 register["GT"] = arm64.COND_GT 309 register["LE"] = arm64.COND_LE 310 register["AL"] = arm64.COND_AL 311 register["NV"] = arm64.COND_NV 312 // Pseudo-registers. 313 register["SB"] = RSB 314 register["FP"] = RFP 315 register["PC"] = RPC 316 register["SP"] = RSP 317 // Avoid unintentionally clobbering g using R28. 318 delete(register, "R28") 319 register["g"] = arm64.REG_R28 320 registerPrefix := map[string]bool{ 321 "F": true, 322 "R": true, 323 "V": true, 324 } 325 326 instructions := make(map[string]obj.As) 327 for i, s := range obj.Anames { 328 instructions[s] = obj.As(i) 329 } 330 for i, s := range arm64.Anames { 331 if obj.As(i) >= obj.A_ARCHSPECIFIC { 332 instructions[s] = obj.As(i) + obj.ABaseARM64 333 } 334 } 335 // Annoying aliases. 336 instructions["B"] = arm64.AB 337 instructions["BL"] = arm64.ABL 338 339 return &Arch{ 340 LinkArch: &arm64.Linkarm64, 341 Instructions: instructions, 342 Register: register, 343 RegisterPrefix: registerPrefix, 344 RegisterNumber: arm64RegisterNumber, 345 IsJump: jumpArm64, 346 } 347 348 } 349 350 func archPPC64(linkArch *obj.LinkArch) *Arch { 351 register := make(map[string]int16) 352 // Create maps for easy lookup of instruction names etc. 353 // Note that there is no list of names as there is for x86. 354 for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ { 355 register[obj.Rconv(i)] = int16(i) 356 } 357 for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ { 358 register[obj.Rconv(i)] = int16(i) 359 } 360 for i := ppc64.REG_V0; i <= ppc64.REG_V31; i++ { 361 register[obj.Rconv(i)] = int16(i) 362 } 363 for i := ppc64.REG_VS0; i <= ppc64.REG_VS63; i++ { 364 register[obj.Rconv(i)] = int16(i) 365 } 366 for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ { 367 register[obj.Rconv(i)] = int16(i) 368 } 369 for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ { 370 register[obj.Rconv(i)] = int16(i) 371 } 372 register["CR"] = ppc64.REG_CR 373 register["XER"] = ppc64.REG_XER 374 register["LR"] = ppc64.REG_LR 375 register["CTR"] = ppc64.REG_CTR 376 register["FPSCR"] = ppc64.REG_FPSCR 377 register["MSR"] = ppc64.REG_MSR 378 // Pseudo-registers. 379 register["SB"] = RSB 380 register["FP"] = RFP 381 register["PC"] = RPC 382 // Avoid unintentionally clobbering g using R30. 383 delete(register, "R30") 384 register["g"] = ppc64.REG_R30 385 registerPrefix := map[string]bool{ 386 "CR": true, 387 "F": true, 388 "R": true, 389 "SPR": true, 390 } 391 392 instructions := make(map[string]obj.As) 393 for i, s := range obj.Anames { 394 instructions[s] = obj.As(i) 395 } 396 for i, s := range ppc64.Anames { 397 if obj.As(i) >= obj.A_ARCHSPECIFIC { 398 instructions[s] = obj.As(i) + obj.ABasePPC64 399 } 400 } 401 // Annoying aliases. 402 instructions["BR"] = ppc64.ABR 403 instructions["BL"] = ppc64.ABL 404 405 return &Arch{ 406 LinkArch: linkArch, 407 Instructions: instructions, 408 Register: register, 409 RegisterPrefix: registerPrefix, 410 RegisterNumber: ppc64RegisterNumber, 411 IsJump: jumpPPC64, 412 } 413 } 414 415 func archMips(linkArch *obj.LinkArch) *Arch { 416 register := make(map[string]int16) 417 // Create maps for easy lookup of instruction names etc. 418 // Note that there is no list of names as there is for x86. 419 for i := mips.REG_R0; i <= mips.REG_R31; i++ { 420 register[obj.Rconv(i)] = int16(i) 421 } 422 423 for i := mips.REG_F0; i <= mips.REG_F31; i++ { 424 register[obj.Rconv(i)] = int16(i) 425 } 426 for i := mips.REG_M0; i <= mips.REG_M31; i++ { 427 register[obj.Rconv(i)] = int16(i) 428 } 429 for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ { 430 register[obj.Rconv(i)] = int16(i) 431 } 432 register["HI"] = mips.REG_HI 433 register["LO"] = mips.REG_LO 434 // Pseudo-registers. 435 register["SB"] = RSB 436 register["FP"] = RFP 437 register["PC"] = RPC 438 // Avoid unintentionally clobbering g using R30. 439 delete(register, "R30") 440 register["g"] = mips.REG_R30 441 442 registerPrefix := map[string]bool{ 443 "F": true, 444 "FCR": true, 445 "M": true, 446 "R": true, 447 } 448 449 instructions := make(map[string]obj.As) 450 for i, s := range obj.Anames { 451 instructions[s] = obj.As(i) 452 } 453 for i, s := range mips.Anames { 454 if obj.As(i) >= obj.A_ARCHSPECIFIC { 455 instructions[s] = obj.As(i) + obj.ABaseMIPS 456 } 457 } 458 // Annoying alias. 459 instructions["JAL"] = mips.AJAL 460 461 return &Arch{ 462 LinkArch: linkArch, 463 Instructions: instructions, 464 Register: register, 465 RegisterPrefix: registerPrefix, 466 RegisterNumber: mipsRegisterNumber, 467 IsJump: jumpMIPS, 468 } 469 } 470 471 func archMips64(linkArch *obj.LinkArch) *Arch { 472 register := make(map[string]int16) 473 // Create maps for easy lookup of instruction names etc. 474 // Note that there is no list of names as there is for x86. 475 for i := mips.REG_R0; i <= mips.REG_R31; i++ { 476 register[obj.Rconv(i)] = int16(i) 477 } 478 for i := mips.REG_F0; i <= mips.REG_F31; i++ { 479 register[obj.Rconv(i)] = int16(i) 480 } 481 for i := mips.REG_M0; i <= mips.REG_M31; i++ { 482 register[obj.Rconv(i)] = int16(i) 483 } 484 for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ { 485 register[obj.Rconv(i)] = int16(i) 486 } 487 register["HI"] = mips.REG_HI 488 register["LO"] = mips.REG_LO 489 // Pseudo-registers. 490 register["SB"] = RSB 491 register["FP"] = RFP 492 register["PC"] = RPC 493 // Avoid unintentionally clobbering g using R30. 494 delete(register, "R30") 495 register["g"] = mips.REG_R30 496 // Avoid unintentionally clobbering RSB using R28. 497 delete(register, "R28") 498 register["RSB"] = mips.REG_R28 499 registerPrefix := map[string]bool{ 500 "F": true, 501 "FCR": true, 502 "M": true, 503 "R": true, 504 } 505 506 instructions := make(map[string]obj.As) 507 for i, s := range obj.Anames { 508 instructions[s] = obj.As(i) 509 } 510 for i, s := range mips.Anames { 511 if obj.As(i) >= obj.A_ARCHSPECIFIC { 512 instructions[s] = obj.As(i) + obj.ABaseMIPS 513 } 514 } 515 // Annoying alias. 516 instructions["JAL"] = mips.AJAL 517 518 return &Arch{ 519 LinkArch: linkArch, 520 Instructions: instructions, 521 Register: register, 522 RegisterPrefix: registerPrefix, 523 RegisterNumber: mipsRegisterNumber, 524 IsJump: jumpMIPS, 525 } 526 } 527 528 func archRISCV64() *Arch { 529 register := make(map[string]int16) 530 531 // Standard register names. 532 for i := riscv.REG_X0; i <= riscv.REG_X31; i++ { 533 name := fmt.Sprintf("X%d", i-riscv.REG_X0) 534 register[name] = int16(i) 535 } 536 for i := riscv.REG_F0; i <= riscv.REG_F31; i++ { 537 name := fmt.Sprintf("F%d", i-riscv.REG_F0) 538 register[name] = int16(i) 539 } 540 541 // General registers with ABI names. 542 register["ZERO"] = riscv.REG_ZERO 543 register["RA"] = riscv.REG_RA 544 register["SP"] = riscv.REG_SP 545 register["GP"] = riscv.REG_GP 546 register["TP"] = riscv.REG_TP 547 register["T0"] = riscv.REG_T0 548 register["T1"] = riscv.REG_T1 549 register["T2"] = riscv.REG_T2 550 register["S0"] = riscv.REG_S0 551 register["S1"] = riscv.REG_S1 552 register["A0"] = riscv.REG_A0 553 register["A1"] = riscv.REG_A1 554 register["A2"] = riscv.REG_A2 555 register["A3"] = riscv.REG_A3 556 register["A4"] = riscv.REG_A4 557 register["A5"] = riscv.REG_A5 558 register["A6"] = riscv.REG_A6 559 register["A7"] = riscv.REG_A7 560 register["S2"] = riscv.REG_S2 561 register["S3"] = riscv.REG_S3 562 register["S4"] = riscv.REG_S4 563 register["S5"] = riscv.REG_S5 564 register["S6"] = riscv.REG_S6 565 register["S7"] = riscv.REG_S7 566 register["S8"] = riscv.REG_S8 567 register["S9"] = riscv.REG_S9 568 register["S10"] = riscv.REG_S10 569 register["S11"] = riscv.REG_S11 570 register["T3"] = riscv.REG_T3 571 register["T4"] = riscv.REG_T4 572 register["T5"] = riscv.REG_T5 573 register["T6"] = riscv.REG_T6 574 575 // Go runtime register names. 576 register["g"] = riscv.REG_G 577 register["CTXT"] = riscv.REG_CTXT 578 register["TMP"] = riscv.REG_TMP 579 580 // ABI names for floating point register. 581 register["FT0"] = riscv.REG_FT0 582 register["FT1"] = riscv.REG_FT1 583 register["FT2"] = riscv.REG_FT2 584 register["FT3"] = riscv.REG_FT3 585 register["FT4"] = riscv.REG_FT4 586 register["FT5"] = riscv.REG_FT5 587 register["FT6"] = riscv.REG_FT6 588 register["FT7"] = riscv.REG_FT7 589 register["FS0"] = riscv.REG_FS0 590 register["FS1"] = riscv.REG_FS1 591 register["FA0"] = riscv.REG_FA0 592 register["FA1"] = riscv.REG_FA1 593 register["FA2"] = riscv.REG_FA2 594 register["FA3"] = riscv.REG_FA3 595 register["FA4"] = riscv.REG_FA4 596 register["FA5"] = riscv.REG_FA5 597 register["FA6"] = riscv.REG_FA6 598 register["FA7"] = riscv.REG_FA7 599 register["FS2"] = riscv.REG_FS2 600 register["FS3"] = riscv.REG_FS3 601 register["FS4"] = riscv.REG_FS4 602 register["FS5"] = riscv.REG_FS5 603 register["FS6"] = riscv.REG_FS6 604 register["FS7"] = riscv.REG_FS7 605 register["FS8"] = riscv.REG_FS8 606 register["FS9"] = riscv.REG_FS9 607 register["FS10"] = riscv.REG_FS10 608 register["FS11"] = riscv.REG_FS11 609 register["FT8"] = riscv.REG_FT8 610 register["FT9"] = riscv.REG_FT9 611 register["FT10"] = riscv.REG_FT10 612 register["FT11"] = riscv.REG_FT11 613 614 // Pseudo-registers. 615 register["SB"] = RSB 616 register["FP"] = RFP 617 register["PC"] = RPC 618 619 instructions := make(map[string]obj.As) 620 for i, s := range obj.Anames { 621 instructions[s] = obj.As(i) 622 } 623 for i, s := range riscv.Anames { 624 if obj.As(i) >= obj.A_ARCHSPECIFIC { 625 instructions[s] = obj.As(i) + obj.ABaseRISCV 626 } 627 } 628 629 return &Arch{ 630 LinkArch: &riscv.LinkRISCV64, 631 Instructions: instructions, 632 Register: register, 633 RegisterPrefix: nil, 634 RegisterNumber: nilRegisterNumber, 635 IsJump: jumpRISCV, 636 } 637 } 638 639 func archS390x() *Arch { 640 register := make(map[string]int16) 641 // Create maps for easy lookup of instruction names etc. 642 // Note that there is no list of names as there is for x86. 643 for i := s390x.REG_R0; i <= s390x.REG_R15; i++ { 644 register[obj.Rconv(i)] = int16(i) 645 } 646 for i := s390x.REG_F0; i <= s390x.REG_F15; i++ { 647 register[obj.Rconv(i)] = int16(i) 648 } 649 for i := s390x.REG_V0; i <= s390x.REG_V31; i++ { 650 register[obj.Rconv(i)] = int16(i) 651 } 652 for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ { 653 register[obj.Rconv(i)] = int16(i) 654 } 655 register["LR"] = s390x.REG_LR 656 // Pseudo-registers. 657 register["SB"] = RSB 658 register["FP"] = RFP 659 register["PC"] = RPC 660 // Avoid unintentionally clobbering g using R13. 661 delete(register, "R13") 662 register["g"] = s390x.REG_R13 663 registerPrefix := map[string]bool{ 664 "AR": true, 665 "F": true, 666 "R": true, 667 } 668 669 instructions := make(map[string]obj.As) 670 for i, s := range obj.Anames { 671 instructions[s] = obj.As(i) 672 } 673 for i, s := range s390x.Anames { 674 if obj.As(i) >= obj.A_ARCHSPECIFIC { 675 instructions[s] = obj.As(i) + obj.ABaseS390X 676 } 677 } 678 // Annoying aliases. 679 instructions["BR"] = s390x.ABR 680 instructions["BL"] = s390x.ABL 681 682 return &Arch{ 683 LinkArch: &s390x.Links390x, 684 Instructions: instructions, 685 Register: register, 686 RegisterPrefix: registerPrefix, 687 RegisterNumber: s390xRegisterNumber, 688 IsJump: jumpS390x, 689 } 690 } 691 692 func archWasm() *Arch { 693 instructions := make(map[string]obj.As) 694 for i, s := range obj.Anames { 695 instructions[s] = obj.As(i) 696 } 697 for i, s := range wasm.Anames { 698 if obj.As(i) >= obj.A_ARCHSPECIFIC { 699 instructions[s] = obj.As(i) + obj.ABaseWasm 700 } 701 } 702 703 return &Arch{ 704 LinkArch: &wasm.Linkwasm, 705 Instructions: instructions, 706 Register: wasm.Register, 707 RegisterPrefix: nil, 708 RegisterNumber: nilRegisterNumber, 709 IsJump: jumpWasm, 710 } 711 }