1// Copyright 2022 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 6// Loong64 (LoongArch64) instruction set, to minimize its interaction 7// with the core of the assembler. 8 9package arch 10 11import ( 12 "cmd/internal/obj" 13 "cmd/internal/obj/loong64" 14) 15 16func jumpLoong64(word string) bool { 17 switch word { 18 case "BEQ", "BFPF", "BFPT", "BLTZ", "BGEZ", "BLEZ", "BGTZ", "BLT", "BLTU", "JIRL", "BNE", "BGE", "BGEU", "JMP", "JAL", "CALL": 19 return true 20 } 21 return false 22} 23 24// IsLoong64CMP reports whether the op (as defined by an loong64.A* constant) is 25// one of the CMP instructions that require special handling. 26func IsLoong64CMP(op obj.As) bool { 27 switch op { 28 case loong64.ACMPEQF, loong64.ACMPEQD, loong64.ACMPGEF, loong64.ACMPGED, 29 loong64.ACMPGTF, loong64.ACMPGTD: 30 return true 31 } 32 return false 33} 34 35// IsLoong64MUL reports whether the op (as defined by an loong64.A* constant) is 36// one of the MUL/DIV/REM instructions that require special handling. 37func IsLoong64MUL(op obj.As) bool { 38 switch op { 39 case loong64.AMUL, loong64.AMULU, loong64.AMULV, loong64.AMULVU, 40 loong64.ADIV, loong64.ADIVU, loong64.ADIVV, loong64.ADIVVU, 41 loong64.AREM, loong64.AREMU, loong64.AREMV, loong64.AREMVU: 42 return true 43 } 44 return false 45} 46 47// IsLoong64RDTIME reports whether the op (as defined by an loong64.A* 48// constant) is one of the RDTIMELW/RDTIMEHW/RDTIMED instructions that 49// require special handling. 50func IsLoong64RDTIME(op obj.As) bool { 51 switch op { 52 case loong64.ARDTIMELW, loong64.ARDTIMEHW, loong64.ARDTIMED: 53 return true 54 } 55 return false 56} 57 58func IsLoong64AMO(op obj.As) bool { 59 return loong64.IsAtomicInst(op) 60} 61 62func loong64RegisterNumber(name string, n int16) (int16, bool) { 63 switch name { 64 case "F": 65 if 0 <= n && n <= 31 { 66 return loong64.REG_F0 + n, true 67 } 68 case "FCSR": 69 if 0 <= n && n <= 31 { 70 return loong64.REG_FCSR0 + n, true 71 } 72 case "FCC": 73 if 0 <= n && n <= 31 { 74 return loong64.REG_FCC0 + n, true 75 } 76 case "R": 77 if 0 <= n && n <= 31 { 78 return loong64.REG_R0 + n, true 79 } 80 } 81 return 0, false 82} 83