aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj
diff options
context:
space:
mode:
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>2024-08-12 15:18:45 +0800
committerabner chenc <chenguoqi@loongson.cn>2024-08-23 00:53:08 +0000
commitea08952aa2db17ce4c14d9f9cb0fab03380073a0 (patch)
treef6732f08ae6679c2e4880b6340d9c6411327a350 /src/cmd/internal/obj
parent10ed134afe1319403a9a6a8b6bb798f29e5a4d5e (diff)
downloadgo-ea08952aa2db17ce4c14d9f9cb0fab03380073a0.tar.xz
cmd/internal/obj/loong64: add support for instructions BSTRPICK.{W/D} and BSTRINS.{W/D}
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>
Diffstat (limited to 'src/cmd/internal/obj')
-rw-r--r--src/cmd/internal/obj/loong64/a.out.go8
-rw-r--r--src/cmd/internal/obj/loong64/anames.go4
-rw-r--r--src/cmd/internal/obj/loong64/asm.go52
-rw-r--r--src/cmd/internal/obj/loong64/doc.go8
4 files changed, 71 insertions, 1 deletions
diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go
index d1cd35b878..7c20df3b2d 100644
--- a/src/cmd/internal/obj/loong64/a.out.go
+++ b/src/cmd/internal/obj/loong64/a.out.go
@@ -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
diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go
index 0749db8312..ed3d5b25ce 100644
--- a/src/cmd/internal/obj/loong64/anames.go
+++ b/src/cmd/internal/obj/loong64/anames.go
@@ -175,6 +175,10 @@ var Anames = []string{
"AMMAXDBVU",
"AMMINDBWU",
"AMMINDBVU",
+ "BSTRINSW",
+ "BSTRINSV",
+ "BSTRPICKW",
+ "BSTRPICKV",
"RDTIMELW",
"RDTIMEHW",
"RDTIMED",
diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go
index 52fe7b2c89..d78e594fc9 100644
--- a/src/cmd/internal/obj/loong64/asm.go
+++ b/src/cmd/internal/obj/loong64/asm.go
@@ -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:
diff --git a/src/cmd/internal/obj/loong64/doc.go b/src/cmd/internal/obj/loong64/doc.go
index c46d31d2c2..6ec53e7a17 100644
--- a/src/cmd/internal/obj/loong64/doc.go
+++ b/src/cmd/internal/obj/loong64/doc.go
@@ -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).