This libgo patch by Maciej W. Rozycki adds 32-bit RISC-V support.
Bootstrapped and ran Go tests on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian
a119b20263517656379c4833a3341031a6d58dc4
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 314ffd2efab..8d9fda54619 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-9e55baf44ab63ba06af0b57038e7b3aab8216222
+c9c084bce713e258721e12041a351ec8ad33ad17
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/configure.ac b/libgo/configure.ac
index abc58b87b53..f15f8d830bb 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -342,8 +342,14 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
 [GOARCH=ppc64le],
 [GOARCH=ppc64])])
     ;;
-  riscv64-*-*)
-    GOARCH=riscv64
+  riscv*-*-*)
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+#if __riscv_xlen == 64
+#error 64-bit
+#endif
+])],
+[GOARCH=riscv],
+[GOARCH=riscv64])
     ;;
   s390*-*-*)
     AC_COMPILE_IFELSE([AC_LANG_SOURCE([
diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go
index 80f35681d75..6de6d69ce6c 100644
--- a/libgo/go/cmd/cgo/main.go
+++ b/libgo/go/cmd/cgo/main.go
@@ -184,6 +184,7 @@ var ptrSizeMap = map[string]int64{
        "ppc":         4,
        "ppc64":       8,
        "ppc64le":     8,
+       "riscv":       4,
        "riscv64":     8,
        "s390":        4,
        "s390x":       8,
@@ -210,6 +211,7 @@ var intSizeMap = map[string]int64{
        "ppc":         4,
        "ppc64":       8,
        "ppc64le":     8,
+       "riscv":       4,
        "riscv64":     8,
        "s390":        4,
        "s390x":       8,
diff --git a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt 
b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt
index 46b0ef4200e..3030ee924ff 100644
--- a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt
+++ b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt
@@ -8,8 +8,9 @@
 # See: https://github.com/golang/go/issues/8912
 [linux] [ppc64] skip
 
-# External linking is not supported on linux/riscv64.
+# External linking is not supported on linux/riscv, linux/riscv64.
 # See: https://github.com/golang/go/issues/36739
+[linux] [riscv] skip
 [linux] [riscv64] skip
 
 cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c
diff --git a/libgo/go/cmd/internal/sys/arch.go 
b/libgo/go/cmd/internal/sys/arch.go
index e8687363def..60a3b3c8ecd 100644
--- a/libgo/go/cmd/internal/sys/arch.go
+++ b/libgo/go/cmd/internal/sys/arch.go
@@ -19,6 +19,7 @@ const (
        MIPS
        MIPS64
        PPC64
+       RISCV
        RISCV64
        S390X
        Wasm
@@ -143,6 +144,15 @@ var ArchPPC64LE = &Arch{
        MinLC:     4,
 }
 
+var ArchRISCV = &Arch{
+       Name:      "riscv",
+       Family:    RISCV,
+       ByteOrder: binary.LittleEndian,
+       PtrSize:   4,
+       RegSize:   4,
+       MinLC:     4,
+}
+
 var ArchRISCV64 = &Arch{
        Name:      "riscv64",
        Family:    RISCV64,
@@ -181,6 +191,7 @@ var Archs = [...]*Arch{
        ArchMIPS64LE,
        ArchPPC64,
        ArchPPC64LE,
+       ArchRISCV,
        ArchRISCV64,
        ArchS390X,
        ArchWasm,
diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go
index b9a8b1e0cbb..48178d480d7 100644
--- a/libgo/go/debug/elf/file.go
+++ b/libgo/go/debug/elf/file.go
@@ -617,6 +617,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) 
error {
                return f.applyRelocationsMIPS(dst, rels)
        case f.Class == ELFCLASS64 && f.Machine == EM_MIPS:
                return f.applyRelocationsMIPS64(dst, rels)
+       case f.Class == ELFCLASS32 && f.Machine == EM_RISCV:
+               return f.applyRelocationsRISCV(dst, rels)
        case f.Class == ELFCLASS64 && f.Machine == EM_RISCV:
                return f.applyRelocationsRISCV64(dst, rels)
        case f.Class == ELFCLASS64 && f.Machine == EM_S390:
@@ -1008,6 +1010,47 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels 
[]byte) error {
        return nil
 }
 
+func (f *File) applyRelocationsRISCV(dst []byte, rels []byte) error {
+       // 12 is the size of Rela32.
+       if len(rels)%12 != 0 {
+               return errors.New("length of relocation section is not a 
multiple of 12")
+       }
+
+       symbols, _, err := f.getSymbols(SHT_SYMTAB)
+       if err != nil {
+               return err
+       }
+
+       b := bytes.NewReader(rels)
+       var rela Rela32
+
+       for b.Len() > 0 {
+               binary.Read(b, f.ByteOrder, &rela)
+               symNo := rela.Info >> 8
+               t := R_RISCV(rela.Info & 0xff)
+
+               if symNo == 0 || symNo > uint32(len(symbols)) {
+                       continue
+               }
+               sym := &symbols[symNo-1]
+               needed, val := relocSymbolTargetOK(sym)
+               if !needed {
+                       continue
+               }
+
+               switch t {
+               case R_RISCV_32:
+                       if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
+                               continue
+                       }
+                       val32 := uint32(val) + uint32(rela.Addend)
+                       f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+               }
+       }
+
+       return nil
+}
+
 func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
        // 24 is the size of Rela64.
        if len(rels)%24 != 0 {
diff --git a/libgo/go/go/types/sizes.go b/libgo/go/go/types/sizes.go
index 6ab6157b82d..4787b242cc0 100644
--- a/libgo/go/go/types/sizes.go
+++ b/libgo/go/go/types/sizes.go
@@ -167,6 +167,7 @@ var gcArchSizes = map[string]*StdSizes{
        "mips64le": {8, 8},
        "ppc64":    {8, 8},
        "ppc64le":  {8, 8},
+       "riscv":    {4, 4},
        "riscv64":  {8, 8},
        "s390x":    {8, 8},
        "sparc64":  {8, 8},
@@ -180,7 +181,8 @@ var gcArchSizes = map[string]*StdSizes{
 //
 // Supported architectures for compiler "gc":
 // "386", "arm", "arm64", "amd64", "amd64p32", "mips", "mipsle",
-// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", 
"wasm".
+// "mips64", "mips64le", "ppc64", "ppc64le", "riscv", "riscv64",
+// "s390x", "sparc64", "wasm".
 func SizesFor(compiler, arch string) Sizes {
        var m map[string]*StdSizes
        switch compiler {
diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_riscv.go 
b/libgo/go/golang.org/x/sys/cpu/cpu_riscv.go
new file mode 100644
index 00000000000..891cb98b455
--- /dev/null
+++ b/libgo/go/golang.org/x/sys/cpu/cpu_riscv.go
@@ -0,0 +1,7 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build riscv
+
+package cpu
diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go 
b/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
index e6bfe715391..0f521503ac6 100644
--- a/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
+++ b/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
@@ -87,6 +87,7 @@ var (
        asmArchMips64LE = asmArch{name: "mips64le", bigEndian: false, stack: 
"R29", lr: true}
        asmArchPpc64    = asmArch{name: "ppc64", bigEndian: true, stack: "R1", 
lr: true}
        asmArchPpc64LE  = asmArch{name: "ppc64le", bigEndian: false, stack: 
"R1", lr: true}
+       asmArchRISCV    = asmArch{name: "riscv", bigEndian: false, stack: "SP", 
lr: true}
        asmArchRISCV64  = asmArch{name: "riscv64", bigEndian: false, stack: 
"SP", lr: true}
        asmArchS390X    = asmArch{name: "s390x", bigEndian: true, stack: "R15", 
lr: true}
        asmArchWasm     = asmArch{name: "wasm", bigEndian: false, stack: "SP", 
lr: false}
@@ -102,6 +103,7 @@ var (
                &asmArchMips64LE,
                &asmArchPpc64,
                &asmArchPpc64LE,
+               &asmArchRISCV,
                &asmArchRISCV64,
                &asmArchS390X,
                &asmArchWasm,
diff --git a/libgo/go/internal/bytealg/indexbyte_generic.go 
b/libgo/go/internal/bytealg/indexbyte_generic.go
index a863d814b6b..46325dd7f07 100644
--- a/libgo/go/internal/bytealg/indexbyte_generic.go
+++ b/libgo/go/internal/bytealg/indexbyte_generic.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build ignore_for_gccgo
-// +build 
!386,!amd64,!s390x,!arm,!arm64,!ppc64,!ppc64le,!mips,!mipsle,!mips64,!mips64le,!riscv64,!wasm
+// +build 
!386,!amd64,!s390x,!arm,!arm64,!ppc64,!ppc64le,!mips,!mipsle,!mips64,!mips64le,!riscv,!riscv64,!wasm
 
 package bytealg
 
diff --git a/libgo/go/internal/bytealg/indexbyte_native.go 
b/libgo/go/internal/bytealg/indexbyte_native.go
index 20da788fb86..c427e669bbd 100644
--- a/libgo/go/internal/bytealg/indexbyte_native.go
+++ b/libgo/go/internal/bytealg/indexbyte_native.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// -build 386 amd64 s390x arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le 
riscv64 wasm
+// -build 386 amd64 s390x arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le 
riscv riscv64 wasm
 
 package bytealg
 
diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_generic.go 
b/libgo/go/internal/syscall/unix/sysnum_linux_generic.go
index 3e00703679a..3d34fdb73e3 100644
--- a/libgo/go/internal/syscall/unix/sysnum_linux_generic.go
+++ b/libgo/go/internal/syscall/unix/sysnum_linux_generic.go
@@ -9,7 +9,7 @@ package unix
 
 // This file is named "generic" because at a certain point Linux started
 // standardizing on system call numbers across architectures. So far this
-// means only arm64, nios2 and riscv use the standard numbers.
+// means only arm64, nios2, riscv and riscv64 use the standard numbers.
 
 const (
        getrandomTrap     uintptr = 278
diff --git a/libgo/go/runtime/gcinfo_test.go b/libgo/go/runtime/gcinfo_test.go
index ddbe5dd5fea..c26f411153f 100644
--- a/libgo/go/runtime/gcinfo_test.go
+++ b/libgo/go/runtime/gcinfo_test.go
@@ -157,7 +157,7 @@ type BigStruct struct {
 
 func infoBigStruct() []byte {
        switch runtime.GOARCH {
-       case "386", "arm", "mips", "mipsle":
+       case "386", "arm", "mips", "mipsle", "riscv":
                return []byte{
                        typePointer,                                            
    // q *int
                        typeScalar, typeScalar, typeScalar, typeScalar, 
typeScalar, // w byte; e [17]byte
diff --git a/libgo/go/runtime/hash32.go b/libgo/go/runtime/hash32.go
index fba6bc354b1..89efc1cde5c 100644
--- a/libgo/go/runtime/hash32.go
+++ b/libgo/go/runtime/hash32.go
@@ -6,7 +6,7 @@
 //   xxhash: https://code.google.com/p/xxhash/
 // cityhash: https://code.google.com/p/cityhash/
 
-// +build 386 arm armbe m68k mips mipsle nios2 ppc s390 sh shbe sparc
+// +build 386 arm armbe m68k mips mipsle nios2 ppc riscv s390 sh shbe sparc
 
 package runtime
 
diff --git a/libgo/go/runtime/lfstack_32bit.go 
b/libgo/go/runtime/lfstack_32bit.go
index 6da037e3f36..b3194dc7668 100644
--- a/libgo/go/runtime/lfstack_32bit.go
+++ b/libgo/go/runtime/lfstack_32bit.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build 386 amd64p32 arm armbe m68k mips mipsle mips64p32 mips64p32le nios2 
ppc s390 sh shbe sparc
+// +build 386 amd64p32 arm armbe m68k mips mipsle mips64p32 mips64p32le nios2 
ppc riscv s390 sh shbe sparc
 
 package runtime
 
diff --git a/libgo/go/runtime/mkpreempt.go b/libgo/go/runtime/mkpreempt.go
index 1fe77663b9c..268941d3532 100644
--- a/libgo/go/runtime/mkpreempt.go
+++ b/libgo/go/runtime/mkpreempt.go
@@ -83,6 +83,7 @@ var arches = map[string]func(){
        "mips64x": func() { genMIPS(true) },
        "mipsx":   func() { genMIPS(false) },
        "ppc64x":  genPPC64,
+       "riscv":   genRISCV,
        "riscv64": genRISCV64,
        "s390x":   genS390X,
        "wasm":    genWasm,
@@ -501,6 +502,11 @@ func genPPC64() {
        p("JMP (CTR)")
 }
 
+func genRISCV() {
+       p("// No async preemption on riscv - see issue 36711")
+       p("UNDEF")
+}
+
 func genRISCV64() {
        // X0 (zero), X1 (LR), X2 (SP), X4 (g), X31 (TMP) are special.
        var l = layout{sp: "X2", stack: 8}
diff --git a/libgo/go/runtime/mpagealloc_32bit.go 
b/libgo/go/runtime/mpagealloc_32bit.go
index d18970ca26c..249b5fea01b 100644
--- a/libgo/go/runtime/mpagealloc_32bit.go
+++ b/libgo/go/runtime/mpagealloc_32bit.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build 386 arm mips mipsle wasm darwin,arm64 amd64p32 armbe m68k mips64p32 
mips64p32le nios2 ppc s390 sh shbe sparc
+// +build 386 arm mips mipsle wasm darwin,arm64 amd64p32 armbe m68k mips64p32 
mips64p32le nios2 ppc riscv s390 sh shbe sparc
 
 // wasm is a treated as a 32-bit architecture for the purposes of the page
 // allocator, even though it has 64-bit pointers. This is because any wasm
diff --git a/libgo/go/syscall/endian_little.go 
b/libgo/go/syscall/endian_little.go
index 0cd2d7524c6..22cac17ef11 100644
--- a/libgo/go/syscall/endian_little.go
+++ b/libgo/go/syscall/endian_little.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
-// +build 386 alpha amd64 amd64p32 arm arm64 ia64 mips64le mipsle mips64p32le 
nios2 ppc64le riscv64 sh wasm
+// +build 386 alpha amd64 amd64p32 arm arm64 ia64 mips64le mipsle mips64p32le 
nios2 ppc64le riscv riscv64 sh wasm
 
 package syscall
 
diff --git a/libgo/match.sh b/libgo/match.sh
index cd35942f8bc..6f7b368f8bf 100755
--- a/libgo/match.sh
+++ b/libgo/match.sh
@@ -116,7 +116,7 @@ for f in $gofiles; do
        aix | android | darwin | dragonfly | freebsd | illumos | hurd | js | 
linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
            tag1=nonmatchingtag
            ;;
-       386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | 
m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | 
ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | 
wasm)
+       386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | 
m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | 
ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | 
sparc64 | wasm)
            tag1=nonmatchingtag
            ;;
     esac
@@ -128,7 +128,7 @@ for f in $gofiles; do
        aix | android | darwin | dragonfly | freebsd | hurd | illumos | js | 
linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
            tag2=nonmatchingtag
            ;;
-       386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | 
m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | 
ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | 
wasm)
+       386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | 
m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | 
ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | 
sparc64 | wasm)
            tag2=nonmatchingtag
            ;;
     esac
diff --git a/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go 
b/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go
index d343aa54d9a..3b53e1ceea2 100644
--- a/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go
+++ b/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux,!arm64,!riscv64 netbsd openbsd
+// +build darwin dragonfly freebsd linux,!arm64,!riscv,!riscv64 netbsd openbsd
 
 package main
 
diff --git a/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go 
b/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go
index 459f0dc1968..79a37730c84 100644
--- a/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go
+++ b/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux,arm64 linux,riscv64
+// +build linux,arm64 linux,riscv,riscv64
 
 package main
 
diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest
index eadafa1a7cd..5bb27ec1631 100755
--- a/libgo/testsuite/gotest
+++ b/libgo/testsuite/gotest
@@ -308,7 +308,7 @@ x)
            aix | android | darwin | dragonfly | freebsd | hurd | illumos | js 
| linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
                tag1=nonmatchingtag
                ;;
-           386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | 
ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | 
nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | 
sparc64 | wasm)
+           386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | 
ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | 
nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | 
sparc | sparc64 | wasm)
                tag1=nonmatchingtag
                ;;
            esac
@@ -320,7 +320,7 @@ x)
            aix | android | darwin | dragonfly | freebsd | hurd | illumos | js 
| linux | nacl | netbsd | openbsd | plan9 | solaris | windows)
                tag2=nonmatchingtag
                ;;
-           386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | 
ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | 
nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | 
sparc64 | wasm)
+           386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | 
ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | 
nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | 
sparc | sparc64 | wasm)
                tag2=nonmatchingtag
                ;;
            esac

Reply via email to