Home | History | Annotate | Download | only in ssa
      1 // Copyright 2016 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package ssa
      6 
      7 // A copy of the code in ../gc/subr.go.
      8 // We can't use it directly because it would generate
      9 // an import cycle. TODO: move to a common support package.
     10 
     11 // argument passing to/from
     12 // smagic and umagic
     13 type magic struct {
     14 	W   int // input for both - width
     15 	S   int // output for both - shift
     16 	Bad int // output for both - unexpected failure
     17 
     18 	// magic multiplier for signed literal divisors
     19 	Sd int64 // input - literal divisor
     20 	Sm int64 // output - multiplier
     21 
     22 	// magic multiplier for unsigned literal divisors
     23 	Ud uint64 // input - literal divisor
     24 	Um uint64 // output - multiplier
     25 	Ua int    // output - adder
     26 }
     27 
     28 // magic number for signed division
     29 // see hacker's delight chapter 10
     30 func smagic(m *magic) {
     31 	var mask uint64
     32 
     33 	m.Bad = 0
     34 	switch m.W {
     35 	default:
     36 		m.Bad = 1
     37 		return
     38 
     39 	case 8:
     40 		mask = 0xff
     41 
     42 	case 16:
     43 		mask = 0xffff
     44 
     45 	case 32:
     46 		mask = 0xffffffff
     47 
     48 	case 64:
     49 		mask = 0xffffffffffffffff
     50 	}
     51 
     52 	two31 := mask ^ (mask >> 1)
     53 
     54 	p := m.W - 1
     55 	ad := uint64(m.Sd)
     56 	if m.Sd < 0 {
     57 		ad = -uint64(m.Sd)
     58 	}
     59 
     60 	// bad denominators
     61 	if ad == 0 || ad == 1 || ad == two31 {
     62 		m.Bad = 1
     63 		return
     64 	}
     65 
     66 	t := two31
     67 	ad &= mask
     68 
     69 	anc := t - 1 - t%ad
     70 	anc &= mask
     71 
     72 	q1 := two31 / anc
     73 	r1 := two31 - q1*anc
     74 	q1 &= mask
     75 	r1 &= mask
     76 
     77 	q2 := two31 / ad
     78 	r2 := two31 - q2*ad
     79 	q2 &= mask
     80 	r2 &= mask
     81 
     82 	var delta uint64
     83 	for {
     84 		p++
     85 		q1 <<= 1
     86 		r1 <<= 1
     87 		q1 &= mask
     88 		r1 &= mask
     89 		if r1 >= anc {
     90 			q1++
     91 			r1 -= anc
     92 			q1 &= mask
     93 			r1 &= mask
     94 		}
     95 
     96 		q2 <<= 1
     97 		r2 <<= 1
     98 		q2 &= mask
     99 		r2 &= mask
    100 		if r2 >= ad {
    101 			q2++
    102 			r2 -= ad
    103 			q2 &= mask
    104 			r2 &= mask
    105 		}
    106 
    107 		delta = ad - r2
    108 		delta &= mask
    109 		if q1 < delta || (q1 == delta && r1 == 0) {
    110 			continue
    111 		}
    112 
    113 		break
    114 	}
    115 
    116 	m.Sm = int64(q2 + 1)
    117 	if uint64(m.Sm)&two31 != 0 {
    118 		m.Sm |= ^int64(mask)
    119 	}
    120 	m.S = p - m.W
    121 }
    122 
    123 // magic number for unsigned division
    124 // see hacker's delight chapter 10
    125 func umagic(m *magic) {
    126 	var mask uint64
    127 
    128 	m.Bad = 0
    129 	m.Ua = 0
    130 
    131 	switch m.W {
    132 	default:
    133 		m.Bad = 1
    134 		return
    135 
    136 	case 8:
    137 		mask = 0xff
    138 
    139 	case 16:
    140 		mask = 0xffff
    141 
    142 	case 32:
    143 		mask = 0xffffffff
    144 
    145 	case 64:
    146 		mask = 0xffffffffffffffff
    147 	}
    148 
    149 	two31 := mask ^ (mask >> 1)
    150 
    151 	m.Ud &= mask
    152 	if m.Ud == 0 || m.Ud == two31 {
    153 		m.Bad = 1
    154 		return
    155 	}
    156 
    157 	nc := mask - (-m.Ud&mask)%m.Ud
    158 	p := m.W - 1
    159 
    160 	q1 := two31 / nc
    161 	r1 := two31 - q1*nc
    162 	q1 &= mask
    163 	r1 &= mask
    164 
    165 	q2 := (two31 - 1) / m.Ud
    166 	r2 := (two31 - 1) - q2*m.Ud
    167 	q2 &= mask
    168 	r2 &= mask
    169 
    170 	var delta uint64
    171 	for {
    172 		p++
    173 		if r1 >= nc-r1 {
    174 			q1 <<= 1
    175 			q1++
    176 			r1 <<= 1
    177 			r1 -= nc
    178 		} else {
    179 			q1 <<= 1
    180 			r1 <<= 1
    181 		}
    182 
    183 		q1 &= mask
    184 		r1 &= mask
    185 		if r2+1 >= m.Ud-r2 {
    186 			if q2 >= two31-1 {
    187 				m.Ua = 1
    188 			}
    189 
    190 			q2 <<= 1
    191 			q2++
    192 			r2 <<= 1
    193 			r2++
    194 			r2 -= m.Ud
    195 		} else {
    196 			if q2 >= two31 {
    197 				m.Ua = 1
    198 			}
    199 
    200 			q2 <<= 1
    201 			r2 <<= 1
    202 			r2++
    203 		}
    204 
    205 		q2 &= mask
    206 		r2 &= mask
    207 
    208 		delta = m.Ud - 1 - r2
    209 		delta &= mask
    210 
    211 		if p < m.W+m.W {
    212 			if q1 < delta || (q1 == delta && r1 == 0) {
    213 				continue
    214 			}
    215 		}
    216 
    217 		break
    218 	}
    219 
    220 	m.Um = q2 + 1
    221 	m.S = p - m.W
    222 }
    223 
    224 // adaptors for use by rewrite rules
    225 func smagic64ok(d int64) bool {
    226 	m := magic{W: 64, Sd: d}
    227 	smagic(&m)
    228 	return m.Bad == 0
    229 }
    230 func smagic64m(d int64) int64 {
    231 	m := magic{W: 64, Sd: d}
    232 	smagic(&m)
    233 	return m.Sm
    234 }
    235 func smagic64s(d int64) int64 {
    236 	m := magic{W: 64, Sd: d}
    237 	smagic(&m)
    238 	return int64(m.S)
    239 }
    240 
    241 func umagic64ok(d int64) bool {
    242 	m := magic{W: 64, Ud: uint64(d)}
    243 	umagic(&m)
    244 	return m.Bad == 0
    245 }
    246 func umagic64m(d int64) int64 {
    247 	m := magic{W: 64, Ud: uint64(d)}
    248 	umagic(&m)
    249 	return int64(m.Um)
    250 }
    251 func umagic64s(d int64) int64 {
    252 	m := magic{W: 64, Ud: uint64(d)}
    253 	umagic(&m)
    254 	return int64(m.S)
    255 }
    256 func umagic64a(d int64) bool {
    257 	m := magic{W: 64, Ud: uint64(d)}
    258 	umagic(&m)
    259 	return m.Ua != 0
    260 }
    261