mirror of
https://github.com/golang/go.git
synced 2025-05-26 01:41:25 +00:00
cmd/asm/internal: configure assembler for loong64
Contributors to the loong64 port are: Weining Lu <luweining@loongson.cn> Lei Wang <wanglei@loongson.cn> Lingqin Gong <gonglingqin@loongson.cn> Xiaolin Zhao <zhaoxiaolin@loongson.cn> Meidan Li <limeidan@loongson.cn> Xiaojuan Zhai <zhaixiaojuan@loongson.cn> Qiyuan Pu <puqiyuan@loongson.cn> Guoqi Chen <chenguoqi@loongson.cn> This port has been updated to Go 1.15.6: https://github.com/loongson/go Updates #46229 Change-Id: I4b0247a331256162b47fbd94589f46ba062d4d44 Reviewed-on: https://go-review.googlesource.com/c/go/+/387234 Auto-Submit: Ian Lance Taylor <iant@google.com> Run-TryBot: David Chase <drchase@google.com> Run-TryBot: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
fd17a4dc09
commit
0653cb4cf7
@ -9,6 +9,7 @@ import (
|
|||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/obj/arm"
|
"cmd/internal/obj/arm"
|
||||||
"cmd/internal/obj/arm64"
|
"cmd/internal/obj/arm64"
|
||||||
|
"cmd/internal/obj/loong64"
|
||||||
"cmd/internal/obj/mips"
|
"cmd/internal/obj/mips"
|
||||||
"cmd/internal/obj/ppc64"
|
"cmd/internal/obj/ppc64"
|
||||||
"cmd/internal/obj/riscv"
|
"cmd/internal/obj/riscv"
|
||||||
@ -60,6 +61,8 @@ func Set(GOARCH string, shared bool) *Arch {
|
|||||||
return archArm()
|
return archArm()
|
||||||
case "arm64":
|
case "arm64":
|
||||||
return archArm64()
|
return archArm64()
|
||||||
|
case "loong64":
|
||||||
|
return archLoong64(&loong64.Linkloong64)
|
||||||
case "mips":
|
case "mips":
|
||||||
return archMips(&mips.Linkmips)
|
return archMips(&mips.Linkmips)
|
||||||
case "mipsle":
|
case "mipsle":
|
||||||
@ -502,6 +505,59 @@ func archMips64(linkArch *obj.LinkArch) *Arch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func archLoong64(linkArch *obj.LinkArch) *Arch {
|
||||||
|
register := make(map[string]int16)
|
||||||
|
// Create maps for easy lookup of instruction names etc.
|
||||||
|
// Note that there is no list of names as there is for x86.
|
||||||
|
for i := loong64.REG_R0; i <= loong64.REG_R31; i++ {
|
||||||
|
register[obj.Rconv(i)] = int16(i)
|
||||||
|
}
|
||||||
|
for i := loong64.REG_F0; i <= loong64.REG_F31; i++ {
|
||||||
|
register[obj.Rconv(i)] = int16(i)
|
||||||
|
}
|
||||||
|
for i := loong64.REG_FCSR0; i <= loong64.REG_FCSR31; i++ {
|
||||||
|
register[obj.Rconv(i)] = int16(i)
|
||||||
|
}
|
||||||
|
for i := loong64.REG_FCC0; i <= loong64.REG_FCC31; i++ {
|
||||||
|
register[obj.Rconv(i)] = int16(i)
|
||||||
|
}
|
||||||
|
// Pseudo-registers.
|
||||||
|
register["SB"] = RSB
|
||||||
|
register["FP"] = RFP
|
||||||
|
register["PC"] = RPC
|
||||||
|
// Avoid unintentionally clobbering g using R22.
|
||||||
|
delete(register, "R22")
|
||||||
|
register["g"] = loong64.REG_R22
|
||||||
|
register["RSB"] = loong64.REG_R31
|
||||||
|
registerPrefix := map[string]bool{
|
||||||
|
"F": true,
|
||||||
|
"FCSR": true,
|
||||||
|
"FCC": true,
|
||||||
|
"R": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
instructions := make(map[string]obj.As)
|
||||||
|
for i, s := range obj.Anames {
|
||||||
|
instructions[s] = obj.As(i)
|
||||||
|
}
|
||||||
|
for i, s := range loong64.Anames {
|
||||||
|
if obj.As(i) >= obj.A_ARCHSPECIFIC {
|
||||||
|
instructions[s] = obj.As(i) + obj.ABaseLoong64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Annoying alias.
|
||||||
|
instructions["JAL"] = loong64.AJAL
|
||||||
|
|
||||||
|
return &Arch{
|
||||||
|
LinkArch: linkArch,
|
||||||
|
Instructions: instructions,
|
||||||
|
Register: register,
|
||||||
|
RegisterPrefix: registerPrefix,
|
||||||
|
RegisterNumber: loong64RegisterNumber,
|
||||||
|
IsJump: jumpLoong64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func archRISCV64(shared bool) *Arch {
|
func archRISCV64(shared bool) *Arch {
|
||||||
register := make(map[string]int16)
|
register := make(map[string]int16)
|
||||||
|
|
||||||
|
67
src/cmd/asm/internal/arch/loong64.go
Normal file
67
src/cmd/asm/internal/arch/loong64.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// This file encapsulates some of the odd characteristics of the
|
||||||
|
// Loong64 (LoongArch64) instruction set, to minimize its interaction
|
||||||
|
// with the core of the assembler.
|
||||||
|
|
||||||
|
package arch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"cmd/internal/obj"
|
||||||
|
"cmd/internal/obj/loong64"
|
||||||
|
)
|
||||||
|
|
||||||
|
func jumpLoong64(word string) bool {
|
||||||
|
switch word {
|
||||||
|
case "BEQ", "BFPF", "BFPT", "BLTZ", "BGEZ", "BLEZ", "BGTZ", "BLT", "BLTU", "JIRL", "BNE", "BGE", "BGEU", "JMP", "JAL", "CALL":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLoong64CMP reports whether the op (as defined by an loong64.A* constant) is
|
||||||
|
// one of the CMP instructions that require special handling.
|
||||||
|
func IsLoong64CMP(op obj.As) bool {
|
||||||
|
switch op {
|
||||||
|
case loong64.ACMPEQF, loong64.ACMPEQD, loong64.ACMPGEF, loong64.ACMPGED,
|
||||||
|
loong64.ACMPGTF, loong64.ACMPGTD:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLoong64MUL reports whether the op (as defined by an loong64.A* constant) is
|
||||||
|
// one of the MUL/DIV/REM instructions that require special handling.
|
||||||
|
func IsLoong64MUL(op obj.As) bool {
|
||||||
|
switch op {
|
||||||
|
case loong64.AMUL, loong64.AMULU, loong64.AMULV, loong64.AMULVU,
|
||||||
|
loong64.ADIV, loong64.ADIVU, loong64.ADIVV, loong64.ADIVVU,
|
||||||
|
loong64.AREM, loong64.AREMU, loong64.AREMV, loong64.AREMVU:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func loong64RegisterNumber(name string, n int16) (int16, bool) {
|
||||||
|
switch name {
|
||||||
|
case "F":
|
||||||
|
if 0 <= n && n <= 31 {
|
||||||
|
return loong64.REG_F0 + n, true
|
||||||
|
}
|
||||||
|
case "FCSR":
|
||||||
|
if 0 <= n && n <= 31 {
|
||||||
|
return loong64.REG_FCSR0 + n, true
|
||||||
|
}
|
||||||
|
case "FCC":
|
||||||
|
if 0 <= n && n <= 31 {
|
||||||
|
return loong64.REG_FCC0 + n, true
|
||||||
|
}
|
||||||
|
case "R":
|
||||||
|
if 0 <= n && n <= 31 {
|
||||||
|
return loong64.REG_R0 + n, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
@ -460,6 +460,14 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
|
|||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if p.arch.Family == sys.Loong64 {
|
||||||
|
// 3-operand jumps.
|
||||||
|
// First two must be registers
|
||||||
|
target = &a[2]
|
||||||
|
prog.From = a[0]
|
||||||
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
|
break
|
||||||
|
}
|
||||||
if p.arch.Family == sys.S390X {
|
if p.arch.Family == sys.S390X {
|
||||||
// 3-operand jumps.
|
// 3-operand jumps.
|
||||||
target = &a[2]
|
target = &a[2]
|
||||||
@ -620,6 +628,12 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
|||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else if p.arch.Family == sys.Loong64 {
|
||||||
|
if arch.IsLoong64CMP(op) {
|
||||||
|
prog.From = a[0]
|
||||||
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.To = a[1]
|
prog.To = a[1]
|
||||||
@ -629,6 +643,10 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
|||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
|
case sys.Loong64:
|
||||||
|
prog.From = a[0]
|
||||||
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
|
prog.To = a[2]
|
||||||
case sys.ARM:
|
case sys.ARM:
|
||||||
// Special cases.
|
// Special cases.
|
||||||
if arch.IsARMSTREX(op) {
|
if arch.IsARMSTREX(op) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user