github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/src/cmd/asm/internal/arch/arm64.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  // This file encapsulates some of the odd characteristics of the ARM64
     6  // instruction set, to minimize its interaction with the core of the
     7  // assembler.
     8  
     9  package arch
    10  
    11  import (
    12  	"cmd/internal/obj"
    13  	"cmd/internal/obj/arm64"
    14  )
    15  
    16  var arm64LS = map[string]uint8{
    17  	"P": arm64.C_XPOST,
    18  	"W": arm64.C_XPRE,
    19  }
    20  
    21  var arm64Jump = map[string]bool{
    22  	"B":     true,
    23  	"BL":    true,
    24  	"BEQ":   true,
    25  	"BNE":   true,
    26  	"BCS":   true,
    27  	"BHS":   true,
    28  	"BCC":   true,
    29  	"BLO":   true,
    30  	"BMI":   true,
    31  	"BPL":   true,
    32  	"BVS":   true,
    33  	"BVC":   true,
    34  	"BHI":   true,
    35  	"BLS":   true,
    36  	"BGE":   true,
    37  	"BLT":   true,
    38  	"BGT":   true,
    39  	"BLE":   true,
    40  	"CALL":  true,
    41  	"CBZ":   true,
    42  	"CBZW":  true,
    43  	"CBNZ":  true,
    44  	"CBNZW": true,
    45  	"JMP":   true,
    46  	"TBNZ":  true,
    47  	"TBZ":   true,
    48  }
    49  
    50  func jumpArm64(word string) bool {
    51  	return arm64Jump[word]
    52  }
    53  
    54  // IsARM64CMP reports whether the op (as defined by an arm.A* constant) is
    55  // one of the comparison instructions that require special handling.
    56  func IsARM64CMP(op obj.As) bool {
    57  	switch op {
    58  	case arm64.ACMN, arm64.ACMP, arm64.ATST,
    59  		arm64.ACMNW, arm64.ACMPW, arm64.ATSTW,
    60  		arm64.AFCMPS, arm64.AFCMPD,
    61  		arm64.AFCMPES, arm64.AFCMPED:
    62  		return true
    63  	}
    64  	return false
    65  }
    66  
    67  // IsARM64STLXR reports whether the op (as defined by an arm64.A*
    68  // constant) is one of the STLXR-like instructions that require special
    69  // handling.
    70  func IsARM64STLXR(op obj.As) bool {
    71  	switch op {
    72  	case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR,
    73  		arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR:
    74  		return true
    75  	}
    76  	return false
    77  }
    78  
    79  // ARM64Suffix handles the special suffix for the ARM64.
    80  // It returns a boolean to indicate success; failure means
    81  // cond was unrecognized.
    82  func ARM64Suffix(prog *obj.Prog, cond string) bool {
    83  	if cond == "" {
    84  		return true
    85  	}
    86  	bits, ok := ParseARM64Suffix(cond)
    87  	if !ok {
    88  		return false
    89  	}
    90  	prog.Scond = bits
    91  	return true
    92  }
    93  
    94  // ParseARM64Suffix parses the suffix attached to an ARM64 instruction.
    95  // The input is a single string consisting of period-separated condition
    96  // codes, such as ".P.W". An initial period is ignored.
    97  func ParseARM64Suffix(cond string) (uint8, bool) {
    98  	if cond == "" {
    99  		return 0, true
   100  	}
   101  	return parseARMCondition(cond, arm64LS, nil)
   102  }
   103  
   104  func arm64RegisterNumber(name string, n int16) (int16, bool) {
   105  	switch name {
   106  	case "F":
   107  		if 0 <= n && n <= 31 {
   108  			return arm64.REG_F0 + n, true
   109  		}
   110  	case "R":
   111  		if 0 <= n && n <= 30 { // not 31
   112  			return arm64.REG_R0 + n, true
   113  		}
   114  	case "V":
   115  		if 0 <= n && n <= 31 {
   116  			return arm64.REG_V0 + n, true
   117  		}
   118  	}
   119  	return 0, false
   120  }