mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 22:32:25 -05:00 
			
		
		
		
	[chore] Update gin to v1.9.0 (#1553)
This commit is contained in:
		
					parent
					
						
							
								689a10fe17
							
						
					
				
			
			
				commit
				
					
						ecdc8379fa
					
				
			
		
					 347 changed files with 166814 additions and 3671 deletions
				
			
		
							
								
								
									
										716
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arch.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										716
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arch.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,716 @@ | |||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // Package arch defines architecture-specific information and support functions. | ||||
| package arch | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/arm" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/arm64" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/mips" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/ppc64" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/riscv" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/s390x" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/wasm" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/x86" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // Pseudo-registers whose names are the constant name without the leading R. | ||||
| const ( | ||||
| 	RFP = -(iota + 1) | ||||
| 	RSB | ||||
| 	RSP | ||||
| 	RPC | ||||
| ) | ||||
| 
 | ||||
| // Arch wraps the link architecture object with more architecture-specific information. | ||||
| type Arch struct { | ||||
| 	*obj.LinkArch | ||||
| 	// Map of instruction names to enumeration. | ||||
| 	Instructions map[string]obj.As | ||||
| 	// Map of register names to enumeration. | ||||
| 	Register map[string]int16 | ||||
| 	// Table of register prefix names. These are things like R for R(0) and SPR for SPR(268). | ||||
| 	RegisterPrefix map[string]bool | ||||
| 	// RegisterNumber converts R(10) into arm.REG_R10. | ||||
| 	RegisterNumber func(string, int16) (int16, bool) | ||||
| 	// Instruction is a jump. | ||||
| 	IsJump func(word string) bool | ||||
| } | ||||
| 
 | ||||
| // nilRegisterNumber is the register number function for architectures | ||||
| // that do not accept the R(N) notation. It always returns failure. | ||||
| func nilRegisterNumber(name string, n int16) (int16, bool) { | ||||
| 	return 0, false | ||||
| } | ||||
| 
 | ||||
| // Set configures the architecture specified by GOARCH and returns its representation. | ||||
| // It returns nil if GOARCH is not recognized. | ||||
| func Set(GOARCH string) *Arch { | ||||
| 	switch GOARCH { | ||||
| 	case "386": | ||||
| 		return archX86(&x86.Link386) | ||||
| 	case "amd64": | ||||
| 		return archX86(&x86.Linkamd64) | ||||
| 	case "arm": | ||||
| 		return archArm() | ||||
| 	case "arm64": | ||||
| 		return archArm64() | ||||
| 	case "mips": | ||||
| 		return archMips(&mips.Linkmips) | ||||
| 	case "mipsle": | ||||
| 		return archMips(&mips.Linkmipsle) | ||||
| 	case "mips64": | ||||
| 		return archMips64(&mips.Linkmips64) | ||||
| 	case "mips64le": | ||||
| 		return archMips64(&mips.Linkmips64le) | ||||
| 	case "ppc64": | ||||
| 		return archPPC64(&ppc64.Linkppc64) | ||||
| 	case "ppc64le": | ||||
| 		return archPPC64(&ppc64.Linkppc64le) | ||||
| 	case "riscv64": | ||||
| 		return archRISCV64() | ||||
| 	case "s390x": | ||||
| 		return archS390x() | ||||
| 	case "wasm": | ||||
| 		return archWasm() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func jumpX86(word string) bool { | ||||
| 	return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN" | ||||
| } | ||||
| 
 | ||||
| func jumpRISCV(word string) bool { | ||||
| 	switch word { | ||||
| 	case "BEQ", "BEQZ", "BGE", "BGEU", "BGEZ", "BGT", "BGTU", "BGTZ", "BLE", "BLEU", "BLEZ", | ||||
| 		"BLT", "BLTU", "BLTZ", "BNE", "BNEZ", "CALL", "JAL", "JALR", "JMP": | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func jumpWasm(word string) bool { | ||||
| 	return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf" | ||||
| } | ||||
| 
 | ||||
| func archX86(linkArch *obj.LinkArch) *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 	// Create maps for easy lookup of instruction names etc. | ||||
| 	for i, s := range x86.Register { | ||||
| 		register[s] = int16(i + x86.REG_AL) | ||||
| 	} | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 	// Register prefix not used on this architecture. | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range x86.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseAMD64 | ||||
| 		} | ||||
| 	} | ||||
| 	// Annoying aliases. | ||||
| 	instructions["JA"] = x86.AJHI   /* alternate */ | ||||
| 	instructions["JAE"] = x86.AJCC  /* alternate */ | ||||
| 	instructions["JB"] = x86.AJCS   /* alternate */ | ||||
| 	instructions["JBE"] = x86.AJLS  /* alternate */ | ||||
| 	instructions["JC"] = x86.AJCS   /* alternate */ | ||||
| 	instructions["JCC"] = x86.AJCC  /* carry clear (CF = 0) */ | ||||
| 	instructions["JCS"] = x86.AJCS  /* carry set (CF = 1) */ | ||||
| 	instructions["JE"] = x86.AJEQ   /* alternate */ | ||||
| 	instructions["JEQ"] = x86.AJEQ  /* equal (ZF = 1) */ | ||||
| 	instructions["JG"] = x86.AJGT   /* alternate */ | ||||
| 	instructions["JGE"] = x86.AJGE  /* greater than or equal (signed) (SF = OF) */ | ||||
| 	instructions["JGT"] = x86.AJGT  /* greater than (signed) (ZF = 0 && SF = OF) */ | ||||
| 	instructions["JHI"] = x86.AJHI  /* higher (unsigned) (CF = 0 && ZF = 0) */ | ||||
| 	instructions["JHS"] = x86.AJCC  /* alternate */ | ||||
| 	instructions["JL"] = x86.AJLT   /* alternate */ | ||||
| 	instructions["JLE"] = x86.AJLE  /* less than or equal (signed) (ZF = 1 || SF != OF) */ | ||||
| 	instructions["JLO"] = x86.AJCS  /* alternate */ | ||||
| 	instructions["JLS"] = x86.AJLS  /* lower or same (unsigned) (CF = 1 || ZF = 1) */ | ||||
| 	instructions["JLT"] = x86.AJLT  /* less than (signed) (SF != OF) */ | ||||
| 	instructions["JMI"] = x86.AJMI  /* negative (minus) (SF = 1) */ | ||||
| 	instructions["JNA"] = x86.AJLS  /* alternate */ | ||||
| 	instructions["JNAE"] = x86.AJCS /* alternate */ | ||||
| 	instructions["JNB"] = x86.AJCC  /* alternate */ | ||||
| 	instructions["JNBE"] = x86.AJHI /* alternate */ | ||||
| 	instructions["JNC"] = x86.AJCC  /* alternate */ | ||||
| 	instructions["JNE"] = x86.AJNE  /* not equal (ZF = 0) */ | ||||
| 	instructions["JNG"] = x86.AJLE  /* alternate */ | ||||
| 	instructions["JNGE"] = x86.AJLT /* alternate */ | ||||
| 	instructions["JNL"] = x86.AJGE  /* alternate */ | ||||
| 	instructions["JNLE"] = x86.AJGT /* alternate */ | ||||
| 	instructions["JNO"] = x86.AJOC  /* alternate */ | ||||
| 	instructions["JNP"] = x86.AJPC  /* alternate */ | ||||
| 	instructions["JNS"] = x86.AJPL  /* alternate */ | ||||
| 	instructions["JNZ"] = x86.AJNE  /* alternate */ | ||||
| 	instructions["JO"] = x86.AJOS   /* alternate */ | ||||
| 	instructions["JOC"] = x86.AJOC  /* overflow clear (OF = 0) */ | ||||
| 	instructions["JOS"] = x86.AJOS  /* overflow set (OF = 1) */ | ||||
| 	instructions["JP"] = x86.AJPS   /* alternate */ | ||||
| 	instructions["JPC"] = x86.AJPC  /* parity clear (PF = 0) */ | ||||
| 	instructions["JPE"] = x86.AJPS  /* alternate */ | ||||
| 	instructions["JPL"] = x86.AJPL  /* non-negative (plus) (SF = 0) */ | ||||
| 	instructions["JPO"] = x86.AJPC  /* alternate */ | ||||
| 	instructions["JPS"] = x86.AJPS  /* parity set (PF = 1) */ | ||||
| 	instructions["JS"] = x86.AJMI   /* alternate */ | ||||
| 	instructions["JZ"] = x86.AJEQ   /* alternate */ | ||||
| 	instructions["MASKMOVDQU"] = x86.AMASKMOVOU | ||||
| 	instructions["MOVD"] = x86.AMOVQ | ||||
| 	instructions["MOVDQ2Q"] = x86.AMOVQ | ||||
| 	instructions["MOVNTDQ"] = x86.AMOVNTO | ||||
| 	instructions["MOVOA"] = x86.AMOVO | ||||
| 	instructions["PSLLDQ"] = x86.APSLLO | ||||
| 	instructions["PSRLDQ"] = x86.APSRLO | ||||
| 	instructions["PADDD"] = x86.APADDL | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       linkArch, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: nil, | ||||
| 		RegisterNumber: nilRegisterNumber, | ||||
| 		IsJump:         jumpX86, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func archArm() *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 	// Create maps for easy lookup of instruction names etc. | ||||
| 	// Note that there is no list of names as there is for x86. | ||||
| 	for i := arm.REG_R0; i < arm.REG_SPSR; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	// Avoid unintentionally clobbering g using R10. | ||||
| 	delete(register, "R10") | ||||
| 	register["g"] = arm.REG_R10 | ||||
| 	for i := 0; i < 16; i++ { | ||||
| 		register[fmt.Sprintf("C%d", i)] = int16(i) | ||||
| 	} | ||||
| 
 | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 	register["SP"] = RSP | ||||
| 	registerPrefix := map[string]bool{ | ||||
| 		"F": true, | ||||
| 		"R": true, | ||||
| 	} | ||||
| 
 | ||||
| 	// special operands for DMB/DSB instructions | ||||
| 	register["MB_SY"] = arm.REG_MB_SY | ||||
| 	register["MB_ST"] = arm.REG_MB_ST | ||||
| 	register["MB_ISH"] = arm.REG_MB_ISH | ||||
| 	register["MB_ISHST"] = arm.REG_MB_ISHST | ||||
| 	register["MB_NSH"] = arm.REG_MB_NSH | ||||
| 	register["MB_NSHST"] = arm.REG_MB_NSHST | ||||
| 	register["MB_OSH"] = arm.REG_MB_OSH | ||||
| 	register["MB_OSHST"] = arm.REG_MB_OSHST | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range arm.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseARM | ||||
| 		} | ||||
| 	} | ||||
| 	// Annoying aliases. | ||||
| 	instructions["B"] = obj.AJMP | ||||
| 	instructions["BL"] = obj.ACALL | ||||
| 	// MCR differs from MRC by the way fields of the word are encoded. | ||||
| 	// (Details in arm.go). Here we add the instruction so parse will find | ||||
| 	// it, but give it an opcode number known only to us. | ||||
| 	instructions["MCR"] = aMCR | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       &arm.Linkarm, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: registerPrefix, | ||||
| 		RegisterNumber: armRegisterNumber, | ||||
| 		IsJump:         jumpArm, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func archArm64() *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 	// Create maps for easy lookup of instruction names etc. | ||||
| 	// Note that there is no list of names as there is for 386 and amd64. | ||||
| 	register[obj.Rconv(arm64.REGSP)] = int16(arm64.REGSP) | ||||
| 	for i := arm64.REG_R0; i <= arm64.REG_R31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	// Rename R18 to R18_PLATFORM to avoid accidental use. | ||||
| 	register["R18_PLATFORM"] = register["R18"] | ||||
| 	delete(register, "R18") | ||||
| 	for i := arm64.REG_F0; i <= arm64.REG_F31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := arm64.REG_V0; i <= arm64.REG_V31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 
 | ||||
| 	// System registers. | ||||
| 	for i := 0; i < len(arm64.SystemReg); i++ { | ||||
| 		register[arm64.SystemReg[i].Name] = arm64.SystemReg[i].Reg | ||||
| 	} | ||||
| 
 | ||||
| 	register["LR"] = arm64.REGLINK | ||||
| 	register["DAIFSet"] = arm64.REG_DAIFSet | ||||
| 	register["DAIFClr"] = arm64.REG_DAIFClr | ||||
| 	register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP | ||||
| 	register["PLDL1STRM"] = arm64.REG_PLDL1STRM | ||||
| 	register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP | ||||
| 	register["PLDL2STRM"] = arm64.REG_PLDL2STRM | ||||
| 	register["PLDL3KEEP"] = arm64.REG_PLDL3KEEP | ||||
| 	register["PLDL3STRM"] = arm64.REG_PLDL3STRM | ||||
| 	register["PLIL1KEEP"] = arm64.REG_PLIL1KEEP | ||||
| 	register["PLIL1STRM"] = arm64.REG_PLIL1STRM | ||||
| 	register["PLIL2KEEP"] = arm64.REG_PLIL2KEEP | ||||
| 	register["PLIL2STRM"] = arm64.REG_PLIL2STRM | ||||
| 	register["PLIL3KEEP"] = arm64.REG_PLIL3KEEP | ||||
| 	register["PLIL3STRM"] = arm64.REG_PLIL3STRM | ||||
| 	register["PSTL1KEEP"] = arm64.REG_PSTL1KEEP | ||||
| 	register["PSTL1STRM"] = arm64.REG_PSTL1STRM | ||||
| 	register["PSTL2KEEP"] = arm64.REG_PSTL2KEEP | ||||
| 	register["PSTL2STRM"] = arm64.REG_PSTL2STRM | ||||
| 	register["PSTL3KEEP"] = arm64.REG_PSTL3KEEP | ||||
| 	register["PSTL3STRM"] = arm64.REG_PSTL3STRM | ||||
| 
 | ||||
| 	// Conditional operators, like EQ, NE, etc. | ||||
| 	register["EQ"] = arm64.COND_EQ | ||||
| 	register["NE"] = arm64.COND_NE | ||||
| 	register["HS"] = arm64.COND_HS | ||||
| 	register["CS"] = arm64.COND_HS | ||||
| 	register["LO"] = arm64.COND_LO | ||||
| 	register["CC"] = arm64.COND_LO | ||||
| 	register["MI"] = arm64.COND_MI | ||||
| 	register["PL"] = arm64.COND_PL | ||||
| 	register["VS"] = arm64.COND_VS | ||||
| 	register["VC"] = arm64.COND_VC | ||||
| 	register["HI"] = arm64.COND_HI | ||||
| 	register["LS"] = arm64.COND_LS | ||||
| 	register["GE"] = arm64.COND_GE | ||||
| 	register["LT"] = arm64.COND_LT | ||||
| 	register["GT"] = arm64.COND_GT | ||||
| 	register["LE"] = arm64.COND_LE | ||||
| 	register["AL"] = arm64.COND_AL | ||||
| 	register["NV"] = arm64.COND_NV | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 	register["SP"] = RSP | ||||
| 	// Avoid unintentionally clobbering g using R28. | ||||
| 	delete(register, "R28") | ||||
| 	register["g"] = arm64.REG_R28 | ||||
| 	registerPrefix := map[string]bool{ | ||||
| 		"F": true, | ||||
| 		"R": true, | ||||
| 		"V": true, | ||||
| 	} | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range arm64.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseARM64 | ||||
| 		} | ||||
| 	} | ||||
| 	// Annoying aliases. | ||||
| 	instructions["B"] = arm64.AB | ||||
| 	instructions["BL"] = arm64.ABL | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       &arm64.Linkarm64, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: registerPrefix, | ||||
| 		RegisterNumber: arm64RegisterNumber, | ||||
| 		IsJump:         jumpArm64, | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func archPPC64(linkArch *obj.LinkArch) *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 	// Create maps for easy lookup of instruction names etc. | ||||
| 	// Note that there is no list of names as there is for x86. | ||||
| 	for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := ppc64.REG_V0; i <= ppc64.REG_V31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := ppc64.REG_VS0; i <= ppc64.REG_VS63; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	register["CR"] = ppc64.REG_CR | ||||
| 	register["XER"] = ppc64.REG_XER | ||||
| 	register["LR"] = ppc64.REG_LR | ||||
| 	register["CTR"] = ppc64.REG_CTR | ||||
| 	register["FPSCR"] = ppc64.REG_FPSCR | ||||
| 	register["MSR"] = ppc64.REG_MSR | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 	// Avoid unintentionally clobbering g using R30. | ||||
| 	delete(register, "R30") | ||||
| 	register["g"] = ppc64.REG_R30 | ||||
| 	registerPrefix := map[string]bool{ | ||||
| 		"CR":  true, | ||||
| 		"F":   true, | ||||
| 		"R":   true, | ||||
| 		"SPR": true, | ||||
| 	} | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range ppc64.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABasePPC64 | ||||
| 		} | ||||
| 	} | ||||
| 	// Annoying aliases. | ||||
| 	instructions["BR"] = ppc64.ABR | ||||
| 	instructions["BL"] = ppc64.ABL | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       linkArch, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: registerPrefix, | ||||
| 		RegisterNumber: ppc64RegisterNumber, | ||||
| 		IsJump:         jumpPPC64, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func archMips(linkArch *obj.LinkArch) *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 	// Create maps for easy lookup of instruction names etc. | ||||
| 	// Note that there is no list of names as there is for x86. | ||||
| 	for i := mips.REG_R0; i <= mips.REG_R31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 
 | ||||
| 	for i := mips.REG_F0; i <= mips.REG_F31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := mips.REG_M0; i <= mips.REG_M31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	register["HI"] = mips.REG_HI | ||||
| 	register["LO"] = mips.REG_LO | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 	// Avoid unintentionally clobbering g using R30. | ||||
| 	delete(register, "R30") | ||||
| 	register["g"] = mips.REG_R30 | ||||
| 
 | ||||
| 	registerPrefix := map[string]bool{ | ||||
| 		"F":   true, | ||||
| 		"FCR": true, | ||||
| 		"M":   true, | ||||
| 		"R":   true, | ||||
| 	} | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range mips.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseMIPS | ||||
| 		} | ||||
| 	} | ||||
| 	// Annoying alias. | ||||
| 	instructions["JAL"] = mips.AJAL | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       linkArch, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: registerPrefix, | ||||
| 		RegisterNumber: mipsRegisterNumber, | ||||
| 		IsJump:         jumpMIPS, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func archMips64(linkArch *obj.LinkArch) *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 	// Create maps for easy lookup of instruction names etc. | ||||
| 	// Note that there is no list of names as there is for x86. | ||||
| 	for i := mips.REG_R0; i <= mips.REG_R31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := mips.REG_F0; i <= mips.REG_F31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := mips.REG_M0; i <= mips.REG_M31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := mips.REG_W0; i <= mips.REG_W31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	register["HI"] = mips.REG_HI | ||||
| 	register["LO"] = mips.REG_LO | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 	// Avoid unintentionally clobbering g using R30. | ||||
| 	delete(register, "R30") | ||||
| 	register["g"] = mips.REG_R30 | ||||
| 	// Avoid unintentionally clobbering RSB using R28. | ||||
| 	delete(register, "R28") | ||||
| 	register["RSB"] = mips.REG_R28 | ||||
| 	registerPrefix := map[string]bool{ | ||||
| 		"F":   true, | ||||
| 		"FCR": true, | ||||
| 		"M":   true, | ||||
| 		"R":   true, | ||||
| 		"W":   true, | ||||
| 	} | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range mips.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseMIPS | ||||
| 		} | ||||
| 	} | ||||
| 	// Annoying alias. | ||||
| 	instructions["JAL"] = mips.AJAL | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       linkArch, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: registerPrefix, | ||||
| 		RegisterNumber: mipsRegisterNumber, | ||||
| 		IsJump:         jumpMIPS, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func archRISCV64() *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 
 | ||||
| 	// Standard register names. | ||||
| 	for i := riscv.REG_X0; i <= riscv.REG_X31; i++ { | ||||
| 		name := fmt.Sprintf("X%d", i-riscv.REG_X0) | ||||
| 		register[name] = int16(i) | ||||
| 	} | ||||
| 	for i := riscv.REG_F0; i <= riscv.REG_F31; i++ { | ||||
| 		name := fmt.Sprintf("F%d", i-riscv.REG_F0) | ||||
| 		register[name] = int16(i) | ||||
| 	} | ||||
| 
 | ||||
| 	// General registers with ABI names. | ||||
| 	register["ZERO"] = riscv.REG_ZERO | ||||
| 	register["RA"] = riscv.REG_RA | ||||
| 	register["SP"] = riscv.REG_SP | ||||
| 	register["GP"] = riscv.REG_GP | ||||
| 	register["TP"] = riscv.REG_TP | ||||
| 	register["T0"] = riscv.REG_T0 | ||||
| 	register["T1"] = riscv.REG_T1 | ||||
| 	register["T2"] = riscv.REG_T2 | ||||
| 	register["S0"] = riscv.REG_S0 | ||||
| 	register["S1"] = riscv.REG_S1 | ||||
| 	register["A0"] = riscv.REG_A0 | ||||
| 	register["A1"] = riscv.REG_A1 | ||||
| 	register["A2"] = riscv.REG_A2 | ||||
| 	register["A3"] = riscv.REG_A3 | ||||
| 	register["A4"] = riscv.REG_A4 | ||||
| 	register["A5"] = riscv.REG_A5 | ||||
| 	register["A6"] = riscv.REG_A6 | ||||
| 	register["A7"] = riscv.REG_A7 | ||||
| 	register["S2"] = riscv.REG_S2 | ||||
| 	register["S3"] = riscv.REG_S3 | ||||
| 	register["S4"] = riscv.REG_S4 | ||||
| 	register["S5"] = riscv.REG_S5 | ||||
| 	register["S6"] = riscv.REG_S6 | ||||
| 	register["S7"] = riscv.REG_S7 | ||||
| 	register["S8"] = riscv.REG_S8 | ||||
| 	register["S9"] = riscv.REG_S9 | ||||
| 	register["S10"] = riscv.REG_S10 | ||||
| 	register["S11"] = riscv.REG_S11 | ||||
| 	register["T3"] = riscv.REG_T3 | ||||
| 	register["T4"] = riscv.REG_T4 | ||||
| 	register["T5"] = riscv.REG_T5 | ||||
| 	register["T6"] = riscv.REG_T6 | ||||
| 
 | ||||
| 	// Go runtime register names. | ||||
| 	register["g"] = riscv.REG_G | ||||
| 	register["CTXT"] = riscv.REG_CTXT | ||||
| 	register["TMP"] = riscv.REG_TMP | ||||
| 
 | ||||
| 	// ABI names for floating point register. | ||||
| 	register["FT0"] = riscv.REG_FT0 | ||||
| 	register["FT1"] = riscv.REG_FT1 | ||||
| 	register["FT2"] = riscv.REG_FT2 | ||||
| 	register["FT3"] = riscv.REG_FT3 | ||||
| 	register["FT4"] = riscv.REG_FT4 | ||||
| 	register["FT5"] = riscv.REG_FT5 | ||||
| 	register["FT6"] = riscv.REG_FT6 | ||||
| 	register["FT7"] = riscv.REG_FT7 | ||||
| 	register["FS0"] = riscv.REG_FS0 | ||||
| 	register["FS1"] = riscv.REG_FS1 | ||||
| 	register["FA0"] = riscv.REG_FA0 | ||||
| 	register["FA1"] = riscv.REG_FA1 | ||||
| 	register["FA2"] = riscv.REG_FA2 | ||||
| 	register["FA3"] = riscv.REG_FA3 | ||||
| 	register["FA4"] = riscv.REG_FA4 | ||||
| 	register["FA5"] = riscv.REG_FA5 | ||||
| 	register["FA6"] = riscv.REG_FA6 | ||||
| 	register["FA7"] = riscv.REG_FA7 | ||||
| 	register["FS2"] = riscv.REG_FS2 | ||||
| 	register["FS3"] = riscv.REG_FS3 | ||||
| 	register["FS4"] = riscv.REG_FS4 | ||||
| 	register["FS5"] = riscv.REG_FS5 | ||||
| 	register["FS6"] = riscv.REG_FS6 | ||||
| 	register["FS7"] = riscv.REG_FS7 | ||||
| 	register["FS8"] = riscv.REG_FS8 | ||||
| 	register["FS9"] = riscv.REG_FS9 | ||||
| 	register["FS10"] = riscv.REG_FS10 | ||||
| 	register["FS11"] = riscv.REG_FS11 | ||||
| 	register["FT8"] = riscv.REG_FT8 | ||||
| 	register["FT9"] = riscv.REG_FT9 | ||||
| 	register["FT10"] = riscv.REG_FT10 | ||||
| 	register["FT11"] = riscv.REG_FT11 | ||||
| 
 | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range riscv.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseRISCV | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       &riscv.LinkRISCV64, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: nil, | ||||
| 		RegisterNumber: nilRegisterNumber, | ||||
| 		IsJump:         jumpRISCV, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func archS390x() *Arch { | ||||
| 	register := make(map[string]int16) | ||||
| 	// Create maps for easy lookup of instruction names etc. | ||||
| 	// Note that there is no list of names as there is for x86. | ||||
| 	for i := s390x.REG_R0; i <= s390x.REG_R15; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := s390x.REG_F0; i <= s390x.REG_F15; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := s390x.REG_V0; i <= s390x.REG_V31; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ { | ||||
| 		register[obj.Rconv(i)] = int16(i) | ||||
| 	} | ||||
| 	register["LR"] = s390x.REG_LR | ||||
| 	// Pseudo-registers. | ||||
| 	register["SB"] = RSB | ||||
| 	register["FP"] = RFP | ||||
| 	register["PC"] = RPC | ||||
| 	// Avoid unintentionally clobbering g using R13. | ||||
| 	delete(register, "R13") | ||||
| 	register["g"] = s390x.REG_R13 | ||||
| 	registerPrefix := map[string]bool{ | ||||
| 		"AR": true, | ||||
| 		"F":  true, | ||||
| 		"R":  true, | ||||
| 	} | ||||
| 
 | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range s390x.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseS390X | ||||
| 		} | ||||
| 	} | ||||
| 	// Annoying aliases. | ||||
| 	instructions["BR"] = s390x.ABR | ||||
| 	instructions["BL"] = s390x.ABL | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       &s390x.Links390x, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       register, | ||||
| 		RegisterPrefix: registerPrefix, | ||||
| 		RegisterNumber: s390xRegisterNumber, | ||||
| 		IsJump:         jumpS390x, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func archWasm() *Arch { | ||||
| 	instructions := make(map[string]obj.As) | ||||
| 	for i, s := range obj.Anames { | ||||
| 		instructions[s] = obj.As(i) | ||||
| 	} | ||||
| 	for i, s := range wasm.Anames { | ||||
| 		if obj.As(i) >= obj.A_ARCHSPECIFIC { | ||||
| 			instructions[s] = obj.As(i) + obj.ABaseWasm | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &Arch{ | ||||
| 		LinkArch:       &wasm.Linkwasm, | ||||
| 		Instructions:   instructions, | ||||
| 		Register:       wasm.Register, | ||||
| 		RegisterPrefix: nil, | ||||
| 		RegisterNumber: nilRegisterNumber, | ||||
| 		IsJump:         jumpWasm, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										257
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,257 @@ | |||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // This file encapsulates some of the odd characteristics of the ARM | ||||
| // instruction set, to minimize its interaction with the core of the | ||||
| // assembler. | ||||
| 
 | ||||
| package arch | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/arm" | ||||
| ) | ||||
| 
 | ||||
| var armLS = map[string]uint8{ | ||||
| 	"U":  arm.C_UBIT, | ||||
| 	"S":  arm.C_SBIT, | ||||
| 	"W":  arm.C_WBIT, | ||||
| 	"P":  arm.C_PBIT, | ||||
| 	"PW": arm.C_WBIT | arm.C_PBIT, | ||||
| 	"WP": arm.C_WBIT | arm.C_PBIT, | ||||
| } | ||||
| 
 | ||||
| var armSCOND = map[string]uint8{ | ||||
| 	"EQ":  arm.C_SCOND_EQ, | ||||
| 	"NE":  arm.C_SCOND_NE, | ||||
| 	"CS":  arm.C_SCOND_HS, | ||||
| 	"HS":  arm.C_SCOND_HS, | ||||
| 	"CC":  arm.C_SCOND_LO, | ||||
| 	"LO":  arm.C_SCOND_LO, | ||||
| 	"MI":  arm.C_SCOND_MI, | ||||
| 	"PL":  arm.C_SCOND_PL, | ||||
| 	"VS":  arm.C_SCOND_VS, | ||||
| 	"VC":  arm.C_SCOND_VC, | ||||
| 	"HI":  arm.C_SCOND_HI, | ||||
| 	"LS":  arm.C_SCOND_LS, | ||||
| 	"GE":  arm.C_SCOND_GE, | ||||
| 	"LT":  arm.C_SCOND_LT, | ||||
| 	"GT":  arm.C_SCOND_GT, | ||||
| 	"LE":  arm.C_SCOND_LE, | ||||
| 	"AL":  arm.C_SCOND_NONE, | ||||
| 	"U":   arm.C_UBIT, | ||||
| 	"S":   arm.C_SBIT, | ||||
| 	"W":   arm.C_WBIT, | ||||
| 	"P":   arm.C_PBIT, | ||||
| 	"PW":  arm.C_WBIT | arm.C_PBIT, | ||||
| 	"WP":  arm.C_WBIT | arm.C_PBIT, | ||||
| 	"F":   arm.C_FBIT, | ||||
| 	"IBW": arm.C_WBIT | arm.C_PBIT | arm.C_UBIT, | ||||
| 	"IAW": arm.C_WBIT | arm.C_UBIT, | ||||
| 	"DBW": arm.C_WBIT | arm.C_PBIT, | ||||
| 	"DAW": arm.C_WBIT, | ||||
| 	"IB":  arm.C_PBIT | arm.C_UBIT, | ||||
| 	"IA":  arm.C_UBIT, | ||||
| 	"DB":  arm.C_PBIT, | ||||
| 	"DA":  0, | ||||
| } | ||||
| 
 | ||||
| var armJump = map[string]bool{ | ||||
| 	"B":    true, | ||||
| 	"BL":   true, | ||||
| 	"BX":   true, | ||||
| 	"BEQ":  true, | ||||
| 	"BNE":  true, | ||||
| 	"BCS":  true, | ||||
| 	"BHS":  true, | ||||
| 	"BCC":  true, | ||||
| 	"BLO":  true, | ||||
| 	"BMI":  true, | ||||
| 	"BPL":  true, | ||||
| 	"BVS":  true, | ||||
| 	"BVC":  true, | ||||
| 	"BHI":  true, | ||||
| 	"BLS":  true, | ||||
| 	"BGE":  true, | ||||
| 	"BLT":  true, | ||||
| 	"BGT":  true, | ||||
| 	"BLE":  true, | ||||
| 	"CALL": true, | ||||
| 	"JMP":  true, | ||||
| } | ||||
| 
 | ||||
| func jumpArm(word string) bool { | ||||
| 	return armJump[word] | ||||
| } | ||||
| 
 | ||||
| // IsARMCMP reports whether the op (as defined by an arm.A* constant) is | ||||
| // one of the comparison instructions that require special handling. | ||||
| func IsARMCMP(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm.ACMN, arm.ACMP, arm.ATEQ, arm.ATST: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsARMSTREX reports whether the op (as defined by an arm.A* constant) is | ||||
| // one of the STREX-like instructions that require special handling. | ||||
| func IsARMSTREX(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm.ASTREX, arm.ASTREXD, arm.ASWPW, arm.ASWPBU: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // MCR is not defined by the obj/arm; instead we define it privately here. | ||||
| // It is encoded as an MRC with a bit inside the instruction word, | ||||
| // passed to arch.ARMMRCOffset. | ||||
| const aMCR = arm.ALAST + 1 | ||||
| 
 | ||||
| // IsARMMRC reports whether the op (as defined by an arm.A* constant) is | ||||
| // MRC or MCR | ||||
| func IsARMMRC(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm.AMRC, aMCR: // Note: aMCR is defined in this package. | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsARMBFX reports whether the op (as defined by an arm.A* constant) is one the | ||||
| // BFX-like instructions which are in the form of "op $width, $LSB, (Reg,) Reg". | ||||
| func IsARMBFX(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm.ABFX, arm.ABFXU, arm.ABFC, arm.ABFI: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsARMFloatCmp reports whether the op is a floating comparison instruction. | ||||
| func IsARMFloatCmp(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm.ACMPF, arm.ACMPD: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // ARMMRCOffset implements the peculiar encoding of the MRC and MCR instructions. | ||||
| // The difference between MRC and MCR is represented by a bit high in the word, not | ||||
| // in the usual way by the opcode itself. Asm must use AMRC for both instructions, so | ||||
| // we return the opcode for MRC so that asm doesn't need to import obj/arm. | ||||
| func ARMMRCOffset(op obj.As, cond string, x0, x1, x2, x3, x4, x5 int64) (offset int64, op0 obj.As, ok bool) { | ||||
| 	op1 := int64(0) | ||||
| 	if op == arm.AMRC { | ||||
| 		op1 = 1 | ||||
| 	} | ||||
| 	bits, ok := ParseARMCondition(cond) | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
| 	offset = (0xe << 24) | // opcode | ||||
| 		(op1 << 20) | // MCR/MRC | ||||
| 		((int64(bits) ^ arm.C_SCOND_XOR) << 28) | // scond | ||||
| 		((x0 & 15) << 8) | //coprocessor number | ||||
| 		((x1 & 7) << 21) | // coprocessor operation | ||||
| 		((x2 & 15) << 12) | // ARM register | ||||
| 		((x3 & 15) << 16) | // Crn | ||||
| 		((x4 & 15) << 0) | // Crm | ||||
| 		((x5 & 7) << 5) | // coprocessor information | ||||
| 		(1 << 4) /* must be set */ | ||||
| 	return offset, arm.AMRC, true | ||||
| } | ||||
| 
 | ||||
| // IsARMMULA reports whether the op (as defined by an arm.A* constant) is | ||||
| // MULA, MULS, MMULA, MMULS, MULABB, MULAWB or MULAWT, the 4-operand instructions. | ||||
| func IsARMMULA(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm.AMULA, arm.AMULS, arm.AMMULA, arm.AMMULS, arm.AMULABB, arm.AMULAWB, arm.AMULAWT: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| var bcode = []obj.As{ | ||||
| 	arm.ABEQ, | ||||
| 	arm.ABNE, | ||||
| 	arm.ABCS, | ||||
| 	arm.ABCC, | ||||
| 	arm.ABMI, | ||||
| 	arm.ABPL, | ||||
| 	arm.ABVS, | ||||
| 	arm.ABVC, | ||||
| 	arm.ABHI, | ||||
| 	arm.ABLS, | ||||
| 	arm.ABGE, | ||||
| 	arm.ABLT, | ||||
| 	arm.ABGT, | ||||
| 	arm.ABLE, | ||||
| 	arm.AB, | ||||
| 	obj.ANOP, | ||||
| } | ||||
| 
 | ||||
| // ARMConditionCodes handles the special condition code situation for the ARM. | ||||
| // It returns a boolean to indicate success; failure means cond was unrecognized. | ||||
| func ARMConditionCodes(prog *obj.Prog, cond string) bool { | ||||
| 	if cond == "" { | ||||
| 		return true | ||||
| 	} | ||||
| 	bits, ok := ParseARMCondition(cond) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	/* hack to make B.NE etc. work: turn it into the corresponding conditional */ | ||||
| 	if prog.As == arm.AB { | ||||
| 		prog.As = bcode[(bits^arm.C_SCOND_XOR)&0xf] | ||||
| 		bits = (bits &^ 0xf) | arm.C_SCOND_NONE | ||||
| 	} | ||||
| 	prog.Scond = bits | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // ParseARMCondition parses the conditions attached to an ARM instruction. | ||||
| // The input is a single string consisting of period-separated condition | ||||
| // codes, such as ".P.W". An initial period is ignored. | ||||
| func ParseARMCondition(cond string) (uint8, bool) { | ||||
| 	return parseARMCondition(cond, armLS, armSCOND) | ||||
| } | ||||
| 
 | ||||
| func parseARMCondition(cond string, ls, scond map[string]uint8) (uint8, bool) { | ||||
| 	cond = strings.TrimPrefix(cond, ".") | ||||
| 	if cond == "" { | ||||
| 		return arm.C_SCOND_NONE, true | ||||
| 	} | ||||
| 	names := strings.Split(cond, ".") | ||||
| 	bits := uint8(0) | ||||
| 	for _, name := range names { | ||||
| 		if b, present := ls[name]; present { | ||||
| 			bits |= b | ||||
| 			continue | ||||
| 		} | ||||
| 		if b, present := scond[name]; present { | ||||
| 			bits = (bits &^ arm.C_SCOND) | b | ||||
| 			continue | ||||
| 		} | ||||
| 		return 0, false | ||||
| 	} | ||||
| 	return bits, true | ||||
| } | ||||
| 
 | ||||
| func armRegisterNumber(name string, n int16) (int16, bool) { | ||||
| 	if n < 0 || 15 < n { | ||||
| 		return 0, false | ||||
| 	} | ||||
| 	switch name { | ||||
| 	case "R": | ||||
| 		return arm.REG_R0 + n, true | ||||
| 	case "F": | ||||
| 		return arm.REG_F0 + n, true | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
							
								
								
									
										350
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,350 @@ | |||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // This file encapsulates some of the odd characteristics of the ARM64 | ||||
| // instruction set, to minimize its interaction with the core of the | ||||
| // assembler. | ||||
| 
 | ||||
| package arch | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/arm64" | ||||
| 	"errors" | ||||
| ) | ||||
| 
 | ||||
| var arm64LS = map[string]uint8{ | ||||
| 	"P": arm64.C_XPOST, | ||||
| 	"W": arm64.C_XPRE, | ||||
| } | ||||
| 
 | ||||
| var arm64Jump = map[string]bool{ | ||||
| 	"B":     true, | ||||
| 	"BL":    true, | ||||
| 	"BEQ":   true, | ||||
| 	"BNE":   true, | ||||
| 	"BCS":   true, | ||||
| 	"BHS":   true, | ||||
| 	"BCC":   true, | ||||
| 	"BLO":   true, | ||||
| 	"BMI":   true, | ||||
| 	"BPL":   true, | ||||
| 	"BVS":   true, | ||||
| 	"BVC":   true, | ||||
| 	"BHI":   true, | ||||
| 	"BLS":   true, | ||||
| 	"BGE":   true, | ||||
| 	"BLT":   true, | ||||
| 	"BGT":   true, | ||||
| 	"BLE":   true, | ||||
| 	"CALL":  true, | ||||
| 	"CBZ":   true, | ||||
| 	"CBZW":  true, | ||||
| 	"CBNZ":  true, | ||||
| 	"CBNZW": true, | ||||
| 	"JMP":   true, | ||||
| 	"TBNZ":  true, | ||||
| 	"TBZ":   true, | ||||
| } | ||||
| 
 | ||||
| func jumpArm64(word string) bool { | ||||
| 	return arm64Jump[word] | ||||
| } | ||||
| 
 | ||||
| // IsARM64CMP reports whether the op (as defined by an arm.A* constant) is | ||||
| // one of the comparison instructions that require special handling. | ||||
| func IsARM64CMP(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm64.ACMN, arm64.ACMP, arm64.ATST, | ||||
| 		arm64.ACMNW, arm64.ACMPW, arm64.ATSTW, | ||||
| 		arm64.AFCMPS, arm64.AFCMPD, | ||||
| 		arm64.AFCMPES, arm64.AFCMPED: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsARM64STLXR reports whether the op (as defined by an arm64.A* | ||||
| // constant) is one of the STLXR-like instructions that require special | ||||
| // handling. | ||||
| func IsARM64STLXR(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR, | ||||
| 		arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR, | ||||
| 		arm64.ASTXP, arm64.ASTXPW, arm64.ASTLXP, arm64.ASTLXPW: | ||||
| 		return true | ||||
| 	} | ||||
| 	// atomic instructions | ||||
| 	if arm64.IsAtomicInstruction(op) { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // ARM64Suffix handles the special suffix for the ARM64. | ||||
| // It returns a boolean to indicate success; failure means | ||||
| // cond was unrecognized. | ||||
| func ARM64Suffix(prog *obj.Prog, cond string) bool { | ||||
| 	if cond == "" { | ||||
| 		return true | ||||
| 	} | ||||
| 	bits, ok := parseARM64Suffix(cond) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	prog.Scond = bits | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // parseARM64Suffix parses the suffix attached to an ARM64 instruction. | ||||
| // The input is a single string consisting of period-separated condition | ||||
| // codes, such as ".P.W". An initial period is ignored. | ||||
| func parseARM64Suffix(cond string) (uint8, bool) { | ||||
| 	if cond == "" { | ||||
| 		return 0, true | ||||
| 	} | ||||
| 	return parseARMCondition(cond, arm64LS, nil) | ||||
| } | ||||
| 
 | ||||
| func arm64RegisterNumber(name string, n int16) (int16, bool) { | ||||
| 	switch name { | ||||
| 	case "F": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return arm64.REG_F0 + n, true | ||||
| 		} | ||||
| 	case "R": | ||||
| 		if 0 <= n && n <= 30 { // not 31 | ||||
| 			return arm64.REG_R0 + n, true | ||||
| 		} | ||||
| 	case "V": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return arm64.REG_V0 + n, true | ||||
| 		} | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
| 
 | ||||
| // IsARM64TBL reports whether the op (as defined by an arm64.A* | ||||
| // constant) is one of the table lookup instructions that require special | ||||
| // handling. | ||||
| func IsARM64TBL(op obj.As) bool { | ||||
| 	return op == arm64.AVTBL | ||||
| } | ||||
| 
 | ||||
| // ARM64RegisterExtension parses an ARM64 register with extension or arrangement. | ||||
| func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error { | ||||
| 	Rnum := (reg & 31) + int16(num<<5) | ||||
| 	if isAmount { | ||||
| 		if num < 0 || num > 7 { | ||||
| 			return errors.New("index shift amount is out of range") | ||||
| 		} | ||||
| 	} | ||||
| 	switch ext { | ||||
| 	case "UXTB": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		if a.Type == obj.TYPE_MEM { | ||||
| 			return errors.New("invalid shift for the register offset addressing mode") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_UXTB + Rnum | ||||
| 	case "UXTH": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		if a.Type == obj.TYPE_MEM { | ||||
| 			return errors.New("invalid shift for the register offset addressing mode") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_UXTH + Rnum | ||||
| 	case "UXTW": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		// effective address of memory is a base register value and an offset register value. | ||||
| 		if a.Type == obj.TYPE_MEM { | ||||
| 			a.Index = arm64.REG_UXTW + Rnum | ||||
| 		} else { | ||||
| 			a.Reg = arm64.REG_UXTW + Rnum | ||||
| 		} | ||||
| 	case "UXTX": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		if a.Type == obj.TYPE_MEM { | ||||
| 			return errors.New("invalid shift for the register offset addressing mode") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_UXTX + Rnum | ||||
| 	case "SXTB": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_SXTB + Rnum | ||||
| 	case "SXTH": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		if a.Type == obj.TYPE_MEM { | ||||
| 			return errors.New("invalid shift for the register offset addressing mode") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_SXTH + Rnum | ||||
| 	case "SXTW": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		if a.Type == obj.TYPE_MEM { | ||||
| 			a.Index = arm64.REG_SXTW + Rnum | ||||
| 		} else { | ||||
| 			a.Reg = arm64.REG_SXTW + Rnum | ||||
| 		} | ||||
| 	case "SXTX": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		if a.Type == obj.TYPE_MEM { | ||||
| 			a.Index = arm64.REG_SXTX + Rnum | ||||
| 		} else { | ||||
| 			a.Reg = arm64.REG_SXTX + Rnum | ||||
| 		} | ||||
| 	case "LSL": | ||||
| 		if !isAmount { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Index = arm64.REG_LSL + Rnum | ||||
| 	case "B8": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8B & 15) << 5) | ||||
| 	case "B16": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_16B & 15) << 5) | ||||
| 	case "H4": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4H & 15) << 5) | ||||
| 	case "H8": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8H & 15) << 5) | ||||
| 	case "S2": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2S & 15) << 5) | ||||
| 	case "S4": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4S & 15) << 5) | ||||
| 	case "D1": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1D & 15) << 5) | ||||
| 	case "D2": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2D & 15) << 5) | ||||
| 	case "Q1": | ||||
| 		if isIndex { | ||||
| 			return errors.New("invalid register extension") | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1Q & 15) << 5) | ||||
| 	case "B": | ||||
| 		if !isIndex { | ||||
| 			return nil | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_B & 15) << 5) | ||||
| 		a.Index = num | ||||
| 	case "H": | ||||
| 		if !isIndex { | ||||
| 			return nil | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_H & 15) << 5) | ||||
| 		a.Index = num | ||||
| 	case "S": | ||||
| 		if !isIndex { | ||||
| 			return nil | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_S & 15) << 5) | ||||
| 		a.Index = num | ||||
| 	case "D": | ||||
| 		if !isIndex { | ||||
| 			return nil | ||||
| 		} | ||||
| 		a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_D & 15) << 5) | ||||
| 		a.Index = num | ||||
| 	default: | ||||
| 		return errors.New("unsupported register extension type: " + ext) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // ARM64RegisterArrangement parses an ARM64 vector register arrangement. | ||||
| func ARM64RegisterArrangement(reg int16, name, arng string) (int64, error) { | ||||
| 	var curQ, curSize uint16 | ||||
| 	if name[0] != 'V' { | ||||
| 		return 0, errors.New("expect V0 through V31; found: " + name) | ||||
| 	} | ||||
| 	if reg < 0 { | ||||
| 		return 0, errors.New("invalid register number: " + name) | ||||
| 	} | ||||
| 	switch arng { | ||||
| 	case "B8": | ||||
| 		curSize = 0 | ||||
| 		curQ = 0 | ||||
| 	case "B16": | ||||
| 		curSize = 0 | ||||
| 		curQ = 1 | ||||
| 	case "H4": | ||||
| 		curSize = 1 | ||||
| 		curQ = 0 | ||||
| 	case "H8": | ||||
| 		curSize = 1 | ||||
| 		curQ = 1 | ||||
| 	case "S2": | ||||
| 		curSize = 2 | ||||
| 		curQ = 0 | ||||
| 	case "S4": | ||||
| 		curSize = 2 | ||||
| 		curQ = 1 | ||||
| 	case "D1": | ||||
| 		curSize = 3 | ||||
| 		curQ = 0 | ||||
| 	case "D2": | ||||
| 		curSize = 3 | ||||
| 		curQ = 1 | ||||
| 	default: | ||||
| 		return 0, errors.New("invalid arrangement in ARM64 register list") | ||||
| 	} | ||||
| 	return (int64(curQ) & 1 << 30) | (int64(curSize&3) << 10), nil | ||||
| } | ||||
| 
 | ||||
| // ARM64RegisterListOffset generates offset encoding according to AArch64 specification. | ||||
| func ARM64RegisterListOffset(firstReg, regCnt int, arrangement int64) (int64, error) { | ||||
| 	offset := int64(firstReg) | ||||
| 	switch regCnt { | ||||
| 	case 1: | ||||
| 		offset |= 0x7 << 12 | ||||
| 	case 2: | ||||
| 		offset |= 0xa << 12 | ||||
| 	case 3: | ||||
| 		offset |= 0x6 << 12 | ||||
| 	case 4: | ||||
| 		offset |= 0x2 << 12 | ||||
| 	default: | ||||
| 		return 0, errors.New("invalid register numbers in ARM64 register list") | ||||
| 	} | ||||
| 	offset |= arrangement | ||||
| 	// arm64 uses the 60th bit to differentiate from other archs | ||||
| 	// For more details, refer to: obj/arm64/list7.go | ||||
| 	offset |= 1 << 60 | ||||
| 	return offset, nil | ||||
| } | ||||
							
								
								
									
										72
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/mips.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/mips.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,72 @@ | |||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // This file encapsulates some of the odd characteristics of the | ||||
| // MIPS (MIPS64) instruction set, to minimize its interaction | ||||
| // with the core of the assembler. | ||||
| 
 | ||||
| package arch | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/mips" | ||||
| ) | ||||
| 
 | ||||
| func jumpMIPS(word string) bool { | ||||
| 	switch word { | ||||
| 	case "BEQ", "BFPF", "BFPT", "BGEZ", "BGEZAL", "BGTZ", "BLEZ", "BLTZ", "BLTZAL", "BNE", "JMP", "JAL", "CALL": | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsMIPSCMP reports whether the op (as defined by an mips.A* constant) is | ||||
| // one of the CMP instructions that require special handling. | ||||
| func IsMIPSCMP(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case mips.ACMPEQF, mips.ACMPEQD, mips.ACMPGEF, mips.ACMPGED, | ||||
| 		mips.ACMPGTF, mips.ACMPGTD: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsMIPSMUL reports whether the op (as defined by an mips.A* constant) is | ||||
| // one of the MUL/DIV/REM/MADD/MSUB instructions that require special handling. | ||||
| func IsMIPSMUL(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case mips.AMUL, mips.AMULU, mips.AMULV, mips.AMULVU, | ||||
| 		mips.ADIV, mips.ADIVU, mips.ADIVV, mips.ADIVVU, | ||||
| 		mips.AREM, mips.AREMU, mips.AREMV, mips.AREMVU, | ||||
| 		mips.AMADD, mips.AMSUB: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func mipsRegisterNumber(name string, n int16) (int16, bool) { | ||||
| 	switch name { | ||||
| 	case "F": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return mips.REG_F0 + n, true | ||||
| 		} | ||||
| 	case "FCR": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return mips.REG_FCR0 + n, true | ||||
| 		} | ||||
| 	case "M": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return mips.REG_M0 + n, true | ||||
| 		} | ||||
| 	case "R": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return mips.REG_R0 + n, true | ||||
| 		} | ||||
| 	case "W": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return mips.REG_W0 + n, true | ||||
| 		} | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
							
								
								
									
										102
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/ppc64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/ppc64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | |||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // This file encapsulates some of the odd characteristics of the | ||||
| // 64-bit PowerPC (PPC64) instruction set, to minimize its interaction | ||||
| // with the core of the assembler. | ||||
| 
 | ||||
| package arch | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/ppc64" | ||||
| ) | ||||
| 
 | ||||
| func jumpPPC64(word string) bool { | ||||
| 	switch word { | ||||
| 	case "BC", "BCL", "BEQ", "BGE", "BGT", "BL", "BLE", "BLT", "BNE", "BR", "BVC", "BVS", "CALL", "JMP": | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsPPC64RLD reports whether the op (as defined by an ppc64.A* constant) is | ||||
| // one of the RLD-like instructions that require special handling. | ||||
| // The FMADD-like instructions behave similarly. | ||||
| func IsPPC64RLD(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case ppc64.ARLDC, ppc64.ARLDCCC, ppc64.ARLDCL, ppc64.ARLDCLCC, | ||||
| 		ppc64.ARLDCR, ppc64.ARLDCRCC, ppc64.ARLDMI, ppc64.ARLDMICC, | ||||
| 		ppc64.ARLWMI, ppc64.ARLWMICC, ppc64.ARLWNM, ppc64.ARLWNMCC: | ||||
| 		return true | ||||
| 	case ppc64.AFMADD, ppc64.AFMADDCC, ppc64.AFMADDS, ppc64.AFMADDSCC, | ||||
| 		ppc64.AFMSUB, ppc64.AFMSUBCC, ppc64.AFMSUBS, ppc64.AFMSUBSCC, | ||||
| 		ppc64.AFNMADD, ppc64.AFNMADDCC, ppc64.AFNMADDS, ppc64.AFNMADDSCC, | ||||
| 		ppc64.AFNMSUB, ppc64.AFNMSUBCC, ppc64.AFNMSUBS, ppc64.AFNMSUBSCC: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func IsPPC64ISEL(op obj.As) bool { | ||||
| 	return op == ppc64.AISEL | ||||
| } | ||||
| 
 | ||||
| // IsPPC64CMP reports whether the op (as defined by an ppc64.A* constant) is | ||||
| // one of the CMP instructions that require special handling. | ||||
| func IsPPC64CMP(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case ppc64.ACMP, ppc64.ACMPU, ppc64.ACMPW, ppc64.ACMPWU, ppc64.AFCMPU: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsPPC64NEG reports whether the op (as defined by an ppc64.A* constant) is | ||||
| // one of the NEG-like instructions that require special handling. | ||||
| func IsPPC64NEG(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case ppc64.AADDMECC, ppc64.AADDMEVCC, ppc64.AADDMEV, ppc64.AADDME, | ||||
| 		ppc64.AADDZECC, ppc64.AADDZEVCC, ppc64.AADDZEV, ppc64.AADDZE, | ||||
| 		ppc64.ACNTLZDCC, ppc64.ACNTLZD, ppc64.ACNTLZWCC, ppc64.ACNTLZW, | ||||
| 		ppc64.AEXTSBCC, ppc64.AEXTSB, ppc64.AEXTSHCC, ppc64.AEXTSH, | ||||
| 		ppc64.AEXTSWCC, ppc64.AEXTSW, ppc64.ANEGCC, ppc64.ANEGVCC, | ||||
| 		ppc64.ANEGV, ppc64.ANEG, ppc64.ASLBMFEE, ppc64.ASLBMFEV, | ||||
| 		ppc64.ASLBMTE, ppc64.ASUBMECC, ppc64.ASUBMEVCC, ppc64.ASUBMEV, | ||||
| 		ppc64.ASUBME, ppc64.ASUBZECC, ppc64.ASUBZEVCC, ppc64.ASUBZEV, | ||||
| 		ppc64.ASUBZE: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func ppc64RegisterNumber(name string, n int16) (int16, bool) { | ||||
| 	switch name { | ||||
| 	case "CR": | ||||
| 		if 0 <= n && n <= 7 { | ||||
| 			return ppc64.REG_CR0 + n, true | ||||
| 		} | ||||
| 	case "VS": | ||||
| 		if 0 <= n && n <= 63 { | ||||
| 			return ppc64.REG_VS0 + n, true | ||||
| 		} | ||||
| 	case "V": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return ppc64.REG_V0 + n, true | ||||
| 		} | ||||
| 	case "F": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return ppc64.REG_F0 + n, true | ||||
| 		} | ||||
| 	case "R": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return ppc64.REG_R0 + n, true | ||||
| 		} | ||||
| 	case "SPR": | ||||
| 		if 0 <= n && n <= 1024 { | ||||
| 			return ppc64.REG_SPR0 + n, true | ||||
| 		} | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
							
								
								
									
										28
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/riscv64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/riscv64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| // Copyright 2020 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // This file encapsulates some of the odd characteristics of the RISCV64 | ||||
| // instruction set, to minimize its interaction with the core of the | ||||
| // assembler. | ||||
| 
 | ||||
| package arch | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj" | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/riscv" | ||||
| ) | ||||
| 
 | ||||
| // IsRISCV64AMO reports whether the op (as defined by a riscv.A* | ||||
| // constant) is one of the AMO instructions that requires special | ||||
| // handling. | ||||
| func IsRISCV64AMO(op obj.As) bool { | ||||
| 	switch op { | ||||
| 	case riscv.ASCW, riscv.ASCD, riscv.AAMOSWAPW, riscv.AAMOSWAPD, riscv.AAMOADDW, riscv.AAMOADDD, | ||||
| 		riscv.AAMOANDW, riscv.AAMOANDD, riscv.AAMOORW, riscv.AAMOORD, riscv.AAMOXORW, riscv.AAMOXORD, | ||||
| 		riscv.AAMOMINW, riscv.AAMOMIND, riscv.AAMOMINUW, riscv.AAMOMINUD, | ||||
| 		riscv.AAMOMAXW, riscv.AAMOMAXD, riscv.AAMOMAXUW, riscv.AAMOMAXUD: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
							
								
								
									
										81
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/s390x.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/twitchyliquid64/golang-asm/asm/arch/s390x.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,81 @@ | |||
| // Copyright 2016 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // This file encapsulates some of the odd characteristics of the | ||||
| // s390x instruction set, to minimize its interaction | ||||
| // with the core of the assembler. | ||||
| 
 | ||||
| package arch | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/twitchyliquid64/golang-asm/obj/s390x" | ||||
| ) | ||||
| 
 | ||||
| func jumpS390x(word string) bool { | ||||
| 	switch word { | ||||
| 	case "BRC", | ||||
| 		"BC", | ||||
| 		"BCL", | ||||
| 		"BEQ", | ||||
| 		"BGE", | ||||
| 		"BGT", | ||||
| 		"BL", | ||||
| 		"BLE", | ||||
| 		"BLEU", | ||||
| 		"BLT", | ||||
| 		"BLTU", | ||||
| 		"BNE", | ||||
| 		"BR", | ||||
| 		"BVC", | ||||
| 		"BVS", | ||||
| 		"BRCT", | ||||
| 		"BRCTG", | ||||
| 		"CMPBEQ", | ||||
| 		"CMPBGE", | ||||
| 		"CMPBGT", | ||||
| 		"CMPBLE", | ||||
| 		"CMPBLT", | ||||
| 		"CMPBNE", | ||||
| 		"CMPUBEQ", | ||||
| 		"CMPUBGE", | ||||
| 		"CMPUBGT", | ||||
| 		"CMPUBLE", | ||||
| 		"CMPUBLT", | ||||
| 		"CMPUBNE", | ||||
| 		"CRJ", | ||||
| 		"CGRJ", | ||||
| 		"CLRJ", | ||||
| 		"CLGRJ", | ||||
| 		"CIJ", | ||||
| 		"CGIJ", | ||||
| 		"CLIJ", | ||||
| 		"CLGIJ", | ||||
| 		"CALL", | ||||
| 		"JMP": | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func s390xRegisterNumber(name string, n int16) (int16, bool) { | ||||
| 	switch name { | ||||
| 	case "AR": | ||||
| 		if 0 <= n && n <= 15 { | ||||
| 			return s390x.REG_AR0 + n, true | ||||
| 		} | ||||
| 	case "F": | ||||
| 		if 0 <= n && n <= 15 { | ||||
| 			return s390x.REG_F0 + n, true | ||||
| 		} | ||||
| 	case "R": | ||||
| 		if 0 <= n && n <= 15 { | ||||
| 			return s390x.REG_R0 + n, true | ||||
| 		} | ||||
| 	case "V": | ||||
| 		if 0 <= n && n <= 31 { | ||||
| 			return s390x.REG_V0 + n, true | ||||
| 		} | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue