]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/loong64: add support for instructions BSTRPICK.{W/D} and BSTRINS...
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Mon, 12 Aug 2024 07:18:45 +0000 (15:18 +0800)
committerabner chenc <chenguoqi@loongson.cn>
Fri, 23 Aug 2024 00:53:08 +0000 (00:53 +0000)
Go asm syntax:
BSTRPICK{W/V} $msb, RJ, $lsb, RD
BSTRINS{W/V} $msb, RJ, $lsb, RD

Equivalent platform assembler syntax:
bstrpick.{w/d} rd, rj, $msb, $lsb
bstrins.{w/d} rd, rj, $msb, $lsb

Ref: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html

Change-Id: I8b89b766ed22a96da7d8d5b2b2873382a49208de
Reviewed-on: https://go-review.googlesource.com/c/go/+/604735
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
src/cmd/asm/internal/asm/asm.go
src/cmd/asm/internal/asm/testdata/loong64enc1.s
src/cmd/internal/obj/loong64/a.out.go
src/cmd/internal/obj/loong64/anames.go
src/cmd/internal/obj/loong64/asm.go
src/cmd/internal/obj/loong64/doc.go

index bdbb3e17e0654b2f00c629cc43d400eacc9853a4..b960d8f022e19647b7aee5b3bf57d916ae4818c8 100644 (file)
@@ -822,6 +822,13 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
                        prog.To = a[3]
                        break
                }
+               if p.arch.Family == sys.Loong64 {
+                       prog.From = a[0]
+                       prog.Reg = p.getRegister(prog, op, &a[1])
+                       prog.AddRestSource(a[2])
+                       prog.To = a[3]
+                       break
+               }
                if p.arch.Family == sys.PPC64 {
                        prog.From = a[0]
                        prog.To = a[3]
index b24aa2fe7cbda4bf7b0c8acfd04d61f8836e127d..8d4231fa6cf1a9392d234b81c12830b2c031ac7d 100644 (file)
@@ -332,3 +332,17 @@ lable2:
        // FSTX.{S,D} instructions
        MOVF            F2, (R14)(R13)  // c2353838
        MOVD            F2, (R14)(R13)  // c2353c38
+
+       BSTRINSW        $0, R4, $0, R5  // 85006000
+       BSTRINSW        $31, R4, $0, R5 // 85007f00
+       BSTRINSW        $15, R4, $6, R5 // 85186f00
+       BSTRINSV        $0, R4, $0, R5  // 85008000
+       BSTRINSV        $63, R4, $0, R5 // 8500bf00
+       BSTRINSV        $15, R4, $6, R5 // 85188f00
+
+       BSTRPICKW       $0, R4, $0, R5  // 85806000
+       BSTRPICKW       $31, R4, $0, R5 // 85807f00
+       BSTRPICKW       $15, R4, $6, R5 // 85986f00
+       BSTRPICKV       $0, R4, $0, R5  // 8500c000
+       BSTRPICKV       $63, R4, $0, R5 // 8500ff00
+       BSTRPICKV       $15, R4, $6, R5 // 8518cf00
index d1cd35b878f052e8caaf04e7e42968cde46bacca..7c20df3b2d541bc8e5f9f1f48df6a4d4dff4f09d 100644 (file)
@@ -435,6 +435,14 @@ const (
        AAMMINDBWU
        AAMMINDBVU
 
+       // 2.2.3.8
+       ABSTRINSW
+       ABSTRINSV
+
+       // 2.2.3.9
+       ABSTRPICKW
+       ABSTRPICKV
+
        // 2.2.10. Other Miscellaneous Instructions
        ARDTIMELW
        ARDTIMEHW
index 0749db8312171b4797b1793111e7cf9105110f9b..ed3d5b25ced88ddf9cd77fd3a0d321c9dd54f7b2 100644 (file)
@@ -175,6 +175,10 @@ var Anames = []string{
        "AMMAXDBVU",
        "AMMINDBWU",
        "AMMINDBVU",
+       "BSTRINSW",
+       "BSTRINSV",
+       "BSTRPICKW",
+       "BSTRPICKV",
        "RDTIMELW",
        "RDTIMEHW",
        "RDTIMED",
index 52fe7b2c894ce1bae45f9272636fb72d43bb6a0c..d78e594fc97961c604f1fcf77184eb154e9e6d38 100644 (file)
@@ -217,6 +217,10 @@ var optab = []Optab{
        {ASLLV, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
        {ASLLV, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
 
+       {ABSTRPICKW, C_SCON, C_REG, C_SCON, C_REG, C_NONE, 17, 4, 0, 0},
+       {ABSTRPICKW, C_SCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
+       {ABSTRPICKW, C_ZCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
+
        {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
        {ASYSCALL, C_ANDCON, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
 
@@ -1159,6 +1163,11 @@ func buildop(ctxt *obj.Link) {
                        opset(ASRLV, r0)
                        opset(AROTRV, r0)
 
+               case ABSTRPICKW:
+                       opset(ABSTRPICKV, r0)
+                       opset(ABSTRINSW, r0)
+                       opset(ABSTRINSV, r0)
+
                case ASUB:
                        opset(ASUBU, r0)
                        opset(ANOR, r0)
@@ -1265,6 +1274,14 @@ func OP_15I(op uint32, i uint32) uint32 {
        return op | (i&0x7FFF)<<0
 }
 
+// i1 -> msb
+// r2 -> rj
+// i3 -> lsb
+// r4 -> rd
+func OP_IRIR(op uint32, i1 uint32, r2 uint32, i3 uint32, r4 uint32) uint32 {
+       return op | (i1 << 16) | (r2&0x1F)<<5 | (i3 << 10) | (r4&0x1F)<<0
+}
+
 // Encoding for the 'b' or 'bl' instruction.
 func OP_B_BL(op uint32, i uint32) uint32 {
        return op | ((i & 0xFFFF) << 10) | ((i >> 16) & 0x3FF)
@@ -1478,6 +1495,26 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x1f, uint32(r), uint32(p.To.Reg))
                }
 
+       case 17: // bstrpickw $msbw, r1, $lsbw, r2
+               rd, rj := p.To.Reg, p.Reg
+               if rj == obj.REG_NONE {
+                       rj = rd
+               }
+               msb, lsb := p.From.Offset, p.GetFrom3().Offset
+
+               // check the range of msb and lsb
+               var b uint32
+               if p.As == ABSTRPICKW || p.As == ABSTRINSW {
+                       b = 32
+               } else {
+                       b = 64
+               }
+               if lsb < 0 || uint32(lsb) >= b || msb < 0 || uint32(msb) >= b || uint32(lsb) > uint32(msb) {
+                       c.ctxt.Diag("illegal bit number\n%v", p)
+               }
+
+               o1 = OP_IRIR(c.opirir(p.As), uint32(msb), uint32(rj), uint32(lsb), uint32(rd))
+
        case 18: // jmp [r1],0(r2)
                r := int(p.Reg)
                if r == 0 {
@@ -2250,6 +2287,21 @@ func (c *ctxt0) opirr(a obj.As) uint32 {
        return 0
 }
 
+func (c *ctxt0) opirir(a obj.As) uint32 {
+       switch a {
+       case ABSTRINSW:
+               return 0x3<<21 | 0x0<<15 // bstrins.w
+       case ABSTRINSV:
+               return 0x2 << 22 // bstrins.d
+       case ABSTRPICKW:
+               return 0x3<<21 | 0x1<<15 // bstrpick.w
+       case ABSTRPICKV:
+               return 0x3 << 22 // bstrpick.d
+       }
+
+       return 0
+}
+
 func (c *ctxt0) specailFpMovInst(a obj.As, fclass int, tclass int) uint32 {
        switch a {
        case AMOVV:
index c46d31d2c291a6acd2672a808582907a68d6156c..6ec53e7a171c681874f0de2feb0125b74b08a017 100644 (file)
@@ -63,13 +63,19 @@ Examples:
        OR      R5, R6        <=> or R6, R6, R5
 
 Special Cases.
-Argument order is the same as in the GNU Loong64 syntax: jump instructions,
+(1) Argument order is the same as in the GNU Loong64 syntax: jump instructions,
 
 Examples:
 
        BEQ     R0, R4, lable1  <=>  beq R0, R4, lable1
        JMP     lable1          <=>  b lable1
 
+(2) BSTRINSW, BSTRINSV, BSTRPICKW, BSTRPICKV $<msb>, <Rj>, $<lsb>, <Rd>
+
+Examples:
+
+       BSTRPICKW $15, R4, $6, R5  <=>  bstrpick.w r5, r4, 15, 6
+
 2. Expressions for special arguments.
 
 Memory references: a base register and an offset register is written as (Rbase)(Roff).