/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. #include "codegen.h"
  30. #include "segment.h"
  31. #define BLOCK_SIZE 4096
  32. #define MAX_BLOCKS 512
  33. typedef struct block_t
  34. {
  35. U8 memory[BLOCK_SIZE];
  36. }
  37. block_t;
  38. struct cg_segment_t
  39. /************************************************************************/
  40. /* Code segment data structure */
  41. /************************************************************************/
  42. {
  43. const char * name; /* name of the segment */
  44. block_t * blocks[MAX_BLOCKS]; /* array of block pointers */
  45. size_t current_size; /* current size of the segment */
  46. };
  47. cg_segment_t * cg_segment_create(const char * name)
  48. /************************************************************************/
  49. /* Create a named segment. The name is really for debugging only. */
  50. /************************************************************************/
  51. {
  52. cg_segment_t * result = (cg_segment_t *) malloc(sizeof(cg_segment_t));
  53. memset(result->blocks, 0, sizeof(result->blocks));
  54. result->current_size = 0;
  55. result->name = name;
  56. return result;
  57. }
  58. void cg_segment_destroy(cg_segment_t * segment)
  59. /************************************************************************/
  60. /* Destroy the segment and all associated data */
  61. /************************************************************************/
  62. {
  63. size_t index;
  64. for (index = 0; index < MAX_BLOCKS; ++index)
  65. {
  66. if (segment->blocks[index])
  67. free(segment->blocks[index]);
  68. }
  69. free(segment);
  70. }
  71. size_t cg_segment_size(cg_segment_t * segment)
  72. /************************************************************************/
  73. /* Retrieve the current size of a segement */
  74. /************************************************************************/
  75. {
  76. return segment->current_size;
  77. }
  78. const char * cg_segment_name(cg_segment_t * segment)
  79. /************************************************************************/
  80. /* Return the name of the segment */
  81. /************************************************************************/
  82. {
  83. return segment->name;
  84. }
  85. size_t cg_segment_align(cg_segment_t * segment, size_t alignment)
  86. /************************************************************************/
  87. /* Align the memory segment to the given alignment boundary. */
  88. /* The adjusted size is returned. */
  89. /************************************************************************/
  90. {
  91. segment->current_size =
  92. (segment->current_size + (alignment - 1)) & ~(alignment - 1);
  93. return segment->current_size;
  94. }
  95. static block_t * block_pointer(cg_segment_t * segment, size_t block_index)
  96. {
  97. block_t * block = segment->blocks[block_index];
  98. if (block == (block_t *) 0)
  99. {
  100. block = (block_t *) malloc(sizeof(block_t));
  101. memset(block, 0, sizeof(block_t));
  102. segment->blocks[block_index] = block;
  103. }
  104. return block;
  105. }
  106. static void * data_pointer(cg_segment_t * segment, size_t offset)
  107. {
  108. size_t block_index = offset / BLOCK_SIZE;
  109. size_t block_offset = offset % BLOCK_SIZE;
  110. block_t * block = block_pointer(segment, block_index);
  111. return block->memory + block_offset;
  112. }
  113. /****************************************************************************/
  114. /* Emit (append) data to the target segment */
  115. /****************************************************************************/
  116. void cg_segment_emit_u8(cg_segment_t * segment, U8 byte)
  117. {
  118. *((U8 *) data_pointer(segment, segment->current_size)) = byte;
  119. segment->current_size += sizeof(U8);
  120. }
  121. void cg_segment_emit_u16(cg_segment_t * segment, U16 half_word)
  122. {
  123. cg_segment_align(segment, sizeof(U16));
  124. *((U16 *) data_pointer(segment, segment->current_size)) = half_word;
  125. segment->current_size += sizeof(U16);
  126. }
  127. void cg_segment_emit_u32(cg_segment_t * segment, U32 word)
  128. {
  129. cg_segment_align(segment, sizeof(U32));
  130. *((U32 *) data_pointer(segment, segment->current_size)) = word;
  131. segment->current_size += sizeof(U32);
  132. }
  133. void cg_segment_emit_i8(cg_segment_t * segment, I8 byte)
  134. {
  135. *((I8 *) data_pointer(segment, segment->current_size)) = byte;
  136. segment->current_size += sizeof(I8);
  137. }
  138. void cg_segment_emit_i16(cg_segment_t * segment, I16 half_word)
  139. {
  140. cg_segment_align(segment, sizeof(I16));
  141. *((I16 *) data_pointer(segment, segment->current_size)) = half_word;
  142. segment->current_size += sizeof(I16);
  143. }
  144. void cg_segment_emit_i32(cg_segment_t * segment, I32 word)
  145. {
  146. cg_segment_align(segment, sizeof(I32));
  147. *((I32 *) data_pointer(segment, segment->current_size)) = word;
  148. segment->current_size += sizeof(I32);
  149. }
  150. void cg_segment_emit_block(cg_segment_t * segment, const void * p, size_t size)
  151. {
  152. while (size != 0)
  153. {
  154. size_t block_index = segment->current_size / BLOCK_SIZE;
  155. size_t block_offset = segment->current_size % BLOCK_SIZE;
  156. size_t remaining_size = BLOCK_SIZE - block_offset;
  157. size_t chunk_size = (size <= remaining_size) ? size : remaining_size;
  158. block_t * block = block_pointer(segment, block_index);
  159. memcpy(block->memory, p, chunk_size);
  160. segment->current_size += chunk_size;
  161. p = (U8 *) p + chunk_size;
  162. size -= chunk_size;
  163. }
  164. }
  165. /****************************************************************************/
  166. /* Set data in the target segment */
  167. /****************************************************************************/
  168. void cg_segment_set_u8(cg_segment_t * segment, size_t offset, U8 byte)
  169. {
  170. *((U8 *) data_pointer(segment, offset)) = byte;
  171. }
  172. void cg_segment_set_u16(cg_segment_t * segment, size_t offset, U16 half_word)
  173. {
  174. *((U16 *) data_pointer(segment, offset)) = half_word;
  175. }
  176. void cg_segment_set_u32(cg_segment_t * segment, size_t offset, U32 word)
  177. {
  178. *((U32 *) data_pointer(segment, offset)) = word;
  179. }
  180. void cg_segment_set_i8(cg_segment_t * segment, size_t offset, I8 byte)
  181. {
  182. *((I8 *) data_pointer(segment, offset)) = byte;
  183. }
  184. void cg_segment_set_i16(cg_segment_t * segment, size_t offset, I16 half_word)
  185. {
  186. *((I16 *) data_pointer(segment, offset)) = half_word;
  187. }
  188. void cg_segment_set_i32(cg_segment_t * segment, size_t offset, I32 word)
  189. {
  190. *((I32 *) data_pointer(segment, offset)) = word;
  191. }
  192. void cg_segment_set_block(cg_segment_t * segment, size_t offset, const void * p,
  193. size_t size)
  194. {
  195. while (size != 0)
  196. {
  197. size_t block_index = offset / BLOCK_SIZE;
  198. size_t block_offset = offset % BLOCK_SIZE;
  199. size_t remaining_size = BLOCK_SIZE - block_offset;
  200. size_t chunk_size = (size <= remaining_size) ? size : remaining_size;
  201. block_t * block = block_pointer(segment, block_index);
  202. memcpy(block->memory, p, chunk_size);
  203. offset += chunk_size;
  204. p = (U8 *) p + chunk_size;
  205. size -= chunk_size;
  206. }
  207. }
  208. /****************************************************************************/
  209. /* Retrieve data from the target segment */
  210. /****************************************************************************/
  211. U8 cg_segment_get_u8(cg_segment_t * segment, size_t offset)
  212. {
  213. return *((U8 *) data_pointer(segment, offset));
  214. }
  215. U16 cg_segment_get_u16(cg_segment_t * segment, size_t offset)
  216. {
  217. return *((U16 *) data_pointer(segment, offset));
  218. }
  219. U32 cg_segment_get_u32(cg_segment_t * segment, size_t offset)
  220. {
  221. return *((U32 *) data_pointer(segment, offset));
  222. }
  223. I8 cg_segment_get_i8(cg_segment_t * segment, size_t offset)
  224. {
  225. return *((I8 *) data_pointer(segment, offset));
  226. }
  227. I16 cg_segment_get_i16(cg_segment_t * segment, size_t offset)
  228. {
  229. return *((I16 *) data_pointer(segment, offset));
  230. }
  231. I32 cg_segment_get_i32(cg_segment_t * segment, size_t offset)
  232. {
  233. return *((I32 *) data_pointer(segment, offset));
  234. }
  235. void cg_segment_get_block(cg_segment_t * segment, size_t offset, void * p,
  236. size_t size)
  237. {
  238. while (size != 0)
  239. {
  240. size_t block_index = offset / BLOCK_SIZE;
  241. size_t block_offset = offset % BLOCK_SIZE;
  242. size_t remaining_size = BLOCK_SIZE - block_offset;
  243. size_t chunk_size = (size <= remaining_size) ? size : remaining_size;
  244. block_t * block = block_pointer(segment, block_index);
  245. memcpy(p, block->memory, chunk_size);
  246. offset += chunk_size;
  247. p = (U8 *) p + chunk_size;
  248. size -= chunk_size;
  249. }
  250. }