From bf8d142b4ebe9f84e75b20a87d292d2d6ec13fab Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Thu, 4 Aug 2022 18:13:59 +0800 Subject: cmd/asm: add RDTIME{L,H}.W, RDTIME.D support for loong64 Instruction formats: rdtime rd, rj The RDTIME family of instructions are used to read constant frequency timer information, the stable counter value is written into the general register rd, and the counter id information is written into the general register rj. (Note: both of its register operands are outputs). Ref: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html Change-Id: Ida5bbb28316ef70b5f616dac3e6fa6f2e77875b5 Reviewed-on: https://go-review.googlesource.com/c/go/+/421655 Reviewed-by: xiaodong liu Reviewed-by: WANG Xuerui Reviewed-by: Wayne Zuo Reviewed-by: Cherry Mui Reviewed-by: Michael Knyszek Run-TryBot: Wayne Zuo TryBot-Result: Gopher Robot Reviewed-by: Meidan Li --- src/cmd/asm/internal/arch/loong64.go | 11 +++++++++++ src/cmd/asm/internal/asm/asm.go | 12 ++++++++++++ src/cmd/asm/internal/asm/testdata/loong64enc1.s | 4 ++++ 3 files changed, 27 insertions(+) (limited to 'src/cmd/asm/internal') diff --git a/src/cmd/asm/internal/arch/loong64.go b/src/cmd/asm/internal/arch/loong64.go index ebf842c1f2..2958ee1a86 100644 --- a/src/cmd/asm/internal/arch/loong64.go +++ b/src/cmd/asm/internal/arch/loong64.go @@ -44,6 +44,17 @@ func IsLoong64MUL(op obj.As) bool { return false } +// IsLoong64RDTIME reports whether the op (as defined by an loong64.A* +// constant) is one of the RDTIMELW/RDTIMEHW/RDTIMED instructions that +// require special handling. +func IsLoong64RDTIME(op obj.As) bool { + switch op { + case loong64.ARDTIMELW, loong64.ARDTIMEHW, loong64.ARDTIMED: + return true + } + return false +} + func loong64RegisterNumber(name string, n int16) (int16, bool) { switch name { case "F": diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 00fb7f417f..4d0eeacc74 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -642,6 +642,18 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { prog.Reg = p.getRegister(prog, op, &a[1]) break } + + if arch.IsLoong64RDTIME(op) { + // The Loong64 RDTIME family of instructions is a bit special, + // in that both its register operands are outputs + prog.To = a[0] + if a[1].Type != obj.TYPE_REG { + p.errorf("invalid addressing modes for 2nd operand to %s instruction, must be register", op) + return + } + prog.RegTo2 = a[1].Reg + break + } } prog.From = a[0] prog.To = a[1] diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s index 83bb6ec078..0cc077c091 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s @@ -218,3 +218,7 @@ lable2: CMPGEF F4, R5 // a090130c CMPGED F4, R5 // a090230c CMPEQD F4, R5 // a010220c + + RDTIMELW R4, R0 // 80600000 + RDTIMEHW R4, R0 // 80640000 + RDTIMED R4, R5 // 85680000 -- cgit v1.3-5-g9baa