📄 p2put.c
字号:
putCONG( string , length , required ) char *string; int length; int required; { char name[ BUFSIZ ]; char *label; char *cp; int pad; int others; if ( !CGENNING ) return; putprintf( " .data" , 0 ); aligndot(A_STRUCT); label = getlab(); (void) putlab( label ); cp = string; while ( *cp ) { putprintf( " .byte 0%o" , 1 , *cp ++ ); for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { putprintf( ",0%o" , 1 , *cp++ ); } putprintf( "" , 0 ); } pad = length - strlen( string ); while ( pad-- > 0 ) { putprintf( " .byte 0%o" , 1 , ' ' ); for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { putprintf( ",0%o" , 1 , ' ' ); } putprintf( "" , 0 ); } putprintf( " .byte 0" , 0 ); putprintf( " .text" , 0 ); sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); if ( required == RREQ ) { putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name ); } else { putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name ); } } /* * map a pascal type to a c type * this would be tail recursive, but i unfolded it into a for (;;). * this is sort of like isa and lwidth * a note on the types used by the portable c compiler: * they are divided into a basic type (char, short, int, long, etc.) * and qualifications on those basic types (pointer, function, array). * the basic type is kept in the low 4 bits of the type descriptor, * and the qualifications are arranged in two bit chunks, with the * most significant on the right, * and the least significant on the left * e.g. int *foo(); * (a function returning a pointer to an integer) * is stored as * <ptr><ftn><int> * so, we build types recursively * also, we know that /lib/f1 can only deal with 6 qualifications * so we stop the recursion there. this stops infinite type recursion * through mutually recursive pointer types. */#define MAXQUALS 6intp2type( np ) struct nl *np;{ return typerecur( np , 0 );}typerecur( np , quals ) struct nl *np; int quals; { if ( np == NIL || quals > MAXQUALS ) { return PCCT_UNDEF; } switch ( np -> class ) { case SCAL : case RANGE : case CRANGE : if ( np -> type == ( nl + TDOUBLE ) ) { return PCCT_DOUBLE; } switch ( bytes( np -> range[0] , np -> range[1] ) ) { case 1: return PCCT_CHAR; case 2: return PCCT_SHORT; case 4: return PCCT_INT; default: panic( "p2type int" ); /* NOTREACHED */ } case STR : return ( PCCTM_ARY | PCCT_CHAR ); case RECORD : case SET : return PCCT_STRTY; case FILET : return ( PCCTM_PTR | PCCT_STRTY ); case CONST : case VAR : case FIELD : return p2type( np -> type ); case TYPE : switch ( nloff( np ) ) { case TNIL : return ( PCCTM_PTR | PCCT_UNDEF ); case TSTR : return ( PCCTM_ARY | PCCT_CHAR ); case TSET : return PCCT_STRTY; default : return ( p2type( np -> type ) ); } case REF: case WITHPTR: case PTR : return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR ); case ARRAY : return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY ); case FUNC : /* * functions are really pointers to functions * which return their underlying type. */ return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) , PCCTM_FTN ) , PCCTM_PTR ); case PROC : /* * procedures are pointers to functions * which return integers (whether you look at them or not) */ return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR ); case FFUNC : case FPROC : /* * formal procedures and functions are pointers * to structures which describe their environment. */ return ( PCCTM_PTR | PCCT_STRTY ); default : panic( "p2type" ); /* NOTREACHED */ } } /* * put a typed operator to the pcstream */putop( op , type ) int op; int type; { extern char *p2opname(); if ( !CGENNING ) return; p2word( PCCM_TRIPLE( op , 0 , type ) );# ifdef DEBUG if ( opt( 'k' ) ) { fprintf( stdout , "%s (%d) | 0 | 0x%x\n" , p2opname( op ) , op , type ); }# endif } /* * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) * which looks just like a regular operator, only the size and * alignment go in the next consecutive words */putstrop( op , type , size , alignment ) int op; int type; int size; int alignment; { extern char *p2opname(); if ( !CGENNING ) return; p2word( PCCM_TRIPLE( op , 0 , type ) ); p2word( size ); p2word( alignment );# ifdef DEBUG if ( opt( 'k' ) ) { fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" , p2opname( op ) , op , type , size , alignment ); }# endif } /* * the string names of p2ops */struct p2op { int op; char *name;};static struct p2op p2opnames[] = { PCC_ERROR, "PCC_ERROR", PCC_NAME, "PCC_NAME", PCC_STRING, "PCC_STRING", PCC_ICON, "PCC_ICON", PCC_FCON, "PCC_FCON", PCC_PLUS, "PCC_PLUS", PCC_MINUS, "PCC_MINUS", PCC_UMINUS, "PCC_UMINUS", PCC_MUL, "PCC_MUL", PCC_DEREF, "PCC_DEREF", PCC_AND, "PCC_AND", PCC_ADDROF, "PCC_ADDROF", PCC_OR, "PCC_OR", PCC_ER, "PCC_ER", PCC_QUEST, "PCC_QUEST", PCC_COLON, "PCC_COLON", PCC_ANDAND, "PCC_ANDAND", PCC_OROR, "PCC_OROR", PCC_CM, "PCC_CM", PCC_ASSIGN, "PCC_ASSIGN", PCC_COMOP, "PCC_COMOP", PCC_DIV, "PCC_DIV", PCC_MOD, "PCC_MOD", PCC_LS, "PCC_LS", PCC_RS, "PCC_RS", PCC_DOT, "PCC_DOT", PCC_STREF, "PCC_STREF", PCC_CALL, "PCC_CALL", PCC_UCALL, "PCC_UCALL", PCC_FORTCALL, "PCC_FORTCALL", PCC_UFORTCALL, "PCC_UFORTCALL", PCC_NOT, "PCC_NOT", PCC_COMPL, "PCC_COMPL", PCC_INCR, "PCC_INCR", PCC_DECR, "PCC_DECR", PCC_EQ, "PCC_EQ", PCC_NE, "PCC_NE", PCC_LE, "PCC_LE", PCC_LT, "PCC_LT", PCC_GE, "PCC_GE", PCC_GT, "PCC_GT", PCC_ULE, "PCC_ULE", PCC_ULT, "PCC_ULT", PCC_UGE, "PCC_UGE", PCC_UGT, "PCC_UGT", PCC_REG, "PCC_REG", PCC_OREG, "PCC_OREG", PCC_CCODES, "PCC_CCODES", PCC_FREE, "PCC_FREE", PCC_STASG, "PCC_STASG", PCC_STARG, "PCC_STARG", PCC_STCALL, "PCC_STCALL", PCC_USTCALL, "PCC_USTCALL", PCC_FLD, "PCC_FLD", PCC_SCONV, "PCC_SCONV", PCC_PCONV, "PCC_PCONV", PCC_PMCONV, "PCC_PMCONV", PCC_PVCONV, "PCC_PVCONV", PCC_FORCE, "PCC_FORCE", PCC_CBRANCH, "PCC_CBRANCH", PCC_INIT, "PCC_INIT", PCC_CAST, "PCC_CAST", -1, "" };char *p2opname( op ) register int op; { static char *p2map[PCC_MAXOP+1]; static bool mapready = FALSE; register struct p2op *pp; if ( mapready == FALSE ) { for ( pp = p2opnames; pp->op >= 0; pp++ ) p2map[ pp->op ] = pp->name; mapready = TRUE; } return ( p2map[ op ] ? p2map[ op ] : "unknown" ); } /* * low level routines */ /* * puts a long word on the pcstream */p2word( word ) int word; { putw( word , pcstream ); } /* * put a length 0 mod 4 null padded string onto the pcstream */p2string( string ) char *string; { int slen = strlen( string ); int wlen = ( slen + 3 ) / 4; int plen = ( wlen * 4 ) - slen; char *cp; int p; for ( cp = string ; *cp ; cp++ ) putc( *cp , pcstream ); for ( p = 1 ; p <= plen ; p++ ) putc( '\0' , pcstream );# ifdef DEBUG if ( opt( 'k' ) ) { fprintf( stdout , "\"%s" , string ); for ( p = 1 ; p <= plen ; p++ ) fprintf( stdout , "\\0" ); fprintf( stdout , "\"\n" ); }# endif } /* * puts a name on the pcstream */p2name( name ) char *name; { int pad; fprintf( pcstream , NAMEFORMAT , name ); pad = strlen( name ) % sizeof (long); for ( ; pad < sizeof (long) ; pad++ ) { putc( '\0' , pcstream ); }# ifdef DEBUG if ( opt( 'k' ) ) { fprintf( stdout , NAMEFORMAT , name ); pad = strlen( name ) % sizeof (long); for ( ; pad < sizeof (long) ; pad++ ) { fprintf( stdout , "\\0" ); } fprintf( stdout , "\n" ); }# endif } /* * put out a jump to a label */putjbr( label ) long label; { printjbr( LABELPREFIX , label ); } /* * put out a jump to any kind of label */printjbr( prefix , label ) char *prefix; long label; {# if defined(vax) || defined(tahoe) putprintf( " jbr " , 1 ); putprintf( PREFIXFORMAT , 0 , prefix , label );# endif vax || tahoe# ifdef mc68000 putprintf( " jra " , 1 ); putprintf( PREFIXFORMAT , 0 , prefix , label );# endif mc68000 } /* * another version of put to catch calls to put *//* VARARGS */put() { panic("put()"); }#endif PC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -