github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/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/mips"
    12  	"cmd/internal/obj/ppc64"
    13  	"cmd/internal/obj/riscv"
    14  	"cmd/internal/obj/s390x"
    15  	"cmd/internal/obj/x86"
    16  	"fmt"
    17  	"strings"
    18  )
    19  
    20  // Pseudo-registers whose names are the constant name without the leading R.
    21  const (
    22  	RFP = -(iota + 1)
    23  	RSB
    24  	RSP
    25  	RPC
    26  )
    27  
    28  // Arch wraps the link architecture object with more architecture-specific information.
    29  type Arch struct {
    30  	*obj.LinkArch
    31  	// Map of instruction names to enumeration.
    32  	Instructions map[string]obj.As
    33  	// Map of register names to enumeration.
    34  	Register map[string]int16
    35  	// Table of register prefix names. These are things like R for R(0) and SPR for SPR(268).
    36  	RegisterPrefix map[string]bool
    37  	// RegisterNumber converts R(10) into arm.REG_R10.
    38  	RegisterNumber func(string, int16) (int16, bool)
    39  	// Instruction is a jump.
    40  	IsJump func(word string) bool
    41  }
    42  
    43  // nilRegisterNumber is the register number function for architectures
    44  // that do not accept the R(N) notation. It always returns failure.
    45  func nilRegisterNumber(name string, n int16) (int16, bool) {
    46  	return 0, false
    47  }
    48  
    49  // Set configures the architecture specified by GOARCH and returns its representation.
    50  // It returns nil if GOARCH is not recognized.
    51  func Set(GOARCH string) *Arch {
    52  	switch GOARCH {
    53  	case "386":
    54  		return archX86(&x86.Link386)
    55  	case "amd64":
    56  		return archX86(&x86.Linkamd64)
    57  	case "amd64p32":
    58  		return archX86(&x86.Linkamd64p32)
    59  	case "arm":
    60  		return archArm()
    61  	case "arm64":
    62  		return archArm64()
    63  	case "mips":
    64  		a := archMips()
    65  		a.LinkArch = &mips.Linkmips
    66  		return a
    67  	case "mipsle":
    68  		a := archMips()
    69  		a.LinkArch = &mips.Linkmipsle
    70  		return a
    71  	case "mips64":
    72  		a := archMips64()
    73  		a.LinkArch = &mips.Linkmips64
    74  		return a
    75  	case "mips64le":
    76  		a := archMips64()
    77  		a.LinkArch = &mips.Linkmips64le
    78  		return a
    79  	case "ppc64":
    80  		a := archPPC64()
    81  		a.LinkArch = &ppc64.Linkppc64
    82  		return a
    83  	case "ppc64le":
    84  		a := archPPC64()
    85  		a.LinkArch = &ppc64.Linkppc64le
    86  		return a
    87  	case "riscv":
    88  		return archRiscv()
    89  	case "s390x":
    90  		a := archS390x()
    91  		a.LinkArch = &s390x.Links390x
    92  		return a
    93  	}
    94  	return nil
    95  }
    96  
    97  func jumpX86(word string) bool {
    98  	return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
    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  	instructions := make(map[string]obj.As)
   212  	for i, s := range obj.Anames {
   213  		instructions[s] = obj.As(i)
   214  	}
   215  	for i, s := range arm.Anames {
   216  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   217  			instructions[s] = obj.As(i) + obj.ABaseARM
   218  		}
   219  	}
   220  	// Annoying aliases.
   221  	instructions["B"] = obj.AJMP
   222  	instructions["BL"] = obj.ACALL
   223  	// MCR differs from MRC by the way fields of the word are encoded.
   224  	// (Details in arm.go). Here we add the instruction so parse will find
   225  	// it, but give it an opcode number known only to us.
   226  	instructions["MCR"] = aMCR
   227  
   228  	return &Arch{
   229  		LinkArch:       &arm.Linkarm,
   230  		Instructions:   instructions,
   231  		Register:       register,
   232  		RegisterPrefix: registerPrefix,
   233  		RegisterNumber: armRegisterNumber,
   234  		IsJump:         jumpArm,
   235  	}
   236  }
   237  
   238  func archArm64() *Arch {
   239  	register := make(map[string]int16)
   240  	// Create maps for easy lookup of instruction names etc.
   241  	// Note that there is no list of names as there is for 386 and amd64.
   242  	register[arm64.Rconv(arm64.REGSP)] = int16(arm64.REGSP)
   243  	for i := arm64.REG_R0; i <= arm64.REG_R31; i++ {
   244  		register[arm64.Rconv(i)] = int16(i)
   245  	}
   246  	for i := arm64.REG_F0; i <= arm64.REG_F31; i++ {
   247  		register[arm64.Rconv(i)] = int16(i)
   248  	}
   249  	for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
   250  		register[arm64.Rconv(i)] = int16(i)
   251  	}
   252  	register["LR"] = arm64.REGLINK
   253  	register["DAIF"] = arm64.REG_DAIF
   254  	register["NZCV"] = arm64.REG_NZCV
   255  	register["FPSR"] = arm64.REG_FPSR
   256  	register["FPCR"] = arm64.REG_FPCR
   257  	register["SPSR_EL1"] = arm64.REG_SPSR_EL1
   258  	register["ELR_EL1"] = arm64.REG_ELR_EL1
   259  	register["SPSR_EL2"] = arm64.REG_SPSR_EL2
   260  	register["ELR_EL2"] = arm64.REG_ELR_EL2
   261  	register["CurrentEL"] = arm64.REG_CurrentEL
   262  	register["SP_EL0"] = arm64.REG_SP_EL0
   263  	register["SPSel"] = arm64.REG_SPSel
   264  	register["DAIFSet"] = arm64.REG_DAIFSet
   265  	register["DAIFClr"] = arm64.REG_DAIFClr
   266  	// Conditional operators, like EQ, NE, etc.
   267  	register["EQ"] = arm64.COND_EQ
   268  	register["NE"] = arm64.COND_NE
   269  	register["HS"] = arm64.COND_HS
   270  	register["CS"] = arm64.COND_HS
   271  	register["LO"] = arm64.COND_LO
   272  	register["CC"] = arm64.COND_LO
   273  	register["MI"] = arm64.COND_MI
   274  	register["PL"] = arm64.COND_PL
   275  	register["VS"] = arm64.COND_VS
   276  	register["VC"] = arm64.COND_VC
   277  	register["HI"] = arm64.COND_HI
   278  	register["LS"] = arm64.COND_LS
   279  	register["GE"] = arm64.COND_GE
   280  	register["LT"] = arm64.COND_LT
   281  	register["GT"] = arm64.COND_GT
   282  	register["LE"] = arm64.COND_LE
   283  	register["AL"] = arm64.COND_AL
   284  	register["NV"] = arm64.COND_NV
   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() *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_CR0; i <= ppc64.REG_CR7; i++ {
   340  		register[obj.Rconv(i)] = int16(i)
   341  	}
   342  	for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ {
   343  		register[obj.Rconv(i)] = int16(i)
   344  	}
   345  	register["CR"] = ppc64.REG_CR
   346  	register["XER"] = ppc64.REG_XER
   347  	register["LR"] = ppc64.REG_LR
   348  	register["CTR"] = ppc64.REG_CTR
   349  	register["FPSCR"] = ppc64.REG_FPSCR
   350  	register["MSR"] = ppc64.REG_MSR
   351  	// Pseudo-registers.
   352  	register["SB"] = RSB
   353  	register["FP"] = RFP
   354  	register["PC"] = RPC
   355  	// Avoid unintentionally clobbering g using R30.
   356  	delete(register, "R30")
   357  	register["g"] = ppc64.REG_R30
   358  	registerPrefix := map[string]bool{
   359  		"CR":  true,
   360  		"F":   true,
   361  		"R":   true,
   362  		"SPR": true,
   363  	}
   364  
   365  	instructions := make(map[string]obj.As)
   366  	for i, s := range obj.Anames {
   367  		instructions[s] = obj.As(i)
   368  	}
   369  	for i, s := range ppc64.Anames {
   370  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   371  			instructions[s] = obj.As(i) + obj.ABasePPC64
   372  		}
   373  	}
   374  	// Annoying aliases.
   375  	instructions["BR"] = ppc64.ABR
   376  	instructions["BL"] = ppc64.ABL
   377  
   378  	return &Arch{
   379  		LinkArch:       &ppc64.Linkppc64,
   380  		Instructions:   instructions,
   381  		Register:       register,
   382  		RegisterPrefix: registerPrefix,
   383  		RegisterNumber: ppc64RegisterNumber,
   384  		IsJump:         jumpPPC64,
   385  	}
   386  }
   387  
   388  func archMips() *Arch {
   389  	register := make(map[string]int16)
   390  	// Create maps for easy lookup of instruction names etc.
   391  	// Note that there is no list of names as there is for x86.
   392  	for i := mips.REG_R0; i <= mips.REG_R31; i++ {
   393  		register[obj.Rconv(i)] = int16(i)
   394  	}
   395  
   396  	for i := mips.REG_F0; i <= mips.REG_F31; i++ {
   397  		register[obj.Rconv(i)] = int16(i)
   398  	}
   399  	for i := mips.REG_M0; i <= mips.REG_M31; i++ {
   400  		register[obj.Rconv(i)] = int16(i)
   401  	}
   402  	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
   403  		register[obj.Rconv(i)] = int16(i)
   404  	}
   405  	register["HI"] = mips.REG_HI
   406  	register["LO"] = mips.REG_LO
   407  	// Pseudo-registers.
   408  	register["SB"] = RSB
   409  	register["FP"] = RFP
   410  	register["PC"] = RPC
   411  	// Avoid unintentionally clobbering g using R30.
   412  	delete(register, "R30")
   413  	register["g"] = mips.REG_R30
   414  
   415  	registerPrefix := map[string]bool{
   416  		"F":   true,
   417  		"FCR": true,
   418  		"M":   true,
   419  		"R":   true,
   420  	}
   421  
   422  	instructions := make(map[string]obj.As)
   423  	for i, s := range obj.Anames {
   424  		instructions[s] = obj.As(i)
   425  	}
   426  	for i, s := range mips.Anames {
   427  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   428  			instructions[s] = obj.As(i) + obj.ABaseMIPS
   429  		}
   430  	}
   431  	// Annoying alias.
   432  	instructions["JAL"] = mips.AJAL
   433  
   434  	return &Arch{
   435  		LinkArch:       &mips.Linkmipsle,
   436  		Instructions:   instructions,
   437  		Register:       register,
   438  		RegisterPrefix: registerPrefix,
   439  		RegisterNumber: mipsRegisterNumber,
   440  		IsJump:         jumpMIPS,
   441  	}
   442  }
   443  
   444  func archMips64() *Arch {
   445  	register := make(map[string]int16)
   446  	// Create maps for easy lookup of instruction names etc.
   447  	// Note that there is no list of names as there is for x86.
   448  	for i := mips.REG_R0; i <= mips.REG_R31; i++ {
   449  		register[obj.Rconv(i)] = int16(i)
   450  	}
   451  	for i := mips.REG_F0; i <= mips.REG_F31; i++ {
   452  		register[obj.Rconv(i)] = int16(i)
   453  	}
   454  	for i := mips.REG_M0; i <= mips.REG_M31; i++ {
   455  		register[obj.Rconv(i)] = int16(i)
   456  	}
   457  	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
   458  		register[obj.Rconv(i)] = int16(i)
   459  	}
   460  	register["HI"] = mips.REG_HI
   461  	register["LO"] = mips.REG_LO
   462  	// Pseudo-registers.
   463  	register["SB"] = RSB
   464  	register["FP"] = RFP
   465  	register["PC"] = RPC
   466  	// Avoid unintentionally clobbering g using R30.
   467  	delete(register, "R30")
   468  	register["g"] = mips.REG_R30
   469  	// Avoid unintentionally clobbering RSB using R28.
   470  	delete(register, "R28")
   471  	register["RSB"] = mips.REG_R28
   472  	registerPrefix := map[string]bool{
   473  		"F":   true,
   474  		"FCR": true,
   475  		"M":   true,
   476  		"R":   true,
   477  	}
   478  
   479  	instructions := make(map[string]obj.As)
   480  	for i, s := range obj.Anames {
   481  		instructions[s] = obj.As(i)
   482  	}
   483  	for i, s := range mips.Anames {
   484  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   485  			instructions[s] = obj.As(i) + obj.ABaseMIPS
   486  		}
   487  	}
   488  	// Annoying alias.
   489  	instructions["JAL"] = mips.AJAL
   490  
   491  	return &Arch{
   492  		LinkArch:       &mips.Linkmips64,
   493  		Instructions:   instructions,
   494  		Register:       register,
   495  		RegisterPrefix: registerPrefix,
   496  		RegisterNumber: mipsRegisterNumber,
   497  		IsJump:         jumpMIPS,
   498  	}
   499  }
   500  
   501  var riscvJumps = map[string]bool{
   502  	"BEQ":  true,
   503  	"BNE":  true,
   504  	"BLT":  true,
   505  	"BGE":  true,
   506  	"BLTU": true,
   507  	"BGEU": true,
   508  	"CALL": true,
   509  	"JAL":  true,
   510  	"JALR": true,
   511  	"JMP":  true,
   512  }
   513  
   514  func archRiscv() *Arch {
   515  	// Pseudo-registers.
   516  	riscv.Registers["SB"] = RSB
   517  	riscv.Registers["FP"] = RFP
   518  	riscv.Registers["PC"] = RPC
   519  
   520  	return &Arch{
   521  		LinkArch:       &riscv.LinkRISCV,
   522  		Instructions:   riscv.Instructions,
   523  		Register:       riscv.Registers,
   524  		RegisterPrefix: nil,
   525  		RegisterNumber: nilRegisterNumber,
   526  		IsJump: func(s string) bool {
   527  			return riscvJumps[s]
   528  		},
   529  	}
   530  }
   531  
   532  func archS390x() *Arch {
   533  	register := make(map[string]int16)
   534  	// Create maps for easy lookup of instruction names etc.
   535  	// Note that there is no list of names as there is for x86.
   536  	for i := s390x.REG_R0; i <= s390x.REG_R15; i++ {
   537  		register[obj.Rconv(i)] = int16(i)
   538  	}
   539  	for i := s390x.REG_F0; i <= s390x.REG_F15; i++ {
   540  		register[obj.Rconv(i)] = int16(i)
   541  	}
   542  	for i := s390x.REG_V0; i <= s390x.REG_V31; i++ {
   543  		register[obj.Rconv(i)] = int16(i)
   544  	}
   545  	for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ {
   546  		register[obj.Rconv(i)] = int16(i)
   547  	}
   548  	register["LR"] = s390x.REG_LR
   549  	// Pseudo-registers.
   550  	register["SB"] = RSB
   551  	register["FP"] = RFP
   552  	register["PC"] = RPC
   553  	// Avoid unintentionally clobbering g using R13.
   554  	delete(register, "R13")
   555  	register["g"] = s390x.REG_R13
   556  	registerPrefix := map[string]bool{
   557  		"AR": true,
   558  		"F":  true,
   559  		"R":  true,
   560  	}
   561  
   562  	instructions := make(map[string]obj.As)
   563  	for i, s := range obj.Anames {
   564  		instructions[s] = obj.As(i)
   565  	}
   566  	for i, s := range s390x.Anames {
   567  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   568  			instructions[s] = obj.As(i) + obj.ABaseS390X
   569  		}
   570  	}
   571  	// Annoying aliases.
   572  	instructions["BR"] = s390x.ABR
   573  	instructions["BL"] = s390x.ABL
   574  
   575  	return &Arch{
   576  		LinkArch:       &s390x.Links390x,
   577  		Instructions:   instructions,
   578  		Register:       register,
   579  		RegisterPrefix: registerPrefix,
   580  		RegisterNumber: s390xRegisterNumber,
   581  		IsJump:         jumpS390x,
   582  	}
   583  }