summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@wdc.com>2020-08-28 16:05:56 +0100
committerIan Lance Taylor <iant@golang.org>2020-09-30 19:47:48 -0700
commit2c5499b57cf4a68ebc8decce90d3eb1e281c31a9 (patch)
treea53f1214796df28a6c081cdcd556c5bdd1bda5c9 /libgo
parent2dd7b93778d551b6981c8086ecb38e26f677bd2b (diff)
libgo: add 32-bit RISC-V (RV32) support
Add support for the 32-bit RISC-V (RV32) ISA matching the 64-bit RISC-V (RV64) port except for async preemption added as a stub only. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/251179
Diffstat (limited to 'libgo')
-rwxr-xr-xlibgo/configure17
-rw-r--r--libgo/configure.ac10
-rw-r--r--libgo/go/cmd/cgo/main.go2
-rw-r--r--libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt3
-rw-r--r--libgo/go/cmd/internal/sys/arch.go11
-rw-r--r--libgo/go/debug/elf/file.go43
-rw-r--r--libgo/go/go/types/sizes.go4
-rw-r--r--libgo/go/golang.org/x/sys/cpu/cpu_riscv.go7
-rw-r--r--libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go2
-rw-r--r--libgo/go/internal/bytealg/indexbyte_generic.go2
-rw-r--r--libgo/go/internal/bytealg/indexbyte_native.go2
-rw-r--r--libgo/go/internal/syscall/unix/sysnum_linux_generic.go2
-rw-r--r--libgo/go/runtime/gcinfo_test.go2
-rw-r--r--libgo/go/runtime/hash32.go2
-rw-r--r--libgo/go/runtime/lfstack_32bit.go2
-rw-r--r--libgo/go/runtime/mkpreempt.go6
-rw-r--r--libgo/go/runtime/mpagealloc_32bit.go2
-rw-r--r--libgo/go/syscall/endian_little.go2
-rwxr-xr-xlibgo/match.sh4
-rw-r--r--libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go2
-rw-r--r--libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go2
-rwxr-xr-xlibgo/testsuite/gotest4
22 files changed, 113 insertions, 20 deletions
diff --git a/libgo/configure b/libgo/configure
index 7be95718962..641d060ffac 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -14226,8 +14226,21 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
;;
- riscv64-*-*)
- GOARCH=riscv64
+ riscv*-*-*)
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if __riscv_xlen == 64
+#error 64-bit
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ GOARCH=riscv
+else
+ GOARCH=riscv64
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
;;
s390*-*-*)
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
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