Skip to content

Commit 2396c22

Browse files
authored
risc-v: add support for 64-bit RISC-V CPUs
1 parent d61d5d7 commit 2396c22

File tree

8 files changed

+100
-8
lines changed

8 files changed

+100
-8
lines changed

src/runtime/volatile/register.go

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package volatile
22

3-
// This file defines Register{8,16,32} types, which are convenience types for
3+
// This file defines Register{8,16,32,64} types, which are convenience types for
44
// volatile register accesses.
55

66
// Special types that causes loads/stores to be volatile (necessary for
@@ -190,3 +190,65 @@ func (r *Register32) HasBits(value uint32) bool {
190190
func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) {
191191
StoreUint32(&r.Reg, LoadUint32(&r.Reg)&^(mask<<pos)|value<<pos)
192192
}
193+
194+
type Register64 struct {
195+
Reg uint64
196+
}
197+
198+
// Get returns the value in the register. It is the volatile equivalent of:
199+
//
200+
// *r.Reg
201+
//
202+
//go:inline
203+
func (r *Register64) Get() uint64 {
204+
return LoadUint64(&r.Reg)
205+
}
206+
207+
// Set updates the register value. It is the volatile equivalent of:
208+
//
209+
// *r.Reg = value
210+
//
211+
//go:inline
212+
func (r *Register64) Set(value uint64) {
213+
StoreUint64(&r.Reg, value)
214+
}
215+
216+
// SetBits reads the register, sets the given bits, and writes it back. It is
217+
// the volatile equivalent of:
218+
//
219+
// r.Reg |= value
220+
//
221+
//go:inline
222+
func (r *Register64) SetBits(value uint64) {
223+
StoreUint64(&r.Reg, LoadUint64(&r.Reg)|value)
224+
}
225+
226+
// ClearBits reads the register, clears the given bits, and writes it back. It
227+
// is the volatile equivalent of:
228+
//
229+
// r.Reg &^= value
230+
//
231+
//go:inline
232+
func (r *Register64) ClearBits(value uint64) {
233+
StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^value)
234+
}
235+
236+
// HasBits reads the register and then checks to see if the passed bits are set. It
237+
// is the volatile equivalent of:
238+
//
239+
// (*r.Reg & value) > 0
240+
//
241+
//go:inline
242+
func (r *Register64) HasBits(value uint64) bool {
243+
return (r.Get() & value) > 0
244+
}
245+
246+
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
247+
// once. It is the volatile equivalent of:
248+
//
249+
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
250+
//
251+
// go:inline
252+
func (r *Register64) ReplaceBits(value uint64, mask uint64, pos uint8) {
253+
StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^(mask<<pos)|value<<pos)
254+
}

src/runtime/volatile/volatile.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ func LoadUint16(addr *uint16) (val uint16)
2424
// LoadUint32 loads the volatile value *addr.
2525
func LoadUint32(addr *uint32) (val uint32)
2626

27+
// LoadUint64 loads the volatile value *addr.
28+
func LoadUint64(addr *uint64) (val uint64)
29+
2730
// StoreUint8 stores val to the volatile value *addr.
2831
func StoreUint8(addr *uint8, val uint8)
2932

@@ -32,3 +35,6 @@ func StoreUint16(addr *uint16, val uint16)
3235

3336
// StoreUint32 stores val to the volatile value *addr.
3437
func StoreUint32(addr *uint32, val uint32)
38+
39+
// StoreUint64 stores val to the volatile value *addr.
40+
func StoreUint64(addr *uint64, val uint64)

targets/fe310.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"inherits": ["riscv"],
2+
"inherits": ["riscv32"],
33
"features": ["+a", "+c", "+m"],
44
"build-tags": ["fe310", "sifive"]
55
}

targets/riscv-qemu.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"inherits": ["riscv"],
2+
"inherits": ["riscv32"],
33
"features": ["+a", "+c", "+m"],
44
"build-tags": ["virt", "qemu"],
55
"linkerscript": "targets/riscv-qemu.ld",

targets/riscv.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
2-
"llvm-target": "riscv32--none",
32
"goos": "linux",
43
"goarch": "arm",
54
"build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"],
@@ -9,16 +8,12 @@
98
"rtlib": "compiler-rt",
109
"libc": "picolibc",
1110
"cflags": [
12-
"--target=riscv32--none",
13-
"-march=rv32imac",
14-
"-mabi=ilp32",
1511
"-Os",
1612
"-Werror",
1713
"-fno-exceptions", "-fno-unwind-tables",
1814
"-ffunction-sections", "-fdata-sections"
1915
],
2016
"ldflags": [
21-
"-melf32lriscv",
2217
"--gc-sections"
2318
],
2419
"extra-files": [

targets/riscv32.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"inherits": ["riscv"],
3+
"llvm-target": "riscv32--none",
4+
"cflags": [
5+
"--target=riscv32--none",
6+
"-march=rv32imac",
7+
"-mabi=ilp32"
8+
],
9+
"ldflags": [
10+
"-melf32lriscv"
11+
]
12+
}

targets/riscv64.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"inherits": ["riscv"],
3+
"llvm-target": "riscv64--none",
4+
"build-tags": ["tinygo.riscv64"],
5+
"cflags": [
6+
"--target=riscv64--none",
7+
"-march=rv64gc",
8+
"-mabi=lp64"
9+
],
10+
"ldflags": [
11+
"-melf64lriscv"
12+
]
13+
}

tools/gen-device-svd/gen-device-svd.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ var (
681681

682682
var regType string
683683
switch register.elementSize {
684+
case 8:
685+
regType = "volatile.Register64"
684686
case 4:
685687
regType = "volatile.Register32"
686688
case 2:
@@ -710,6 +712,8 @@ var (
710712
for _, subregister := range register.registers {
711713
var subregType string
712714
switch subregister.elementSize {
715+
case 8:
716+
subregType = "volatile.Register64"
713717
case 4:
714718
subregType = "volatile.Register32"
715719
case 2:

0 commit comments

Comments
 (0)