| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // This file encapsulates some of the odd characteristics of the ARM64 |
| // instruction set, to minimize its interaction with the core of the |
| // assembler. |
| |
| package arch |
| |
| import ( |
| "cmd/internal/obj" |
| "cmd/internal/obj/arm64" |
| ) |
| |
| var arm64LS = map[string]uint8{ |
| "P": arm64.C_XPOST, |
| "W": arm64.C_XPRE, |
| } |
| |
| var arm64Jump = map[string]bool{ |
| "B": true, |
| "BL": true, |
| "BEQ": true, |
| "BNE": true, |
| "BCS": true, |
| "BHS": true, |
| "BCC": true, |
| "BLO": true, |
| "BMI": true, |
| "BPL": true, |
| "BVS": true, |
| "BVC": true, |
| "BHI": true, |
| "BLS": true, |
| "BGE": true, |
| "BLT": true, |
| "BGT": true, |
| "BLE": true, |
| "CALL": true, |
| "CBZ": true, |
| "CBZW": true, |
| "CBNZ": true, |
| "CBNZW": true, |
| "JMP": true, |
| } |
| |
| func jumpArm64(word string) bool { |
| return arm64Jump[word] |
| } |
| |
| // IsARM64CMP reports whether the op (as defined by an arm.A* constant) is |
| // one of the comparison instructions that require special handling. |
| func IsARM64CMP(op obj.As) bool { |
| switch op { |
| case arm64.ACMN, arm64.ACMP, arm64.ATST, |
| arm64.ACMNW, arm64.ACMPW, arm64.ATSTW: |
| return true |
| } |
| return false |
| } |
| |
| // IsARM64STLXR reports whether the op (as defined by an arm64.A* |
| // constant) is one of the STLXR-like instructions that require special |
| // handling. |
| func IsARM64STLXR(op obj.As) bool { |
| switch op { |
| case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR: |
| return true |
| } |
| return false |
| } |
| |
| // ARM64Suffix handles the special suffix for the ARM64. |
| // It returns a boolean to indicate success; failure means |
| // cond was unrecognized. |
| func ARM64Suffix(prog *obj.Prog, cond string) bool { |
| if cond == "" { |
| return true |
| } |
| bits, ok := ParseARM64Suffix(cond) |
| if !ok { |
| return false |
| } |
| prog.Scond = bits |
| return true |
| } |
| |
| // ParseARM64Suffix parses the suffix attached to an ARM64 instruction. |
| // The input is a single string consisting of period-separated condition |
| // codes, such as ".P.W". An initial period is ignored. |
| func ParseARM64Suffix(cond string) (uint8, bool) { |
| if cond == "" { |
| return 0, true |
| } |
| return parseARMCondition(cond, arm64LS, nil) |
| } |
| |
| func arm64RegisterNumber(name string, n int16) (int16, bool) { |
| switch name { |
| case "F": |
| if 0 <= n && n <= 31 { |
| return arm64.REG_F0 + n, true |
| } |
| case "R": |
| if 0 <= n && n <= 30 { // not 31 |
| return arm64.REG_R0 + n, true |
| } |
| case "V": |
| if 0 <= n && n <= 31 { |
| return arm64.REG_V0 + n, true |
| } |
| } |
| return 0, false |
| } |