/* * mm_free - Freeing a block does nothing. */ void mm_free(void *ptr) { int index; // get size of the block unsigned int size = SIZE(ptr); // get index of the freelist if(size == 4104) { index = 18; // coalescing or not if (((char*)freelist[index].next == ((char*)ptr - 4104))) { index = 19; ptr = (char*)ptr - 4104; *(size_t *)((char*)ptr - 8) = 8208; remove_from_head(&freelist[18]); } } else if(size == 8208) { index = 18; *(size_t *)((char*)ptr - 8) = 4104; ptr = (char*)ptr + 4104; *(size_t *)((char*)ptr - 8) = 4104; insert_at_head(ptr, &freelist[index]); ptr = (char*)ptr - 4104; } else { index = get_index(size); } // insert at the head of the freelist insert_at_head(ptr,&freelist[index]); return; }
/** * Update fragment state. This is called just prior to drawing * something when some fragment-related state has changed. */ void llvmpipe_update_fs(struct llvmpipe_context *lp) { struct lp_fragment_shader *shader = lp->fs; struct lp_fragment_shader_variant_key key; struct lp_fragment_shader_variant *variant = NULL; struct lp_fs_variant_list_item *li; make_variant_key(lp, shader, &key); li = first_elem(&shader->variants); while(!at_end(&shader->variants, li)) { if(memcmp(&li->base->key, &key, shader->variant_key_size) == 0) { variant = li->base; break; } li = next_elem(li); } if (variant) { move_to_head(&lp->fs_variants_list, &variant->list_item_global); } else { int64_t t0, t1; int64_t dt; unsigned i; if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) { struct pipe_context *pipe = &lp->pipe; /* * XXX: we need to flush the context until we have some sort of reference * counting in fragment shaders as they may still be binned * Flushing alone might not be sufficient we need to wait on it too. */ llvmpipe_finish(pipe, __FUNCTION__); for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) { struct lp_fs_variant_list_item *item = last_elem(&lp->fs_variants_list); remove_shader_variant(lp, item->base); } } t0 = os_time_get(); variant = generate_variant(lp, shader, &key); t1 = os_time_get(); dt = t1 - t0; LP_COUNT_ADD(llvm_compile_time, dt); LP_COUNT_ADD(nr_llvm_compiles, 2); /* emit vs. omit in/out test */ if (variant) { insert_at_head(&shader->variants, &variant->list_item_local); insert_at_head(&lp->fs_variants_list, &variant->list_item_global); lp->nr_fs_variants++; shader->variants_cached++; } } lp_setup_set_fs_variant(lp->setup, variant); }
static struct dynfn *makeSSENormal3fv( GLcontext *ctx, const int *key ) { /* Requires P4 (sse2?) */ static unsigned char temp[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $0x12345678,%edx */ 0xf3, 0x0f, 0x7e, 0x00, /* movq (%eax),%xmm0 */ 0x66, 0x0f, 0x6e, 0x48, 0x08, /* movd 0x8(%eax),%xmm1 */ 0x66, 0x0f, 0xd6, 0x42, 0x0c, /* movq %xmm0,0xc(%edx) */ 0x66, 0x0f, 0x7e, 0x4a, 0x14, /* movd %xmm1,0x14(%edx) */ 0xc3, /* ret */ }; struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); insert_at_head( &rmesa->vb.dfn_cache.Normal3fv, dfn ); dfn->key[0] = key[0]; dfn->key[1] = key[1]; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 5, 0x0, (int)vb.normalptr); return dfn; }
struct dynfn *tnl_makeX86Attr4ubv( TNLcontext *tnl, int key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); insert_at_head( &tnl->dfn_cache.Color4ubv, dfn ); dfn->key = key; if (TNL_DEBUG & DEBUG_CODEGEN) _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key ); if (key & TNL_CP_VC_FRMT_PKCOLOR) { static char temp[] = { 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ 0x8b, 0x00, /* mov (%eax),%eax */ 0x89, 0x02, /* mov %eax,(%edx) */ 0xc3, /* ret */ }; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 5, 0x12345678, (int)tnl->ubytecolorptr); return dfn; } else { static char temp[] = { 0x53, /* push %ebx */ 0xba, 0x00, 0x00, 0x00, 0x00, /* mov $0x0,%edx */ 0x31, 0xc0, /* xor %eax,%eax */ 0x31, 0xc9, /* xor %ecx,%ecx */ 0x8b, 0x5c, 0x24, 0x08, /* mov 0x8(%esp,1), %ebx */ 0x8b, 0x1b, /* mov (%ebx), %ebx */ 0x88, 0xd8, /* mov %bl, %al */ 0x88, 0xf9, /* mov %bh, %cl */ 0x8b, 0x04, 0x82, /* mov (%edx,%eax,4),%eax */ 0x8b, 0x0c, 0x8a, /* mov (%edx,%ecx,4),%ecx */ 0xa3, 0xaf, 0xbe, 0xad, 0xde, /* mov %eax,0xdeadbeaf */ 0x89, 0x0d, 0xaf, 0xbe, 0xad, 0xde, /* mov %ecx,0xdeadbeaf */ 0x31, 0xc0, /* xor %eax,%eax */ 0x31, 0xc9, /* xor %ecx,%ecx */ 0xc1, 0xeb, 0x10, /* shr $0x10, %ebx */ 0x88, 0xd8, /* mov %bl, %al */ 0x88, 0xf9, /* mov %bh, %cl */ 0x8b, 0x04, 0x82, /* mov (%edx,%eax,4),%eax */ 0x8b, 0x0c, 0x8a, /* mov (%edx,%ecx,4),%ecx */ 0xa3, 0xaf, 0xbe, 0xad, 0xde, /* mov %eax,0xdeadbeaf */ 0x89, 0x0d, 0xaf, 0xbe, 0xad, 0xde, /* mov %ecx,0xdeadbeaf */ 0x5b, /* pop %ebx */ 0xc3, /* ret */ }; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); FIXUP(dfn->code, 27, 0xdeadbeaf, (int)tnl->floatcolorptr); FIXUP(dfn->code, 33, 0xdeadbeaf, (int)tnl->floatcolorptr+4); FIXUP(dfn->code, 55, 0xdeadbeaf, (int)tnl->floatcolorptr+8); FIXUP(dfn->code, 61, 0xdeadbeaf, (int)tnl->floatcolorptr+12); return dfn; } }
struct dynfn *tnl_makeX86Attr3f( TNLcontext *tnl, int key ) { static char temp[] = { 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */ 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ 0x89, 0x02, /* mov %eax,(%edx) */ 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */ 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */ 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */ 0xc3, /* ret */ }; struct dynfn *dfn = MALLOC_STRUCT( dynfn ); if (TNL_DEBUG & DEBUG_CODEGEN) _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key ); insert_at_head( &tnl->dfn_cache.Normal3f, dfn ); dfn->key = key; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr); return dfn; }
void util_cache_set(struct util_cache *cache, void *key, void *value) { struct util_cache_entry *entry; uint32_t hash = cache->hash(key); assert(cache); if (!cache) return; entry = util_cache_entry_get(cache, hash, key); if (!entry) entry = cache->lru.prev; if (cache->count >= cache->size / CACHE_DEFAULT_ALPHA) util_cache_entry_destroy(cache, cache->lru.prev); util_cache_entry_destroy(cache, entry); #ifdef DEBUG ++entry->count; #endif entry->key = key; entry->hash = hash; entry->value = value; entry->state = FILLED; insert_at_head(&cache->lru, entry); cache->count++; ensure_sanity(cache); }
int main(int argc, char const *argv[]) { struct node *head = NULL; int option = 1, aux_i; while(option != 0) { printf("1. Add at head.\n2. List items.\n3. Solve.\n0. Exit.\n"); scanf("%d", &option); if(option == 1) { struct node *new_head; printf("value: "); scanf("%d", &aux_i); new_head->next = NULL; new_head->data = aux_i; insert_at_head(head, new_head); } else if(option == 2) { print_list(head); } else if(option == 3) { int n; printf("N:"); scanf("%d", &n); solve(head, n); } } return 0; }
int main() { slist_t *head = NULL, *tail = NULL; size_t list_size = 0; int i, ret; time_t t; time (&t); srand (t); for (i = 13; i > 0; i--) { ret = insert_at_head (&head, &tail, &list_size, (rand() % 10)); if (ret < 0) { destroy_list (&head, &tail); return -1; } } print_list (&head); delete_duplicates (&head, &list_size); print_list (&head); destroy_list (&head, &tail); print_list (&head); return 0; }
struct dynfn *tnl_makeX86Vertex2f( TNLcontext *tnl, int key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); if (RADEON_DEBUG & DEBUG_CODEGEN) _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key ); switch (tnl->vertex_size) { default: { /* Repz convenient as it's possible to emit code for any size * vertex with little tweaking. Might as well read vertsize * though, and have only one of these. */ static char temp[] = { 0x57, /* push %edi */ 0x56, /* push %esi */ 0xbe, 0, 0, 0, 0, /* mov $VERTEX+2,%esi */ 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */ 0x8b, 0x44, 0x24, 0x0c, /* mov 0x0c(%esp,1),%eax */ 0x8b, 0x54, 0x24, 0x10, /* mov 0x10(%esp,1),%edx */ 0x89, 0x07, /* mov %eax,(%edi) */ 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */ 0x83, 0xc7, 0x08, /* add $0x8,%edi */ 0xb9, 0, 0, 0, 0, /* mov $VERTSIZE-2,%ecx */ 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/ 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */ 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */ 0x48, /* dec %eax */ 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */ 0x5e, /* pop %esi */ 0x5f, /* pop %edi */ 0x74, 0x01, /* je +1 */ 0xc3, /* ret */ 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */ }; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[2]); FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr); FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-2); FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter); FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr); FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter); FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify); break; } } insert_at_head( &tnl->dfn_cache.Vertex3f, dfn ); dfn->key = key; return dfn; }
struct dynfn *tnl_makeX86Attr4ub( TNLcontext *tnl, int key ) { if (TNL_DEBUG & DEBUG_CODEGEN) _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key ); if (key & TNL_CP_VC_FRMT_PKCOLOR) { /* XXX push/pop */ static char temp[] = { 0x53, /* push %ebx */ 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */ 0x8b, 0x54, 0x24, 0x0c, /* mov 0xc(%esp,1),%edx */ 0x8b, 0x4c, 0x24, 0x10, /* mov 0x10(%esp,1),%ecx */ 0x8b, 0x5c, 0x24, 0x14, /* mov 0x14(%esp,1),%ebx */ 0xa2, 0, 0, 0, 0, /* mov %al,DEST */ 0x88, 0x15, 0, 0, 0, 0, /* mov %dl,DEST+1 */ 0x88, 0x0d, 0, 0, 0, 0, /* mov %cl,DEST+2 */ 0x88, 0x1d, 0, 0, 0, 0, /* mov %bl,DEST+3 */ 0x5b, /* pop %ebx */ 0xc3, /* ret */ }; struct dynfn *dfn = MALLOC_STRUCT( dynfn ); insert_at_head( &tnl->dfn_cache.Color4ub, dfn ); dfn->key = key; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 18, 0x0, (int)tnl->ubytecolorptr); FIXUP(dfn->code, 24, 0x0, (int)tnl->ubytecolorptr+1); FIXUP(dfn->code, 30, 0x0, (int)tnl->ubytecolorptr+2); FIXUP(dfn->code, 36, 0x0, (int)tnl->ubytecolorptr+3); return dfn; } else return 0; }
static void llvm_middle_end_prepare_gs(struct llvm_middle_end *fpme) { struct draw_context *draw = fpme->draw; struct draw_geometry_shader *gs = draw->gs.geometry_shader; struct draw_gs_llvm_variant_key *key; struct draw_gs_llvm_variant *variant = NULL; struct draw_gs_llvm_variant_list_item *li; struct llvm_geometry_shader *shader = llvm_geometry_shader(gs); char store[DRAW_GS_LLVM_MAX_VARIANT_KEY_SIZE]; unsigned i; key = draw_gs_llvm_make_variant_key(fpme->llvm, store); /* Search shader's list of variants for the key */ li = first_elem(&shader->variants); while (!at_end(&shader->variants, li)) { if (memcmp(&li->base->key, key, shader->variant_key_size) == 0) { variant = li->base; break; } li = next_elem(li); } if (variant) { /* found the variant, move to head of global list (for LRU) */ move_to_head(&fpme->llvm->gs_variants_list, &variant->list_item_global); } else { /* Need to create new variant */ /* First check if we've created too many variants. If so, free * 25% of the LRU to avoid using too much memory. */ if (fpme->llvm->nr_gs_variants >= DRAW_MAX_SHADER_VARIANTS) { /* * XXX: should we flush here ? */ for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) { struct draw_gs_llvm_variant_list_item *item; if (is_empty_list(&fpme->llvm->gs_variants_list)) { break; } item = last_elem(&fpme->llvm->gs_variants_list); assert(item); assert(item->base); draw_gs_llvm_destroy_variant(item->base); } } variant = draw_gs_llvm_create_variant(fpme->llvm, gs->info.num_outputs, key); if (variant) { insert_at_head(&shader->variants, &variant->list_item_local); insert_at_head(&fpme->llvm->gs_variants_list, &variant->list_item_global); fpme->llvm->nr_gs_variants++; shader->variants_cached++; } } gs->current_variant = variant; }
/** * Prepare/validate middle part of the vertex pipeline. * NOTE: if you change this function, also look at the non-LLVM * function fetch_pipeline_prepare() for similar changes. */ static void llvm_middle_end_prepare( struct draw_pt_middle_end *middle, unsigned in_prim, unsigned opt, unsigned *max_vertices ) { struct llvm_middle_end *fpme = llvm_middle_end(middle); struct draw_context *draw = fpme->draw; struct draw_vertex_shader *vs = draw->vs.vertex_shader; struct draw_geometry_shader *gs = draw->gs.geometry_shader; const unsigned out_prim = gs ? gs->output_primitive : u_assembled_prim(in_prim); unsigned point_clip = draw->rasterizer->fill_front == PIPE_POLYGON_MODE_POINT || out_prim == PIPE_PRIM_POINTS; unsigned nr; fpme->input_prim = in_prim; fpme->opt = opt; draw_pt_post_vs_prepare( fpme->post_vs, draw->clip_xy, draw->clip_z, draw->clip_user, point_clip ? draw->guard_band_points_xy : draw->guard_band_xy, draw->identity_viewport, draw->rasterizer->clip_halfz, (draw->vs.edgeflag_output ? TRUE : FALSE) ); draw_pt_so_emit_prepare( fpme->so_emit, gs == NULL ); if (!(opt & PT_PIPELINE)) { draw_pt_emit_prepare( fpme->emit, out_prim, max_vertices ); *max_vertices = MAX2( *max_vertices, 4096 ); } else { /* limit max fetches by limiting max_vertices */ *max_vertices = 4096; } /* Get the number of float[4] attributes per vertex. * Note: this must be done after draw_pt_emit_prepare() since that * can effect the vertex size. */ nr = MAX2(vs->info.num_inputs, draw_total_vs_outputs(draw)); /* Always leave room for the vertex header whether we need it or * not. It's hard to get rid of it in particular because of the * viewport code in draw_pt_post_vs.c. */ fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); /* Get the number of float[4] attributes per vertex. * Note: this must be done after draw_pt_emit_prepare() since that * can effect the vertex size. */ nr = MAX2(vs->info.num_inputs, draw_total_vs_outputs(draw)); /* Always leave room for the vertex header whether we need it or * not. It's hard to get rid of it in particular because of the * viewport code in draw_pt_post_vs.c. */ fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); /* return even number */ *max_vertices = *max_vertices & ~1; /* Find/create the vertex shader variant */ { struct draw_llvm_variant_key *key; struct draw_llvm_variant *variant = NULL; struct draw_llvm_variant_list_item *li; struct llvm_vertex_shader *shader = llvm_vertex_shader(vs); char store[DRAW_LLVM_MAX_VARIANT_KEY_SIZE]; unsigned i; key = draw_llvm_make_variant_key(fpme->llvm, store); /* Search shader's list of variants for the key */ li = first_elem(&shader->variants); while (!at_end(&shader->variants, li)) { if (memcmp(&li->base->key, key, shader->variant_key_size) == 0) { variant = li->base; break; } li = next_elem(li); } if (variant) { /* found the variant, move to head of global list (for LRU) */ move_to_head(&fpme->llvm->vs_variants_list, &variant->list_item_global); } else { /* Need to create new variant */ /* First check if we've created too many variants. If so, free * 25% of the LRU to avoid using too much memory. */ if (fpme->llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) { /* * XXX: should we flush here ? */ for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) { struct draw_llvm_variant_list_item *item; if (is_empty_list(&fpme->llvm->vs_variants_list)) { break; } item = last_elem(&fpme->llvm->vs_variants_list); assert(item); assert(item->base); draw_llvm_destroy_variant(item->base); } } variant = draw_llvm_create_variant(fpme->llvm, nr, key); if (variant) { insert_at_head(&shader->variants, &variant->list_item_local); insert_at_head(&fpme->llvm->vs_variants_list, &variant->list_item_global); fpme->llvm->nr_variants++; shader->variants_cached++; } } fpme->current_variant = variant; } if (gs) { llvm_middle_end_prepare_gs(fpme); } }
static void llvm_middle_end_prepare( struct draw_pt_middle_end *middle, unsigned in_prim, unsigned opt, unsigned *max_vertices ) { struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; struct draw_context *draw = fpme->draw; struct llvm_vertex_shader *shader = llvm_vertex_shader(draw->vs.vertex_shader); char store[DRAW_LLVM_MAX_VARIANT_KEY_SIZE]; struct draw_llvm_variant_key *key; struct draw_llvm_variant *variant = NULL; struct draw_llvm_variant_list_item *li; unsigned i; unsigned instance_id_index = ~0; const unsigned out_prim = (draw->gs.geometry_shader ? draw->gs.geometry_shader->output_primitive : in_prim); /* Add one to num_outputs because the pipeline occasionally tags on * an additional texcoord, eg for AA lines. */ const unsigned nr = MAX2( shader->base.info.num_inputs, shader->base.info.num_outputs + 1 ); /* Scan for instanceID system value. * XXX but we never use instance_id_index?! */ for (i = 0; i < shader->base.info.num_inputs; i++) { if (shader->base.info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) { instance_id_index = i; break; } } fpme->input_prim = in_prim; fpme->opt = opt; /* Always leave room for the vertex header whether we need it or * not. It's hard to get rid of it in particular because of the * viewport code in draw_pt_post_vs.c. */ fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); /* XXX: it's not really gl rasterization rules we care about here, * but gl vs dx9 clip spaces. */ draw_pt_post_vs_prepare( fpme->post_vs, draw->clip_xy, draw->clip_z, draw->clip_user, draw->identity_viewport, (boolean)draw->rasterizer->gl_rasterization_rules, (draw->vs.edgeflag_output ? TRUE : FALSE) ); draw_pt_so_emit_prepare( fpme->so_emit ); if (!(opt & PT_PIPELINE)) { draw_pt_emit_prepare( fpme->emit, out_prim, max_vertices ); *max_vertices = MAX2( *max_vertices, 4096 ); } else { /* limit max fetches by limiting max_vertices */ *max_vertices = 4096; } /* return even number */ *max_vertices = *max_vertices & ~1; key = draw_llvm_make_variant_key(fpme->llvm, store); /* Search shader's list of variants for the key */ li = first_elem(&shader->variants); while (!at_end(&shader->variants, li)) { if (memcmp(&li->base->key, key, shader->variant_key_size) == 0) { variant = li->base; break; } li = next_elem(li); } if (variant) { /* found the variant, move to head of global list (for LRU) */ move_to_head(&fpme->llvm->vs_variants_list, &variant->list_item_global); } else { /* Need to create new variant */ unsigned i; /* First check if we've created too many variants. If so, free * 25% of the LRU to avoid using too much memory. */ if (fpme->llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) { /* * XXX: should we flush here ? */ for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) { struct draw_llvm_variant_list_item *item = last_elem(&fpme->llvm->vs_variants_list); draw_llvm_destroy_variant(item->base); } } variant = draw_llvm_create_variant(fpme->llvm, nr, key); if (variant) { insert_at_head(&shader->variants, &variant->list_item_local); insert_at_head(&fpme->llvm->vs_variants_list, &variant->list_item_global); fpme->llvm->nr_variants++; shader->variants_cached++; } } fpme->current_variant = variant; /*XXX we only support one constant buffer */ fpme->llvm->jit_context.vs_constants = draw->pt.user.vs_constants[0]; fpme->llvm->jit_context.gs_constants = draw->pt.user.gs_constants[0]; fpme->llvm->jit_context.planes = (float (*) [12][4]) draw->pt.user.planes[0]; fpme->llvm->jit_context.viewport = (float *)draw->viewport.scale; }
struct dynfn *tnl_makeX86Vertex3fv( TNLcontext *tnl, int key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); if (TNL_DEBUG & DEBUG_CODEGEN) _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key ); switch (tnl->vertex_size) { case 6: { static char temp[] = { 0xa1, 0x00, 0x00, 0, 0, /* mov 0x0,%eax */ 0x8b, 0x4c, 0x24, 0x04, /* mov 0x4(%esp,1),%ecx */ 0x8b, 0x11, /* mov (%ecx),%edx */ 0x89, 0x10, /* mov %edx,(%eax) */ 0x8b, 0x51, 0x04, /* mov 0x4(%ecx),%edx */ 0x8b, 0x49, 0x08, /* mov 0x8(%ecx),%ecx */ 0x89, 0x50, 0x04, /* mov %edx,0x4(%eax) */ 0x89, 0x48, 0x08, /* mov %ecx,0x8(%eax) */ 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */ 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */ 0x89, 0x50, 0x0c, /* mov %edx,0xc(%eax) */ 0x89, 0x48, 0x10, /* mov %ecx,0x10(%eax) */ 0x8b, 0x15, 0x24, 0, 0, 0, /* mov 0x24,%edx */ 0x89, 0x50, 0x14, /* mov %edx,0x14(%eax) */ 0x83, 0xc0, 0x18, /* add $0x18,%eax */ 0xa3, 0x00, 0x00, 0, 0, /* mov %eax,0x0 */ 0xa1, 0x04, 0x00, 0, 0, /* mov 0x4,%eax */ 0x48, /* dec %eax */ 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */ 0x74, 0x01, /* je 2a4 <.f11> */ 0xc3, /* ret */ 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */ }; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr); FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]); FIXUP(dfn->code, 33, 0x00000020, (int)&tnl->vertex[4]); FIXUP(dfn->code, 45, 0x00000024, (int)&tnl->vertex[5]); FIXUP(dfn->code, 56, 0x00000000, (int)&tnl->dmaptr); FIXUP(dfn->code, 61, 0x00000004, (int)&tnl->counter); FIXUP(dfn->code, 67, 0x00000004, (int)&tnl->counter); FIXUP(dfn->code, 76, 0x00000008, (int)&tnl->notify); break; } case 8: { static char temp[] = { 0xa1, 0x00, 0x00, 0, 0, /* mov 0x0,%eax */ 0x8b, 0x4c, 0x24, 0x04, /* mov 0x4(%esp,1),%ecx */ 0x8b, 0x11, /* mov (%ecx),%edx */ 0x89, 0x10, /* mov %edx,(%eax) */ 0x8b, 0x51, 0x04, /* mov 0x4(%ecx),%edx */ 0x8b, 0x49, 0x08, /* mov 0x8(%ecx),%ecx */ 0x89, 0x50, 0x04, /* mov %edx,0x4(%eax) */ 0x89, 0x48, 0x08, /* mov %ecx,0x8(%eax) */ 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */ 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */ 0x89, 0x50, 0x0c, /* mov %edx,0xc(%eax) */ 0x89, 0x48, 0x10, /* mov %ecx,0x10(%eax) */ 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */ 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */ 0x89, 0x50, 0x14, /* mov %edx,0x14(%eax) */ 0x89, 0x48, 0x18, /* mov %ecx,0x18(%eax) */ 0x8b, 0x15, 0x24, 0, 0, 0, /* mov 0x24,%edx */ 0x89, 0x50, 0x1c, /* mov %edx,0x1c(%eax) */ 0x83, 0xc0, 0x20, /* add $0x20,%eax */ 0xa3, 0x00, 0x00, 0, 0, /* mov %eax,0x0 */ 0xa1, 0x04, 0x00, 0, 0, /* mov 0x4,%eax */ 0x48, /* dec %eax */ 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */ 0x74, 0x01, /* je 2a4 <.f11> */ 0xc3, /* ret */ 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */ }; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr); FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]); FIXUP(dfn->code, 33, 0x00000020, (int)&tnl->vertex[4]); FIXUP(dfn->code, 45, 0x0000001c, (int)&tnl->vertex[5]); FIXUP(dfn->code, 51, 0x00000020, (int)&tnl->vertex[6]); FIXUP(dfn->code, 63, 0x00000024, (int)&tnl->vertex[7]); FIXUP(dfn->code, 74, 0x00000000, (int)&tnl->dmaptr); FIXUP(dfn->code, 79, 0x00000004, (int)&tnl->counter); FIXUP(dfn->code, 85, 0x00000004, (int)&tnl->counter); FIXUP(dfn->code, 94, 0x00000008, (int)&tnl->notify); break; } default: { /* Repz convenient as it's possible to emit code for any size * vertex with little tweaking. Might as well read vertsize * though, and have only one of these. */ static char temp[] = { 0x8b, 0x54, 0x24, 0x04, /* mov 0x4(%esp,1),%edx */ 0x57, /* push %edi */ 0x56, /* push %esi */ 0x8b, 0x3d, 1,1,1,1, /* mov DMAPTR,%edi */ 0x8b, 0x02, /* mov (%edx),%eax */ 0x8b, 0x4a, 0x04, /* mov 0x4(%edx),%ecx */ 0x8b, 0x72, 0x08, /* mov 0x8(%edx),%esi */ 0x89, 0x07, /* mov %eax,(%edi) */ 0x89, 0x4f, 0x04, /* mov %ecx,0x4(%edi) */ 0x89, 0x77, 0x08, /* mov %esi,0x8(%edi) */ 0x83, 0xc7, 0x0c, /* add $0xc,%edi */ 0xb9, 0x06, 0x00, 0x00, 0x00, /* mov $VERTSIZE-3,%ecx */ 0xbe, 0x58, 0x00, 0x00, 0x00, /* mov $VERTEX[3],%esi */ 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/ 0x89, 0x3d, 1, 1, 1, 1, /* mov %edi,DMAPTR */ 0xa1, 2, 2, 2, 2, /* mov COUNTER,%eax */ 0x5e, /* pop %esi */ 0x5f, /* pop %edi */ 0x48, /* dec %eax */ 0xa3, 2, 2, 2, 2, /* mov %eax,COUNTER */ 0x74, 0x01, /* je +1 */ 0xc3, /* ret */ 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */ }; dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); memcpy (dfn->code, temp, sizeof(temp)); FIXUP(dfn->code, 8, 0x01010101, (int)&tnl->dmaptr); FIXUP(dfn->code, 32, 0x00000006, tnl->vertex_size-3); FIXUP(dfn->code, 37, 0x00000058, (int)&tnl->vertex[3]); FIXUP(dfn->code, 45, 0x01010101, (int)&tnl->dmaptr); FIXUP(dfn->code, 50, 0x02020202, (int)&tnl->counter); FIXUP(dfn->code, 58, 0x02020202, (int)&tnl->counter); FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify); break; } } insert_at_head( &tnl->dfn_cache.Vertex3fv, dfn ); dfn->key = key; return dfn; }