...

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

     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