Example ML fragments to convert shift operations to a bit lane form: -------------------------------------------------------------------- (* Zero pad extends the shorter arg with leading zeros. *) fun pand_zp(nil, nil, p, q) = (rev p, rev q) | pand_zp(nil, a::b, p, q) = pand_zp([ xi_false ], a::b, p, q) | pand_zp(a::b, nil, p, q) = pand_zp(a::b, [ xi_false ], p, q) | pand_zp(c::cc, d::dd, p, q) = pand_zp(cc, dd, c::p, d::q) fun pand_zeropad(a, b) = pand_zp(a, b, [], []) (* * Dynamic bit-extract of a bit from a bus uses barrel shifter approach: * Barrel discards one bit of r on each iteration starting with butterflies of strathe 2. *) | pandex w P (XINT_BSUBSC(l, r)) = let val l' = pandex w P r val r' = pandex w P r fun barrel st nil item = item | barrel st (h::t) item = let fun k [] = [] | k (ih::it) = xgen_mux2(h, ih, select_nth_or (st-1) it x_false) :: (k it) val item' = k item in barrel (st*2) t item' end in [ hd(barrel 2 r' l') ] end (* Constant shifts just involve padding: *) fun pand_lshift1 (a, n) = if n=0 then a else xi_false::(pand_lshift1(a, n-1)) fun pand_rshift1 (a, n) = if n=0 orelse a=nil then a else pand_rshift1(tl a, n-1) fun pand_mux g (nil, nil) = nil | pand_mux g (a::at, b::bt) = xi_query(g, xi_blift a, xi_blift b) :: (pand_mux g (at, bt)) fun pand_muxzp g (a, b) = pand_mux g (pand_zeropad(a, b)) (* Variable shifts again use a barrel approach: *) fun pand_rshift (a, nil, x) = a | pand_rshift (a, h::t, x) = let val r = map gen_orred (pand_rshift(a, t, x*2)) in pand_muxzp h (pand_rshift1(r, x), r) end fun pand_lshift (a, nil, x) = a | pand_lshift (a, h::t, x) = let val r = map gen_orred (pand_lshift(a, t, x*2)) in pand_muxzp h (pand_lshift1(r, x), r) end (* END *)