Home | History | Annotate | Download | only in arch
      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 }
     47 
     48 func jumpArm64(word string) bool {
     49 	return arm64Jump[word]
     50 }
     51 
     52 // IsARM64CMP reports whether the op (as defined by an arm.A* constant) is
     53 // one of the comparison instructions that require special handling.
     54 func IsARM64CMP(op obj.As) bool {
     55 	switch op {
     56 	case arm64.ACMN, arm64.ACMP, arm64.ATST,
     57 		arm64.ACMNW, arm64.ACMPW, arm64.ATSTW:
     58 		return true
     59 	}
     60 	return false
     61 }
     62 
     63 // IsARM64STLXR reports whether the op (as defined by an arm64.A*
     64 // constant) is one of the STLXR-like instructions that require special
     65 // handling.
     66 func IsARM64STLXR(op obj.As) bool {
     67 	switch op {
     68 	case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR:
     69 		return true
     70 	}
     71 	return false
     72 }
     73 
     74 // ARM64Suffix handles the special suffix for the ARM64.
     75 // It returns a boolean to indicate success; failure means
     76 // cond was unrecognized.
     77 func ARM64Suffix(prog *obj.Prog, cond string) bool {
     78 	if cond == "" {
     79 		return true
     80 	}
     81 	bits, ok := ParseARM64Suffix(cond)
     82 	if !ok {
     83 		return false
     84 	}
     85 	prog.Scond = bits
     86 	return true
     87 }
     88 
     89 // ParseARM64Suffix parses the suffix attached to an ARM64 instruction.
     90 // The input is a single string consisting of period-separated condition
     91 // codes, such as ".P.W". An initial period is ignored.
     92 func ParseARM64Suffix(cond string) (uint8, bool) {
     93 	if cond == "" {
     94 		return 0, true
     95 	}
     96 	return parseARMCondition(cond, arm64LS, nil)
     97 }
     98 
     99 func arm64RegisterNumber(name string, n int16) (int16, bool) {
    100 	switch name {
    101 	case "F":
    102 		if 0 <= n && n <= 31 {
    103 			return arm64.REG_F0 + n, true
    104 		}
    105 	case "R":
    106 		if 0 <= n && n <= 30 { // not 31
    107 			return arm64.REG_R0 + n, true
    108 		}
    109 	case "V":
    110 		if 0 <= n && n <= 31 {
    111 			return arm64.REG_V0 + n, true
    112 		}
    113 	}
    114 	return 0, false
    115 }
    116