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])
Index: uint8(p.arch.D_NONE),
},
}
+
// Encoding of frameSize and argSize depends on architecture.
switch p.arch.Thechar {
case '6':
default:
p.errorf("internal error: can't encode TEXT $arg-frame")
}
+
p.append(prog, true)
}
p.branch(patch.prog, targetProg)
}
}
+ p.toPatch = p.toPatch[:0]
}
func (p *Parser) branch(jmp, target *obj.Prog) {
+++ /dev/null
-// 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
-}
-*/
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()
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()
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()
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()