@@ -213,6 +213,75 @@ func TestFunVW(t *testing.T) {
213
213
}
214
214
}
215
215
216
+ type argVU struct {
217
+ d []Word // d is a Word slice, the input parameters x and z come from this array.
218
+ l uint // l is the length of the input parameters x and z.
219
+ xp uint // xp is the starting position of the input parameter x, x := d[xp:xp+l].
220
+ zp uint // zp is the starting position of the input parameter z, z := d[zp:zp+l].
221
+ s uint // s is the shift number.
222
+ r []Word // r is the expected output result z.
223
+ c Word // c is the expected return value.
224
+ m string // message.
225
+ }
226
+
227
+ var argshlVU = []argVU {
228
+ // test cases for shlVU
229
+ {[]Word {1 , _M , _M , _M , _M , _M , 3 << (_W - 2 ), 0 }, 7 , 0 , 0 , 1 , []Word {2 , _M - 1 , _M , _M , _M , _M , 1 << (_W - 1 ) + 1 }, 1 , "complete overlap of shlVU" },
230
+ {[]Word {1 , _M , _M , _M , _M , _M , 3 << (_W - 2 ), 0 , 0 , 0 , 0 }, 7 , 0 , 3 , 1 , []Word {2 , _M - 1 , _M , _M , _M , _M , 1 << (_W - 1 ) + 1 }, 1 , "partial overlap by half of shlVU" },
231
+ {[]Word {1 , _M , _M , _M , _M , _M , 3 << (_W - 2 ), 0 , 0 , 0 , 0 , 0 , 0 , 0 }, 7 , 0 , 6 , 1 , []Word {2 , _M - 1 , _M , _M , _M , _M , 1 << (_W - 1 ) + 1 }, 1 , "partial overlap by 1 Word of shlVU" },
232
+ {[]Word {1 , _M , _M , _M , _M , _M , 3 << (_W - 2 ), 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, 7 , 0 , 7 , 1 , []Word {2 , _M - 1 , _M , _M , _M , _M , 1 << (_W - 1 ) + 1 }, 1 , "no overlap of shlVU" },
233
+ }
234
+
235
+ var argshrVU = []argVU {
236
+ // test cases for shrVU
237
+ {[]Word {0 , 3 , _M , _M , _M , _M , _M , 1 << (_W - 1 )}, 7 , 1 , 1 , 1 , []Word {1 << (_W - 1 ) + 1 , _M , _M , _M , _M , _M >> 1 , 1 << (_W - 2 )}, 1 << (_W - 1 ), "complete overlap of shrVU" },
238
+ {[]Word {0 , 0 , 0 , 0 , 3 , _M , _M , _M , _M , _M , 1 << (_W - 1 )}, 7 , 4 , 1 , 1 , []Word {1 << (_W - 1 ) + 1 , _M , _M , _M , _M , _M >> 1 , 1 << (_W - 2 )}, 1 << (_W - 1 ), "partial overlap by half of shrVU" },
239
+ {[]Word {0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , _M , _M , _M , _M , _M , 1 << (_W - 1 )}, 7 , 7 , 1 , 1 , []Word {1 << (_W - 1 ) + 1 , _M , _M , _M , _M , _M >> 1 , 1 << (_W - 2 )}, 1 << (_W - 1 ), "partial overlap by 1 Word of shrVU" },
240
+ {[]Word {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , _M , _M , _M , _M , _M , 1 << (_W - 1 )}, 7 , 8 , 1 , 1 , []Word {1 << (_W - 1 ) + 1 , _M , _M , _M , _M , _M >> 1 , 1 << (_W - 2 )}, 1 << (_W - 1 ), "no overlap of shrVU" },
241
+ }
242
+
243
+ func testShiftFunc (t * testing.T , f func (z , x []Word , s uint ) Word , a argVU ) {
244
+ // save a.d for error message, or it will be overwritten.
245
+ b := make ([]Word , len (a .d ))
246
+ copy (b , a .d )
247
+ z := a .d [a .zp : a .zp + a .l ]
248
+ x := a .d [a .xp : a .xp + a .l ]
249
+ c := f (z , x , a .s )
250
+ for i , zi := range z {
251
+ if zi != a .r [i ] {
252
+ t .Errorf ("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n \t got z[%d] = %#x; want %#x" , b , a .m , a .zp , a .zp + a .l , a .xp , a .xp + a .l , a .s , i , zi , a .r [i ])
253
+ break
254
+ }
255
+ }
256
+ if c != a .c {
257
+ t .Errorf ("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n \t got c = %#x; want %#x" , b , a .m , a .zp , a .zp + a .l , a .xp , a .xp + a .l , a .s , c , a .c )
258
+ }
259
+ }
260
+
261
+ func TestShiftOverlap (t * testing.T ) {
262
+ for _ , a := range argshlVU {
263
+ arg := a
264
+ testShiftFunc (t , shlVU , arg )
265
+ }
266
+
267
+ for _ , a := range argshrVU {
268
+ arg := a
269
+ testShiftFunc (t , shrVU , arg )
270
+ }
271
+ }
272
+
273
+ func TestIssue31084 (t * testing.T ) {
274
+ // compute 10^n via 5^n << n.
275
+ const n = 165
276
+ p := nat (nil ).expNN (nat {5 }, nat {n }, nil )
277
+ p = p .shl (p , uint (n ))
278
+ got := string (p .utoa (10 ))
279
+ want := "1" + strings .Repeat ("0" , n )
280
+ if got != want {
281
+ t .Errorf ("shl(%v, %v)\n \t got %s; want %s\n " , p , uint (n ), got , want )
282
+ }
283
+ }
284
+
216
285
func BenchmarkAddVW (b * testing.B ) {
217
286
for _ , n := range benchSizes {
218
287
if isRaceBuilder && n > 1e3 {
0 commit comments