1 /* $NetBSD: citrus_mapper_zone.c,v 1.4 2003/07/12 15:39:21 tshiozak Exp $ */
4 * Copyright (c)2003 Citrus Project,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 #if defined(LIBC_SCCS) && !defined(lint)
31 __RCSID("$NetBSD: citrus_mapper_zone.c,v 1.4 2003/07/12 15:39:21 tshiozak Exp $");
32 #endif /* LIBC_SCCS and not lint */
39 #include <sys/queue.h>
41 #include "citrus_namespace.h"
42 #include "citrus_types.h"
43 #include "citrus_bcs.h"
44 #include "citrus_module.h"
45 #include "citrus_region.h"
46 #include "citrus_memstream.h"
47 #include "citrus_mmap.h"
48 #include "citrus_hash.h"
49 #include "citrus_mapper.h"
50 #include "citrus_mapper_zone.h"
52 /* ---------------------------------------------------------------------- */
54 _CITRUS_MAPPER_DECLS(mapper_zone
);
55 _CITRUS_MAPPER_DEF_OPS(mapper_zone
);
58 /* ---------------------------------------------------------------------- */
65 struct _citrus_mapper_zone
{
69 int32_t mz_row_offset
;
70 int32_t mz_col_offset
;
74 enum { S_BEGIN
, S_OFFSET
} ps_state
;
80 #define ps_u_imm u.u_imm
81 #define ps_s_imm u.s_imm
82 #define ps_zone u.zone
87 _citrus_mapper_zone_mapper_getops(struct _citrus_mapper_ops
*ops
,
88 size_t lenops
, uint32_t expected_version
)
90 if (expected_version
<_CITRUS_MAPPER_ABI_VERSION
|| lenops
<sizeof(*ops
))
93 memcpy(ops
, &_citrus_mapper_zone_mapper_ops
,
94 sizeof(_citrus_mapper_zone_mapper_ops
));
104 get_imm(struct _memstream
*ms
, struct _parse_state
*ps
)
108 char buf
[BUFSIZE
+1], *p
;
110 for (i
=0; i
<BUFSIZE
; i
++) {
112 c
= _memstream_peek(ms
);
114 if (sign
== 0 && (c
== '+' || c
== '-')) {
118 } else if (!_bcs_isdigit(c
))
120 } else if (!_bcs_isxdigit(c
))
121 if (!(i
==1 && c
== 'x'))
123 buf
[i
] = _memstream_getc(ms
);
126 ps
->ps_u_imm
= strtoul(buf
, &p
, 0);
130 ps
->ps_u_imm
= (unsigned long)-(long)ps
->ps_u_imm
;
135 get_tok(struct _memstream
*ms
, struct _parse_state
*ps
)
140 c
= _memstream_peek(ms
);
143 if (_bcs_isspace(c
)) {
148 switch (ps
->ps_state
) {
166 return get_imm(ms
, ps
);
186 return get_imm(ms
, ps
);
194 parse_zone(struct _memstream
*ms
, struct _parse_state
*ps
, struct _zone
*z
)
196 if (get_tok(ms
, ps
) != T_IMM
)
198 z
->z_begin
= ps
->ps_u_imm
;
199 if (get_tok(ms
, ps
) != '-')
201 if (get_tok(ms
, ps
) != T_IMM
)
203 z
->z_end
= ps
->ps_u_imm
;
205 if (z
->z_begin
> z
->z_end
)
212 check_rowcol(struct _zone
*z
, int32_t ofs
, uint32_t maxval
)
216 if (maxval
!= 0 && z
->z_end
>= maxval
)
221 /* this should 0x100000000 - z->z_end */
225 remain
= 0xFFFFFFFF - z
->z_end
+ 1;
228 remain
= maxval
- z
->z_end
;
229 if ((u_int32_t
)ofs
> remain
)
231 } else if (ofs
< 0) {
232 if (z
->z_begin
< (u_int32_t
)-ofs
)
240 parse_var(struct _citrus_mapper_zone
*mz
, struct _memstream
*ms
)
242 struct _parse_state ps
;
244 uint32_t rowmax
, colmax
;
246 ps
.ps_state
= S_BEGIN
;
248 if (parse_zone(ms
, &ps
, &mz
->mz_col
))
251 ret
= get_tok(ms
, &ps
);
253 /* rowzone / colzone / bits */
255 mz
->mz_row
= mz
->mz_col
;
257 if (parse_zone(ms
, &ps
, &mz
->mz_col
))
259 if (get_tok(ms
, &ps
) != '/')
261 if (get_tok(ms
, &ps
) != T_IMM
)
263 mz
->mz_col_bits
= ps
.ps_u_imm
;
264 if (mz
->mz_col_bits
<0 || mz
->mz_col_bits
>32)
266 ret
= get_tok(ms
, &ps
);
270 mz
->mz_col_bits
= 32;
271 mz
->mz_row
.z_begin
= mz
->mz_row
.z_end
= 0;
275 ps
.ps_state
= S_OFFSET
;
276 if (get_tok(ms
, &ps
) != T_IMM
)
278 mz
->mz_col_offset
= ps
.ps_s_imm
;
281 mz
->mz_row_offset
= mz
->mz_col_offset
;
282 if (get_tok(ms
, &ps
) != '/')
284 if (get_tok(ms
, &ps
) != T_IMM
)
286 mz
->mz_col_offset
= ps
.ps_s_imm
;
288 mz
->mz_row_offset
= 0;
289 ret
= get_tok(ms
, &ps
);
295 if (mz
->mz_col_bits
==32)
298 colmax
= 1 << mz
->mz_col_bits
;
299 if (mz
->mz_col_bits
==0)
302 rowmax
= 1 << (32-mz
->mz_col_bits
);
303 if (check_rowcol(&mz
->mz_col
, mz
->mz_col_offset
, colmax
))
305 if (check_rowcol(&mz
->mz_row
, mz
->mz_row_offset
, rowmax
))
313 _citrus_mapper_zone_mapper_init(struct _citrus_mapper_area
*__restrict ma
,
314 struct _citrus_mapper
* __restrict cm
,
315 const char * __restrict dir
,
316 const void * __restrict var
, size_t lenvar
,
317 struct _citrus_mapper_traits
* __restrict mt
,
320 struct _citrus_mapper_zone
*mz
;
321 struct _memstream ms
;
324 _DIAGASSERT(cm
&& dir
&& mt
);
326 if (lenmt
<sizeof(*mt
))
329 mz
= malloc(sizeof(*mz
));
333 mz
->mz_col
.z_begin
= mz
->mz_col
.z_end
= 0;
334 mz
->mz_row
.z_begin
= mz
->mz_row
.z_end
= 0;
336 mz
->mz_row_offset
= 0;
337 mz
->mz_col_offset
= 0;
339 _region_init(&r
, (void *)var
, lenvar
);
340 _memstream_bind(&ms
, &r
);
341 if (parse_var(mz
, &ms
)) {
346 mt
->mt_src_max
= mt
->mt_dst_max
= 1; /* 1:1 converter */
347 mt
->mt_state_size
= 0; /* stateless */
354 _citrus_mapper_zone_mapper_uninit(struct _citrus_mapper
*cm
)
360 _citrus_mapper_zone_mapper_convert(struct _citrus_mapper
* __restrict cm
,
361 _citrus_index_t
* __restrict dst
,
362 _citrus_index_t src
, void * __restrict ps
)
365 struct _citrus_mapper_zone
*mz
= cm
->cm_closure
;
367 if (mz
->mz_col_bits
== 32) {
370 if (col
< mz
->mz_col
.z_begin
|| col
> mz
->mz_col
.z_end
)
371 return _CITRUS_MAPPER_CONVERT_NONIDENTICAL
;
372 if (mz
->mz_col_offset
>0)
373 col
+= (u_int32_t
)mz
->mz_col_offset
;
375 col
-= (u_int32_t
)-mz
->mz_col_offset
;
378 col
= src
& (((u_int32_t
)1<<mz
->mz_col_bits
)-1);
379 row
= src
>> mz
->mz_col_bits
;
380 if (row
< mz
->mz_row
.z_begin
|| row
> mz
->mz_row
.z_end
||
381 col
< mz
->mz_col
.z_begin
|| col
> mz
->mz_col
.z_end
)
382 return _CITRUS_MAPPER_CONVERT_NONIDENTICAL
;
383 if (mz
->mz_col_offset
>0)
384 col
+= (u_int32_t
)mz
->mz_col_offset
;
386 col
-= (u_int32_t
)-mz
->mz_col_offset
;
387 if (mz
->mz_row_offset
>0)
388 row
+= (u_int32_t
)mz
->mz_row_offset
;
390 row
-= (u_int32_t
)-mz
->mz_row_offset
;
391 *dst
= col
| (row
<< mz
->mz_col_bits
);
393 return _CITRUS_MAPPER_CONVERT_SUCCESS
;
398 _citrus_mapper_zone_mapper_init_state(struct _citrus_mapper
* __restrict cm
,
399 void * __restrict ps
)