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