| // 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 | |
| REGRT1 = REG_R20 // reserved for runtime, trampoline | |
| REGRT2 = REG_R21 // reserved for runtime, trampoline | |
| REGTLS = REG_R2 // C ABI TLS base pointer | |
| 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 << iota | |
| LEAF | |
| SYNC | |
| BRANCH | |
| // branchLoopHead marks loop entry. | |
| // Used to insert padding for under-aligned loops. | |
| branchLoopHead | |
| // p expands to multiple instructions and uses REGTMP. | |
| USES_REG_TMP | |
| ) | |
| // 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 << 12) + (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") | |
| } | |
| } |