⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slang_execute_x86.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -