PageRenderTime 41ms CodeModel.GetById 20ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/opengles/src/codegen/segment.c

http://ftk.googlecode.com/
C | 335 lines | 194 code | 85 blank | 56 comment | 10 complexity | 3de7fd4c62f48b3199f5758b32568499 MD5 | raw file
  1/****************************************************************************/
  2/*																			*/
  3/* Copyright (c) 2004, Hans-Martin Will. All rights reserved.				*/
  4/*																			*/
  5/* Redistribution and use in source and binary forms, with or without		*/
  6/* modification, are permitted provided that the following conditions are   */
  7/* met:																		*/
  8/*																			*/
  9/* *  Redistributions of source code must retain the above copyright		*/
 10/*    notice, this list of conditions and the following disclaimer.			*/
 11/*																			*/
 12/* *  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.  */
 15/*																			*/
 16/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS		*/
 17/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT		*/
 18/* LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A   */
 19/* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER */
 20/* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
 21/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,		*/
 22/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR		*/
 23/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF   */
 24/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING		*/
 25/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS		*/
 26/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.				*/
 27/*																			*/
 28/****************************************************************************/
 29
 30#include "codegen.h"
 31#include "segment.h"
 32
 33
 34#define BLOCK_SIZE		4096
 35#define MAX_BLOCKS		512
 36
 37
 38typedef struct block_t 
 39{
 40	U8 memory[BLOCK_SIZE];
 41} 
 42block_t;
 43
 44
 45struct cg_segment_t 
 46	/************************************************************************/
 47	/* Code segment data structure											*/
 48	/************************************************************************/
 49{
 50	const char *	name;					/* name of the segment			*/
 51	block_t *		blocks[MAX_BLOCKS];		/* array of block pointers		*/
 52	size_t			current_size;			/* current size of the segment	*/
 53};
 54
 55
 56cg_segment_t * cg_segment_create(const char * name)
 57	/************************************************************************/
 58	/* Create a named segment. The name is really for debugging only.		*/
 59	/************************************************************************/
 60{
 61	cg_segment_t * result = (cg_segment_t *) malloc(sizeof(cg_segment_t));
 62
 63	memset(result->blocks, 0, sizeof(result->blocks));
 64	result->current_size = 0;
 65	result->name = name;
 66
 67	return result;
 68}
 69
 70
 71void cg_segment_destroy(cg_segment_t * segment)
 72	/************************************************************************/
 73	/* Destroy the segment and all associated data							*/
 74	/************************************************************************/
 75{
 76	size_t index;
 77
 78	for (index = 0; index < MAX_BLOCKS; ++index) 
 79	{
 80		if (segment->blocks[index]) 
 81			free(segment->blocks[index]);
 82	}
 83
 84	free(segment);
 85}
 86
 87
 88size_t cg_segment_size(cg_segment_t * segment) 
 89	/************************************************************************/
 90	/* Retrieve the current size of a segement								*/
 91	/************************************************************************/
 92{
 93	return segment->current_size;
 94}
 95
 96
 97const char * cg_segment_name(cg_segment_t * segment)
 98	/************************************************************************/
 99	/* Return the name of the segment										*/
100	/************************************************************************/
101{
102	return segment->name;
103}
104
105
106size_t cg_segment_align(cg_segment_t * segment, size_t alignment)
107	/************************************************************************/
108	/* Align the memory segment to the given alignment boundary.			*/
109	/* The adjusted size is returned.										*/
110	/************************************************************************/
111{
112	segment->current_size = 
113		(segment->current_size + (alignment - 1)) & ~(alignment - 1);
114	return segment->current_size;
115}
116
117
118static block_t * block_pointer(cg_segment_t * segment, size_t block_index) 
119{
120	block_t * block = segment->blocks[block_index];
121
122	if (block == (block_t *) 0) 
123	{
124		block = (block_t *) malloc(sizeof(block_t));
125		memset(block, 0, sizeof(block_t));
126		segment->blocks[block_index] = block;
127	}
128
129	return block;
130}
131
132static void * data_pointer(cg_segment_t * segment, size_t offset) 
133{
134	size_t block_index = offset / BLOCK_SIZE;
135	size_t block_offset = offset % BLOCK_SIZE;
136
137	block_t * block = block_pointer(segment, block_index);
138
139	return block->memory + block_offset;
140}
141
142/****************************************************************************/
143/* Emit (append) data to the target segment									*/
144/****************************************************************************/
145
146void cg_segment_emit_u8(cg_segment_t * segment, U8 byte) 
147{
148	*((U8 *) data_pointer(segment, segment->current_size)) = byte;
149	segment->current_size += sizeof(U8);
150}
151
152
153void cg_segment_emit_u16(cg_segment_t * segment, U16 half_word) 
154{
155	cg_segment_align(segment, sizeof(U16));
156	*((U16 *) data_pointer(segment, segment->current_size)) = half_word;
157	segment->current_size += sizeof(U16);
158}
159
160
161void cg_segment_emit_u32(cg_segment_t * segment, U32 word)
162{
163	cg_segment_align(segment, sizeof(U32));
164	*((U32 *) data_pointer(segment, segment->current_size)) = word;
165	segment->current_size += sizeof(U32);
166}
167
168
169void cg_segment_emit_i8(cg_segment_t * segment, I8 byte) 
170{
171	*((I8 *) data_pointer(segment, segment->current_size)) = byte;
172	segment->current_size += sizeof(I8);
173}
174
175
176void cg_segment_emit_i16(cg_segment_t * segment, I16 half_word) 
177{
178	cg_segment_align(segment, sizeof(I16));
179	*((I16 *) data_pointer(segment, segment->current_size)) = half_word;
180	segment->current_size += sizeof(I16);
181}
182
183
184void cg_segment_emit_i32(cg_segment_t * segment, I32 word)
185{
186	cg_segment_align(segment, sizeof(I32));
187	*((I32 *) data_pointer(segment, segment->current_size)) = word;
188	segment->current_size += sizeof(I32);
189}
190
191
192void cg_segment_emit_block(cg_segment_t * segment, const void * p, size_t size)
193{
194	while (size != 0) 
195	{
196		size_t block_index = segment->current_size / BLOCK_SIZE;
197		size_t block_offset = segment->current_size % BLOCK_SIZE;
198		
199		size_t remaining_size = BLOCK_SIZE - block_offset;
200		size_t chunk_size = (size <= remaining_size) ? size : remaining_size;
201
202		block_t * block = block_pointer(segment, block_index);
203
204		memcpy(block->memory, p, chunk_size);
205
206		segment->current_size += chunk_size;
207		p = (U8 *) p + chunk_size;
208		size -= chunk_size;
209	}
210}
211
212
213/****************************************************************************/
214/* Set data in the target segment											*/
215/****************************************************************************/
216
217void cg_segment_set_u8(cg_segment_t * segment, size_t offset, U8 byte)
218{
219	*((U8 *) data_pointer(segment, offset)) = byte;
220}
221
222
223void cg_segment_set_u16(cg_segment_t * segment, size_t offset, U16 half_word)
224{
225	*((U16 *) data_pointer(segment, offset)) = half_word;
226}
227
228
229void cg_segment_set_u32(cg_segment_t * segment, size_t offset, U32 word)
230{
231	*((U32 *) data_pointer(segment, offset)) = word;
232}
233
234
235void cg_segment_set_i8(cg_segment_t * segment, size_t offset, I8 byte)
236{
237	*((I8 *) data_pointer(segment, offset)) = byte;
238}
239
240
241void cg_segment_set_i16(cg_segment_t * segment, size_t offset, I16 half_word)
242{
243	*((I16 *) data_pointer(segment, offset)) = half_word;
244}
245
246
247void cg_segment_set_i32(cg_segment_t * segment, size_t offset, I32 word)
248{
249	*((I32 *) data_pointer(segment, offset)) = word;
250}
251
252
253void cg_segment_set_block(cg_segment_t * segment, size_t offset, const void * p, 
254						  size_t size)
255{
256	while (size != 0) 
257	{
258		size_t block_index = offset / BLOCK_SIZE;
259		size_t block_offset = offset % BLOCK_SIZE;
260		
261		size_t remaining_size = BLOCK_SIZE - block_offset;
262		size_t chunk_size = (size <= remaining_size) ? size : remaining_size;
263
264		block_t * block = block_pointer(segment, block_index);
265
266		memcpy(block->memory, p, chunk_size);
267
268		offset += chunk_size;
269		p = (U8 *) p + chunk_size;
270		size -= chunk_size;
271	}
272}
273
274
275/****************************************************************************/
276/* Retrieve data from the target segment									*/
277/****************************************************************************/
278
279U8 cg_segment_get_u8(cg_segment_t * segment, size_t offset)
280{
281	return *((U8 *) data_pointer(segment, offset));
282}
283
284
285U16 cg_segment_get_u16(cg_segment_t * segment, size_t offset)
286{
287	return *((U16 *) data_pointer(segment, offset));
288}
289
290
291U32 cg_segment_get_u32(cg_segment_t * segment, size_t offset)
292{
293	return *((U32 *) data_pointer(segment, offset));
294}
295
296
297I8 cg_segment_get_i8(cg_segment_t * segment, size_t offset)
298{
299	return *((I8 *) data_pointer(segment, offset));
300}
301
302
303I16 cg_segment_get_i16(cg_segment_t * segment, size_t offset)
304{
305	return *((I16 *) data_pointer(segment, offset));
306}
307
308
309I32 cg_segment_get_i32(cg_segment_t * segment, size_t offset)
310{
311	return *((I32 *) data_pointer(segment, offset));
312}
313
314
315void cg_segment_get_block(cg_segment_t * segment, size_t offset, void * p, 
316						  size_t size)
317{
318	while (size != 0) 
319	{
320		size_t block_index = offset / BLOCK_SIZE;
321		size_t block_offset = offset % BLOCK_SIZE;
322		
323		size_t remaining_size = BLOCK_SIZE - block_offset;
324		size_t chunk_size = (size <= remaining_size) ? size : remaining_size;
325
326		block_t * block = block_pointer(segment, block_index);
327
328		memcpy(p, block->memory, chunk_size);
329
330		offset += chunk_size;
331		p = (U8 *) p + chunk_size;
332		size -= chunk_size;
333	}
334}
335