]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/loong64: change the immediate range of ALSL{W/WU/V}
authorlimeidan <limeidan@loongson.cn>
Wed, 6 Aug 2025 06:57:39 +0000 (14:57 +0800)
committerabner chenc <chenguoqi@loongson.cn>
Fri, 8 Aug 2025 02:04:41 +0000 (19:04 -0700)
When executing the alsl.w/wu/d family of instructions, the actual shift amount is the immediate value
in the instruction encoding plus one. Therefore, this change is made to align the immediate value
in the assembly code with the programmer's intended shift amount, and to include the result of
the immediate value minus one in the final encoding.

Change-Id: Ic82249251878eabde8372e183d841a03f963f9f9
Reviewed-on: https://go-review.googlesource.com/c/go/+/693475
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: sophie zhao <zhaoxiaolin@loongson.cn>
src/cmd/asm/internal/asm/testdata/loong64enc1.s
src/cmd/internal/obj/loong64/asm.go
src/cmd/internal/obj/loong64/doc.go

index 8990a99557d71078730dbe8477925d6a0333d7b0..72e65734666c2a477be957020c06add2461c6618 100644 (file)
@@ -1101,6 +1101,6 @@ lable2:
        XVBITREVV       $63, X2, X1     // 41fc1977
 
        // ALSL{W/WU/D}
-       ALSLW           $3, R4, R5, R6  // 86940500
-       ALSLWU          $3, R4, R5, R6  // 86940700
-       ALSLV           $3, R4, R5, R6  // 86942d00
+       ALSLW           $4, R4, R5, R6  // 86940500
+       ALSLWU          $4, R4, R5, R6  // 86940700
+       ALSLV           $4, R4, R5, R6  // 86942d00
index 1d10ad67d927aa3f5ed477cb9c6c7fbc77983e8e..76ad8e877935e12f5000fb564407a8fb456b6fde 100644 (file)
@@ -425,7 +425,7 @@ var optab = []Optab{
        {APRELD, C_SOREG, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0},
        {APRELDX, C_SOREG, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0},
 
-       {AALSLV, C_U2CON, C_REG, C_REG, C_REG, C_NONE, 64, 4, 0, 0},
+       {AALSLV, C_U3CON, C_REG, C_REG, C_REG, C_NONE, 64, 4, 0, 0},
 
        {obj.APCALIGN, C_U12CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
        {obj.APCDATA, C_32CON, C_NONE, C_NONE, C_32CON, C_NONE, 0, 0, 0, 0},
@@ -2742,8 +2742,12 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 = OP_RR(c.oprr(p.As), uint32(p.To.Reg), uint32(p.RegTo2))
 
        case 64: // alsl rd, rj, rk, sa2
+               sa := p.From.Offset - 1
+               if sa > 3 {
+                       c.ctxt.Diag("The shift amount is too large.")
+               }
                r := p.GetFrom3().Reg
-               o1 = OP_2IRRR(c.opirrr(p.As), uint32(p.From.Offset), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
+               o1 = OP_2IRRR(c.opirrr(p.As), uint32(sa), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
 
        case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
                o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
index a990b230892623603d74350dc227b095a03dbaa7..64bb41ae5a22190f316a9e217e4b66eab6c4fd3e 100644 (file)
@@ -268,6 +268,27 @@ Note: In the following sections 3.1 to 3.6, "ui4" (4-bit unsigned int immediate)
       bits[11:1]:  block size, the value range is [16, 1024], and it must be an integer multiple of 16
       bits[20:12]: block num, the value range is [1, 256]
       bits[36:21]: stride, the value range is [0, 0xffff]
+
+4. ShiftAdd instructions
+    Mapping between Go and platform assembly:
+                Go assembly            |    platform assembly
+     ALSL.W/WU/V $Imm, Rj, Rk, Rd      |    alsl.w/wu/d rd, rj, rk, $imm
+
+    Instruction encoding format is as follows:
+
+       | 31 ~ 17 | 16 ~ 15 | 14 ~ 10 | 9 ~ 5 | 4 ~ 0 |
+       |  opcode |   sa2   |   rk    |   rj  |   rd  |
+
+    The alsl.w/wu/v series of instructions shift the data in rj left by sa+1, add the value
+    in rk, and write the result to rd.
+
+    To allow programmers to directly write the desired shift amount in assembly code, we actually write
+    the value of sa2+1 in the assembly code and then include the value of sa2 in the instruction encoding.
+
+    For example:
+
+            Go assembly      | instruction Encoding
+        ALSLV $4, r4, r5, R6 |      002d9486
 */
 
 package loong64