Source file src/cmd/asm/internal/arch/arch.go

Documentation: cmd/asm/internal/arch

     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  	"cmd/internal/obj"
    10  	"cmd/internal/obj/arm"
    11  	"cmd/internal/obj/arm64"
    12  	"cmd/internal/obj/mips"
    13  	"cmd/internal/obj/ppc64"
    14  	"cmd/internal/obj/s390x"
    15  	"cmd/internal/obj/wasm"
    16  	"cmd/internal/obj/x86"
    17  	"fmt"
    18  	"strings"
    19  )
    20  
    21  // Pseudo-registers whose names are the constant name without the leading R.
    22  const (
    23  	RFP = -(iota + 1)
    24  	RSB
    25  	RSP
    26  	RPC
    27  )
    28  
    29  // Arch wraps the link architecture object with more architecture-specific information.
    30  type Arch struct {
    31  	*obj.LinkArch
    32  	// Map of instruction names to enumeration.
    33  	Instructions map[string]obj.As
    34  	// Map of register names to enumeration.
    35  	Register map[string]int16
    36  	// Table of register prefix names. These are things like R for R(0) and SPR for SPR(268).
    37  	RegisterPrefix map[string]bool
    38  	// RegisterNumber converts R(10) into arm.REG_R10.
    39  	RegisterNumber func(string, int16) (int16, bool)
    40  	// Instruction is a jump.
    41  	IsJump func(word string) bool
    42  }
    43  
    44  // nilRegisterNumber is the register number function for architectures
    45  // that do not accept the R(N) notation. It always returns failure.
    46  func nilRegisterNumber(name string, n int16) (int16, bool) {
    47  	return 0, false
    48  }
    49  
    50  // Set configures the architecture specified by GOARCH and returns its representation.
    51  // It returns nil if GOARCH is not recognized.
    52  func Set(GOARCH string) *Arch {
    53  	switch GOARCH {
    54  	case "386":
    55  		return archX86(&x86.Link386)
    56  	case "amd64":
    57  		return archX86(&x86.Linkamd64)
    58  	case "amd64p32":
    59  		return archX86(&x86.Linkamd64p32)
    60  	case "arm":
    61  		return archArm()
    62  	case "arm64":
    63  		return archArm64()
    64  	case "mips":
    65  		a := archMips()
    66  		a.LinkArch = &mips.Linkmips
    67  		return a
    68  	case "mipsle":
    69  		a := archMips()
    70  		a.LinkArch = &mips.Linkmipsle
    71  		return a
    72  	case "mips64":
    73  		a := archMips64()
    74  		a.LinkArch = &mips.Linkmips64
    75  		return a
    76  	case "mips64le":
    77  		a := archMips64()
    78  		a.LinkArch = &mips.Linkmips64le
    79  		return a
    80  	case "ppc64":
    81  		a := archPPC64()
    82  		a.LinkArch = &ppc64.Linkppc64
    83  		return a
    84  	case "ppc64le":
    85  		a := archPPC64()
    86  		a.LinkArch = &ppc64.Linkppc64le
    87  		return a
    88  	case "s390x":
    89  		a := archS390x()
    90  		a.LinkArch = &s390x.Links390x
    91  		return a
    92  	case "wasm":
    93  		return archWasm()
    94  	}
    95  	return nil
    96  }
    97  
    98  func jumpX86(word string) bool {
    99  	return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
   100  }
   101  
   102  func jumpWasm(word string) bool {
   103  	return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf"
   104  }
   105  
   106  func archX86(linkArch *obj.LinkArch) *Arch {
   107  	register := make(map[string]int16)
   108  	// Create maps for easy lookup of instruction names etc.
   109  	for i, s := range x86.Register {
   110  		register[s] = int16(i + x86.REG_AL)
   111  	}
   112  	// Pseudo-registers.
   113  	register["SB"] = RSB
   114  	register["FP"] = RFP
   115  	register["PC"] = RPC
   116  	// Register prefix not used on this architecture.
   117  
   118  	instructions := make(map[string]obj.As)
   119  	for i, s := range obj.Anames {
   120  		instructions[s] = obj.As(i)
   121  	}
   122  	for i, s := range x86.Anames {
   123  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   124  			instructions[s] = obj.As(i) + obj.ABaseAMD64
   125  		}
   126  	}
   127  	// Annoying aliases.
   128  	instructions["JA"] = x86.AJHI   /* alternate */
   129  	instructions["JAE"] = x86.AJCC  /* alternate */
   130  	instructions["JB"] = x86.AJCS   /* alternate */
   131  	instructions["JBE"] = x86.AJLS  /* alternate */
   132  	instructions["JC"] = x86.AJCS   /* alternate */
   133  	instructions["JCC"] = x86.AJCC  /* carry clear (CF = 0) */
   134  	instructions["JCS"] = x86.AJCS  /* carry set (CF = 1) */
   135  	instructions["JE"] = x86.AJEQ   /* alternate */
   136  	instructions["JEQ"] = x86.AJEQ  /* equal (ZF = 1) */
   137  	instructions["JG"] = x86.AJGT   /* alternate */
   138  	instructions["JGE"] = x86.AJGE  /* greater than or equal (signed) (SF = OF) */
   139  	instructions["JGT"] = x86.AJGT  /* greater than (signed) (ZF = 0 && SF = OF) */
   140  	instructions["JHI"] = x86.AJHI  /* higher (unsigned) (CF = 0 && ZF = 0) */
   141  	instructions["JHS"] = x86.AJCC  /* alternate */
   142  	instructions["JL"] = x86.AJLT   /* alternate */
   143  	instructions["JLE"] = x86.AJLE  /* less than or equal (signed) (ZF = 1 || SF != OF) */
   144  	instructions["JLO"] = x86.AJCS  /* alternate */
   145  	instructions["JLS"] = x86.AJLS  /* lower or same (unsigned) (CF = 1 || ZF = 1) */
   146  	instructions["JLT"] = x86.AJLT  /* less than (signed) (SF != OF) */
   147  	instructions["JMI"] = x86.AJMI  /* negative (minus) (SF = 1) */
   148  	instructions["JNA"] = x86.AJLS  /* alternate */
   149  	instructions["JNAE"] = x86.AJCS /* alternate */
   150  	instructions["JNB"] = x86.AJCC  /* alternate */
   151  	instructions["JNBE"] = x86.AJHI /* alternate */
   152  	instructions["JNC"] = x86.AJCC  /* alternate */
   153  	instructions["JNE"] = x86.AJNE  /* not equal (ZF = 0) */
   154  	instructions["JNG"] = x86.AJLE  /* alternate */
   155  	instructions["JNGE"] = x86.AJLT /* alternate */
   156  	instructions["JNL"] = x86.AJGE  /* alternate */
   157  	instructions["JNLE"] = x86.AJGT /* alternate */
   158  	instructions["JNO"] = x86.AJOC  /* alternate */
   159  	instructions["JNP"] = x86.AJPC  /* alternate */
   160  	instructions["JNS"] = x86.AJPL  /* alternate */
   161  	instructions["JNZ"] = x86.AJNE  /* alternate */
   162  	instructions["JO"] = x86.AJOS   /* alternate */
   163  	instructions["JOC"] = x86.AJOC  /* overflow clear (OF = 0) */
   164  	instructions["JOS"] = x86.AJOS  /* overflow set (OF = 1) */
   165  	instructions["JP"] = x86.AJPS   /* alternate */
   166  	instructions["JPC"] = x86.AJPC  /* parity clear (PF = 0) */
   167  	instructions["JPE"] = x86.AJPS  /* alternate */
   168  	instructions["JPL"] = x86.AJPL  /* non-negative (plus) (SF = 0) */
   169  	instructions["JPO"] = x86.AJPC  /* alternate */
   170  	instructions["JPS"] = x86.AJPS  /* parity set (PF = 1) */
   171  	instructions["JS"] = x86.AJMI   /* alternate */
   172  	instructions["JZ"] = x86.AJEQ   /* alternate */
   173  	instructions["MASKMOVDQU"] = x86.AMASKMOVOU
   174  	instructions["MOVD"] = x86.AMOVQ
   175  	instructions["MOVDQ2Q"] = x86.AMOVQ
   176  	instructions["MOVNTDQ"] = x86.AMOVNTO
   177  	instructions["MOVOA"] = x86.AMOVO
   178  	instructions["PSLLDQ"] = x86.APSLLO
   179  	instructions["PSRLDQ"] = x86.APSRLO
   180  	instructions["PADDD"] = x86.APADDL
   181  
   182  	return &Arch{
   183  		LinkArch:       linkArch,
   184  		Instructions:   instructions,
   185  		Register:       register,
   186  		RegisterPrefix: nil,
   187  		RegisterNumber: nilRegisterNumber,
   188  		IsJump:         jumpX86,
   189  	}
   190  }
   191  
   192  func archArm() *Arch {
   193  	register := make(map[string]int16)
   194  	// Create maps for easy lookup of instruction names etc.
   195  	// Note that there is no list of names as there is for x86.
   196  	for i := arm.REG_R0; i < arm.REG_SPSR; i++ {
   197  		register[obj.Rconv(i)] = int16(i)
   198  	}
   199  	// Avoid unintentionally clobbering g using R10.
   200  	delete(register, "R10")
   201  	register["g"] = arm.REG_R10
   202  	for i := 0; i < 16; i++ {
   203  		register[fmt.Sprintf("C%d", i)] = int16(i)
   204  	}
   205  
   206  	// Pseudo-registers.
   207  	register["SB"] = RSB
   208  	register["FP"] = RFP
   209  	register["PC"] = RPC
   210  	register["SP"] = RSP
   211  	registerPrefix := map[string]bool{
   212  		"F": true,
   213  		"R": true,
   214  	}
   215  
   216  	// special operands for DMB/DSB instructions
   217  	register["MB_SY"] = arm.REG_MB_SY
   218  	register["MB_ST"] = arm.REG_MB_ST
   219  	register["MB_ISH"] = arm.REG_MB_ISH
   220  	register["MB_ISHST"] = arm.REG_MB_ISHST
   221  	register["MB_NSH"] = arm.REG_MB_NSH
   222  	register["MB_NSHST"] = arm.REG_MB_NSHST
   223  	register["MB_OSH"] = arm.REG_MB_OSH
   224  	register["MB_OSHST"] = arm.REG_MB_OSHST
   225  
   226  	instructions := make(map[string]obj.As)
   227  	for i, s := range obj.Anames {
   228  		instructions[s] = obj.As(i)
   229  	}
   230  	for i, s := range arm.Anames {
   231  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   232  			instructions[s] = obj.As(i) + obj.ABaseARM
   233  		}
   234  	}
   235  	// Annoying aliases.
   236  	instructions["B"] = obj.AJMP
   237  	instructions["BL"] = obj.ACALL
   238  	// MCR differs from MRC by the way fields of the word are encoded.
   239  	// (Details in arm.go). Here we add the instruction so parse will find
   240  	// it, but give it an opcode number known only to us.
   241  	instructions["MCR"] = aMCR
   242  
   243  	return &Arch{
   244  		LinkArch:       &arm.Linkarm,
   245  		Instructions:   instructions,
   246  		Register:       register,
   247  		RegisterPrefix: registerPrefix,
   248  		RegisterNumber: armRegisterNumber,
   249  		IsJump:         jumpArm,
   250  	}
   251  }
   252  
   253  func archArm64() *Arch {
   254  	register := make(map[string]int16)
   255  	// Create maps for easy lookup of instruction names etc.
   256  	// Note that there is no list of names as there is for 386 and amd64.
   257  	register[obj.Rconv(arm64.REGSP)] = int16(arm64.REGSP)
   258  	for i := arm64.REG_R0; i <= arm64.REG_R31; i++ {
   259  		register[obj.Rconv(i)] = int16(i)
   260  	}
   261  	// Rename R18 to R18_PLATFORM to avoid accidental use.
   262  	register["R18_PLATFORM"] = register["R18"]
   263  	delete(register, "R18")
   264  	for i := arm64.REG_F0; i <= arm64.REG_F31; i++ {
   265  		register[obj.Rconv(i)] = int16(i)
   266  	}
   267  	for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
   268  		register[obj.Rconv(i)] = int16(i)
   269  	}
   270  	register["LR"] = arm64.REGLINK
   271  	register["DAIF"] = arm64.REG_DAIF
   272  	register["NZCV"] = arm64.REG_NZCV
   273  	register["FPSR"] = arm64.REG_FPSR
   274  	register["FPCR"] = arm64.REG_FPCR
   275  	register["SPSR_EL1"] = arm64.REG_SPSR_EL1
   276  	register["ELR_EL1"] = arm64.REG_ELR_EL1
   277  	register["SPSR_EL2"] = arm64.REG_SPSR_EL2
   278  	register["ELR_EL2"] = arm64.REG_ELR_EL2
   279  	register["CurrentEL"] = arm64.REG_CurrentEL
   280  	register["SP_EL0"] = arm64.REG_SP_EL0
   281  	register["SPSel"] = arm64.REG_SPSel
   282  	register["DAIFSet"] = arm64.REG_DAIFSet
   283  	register["DAIFClr"] = arm64.REG_DAIFClr
   284  	register["DCZID_EL0"] = arm64.REG_DCZID_EL0
   285  	register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP
   286  	register["PLDL1STRM"] = arm64.REG_PLDL1STRM
   287  	register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP
   288  	register["PLDL2STRM"] = arm64.REG_PLDL2STRM
   289  	register["PLDL3KEEP"] = arm64.REG_PLDL3KEEP
   290  	register["PLDL3STRM"] = arm64.REG_PLDL3STRM
   291  	register["PLIL1KEEP"] = arm64.REG_PLIL1KEEP
   292  	register["PLIL1STRM"] = arm64.REG_PLIL1STRM
   293  	register["PLIL2KEEP"] = arm64.REG_PLIL2KEEP
   294  	register["PLIL2STRM"] = arm64.REG_PLIL2STRM
   295  	register["PLIL3KEEP"] = arm64.REG_PLIL3KEEP
   296  	register["PLIL3STRM"] = arm64.REG_PLIL3STRM
   297  	register["PSTL1KEEP"] = arm64.REG_PSTL1KEEP
   298  	register["PSTL1STRM"] = arm64.REG_PSTL1STRM
   299  	register["PSTL2KEEP"] = arm64.REG_PSTL2KEEP
   300  	register["PSTL2STRM"] = arm64.REG_PSTL2STRM
   301  	register["PSTL3KEEP"] = arm64.REG_PSTL3KEEP
   302  	register["PSTL3STRM"] = arm64.REG_PSTL3STRM
   303  
   304  	// Conditional operators, like EQ, NE, etc.
   305  	register["EQ"] = arm64.COND_EQ
   306  	register["NE"] = arm64.COND_NE
   307  	register["HS"] = arm64.COND_HS
   308  	register["CS"] = arm64.COND_HS
   309  	register["LO"] = arm64.COND_LO
   310  	register["CC"] = arm64.COND_LO
   311  	register["MI"] = arm64.COND_MI
   312  	register["PL"] = arm64.COND_PL
   313  	register["VS"] = arm64.COND_VS
   314  	register["VC"] = arm64.COND_VC
   315  	register["HI"] = arm64.COND_HI
   316  	register["LS"] = arm64.COND_LS
   317  	register["GE"] = arm64.COND_GE
   318  	register["LT"] = arm64.COND_LT
   319  	register["GT"] = arm64.COND_GT
   320  	register["LE"] = arm64.COND_LE
   321  	register["AL"] = arm64.COND_AL
   322  	register["NV"] = arm64.COND_NV
   323  	// Pseudo-registers.
   324  	register["SB"] = RSB
   325  	register["FP"] = RFP
   326  	register["PC"] = RPC
   327  	register["SP"] = RSP
   328  	// Avoid unintentionally clobbering g using R28.
   329  	delete(register, "R28")
   330  	register["g"] = arm64.REG_R28
   331  	registerPrefix := map[string]bool{
   332  		"F": true,
   333  		"R": true,
   334  		"V": true,
   335  	}
   336  
   337  	instructions := make(map[string]obj.As)
   338  	for i, s := range obj.Anames {
   339  		instructions[s] = obj.As(i)
   340  	}
   341  	for i, s := range arm64.Anames {
   342  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   343  			instructions[s] = obj.As(i) + obj.ABaseARM64
   344  		}
   345  	}
   346  	// Annoying aliases.
   347  	instructions["B"] = arm64.AB
   348  	instructions["BL"] = arm64.ABL
   349  
   350  	return &Arch{
   351  		LinkArch:       &arm64.Linkarm64,
   352  		Instructions:   instructions,
   353  		Register:       register,
   354  		RegisterPrefix: registerPrefix,
   355  		RegisterNumber: arm64RegisterNumber,
   356  		IsJump:         jumpArm64,
   357  	}
   358  
   359  }
   360  
   361  func archPPC64() *Arch {
   362  	register := make(map[string]int16)
   363  	// Create maps for easy lookup of instruction names etc.
   364  	// Note that there is no list of names as there is for x86.
   365  	for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ {
   366  		register[obj.Rconv(i)] = int16(i)
   367  	}
   368  	for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ {
   369  		register[obj.Rconv(i)] = int16(i)
   370  	}
   371  	for i := ppc64.REG_V0; i <= ppc64.REG_V31; i++ {
   372  		register[obj.Rconv(i)] = int16(i)
   373  	}
   374  	for i := ppc64.REG_VS0; i <= ppc64.REG_VS63; i++ {
   375  		register[obj.Rconv(i)] = int16(i)
   376  	}
   377  	for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ {
   378  		register[obj.Rconv(i)] = int16(i)
   379  	}
   380  	for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ {
   381  		register[obj.Rconv(i)] = int16(i)
   382  	}
   383  	register["CR"] = ppc64.REG_CR
   384  	register["XER"] = ppc64.REG_XER
   385  	register["LR"] = ppc64.REG_LR
   386  	register["CTR"] = ppc64.REG_CTR
   387  	register["FPSCR"] = ppc64.REG_FPSCR
   388  	register["MSR"] = ppc64.REG_MSR
   389  	// Pseudo-registers.
   390  	register["SB"] = RSB
   391  	register["FP"] = RFP
   392  	register["PC"] = RPC
   393  	// Avoid unintentionally clobbering g using R30.
   394  	delete(register, "R30")
   395  	register["g"] = ppc64.REG_R30
   396  	registerPrefix := map[string]bool{
   397  		"CR":  true,
   398  		"F":   true,
   399  		"R":   true,
   400  		"SPR": true,
   401  	}
   402  
   403  	instructions := make(map[string]obj.As)
   404  	for i, s := range obj.Anames {
   405  		instructions[s] = obj.As(i)
   406  	}
   407  	for i, s := range ppc64.Anames {
   408  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   409  			instructions[s] = obj.As(i) + obj.ABasePPC64
   410  		}
   411  	}
   412  	// Annoying aliases.
   413  	instructions["BR"] = ppc64.ABR
   414  	instructions["BL"] = ppc64.ABL
   415  
   416  	return &Arch{
   417  		LinkArch:       &ppc64.Linkppc64,
   418  		Instructions:   instructions,
   419  		Register:       register,
   420  		RegisterPrefix: registerPrefix,
   421  		RegisterNumber: ppc64RegisterNumber,
   422  		IsJump:         jumpPPC64,
   423  	}
   424  }
   425  
   426  func archMips() *Arch {
   427  	register := make(map[string]int16)
   428  	// Create maps for easy lookup of instruction names etc.
   429  	// Note that there is no list of names as there is for x86.
   430  	for i := mips.REG_R0; i <= mips.REG_R31; i++ {
   431  		register[obj.Rconv(i)] = int16(i)
   432  	}
   433  
   434  	for i := mips.REG_F0; i <= mips.REG_F31; i++ {
   435  		register[obj.Rconv(i)] = int16(i)
   436  	}
   437  	for i := mips.REG_M0; i <= mips.REG_M31; i++ {
   438  		register[obj.Rconv(i)] = int16(i)
   439  	}
   440  	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
   441  		register[obj.Rconv(i)] = int16(i)
   442  	}
   443  	register["HI"] = mips.REG_HI
   444  	register["LO"] = mips.REG_LO
   445  	// Pseudo-registers.
   446  	register["SB"] = RSB
   447  	register["FP"] = RFP
   448  	register["PC"] = RPC
   449  	// Avoid unintentionally clobbering g using R30.
   450  	delete(register, "R30")
   451  	register["g"] = mips.REG_R30
   452  
   453  	registerPrefix := map[string]bool{
   454  		"F":   true,
   455  		"FCR": true,
   456  		"M":   true,
   457  		"R":   true,
   458  	}
   459  
   460  	instructions := make(map[string]obj.As)
   461  	for i, s := range obj.Anames {
   462  		instructions[s] = obj.As(i)
   463  	}
   464  	for i, s := range mips.Anames {
   465  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   466  			instructions[s] = obj.As(i) + obj.ABaseMIPS
   467  		}
   468  	}
   469  	// Annoying alias.
   470  	instructions["JAL"] = mips.AJAL
   471  
   472  	return &Arch{
   473  		LinkArch:       &mips.Linkmipsle,
   474  		Instructions:   instructions,
   475  		Register:       register,
   476  		RegisterPrefix: registerPrefix,
   477  		RegisterNumber: mipsRegisterNumber,
   478  		IsJump:         jumpMIPS,
   479  	}
   480  }
   481  
   482  func archMips64() *Arch {
   483  	register := make(map[string]int16)
   484  	// Create maps for easy lookup of instruction names etc.
   485  	// Note that there is no list of names as there is for x86.
   486  	for i := mips.REG_R0; i <= mips.REG_R31; i++ {
   487  		register[obj.Rconv(i)] = int16(i)
   488  	}
   489  	for i := mips.REG_F0; i <= mips.REG_F31; i++ {
   490  		register[obj.Rconv(i)] = int16(i)
   491  	}
   492  	for i := mips.REG_M0; i <= mips.REG_M31; i++ {
   493  		register[obj.Rconv(i)] = int16(i)
   494  	}
   495  	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
   496  		register[obj.Rconv(i)] = int16(i)
   497  	}
   498  	register["HI"] = mips.REG_HI
   499  	register["LO"] = mips.REG_LO
   500  	// Pseudo-registers.
   501  	register["SB"] = RSB
   502  	register["FP"] = RFP
   503  	register["PC"] = RPC
   504  	// Avoid unintentionally clobbering g using R30.
   505  	delete(register, "R30")
   506  	register["g"] = mips.REG_R30
   507  	// Avoid unintentionally clobbering RSB using R28.
   508  	delete(register, "R28")
   509  	register["RSB"] = mips.REG_R28
   510  	registerPrefix := map[string]bool{
   511  		"F":   true,
   512  		"FCR": true,
   513  		"M":   true,
   514  		"R":   true,
   515  	}
   516  
   517  	instructions := make(map[string]obj.As)
   518  	for i, s := range obj.Anames {
   519  		instructions[s] = obj.As(i)
   520  	}
   521  	for i, s := range mips.Anames {
   522  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   523  			instructions[s] = obj.As(i) + obj.ABaseMIPS
   524  		}
   525  	}
   526  	// Annoying alias.
   527  	instructions["JAL"] = mips.AJAL
   528  
   529  	return &Arch{
   530  		LinkArch:       &mips.Linkmips64,
   531  		Instructions:   instructions,
   532  		Register:       register,
   533  		RegisterPrefix: registerPrefix,
   534  		RegisterNumber: mipsRegisterNumber,
   535  		IsJump:         jumpMIPS,
   536  	}
   537  }
   538  
   539  func archS390x() *Arch {
   540  	register := make(map[string]int16)
   541  	// Create maps for easy lookup of instruction names etc.
   542  	// Note that there is no list of names as there is for x86.
   543  	for i := s390x.REG_R0; i <= s390x.REG_R15; i++ {
   544  		register[obj.Rconv(i)] = int16(i)
   545  	}
   546  	for i := s390x.REG_F0; i <= s390x.REG_F15; i++ {
   547  		register[obj.Rconv(i)] = int16(i)
   548  	}
   549  	for i := s390x.REG_V0; i <= s390x.REG_V31; i++ {
   550  		register[obj.Rconv(i)] = int16(i)
   551  	}
   552  	for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ {
   553  		register[obj.Rconv(i)] = int16(i)
   554  	}
   555  	register["LR"] = s390x.REG_LR
   556  	// Pseudo-registers.
   557  	register["SB"] = RSB
   558  	register["FP"] = RFP
   559  	register["PC"] = RPC
   560  	// Avoid unintentionally clobbering g using R13.
   561  	delete(register, "R13")
   562  	register["g"] = s390x.REG_R13
   563  	registerPrefix := map[string]bool{
   564  		"AR": true,
   565  		"F":  true,
   566  		"R":  true,
   567  	}
   568  
   569  	instructions := make(map[string]obj.As)
   570  	for i, s := range obj.Anames {
   571  		instructions[s] = obj.As(i)
   572  	}
   573  	for i, s := range s390x.Anames {
   574  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   575  			instructions[s] = obj.As(i) + obj.ABaseS390X
   576  		}
   577  	}
   578  	// Annoying aliases.
   579  	instructions["BR"] = s390x.ABR
   580  	instructions["BL"] = s390x.ABL
   581  
   582  	return &Arch{
   583  		LinkArch:       &s390x.Links390x,
   584  		Instructions:   instructions,
   585  		Register:       register,
   586  		RegisterPrefix: registerPrefix,
   587  		RegisterNumber: s390xRegisterNumber,
   588  		IsJump:         jumpS390x,
   589  	}
   590  }
   591  
   592  func archWasm() *Arch {
   593  	instructions := make(map[string]obj.As)
   594  	for i, s := range obj.Anames {
   595  		instructions[s] = obj.As(i)
   596  	}
   597  	for i, s := range wasm.Anames {
   598  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
   599  			instructions[s] = obj.As(i) + obj.ABaseWasm
   600  		}
   601  	}
   602  
   603  	return &Arch{
   604  		LinkArch:       &wasm.Linkwasm,
   605  		Instructions:   instructions,
   606  		Register:       wasm.Register,
   607  		RegisterPrefix: nil,
   608  		RegisterNumber: nilRegisterNumber,
   609  		IsJump:         jumpWasm,
   610  	}
   611  }
   612  

View as plain text