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