From: limeidan Date: Wed, 6 Aug 2025 06:57:39 +0000 (+0800) Subject: cmd/internal/obj/loong64: change the immediate range of ALSL{W/WU/V} X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=73ff6d148038da77dd05b3dca3f0767db000a0f7;p=gostls13.git cmd/internal/obj/loong64: change the immediate range of ALSL{W/WU/V} 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 Reviewed-by: Mark Freeman LUCI-TryBot-Result: Go LUCI Reviewed-by: abner chenc Reviewed-by: sophie zhao --- diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s index 8990a99557..72e6573466 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s @@ -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 diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index 1d10ad67d9..76ad8e8779 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -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)) diff --git a/src/cmd/internal/obj/loong64/doc.go b/src/cmd/internal/obj/loong64/doc.go index a990b23089..64bb41ae5a 100644 --- a/src/cmd/internal/obj/loong64/doc.go +++ b/src/cmd/internal/obj/loong64/doc.go @@ -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