diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 63adef271be..43085ae2568 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -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 index a4292011aef..00000000000 --- a/src/cmd/asm/internal/asm/overflow.go +++ /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 -} -*/ diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go index be616ec0bcc..b0f6ca9f08e 100644 --- a/src/cmd/asm/internal/asm/parse.go +++ b/src/cmd/asm/internal/asm/parse.go @@ -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()