]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] cmd/asm: delete overflow checking, make labels function-scoped
authorRob Pike <r@golang.org>
Thu, 29 Jan 2015 20:07:50 +0000 (12:07 -0800)
committerRob Pike <r@golang.org>
Thu, 29 Jan 2015 20:26:26 +0000 (20:26 +0000)
The overflow checking was causing more problems than it was avoiding,
so get rid of it. But because arithmetic is done with uint64s, to simplify
dealing with large constants, complain about right shift and divide with
huge numbers to avoid ambiguity about signed shifts.

Change-Id: I5b5ea55d8e8c02846605f4a3f8fd7a176b1e962b
Reviewed-on: https://go-review.googlesource.com/3531
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/asm/internal/asm/asm.go
src/cmd/asm/internal/asm/overflow.go [deleted file]
src/cmd/asm/internal/asm/parse.go

index 63adef271be2abe3ff45360ec50c7bc6134ba009..43085ae256861e0aa1b59a81e24c71b741671b1a 100644 (file)
@@ -153,6 +153,11 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
                p.errorf("expect two or three operands for TEXT")
        }
 
+       // Labels are function scoped. Patch existing labels and
+       // create a new label space for this TEXT.
+       p.patch()
+       p.labels = make(map[string]*obj.Prog)
+
        // Operand 0 is the symbol name in the form foo(SB).
        // That means symbol plus indirect on SB and no offset.
        nameAddr := p.address(operands[0])
@@ -219,6 +224,7 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
                        Index: uint8(p.arch.D_NONE),
                },
        }
+
        // Encoding of frameSize and argSize depends on architecture.
        switch p.arch.Thechar {
        case '6':
@@ -231,6 +237,7 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
        default:
                p.errorf("internal error: can't encode TEXT $arg-frame")
        }
+
        p.append(prog, true)
 }
 
@@ -493,6 +500,7 @@ func (p *Parser) patch() {
                        p.branch(patch.prog, targetProg)
                }
        }
+       p.toPatch = p.toPatch[:0]
 }
 
 func (p *Parser) branch(jmp, target *obj.Prog) {
diff --git a/src/cmd/asm/internal/asm/overflow.go b/src/cmd/asm/internal/asm/overflow.go
deleted file mode 100644 (file)
index a429201..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2015 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.
-
-package asm
-
-/*
-       Tested with uint8s like this:
-
-       for a := 0; a <= 255; a++ {
-               for b := 0; b <= 127; b++ {
-                       ovfl := a+b != int(uint8(a)+uint8(b))
-                       if addOverflows(uint8(a), uint8(b)) != ovfl {
-                               fmt.Printf("%d+%d fails\n", a, b)
-                               break
-                       }
-               }
-       }
-       for a := 0; a <= 255; a++ {
-               for b := 0; b <= 127; b++ {
-                       ovfl := a-b != int(uint8(a)-uint8(b))
-                       if subOverflows(uint8(a), uint8(b)) != ovfl {
-                               fmt.Printf("%d-%d fails\n", a, b)
-                               break
-                       }
-               }
-       }
-       for a := 0; a <= 255; a++ {
-               for b := 0; b <= 255; b++ {
-                       ovfl := a*b != int(uint8(a)*uint8(b))
-                       if mulOverflows(uint8(a), uint8(b)) != ovfl {
-                               fmt.Printf("%d*%d fails\n", a, b)
-                       }
-               }
-       }
-       overflow := func(a, b int) bool {
-               for ; b > 0; b-- {
-                       a <<= 1
-                       if a >= 256 {
-                               return true
-                       }
-               }
-               return false
-       }
-       for a := 0; a <= 255; a++ {
-               for b := 0; b <= 255; b++ {
-                       ovfl := overflow(a, b)
-                       if shiftOverflows(uint8(a), uint8(b)) != ovfl {
-                               fmt.Printf("%d<<%d fails\n", a, b)
-                       }
-               }
-       }
-*/
-
-func addOverflows(a, b uint64) bool {
-       return a+b < a
-}
-
-func subOverflows(a, b uint64) bool {
-       return a-b > a
-}
-
-func mulOverflows(a, b uint64) bool {
-       if a <= 1 || b <= 1 {
-               return false
-       }
-       c := a * b
-       return c/b != a
-}
-
-func shiftOverflows(a, b uint64) bool {
-       c := a << b
-       return c>>b != a
-}
-
-/*
-For the record, signed overflow:
-
-const mostNegative = -(mostPositive + 1)
-const mostPositive = 1<<63 - 1
-
-func signedAddOverflows(a, b int64) bool {
-       if (a >= 0) != (b >= 0) {
-               // Different signs cannot overflow.
-               return false
-       }
-       if a >= 0 {
-               // Both are positive.
-               return a+b < 0
-       }
-       return a+b >= 0
-}
-
-func signedSubOverflows(a, b int64) bool {
-       if (a >= 0) == (b >= 0) {
-               // Same signs cannot overflow.
-               return false
-       }
-       if a >= 0 {
-               // a positive, b negative.
-               return a-b < 0
-       }
-       return a-b >= 0
-}
-
-func signedMulOverflows(a, b int64) bool {
-       if a == 0 || b == 0 || a == 1 || b == 1 {
-               return false
-       }
-       if a == mostNegative || b == mostNegative {
-               return true
-       }
-       c := a * b
-       return c/b != a
-}
-
-func signedShiftOverflows(a, b int64) bool {
-       // Avoid right shift of a negative number.
-       if a >= 0 {
-               c := a << b
-               return c>>b != a
-       }
-       // Otherwise it's negative, so we complement, which
-       // puts zeros at the top.
-       a = ^a
-       c := a << b
-       return c>>b != a
-}
-*/
index be616ec0bcc576840bcf97c1bb6594d5deec797b..b0f6ca9f08ee1d16982aae123f1d1f6ef1631e33 100644 (file)
@@ -360,11 +360,7 @@ func (p *Parser) expr() uint64 {
                switch p.peek() {
                case '+':
                        p.next()
-                       x := p.term()
-                       if addOverflows(x, value) {
-                               p.errorf("overflow in %d+%d", value, x)
-                       }
-                       value += x
+                       value += p.term()
                case '-':
                        p.next()
                        value -= p.term()
@@ -408,13 +404,12 @@ func (p *Parser) term() uint64 {
                switch p.peek() {
                case '*':
                        p.next()
-                       x := p.factor()
-                       if mulOverflows(value, x) {
-                               p.errorf("%d * %d overflows", value, x)
-                       }
-                       value *= x
+                       value *= p.factor()
                case '/':
                        p.next()
+                       if value&(1<<63) != 0 {
+                               p.errorf("divide with high bit set")
+                       }
                        value /= p.factor()
                case '%':
                        p.next()
@@ -425,9 +420,6 @@ func (p *Parser) term() uint64 {
                        if int64(shift) < 0 {
                                p.errorf("negative left shift %d", shift)
                        }
-                       if shiftOverflows(value, shift) {
-                               p.errorf("%d << %d overflows", value, shift)
-                       }
                        return value << shift
                case lex.RSH:
                        p.next()
@@ -435,6 +427,9 @@ func (p *Parser) term() uint64 {
                        if shift < 0 {
                                p.errorf("negative right shift %d", shift)
                        }
+                       if shift > 0 && value&(1<<63) != 0 {
+                               p.errorf("right shift with high bit set")
+                       }
                        value >>= uint(shift)
                case '&':
                        p.next()