]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/riscv: add environment call/breakpoint and base counter/timer instru...
authorJoel Sing <joel@sing.id.au>
Sat, 7 Sep 2019 18:11:07 +0000 (04:11 +1000)
committerJoel Sing <joel@sing.id.au>
Tue, 24 Sep 2019 04:16:35 +0000 (04:16 +0000)
This implements assembler support for ECALL/EBREAK, along with base
counter/timer instructions.

Based on riscv-go port.

Updates #27532

Change-Id: I690a9fd835eeddee1fe9a5616d2b2f856d3952b8
Reviewed-on: https://go-review.googlesource.com/c/go/+/195918
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/asm/internal/asm/testdata/riscvenc.s
src/cmd/internal/obj/riscv/obj.go

index 2e4d464626b886f15cb9a58309ce0a18fc8ab536..1902138504fad2c9edfe276b4a99b854a76668a7 100644 (file)
@@ -116,6 +116,19 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        REMW    X5, X6, X7                              // bb635302
        REMUW   X5, X6, X7                              // bb735302
 
+       // 10.1: Base Counters and Timers
+       RDCYCLE         X5                              // f32200c0
+       RDTIME          X5                              // f32210c0
+       RDINSTRET       X5                              // f32220c0
+
+       // Privileged ISA
+
+       // 3.2.1: Environment Call and Breakpoint
+       ECALL                                           // 73000000
+       SCALL                                           // 73000000
+       EBREAK                                          // 73001000
+       SBREAK                                          // 73001000
+
        // Arbitrary bytes (entered in little-endian mode)
        WORD    $0x12345678     // WORD $305419896      // 78563412
        WORD    $0x9abcdef0     // WORD $2596069104     // f0debc9a
index e97be4b69ed5f34430030f565744df3bad37fac6..1182053191822452030f83f8d11f18c5220fbc53 100644 (file)
@@ -68,6 +68,35 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
                        p.As = ASRAI
                }
        }
+
+       switch p.As {
+       case obj.AUNDEF, AECALL, AEBREAK, ASCALL, ASBREAK, ARDCYCLE, ARDTIME, ARDINSTRET:
+               switch p.As {
+               case obj.AUNDEF:
+                       p.As = AEBREAK
+               case ASCALL:
+                       // SCALL is the old name for ECALL.
+                       p.As = AECALL
+               case ASBREAK:
+                       // SBREAK is the old name for EBREAK.
+                       p.As = AEBREAK
+               }
+
+               ins := encode(p.As)
+               if ins == nil {
+                       panic("progedit: tried to rewrite nonexistent instruction")
+               }
+
+               // The CSR isn't exactly an offset, but it winds up in the
+               // immediate area of the encoded instruction, so record it in
+               // the Offset field.
+               p.From.Type = obj.TYPE_CONST
+               p.From.Offset = ins.csr
+               p.Reg = REG_ZERO
+               if p.To.Type == obj.TYPE_NONE {
+                       p.To.Type, p.To.Reg = obj.TYPE_REG, REG_ZERO
+               }
+       }
 }
 
 // setPCs sets the Pc field in all instructions reachable from p.
@@ -391,6 +420,17 @@ var encodingForAs = [ALAST & obj.AMask]encoding{
        AREMW & obj.AMask:   rIIIEncoding,
        AREMUW & obj.AMask:  rIIIEncoding,
 
+       // 10.1: Base Counters and Timers
+       ARDCYCLE & obj.AMask:   iIEncoding,
+       ARDTIME & obj.AMask:    iIEncoding,
+       ARDINSTRET & obj.AMask: iIEncoding,
+
+       // Privileged ISA
+
+       // 3.2.1: Environment Call and Breakpoint
+       AECALL & obj.AMask:  iIEncoding,
+       AEBREAK & obj.AMask: iIEncoding,
+
        // Escape hatch
        AWORD & obj.AMask: rawEncoding,