arm64/arm64gen: get system register readable and writeable attribute

This patch gets the readable and writeable property of system register from the
generator sysreggen.go and writes it to the sysRegEnc.go file. This attribute
would be used by assembler to check the correctness of system register's
read/write access for MRS/MSR instruction.

Change-Id: I637f86710c9f53e9e621d1dd6b7c4142f7bd4c11
Reviewed-on: https://go-review.googlesource.com/c/arch/+/194937
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
diaxu01 2019-08-21 09:42:33 +00:00 коммит произвёл Cherry Zhang
Родитель 1137aedcb1
Коммит 4e8777c89b
1 изменённых файлов: 63 добавлений и 11 удалений

Просмотреть файл

@ -82,8 +82,9 @@ type Enc struct {
}
type SystemReg struct {
RegName string
EncBinary uint32
RegName string
EncBinary uint32
RegAccessFlags string
}
func check(e error) {
@ -92,6 +93,26 @@ func check(e error) {
}
}
type accessFlag uint8
const (
SR_READ accessFlag = 1 << iota
SR_WRITE
)
func (a accessFlag) String() string {
switch a {
case SR_READ:
return "SR_READ"
case SR_WRITE:
return "SR_WRITE"
case SR_READ | SR_WRITE:
return "SR_READ | SR_WRITE"
default:
return ""
}
}
func main() {
// Write system register encoding to the sysRegEnc.go file.
// This file should be put into $GOROOT/src/cmd/internal/obj/arm64/ directory.
@ -149,6 +170,19 @@ func main() {
continue
}
m := sysreg.AccessMechanisms.AccessMechanism
accessF := accessFlag(0)
for j := range m {
accessor := m[j].Accessor
if strings.Contains(accessor, "MRS") {
accessF |= SR_READ
}
if strings.Contains(accessor, "MSR") {
accessF |= SR_WRITE
}
}
aFlags := accessF.String()
max := 0
var enc [5]uint64
if len(m0.Encoding.Enc) != 5 {
@ -162,11 +196,11 @@ func main() {
check(err)
for n := 0; n <= max; n++ {
name := strings.Replace(sysregName, "<n>", strconv.Itoa(n), -1)
systemregs = append(systemregs, SystemReg{name, 0})
systemregs = append(systemregs, SystemReg{name, 0, aFlags})
regNum++
}
} else {
systemregs = append(systemregs, SystemReg{sysregName, 0})
systemregs = append(systemregs, SystemReg{sysregName, 0, aFlags})
regNum++
}
for i := 0; i <= max; i++ {
@ -237,15 +271,33 @@ func main() {
fmt.Fprintf(w, "\tREG_%s\n", systemregs[i].RegName)
}
fmt.Fprintln(w, "\tSYSREG_END\n)")
fmt.Fprintln(w, "\nvar SystemReg = []struct {\n\tName string\n\tReg int16\n\tEnc uint32\n}{")
fmt.Fprintln(w, `
const (
SR_READ = 1 << iota
SR_WRITE
)
var SystemReg = []struct {
Name string
Reg int16
Enc uint32
// AccessFlags is the readable and writeable property of system register.
AccessFlags uint8
}{`)
for i := 0; i < regNum; i++ {
fmt.Fprintf(w, "\t{\"%s\", REG_%s, 0x%x},\n", systemregs[i].RegName, systemregs[i].RegName, systemregs[i].EncBinary)
fmt.Fprintf(w, "\t{\"%s\", REG_%s, 0x%x, %s},\n", systemregs[i].RegName, systemregs[i].RegName, systemregs[i].EncBinary, systemregs[i].RegAccessFlags)
}
fmt.Fprintln(w, "}")
fmt.Fprintln(w, "\nfunc SysRegEnc(r int16) (string, uint32) {")
fmt.Fprintln(w, "\t// The automatic generator guarantees that the order")
fmt.Fprintln(w, "\t// of Reg in SystemReg struct is consistent with the")
fmt.Fprintln(w, "\t// order of system register declarations")
fmt.Fprintln(w, "\tif r <= SYSREG_BEGIN || r >= SYSREG_END {\n\t\treturn \"\", 0\n\t}\n\tv := SystemReg[r-SYSREG_BEGIN-1]\n\treturn v.Name, v.Enc\n}")
fmt.Fprintln(w, `
func SysRegEnc(r int16) (string, uint32, uint8) {
// The automatic generator guarantees that the order
// of Reg in SystemReg struct is consistent with the
// order of system register declarations
if r <= SYSREG_BEGIN || r >= SYSREG_END {
return "", 0, 0
}
v := SystemReg[r-SYSREG_BEGIN-1]
return v.Name, v.Enc, v.AccessFlags
}`)
w.Flush()
}