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