コード例 #1
0
static void instruction_ready(struct schedule_state * s, struct schedule_instruction * sinst)
{
	DBG("%i is now ready\n", sinst->Instruction->IP);

	/* Adding Ready TEX instructions to the end of the "Ready List" helps
	 * us emit TEX instructions in blocks without losing our place. */
	if (sinst->Instruction->Type == RC_INSTRUCTION_NORMAL)
		add_inst_to_list_end(&s->ReadyTEX, sinst);
	else if (sinst->Instruction->U.P.Alpha.Opcode == RC_OPCODE_NOP)
		add_inst_to_list(&s->ReadyRGB, sinst);
	else if (sinst->Instruction->U.P.RGB.Opcode == RC_OPCODE_NOP)
		add_inst_to_list(&s->ReadyAlpha, sinst);
	else
		add_inst_to_list(&s->ReadyFullALU, sinst);
}
コード例 #2
0
static void try_convert_and_pair(
	struct schedule_state *s,
	struct schedule_instruction ** inst_list)
{
	struct schedule_instruction * list_ptr = *inst_list;
	while (list_ptr && *inst_list && (*inst_list)->NextReady) {
		int paired = 0;
		if (list_ptr->Instruction->U.P.Alpha.Opcode != RC_OPCODE_NOP
			&& list_ptr->Instruction->U.P.RGB.Opcode
						!= RC_OPCODE_REPL_ALPHA) {
				goto next;
		}
		if (list_ptr->NumWriteValues == 1
					&& convert_rgb_to_alpha(s, list_ptr)) {

			struct schedule_instruction * pair_ptr;
			remove_inst_from_list(inst_list, list_ptr);
			add_inst_to_list_score(&s->ReadyAlpha, list_ptr);

			for (pair_ptr = s->ReadyRGB; pair_ptr;
					pair_ptr = pair_ptr->NextReady) {
				if (merge_instructions(&pair_ptr->Instruction->U.P,
						&list_ptr->Instruction->U.P)) {
					remove_inst_from_list(&s->ReadyAlpha, list_ptr);
					remove_inst_from_list(&s->ReadyRGB, pair_ptr);
					pair_ptr->PairedInst = list_ptr;

					add_inst_to_list(&s->ReadyFullALU, pair_ptr);
					list_ptr = *inst_list;
					paired = 1;
					break;
				}

			}
		}
		if (!paired) {
next:
			list_ptr = list_ptr->NextReady;
		}
	}
}
コード例 #3
0
/**
 * This function attempts to merge RGB and Alpha instructions together.
 */
static void pair_instructions(struct schedule_state * s)
{
	struct schedule_instruction *rgb_ptr;
	struct schedule_instruction *alpha_ptr;

	/* Some pairings might fail because they require too
	 * many source slots; try all possible pairings if necessary */
	rgb_ptr = s->ReadyRGB;
	while(rgb_ptr) {
		struct schedule_instruction * rgb_next = rgb_ptr->NextReady;
		alpha_ptr = s->ReadyAlpha;
		while(alpha_ptr) {
			struct schedule_instruction * alpha_next = alpha_ptr->NextReady;
			if (merge_instructions(&rgb_ptr->Instruction->U.P, &alpha_ptr->Instruction->U.P)) {
				/* Remove RGB and Alpha from their ready lists.
				 */
				remove_inst_from_list(&s->ReadyRGB, rgb_ptr);
				remove_inst_from_list(&s->ReadyAlpha, alpha_ptr);
				rgb_ptr->PairedInst = alpha_ptr;
				add_inst_to_list(&s->ReadyFullALU, rgb_ptr);
				break;
			}
			alpha_ptr = alpha_next;
		}
		rgb_ptr = rgb_next;
	}

	if (!s->Opt) {
		return;
	}

	/* Full instructions that have RC_OPCODE_REPL_ALPHA in the RGB
	 * slot can be converted into Alpha instructions. */
	try_convert_and_pair(s, &s->ReadyFullALU);

	/* Try to convert some of the RGB instructions to Alpha and
	 * try to pair it with another RGB. */
	try_convert_and_pair(s, &s->ReadyRGB);
}