github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/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  		return true
    61  	}
    62  	return false
    63  }
    64  
    65  // IsARM64STLXR reports whether the op (as defined by an arm64.A*
    66  // constant) is one of the STLXR-like instructions that require special
    67  // handling.
    68  func IsARM64STLXR(op obj.As) bool {
    69  	switch op {
    70  	case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR,
    71  		arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR:
    72  		return true
    73  	}
    74  	return false
    75  }
    76  
    77  // ARM64Suffix handles the special suffix for the ARM64.
    78  // It returns a boolean to indicate success; failure means
    79  // cond was unrecognized.
    80  func ARM64Suffix(prog *obj.Prog, cond string) bool {
    81  	if cond == "" {
    82  		return true
    83  	}
    84  	bits, ok := ParseARM64Suffix(cond)
    85  	if !ok {
    86  		return false
    87  	}
    88  	prog.Scond = bits
    89  	return true
    90  }
    91  
    92  // ParseARM64Suffix parses the suffix attached to an ARM64 instruction.
    93  // The input is a single string consisting of period-separated condition
    94  // codes, such as ".P.W". An initial period is ignored.
    95  func ParseARM64Suffix(cond string) (uint8, bool) {
    96  	if cond == "" {
    97  		return 0, true
    98  	}
    99  	return parseARMCondition(cond, arm64LS, nil)
   100  }
   101  
   102  func arm64RegisterNumber(name string, n int16) (int16, bool) {
   103  	switch name {
   104  	case "F":
   105  		if 0 <= n && n <= 31 {
   106  			return arm64.REG_F0 + n, true
   107  		}
   108  	case "R":
   109  		if 0 <= n && n <= 30 { // not 31
   110  			return arm64.REG_R0 + n, true
   111  		}
   112  	case "V":
   113  		if 0 <= n && n <= 31 {
   114  			return arm64.REG_V0 + n, true
   115  		}
   116  	}
   117  	return 0, false
   118  }