}
+func shlVW(z, x *Word, s Word, n int) (c Word)
+func shlVW_g(z, x *Word, s Word, n int) (c Word) {
+ ŝ := _W - s
+ for i := 0; i < n; i++ {
+ w := *x.at(i)
+ c, *z.at(i) = w>>ŝ, w<<s|c
+ }
+ return
+}
+
+
+func shrVW(z, x *Word, s Word, n int) (c Word)
+func shrVW_g(z, x *Word, s Word, n int) (c Word) {
+ ŝ := _W - s
+ for i := n - 1; i >= 0; i-- {
+ w := *x.at(i)
+ c, *z.at(i) = w<<ŝ, w>>s|c
+ }
+ return
+}
+
+
func mulAddVWW(z, x *Word, y, r Word, n int) (c Word)
func mulAddVWW_g(z, x *Word, y, r Word, n int) (c Word) {
c = r
argVW{nat{_M << 7 & _M, _M, _M, _M}, nat{_M, _M, _M, _M}, 1 << 7, _M >> (_W - 7)},
}
+var lshVW = []argVW{
+ argVW{},
+ argVW{nat{0}, nat{0}, 0, 0},
+ argVW{nat{0}, nat{0}, 1, 0},
+ argVW{nat{0}, nat{0}, 20, 0},
+
+ argVW{nat{_M}, nat{_M}, 0, 0},
+ argVW{nat{_M << 1 & _M}, nat{_M}, 1, 1},
+ argVW{nat{_M << 20 & _M}, nat{_M}, 20, _M >> (_W - 20)},
+
+ argVW{nat{_M, _M, _M}, nat{_M, _M, _M}, 0, 0},
+ argVW{nat{_M << 1 & _M, _M, _M}, nat{_M, _M, _M}, 1, 1},
+ argVW{nat{_M << 20 & _M, _M, _M}, nat{_M, _M, _M}, 20, _M >> (_W - 20)},
+}
+
+var rshVW = []argVW{
+ argVW{},
+ argVW{nat{0}, nat{0}, 0, 0},
+ argVW{nat{0}, nat{0}, 1, 0},
+ argVW{nat{0}, nat{0}, 20, 0},
+
+ argVW{nat{_M}, nat{_M}, 0, 0},
+ argVW{nat{_M >> 1}, nat{_M}, 1, _M << (_W - 1) & _M},
+ argVW{nat{_M >> 20}, nat{_M}, 20, _M << (_W - 20) & _M},
+
+ argVW{nat{_M, _M, _M}, nat{_M, _M, _M}, 0, 0},
+ argVW{nat{_M, _M, _M >> 1}, nat{_M, _M, _M}, 1, _M << (_W - 1) & _M},
+ argVW{nat{_M, _M, _M >> 20}, nat{_M, _M, _M}, 20, _M << (_W - 20) & _M},
+}
+
func testFunVW(t *testing.T, msg string, f funVW, a argVW) {
n := len(a.z)
testFunVW(t, "subVW_g", subVW_g, arg)
testFunVW(t, "subVW", subVW, arg)
}
+
+ for _, a := range lshVW {
+ arg := a
+ testFunVW(t, "shlVW_g", shlVW_g, arg)
+ testFunVW(t, "shlVW", shlVW, arg)
+ }
+
+ for _, a := range rshVW {
+ arg := a
+ testFunVW(t, "shrVW_g", shrVW_g, arg)
+ testFunVW(t, "shrVW", shrVW, arg)
+ }
}