github.com/zxy12/go_duplicate_1_12@v0.0.0-20200217043740-b1636fc0368b/src/cmd/asm/internal/arch/arch.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package arch 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  	"log"
    19  	"strings"
    20  )
    21  
    22  // Pseudo-registers whose names are the constant name without the leading R.
    23  const (
    24  	RFP = -(iota + 1)
    25  	RSB
    26  	RSP
    27  	RPC
    28  )
    29  
    30  // Arch wraps the link architecture object with more architecture-specific information.
    31  type Arch struct {
    32  	*obj.LinkArch
    33  	// Map of instruction names to enumeration.
    34  	Instructions map[string]obj.As
    35  	// Map of register names to enumeration.
    36  	Register map[string]int16
    37  	// Table of register prefix names. These are things like R for R(0) and SPR for SPR(268).
    38  	RegisterPrefix map[string]bool
    39  	// RegisterNumber converts R(10) into arm.REG_R10.
    40  	RegisterNumber func(string, int16) (int16, bool)
    41  	// Instruction is a jump.
    42  	IsJump func(word string) bool
    43  }
    44  
    45  // nilRegisterNumber is the register number function for architectures
    46  // that do not accept the R(N) notation. It always returns failure.
    47  func nilRegisterNumber(name string, n int16) (int16, bool) {
    48  	return 0, false
    49  }
    50  
    51  func jumpX86(word string) bool {
    52  	return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
    53  }
    54  
    55  // Set configures the architecture specified by GOARCH and returns its representation.
    56  // It returns nil if GOARCH is not recognized.
    57  func Set(GOARCH string) *Arch {
    58  	log.Printf("Arch set GOARCH[%s]\n", GOARCH)
    59  	switch GOARCH {
    60  	case "amd64":
    61  		return archX86(&x86.Linkamd64)
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  func archX86(linkArch *obj.LinkArch) *Arch {
    68  	register := make(map[string]int16)
    69  	// Create maps for easy lookup of instruction names etc.
    70  	for i, s := range x86.Register {
    71  		register[s] = int16(i + x86.REG_AL)
    72  	}
    73  	// Pseudo-registers.
    74  	register["SB"] = RSB
    75  	register["FP"] = RFP
    76  	register["PC"] = RPC
    77  	// Register prefix not used on this architecture.
    78  
    79  	instructions := make(map[string]obj.As)
    80  	for i, s := range obj.Anames {
    81  		instructions[s] = obj.As(i)
    82  	}
    83  	for i, s := range x86.Anames {
    84  		if obj.As(i) >= obj.A_ARCHSPECIFIC {
    85  			instructions[s] = obj.As(i) + obj.ABaseAMD64
    86  		}
    87  	}
    88  	// Annoying aliases.
    89  	instructions["JA"] = x86.AJHI   /* alternate */
    90  	instructions["JAE"] = x86.AJCC  /* alternate */
    91  	instructions["JB"] = x86.AJCS   /* alternate */
    92  	instructions["JBE"] = x86.AJLS  /* alternate */
    93  	instructions["JC"] = x86.AJCS   /* alternate */
    94  	instructions["JCC"] = x86.AJCC  /* carry clear (CF = 0) */
    95  	instructions["JCS"] = x86.AJCS  /* carry set (CF = 1) */
    96  	instructions["JE"] = x86.AJEQ   /* alternate */
    97  	instructions["JEQ"] = x86.AJEQ  /* equal (ZF = 1) */
    98  	instructions["JG"] = x86.AJGT   /* alternate */
    99  	instructions["JGE"] = x86.AJGE  /* greater than or equal (signed) (SF = OF) */
   100  	instructions["JGT"] = x86.AJGT  /* greater than (signed) (ZF = 0 && SF = OF) */
   101  	instructions["JHI"] = x86.AJHI  /* higher (unsigned) (CF = 0 && ZF = 0) */
   102  	instructions["JHS"] = x86.AJCC  /* alternate */
   103  	instructions["JL"] = x86.AJLT   /* alternate */
   104  	instructions["JLE"] = x86.AJLE  /* less than or equal (signed) (ZF = 1 || SF != OF) */
   105  	instructions["JLO"] = x86.AJCS  /* alternate */
   106  	instructions["JLS"] = x86.AJLS  /* lower or same (unsigned) (CF = 1 || ZF = 1) */
   107  	instructions["JLT"] = x86.AJLT  /* less than (signed) (SF != OF) */
   108  	instructions["JMI"] = x86.AJMI  /* negative (minus) (SF = 1) */
   109  	instructions["JNA"] = x86.AJLS  /* alternate */
   110  	instructions["JNAE"] = x86.AJCS /* alternate */
   111  	instructions["JNB"] = x86.AJCC  /* alternate */
   112  	instructions["JNBE"] = x86.AJHI /* alternate */
   113  	instructions["JNC"] = x86.AJCC  /* alternate */
   114  	instructions["JNE"] = x86.AJNE  /* not equal (ZF = 0) */
   115  	instructions["JNG"] = x86.AJLE  /* alternate */
   116  	instructions["JNGE"] = x86.AJLT /* alternate */
   117  	instructions["JNL"] = x86.AJGE  /* alternate */
   118  	instructions["JNLE"] = x86.AJGT /* alternate */
   119  	instructions["JNO"] = x86.AJOC  /* alternate */
   120  	instructions["JNP"] = x86.AJPC  /* alternate */
   121  	instructions["JNS"] = x86.AJPL  /* alternate */
   122  	instructions["JNZ"] = x86.AJNE  /* alternate */
   123  	instructions["JO"] = x86.AJOS   /* alternate */
   124  	instructions["JOC"] = x86.AJOC  /* overflow clear (OF = 0) */
   125  	instructions["JOS"] = x86.AJOS  /* overflow set (OF = 1) */
   126  	instructions["JP"] = x86.AJPS   /* alternate */
   127  	instructions["JPC"] = x86.AJPC  /* parity clear (PF = 0) */
   128  	instructions["JPE"] = x86.AJPS  /* alternate */
   129  	instructions["JPL"] = x86.AJPL  /* non-negative (plus) (SF = 0) */
   130  	instructions["JPO"] = x86.AJPC  /* alternate */
   131  	instructions["JPS"] = x86.AJPS  /* parity set (PF = 1) */
   132  	instructions["JS"] = x86.AJMI   /* alternate */
   133  	instructions["JZ"] = x86.AJEQ   /* alternate */
   134  	instructions["MASKMOVDQU"] = x86.AMASKMOVOU
   135  	instructions["MOVD"] = x86.AMOVQ
   136  	instructions["MOVDQ2Q"] = x86.AMOVQ
   137  	instructions["MOVNTDQ"] = x86.AMOVNTO
   138  	instructions["MOVOA"] = x86.AMOVO
   139  	instructions["PSLLDQ"] = x86.APSLLO
   140  	instructions["PSRLDQ"] = x86.APSRLO
   141  	instructions["PADDD"] = x86.APADDL
   142  
   143  	return &Arch{
   144  		LinkArch:       linkArch,
   145  		Instructions:   instructions,
   146  		Register:       register,
   147  		RegisterPrefix: nil,
   148  		RegisterNumber: nilRegisterNumber,
   149  		IsJump:         jumpX86,
   150  	}
   151  }