// 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 int) 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 int) 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 }