📄 local2.c
字号:
# ifndef lintstatic char *sccsid = "@(#)local2.c 4.2 (ULTRIX) 8/13/90";# endif# include "mfile2"# include "ctype.h"/************************************************************************ * * * Copyright (c) 1983 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * Modification History * * Jon Reeves, 90-Feb-01 * 007 Add BSD4.3 code to zzzcode() to do SCONV's, including proper * handling of unsigned to float and ZG; also replaces old conversion * code. Add support routine collapsible(), also from BSD4.3. * * David L Ballenger, 16-Mar-1986 * 006 Fix problem in zzzcode() where two cvt instructions were written * on the same line with no intervening spaces or line feeds. * * David L Ballenger, 16-Mar-1986 * 005 Add bug fixes from SUN for NFS. * * Lu Anne Van de Pas, 1-Mar-86: * 004- added support for f floating constants (FCON) and f floating * arithmetic to be done in f when -f is specified on the command * line (fflag). * * Rich Phillips, 30-July-84: * 003- Change fix 002 so it is not so retrictive. Allow pointer increments * in structure assignments of structures that are 1,2,4, or 8 bytes * long to return STAREG. Continue to disallow cases when the object * referenced is not the same size as the increment of the register. * * Stephen Reilly, 16-Feb-84: * 002- postfix of ++ or -- is incorrectly handled when the a pointer to a * structure is 4 byte in size and is the expr of a if style * statement. * * Stephen Reilly, 21-Oct-83: * 001- New -M flag is added that indicates that the compiler is to * emit gfloat instructions, rather than dfloat instructions. * ***********************************************************************//* * If Mflag when set it indicates that gfloat instructions are * required by the user */extern Mflag; /* slr001 -M flag */extern fflag; /* vdp004 -f flag */ # ifdef FORTint ftlab1, ftlab2;# endif/* a lot of the machine dependent parts of the second pass */# define putstr(s) fputs((s), stdout)# define BITMASK(n) ((1L<<n)-1)where(c){ fprintf( stderr, "%s, line %d: ", filename, lineno ); }lineid( l, fn ) char *fn; { /* identify line l and file fn */ printf( "# line %d, file %s\n", l, fn ); }eobl2(){ OFFSZ spoff; /* offset from stack pointer */#ifdef FORT spoff = maxoff; if( spoff >= AUTOINIT ) spoff -= AUTOINIT; spoff /= SZCHAR; SETOFF(spoff,4);#ifndef FLEXNAMES printf( " .set .F%d,%ld\n", ftnno, spoff );#else /* SHOULD BE L%d ... ftnno but must change pc/f77 */ printf( " .set LF%d,%ld\n", ftnno, spoff );#endif#else extern int ftlab1, ftlab2; spoff = maxoff; if( spoff >= AUTOINIT ) spoff -= AUTOINIT; spoff /= SZCHAR; SETOFF(spoff,4); printf( "L%d:\n", ftlab1); if( spoff!=0 ) if( spoff < 64 ) printf( " subl2 $%ld,sp\n", spoff); else printf( " movab -%ld(sp),sp\n", spoff); printf( " jbr L%d\n", ftlab2);#endif maxargs = -1; }struct hoptab { int opmask; char * opstring; } ioptab[] = { ASG PLUS, "add", ASG MINUS, "sub", ASG MUL, "mul", ASG DIV, "div", ASG OR, "bis", ASG ER, "xor", ASG AND, "bic", PLUS, "add", MINUS, "sub", MUL, "mul", DIV, "div", OR, "bis", ER, "xor", AND, "bic", -1, "" };hopcode( f, o ){ /* output the appropriate string from the above table */ register struct hoptab *q; for( q = ioptab; q->opmask>=0; ++q ){ if( q->opmask == o ){ putstr( q->opstring );/* tbl if( f == 'F' ) putchar( 'e' ); else if( f == 'D' ) putchar( 'd' ); tbl *//* tbl */ /* * Put the appropriate data type * suffix on instruction */ switch( f ) { case 'L': case 'W': case 'B': putchar(tolower(f)); break; /* slr001 */ case 'F': /* If -f flag set then put the f * suffix out for f floating * operations. Actually we * should never have 'F' if * fflag is not set (see FLOATFLG) * in table. I'm just making * sure. vdp004 */ if (fflag) { putchar('f'); break; } case 'D': /* * If -M flag set then put the * g suffix which indicates gfloat */ if ( Mflag ) /* slr001 */ putchar('g'); /* slr001 */ else /* slr001 */ putchar(tolower(f)); /* slr001 */ break; }/* tbl */ return; } } cerror( "no hoptab for %s", opst[o] ); }char *rnames[] = { /* keyed to register number tokens */ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", };int rstatus[] = { SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, };tlen(p) NODE *p;{ switch(p->in.type) { case CHAR: case UCHAR: return(1); case SHORT: case USHORT: return(2); case DOUBLE: return(8); default: return(4); }}mixtypes(p, q) NODE *p, *q;{ register TWORD tp, tq; tp = p->in.type; tq = q->in.type; return( (tp==FLOAT || tp==DOUBLE) != (tq==FLOAT || tq==DOUBLE) );}prtype(n) NODE *n;{ switch (n->in.type) { case DOUBLE: /* * If -M flag set put gfloat suffix * on instruction */ if ( Mflag ) /* slr001 */ putchar('g'); /* slr001 */ else /* slr001 */ putchar('d'); /* slr001 */ return; case FLOAT: putchar('f'); return; case LONG: case ULONG: case INT: case UNSIGNED: putchar('l'); return; case SHORT: case USHORT: putchar('w'); return; case CHAR: case UCHAR: putchar('b'); return; default: if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type"); else { putchar('l'); return; } }}zzzcode( p, c ) register NODE *p; { register m; CONSZ val; switch( c ){ case 'N': /* logical ops, turned into 0-1 */ /* use register given by register 1 */ cbgen( 0, m=getlab(), 'I' ); deflab( p->bn.label ); printf( " clrl %s\n", rnames[getlr( p, '1' )->tn.rval] ); deflab( m ); return; case 'I': case 'P': cbgen( p->in.op, p->bn.label, c ); return; case 'A': { register NODE *l, *r; if (xdebug) eprint(p, 0, &val, &val); r = getlr(p, 'R'); if (optype(p->in.op) == LTYPE || p->in.op == UNARY MUL) { l = resc; if (fflag) /*vdp004- check for floating arith */ { l->in.type = (r->in.type==FLOAT) ? FLOAT : (r->in.type==DOUBLE) ? DOUBLE : INT; } else l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT); } else if (p->in.op == SCONV) { l = resc; if (fflag) l->in.type = r->in.type; else l->in.type = r->in.type==FLOAT ? DOUBLE : r->in.type; r = getlr(p, 'L'); } else l = getlr(p, 'L'); if (r->in.op == ICON) if (r->in.name[0] == '\0') { if (r->tn.lval == 0) { putstr("clr"); prtype(l); putchar('\t'); adrput(l); return; } if (r->tn.lval < 0 && r->tn.lval >= -63) { putstr("mneg"); prtype(l); r->tn.lval = -r->tn.lval; goto ops; } if (r->tn.lval < 0) r->in.type = r->tn.lval >= -128 ? CHAR : (r->tn.lval >= -32768 ? SHORT : INT); else r->in.type = r->tn.lval <= 63 ? INT : (r->tn.lval <= 127 ? CHAR : (r->tn.lval <= 255 ? UCHAR : (r->tn.lval <= 32767 ? SHORT : (r->tn.lval <= 65535 ? USHORT : INT)))); } else { putstr("moval"); putchar('\t'); acon(r); putchar(','); adrput(l); return; } if (p->in.op == SCONV && !(l->in.type == FLOAT || l->in.type == DOUBLE) && !mixtypes(l, r)) { /* * Because registers must always contain objects * of the same width as INTs, we may have to * perform two conversions to get an INT. Can * the conversions be collapsed into one? */ if (m = collapsible(l, r)) r->in.type = m; else { /* * Two steps are required. */ NODE *x = &resc[1]; *x = *l; if (tlen(x) > tlen(r) && ISUNSIGNED(r->in.type)) putstr("movz"); else putstr("cvt"); prtype(r); prtype(x); putchar('\t'); adrput(r); putchar(','); adrput(x); putchar('\n'); putchar('\t'); r = x; } l->in.type = (ISUNSIGNED(l->in.type) ? UNSIGNED : INT); } if ((r->in.type == UNSIGNED || r->in.type == ULONG) && mixtypes(l, r)) { int label1, label2; label1 = getlab(); label2 = getlab(); putstr("movl\t"); adrput(r); putchar(','); adrput(l); putstr("\n\tjbsc\t$31,"); adrput(l); printf(",L%d\n\tcvtl", label1); prtype(l); putchar('\t'); adrput(l); putchar(','); adrput(l); printf("\n\tjbr\tL%d\nL%d:\n\tcvtl", label2, label1); prtype(l); putchar('\t'); adrput(l); putchar(','); adrput(l); putstr("\n\tadd"); prtype(l); putstr("2\t$0"); prtype(l); putstr("2.147483648e9,"); adrput(l); printf("\nL%d:", label2); return; } if (!mixtypes(l,r)) { if (tlen(l) == tlen(r)) { putstr("mov");#ifdef FORT if (Oflag) prtype(l); else { if (l->in.type == DOUBLE) putchar('q'); else if(l->in.type == FLOAT) putchar('l'); else prtype(l); }#else prtype(l);#endif FORT goto ops; } else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type)) putstr("movz"); else putstr("cvt"); } else putstr("cvt"); prtype(r); prtype(l); ops: putchar('\t'); adrput(r); putchar(','); adrput(l); return; } case 'G': /* i *= f; asgops with int lhs and float rhs */ { register NODE *l, *r, *s; int rt; l = p->in.left; r = p->in.right;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -