]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/asm/internal: configure assembler for loong64
authorXiaodong Liu <liuxiaodong@loongson.cn>
Tue, 22 Feb 2022 07:24:47 +0000 (15:24 +0800)
committerIan Lance Taylor <iant@google.com>
Fri, 13 May 2022 18:18:14 +0000 (18:18 +0000)
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>
src/cmd/asm/internal/arch/arch.go
src/cmd/asm/internal/arch/loong64.go [new file with mode: 0644]
src/cmd/asm/internal/asm/asm.go

index 403e70eee79b98ff2247ba97bc48ec2424234cb2..a724a3b6d929df6e14127c90dcec303d50d86e3a 100644 (file)
@@ -9,6 +9,7 @@ import (
        "cmd/internal/obj"
        "cmd/internal/obj/arm"
        "cmd/internal/obj/arm64"
+       "cmd/internal/obj/loong64"
        "cmd/internal/obj/mips"
        "cmd/internal/obj/ppc64"
        "cmd/internal/obj/riscv"
@@ -60,6 +61,8 @@ func Set(GOARCH string, shared bool) *Arch {
                return archArm()
        case "arm64":
                return archArm64()
+       case "loong64":
+               return archLoong64(&loong64.Linkloong64)
        case "mips":
                return archMips(&mips.Linkmips)
        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 {
        register := make(map[string]int16)
 
diff --git a/src/cmd/asm/internal/arch/loong64.go b/src/cmd/asm/internal/arch/loong64.go
new file mode 100644 (file)
index 0000000..ebf842c
--- /dev/null
@@ -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
+}
index 3afbec8b926292f91a9f0c4bc41860044bd252c1..3babd4b6771313ef93f1f28caf981b7c6e473f08 100644 (file)
@@ -460,6 +460,14 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
                        prog.Reg = p.getRegister(prog, op, &a[1])
                        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 {
                        // 3-operand jumps.
                        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])
                                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.To = a[1]
@@ -629,6 +643,10 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
                        prog.From = a[0]
                        prog.Reg = p.getRegister(prog, op, &a[1])
                        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:
                        // Special cases.
                        if arch.IsARMSTREX(op) {