blob: cb9c03fd4f068d10b12f1291087eebfff20a978d [file] [edit]
// Copyright 2022 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.
package loong64
import (
"cmd/internal/obj"
)
//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p loong64
const (
NSNAME = 8
NSYM = 50
NREG = 32 // number of general registers
NFREG = 32 // number of floating point registers
NVREG = 32 // number of LSX registers
NXREG = 32 // number of LASX registers
)
const (
REG_R0 = obj.RBaseLOONG64 + iota // must be a multiple of 32
REG_R1
REG_R2
REG_R3
REG_R4
REG_R5
REG_R6
REG_R7
REG_R8
REG_R9
REG_R10
REG_R11
REG_R12
REG_R13
REG_R14
REG_R15
REG_R16
REG_R17
REG_R18
REG_R19
REG_R20
REG_R21
REG_R22
REG_R23
REG_R24
REG_R25
REG_R26
REG_R27
REG_R28
REG_R29
REG_R30
REG_R31
REG_F0 // must be a multiple of 32
REG_F1
REG_F2
REG_F3
REG_F4
REG_F5
REG_F6
REG_F7
REG_F8
REG_F9
REG_F10
REG_F11
REG_F12
REG_F13
REG_F14
REG_F15
REG_F16
REG_F17
REG_F18
REG_F19
REG_F20
REG_F21
REG_F22
REG_F23
REG_F24
REG_F25
REG_F26
REG_F27
REG_F28
REG_F29
REG_F30
REG_F31
REG_FCSR0 // must be a multiple of 32
REG_FCSR1
REG_FCSR2
REG_FCSR3 // only four registers are needed
REG_FCSR4
REG_FCSR5
REG_FCSR6
REG_FCSR7
REG_FCSR8
REG_FCSR9
REG_FCSR10
REG_FCSR11
REG_FCSR12
REG_FCSR13
REG_FCSR14
REG_FCSR15
REG_FCSR16
REG_FCSR17
REG_FCSR18
REG_FCSR19
REG_FCSR20
REG_FCSR21
REG_FCSR22
REG_FCSR23
REG_FCSR24
REG_FCSR25
REG_FCSR26
REG_FCSR27
REG_FCSR28
REG_FCSR29
REG_FCSR30
REG_FCSR31
REG_FCC0 // must be a multiple of 32
REG_FCC1
REG_FCC2
REG_FCC3
REG_FCC4
REG_FCC5
REG_FCC6
REG_FCC7 // only eight registers are needed
REG_FCC8
REG_FCC9
REG_FCC10
REG_FCC11
REG_FCC12
REG_FCC13
REG_FCC14
REG_FCC15
REG_FCC16
REG_FCC17
REG_FCC18
REG_FCC19
REG_FCC20
REG_FCC21
REG_FCC22
REG_FCC23
REG_FCC24
REG_FCC25
REG_FCC26
REG_FCC27
REG_FCC28
REG_FCC29
REG_FCC30
REG_FCC31
// LSX: 128-bit vector register
REG_V0
REG_V1
REG_V2
REG_V3
REG_V4
REG_V5
REG_V6
REG_V7
REG_V8
REG_V9
REG_V10
REG_V11
REG_V12
REG_V13
REG_V14
REG_V15
REG_V16
REG_V17
REG_V18
REG_V19
REG_V20
REG_V21
REG_V22
REG_V23
REG_V24
REG_V25
REG_V26
REG_V27
REG_V28
REG_V29
REG_V30
REG_V31
// LASX: 256-bit vector register
REG_X0
REG_X1
REG_X2
REG_X3
REG_X4
REG_X5
REG_X6
REG_X7
REG_X8
REG_X9
REG_X10
REG_X11
REG_X12
REG_X13
REG_X14
REG_X15
REG_X16
REG_X17
REG_X18
REG_X19
REG_X20
REG_X21
REG_X22
REG_X23
REG_X24
REG_X25
REG_X26
REG_X27
REG_X28
REG_X29
REG_X30
REG_X31
REG_SPECIAL = REG_FCSR0
REGZERO = REG_R0 // set to zero
REGLINK = REG_R1
REGSP = REG_R3
REGCTXT = REG_R29 // context for closures
REGG = REG_R22 // G in loong64
REGTMP = REG_R30 // used by the assembler
FREGRET = REG_F0 // not use
)
var LOONG64DWARFRegisters = map[int16]int16{}
func init() {
// f assigns dwarfregisters[from:to] = (base):(to-from+base)
f := func(from, to, base int16) {
for r := from; r <= to; r++ {
LOONG64DWARFRegisters[r] = (r - from) + base
}
}
f(REG_R0, REG_R31, 0)
f(REG_F0, REG_F31, 32)
// The lower bits of V and X registers are alias to F registers
f(REG_V0, REG_V31, 32)
f(REG_X0, REG_X31, 32)
}
const (
BIG_8 = 128 - 2 // FIXME (not sure if -2 is appropriate)
BIG_9 = 256 - 2
BIG_10 = 512 - 2
BIG_11 = 1024 - 2
BIG_12 = 2046
BIG_16 = 32768 - 2
BIG_32 = 2147483648 - 2
)
const (
// mark flags
LABEL = 1 << 0
LEAF = 1 << 1
SYNC = 1 << 2
BRANCH = 1 << 3
)
// Arrangement for Loong64 SIMD instructions
const (
// arrangement types
ARNG_32B int16 = iota
ARNG_16H
ARNG_8W
ARNG_4V
ARNG_2Q
ARNG_16B
ARNG_8H
ARNG_4W
ARNG_2V
ARNG_B
ARNG_H
ARNG_W
ARNG_V
ARNG_BU
ARNG_HU
ARNG_WU
ARNG_VU
)
// LoongArch64 SIMD extension type
const (
LSX int16 = iota
LASX
)
// bits 0-4 indicates register: Vn or Xn
// bits 5-9 indicates arrangement: <T>
// bits 10 indicates SMID type: 0: LSX, 1: LASX
const (
REG_ARNG = obj.RBaseLOONG64 + (1 << 10) + (iota << 11) // Vn.<T>
REG_ELEM // Vn.<T>[index]
REG_ELEM_END
)
const (
EXT_REG_SHIFT = 0
EXT_REG_MASK = 0x1f
EXT_TYPE_SHIFT = 5
EXT_TYPE_MASK = 0x1f
EXT_SIMDTYPE_SHIFT = 10
EXT_SIMDTYPE_MASK = 0x1
)
const (
REG_LAST = REG_ELEM_END // the last defined register
)
//go:generate go run ../mkcnames.go -i cpu.go -o cnames.go -p loong64
const (
C_NONE = iota
C_REG
C_FREG
C_FCSRREG
C_FCCREG
C_VREG
C_XREG
C_ARNG // Vn.<T>
C_ELEM // Vn.<T>[index]
C_ZCON
C_U1CON // 1 bit unsigned constant
C_U2CON // 2 bit unsigned constant
C_U3CON // 3 bit unsigned constant
C_U4CON // 4 bit unsigned constant
C_U5CON // 5 bit unsigned constant
C_U6CON // 6 bit unsigned constant
C_U7CON // 7 bit unsigned constant
C_U8CON // 8 bit unsigned constant
C_S5CON // 5 bit signed constant
C_US12CON // same as C_S12CON, increase the priority of C_S12CON in special cases.
C_UU12CON // same as C_U12CON, increase the priority of C_U12CON in special cases.
C_S12CON // 12 bit signed constant, -0x800 < v <= 0x7ff
C_U12CON // 12 bit unsigned constant, 0 < v <= 0xfff
C_12CON // 12 bit signed constant, or 12 bit unsigned constant
C_S13CON20_0 // 13 bit signed constant, low 12 bits 0
C_S13CON // 13 bit signed constant
C_U13CON20_0 // 13 bit unsigned constant, low 12 bits 0
C_U13CON // 13 bit unsigned constant
C_13CON // 13 bit signed constant, or 13 bit unsigned constant
C_U15CON // 15 bit unsigned constant
C_U15CON20_0 // 15 bit unsigned constant, low 12 bits 0
C_32CON20_0 // 32 bit signed, low 12 bits 0
C_32CON // other 32 bit signed
// 64 bit signed, lo32 bits 0, hi20 bits are not 0, hi12 bits can
// be obtained by sign extension of the hi20 bits.
C_DCON20S_0
// 64 bit signed, lo52 bits 0, hi12 bits are not 0.
C_DCON12_0
// 64 bit signed, lo32 bits 0, hi32 bits are not 0.
C_DCON32_0
// 64 bit signed, lo12 bits 0, lo20 bits are not 0, hi20 bits can be
// obtained by sign extension of the lo20 bits, other bits are not 0.
C_DCON12_20S
// 64 bit signed, lo12 bits 0, hi20 bits are not 0, hi12 bits can be
// obtained by sign extension of the hi20 bits, other bits are not 0.
C_DCON20S_20
// 64 bit signed, lo12 bits 0, other bits are not 0.
C_DCON32_20
// 64 bit signed, lo12 bits are not 0, 12~51 bits can be obtained
// by sign extension of the lo12 bits, other bits are not 0.
C_DCON12_12S
// 64 bit signed, hi20 bits and lo12 bits are not 0, hi12 bits can
// be obtained by sign extension of the hi20 bits, lo20 bits can
// be obtained by sign extension of the lo12 bits.
C_DCON20S_12S
// 64 bit signed, lo12 bits are not 0, lo20 bits can be obtained by sign
// extension of the lo12 bits, other bits are not 0.
C_DCON32_12S
// 64 bit signed, lo20 and lo12 bits are not 0, hi20 bits can be obtained by sign
// extension of the lo20 bits. other bits are not 0.
C_DCON12_32S
// 64 bit signed, hi20 bits are not 0, hi12 bits can be obtained by sign
// extension of the hi20 bits, lo32 bits are not 0.
C_DCON20S_32
// 64 bit signed, 12~51 bits 0, other bits are not 0.
C_DCON12_12U
// 64 bit signed, lo20 bits 0, hi20 bits are not 0, hi12 bits can be
// obtained by sign extension of the hi20 bits, lo12 bits are not 0.
C_DCON20S_12U
// 64 bit signed, lo20 bits 0, other bits are not 0.
C_DCON32_12U
// other 64
C_DCON
C_SACON // $n(REG) where n <= int12
C_LACON // $n(REG) where int12 < n <= int32
C_DACON // $n(REG) where int32 < n
C_EXTADDR // external symbol address
C_BRAN
C_SAUTO
C_LAUTO
C_ZOREG // An $0+reg memory op
C_SOREG_8 // An $n+reg memory arg where n is a 8 bit signed offset
C_SOREG_9 // An $n+reg memory arg where n is a 9 bit signed offset
C_SOREG_10 // An $n+reg memory arg where n is a 10 bit signed offset
C_SOREG_11 // An $n+reg memory arg where n is a 11 bit signed offset
C_SOREG_12 // An $n+reg memory arg where n is a 12 bit signed offset
C_SOREG_16 // An $n+reg memory arg where n is a 16 bit signed offset
C_LOREG_32 // An $n+reg memory arg where n is a 32 bit signed offset
C_LOREG_64 // An $n+reg memory arg where n is a 64 bit signed offset
C_ROFF // register offset
C_ADDR
C_TLS_LE
C_TLS_IE
C_GOTADDR
C_TEXTSIZE
C_GOK
C_NCLASS // must be the last
)
func init() {
// The asm encoder generally assumes that the lowest 5 bits of the
// REG_XX constants match the machine instruction encoding, i.e.
// the lowest 5 bits is the register number.
// Check this here.
if REG_R0%32 != 0 {
panic("REG_R0 is not a multiple of 32")
}
if REG_F0%32 != 0 {
panic("REG_F0 is not a multiple of 32")
}
if REG_FCSR0%32 != 0 {
panic("REG_FCSR0 is not a multiple of 32")
}
if REG_FCC0%32 != 0 {
panic("REG_FCC0 is not a multiple of 32")
}
if REG_V0%32 != 0 {
panic("REG_V0 is not a multiple of 32")
}
if REG_X0%32 != 0 {
panic("REG_X0 is not a multiple of 32")
}
}