inline static int
med3(unsigned int array[], int l, int m, int r)
{
    unsigned int a = array[l];
    unsigned int b = array[m];
    unsigned int c = array[r];
    if (a < b)
    {
        branch_taken(&global_predictor[4]);
        if (b < c)
        {
            branch_taken(&global_predictor[5]);
            return m;
        }
        else
        {
            branch_not_taken(&global_predictor[5]);
            if (a < c)
            {
                branch_taken(&global_predictor[6]);
                return r;
            }
            else
            {
                branch_not_taken(&global_predictor[6]);
                return l;
            }
        }
    }
    else
    {
        branch_not_taken(&global_predictor[4]);
        if (c < b)
        {
            branch_taken(&global_predictor[7]);
            return m;
        }
        else
        {
            branch_not_taken(&global_predictor[7]);
            if (c < a)
            {
                branch_taken(&global_predictor[8]);
                return r;
            }
            else
            {
                branch_not_taken(&global_predictor[8]);
                return l;
            }
        }
    }
}
inline static int
med3_2(unsigned int array[], int l, int m, int r)
{
    unsigned int a = array[l];
    unsigned int b = array[m];
    unsigned int c = array[r];
    if (a < b)
    {
        branch_taken(&global_predictor[9]);
        if (b < c)
        {
            branch_taken(&global_predictor[10]);
            return m;
        }
        else
        {
            branch_not_taken(&global_predictor[10]);
            if (a < c)
            {
                branch_taken(&global_predictor[11]);
                return r;
            }
            else
            {
                branch_not_taken(&global_predictor[11]);
                return l;
            }
        }
    }
    else
    {
        branch_not_taken(&global_predictor[9]);
        if (c < b)
        {
            branch_taken(&global_predictor[12]);
            return m;
        }
        else
        {
            branch_not_taken(&global_predictor[12]);
            if (c < a)
            {
                branch_taken(&global_predictor[13]);
                return r;
            }
            else
            {
                branch_not_taken(&global_predictor[13]);
                return l;
            }
        }
    }
}
Пример #3
0
void
db_set_single_step(db_regs_t *regs)
{
	db_addr_t pc = PC_REGS(regs);
#ifndef SOFTWARE_SSTEP_EMUL
	db_addr_t brpc;
	u_int inst;

	/*
	 * User was stopped at pc, e.g. the instruction
	 * at pc was not executed.
	 */
	inst = db_get_value(pc, sizeof(int), FALSE);
	if (inst_branch(inst) || inst_call(inst) || inst_return(inst)) {
	    brpc = branch_taken(inst, pc, getreg_val, regs);
	    if (brpc != pc) {	/* self-branches are hopeless */
		db_taken_bkpt = db_set_temp_breakpoint(brpc);
	    }
#if 0
	    /* XXX this seems like a true bug, no?  */
	    pc = next_instr_address(pc, 1);
#endif
	}
#endif /*SOFTWARE_SSTEP_EMUL*/
	pc = next_instr_address(pc, 0);
	db_not_taken_bkpt = db_set_temp_breakpoint(pc);
}
Пример #4
0
void
db_set_single_step(db_regs_t *regs)
{
	db_addr_t pc = PC_REGS(regs), brpc = pc;
	bool unconditional;
	unsigned int inst;

	/*
	 *	User was stopped at pc, e.g. the instruction
	 *	at pc was not executed.
	 */
	inst = db_get_value(pc, sizeof(int), false);
	if (inst_branch(inst) || inst_call(inst) || inst_return(inst)) {
		brpc = branch_taken(inst, pc, regs);
		if (brpc != pc) {	/* self-branches are hopeless */
			db_set_temp_breakpoint(&db_taken_bkpt, brpc);
		} else
			db_taken_bkpt.address = 0;
		pc = next_instr_address(pc, true);
	}

	/*
	 *	Check if this control flow instruction is an
	 *	unconditional transfer.
	 */
	unconditional = inst_unconditional_flow_transfer(inst);

	pc = next_instr_address(pc, false);

	/*
	 *	We only set the sequential breakpoint if previous
	 *	instruction was not an unconditional change of flow
	 *	control.  If the previous instruction is an
	 *	unconditional change of flow control, setting a
	 *	breakpoint in the next sequential location may set
	 *	a breakpoint in data or in another routine, which
	 *	could screw up in either the program or the debugger.
	 *	(Consider, for instance, that the next sequential
	 *	instruction is the start of a routine needed by the
	 *	debugger.)
	 *
	 *	Also, don't set both the taken and not-taken breakpoints
	 *	in the same place even if the MD code would otherwise
	 *	have us do so.
	 */
	if (unconditional == false &&
	    db_find_breakpoint_here(pc) == 0 &&
	    pc != brpc)
		db_set_temp_breakpoint(&db_not_taken_bkpt, pc);
	else
		db_not_taken_bkpt.address = 0;
}
static void
insertion_reverse(unsigned int a[], int N)
{
	int i;
	unsigned int v;
	for(i = N-2; i >= 0; i--)
	{
		int j = i;
		branch_taken(&global_predictor[12]);
		v = a[i];

		while((j < N-1) && less(v, a[j+1]))
		{
			branch_taken(&global_predictor[13]);
			a[j] = a[j+1];
			j++;
		}
		branch_not_taken(&global_predictor[13]);
		a[j] = v;
	}
	branch_not_taken(&global_predictor[12]);
}
static void
insertion(unsigned int a[], int N)
{
	int i;
	unsigned int v;
	for(i = 1; i < N; i++)
	{
		int j = i;
		branch_taken(&global_predictor[10]);
		v = a[i];

		while((j > 0) && less(v, a[j-1]))
		{
			branch_taken(&global_predictor[11]);
			a[j] = a[j-1];
			j--;
		}
		branch_not_taken(&global_predictor[11]);
		a[j] = v;
	}
	branch_not_taken(&global_predictor[10]);
}
static void
fixDown(unsigned int a[], int parent, int N)
{
	int child;
	unsigned int v = a[parent];
	while(1) /* see if it has any children */
	{
		if (2*parent <= N) branch_taken(up_down0);
		else
		{
			branch_not_taken(up_down0);
			break;
		}
		child = 2*parent;

		/* its important that this be less for my improvement */
		if (less(a[child], a[child+1])) /* see if it has more than 1 child - check which child is larger */
		{
			branch_taken(up_down1);
			child++;
		}
		else branch_not_taken(up_down1);

		if (!less(v, a[child])) /* when the larger child isnt large enough to be promoted, stop */
		{
			branch_taken(up_down2);
			break;
		}
		else branch_not_taken(up_down2);
	
		/* move down */ 
		a[parent] = a[child];

		parent = child;
	}
	
	a[parent] = v;

}
Пример #8
0
void
db_set_task_single_step(
	register db_regs_t	*regs,
	task_t		   	task)
{
	db_addr_t pc = PC_REGS(regs), brpc;
	register unsigned int	 inst;
	register boolean_t       unconditional;

	/*
	 *	User was stopped at pc, e.g. the instruction
	 *	at pc was not executed.
	 */
	inst = db_get_task_value(pc, sizeof(int), FALSE, task);
	if (inst_branch(inst) || inst_call(inst)) {
	    extern db_expr_t getreg_val();	/* XXX -- need prototype! */

	    brpc = branch_taken(inst, pc, getreg_val, (unsigned char*)regs);
	    if (brpc != pc) {	/* self-branches are hopeless */
		db_taken_bkpt = db_set_temp_breakpoint(task, brpc);
	    } else
	        db_taken_bkpt = 0;
	    pc = next_instr_address(pc,1,task);
	} else 
	    pc = next_instr_address(pc,0,task);
	
	/* 
	 * check if this control flow instruction is an
	 * unconditional transfer
	 */

	unconditional = inst_unconditional_flow_transfer(inst);

	/* 
	  We only set the sequential breakpoint if previous instruction was not
	  an unconditional change of flow of control. If the previous instruction
	  is an unconditional change of flow of control, setting a breakpoint in the
	  next sequential location may set a breakpoint in data or in another routine,
	  which could screw up either the program or the debugger. 
	  (Consider, for instance, that the next sequential instruction is the 
	  start of a routine needed by the debugger.)
	*/
	if (!unconditional && db_find_breakpoint_here(task, pc) == 0 &&
	    (db_taken_bkpt == 0 || db_taken_bkpt->address != pc)) {
	    	db_not_taken_bkpt = db_set_temp_breakpoint(task, pc);
	} else
	    	db_not_taken_bkpt = 0;
}
inline static void
insertion(unsigned int a[], int N)
{
    int i;
    unsigned int v;
    for(i = 2; i < N; i++)
    {
        int j = i;
        v = a[i];

        while(less(v, a[j-1]))
        {
            branch_taken(&global_predictor[3]);
            a[j] = a[j-1];
            j--;
        }
        branch_not_taken(&global_predictor[3]);
        a[j] = v;
    }
}
Пример #10
0
void
db_set_single_step(db_regs_t *regs)
{
	db_addr_t pc = PC_REGS(regs), brpc;
	 unsigned	 inst;

	/*
	 *	User was stopped at pc, e.g. the instruction
	 *	at pc was not executed.
	 */
	inst = db_get_value(pc, sizeof(int), FALSE);
	if (inst_branch(inst) || inst_call(inst)) {
	    brpc = branch_taken(inst, pc, regs);
	    if (brpc != pc) {	/* self-branches are hopeless */
		db_taken_bkpt = db_set_temp_breakpoint(brpc);
	    }
	    pc = next_instr_address(pc,1);
	}
	pc = next_instr_address(pc,0);
	db_not_taken_bkpt = db_set_temp_breakpoint(pc);
}
Пример #11
0
void bxInstrumentation::bx_instr_far_branch(unsigned what, Bit16u new_cs, bx_address new_eip)
{
  branch_taken(new_eip);
}
Пример #12
0
void bxInstrumentation::bx_instr_ucnear_branch(unsigned what, bx_address new_eip)
{
  branch_taken(new_eip);
}
Пример #13
0
void bxInstrumentation::bx_instr_cnear_branch_taken(bx_address new_eip)
{
  branch_taken(new_eip);
}
static void
merge_reverse(unsigned int source[], int N, int starting_size, unsigned int target[])
{
	unsigned int *temp_pointer;
	unsigned int next_count = starting_size * 2;

	int track = N-1;
	int i = N-1;
	int j = i - (next_count - 1);
	int k = i;
	int d = -1;
	if (j < 0) j = 0;

/*	printf("merge reverse(%p, %d, %d, %p) => ", source, N, starting_size, target); */

	while(1)
	{
		/* iterate through the left list */
		while(1)
		{
#ifdef _USE_ROLLED_LOOPS
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[16]);
				break;
			}
			branch_not_taken(&global_predictor[16]);
			target[k] = source[i];
			k += d;
			i--;
#else
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[30]);
				break;
			}
			branch_not_taken(&global_predictor[30]);
			target[k] = source[i];
			k += d;
			i--;


			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[31]);
				break;
			}
			branch_not_taken(&global_predictor[31]);
			target[k] = source[i];
			k += d;
			i--;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[32]);
				break;
			}
			branch_not_taken(&global_predictor[32]);
			target[k] = source[i];
			k += d;
			i--;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[33]);
				break;
			}
			branch_not_taken(&global_predictor[33]);
			target[k] = source[i];
			k += d;
			i--;
			
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[34]);
				break;
			}
			branch_not_taken(&global_predictor[34]);
			target[k] = source[i];
			k += d;
			i--;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[35]);
				break;
			}
			branch_not_taken(&global_predictor[35]);
			target[k] = source[i];
			k += d;
			i--;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[36]);
				break;
			}
			branch_not_taken(&global_predictor[36]);
			target[k] = source[i];
			k += d;
			i--;
		
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[37]);
				break;
			}
			branch_not_taken(&global_predictor[37]);
			target[k] = source[i];
			k += d;
			i--;
#endif
		}

		/* iterate through the right list */
		while(1)
		{

#ifdef _USE_ROLLED_LOOPS
			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[17]);
				break;
			}
			branch_not_taken(&global_predictor[17]);
			target[k] = source[j];
			k += d;
			j++;
#else
			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[38]);
				break;
			}
			branch_not_taken(&global_predictor[38]);
			target[k] = source[j];
			k += d;
			j++;


			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[39]);
				break;
			}
			branch_not_taken(&global_predictor[39]);
			target[k] = source[j];
			k += d;
			j++;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[40]);
				break;
			}
			branch_not_taken(&global_predictor[40]);
			target[k] = source[j];
			k += d;
			j++;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[41]);
				break;
			}
			branch_not_taken(&global_predictor[41]);
			target[k] = source[j];
			k += d;
			j++;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[42]);
				break;
			}
			branch_not_taken(&global_predictor[42]);
			target[k] = source[j];
			k += d;
			j++;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[43]);
				break;
			}
			branch_not_taken(&global_predictor[43]);
			target[k] = source[j];
			k += d;
			j++;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[44]);
				break;
			}
			branch_not_taken(&global_predictor[44]);
			target[k] = source[j];
			k += d;
			j++;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[45]);
				break;
			}
			branch_not_taken(&global_predictor[45]);
			target[k] = source[j];
			k += d;
			j++;

#endif
		}

		/* check if we're in the middle */
		if(i == j)
		{
			branch_taken(&global_predictor[5]);
			target[k] = source[i];

			i = track - next_count;

			/* check whether we have left the building */
			if (i < 0)
			{
				branch_taken(&global_predictor[6]);
				if (next_count > N) /* this means we're done */
				{
					branch_taken(&global_predictor[7]);
					break;
				}
				branch_not_taken(&global_predictor[7]);

				/* the next iteration will be oevr bigger lists */
				next_count <<= 1;

				temp_pointer = source;
				source = target;
				target = temp_pointer;

				i = N-1;
				j = i - (next_count - 1);
				if (j <= 0)
				{
					j = 0;
				}
				track = i;
				k = i;
				d = -1;
				continue;
			}
			else branch_not_taken(&global_predictor[6]);

			j = i - (next_count - 1);
			if (j <= 0)
			{
				j = 0;
			}

			track = i;

			/* setup k for the next one */
			if (d == 1) 
			{
				branch_taken(&global_predictor[8]);
				d = -1;
				k = i;
			}
			else
			{
				branch_not_taken(&global_predictor[8]);
				d = 1;
				k = j;
			}
		}
		else 
		{
			branch_not_taken(&global_predictor[5]);
			
			if (source[i] == source[j])
			{
				branch_taken(&global_predictor[9]);
				target[k] = source[i];
				i--;
				k += d;
			}
			else branch_not_taken(&global_predictor[9]);
		}
	}
/*	printf("%p\n", target); */
}
static void
merge(unsigned int source[], int N, int starting_size, unsigned int target[])
{
	unsigned int *temp_pointer;
	unsigned int count = starting_size;
	unsigned int next_count = count * 2;

	int track = 0;
	int i = 0;
	int j = next_count - 1;
	int k = 0;
	int d = 1;
	if (j >= N) j = N-1;

/*	printf("merge (%p, %d, %d, %p) => ", source, N, starting_size, target); */

	while(1)
	{
		/* iterate through the left list */
		while(1)
		{
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[14]);
				break;
			}
			branch_not_taken(&global_predictor[14]);
			target[k] = source[i];
			k += d;
			i++;

#ifndef _USE_ROLLED_LOOPS
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[15]);
				break;
			}
			branch_not_taken(&global_predictor[15]);
			target[k] = source[i];
			k += d;
			i++;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[16]);
				break;
			}
			branch_not_taken(&global_predictor[16]);
			target[k] = source[i];
			k += d;
			i++;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[17]);
				break;
			}
			branch_not_taken(&global_predictor[17]);
			target[k] = source[i];
			k += d;
			i++;
			
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[18]);
				break;
			}
			branch_not_taken(&global_predictor[18]);
			target[k] = source[i];
			k += d;
			i++;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[19]);
				break;
			}
			branch_not_taken(&global_predictor[19]);
			target[k] = source[i];
			k += d;
			i++;

			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[20]);
				break;
			}
			branch_not_taken(&global_predictor[20]);
			target[k] = source[i];
			k += d;
			i++;
		
			if (source[i] >= source[j])
			{
				branch_taken(&global_predictor[21]);
				break;
			}
			branch_not_taken(&global_predictor[21]);
			target[k] = source[i];
			k += d;
			i++;
#endif
		}

		/* iterate through the right list */
		while(1)
		{
#ifdef _USE_ROLLED_LOOPS
			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[15]);
				break;
			}
			branch_not_taken(&global_predictor[15]);
			target[k] = source[j];
			k += d;
			j--;
#else
			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[22]);
				break;
			}
			branch_not_taken(&global_predictor[22]);
			target[k] = source[j];
			k += d;
			j--;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[23]);
				break;
			}
			branch_not_taken(&global_predictor[23]);
			target[k] = source[j];
			k += d;
			j--;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[24]);
				break;
			}
			branch_not_taken(&global_predictor[24]);
			target[k] = source[j];
			k += d;
			j--;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[25]);
				break;
			}
			branch_not_taken(&global_predictor[25]);
			target[k] = source[j];
			k += d;
			j--;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[26]);
				break;
			}
			branch_not_taken(&global_predictor[26]);
			target[k] = source[j];
			k += d;
			j--;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[27]);
				break;
			}
			branch_not_taken(&global_predictor[27]);
			target[k] = source[j];
			k += d;
			j--;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[28]);
				break;
			}
			branch_not_taken(&global_predictor[28]);
			target[k] = source[j];
			k += d;
			j--;

			if (source[i] <= source[j])
			{
				branch_taken(&global_predictor[29]);
				break;
			}
			branch_not_taken(&global_predictor[29]);
			target[k] = source[j];
			k += d;
			j--;
#endif
		}

		/* check if we're in the middle */
		if(i == j)
		{
			branch_taken(&global_predictor[0]);
			target[k] = source[i];

			i = track + next_count;

			/* check whether we have left the building */
			if (i >= N)
			{
				branch_taken(&global_predictor[1]);
				if (next_count > N) /* this means we're done */
				{
					branch_taken(&global_predictor[2]);
					break;
				}
				branch_not_taken(&global_predictor[2]);

				/* the next iteration will be oevr bigger lists */
				count = next_count;
				next_count <<= 1;


				temp_pointer = source;
				source = target;
				target = temp_pointer;

				i = 0;
				j = next_count - 1;
				if (j >= N)
				{
					j = N-1;
				}
				track = 0;
				k = 0;
				d = 1;
				continue;
			}
			else branch_not_taken(&global_predictor[1]);

			j = i + next_count - 1;
			if (j >= N)
			{
				j = N-1;
			}

			track = i;

			/* setup k for the next one */
			if (d == 1) 
			{
				branch_taken(&global_predictor[3]);
				d = -1;
				k = j;
			}
			else
			{
				branch_not_taken(&global_predictor[3]);
				d = 1;
				k = i;
			}
		}
		else 
		{
			branch_not_taken(&global_predictor[0]);
			if (source[i] == source[j])
			{
				branch_taken(&global_predictor[4]);
				target[k] = source[i];
				i++;
				k += d;
			}
			else branch_not_taken(&global_predictor[4]);
		}
	}

/*	printf("%p\n", target); */
}
void
algorithm_n(unsigned int a[], int N)
{
	unsigned int* aux = malloc(N * sizeof(unsigned int)); /* make it twice the size to use the notation */

	int s = 0; /* this picks which area we write to */
	
	int i,j; /* indices for the first array */
	int k, l; /* indices for second array */
	
	int d, f; /* d => direction, if (f == 0) keep going */

	unsigned int temp;

	unsigned int* source;
	unsigned int* target;

	describe_predictor(&global_predictor[0], "N2");
	describe_predictor(&global_predictor[1], "N3");
	describe_predictor(&global_predictor[2], "N3 i == j");
	describe_predictor(&global_predictor[3], "N5");
	describe_predictor(&global_predictor[4], "N7");
	describe_predictor(&global_predictor[5], "N9");
	describe_predictor(&global_predictor[6], "N11");
	describe_predictor(&global_predictor[7], "N13");

N2:	/* Prepare for pass */

	i = 0;
	j = N-1;
	k = 0;
	l = N-1;
	d = 1;
	f = 1;

	if (s == 0)
	{
		branch_taken(&global_predictor[0]);
		source = a;
		target = aux;
	}
	else
	{
		branch_not_taken(&global_predictor[0]);
		source = aux;
		target = a;
	}
	
/*	printf("2,3\n"); */

N3: /* compare Ki, Kj */

	if (source[i] > source[j])
	{
		branch_taken(&global_predictor[1]);
/*		printf("3,8\n"); */
		goto N8;
	}
	else branch_not_taken(&global_predictor[1]);

	if (i == j)
	{
		branch_taken(&global_predictor[2]);
		target[k] = source[i];
/*		printf("3,13\n"); */
		goto N13;
	}
	else branch_not_taken(&global_predictor[2]);

/*N4:  transmit Ri */

/*	printf("3,4\n"); */

	target[k] = source[i];
	k = k + d; /* increment in the correct direction */

/*N5: // Stepdown? */

	i++;
	if (source[i-1] <= source[i])
	{
		branch_taken(&global_predictor[3]);
/*		printf("4,3\n"); */
		goto N3;
	}
	else branch_not_taken(&global_predictor[3]);

/*	printf("4,6\n"); */
N6: 
	target[k] = source[j];
	k = k + d;

/*N7: // stepdown? */

	j--;
	if (source[j+1] <= source[j])
	{
		branch_taken(&global_predictor[4]);
/*		printf("6,6\n"); */
		goto N6;
	}
	else
	{
		branch_not_taken(&global_predictor[4]);
/*		printf("6,12\n"); */
		goto N12;
	}

N8: /* transmit Rj */

	target[k]  = source[j];
	k = k + d; /* increment in the correct direction */

/*N9: // Stepdown? */

	j--;
	if (source[j+1] <= source[j])
	{
		branch_taken(&global_predictor[5]);
/*		printf("8,3\n"); */
		goto N3;
	}
	else branch_not_taken(&global_predictor[5]);

/*	printf("8,10\n"); */
N10: /* transmit Ri */


	target[k] = source[i];
	k = k + d;

/*N11: // stepdown? */

	i++;
	if (source[i-1] <= source[i])
	{
		branch_taken(&global_predictor[6]);
/*		printf("10,10\n"); */
		goto N10;
	}
	else branch_not_taken(&global_predictor[6]);

/*	printf("10,12\n"); */
N12: /* switch sides (of the flow graph on page 162) */

	f = 0;
	d = -d; /* change the direction */
	temp = k;
	k = l;
	l = temp;

/*	printf("12,3\n"); */

	goto N3;
	

N13: /* switch areas */

	if (f == 0)
	{
		branch_taken(&global_predictor[7]);
		s = 1 - s; /* s = !s */
/*		printf("13,2\n"); */
		goto N2;
	}
	else /* sorting is complete */
	{
		branch_not_taken(&global_predictor[7]);
/*		printf("s = %d\n", s);
		exit(0); */ 
		if (s == 0)
		{
			memcpy(a, target, N * sizeof(unsigned int)); 
		}
	}

	free(aux);

	/* clear uninteresting predictors */
	init_predictor(&global_predictor[0]);
	init_predictor(&global_predictor[4]);
	init_predictor(&global_predictor[6]);
	init_predictor(&global_predictor[7]);

}