cmd/5g etc: mechanical cleanup

Run rsc.io/grind rev a26569f on C->Go conversions.

The new change in grind is the inlining of goto targets.
If code says 'goto x' and the block starting at label x is unreachable
except through that goto and the code can be moved to where
the goto is without changing the meaning of its variable names,
grind does that move. Simlarly, a goto to a plain return statement
turns into that return statement (even if there are other paths to
the return statement).

Combined, these remove many long-distance gotos, which in turn
makes it possible to reduce the scope of more variable declarations.
(Because gotos can't jump across declarations, the gotos were
keeping the declarations from moving.)

Checked bit-for-bit compatibility with toolstash + buildall.

Reduces compiler runtime in html/template by about 12%.

Change-Id: Id727c0bd7763a61aa22f3daa00aeb8fccbc057a3
Reviewed-on: https://go-review.googlesource.com/6472
Reviewed-by: Aram Hăvărneanu <aram@mgk.ro>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
diff --git a/src/cmd/internal/gc/const.go b/src/cmd/internal/gc/const.go
index 43c8809..4730d7d 100644
--- a/src/cmd/internal/gc/const.go
+++ b/src/cmd/internal/gc/const.go
@@ -582,7 +582,96 @@
 	var v Val
 	var norig *Node
 	if nr == nil {
-		goto unary
+		// copy numeric value to avoid modifying
+		// nl, in case someone still refers to it (e.g. iota).
+		v = nl.Val
+
+		if wl == TIDEAL {
+			v = copyval(v)
+		}
+
+		switch uint32(n.Op)<<16 | uint32(v.Ctype) {
+		default:
+			if n.Diag == 0 {
+				Yyerror("illegal constant expression %v %v", Oconv(int(n.Op), 0), Tconv(nl.Type, 0))
+				n.Diag = 1
+			}
+
+			return
+
+		case OCONV<<16 | CTNIL,
+			OARRAYBYTESTR<<16 | CTNIL:
+			if n.Type.Etype == TSTRING {
+				v = tostr(v)
+				nl.Type = n.Type
+				break
+			}
+			fallthrough
+
+			// fall through
+		case OCONV<<16 | CTINT,
+			OCONV<<16 | CTRUNE,
+			OCONV<<16 | CTFLT,
+			OCONV<<16 | CTSTR:
+			convlit1(&nl, n.Type, true)
+
+			v = nl.Val
+
+		case OPLUS<<16 | CTINT,
+			OPLUS<<16 | CTRUNE:
+			break
+
+		case OMINUS<<16 | CTINT,
+			OMINUS<<16 | CTRUNE:
+			mpnegfix(v.U.Xval)
+
+		case OCOM<<16 | CTINT,
+			OCOM<<16 | CTRUNE:
+			et := Txxx
+			if nl.Type != nil {
+				et = int(nl.Type.Etype)
+			}
+
+			// calculate the mask in b
+			// result will be (a ^ mask)
+			var b Mpint
+			switch et {
+			// signed guys change sign
+			default:
+				Mpmovecfix(&b, -1)
+
+				// unsigned guys invert their bits
+			case TUINT8,
+				TUINT16,
+				TUINT32,
+				TUINT64,
+				TUINT,
+				TUINTPTR:
+				mpmovefixfix(&b, Maxintval[et])
+			}
+
+			mpxorfixfix(v.U.Xval, &b)
+
+		case OPLUS<<16 | CTFLT:
+			break
+
+		case OMINUS<<16 | CTFLT:
+			mpnegflt(v.U.Fval)
+
+		case OPLUS<<16 | CTCPLX:
+			break
+
+		case OMINUS<<16 | CTCPLX:
+			mpnegflt(&v.U.Cval.Real)
+			mpnegflt(&v.U.Cval.Imag)
+
+		case ONOT<<16 | CTBOOL:
+			if v.U.Bval == 0 {
+				goto settrue
+			}
+			goto setfalse
+		}
+		goto ret
 	}
 	if nr.Type == nil {
 		return
@@ -944,97 +1033,6 @@
 
 	goto ret
 
-	// copy numeric value to avoid modifying
-	// nl, in case someone still refers to it (e.g. iota).
-unary:
-	v = nl.Val
-
-	if wl == TIDEAL {
-		v = copyval(v)
-	}
-
-	switch uint32(n.Op)<<16 | uint32(v.Ctype) {
-	default:
-		if n.Diag == 0 {
-			Yyerror("illegal constant expression %v %v", Oconv(int(n.Op), 0), Tconv(nl.Type, 0))
-			n.Diag = 1
-		}
-
-		return
-
-	case OCONV<<16 | CTNIL,
-		OARRAYBYTESTR<<16 | CTNIL:
-		if n.Type.Etype == TSTRING {
-			v = tostr(v)
-			nl.Type = n.Type
-			break
-		}
-		fallthrough
-
-		// fall through
-	case OCONV<<16 | CTINT,
-		OCONV<<16 | CTRUNE,
-		OCONV<<16 | CTFLT,
-		OCONV<<16 | CTSTR:
-		convlit1(&nl, n.Type, true)
-
-		v = nl.Val
-
-	case OPLUS<<16 | CTINT,
-		OPLUS<<16 | CTRUNE:
-		break
-
-	case OMINUS<<16 | CTINT,
-		OMINUS<<16 | CTRUNE:
-		mpnegfix(v.U.Xval)
-
-	case OCOM<<16 | CTINT,
-		OCOM<<16 | CTRUNE:
-		et := Txxx
-		if nl.Type != nil {
-			et = int(nl.Type.Etype)
-		}
-
-		// calculate the mask in b
-		// result will be (a ^ mask)
-		var b Mpint
-		switch et {
-		// signed guys change sign
-		default:
-			Mpmovecfix(&b, -1)
-
-			// unsigned guys invert their bits
-		case TUINT8,
-			TUINT16,
-			TUINT32,
-			TUINT64,
-			TUINT,
-			TUINTPTR:
-			mpmovefixfix(&b, Maxintval[et])
-		}
-
-		mpxorfixfix(v.U.Xval, &b)
-
-	case OPLUS<<16 | CTFLT:
-		break
-
-	case OMINUS<<16 | CTFLT:
-		mpnegflt(v.U.Fval)
-
-	case OPLUS<<16 | CTCPLX:
-		break
-
-	case OMINUS<<16 | CTCPLX:
-		mpnegflt(&v.U.Cval.Real)
-		mpnegflt(&v.U.Cval.Imag)
-
-	case ONOT<<16 | CTBOOL:
-		if v.U.Bval == 0 {
-			goto settrue
-		}
-		goto setfalse
-	}
-
 ret:
 	norig = saveorig(n)
 	*n = *nl
diff --git a/src/cmd/internal/gc/cplx.go b/src/cmd/internal/gc/cplx.go
index c07ba34..02b6c79 100644
--- a/src/cmd/internal/gc/cplx.go
+++ b/src/cmd/internal/gc/cplx.go
@@ -255,10 +255,12 @@
 	}
 
 	if n.Op == OREAL || n.Op == OIMAG {
-		goto yes
+		//dump("\ncomplex-yes", n);
+		return true
 	}
 
-	goto no
+	//dump("\ncomplex-no", n);
+	return false
 
 maybe:
 	switch n.Op {
@@ -270,23 +272,20 @@
 		OCOMPLEX,
 		OREAL,
 		OIMAG:
-		goto yes
+		//dump("\ncomplex-yes", n);
+		return true
 
 	case ODOT,
 		ODOTPTR,
 		OINDEX,
 		OIND,
 		ONAME:
-		goto yes
+		//dump("\ncomplex-yes", n);
+		return true
 	}
 
 	//dump("\ncomplex-no", n);
-no:
 	return false
-
-	//dump("\ncomplex-yes", n);
-yes:
-	return true
 }
 
 func Complexmove(f *Node, t *Node) {
diff --git a/src/cmd/internal/gc/lex.go b/src/cmd/internal/gc/lex.go
index 4e5f011..c03222b 100644
--- a/src/cmd/internal/gc/lex.go
+++ b/src/cmd/internal/gc/lex.go
@@ -844,7 +844,6 @@
 var _yylex_lstk *Loophack
 
 func _yylex(yylval *yySymType) int32 {
-	var c int
 	var c1 int
 	var escflag int
 	var v int64
@@ -857,7 +856,7 @@
 	prevlineno = lineno
 
 l0:
-	c = getc()
+	c := getc()
 	if yy_isspace(c) {
 		if c == '\n' && curio.nlsemi != 0 {
 			ungetc(c)
@@ -887,7 +886,82 @@
 	}
 
 	if yy_isdigit(c) {
-		goto tnum
+		cp = &lexbuf
+		cp.Reset()
+		if c != '0' {
+			for {
+				cp.WriteByte(byte(c))
+				c = getc()
+				if yy_isdigit(c) {
+					continue
+				}
+				if c == '.' {
+					goto casedot
+				}
+				if c == 'e' || c == 'E' || c == 'p' || c == 'P' {
+					goto caseep
+				}
+				if c == 'i' {
+					goto casei
+				}
+				goto ncu
+			}
+		}
+
+		cp.WriteByte(byte(c))
+		c = getc()
+		if c == 'x' || c == 'X' {
+			for {
+				cp.WriteByte(byte(c))
+				c = getc()
+				if yy_isdigit(c) {
+					continue
+				}
+				if c >= 'a' && c <= 'f' {
+					continue
+				}
+				if c >= 'A' && c <= 'F' {
+					continue
+				}
+				if lexbuf.Len() == 2 {
+					Yyerror("malformed hex constant")
+				}
+				if c == 'p' {
+					goto caseep
+				}
+				goto ncu
+			}
+		}
+
+		if c == 'p' { // 0p begins floating point zero
+			goto caseep
+		}
+
+		c1 = 0
+		for {
+			if !yy_isdigit(c) {
+				break
+			}
+			if c < '0' || c > '7' {
+				c1 = 1 // not octal
+			}
+			cp.WriteByte(byte(c))
+			c = getc()
+		}
+
+		if c == '.' {
+			goto casedot
+		}
+		if c == 'e' || c == 'E' {
+			goto caseep
+		}
+		if c == 'i' {
+			goto casei
+		}
+		if c1 != 0 {
+			Yyerror("malformed octal constant")
+		}
+		goto ncu
 	}
 
 	switch c {
@@ -1321,86 +1395,6 @@
 	yylval.sym = s
 	return int32(s.Lexical)
 
-tnum:
-	cp = &lexbuf
-	cp.Reset()
-	if c != '0' {
-		for {
-			cp.WriteByte(byte(c))
-			c = getc()
-			if yy_isdigit(c) {
-				continue
-			}
-			goto dc
-		}
-	}
-
-	cp.WriteByte(byte(c))
-	c = getc()
-	if c == 'x' || c == 'X' {
-		for {
-			cp.WriteByte(byte(c))
-			c = getc()
-			if yy_isdigit(c) {
-				continue
-			}
-			if c >= 'a' && c <= 'f' {
-				continue
-			}
-			if c >= 'A' && c <= 'F' {
-				continue
-			}
-			if lexbuf.Len() == 2 {
-				Yyerror("malformed hex constant")
-			}
-			if c == 'p' {
-				goto caseep
-			}
-			goto ncu
-		}
-	}
-
-	if c == 'p' { // 0p begins floating point zero
-		goto caseep
-	}
-
-	c1 = 0
-	for {
-		if !yy_isdigit(c) {
-			break
-		}
-		if c < '0' || c > '7' {
-			c1 = 1 // not octal
-		}
-		cp.WriteByte(byte(c))
-		c = getc()
-	}
-
-	if c == '.' {
-		goto casedot
-	}
-	if c == 'e' || c == 'E' {
-		goto caseep
-	}
-	if c == 'i' {
-		goto casei
-	}
-	if c1 != 0 {
-		Yyerror("malformed octal constant")
-	}
-	goto ncu
-
-dc:
-	if c == '.' {
-		goto casedot
-	}
-	if c == 'e' || c == 'E' || c == 'p' || c == 'P' {
-		goto caseep
-	}
-	if c == 'i' {
-		goto casei
-	}
-
 ncu:
 	cp = nil
 	ungetc(c)
@@ -1523,31 +1517,90 @@
  */
 func getlinepragma() int {
 	var cmd, verb, name string
-	var n int
-	var cp *bytes.Buffer
-	var linep int
 
 	c := int(getr())
 	if c == 'g' {
-		goto go_
+		cp := &lexbuf
+		cp.Reset()
+		cp.WriteByte('g') // already read
+		for {
+			c = int(getr())
+			if c == EOF || c >= utf8.RuneSelf {
+				return c
+			}
+			if c == '\n' {
+				break
+			}
+			cp.WriteByte(byte(c))
+		}
+
+		cp = nil
+
+		if strings.HasPrefix(lexbuf.String(), "go:cgo_") {
+			pragcgo(lexbuf.String())
+		}
+
+		cmd = lexbuf.String()
+		verb = cmd
+		if i := strings.Index(verb, " "); i >= 0 {
+			verb = verb[:i]
+		}
+
+		if verb == "go:linkname" {
+			if imported_unsafe == 0 {
+				Yyerror("//go:linkname only allowed in Go files that import \"unsafe\"")
+			}
+			f := strings.Fields(cmd)
+			if len(f) != 3 {
+				Yyerror("usage: //go:linkname localname linkname")
+				return c
+			}
+
+			Lookup(f[1]).Linkname = f[2]
+			return c
+		}
+
+		if verb == "go:nointerface" && obj.Fieldtrack_enabled != 0 {
+			nointerface = true
+			return c
+		}
+
+		if verb == "go:noescape" {
+			noescape = true
+			return c
+		}
+
+		if verb == "go:nosplit" {
+			nosplit = true
+			return c
+		}
+
+		if verb == "go:nowritebarrier" {
+			if compiling_runtime == 0 {
+				Yyerror("//go:nowritebarrier only allowed in runtime")
+			}
+			nowritebarrier = true
+			return c
+		}
+		return c
 	}
 	if c != 'l' {
-		goto out
+		return c
 	}
 	for i := 1; i < 5; i++ {
 		c = int(getr())
 		if c != int("line "[i]) {
-			goto out
+			return c
 		}
 	}
 
-	cp = &lexbuf
+	cp := &lexbuf
 	cp.Reset()
-	linep = 0
+	linep := 0
 	for {
 		c = int(getr())
 		if c == EOF {
-			goto out
+			return c
 		}
 		if c == '\n' {
 			break
@@ -1564,9 +1617,9 @@
 	cp = nil
 
 	if linep == 0 {
-		goto out
+		return c
 	}
-	n = 0
+	n := 0
 	for _, c := range lexbuf.String()[linep:] {
 		if c < '0' || c > '9' {
 			goto out
@@ -1579,7 +1632,7 @@
 	}
 
 	if n <= 0 {
-		goto out
+		return c
 	}
 
 	// try to avoid allocating file name over and over
@@ -1587,76 +1640,12 @@
 	for h := Ctxt.Hist; h != nil; h = h.Link {
 		if h.Name != "" && h.Name == name {
 			linehist(h.Name, int32(n), 0)
-			goto out
+			return c
 		}
 	}
 
 	linehist(name, int32(n), 0)
-	goto out
-
-go_:
-	cp = &lexbuf
-	cp.Reset()
-	cp.WriteByte('g') // already read
-	for {
-		c = int(getr())
-		if c == EOF || c >= utf8.RuneSelf {
-			goto out
-		}
-		if c == '\n' {
-			break
-		}
-		cp.WriteByte(byte(c))
-	}
-
-	cp = nil
-
-	if strings.HasPrefix(lexbuf.String(), "go:cgo_") {
-		pragcgo(lexbuf.String())
-	}
-
-	cmd = lexbuf.String()
-	verb = cmd
-	if i := strings.Index(verb, " "); i >= 0 {
-		verb = verb[:i]
-	}
-
-	if verb == "go:linkname" {
-		if imported_unsafe == 0 {
-			Yyerror("//go:linkname only allowed in Go files that import \"unsafe\"")
-		}
-		f := strings.Fields(cmd)
-		if len(f) != 3 {
-			Yyerror("usage: //go:linkname localname linkname")
-			goto out
-		}
-
-		Lookup(f[1]).Linkname = f[2]
-		goto out
-	}
-
-	if verb == "go:nointerface" && obj.Fieldtrack_enabled != 0 {
-		nointerface = true
-		goto out
-	}
-
-	if verb == "go:noescape" {
-		noescape = true
-		goto out
-	}
-
-	if verb == "go:nosplit" {
-		nosplit = true
-		goto out
-	}
-
-	if verb == "go:nowritebarrier" {
-		if compiling_runtime == 0 {
-			Yyerror("//go:nowritebarrier only allowed in runtime")
-		}
-		nowritebarrier = true
-		goto out
-	}
+	return c
 
 out:
 	return c
@@ -1708,14 +1697,12 @@
 		var p string
 		p, ok = getquoted(&q)
 		if !ok {
-			goto err1
+			Yyerror("usage: //go:cgo_dynamic_linker \"path\"")
+			return
 		}
 		pragcgobuf += fmt.Sprintf("cgo_dynamic_linker %v\n", plan9quote(p))
-		goto out
+		return
 
-	err1:
-		Yyerror("usage: //go:cgo_dynamic_linker \"path\"")
-		goto out
 	}
 
 	if verb == "dynexport" {
@@ -1729,7 +1716,7 @@
 		}
 		if !more(&q) {
 			pragcgobuf += fmt.Sprintf("%s %v\n", verb, plan9quote(local))
-			goto out
+			return
 		}
 
 		remote = getimpsym(&q)
@@ -1737,11 +1724,11 @@
 			goto err2
 		}
 		pragcgobuf += fmt.Sprintf("%s %v %v\n", verb, plan9quote(local), plan9quote(remote))
-		goto out
+		return
 
 	err2:
 		Yyerror("usage: //go:%s local [remote]", verb)
-		goto out
+		return
 	}
 
 	if verb == "cgo_import_dynamic" || verb == "dynimport" {
@@ -1754,7 +1741,7 @@
 		}
 		if !more(&q) {
 			pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v\n", plan9quote(local))
-			goto out
+			return
 		}
 
 		remote = getimpsym(&q)
@@ -1763,7 +1750,7 @@
 		}
 		if !more(&q) {
 			pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v\n", plan9quote(local), plan9quote(remote))
-			goto out
+			return
 		}
 
 		p, ok = getquoted(&q)
@@ -1771,24 +1758,22 @@
 			goto err3
 		}
 		pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v %v\n", plan9quote(local), plan9quote(remote), plan9quote(p))
-		goto out
+		return
 
 	err3:
 		Yyerror("usage: //go:cgo_import_dynamic local [remote [\"library\"]]")
-		goto out
+		return
 	}
 
 	if verb == "cgo_import_static" {
 		local := getimpsym(&q)
 		if local == "" || more(&q) {
-			goto err4
+			Yyerror("usage: //go:cgo_import_static local")
+			return
 		}
 		pragcgobuf += fmt.Sprintf("cgo_import_static %v\n", plan9quote(local))
-		goto out
+		return
 
-	err4:
-		Yyerror("usage: //go:cgo_import_static local")
-		goto out
 	}
 
 	if verb == "cgo_ldflag" {
@@ -1796,17 +1781,13 @@
 		var p string
 		p, ok = getquoted(&q)
 		if !ok {
-			goto err5
+			Yyerror("usage: //go:cgo_ldflag \"arg\"")
+			return
 		}
 		pragcgobuf += fmt.Sprintf("cgo_ldflag %v\n", plan9quote(p))
-		goto out
+		return
 
-	err5:
-		Yyerror("usage: //go:cgo_ldflag \"arg\"")
-		goto out
 	}
-
-out:
 }
 
 type yy struct{}
@@ -1983,7 +1964,6 @@
 
 	u := 0
 	c = int(getr())
-	var l int64
 	var i int
 	switch c {
 	case 'x':
@@ -2010,7 +1990,24 @@
 		'6',
 		'7':
 		*escflg = 1 // it's a byte
-		goto oct
+		l := int64(c) - '0'
+		for i := 2; i > 0; i-- {
+			c = getc()
+			if c >= '0' && c <= '7' {
+				l = l*8 + int64(c) - '0'
+				continue
+			}
+
+			Yyerror("non-octal character in escape sequence: %c", c)
+			ungetc(c)
+		}
+
+		if l > 255 {
+			Yyerror("octal escape value > 255: %d", l)
+		}
+
+		*val = l
+		return false
 
 	case 'a':
 		c = '\a'
@@ -2039,7 +2036,7 @@
 	return false
 
 hex:
-	l = 0
+	l := int64(0)
 	for ; i > 0; i-- {
 		c = getc()
 		if c >= '0' && c <= '9' {
@@ -2069,26 +2066,6 @@
 
 	*val = l
 	return false
-
-oct:
-	l = int64(c) - '0'
-	for i := 2; i > 0; i-- {
-		c = getc()
-		if c >= '0' && c <= '7' {
-			l = l*8 + int64(c) - '0'
-			continue
-		}
-
-		Yyerror("non-octal character in escape sequence: %c", c)
-		ungetc(c)
-	}
-
-	if l > 255 {
-		Yyerror("octal escape value > 255: %d", l)
-	}
-
-	*val = l
-	return false
 }
 
 var syms = []struct {
diff --git a/src/cmd/internal/gc/mparith1.go b/src/cmd/internal/gc/mparith1.go
index 104992f..d728d6a 100644
--- a/src/cmd/internal/gc/mparith1.go
+++ b/src/cmd/internal/gc/mparith1.go
@@ -451,7 +451,6 @@
 //
 func mpatofix(a *Mpint, as string) {
 	var c int
-	var s0 string
 
 	s := as
 	f := 0
@@ -471,7 +470,43 @@
 		fallthrough
 
 	case '0':
-		goto oct
+		var c int
+		c, s = intstarstringplusplus(s)
+		if c == 'x' || c == 'X' {
+			s0 := s
+			var c int
+			c, _ = intstarstringplusplus(s)
+			for c != 0 {
+				if (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') {
+					s = s[1:]
+					c, _ = intstarstringplusplus(s)
+					continue
+				}
+
+				Yyerror("malformed hex constant: %s", as)
+				goto bad
+			}
+
+			mphextofix(a, s0)
+			if a.Ovf != 0 {
+				Yyerror("constant too large: %s", as)
+				goto bad
+			}
+			goto out
+		}
+		for c != 0 {
+			if c >= '0' && c <= '7' {
+				mpmulcfix(a, 8)
+				mpaddcfix(a, int64(c)-'0')
+				c, s = intstarstringplusplus(s)
+				continue
+			}
+
+			Yyerror("malformed octal constant: %s", as)
+			goto bad
+		}
+
+		goto out
 	}
 
 	for c != 0 {
@@ -488,45 +523,6 @@
 
 	goto out
 
-oct:
-	c, s = intstarstringplusplus(s)
-	if c == 'x' || c == 'X' {
-		goto hex
-	}
-	for c != 0 {
-		if c >= '0' && c <= '7' {
-			mpmulcfix(a, 8)
-			mpaddcfix(a, int64(c)-'0')
-			c, s = intstarstringplusplus(s)
-			continue
-		}
-
-		Yyerror("malformed octal constant: %s", as)
-		goto bad
-	}
-
-	goto out
-
-hex:
-	s0 = s
-	c, _ = intstarstringplusplus(s)
-	for c != 0 {
-		if (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') {
-			s = s[1:]
-			c, _ = intstarstringplusplus(s)
-			continue
-		}
-
-		Yyerror("malformed hex constant: %s", as)
-		goto bad
-	}
-
-	mphextofix(a, s0)
-	if a.Ovf != 0 {
-		Yyerror("constant too large: %s", as)
-		goto bad
-	}
-
 out:
 	if f != 0 {
 		mpnegfix(a)
diff --git a/src/cmd/internal/gc/mparith2.go b/src/cmd/internal/gc/mparith2.go
index c9c9230..7e12913 100644
--- a/src/cmd/internal/gc/mparith2.go
+++ b/src/cmd/internal/gc/mparith2.go
@@ -187,12 +187,44 @@
 	}
 
 	c := 0
-	var x int
 	if a.Neg != b.Neg {
-		goto sub
+		// perform a-b
+		switch mpcmp(a, b) {
+		case 0:
+			Mpmovecfix(a, 0)
+
+		case 1:
+			var x int
+			for i := 0; i < Mpprec; i++ {
+				x = a.A[i] - b.A[i] - c
+				c = 0
+				if x < 0 {
+					x += Mpbase
+					c = 1
+				}
+
+				a.A[i] = x
+			}
+
+		case -1:
+			a.Neg ^= 1
+			var x int
+			for i := 0; i < Mpprec; i++ {
+				x = b.A[i] - a.A[i] - c
+				c = 0
+				if x < 0 {
+					x += Mpbase
+					c = 1
+				}
+
+				a.A[i] = x
+			}
+		}
+		return
 	}
 
 	// perform a+b
+	var x int
 	for i := 0; i < Mpprec; i++ {
 		x = a.A[i] + b.A[i] + c
 		c = 0
@@ -210,40 +242,6 @@
 	}
 
 	return
-
-	// perform a-b
-sub:
-	switch mpcmp(a, b) {
-	case 0:
-		Mpmovecfix(a, 0)
-
-	case 1:
-		var x int
-		for i := 0; i < Mpprec; i++ {
-			x = a.A[i] - b.A[i] - c
-			c = 0
-			if x < 0 {
-				x += Mpbase
-				c = 1
-			}
-
-			a.A[i] = x
-		}
-
-	case -1:
-		a.Neg ^= 1
-		var x int
-		for i := 0; i < Mpprec; i++ {
-			x = b.A[i] - a.A[i] - c
-			c = 0
-			if x < 0 {
-				x += Mpbase
-				c = 1
-			}
-
-			a.A[i] = x
-		}
-	}
 }
 
 func mpmulfixfix(a *Mpint, b *Mpint) {
diff --git a/src/cmd/internal/gc/plive.go b/src/cmd/internal/gc/plive.go
index 86e7ea0..e6211e1 100644
--- a/src/cmd/internal/gc/plive.go
+++ b/src/cmd/internal/gc/plive.go
@@ -657,7 +657,7 @@
 				PPARAMOUT:
 				pos, ok := to.Node.(*Node).Opt.(int32) // index in vars
 				if !ok {
-					goto Next1
+					return
 				}
 				if pos >= int32(len(vars)) || vars[pos] != to.Node {
 					Fatal("bad bookkeeping in liveness %v %d", Nconv(to.Node.(*Node), 0), pos)
@@ -690,8 +690,6 @@
 			}
 		}
 	}
-
-Next1:
 }
 
 // Constructs a new liveness structure used to hold the global state of the
diff --git a/src/cmd/internal/gc/reg.go b/src/cmd/internal/gc/reg.go
index 5f9586b..e051c25 100644
--- a/src/cmd/internal/gc/reg.go
+++ b/src/cmd/internal/gc/reg.go
@@ -185,32 +185,22 @@
 }
 
 func mkvar(f *Flow, a *obj.Addr) Bits {
-	var v *Var
-	var i int
-	var n int
-	var et int
-	var flag int
-	var w int64
-	var o int64
-	var bit Bits
-	var node *Node
-	var r *Reg
-
 	/*
 	 * mark registers used
 	 */
 	if a.Type == obj.TYPE_NONE {
-		goto none
+		return zbits
 	}
 
-	r = f.Data.(*Reg)
+	r := f.Data.(*Reg)
 	r.use1.b[0] |= Thearch.Doregbits(int(a.Index)) // TODO: Use RtoB
 
+	var n int
 	switch a.Type {
 	default:
 		regu := Thearch.Doregbits(int(a.Reg)) | Thearch.RtoB(int(a.Reg)) // TODO: Use RtoB
 		if regu == 0 {
-			goto none
+			return zbits
 		}
 		bit := zbits
 		bit.b[0] = regu
@@ -227,7 +217,7 @@
 		setaddrs(bit)
 		a.Type = obj.TYPE_ADDR
 		Ostats.Naddr++
-		goto none
+		return zbits
 
 	memcase:
 		fallthrough
@@ -243,7 +233,7 @@
 		*/
 		switch a.Name {
 		default:
-			goto none
+			return zbits
 
 		case obj.NAME_EXTERN,
 			obj.NAME_STATIC,
@@ -253,25 +243,27 @@
 		}
 	}
 
+	var node *Node
 	node, _ = a.Node.(*Node)
 	if node == nil || node.Op != ONAME || node.Orig == nil {
-		goto none
+		return zbits
 	}
 	node = node.Orig
 	if node.Orig != node {
 		Fatal("%v: bad node", Ctxt.Dconv(a))
 	}
 	if node.Sym == nil || node.Sym.Name[0] == '.' {
-		goto none
+		return zbits
 	}
-	et = int(a.Etype)
-	o = a.Offset
-	w = a.Width
+	et := int(a.Etype)
+	o := a.Offset
+	w := a.Width
 	if w < 0 {
 		Fatal("bad width %d for %v", w, Ctxt.Dconv(a))
 	}
 
-	flag = 0
+	flag := 0
+	var v *Var
 	for i := 0; i < nvar; i++ {
 		v = &var_[i:][0]
 		if v.node == node && int(v.name) == n {
@@ -299,7 +291,7 @@
 	switch et {
 	case 0,
 		TFUNC:
-		goto none
+		return zbits
 	}
 
 	if nvar >= NVAR {
@@ -319,10 +311,10 @@
 			}
 		}
 
-		goto none
+		return zbits
 	}
 
-	i = nvar
+	i := nvar
 	nvar++
 	v = &var_[i:][0]
 	v.id = i
@@ -341,7 +333,7 @@
 
 	node.Opt = v
 
-	bit = blsh(uint(i))
+	bit := blsh(uint(i))
 	if n == obj.NAME_EXTERN || n == obj.NAME_STATIC {
 		for z := 0; z < BITS; z++ {
 			externs.b[z] |= bit.b[z]
@@ -401,9 +393,6 @@
 	Ostats.Nvar++
 
 	return bit
-
-none:
-	return zbits
 }
 
 func prop(f *Flow, ref Bits, cal Bits) {
diff --git a/src/cmd/internal/gc/sinit.go b/src/cmd/internal/gc/sinit.go
index ca8db418..4cb2dd6 100644
--- a/src/cmd/internal/gc/sinit.go
+++ b/src/cmd/internal/gc/sinit.go
@@ -533,21 +533,18 @@
 
 func simplename(n *Node) bool {
 	if n.Op != ONAME {
-		goto no
+		return false
 	}
 	if n.Addable == 0 {
-		goto no
+		return false
 	}
 	if n.Class&PHEAP != 0 {
-		goto no
+		return false
 	}
 	if n.Class == PPARAMREF {
-		goto no
+		return false
 	}
 	return true
-
-no:
-	return false
 }
 
 func litas(l *Node, r *Node, init **NodeList) {
@@ -1191,48 +1188,48 @@
 }
 
 func oaslit(n *Node, init **NodeList) bool {
-	var ctxt int
-
 	if n.Left == nil || n.Right == nil {
-		goto no
+		// not a special composit literal assignment
+		return false
 	}
 	if n.Left.Type == nil || n.Right.Type == nil {
-		goto no
+		// not a special composit literal assignment
+		return false
 	}
 	if !simplename(n.Left) {
-		goto no
+		// not a special composit literal assignment
+		return false
 	}
 	if !Eqtype(n.Left.Type, n.Right.Type) {
-		goto no
+		// not a special composit literal assignment
+		return false
 	}
 
 	// context is init() function.
 	// implies generated data executed
 	// exactly once and not subject to races.
-	ctxt = 0
+	ctxt := 0
 
 	//	if(n->dodata == 1)
 	//		ctxt = 1;
 
 	switch n.Right.Op {
 	default:
-		goto no
+		// not a special composit literal assignment
+		return false
 
 	case OSTRUCTLIT,
 		OARRAYLIT,
 		OMAPLIT:
 		if vmatch1(n.Left, n.Right) {
-			goto no
+			// not a special composit literal assignment
+			return false
 		}
 		anylit(ctxt, n.Right, n.Left, init)
 	}
 
 	n.Op = OEMPTY
 	return true
-
-	// not a special composit literal assignment
-no:
-	return false
 }
 
 func getlit(lit *Node) int {
@@ -1244,7 +1241,7 @@
 
 func stataddr(nam *Node, n *Node) bool {
 	if n == nil {
-		goto no
+		return false
 	}
 
 	switch n.Op {
@@ -1281,7 +1278,6 @@
 		return true
 	}
 
-no:
 	return false
 }
 
@@ -1420,7 +1416,6 @@
 	var nr *Node
 	var nl *Node
 	var nam Node
-	var nod1 Node
 
 	if n.Dodata == 0 {
 		goto no
@@ -1436,7 +1431,7 @@
 		if nam.Class != PEXTERN {
 			goto no
 		}
-		goto yes
+		return true
 	}
 
 	if nr.Type == nil || !Eqtype(nl.Type, nr.Type) {
@@ -1466,7 +1461,33 @@
 	case OSLICEARR:
 		if nr.Right.Op == OKEY && nr.Right.Left == nil && nr.Right.Right == nil {
 			nr = nr.Left
-			goto slice
+			gused(nil) // in case the data is the dest of a goto
+			nl := nr
+			if nr == nil || nr.Op != OADDR {
+				goto no
+			}
+			nr = nr.Left
+			if nr == nil || nr.Op != ONAME {
+				goto no
+			}
+
+			// nr is the array being converted to a slice
+			if nr.Type == nil || nr.Type.Etype != TARRAY || nr.Type.Bound < 0 {
+				goto no
+			}
+
+			nam.Xoffset += int64(Array_array)
+			gdata(&nam, nl, int(Types[Tptr].Width))
+
+			nam.Xoffset += int64(Array_nel) - int64(Array_array)
+			var nod1 Node
+			Nodconst(&nod1, Types[TINT], nr.Type.Bound)
+			gdata(&nam, &nod1, Widthint)
+
+			nam.Xoffset += int64(Array_cap) - int64(Array_nel)
+			gdata(&nam, &nod1, Widthint)
+
+			return true
 		}
 
 		goto no
@@ -1505,37 +1526,8 @@
 		gdatastring(&nam, nr.Val.U.Sval)
 	}
 
-yes:
 	return true
 
-slice:
-	gused(nil) // in case the data is the dest of a goto
-	nl = nr
-	if nr == nil || nr.Op != OADDR {
-		goto no
-	}
-	nr = nr.Left
-	if nr == nil || nr.Op != ONAME {
-		goto no
-	}
-
-	// nr is the array being converted to a slice
-	if nr.Type == nil || nr.Type.Etype != TARRAY || nr.Type.Bound < 0 {
-		goto no
-	}
-
-	nam.Xoffset += int64(Array_array)
-	gdata(&nam, nl, int(Types[Tptr].Width))
-
-	nam.Xoffset += int64(Array_nel) - int64(Array_array)
-	Nodconst(&nod1, Types[TINT], nr.Type.Bound)
-	gdata(&nam, &nod1, Widthint)
-
-	nam.Xoffset += int64(Array_cap) - int64(Array_nel)
-	gdata(&nam, &nod1, Widthint)
-
-	goto yes
-
 no:
 	if n.Dodata == 2 {
 		Dump("\ngen_as_init", n)
diff --git a/src/cmd/internal/gc/subr.go b/src/cmd/internal/gc/subr.go
index 1c59e59..c8eb1d6 100644
--- a/src/cmd/internal/gc/subr.go
+++ b/src/cmd/internal/gc/subr.go
@@ -1014,14 +1014,14 @@
 				Fatal("struct/interface missing field: %v %v", Tconv(t1, 0), Tconv(t2, 0))
 			}
 			if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, &l) || !eqnote(t1.Note, t2.Note) {
-				goto no
+				return false
 			}
 		}
 
 		if t1 == nil && t2 == nil {
-			goto yes
+			return true
 		}
-		goto no
+		return false
 
 		// Loop over structs: receiver, in, out.
 	case TFUNC:
@@ -1043,40 +1043,34 @@
 					Fatal("func struct missing field: %v %v", Tconv(ta, 0), Tconv(tb, 0))
 				}
 				if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, &l) {
-					goto no
+					return false
 				}
 			}
 
 			if ta != nil || tb != nil {
-				goto no
+				return false
 			}
 		}
 
 		if t1 == nil && t2 == nil {
-			goto yes
+			return true
 		}
-		goto no
+		return false
 
 	case TARRAY:
 		if t1.Bound != t2.Bound {
-			goto no
+			return false
 		}
 
 	case TCHAN:
 		if t1.Chan != t2.Chan {
-			goto no
+			return false
 		}
 	}
 
 	if eqtype1(t1.Down, t2.Down, &l) && eqtype1(t1.Type, t2.Type, &l) {
-		goto yes
+		return true
 	}
-	goto no
-
-yes:
-	return true
-
-no:
 	return false
 }
 
@@ -1376,10 +1370,8 @@
 }
 
 func subtype(stp **Type, t *Type, d int) bool {
-	var st *Type
-
 loop:
-	st = *stp
+	st := *stp
 	if st == nil {
 		return false
 	}
@@ -1762,7 +1754,7 @@
 
 	t = n.Type
 	if t == nil {
-		goto rnil
+		return nil
 	}
 
 	if t.Etype != TFIELD {
@@ -1775,7 +1767,6 @@
 bad:
 	Fatal("structfirst: not struct %v", Tconv(n, 0))
 
-rnil:
 	return nil
 }
 
@@ -1783,21 +1774,17 @@
 	n := s.T
 	t := n.Down
 	if t == nil {
-		goto rnil
+		return nil
 	}
 
 	if t.Etype != TFIELD {
-		goto bad
+		Fatal("structnext: not struct %v", Tconv(n, 0))
+
+		return nil
 	}
 
 	s.T = t
 	return t
-
-bad:
-	Fatal("structnext: not struct %v", Tconv(n, 0))
-
-rnil:
-	return nil
 }
 
 /*
@@ -2135,54 +2122,47 @@
 // will give shortest unique addressing.
 // modify the tree with missing type names.
 func adddot(n *Node) *Node {
-	var s *Sym
-	var c int
-	var d int
-
 	typecheck(&n.Left, Etype|Erv)
 	n.Diag |= n.Left.Diag
 	t := n.Left.Type
 	if t == nil {
-		goto ret
-	}
-
-	if n.Left.Op == OTYPE {
-		goto ret
-	}
-
-	if n.Right.Op != ONAME {
-		goto ret
-	}
-	s = n.Right.Sym
-	if s == nil {
-		goto ret
-	}
-
-	for d = 0; d < len(dotlist); d++ {
-		c = adddot1(s, t, d, nil, 0)
-		if c > 0 {
-			goto out
-		}
-	}
-
-	goto ret
-
-out:
-	if c > 1 {
-		Yyerror("ambiguous selector %v", Nconv(n, 0))
-		n.Left = nil
 		return n
 	}
 
-	// rebuild elided dots
-	for c := d - 1; c >= 0; c-- {
-		if n.Left.Type != nil && Isptr[n.Left.Type.Etype] != 0 {
-			n.Left.Implicit = 1
-		}
-		n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym))
+	if n.Left.Op == OTYPE {
+		return n
 	}
 
-ret:
+	if n.Right.Op != ONAME {
+		return n
+	}
+	s := n.Right.Sym
+	if s == nil {
+		return n
+	}
+
+	var c int
+	for d := 0; d < len(dotlist); d++ {
+		c = adddot1(s, t, d, nil, 0)
+		if c > 0 {
+			if c > 1 {
+				Yyerror("ambiguous selector %v", Nconv(n, 0))
+				n.Left = nil
+				return n
+			}
+
+			// rebuild elided dots
+			for c := d - 1; c >= 0; c-- {
+				if n.Left.Type != nil && Isptr[n.Left.Type.Etype] != 0 {
+					n.Left.Implicit = 1
+				}
+				n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym))
+			}
+
+			return n
+		}
+	}
+
 	return n
 }
 
@@ -3301,18 +3281,15 @@
  * 1000+ if it is a -(power of 2)
  */
 func powtwo(n *Node) int {
-	var v uint64
-	var b uint64
-
 	if n == nil || n.Op != OLITERAL || n.Type == nil {
-		goto no
+		return -1
 	}
 	if Isint[n.Type.Etype] == 0 {
-		goto no
+		return -1
 	}
 
-	v = uint64(Mpgetfix(n.Val.U.Xval))
-	b = 1
+	v := uint64(Mpgetfix(n.Val.U.Xval))
+	b := uint64(1)
 	for i := 0; i < 64; i++ {
 		if b == v {
 			return i
@@ -3321,7 +3298,7 @@
 	}
 
 	if Issigned[n.Type.Etype] == 0 {
-		goto no
+		return -1
 	}
 
 	v = -v
@@ -3333,7 +3310,6 @@
 		b = b << 1
 	}
 
-no:
 	return -1
 }
 
@@ -3592,22 +3568,19 @@
 	for i := 0; i < len(s); i++ {
 		c := s[i]
 		if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
-			goto escape
+			var buf bytes.Buffer
+			for i := 0; i < len(s); i++ {
+				c := s[i]
+				if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
+					fmt.Fprintf(&buf, "%%%02x", c)
+					continue
+				}
+				buf.WriteByte(c)
+			}
+			return buf.String()
 		}
 	}
 	return s
-
-escape:
-	var buf bytes.Buffer
-	for i := 0; i < len(s); i++ {
-		c := s[i]
-		if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
-			fmt.Fprintf(&buf, "%%%02x", c)
-			continue
-		}
-		buf.WriteByte(c)
-	}
-	return buf.String()
 }
 
 func mkpkg(path_ *Strlit) *Pkg {
diff --git a/src/cmd/internal/gc/typecheck.go b/src/cmd/internal/gc/typecheck.go
index 1468d5f..cb0111e 100644
--- a/src/cmd/internal/gc/typecheck.go
+++ b/src/cmd/internal/gc/typecheck.go
@@ -1805,7 +1805,25 @@
 
 arith:
 	if op == OLSH || op == ORSH {
-		goto shift
+		defaultlit(&r, Types[TUINT])
+		n.Right = r
+		t := r.Type
+		if Isint[t.Etype] == 0 || Issigned[t.Etype] != 0 {
+			Yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", Nconv(n, 0), Tconv(r.Type, 0))
+			goto error
+		}
+
+		t = l.Type
+		if t != nil && t.Etype != TIDEAL && Isint[t.Etype] == 0 {
+			Yyerror("invalid operation: %v (shift of type %v)", Nconv(n, 0), Tconv(t, 0))
+			goto error
+		}
+
+		// no defaultlit for left
+		// the outer context gives the type
+		n.Type = l.Type
+
+		goto ret
 	}
 
 	// ideal mixed with non-ideal
@@ -1993,27 +2011,6 @@
 	n.Type = t
 	goto ret
 
-shift:
-	defaultlit(&r, Types[TUINT])
-	n.Right = r
-	t = r.Type
-	if Isint[t.Etype] == 0 || Issigned[t.Etype] != 0 {
-		Yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", Nconv(n, 0), Tconv(r.Type, 0))
-		goto error
-	}
-
-	t = l.Type
-	if t != nil && t.Etype != TIDEAL && Isint[t.Etype] == 0 {
-		Yyerror("invalid operation: %v (shift of type %v)", Nconv(n, 0), Tconv(t, 0))
-		goto error
-	}
-
-	// no defaultlit for left
-	// the outer context gives the type
-	n.Type = l.Type
-
-	goto ret
-
 doconv:
 	ok |= Erv
 	saveorignode(n)
diff --git a/src/cmd/internal/gc/unsafe.go b/src/cmd/internal/gc/unsafe.go
index 7f0a33f..6faed49 100644
--- a/src/cmd/internal/gc/unsafe.go
+++ b/src/cmd/internal/gc/unsafe.go
@@ -14,31 +14,28 @@
  * rewrite with a constant
  */
 func unsafenmagic(nn *Node) *Node {
-	var r *Node
-	var s *Sym
-	var v int64
-
 	fn := nn.Left
 	args := nn.List
 
 	if safemode != 0 || fn == nil || fn.Op != ONAME {
-		goto no
+		return nil
 	}
-	s = fn.Sym
+	s := fn.Sym
 	if s == nil {
-		goto no
+		return nil
 	}
 	if s.Pkg != unsafepkg {
-		goto no
+		return nil
 	}
 
 	if args == nil {
 		Yyerror("missing argument for %v", Sconv(s, 0))
-		goto no
+		return nil
 	}
 
-	r = args.N
+	r := args.N
 
+	var v int64
 	if s.Name == "Sizeof" {
 		typecheck(&r, Erv)
 		defaultlit(&r, nil)
@@ -127,7 +124,6 @@
 		goto yes
 	}
 
-no:
 	return nil
 
 bad:
diff --git a/src/cmd/internal/gc/util.go b/src/cmd/internal/gc/util.go
index df68d50..c3f7db2 100644
--- a/src/cmd/internal/gc/util.go
+++ b/src/cmd/internal/gc/util.go
@@ -39,17 +39,14 @@
 
 func plan9quote(s string) string {
 	if s == "" {
-		goto needquote
+		return "'" + strings.Replace(s, "'", "''", -1) + "'"
 	}
 	for i := 0; i < len(s); i++ {
 		if s[i] <= ' ' || s[i] == '\'' {
-			goto needquote
+			return "'" + strings.Replace(s, "'", "''", -1) + "'"
 		}
 	}
 	return s
-
-needquote:
-	return "'" + strings.Replace(s, "'", "''", -1) + "'"
 }
 
 // simulation of int(*s++) in C
diff --git a/src/cmd/internal/gc/walk.go b/src/cmd/internal/gc/walk.go
index c57bdd6..4667494 100644
--- a/src/cmd/internal/gc/walk.go
+++ b/src/cmd/internal/gc/walk.go
@@ -3653,7 +3653,23 @@
 		if sl >= 0 {
 			sr := int(Mpgetfix(r.Right.Val.U.Xval))
 			if sr >= 0 && sl+sr == w {
-				goto yes
+				// Rewrite left shift half to left rotate.
+				if l.Op == OLSH {
+					n = l
+				} else {
+					n = r
+				}
+				n.Op = OLROT
+
+				// Remove rotate 0 and rotate w.
+				s := int(Mpgetfix(n.Right.Val.U.Xval))
+
+				if s == 0 || s == w {
+					n = n.Left
+				}
+
+				*np = n
+				return
 			}
 		}
 		return
@@ -3661,25 +3677,6 @@
 
 	// TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
 	return
-
-	// Rewrite left shift half to left rotate.
-yes:
-	if l.Op == OLSH {
-		n = l
-	} else {
-		n = r
-	}
-	n.Op = OLROT
-
-	// Remove rotate 0 and rotate w.
-	s := int(Mpgetfix(n.Right.Val.U.Xval))
-
-	if s == 0 || s == w {
-		n = n.Left
-	}
-
-	*np = n
-	return
 }
 
 /*
@@ -3793,11 +3790,124 @@
 		return
 	}
 
-	var n1 *Node
-	var m Magic
-	var n2 *Node
 	if pow < 0 {
-		goto divbymul
+		// try to do division by multiply by (2^w)/d
+		// see hacker's delight chapter 10
+		// TODO: support 64-bit magic multiply here.
+		var m Magic
+		m.W = w
+
+		if Issigned[nl.Type.Etype] != 0 {
+			m.Sd = Mpgetfix(nr.Val.U.Xval)
+			Smagic(&m)
+		} else {
+			m.Ud = uint64(Mpgetfix(nr.Val.U.Xval))
+			Umagic(&m)
+		}
+
+		if m.Bad != 0 {
+			return
+		}
+
+		// We have a quick division method so use it
+		// for modulo too.
+		if n.Op == OMOD {
+			// rewrite as A%B = A - (A/B*B).
+			n1 := Nod(ODIV, nl, nr)
+
+			n2 := Nod(OMUL, n1, nr)
+			n = Nod(OSUB, nl, n2)
+			goto ret
+		}
+
+		switch Simtype[nl.Type.Etype] {
+		default:
+			return
+
+			// n1 = nl * magic >> w (HMUL)
+		case TUINT8,
+			TUINT16,
+			TUINT32:
+			nc := Nod(OXXX, nil, nil)
+
+			Nodconst(nc, nl.Type, int64(m.Um))
+			n1 := Nod(OMUL, nl, nc)
+			typecheck(&n1, Erv)
+			n1.Op = OHMUL
+			if m.Ua != 0 {
+				// Select a Go type with (at least) twice the width.
+				var twide *Type
+				switch Simtype[nl.Type.Etype] {
+				default:
+					return
+
+				case TUINT8,
+					TUINT16:
+					twide = Types[TUINT32]
+
+				case TUINT32:
+					twide = Types[TUINT64]
+
+				case TINT8,
+					TINT16:
+					twide = Types[TINT32]
+
+				case TINT32:
+					twide = Types[TINT64]
+				}
+
+				// add numerator (might overflow).
+				// n2 = (n1 + nl)
+				n2 := Nod(OADD, conv(n1, twide), conv(nl, twide))
+
+				// shift by m.s
+				nc := Nod(OXXX, nil, nil)
+
+				Nodconst(nc, Types[TUINT], int64(m.S))
+				n = conv(Nod(ORSH, n2, nc), nl.Type)
+			} else {
+				// n = n1 >> m.s
+				nc := Nod(OXXX, nil, nil)
+
+				Nodconst(nc, Types[TUINT], int64(m.S))
+				n = Nod(ORSH, n1, nc)
+			}
+
+			// n1 = nl * magic >> w
+		case TINT8,
+			TINT16,
+			TINT32:
+			nc := Nod(OXXX, nil, nil)
+
+			Nodconst(nc, nl.Type, m.Sm)
+			n1 := Nod(OMUL, nl, nc)
+			typecheck(&n1, Erv)
+			n1.Op = OHMUL
+			if m.Sm < 0 {
+				// add the numerator.
+				n1 = Nod(OADD, n1, nl)
+			}
+
+			// shift by m.s
+			nc = Nod(OXXX, nil, nil)
+
+			Nodconst(nc, Types[TUINT], int64(m.S))
+			n2 := conv(Nod(ORSH, n1, nc), nl.Type)
+
+			// add 1 iff n1 is negative.
+			nc = Nod(OXXX, nil, nil)
+
+			Nodconst(nc, Types[TUINT], int64(w)-1)
+			n3 := Nod(ORSH, nl, nc) // n4 = -1 iff n1 is negative.
+			n = Nod(OSUB, n2, n3)
+
+			// apply sign.
+			if m.Sd < 0 {
+				n = Nod(OMINUS, n, nil)
+			}
+		}
+
+		goto ret
 	}
 
 	switch pow {
@@ -3905,127 +4015,6 @@
 
 	goto ret
 
-	// try to do division by multiply by (2^w)/d
-	// see hacker's delight chapter 10
-	// TODO: support 64-bit magic multiply here.
-divbymul:
-	m.W = w
-
-	if Issigned[nl.Type.Etype] != 0 {
-		m.Sd = Mpgetfix(nr.Val.U.Xval)
-		Smagic(&m)
-	} else {
-		m.Ud = uint64(Mpgetfix(nr.Val.U.Xval))
-		Umagic(&m)
-	}
-
-	if m.Bad != 0 {
-		return
-	}
-
-	// We have a quick division method so use it
-	// for modulo too.
-	if n.Op == OMOD {
-		goto longmod
-	}
-
-	switch Simtype[nl.Type.Etype] {
-	default:
-		return
-
-		// n1 = nl * magic >> w (HMUL)
-	case TUINT8,
-		TUINT16,
-		TUINT32:
-		nc := Nod(OXXX, nil, nil)
-
-		Nodconst(nc, nl.Type, int64(m.Um))
-		n1 := Nod(OMUL, nl, nc)
-		typecheck(&n1, Erv)
-		n1.Op = OHMUL
-		if m.Ua != 0 {
-			// Select a Go type with (at least) twice the width.
-			var twide *Type
-			switch Simtype[nl.Type.Etype] {
-			default:
-				return
-
-			case TUINT8,
-				TUINT16:
-				twide = Types[TUINT32]
-
-			case TUINT32:
-				twide = Types[TUINT64]
-
-			case TINT8,
-				TINT16:
-				twide = Types[TINT32]
-
-			case TINT32:
-				twide = Types[TINT64]
-			}
-
-			// add numerator (might overflow).
-			// n2 = (n1 + nl)
-			n2 := Nod(OADD, conv(n1, twide), conv(nl, twide))
-
-			// shift by m.s
-			nc := Nod(OXXX, nil, nil)
-
-			Nodconst(nc, Types[TUINT], int64(m.S))
-			n = conv(Nod(ORSH, n2, nc), nl.Type)
-		} else {
-			// n = n1 >> m.s
-			nc := Nod(OXXX, nil, nil)
-
-			Nodconst(nc, Types[TUINT], int64(m.S))
-			n = Nod(ORSH, n1, nc)
-		}
-
-		// n1 = nl * magic >> w
-	case TINT8,
-		TINT16,
-		TINT32:
-		nc := Nod(OXXX, nil, nil)
-
-		Nodconst(nc, nl.Type, m.Sm)
-		n1 := Nod(OMUL, nl, nc)
-		typecheck(&n1, Erv)
-		n1.Op = OHMUL
-		if m.Sm < 0 {
-			// add the numerator.
-			n1 = Nod(OADD, n1, nl)
-		}
-
-		// shift by m.s
-		nc = Nod(OXXX, nil, nil)
-
-		Nodconst(nc, Types[TUINT], int64(m.S))
-		n2 := conv(Nod(ORSH, n1, nc), nl.Type)
-
-		// add 1 iff n1 is negative.
-		nc = Nod(OXXX, nil, nil)
-
-		Nodconst(nc, Types[TUINT], int64(w)-1)
-		n3 := Nod(ORSH, nl, nc) // n4 = -1 iff n1 is negative.
-		n = Nod(OSUB, n2, n3)
-
-		// apply sign.
-		if m.Sd < 0 {
-			n = Nod(OMINUS, n, nil)
-		}
-	}
-
-	goto ret
-
-	// rewrite as A%B = A - (A/B*B).
-longmod:
-	n1 = Nod(ODIV, nl, nr)
-
-	n2 = Nod(OMUL, n1, nr)
-	n = Nod(OSUB, nl, n2)
-	goto ret
-
 ret:
 	typecheck(&n, Erv)
 	walkexpr(&n, init)