[gforth] / gforth / asm / bitmask2.fs  

gforth: gforth/asm/bitmask2.fs


1 : dvdkhlng 1.1 \ Rewritten and improved bitmask code
2 :    
3 :     \ Author: David Kühling <dvdkhlng AT gmx DOT de>
4 :     \ Created: May 2010
5 :    
6 :     \ Copyright (C) 2010 Free Software Foundation, Inc.
7 :    
8 :     \ This file is part of Gforth.
9 :    
10 :     \ Gforth is free software; you can redistribute it and/or
11 :     \ modify it under the terms of the GNU General Public License
12 :     \ as published by the Free Software Foundation, either version 3
13 :     \ of the License, or (at your option) any later version.
14 :    
15 :     \ This program is distributed in the hope that it will be useful,
16 :     \ but WITHOUT ANY WARRANTY; without even the implied warranty of
17 :     \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 :     \ GNU General Public License for more details.
19 :    
20 :     \ You should have received a copy of the GNU General Public License
21 :     \ along with this program. If not, see http://www.gnu.org/licenses/.
22 :    
23 :     : bitset? ( x #bit -- flag ) \ get value of single bit in cell x
24 :     rshift 1 and ;
25 :     : setbit ( x1 0|1 #bit -- x2 ) \ set value of single bit in cell x
26 :     1 over lshift invert -rot \ mask for deleting bit
27 :     lshift \ mask for optionally setting bit
28 :     -rot and or ; \ first delete then optionally set bit
29 :     : (bits/cell) ( -- +n ) \ measure number of bits per cell
30 :     1 1 begin 1 lshift dup while
31 :     swap 1+ swap
32 :     repeat drop ;
33 :     (bits/cell) CONSTANT bits/cell
34 :    
35 :     : dispense ( x1-val x2-mask -- x3-masked )
36 :     \ encode val into the bits given by mask. bits in mask can be spread out
37 :     \ as much as you like. for signed values 'val', first apply 'narrow' below
38 :     bits/cell 0 do \ iterate over bits in mask
39 :     dup i bitset? if \ if mask bit set:
40 :     over 1 and i setbit \ replace bit in mask by val's bit
41 :     swap 1 rshift swap \ and remove bit from val
42 :     then
43 :     loop
44 :     swap 0<> ABORT" dispense: value does not fit into masked bits" ;
45 :     : embed ( x1-accu x2-val x3-mask -- x4-result )
46 :     \ encode 'val' into bits set given by mask, replacing corresponding bits in
47 :     \ 'accu'
48 :     dup >r dispense \ dispense value over masked bits
49 :     swap r> invert and \ delete corresponding bits in accu
50 :     or ; \ and add dispensed bits
51 :    
52 :     : mask ( +n -- mask ) \ get bitmask for lowest #n bits
53 :     0 invert swap lshift invert ;
54 :     : narrow ( n1 n2 -- x ) \ limit signed value to n2 bits
55 :     \ note: assumes 2-complement number n1 and 2-complement host
56 :     2dup mask and -rot \ compute masked value,
57 :     1- \ but before returning, check whether no bits lost
58 :     -1 over lshift ( lower bund)
59 :     1 rot lshift ( upper bound)
60 :     within 0= ABORT" narrow: signed value out of range" ;
61 :    
62 :     : maskinto ( "x-mask" -- runtime: x1-val x1-accu -- x2-masked )
63 :     \ for backwards compatability with old bitmask code
64 :     ]] swap [[ parse-word s>number drop ]]L embed [[ ; IMMEDIATE

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help