From ddce0522bee36764c3b9529b8584c3d5b53c5dac Mon Sep 17 00:00:00 2001 From: Xiaolin Zhao Date: Tue, 26 Aug 2025 15:40:57 +0800 Subject: [PATCH] cmd/internal/obj/loong64: add ADDU16I.D instruction support Go asm syntax: ADDV16 $(1<<16), R4, R5 Equivalent platform assembler syntax: addu16i.d r5, r4, $1 Change-Id: Ica4a4e779d0a107cda3eade86027abd6458779a4 Reviewed-on: https://go-review.googlesource.com/c/go/+/699056 Reviewed-by: abner chenc Reviewed-by: Michael Pratt Auto-Submit: Michael Pratt LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui --- src/cmd/asm/internal/asm/testdata/loong64enc1.s | 7 +++++++ src/cmd/asm/internal/asm/testdata/loong64error.s | 2 ++ src/cmd/internal/obj/loong64/a.out.go | 3 +++ src/cmd/internal/obj/loong64/anames.go | 1 + src/cmd/internal/obj/loong64/asm.go | 15 ++++++++++++++- src/cmd/internal/obj/loong64/doc.go | 12 ++++++++++++ 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s index c5c6a4479a..fd86db7a4f 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s @@ -282,6 +282,13 @@ lable2: MOVVP 4(R5), R4 // a4040026 MOVVP (R5), R4 // a4000026 + // ADDU16I.D instruction + ADDV16 $(-32768<<16), R4, R5 // ADDV16 $-2147483648, R4, R5 // 85000012 + ADDV16 $(0<<16), R4, R5 // ADDV16 $0, R4, R5 // 85000010 + ADDV16 $(8<<16), R4, R5 // ADDV16 $524288, R4, R5 // 85200010 + ADDV16 $(32767<<16), R4, R5 // ADDV16 $2147418112, R4, R5 // 85fcff11 + ADDV16 $(16<<16), R4 // ADDV16 $1048576, R4 // 84400010 + // Loong64 atomic memory access instructions AMSWAPB R14, (R13), R12 // ac395c38 AMSWAPH R14, (R13), R12 // acb95c38 diff --git a/src/cmd/asm/internal/asm/testdata/loong64error.s b/src/cmd/asm/internal/asm/testdata/loong64error.s index 9272ce51c3..2dcd34bf61 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64error.s +++ b/src/cmd/asm/internal/asm/testdata/loong64error.s @@ -5,3 +5,5 @@ TEXT errors(SB),$0 VSHUF4IV $16, V1, V2 // ERROR "operand out of range 0 to 15" XVSHUF4IV $16, X1, X2 // ERROR "operand out of range 0 to 15" + ADDV16 $1, R4, R5 // ERROR "the constant must be a multiple of 65536." + ADDV16 $65535, R4, R5 // ERROR "the constant must be a multiple of 65536." diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go index 7ab85a2f23..100e99b1c4 100644 --- a/src/cmd/internal/obj/loong64/a.out.go +++ b/src/cmd/internal/obj/loong64/a.out.go @@ -565,6 +565,9 @@ const ( AMOVVF AMOVVD + // 2.2.1.2 + AADDV16 + // 2.2.1.3 AALSLW AALSLWU diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go index c629553d55..422ccbd9b0 100644 --- a/src/cmd/internal/obj/loong64/anames.go +++ b/src/cmd/internal/obj/loong64/anames.go @@ -125,6 +125,7 @@ var Anames = []string{ "MOVDV", "MOVVF", "MOVVD", + "ADDV16", "ALSLW", "ALSLWU", "ALSLV", diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index 848d77fd0d..e20ceaae95 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -267,6 +267,9 @@ var optab = []Optab{ {AADDV, C_U12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, {AADDV, C_U12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, + {AADDV16, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, + {AADDV16, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, + {AAND, C_UU12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, {AAND, C_UU12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, {AAND, C_S12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, @@ -1520,6 +1523,7 @@ func buildop(ctxt *obj.Link) { APRELD, APRELDX, AFSEL, + AADDV16, obj.ANOP, obj.ATEXT, obj.AFUNCDATA, @@ -2087,7 +2091,14 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { if r == 0 { r = int(p.To.Reg) } - o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + if p.As == AADDV16 { + if v&65535 != 0 { + c.ctxt.Diag("%v: the constant must be a multiple of 65536.\n", p) + } + o1 = OP_16IRR(c.opirr(p.As), uint32(v>>16), uint32(r), uint32(p.To.Reg)) + } else { + o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + } case 5: // syscall v := c.regoff(&p.From) @@ -4033,6 +4044,8 @@ func (c *ctxt0) opirr(a obj.As) uint32 { return 0x00b << 22 case AADDVU: return 0x00b << 22 + case AADDV16: + return 0x4 << 26 case AJMP: return 0x14 << 26 diff --git a/src/cmd/internal/obj/loong64/doc.go b/src/cmd/internal/obj/loong64/doc.go index 20c5a9e0a6..f7e5a4fb42 100644 --- a/src/cmd/internal/obj/loong64/doc.go +++ b/src/cmd/internal/obj/loong64/doc.go @@ -326,6 +326,18 @@ Note: In the following sections 3.1 to 3.6, "ui4" (4-bit unsigned int immediate) Go assembly | platform assembly MOVWP 8(R4), R5 | ldptr.w r5, r4, $2 +6. Note of special add instrction + Mapping between Go and platform assembly: + Go assembly | platform assembly + ADDV16 si16<<16, Rj, Rd | addu16i.d rd, rj, si16 + + note: si16 is a 16-bit immediate number, and si16<<16 is the actual operand. + + The addu16i.d instruction logically left-shifts the 16-bit immediate number si16 by 16 bits, then + sign-extends it. The resulting data is added to the [63:0] bits of data in the general-purpose register + rj, and the sum is written into the general-purpose register rd. + The addu16i.d instruction is used in conjunction with the ldptr.w/d and stptr.w/d instructions to + accelerate access based on the GOT table in position-independent code. */ package loong64 -- 2.52.0