risc-v: add support for 64-bit RISC-V CPUs
Этот коммит содержится в:
родитель
d61d5d7ab1
коммит
2396c22658
8 изменённых файлов: 100 добавлений и 8 удалений
|
@ -1,6 +1,6 @@
|
||||||
package volatile
|
package volatile
|
||||||
|
|
||||||
// This file defines Register{8,16,32} types, which are convenience types for
|
// This file defines Register{8,16,32,64} types, which are convenience types for
|
||||||
// volatile register accesses.
|
// volatile register accesses.
|
||||||
|
|
||||||
// Special types that causes loads/stores to be volatile (necessary for
|
// Special types that causes loads/stores to be volatile (necessary for
|
||||||
|
@ -190,3 +190,65 @@ func (r *Register32) HasBits(value uint32) bool {
|
||||||
func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) {
|
func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) {
|
||||||
StoreUint32(&r.Reg, LoadUint32(&r.Reg)&^(mask<<pos)|value<<pos)
|
StoreUint32(&r.Reg, LoadUint32(&r.Reg)&^(mask<<pos)|value<<pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Register64 struct {
|
||||||
|
Reg uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns the value in the register. It is the volatile equivalent of:
|
||||||
|
//
|
||||||
|
// *r.Reg
|
||||||
|
//
|
||||||
|
//go:inline
|
||||||
|
func (r *Register64) Get() uint64 {
|
||||||
|
return LoadUint64(&r.Reg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set updates the register value. It is the volatile equivalent of:
|
||||||
|
//
|
||||||
|
// *r.Reg = value
|
||||||
|
//
|
||||||
|
//go:inline
|
||||||
|
func (r *Register64) Set(value uint64) {
|
||||||
|
StoreUint64(&r.Reg, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBits reads the register, sets the given bits, and writes it back. It is
|
||||||
|
// the volatile equivalent of:
|
||||||
|
//
|
||||||
|
// r.Reg |= value
|
||||||
|
//
|
||||||
|
//go:inline
|
||||||
|
func (r *Register64) SetBits(value uint64) {
|
||||||
|
StoreUint64(&r.Reg, LoadUint64(&r.Reg)|value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearBits reads the register, clears the given bits, and writes it back. It
|
||||||
|
// is the volatile equivalent of:
|
||||||
|
//
|
||||||
|
// r.Reg &^= value
|
||||||
|
//
|
||||||
|
//go:inline
|
||||||
|
func (r *Register64) ClearBits(value uint64) {
|
||||||
|
StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasBits reads the register and then checks to see if the passed bits are set. It
|
||||||
|
// is the volatile equivalent of:
|
||||||
|
//
|
||||||
|
// (*r.Reg & value) > 0
|
||||||
|
//
|
||||||
|
//go:inline
|
||||||
|
func (r *Register64) HasBits(value uint64) bool {
|
||||||
|
return (r.Get() & value) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
||||||
|
// once. It is the volatile equivalent of:
|
||||||
|
//
|
||||||
|
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
||||||
|
//
|
||||||
|
// go:inline
|
||||||
|
func (r *Register64) ReplaceBits(value uint64, mask uint64, pos uint8) {
|
||||||
|
StoreUint64(&r.Reg, LoadUint64(&r.Reg)&^(mask<<pos)|value<<pos)
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ func LoadUint16(addr *uint16) (val uint16)
|
||||||
// LoadUint32 loads the volatile value *addr.
|
// LoadUint32 loads the volatile value *addr.
|
||||||
func LoadUint32(addr *uint32) (val uint32)
|
func LoadUint32(addr *uint32) (val uint32)
|
||||||
|
|
||||||
|
// LoadUint64 loads the volatile value *addr.
|
||||||
|
func LoadUint64(addr *uint64) (val uint64)
|
||||||
|
|
||||||
// StoreUint8 stores val to the volatile value *addr.
|
// StoreUint8 stores val to the volatile value *addr.
|
||||||
func StoreUint8(addr *uint8, val uint8)
|
func StoreUint8(addr *uint8, val uint8)
|
||||||
|
|
||||||
|
@ -32,3 +35,6 @@ func StoreUint16(addr *uint16, val uint16)
|
||||||
|
|
||||||
// StoreUint32 stores val to the volatile value *addr.
|
// StoreUint32 stores val to the volatile value *addr.
|
||||||
func StoreUint32(addr *uint32, val uint32)
|
func StoreUint32(addr *uint32, val uint32)
|
||||||
|
|
||||||
|
// StoreUint64 stores val to the volatile value *addr.
|
||||||
|
func StoreUint64(addr *uint64, val uint64)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"inherits": ["riscv"],
|
"inherits": ["riscv32"],
|
||||||
"features": ["+a", "+c", "+m"],
|
"features": ["+a", "+c", "+m"],
|
||||||
"build-tags": ["fe310", "sifive"]
|
"build-tags": ["fe310", "sifive"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"inherits": ["riscv"],
|
"inherits": ["riscv32"],
|
||||||
"features": ["+a", "+c", "+m"],
|
"features": ["+a", "+c", "+m"],
|
||||||
"build-tags": ["virt", "qemu"],
|
"build-tags": ["virt", "qemu"],
|
||||||
"linkerscript": "targets/riscv-qemu.ld",
|
"linkerscript": "targets/riscv-qemu.ld",
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"llvm-target": "riscv32--none",
|
|
||||||
"goos": "linux",
|
"goos": "linux",
|
||||||
"goarch": "arm",
|
"goarch": "arm",
|
||||||
"build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"],
|
"build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"],
|
||||||
|
@ -9,16 +8,12 @@
|
||||||
"rtlib": "compiler-rt",
|
"rtlib": "compiler-rt",
|
||||||
"libc": "picolibc",
|
"libc": "picolibc",
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"--target=riscv32--none",
|
|
||||||
"-march=rv32imac",
|
|
||||||
"-mabi=ilp32",
|
|
||||||
"-Os",
|
"-Os",
|
||||||
"-Werror",
|
"-Werror",
|
||||||
"-fno-exceptions", "-fno-unwind-tables",
|
"-fno-exceptions", "-fno-unwind-tables",
|
||||||
"-ffunction-sections", "-fdata-sections"
|
"-ffunction-sections", "-fdata-sections"
|
||||||
],
|
],
|
||||||
"ldflags": [
|
"ldflags": [
|
||||||
"-melf32lriscv",
|
|
||||||
"--gc-sections"
|
"--gc-sections"
|
||||||
],
|
],
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
|
|
12
targets/riscv32.json
Обычный файл
12
targets/riscv32.json
Обычный файл
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"inherits": ["riscv"],
|
||||||
|
"llvm-target": "riscv32--none",
|
||||||
|
"cflags": [
|
||||||
|
"--target=riscv32--none",
|
||||||
|
"-march=rv32imac",
|
||||||
|
"-mabi=ilp32"
|
||||||
|
],
|
||||||
|
"ldflags": [
|
||||||
|
"-melf32lriscv"
|
||||||
|
]
|
||||||
|
}
|
13
targets/riscv64.json
Обычный файл
13
targets/riscv64.json
Обычный файл
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"inherits": ["riscv"],
|
||||||
|
"llvm-target": "riscv64--none",
|
||||||
|
"build-tags": ["tinygo.riscv64"],
|
||||||
|
"cflags": [
|
||||||
|
"--target=riscv64--none",
|
||||||
|
"-march=rv64gc",
|
||||||
|
"-mabi=lp64"
|
||||||
|
],
|
||||||
|
"ldflags": [
|
||||||
|
"-melf64lriscv"
|
||||||
|
]
|
||||||
|
}
|
|
@ -681,6 +681,8 @@ var (
|
||||||
|
|
||||||
var regType string
|
var regType string
|
||||||
switch register.elementSize {
|
switch register.elementSize {
|
||||||
|
case 8:
|
||||||
|
regType = "volatile.Register64"
|
||||||
case 4:
|
case 4:
|
||||||
regType = "volatile.Register32"
|
regType = "volatile.Register32"
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -710,6 +712,8 @@ var (
|
||||||
for _, subregister := range register.registers {
|
for _, subregister := range register.registers {
|
||||||
var subregType string
|
var subregType string
|
||||||
switch subregister.elementSize {
|
switch subregister.elementSize {
|
||||||
|
case 8:
|
||||||
|
subregType = "volatile.Register64"
|
||||||
case 4:
|
case 4:
|
||||||
subregType = "volatile.Register32"
|
subregType = "volatile.Register32"
|
||||||
case 2:
|
case 2:
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче