/* * Emit code to compare two longlong numbers. */ static void twollcomp(NODE *p) { int o = p->n_op; int s = getlab2(); int e = p->n_label; int cb1, cb2; if (o >= ULE) o -= (ULE-LE); switch (o) { case NE: cb1 = 0; cb2 = NE; break; case EQ: cb1 = NE; cb2 = 0; break; case LE: case LT: cb1 = GT; cb2 = LT; break; case GE: case GT: cb1 = LT; cb2 = GT; break; default: cb1 = cb2 = 0; /* XXX gcc */ } if (p->n_op >= ULE) cb1 += 4, cb2 += 4; expand(p, 0, "\tsub A1,UL,UR\t# compare 64-bit values (upper)\n"); if (cb1) { printf("\t"); hopcode(' ', cb1); expand(p, 0, "A1"); printf("," LABFMT "\n", s); printf("\tnop\n"); } if (cb2) { printf("\t"); hopcode(' ', cb2); expand(p, 0, "A1"); printf("," LABFMT "\n", e); printf("\tnop\n"); } expand(p, 0, "\tsub A1,AL,AR\t# (and lower)\n"); printf("\t"); hopcode(' ', o); expand(p, 0, "A1"); printf("," LABFMT "\n", e); printf("\tnop\n"); deflab(s); }
/* * generate code by interpreting table entry */ void expand(NODE *p, int cookie, char *cp) { CONSZ val; #if 0 printf("expand\n"); fwalk(p, e2print, 0); #endif for( ; *cp; ++cp ){ switch( *cp ){ default: putchar(*cp); continue; /* this is the usual case... */ case 'Z': /* special machine dependent operations */ zzzcode( p, *++cp ); continue; case 'F': /* this line deleted if FOREFF is active */ if (cookie & FOREFF) { while (*cp && *cp != '\n') cp++; if (*cp == 0) return; } continue; case 'S': /* field size */ if (fldexpand(p, cookie, &cp)) continue; printf("%d", FLDSZ(p->n_rval)); continue; case 'H': /* field shift */ if (fldexpand(p, cookie, &cp)) continue; printf("%d", FLDSHF(p->n_rval)); continue; case 'M': /* field mask */ case 'N': /* complement of field mask */ if (fldexpand(p, cookie, &cp)) continue; val = 1; val <<= FLDSZ(p->n_rval); --val; val <<= FLDSHF(p->n_rval); adrcon( *cp=='M' ? val : ~val ); continue; case 'L': /* output special label field */ if (*++cp == 'C') printf(LABFMT, p->n_label); else printf(LABFMT, (int)getlval(getlr(p,*cp))); continue; case 'O': /* opcode string */ #ifdef FINDMOPS if (p->n_op == ASSIGN) hopcode(*++cp, p->n_right->n_op); else #endif hopcode( *++cp, p->n_op ); continue; case 'B': /* byte offset in word */ val = getlval(getlr(p,*++cp)); val = BYTEOFF(val); printf( CONFMT, val ); continue; case 'C': /* for constant value only */ conput(stdout, getlr( p, *++cp ) ); continue; case 'I': /* in instruction */ insput( getlr( p, *++cp ) ); continue; case 'A': /* address of */ adrput(stdout, getlr( p, *++cp ) ); continue; case 'U': /* for upper half of address, only */ upput(getlr(p, *++cp), SZLONG); continue; } } }