/opengles/src/codegen/segment.c
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