Esempio n. 1
0
/*}}}*/
PRIVATE void tselection (treenode * tptr, const int joinlab)
{
	treenode *specsptr = tptr;

	tptr = tspecs (tptr);
	if (TagOf (tptr) != S_SELECTION)
		badtag (genlocn, TagOf (tptr), "tselection");
	tprocess (CondBodyOf (tptr));
	tdespecs (specsptr);
	genbranch (I_J, joinlab);
}
Esempio n. 2
0
File: gen.c Progetto: minux/subc
void genbrtrue(int dest) {
	gentext();
	if (Q_cmp != cnone) {
		genbranch(dest, 1);
		return;
	}
	if (Q_bool != bnone) {
		genlogbr(dest, 0);
		return;
	}
	commit();
	cgbrtrue(dest);
}
Esempio n. 3
0
File: gen-syn.c Progetto: jezze/gaz
void genbrtrue(int dest)
{

    gentext();

    if (Q_cmp != none)
    {

        genbranch(dest, 1);

        return;

    }

    commit();
    cgbrtrue(dest);

}
Esempio n. 4
0
/*****************************************************************************
 *
 *  tjumptable generates the code for selecting cases given a sorted array
 *             of case values and labels.  Our case values are
 *             case[low .. high].
 *
 *****************************************************************************/
PRIVATE void tjumptable (const int low, const int high, const BOOL nomorejumptables)
{
	const int numcases = (high - low) + 1;
	const BOOL singlelength = fitsinword (selectortype);
#ifdef DEBUG
	{
		int i;

		DEBUG_MSG (("tjumptable: low: %d, high: %d, numcases: %d, nomorejumptables: %d\n", low, high, numcases, nomorejumptables));
		for (i = low; i <= high; i++) {
			DEBUG_MSG (("tjumptable: casetable[%2d].lowvalue = %8X\n", i, casetable[i].lowvalue));
		}
	}
#endif
	if ((numcases <= DELTA) || isquadlength (selectortype)) {
		/* bug INSdi02177 */
		/*{{{  too few cases - output jumps */
		int i;
		BOOL optimisedlast = FALSE;
		for (i = low; i < low + numcases; i++) {
			/*{{{  output a jump for casetable[i] */
			caseentry *thiscase = &(casetable[i]);
			const int old = switch_to_temp_workspace ();
			treenode *snode = newdopnode (S_EQ, NOPOSN, selectorexp, thiscase->selectionexp, selectortype);
			switch_to_prev_workspace (old);

			if ((i == high) && (thiscase->lowvalue != 0)
			    && (thiscase->lowvalue != MOSTNEG_INT32)
			    && fitsinword (selectortype)
			    && (!isinconstanttable (thiscase->selectionexp))) {
				/*{{{  optimise the last case */
				tguard (snode, TRUE, defaultlab);
				genbranch (I_J, thiscase->label);
				thiscase->jumpdest = TRUE;
				optimisedlast = TRUE;
				/*}}} */
			} else {
				tguard (snode, FALSE, thiscase->label);
			}
			/*}}} */
		}
		if (!optimisedlast) {
			genbranch (I_J, defaultlab);
			defaultjumpdest = TRUE;
		}
		/*}}} */
	} else {
		/*{{{  look for biggest jump table */
		int bestlow = 0;
		int besthigh = 0;
		int bestsize = 0;
		if (!nomorejumptables && (!singlelength || (numcases >= MIN_JTAB_SIZE)))
		{
			/*{{{  look for best jump table */
			int i, j;
			const int minjumps = singlelength ? MIN_JTAB_SIZE - 1 : DELTA;

			for (i = low; i < (low + numcases - DELTA); i++) {
				/*{{{  set j to minimum value possible for better subrange */
				j = i + ((bestsize > minjumps) ? bestsize : minjumps);
				/*}}} */
				/*{{{  test all possible subranges starting at i, ending at or past j */
				{
					const int maxaccept = ((high - i) + 1) * DENSITY;
					if (singlelength) {
						/*{{{  single length */
						while (j <= high) {
							/* bug TS/1589 - 04/11/92 this is a bug in gcc 1.36;
							   changing diff to be a BIT32 seems to fix the problem;
							   and is OK as a permanent work-around.
							 */
							/* bug TS/1575 05/11/92 - cast to BIT32 for unsigned arith */
							/*const INT32 diff = casetable[j].lowvalue - casetable[i].lowvalue); */
							/*const INT32 diff = (INT32)((BIT32)casetable[j].lowvalue - (BIT32)casetable[i].lowvalue); */
							const BIT32 diff = (BIT32) casetable[j].lowvalue - (BIT32) casetable[i].lowvalue;
							/*DEBUG_MSG(("i: %2d, j: %2d, lowvalue: %8X, diff: %8X\n",
							   i, j, casetable[j].lowvalue, diff)); */
/*if ((diff < 0) || (diff > maxaccept)) *//* TS/1589 04/11/92 */
							if (diff > (BIT32) maxaccept) {
								DEBUG_MSG (("tjumptable: bombing: diff: %8X\n", diff));
								j = high;	/* no chance so exit */
							} else {
								const int size = (j - i) + 1;
								DEBUG_MSG (("tjumptable: ok: diff: %8X\n", diff));
								if (diff <= (int) (DENSITY * size)) {	/* better subrange   */
									bestlow = i;
									besthigh = j;
									bestsize = size;
								}
							}
							j = j + 1;
						}
						/*}}} */
					} else {
						/*{{{  double length */
						while (j <= high) {
							BIT32 hdiff, ldiff;
							Int64Minus (&hdiff, &ldiff,
								    casetable[j].highvalue, casetable[j].lowvalue,
								    casetable[i].highvalue, casetable[i].lowvalue);
							if ((hdiff != 0) || (ldiff > maxaccept)) {
								j = high;	/* no chance so exit */
							} else {
								const int size = (j - i) + 1;
								if (ldiff <= (int) (DENSITY * size)) {	/* better subrange   */
									bestlow = i;
									besthigh = j;
									bestsize = size;
								}
							}
							j = j + 1;
						}
						/*}}} */
					}
				}
				/*}}} */
			}
			/*}}} */
		}
		if (bestsize == 0) {
			tbinchop (low, high);
		} else {
			/*{{{  do jump table */
			int lesslab = 0, greaterlab = 0;
			caseentry *lowestcase = &(casetable[bestlow]);
			caseentry *highestcase = &(casetable[besthigh]);

			DEBUG_MSG (("generating jump table: bestsize = %d\n", bestsize));
			/*{{{  test for below boundary */
			{
				treenode *lselnexp = lowestcase->selectionexp;
				if (!is_typed_mostneg (selectortype, LoValOf (lselnexp), HiValOf (lselnexp))) {
					int l;
					const int old = switch_to_temp_workspace ();
					treenode *snode = newdopnode (S_GE, NOPOSN, selectorexp, lselnexp, selectortype);
					switch_to_prev_workspace (old);

					if (bestlow == low)
						l = defaultlab;
					else {
						lesslab = newlab ();
						l = lesslab;
					}
					tguard (snode, TRUE, l);
				}
			}
			/*}}} */
			/*{{{  test for above boundary */
			{
				treenode *hselnexp = highestcase->selectionexp;
				if (!is_typed_mostpos (selectortype, LoValOf (hselnexp), HiValOf (hselnexp))) {
					int l;
					const int old = switch_to_temp_workspace ();
					treenode *snode = newdopnode (S_LE, NOPOSN, selectorexp, hselnexp, selectortype);
					switch_to_prev_workspace (old);

					if (besthigh == high)
						l = defaultlab;
					else {
						greaterlab = newlab ();
						l = greaterlab;
					}

					tguard (snode, TRUE, l);
				}
			}
			/*}}} */
			/*{{{  output jump table */
			{
#if 0
				const int jlab = newlab ();
				const int l = newlab ();
#endif
				treenode *snode;

				if (lowestcase->lowvalue != 0) {
					/*{{{  selectorexp; ldc lowvalue; diff */
					const int old = switch_to_temp_workspace ();
					snode = newdopnode (S_MINUS, NOPOSN,	/*           selectorexp           */
							    selectorexp,	/*           ldc   selection       */
							    lowestcase->selectionexp,	/*           diff                  */
							    S_INT);
					switch_to_prev_workspace (old);
					/*}}} */
				} else {
					/*{{{  selectorexp */
					snode = selectorexp;	/*           selectorexp           */
					/*}}} */
				}
				texp (snode, MANY_REGS);
#if 0
				/* subsumed into genstartjumptable to allow optimisation */
				genloadcasescale ();	/*           ldc   casescale       */
				/*{{{  T9000_gamma_badmul */
				if (T9000_gamma_badmul (&tx_global)) {
					gensecondary (I_NOP);
					gencomment0 ("Workaround a slow multiplier");
				}
				/*}}} */
				gensecondary (I_PROD);	/*           prod                  */
				genlabeldiff (I_LDC, jlab, l);	/*           ldc   jlab - l        */
				gensecondary (I_LDPI);	/*           ldpi                  */
				setlab (l);	/* l:                              */
				gensecondary (I_BSUB);	/*           bsub                  */
				gensecondary (I_GCALL);	/*           gcall                 */
				setlab (jlab);	/* jlab:                           */
#endif
				genstartjumptable ();	/* includes jump into table */
				genjumptableentry (I_J, lowestcase->label);
				lowestcase->jumpdest = TRUE;
				/*           j     lowestcase      */
				/*{{{  other cases                                     j     othercases .. */
				{
					int i;
					for (i = bestlow + 1; i <= besthigh; i++) {
						int j;
						/* bug TS/1575 05/11/92 - cast to BIT32 for unsigned arith */
						const int blanks = (int) ((BIT32) casetable[i].lowvalue - (BIT32) casetable[i - 1].lowvalue) - 1;

						for (j = 0; j < blanks; j++) {
							genjumptableentry (I_J, defaultlab);
							defaultjumpdest = TRUE;
						}
						genjumptableentry (I_J, casetable[i].label);
						casetable[i].jumpdest = TRUE;
					}
				}
				/*}}} */
				genendjumptable ();
				/*}}} */
			}
			if (bestlow > low) {
				/*{{{  case on lower values */
				setlab (lesslab);
				tjumptable (low, bestlow - 1, FALSE);
				/*}}} */
			}
			if (besthigh < high) {
				/*{{{  case on higher values */
				setlab (greaterlab);
				tjumptable (besthigh + 1, high, FALSE);
				/*}}} */
			}
			/*}}} */
		}
		/*}}} */
	}
}