82 lines
3.8 KiB
Go
82 lines
3.8 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|||
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
||
|
|
|
||
|
|
package arch
|
||
|
|
|
||
|
|
import "fmt"
|
||
|
|
|
||
|
|
func buildLOONG64() *Table {
|
||
|
|
return newTable(LOONG64, loong64Registers(), relaxCounts(mergedInstrs(loong64Summaries(), commonGeneratedInstrs, loong64GeneratedInstrs, loong64Aliases())))
|
||
|
|
}
|
||
|
|
|
||
|
|
// loong64Aliases are branch spellings the assembler front-end accepts in
|
||
|
|
// addition to the generated opcode table (notably JAL, BFPF and BFPT).
|
||
|
|
func loong64Aliases() []string {
|
||
|
|
return []string{"JAL", "BFPF", "BFPT"}
|
||
|
|
}
|
||
|
|
|
||
|
|
func loong64Summaries() map[string]Instr { return toMap(loong64Curated()) }
|
||
|
|
|
||
|
|
// loong64Registers builds the LoongArch (loong64) register file: 32 integer
|
||
|
|
// (R), 32 floating-point (F), and the LSX/LASX SIMD vector registers (V and X).
|
||
|
|
func loong64Registers() []Register {
|
||
|
|
var regs []Register
|
||
|
|
add := func(name string, class RegClass, desc string) {
|
||
|
|
regs = append(regs, Register{Name: name, Class: class, Desc: desc})
|
||
|
|
}
|
||
|
|
for i := 0; i <= 31; i++ {
|
||
|
|
add(fmt.Sprintf("R%d", i), GPR, "integer register")
|
||
|
|
}
|
||
|
|
for i := 0; i <= 31; i++ {
|
||
|
|
add(fmt.Sprintf("F%d", i), Float, "floating-point register")
|
||
|
|
}
|
||
|
|
for i := 0; i <= 31; i++ {
|
||
|
|
add(fmt.Sprintf("V%d", i), VecARM, "LSX 128-bit vector register")
|
||
|
|
}
|
||
|
|
for i := 0; i <= 31; i++ {
|
||
|
|
add(fmt.Sprintf("X%d", i), VecARM, "LASX 256-bit vector register")
|
||
|
|
}
|
||
|
|
return regs
|
||
|
|
}
|
||
|
|
|
||
|
|
// loong64Curated is a hand-written subset of common LoongArch instructions
|
||
|
|
// carrying summaries. The authoritative, complete set is loong64GeneratedInstrs.
|
||
|
|
func loong64Curated() []Instr {
|
||
|
|
return []Instr{
|
||
|
|
ic("ADD", "Integer add (word)", 3, 3), ic("ADDW", "Add word", 3, 3),
|
||
|
|
ic("ADDD", "Add doubleword", 3, 3), ic("ADDI", "Add immediate", 3, 3),
|
||
|
|
ic("SUB", "Subtract (word)", 3, 3), ic("SUBW", "Subtract word", 3, 3),
|
||
|
|
ic("SUBD", "Subtract doubleword", 3, 3),
|
||
|
|
ic("AND", "Bitwise AND", 3, 3), ic("ANDI", "AND immediate", 3, 3),
|
||
|
|
ic("OR", "Bitwise OR", 3, 3), ic("ORI", "OR immediate", 3, 3),
|
||
|
|
ic("XOR", "Bitwise XOR", 3, 3), ic("XORI", "XOR immediate", 3, 3),
|
||
|
|
ic("NOR", "Bitwise NOR", 3, 3),
|
||
|
|
ic("MUL", "Multiply (word)", 3, 3), ic("MULW", "Multiply word", 3, 3),
|
||
|
|
ic("MULD", "Multiply doubleword", 3, 3),
|
||
|
|
ic("DIV", "Divide (word)", 3, 3), ic("DIVW", "Divide word", 3, 3),
|
||
|
|
ic("DIVD", "Divide doubleword", 3, 3),
|
||
|
|
ic("MOD", "Modulo (word)", 3, 3), ic("MODW", "Modulo word", 3, 3),
|
||
|
|
ic("MODD", "Modulo doubleword", 3, 3),
|
||
|
|
ic("SLL", "Shift left logical", 3, 3), ic("SRL", "Shift right logical", 3, 3),
|
||
|
|
ic("SRA", "Shift right arithmetic", 3, 3), ic("ROTR", "Rotate right", 3, 3),
|
||
|
|
ic("SLT", "Set if less than", 3, 3), ic("SLTU", "Set if less than unsigned", 3, 3),
|
||
|
|
ic("SLTI", "Set if less than immediate", 3, 3),
|
||
|
|
ic("LD", "Load doubleword", 2, 2), ic("LDW", "Load word", 2, 2),
|
||
|
|
ic("LDH", "Load halfword", 2, 2), ic("LDB", "Load byte", 2, 2),
|
||
|
|
ic("ST", "Store doubleword", 2, 2), ic("STW", "Store word", 2, 2),
|
||
|
|
ic("STH", "Store halfword", 2, 2), ic("STB", "Store byte", 2, 2),
|
||
|
|
ic("BEQ", "Branch if equal", 3, 3), ic("BNE", "Branch if not equal", 3, 3),
|
||
|
|
ic("BLT", "Branch if less than", 3, 3), ic("BGE", "Branch if greater or equal", 3, 3),
|
||
|
|
ic("BLTU", "Branch if less than unsigned", 3, 3), ic("BGEU", "Branch if greater or equal unsigned", 3, 3),
|
||
|
|
ic("B", "Unconditional branch", 1, 1), ic("BL", "Branch with link", 1, 1),
|
||
|
|
ic("JIRL", "Jump indirect with link", 1, 3),
|
||
|
|
ic("RET", "Return", 0, 1), ic("NOP", "No operation", 0, 1),
|
||
|
|
i("SYSCALL", "System call"), i("BREAK", "Breakpoint"), i("DBAR", "Barrier"),
|
||
|
|
ic("FADDS", "FP add (single)", 3, 3), ic("FADDD", "FP add (double)", 3, 3),
|
||
|
|
ic("FSUBS", "FP subtract (single)", 3, 3), ic("FSUBD", "FP subtract (double)", 3, 3),
|
||
|
|
ic("FMULS", "FP multiply (single)", 3, 3), ic("FMULD", "FP multiply (double)", 3, 3),
|
||
|
|
ic("FDIVS", "FP divide (single)", 3, 3), ic("FDIVD", "FP divide (double)", 3, 3),
|
||
|
|
ic("MOV", "Move register", 2, 2),
|
||
|
|
}
|
||
|
|
}
|