]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/asm: change register type for loong64 floating-point
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Wed, 3 Apr 2024 07:13:04 +0000 (15:13 +0800)
committerGopher Robot <gobot@golang.org>
Mon, 29 Jul 2024 02:47:00 +0000 (02:47 +0000)
On Loong64, the two input operands and one output operand of the ADDF
instruction are both floating-point registers; and the floating-point
comparison instruction CMPEQ{F,D}, CMPGE{F,D}, CMPGT{F,D} both input
operands are floating-point registers, and the output operation is a
floating-point condition register, currently, only FCC0 is used as the
floating-point condition register.

Example:
ADDF F0, F1, F0
CMPEQF F0, F1, FCC0

Change-Id: I4c1c453e522d43f294a8dcab7b6b5247f41c9c68
Reviewed-on: https://go-review.googlesource.com/c/go/+/580281
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Auto-Submit: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/asm/internal/arch/loong64.go
src/cmd/asm/internal/asm/asm.go
src/cmd/asm/internal/asm/testdata/loong64enc1.s
src/cmd/compile/internal/loong64/ssa.go
src/cmd/internal/obj/loong64/asm.go

index bf34a94f0782b2106edd3a7e7b0137a2efcc761a..48a62c495230ba3a78e951e9d4840895f7eaf351 100644 (file)
@@ -21,17 +21,6 @@ func jumpLoong64(word string) bool {
        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 {
index b2eaa0a28dcaa289419a93bddcd50d868f79c2e6..bdbb3e17e0654b2f00c629cc43d400eacc9853a4 100644 (file)
@@ -642,12 +642,6 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
                                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
-                       }
-
                        if arch.IsLoong64RDTIME(op) {
                                // The Loong64 RDTIME family of instructions is a bit special,
                                // in that both its register operands are outputs
index a98fca08aabfc65a9f00d3ffc25e5552cce686b6..a45ef88150d05a4746e235c07f170659332eb6ed 100644 (file)
@@ -53,8 +53,7 @@ lable2:
        CLZ     R4, R5                  // 85140000
        CPUCFG  R4, R5                  // 856c0000
        ADDF    F4, F5                  // a5900001
-       ADDF    F4, R5, F6              // a6900001
-       CMPEQF  F4, R5                  // a010120c
+       ADDF    F4, F5, F6              // a6900001
        ABSF    F4, F5                  // 85041401
        MOVVF   F4, F5                  // 85181d01
        MOVF    F4, F5                  // 85941401
@@ -220,11 +219,12 @@ lable2:
        MOVWR   y+8(FP), R4             // 6440402e
        MOVWR   1(R5), R4               // a404402e
 
-       CMPGTF  F4, R5                  // a090110c
-       CMPGTD  F4, R5                  // a090210c
-       CMPGEF  F4, R5                  // a090130c
-       CMPGED  F4, R5                  // a090230c
-       CMPEQD  F4, R5                  // a010220c
+       CMPEQF  F4, F5, FCC0            // a010120c
+       CMPGTF  F4, F5, FCC1            // a190110c
+       CMPGTD  F4, F5, FCC2            // a290210c
+       CMPGEF  F4, F5, FCC3            // a390130c
+       CMPGED  F4, F5, FCC4            // a490230c
+       CMPEQD  F4, F5, FCC5            // a510220c
 
        RDTIMELW R4, R0                 // 80600000
        RDTIMEHW R4, R0                 // 80640000
index e7298bdb9fa57011a837b3bbf4e815c184563e6b..1b1fdfdc71437294a8eba3dde9096983abd41b5b 100644 (file)
@@ -244,6 +244,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                p.From.Type = obj.TYPE_REG
                p.From.Reg = v.Args[0].Reg()
                p.Reg = v.Args[1].Reg()
+               p.To.Type = obj.TYPE_REG
+               p.To.Reg = loong64.REG_FCC0
        case ssa.OpLOONG64MOVVaddr:
                p := s.Prog(loong64.AMOVV)
                p.From.Type = obj.TYPE_ADDR
index 9ce63c1f585b39d0f2b19ed8bff4931c50ba5206..8325cbf905c651c581ef1ecc0154a64d7bf185e4 100644 (file)
@@ -82,13 +82,14 @@ var optab = []Optab{
        {ACLO, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 9, 4, 0, 0},
 
        {AADDF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 32, 4, 0, 0},
-       {AADDF, C_FREG, C_REG, C_NONE, C_FREG, C_NONE, 32, 4, 0, 0},
-       {ACMPEQF, C_FREG, C_REG, C_NONE, C_NONE, C_NONE, 32, 4, 0, 0},
+       {AADDF, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 32, 4, 0, 0},
        {AABSF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 33, 4, 0, 0},
        {AMOVVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 33, 4, 0, 0},
        {AMOVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 33, 4, 0, 0},
        {AMOVD, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 33, 4, 0, 0},
 
+       {ACMPEQF, C_FREG, C_FREG, C_NONE, C_FCCREG, C_NONE, 29, 4, 0, 0},
+
        {AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, C_NONE, 7, 4, 0, 0},
        {AMOVWU, C_REG, C_NONE, C_NONE, C_SEXT, C_NONE, 7, 4, 0, 0},
        {AMOVV, C_REG, C_NONE, C_NONE, C_SEXT, C_NONE, 7, 4, 0, 0},
@@ -850,6 +851,21 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
        return C_GOK
 }
 
+func (c *ctxt0) rclass(r int16) int {
+       switch {
+       case REG_R0 <= r && r <= REG_R31:
+               return C_REG
+       case REG_F0 <= r && r <= REG_F31:
+               return C_FREG
+       case REG_FCC0 <= r && r <= REG_FCC31:
+               return C_FCCREG
+       case REG_FCSR0 <= r && r <= REG_FCSR31:
+               return C_FCSRREG
+       }
+
+       return C_GOK
+}
+
 func prasm(p *obj.Prog) {
        fmt.Printf("%v\n", p)
 }
@@ -883,7 +899,7 @@ func (c *ctxt0) oplook(p *obj.Prog) *Optab {
        // 2nd source operand
        a2 := C_NONE
        if p.Reg != 0 {
-               a2 = C_REG
+               a2 = c.rclass(p.Reg)
        }
 
        // 2nd destination operand
@@ -1620,6 +1636,9 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.From.Reg))
                }
 
+       case 29: // fcmp.cond.x fj, fk, fcc
+               o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg))
+
        case 30: // movw r,fr
                a := OP_TEN(8, 1321) // movgr2fr.w
                o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))