📄 slang_execute_x86.c
字号:
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_arcsine:
/* TODO: use fpatan (?) */
x86_call (&G->f, (GLubyte *) _mesa_asinf);
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_arctan:
/* TODO: use fpatan */
x86_call (&G->f, (GLubyte *) _mesa_atanf);
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_power:
x87_fld (&G->f, x86_deref (G->r_esp));
x87_fld (&G->f, x86_make_disp (G->r_esp, 4));
x87_fyl2x (&G->f);
emit_x87_ex2 (G);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_log2:
x87_fld1 (&G->f);
x87_fld (&G->f, x86_deref (G->r_esp));
x87_fyl2x (&G->f);
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_floor:
x86_call (&G->f, (GLubyte *) do_floorf);
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_ceil:
x86_call (&G->f, (GLubyte *) do_ceilf);
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_noise1:
x86_call (&G->f, (GLubyte *) _slang_library_noise1);
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_noise2:
x86_call (&G->f, (GLubyte *) _slang_library_noise2);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_noise3:
x86_call (&G->f, (GLubyte *) _slang_library_noise4);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 8));
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_float_noise4:
x86_call (&G->f, (GLubyte *) _slang_library_noise4);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 12));
x87_fstp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_int_to_float:
break;
case slang_asm_int_to_addr:
x87_fld (&G->f, x86_deref (G->r_esp));
x87_fistp (&G->f, x86_deref (G->r_esp));
break;
case slang_asm_addr_copy:
x86_pop (&G->f, G->r_eax);
x86_mov (&G->f, G->r_ecx, x86_deref (G->r_esp));
x86_mov (&G->f, x86_deref (G->r_ecx), G->r_eax);
break;
case slang_asm_addr_push:
/* TODO: use push imm32 */
x86_mov_reg_imm (&G->f, G->r_eax, (GLint) a->param[0]);
x86_push (&G->f, G->r_eax);
break;
case slang_asm_addr_add:
x86_pop (&G->f, G->r_eax);
x86_add (&G->f, x86_deref (G->r_esp), G->r_eax);
break;
case slang_asm_addr_multiply:
x86_pop (&G->f, G->r_ecx);
x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp));
x86_mul (&G->f, G->r_ecx);
x86_mov (&G->f, x86_deref (G->r_esp), G->r_eax);
break;
case slang_asm_vec4_tex1d:
x86_call (&G->f, (GLubyte *) _slang_library_tex1d);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 12));
break;
case slang_asm_vec4_tex2d:
x86_call (&G->f, (GLubyte *) _slang_library_tex2d);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16));
break;
case slang_asm_vec4_tex3d:
x86_call (&G->f, (GLubyte *) _slang_library_tex3d);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
break;
case slang_asm_vec4_texcube:
x86_call (&G->f, (GLubyte *) _slang_library_texcube);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
break;
case slang_asm_vec4_shad1d:
x86_call (&G->f, (GLubyte *) _slang_library_shad1d);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
break;
case slang_asm_vec4_shad2d:
x86_call (&G->f, (GLubyte *) _slang_library_shad2d);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20));
break;
case slang_asm_jump:
add_fixup (G, a->param[0], x86_jmp_forward (&G->f));
break;
case slang_asm_jump_if_zero:
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));
x86_xor (&G->f, G->r_eax, G->r_eax);
x86_cmp (&G->f, G->r_eax, x86_make_disp (G->r_esp, -4));
{
GLubyte *lab0;
/* TODO: use jcc rel8 */
lab0 = x86_jcc_forward (&G->f, cc_NE);
add_fixup (G, a->param[0], x86_jmp_forward (&G->f));
x86_fixup_fwd_jump (&G->f, lab0);
}
break;
case slang_asm_enter:
/* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
assert (a->param[0] != 0);
x86_push (&G->f, G->r_ebp);
x86_lea (&G->f, G->r_ebp, x86_make_disp (G->r_esp, (GLint) a->param[0]));
break;
case slang_asm_leave:
x86_pop (&G->f, G->r_ebp);
break;
case slang_asm_local_alloc:
/* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
assert (a->param[0] != 0);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -(GLint) a->param[0]));
break;
case slang_asm_local_free:
/* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */
assert (a->param[0] != 0);
x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, (GLint) a->param[0]));
break;
case slang_asm_local_addr:
disp = -(GLint) (a->param[0] + a->param[1]) + 4;
if (disp != 0)
{
x86_lea (&G->f, G->r_eax, x86_make_disp (G->r_ebp, disp));
x86_push (&G->f, G->r_eax);
}
else
x86_push (&G->f, G->r_ebp);
break;
case slang_asm_global_addr:
/* TODO: use push imm32 */
x86_mov_reg_imm (&G->f, G->r_eax, (GLint) &G->mach->mem + a->param[0]);
x86_push (&G->f, G->r_eax);
break;
case slang_asm_call:
add_fixup (G, a->param[0], x86_call_forward (&G->f));
break;
case slang_asm_return:
x86_ret (&G->f);
break;
case slang_asm_discard:
x86_jmp (&G->f, G->l_discard);
break;
case slang_asm_exit:
x86_jmp (&G->f, G->l_exit);
break;
/* mesa-specific extensions */
case slang_asm_float_print:
x86_call (&G->f, (GLubyte *) do_print_float);
break;
case slang_asm_int_print:
x86_call (&G->f, (GLubyte *) do_print_int);
break;
case slang_asm_bool_print:
x86_call (&G->f, (GLubyte *) do_print_bool);
break;
default:
assert (0);
}
}
GLboolean _slang_x86_codegen (slang_machine *mach, slang_assembly_file *file, GLuint start)
{
codegen_ctx G;
GLubyte *j_body, *j_exit;
GLuint i;
/*
* We need as much as 1M because *all* assembly, including built-in library, is
* being translated to x86.
* The built-in library occupies 450K, so we can be safe for now.
* It is going to change in the future, when we get assembly analysis running.
*/
x86_init_func_size (&G.f, 1048576);
G.r_eax = x86_make_reg (file_REG32, reg_AX);
G.r_ecx = x86_make_reg (file_REG32, reg_CX);
G.r_edx = x86_make_reg (file_REG32, reg_DX);
G.r_esp = x86_make_reg (file_REG32, reg_SP);
G.r_ebp = x86_make_reg (file_REG32, reg_BP);
G.r_st0 = x86_make_reg (file_x87, 0);
G.r_st1 = x86_make_reg (file_x87, 1);
G.r_st2 = x86_make_reg (file_x87, 2);
G.r_st3 = x86_make_reg (file_x87, 3);
G.fixups = NULL;
G.fixup_count = 0;
G.labels = (GLubyte **) slang_alloc_malloc (file->count * sizeof (GLubyte *));
G.mach = mach;
G.fpucntl = RESTORE_FPU;
mach->x86.fpucntl_rnd_neg = RND_NEG_FPU;
mach->x86.fpucntl_restore = RESTORE_FPU;
/* prepare stack and jump to start */
x86_push (&G.f, G.r_ebp);
x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &mach->x86.esp_restore);
x86_push (&G.f, G.r_esp);
x86_pop (&G.f, G.r_ecx);
x86_mov (&G.f, x86_deref (G.r_eax), G.r_ecx);
j_body = x86_jmp_forward (&G.f);
/* "discard" instructions jump to this label */
G.l_discard = x86_get_label (&G.f);
x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &G.mach->kill);
x86_mov_reg_imm (&G.f, G.r_ecx, 1);
x86_mov (&G.f, x86_deref (G.r_eax), G.r_ecx);
G.l_exit = x86_get_label (&G.f);
j_exit = x86_jmp_forward (&G.f);
for (i = 0; i < file->count; i++)
{
G.labels[i] = x86_get_label (&G.f);
if (i == start)
x86_fixup_fwd_jump (&G.f, j_body);
codegen_assem (&G, &file->code[i]);
}
/*
* Restore stack and return.
* This must be handled this way, because "discard" can be invoked from any
* place in the code.
*/
x86_fixup_fwd_jump (&G.f, j_exit);
x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &mach->x86.esp_restore);
x86_mov (&G.f, G.r_esp, x86_deref (G.r_eax));
x86_pop (&G.f, G.r_ebp);
if (G.fpucntl != RESTORE_FPU)
{
x87_fnclex (&G.f);
x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &G.mach->x86.fpucntl_restore);
x87_fldcw (&G.f, x86_deref (G.r_eax));
}
x86_ret (&G.f);
/* fixup forward labels */
for (i = 0; i < G.fixup_count; i++)
{
G.f.csr = G.labels[G.fixups[i].index];
x86_fixup_fwd_jump (&G.f, G.fixups[i].csr);
}
slang_alloc_free (G.fixups);
slang_alloc_free (G.labels);
/* install new code */
if (mach->x86.compiled_func != NULL)
_mesa_exec_free (mach->x86.compiled_func);
mach->x86.compiled_func = (GLvoid (*) (slang_machine *)) x86_get_func (&G.f);
return GL_TRUE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -