1762Speter /* Copyright (c) 1979 Regents of the University of California */ 2762Speter 315953Smckusick #ifndef lint 4*18462Sralph static char sccsid[] = "@(#)p2put.c 2.2 03/20/85"; 515953Smckusick #endif 6762Speter 7762Speter /* 8762Speter * functions to help pi put out 9762Speter * polish postfix binary portable c compiler intermediate code 10762Speter * thereby becoming the portable pascal compiler 11762Speter */ 12762Speter 13762Speter #include "whoami.h" 14762Speter #ifdef PC 15762Speter #include "0.h" 1610653Speter #include "objfmt.h" 17*18462Sralph #include <pcc.h> 18762Speter #include "pc.h" 1910653Speter #include "align.h" 2011329Speter #include "tmps.h" 21762Speter 22762Speter /* 23762Speter * emits an ftext operator and a string to the pcstream 24762Speter */ 25762Speter puttext( string ) 26762Speter char *string; 27762Speter { 28762Speter int length = str4len( string ); 29762Speter 303316Speter if ( !CGENNING ) 31762Speter return; 32*18462Sralph p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) ); 33762Speter # ifdef DEBUG 34762Speter if ( opt( 'k' ) ) { 35*18462Sralph fprintf( stdout , "PCCF_FTEXT | %3d | 0 " , length ); 36762Speter } 37762Speter # endif 38762Speter p2string( string ); 39762Speter } 40762Speter 41762Speter int 42762Speter str4len( string ) 43762Speter char *string; 44762Speter { 45762Speter 46762Speter return ( ( strlen( string ) + 3 ) / 4 ); 47762Speter } 48762Speter 49762Speter /* 50762Speter * put formatted text into a buffer for printing to the pcstream. 51762Speter * a call to putpflush actually puts out the text. 52762Speter * none of arg1 .. arg5 need be present. 53762Speter * and you can add more if you need them. 54762Speter */ 5515953Smckusick /* VARARGS */ 56762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 ) 57762Speter char *format; 58762Speter int incomplete; 59762Speter { 60762Speter static char ppbuffer[ BUFSIZ ]; 61762Speter static char *ppbufp = ppbuffer; 62762Speter 633316Speter if ( !CGENNING ) 64762Speter return; 65762Speter sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 ); 66762Speter ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] ); 67762Speter if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) ) 68762Speter panic( "putprintf" ); 69762Speter if ( ! incomplete ) { 70762Speter puttext( ppbuffer ); 71762Speter ppbufp = ppbuffer; 72762Speter } 73762Speter } 74762Speter 75762Speter /* 76762Speter * emit a left bracket operator to pcstream 77762Speter * with function number, the maximum temp register, and total local bytes 78762Speter */ 7911329Speter putlbracket(ftnno, sizesp) 8011329Speter int ftnno; 8111329Speter struct om *sizesp; 8211329Speter { 8311329Speter int maxtempreg; 8411329Speter int alignedframesize; 85762Speter 8611329Speter # ifdef vax 8711329Speter maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL]; 8811329Speter # endif vax 8911329Speter # ifdef mc68000 9011329Speter /* 9114906Speter * this is how /lib/f1 wants it. 9211329Speter */ 9314906Speter maxtempreg = (sizesp->curtmps.next_avail[REG_ADDR] << 4) 9414906Speter | (sizesp->curtmps.next_avail[REG_DATA]); 9511329Speter # endif mc68000 9615953Smckusick alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off), 9715953Smckusick (long)(BITSPERBYTE * A_STACK)); 98*18462Sralph p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) ); 9911329Speter p2word(alignedframesize); 10011329Speter # ifdef DEBUG 10111329Speter if ( opt( 'k' ) ) { 102*18462Sralph fprintf(stdout, "PCCF_FLBRAC | %3d | %d %d\n", 10311329Speter maxtempreg, ftnno, alignedframesize); 10411329Speter } 10511329Speter # endif 10611329Speter } 107762Speter 108762Speter /* 109762Speter * emit a right bracket operator 11014906Speter * which for the binary interface 111762Speter * forces the stack allocate and register mask 112762Speter */ 113762Speter putrbracket( ftnno ) 114762Speter int ftnno; 115762Speter { 116762Speter 117*18462Sralph p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) ); 118762Speter # ifdef DEBUG 119762Speter if ( opt( 'k' ) ) { 120*18462Sralph fprintf( stdout , "PCCF_FRBRAC | 0 | %d\n" , ftnno ); 121762Speter } 122762Speter # endif 123762Speter } 124762Speter 125762Speter /* 126762Speter * emit an eof operator 127762Speter */ 128762Speter puteof() 129762Speter { 130762Speter 131*18462Sralph p2word( PCCF_FEOF ); 132762Speter # ifdef DEBUG 133762Speter if ( opt( 'k' ) ) { 134*18462Sralph fprintf( stdout , "PCCF_FEOF\n" ); 135762Speter } 136762Speter # endif 137762Speter } 138762Speter 139762Speter /* 140762Speter * emit a dot operator, 141762Speter * with a source file line number and name 142762Speter * if line is negative, there was an error on that line, but who cares? 143762Speter */ 144762Speter putdot( filename , line ) 145762Speter char *filename; 146762Speter int line; 147762Speter { 148762Speter int length = str4len( filename ); 149762Speter 150762Speter if ( line < 0 ) { 151762Speter line = -line; 152762Speter } 153*18462Sralph p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) ); 154762Speter # ifdef DEBUG 155762Speter if ( opt( 'k' ) ) { 156*18462Sralph fprintf( stdout , "PCCF_FEXPR | %3d | %d " , length , line ); 157762Speter } 158762Speter # endif 159762Speter p2string( filename ); 160762Speter } 161762Speter 162762Speter /* 163762Speter * put out a leaf node 164762Speter */ 165762Speter putleaf( op , lval , rval , type , name ) 166762Speter int op; 167762Speter int lval; 168762Speter int rval; 169762Speter int type; 170762Speter char *name; 171762Speter { 1723316Speter if ( !CGENNING ) 173762Speter return; 174762Speter switch ( op ) { 175762Speter default: 176762Speter panic( "[putleaf]" ); 177*18462Sralph case PCC_ICON: 178*18462Sralph p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) ); 179762Speter p2word( lval ); 180762Speter # ifdef DEBUG 181762Speter if ( opt( 'k' ) ) { 182*18462Sralph fprintf( stdout , "PCC_ICON | %3d | 0x%x " 183762Speter , name != NIL , type ); 184762Speter fprintf( stdout , "%d\n" , lval ); 185762Speter } 186762Speter # endif 187762Speter if ( name ) 188762Speter p2name( name ); 189762Speter break; 190*18462Sralph case PCC_NAME: 191*18462Sralph p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) ); 192762Speter if ( lval ) 193762Speter p2word( lval ); 194762Speter # ifdef DEBUG 195762Speter if ( opt( 'k' ) ) { 196*18462Sralph fprintf( stdout , "PCC_NAME | %3d | 0x%x " 197762Speter , lval != 0 , type ); 198762Speter if ( lval ) 199762Speter fprintf( stdout , "%d " , lval ); 200762Speter } 201762Speter # endif 202762Speter p2name( name ); 203762Speter break; 204*18462Sralph case PCC_REG: 205*18462Sralph p2word( PCCM_TRIPLE( PCC_REG , rval , type ) ); 206762Speter # ifdef DEBUG 207762Speter if ( opt( 'k' ) ) { 208*18462Sralph fprintf( stdout , "PCC_REG | %3d | 0x%x\n" , 2092474Speter rval , type ); 210762Speter } 211762Speter # endif 212762Speter break; 213762Speter } 214762Speter } 215762Speter 216762Speter /* 217762Speter * rvalues are just lvalues with indirection, except 2183829Speter * special cases for registers and for named globals, 2193829Speter * whose names are their rvalues. 220762Speter */ 2217924Smckusick putRV( name , level , offset , other_flags , type ) 222762Speter char *name; 223762Speter int level; 224762Speter int offset; 2257924Smckusick char other_flags; 226762Speter int type; 227762Speter { 228762Speter char extname[ BUFSIZ ]; 229762Speter char *printname; 230762Speter 2313316Speter if ( !CGENNING ) 232762Speter return; 2337924Smckusick if ( other_flags & NREGVAR ) { 2343829Speter if ( ( offset < 0 ) || ( offset > P2FP ) ) { 2353829Speter panic( "putRV regvar" ); 2363582Speter } 237*18462Sralph putleaf( PCC_REG , 0 , offset , type , (char *) 0 ); 2383277Smckusic return; 2393277Smckusic } 24015953Smckusick if ( whereis( offset , other_flags ) == GLOBALVAR ) { 2413829Speter if ( name != 0 ) { 2423829Speter if ( name[0] != '_' ) { 2433829Speter sprintf( extname , EXTFORMAT , name ); 2443829Speter printname = extname; 2453829Speter } else { 2463829Speter printname = name; 2473829Speter } 248*18462Sralph putleaf( PCC_NAME , offset , 0 , type , printname ); 2493829Speter return; 250762Speter } else { 2513829Speter panic( "putRV no name" ); 252762Speter } 253762Speter } 2547924Smckusick putLV( name , level , offset , other_flags , type ); 255*18462Sralph putop( PCCOM_UNARY PCC_MUL , type ); 256762Speter } 257762Speter 258762Speter /* 259762Speter * put out an lvalue 260762Speter * given a level and offset 261762Speter * special case for 262762Speter * named globals, whose lvalues are just their names as constants. 263762Speter */ 2647924Smckusick putLV( name , level , offset , other_flags , type ) 265762Speter char *name; 266762Speter int level; 267762Speter int offset; 2687924Smckusick char other_flags; 269762Speter int type; 2703277Smckusic { 2713277Smckusic char extname[ BUFSIZ ]; 2723277Smckusic char *printname; 273762Speter 2743316Speter if ( !CGENNING ) 2753277Smckusic return; 2767924Smckusick if ( other_flags & NREGVAR ) { 2773829Speter panic( "putLV regvar" ); 278762Speter } 27915953Smckusick switch ( whereis( offset , other_flags ) ) { 2803829Speter case GLOBALVAR: 2813829Speter if ( ( name != 0 ) ) { 2823829Speter if ( name[0] != '_' ) { 2833829Speter sprintf( extname , EXTFORMAT , name ); 2843829Speter printname = extname; 2853829Speter } else { 2863829Speter printname = name; 2873829Speter } 288*18462Sralph putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR ) 2893829Speter , printname ); 2903829Speter return; 2913829Speter } else { 2923829Speter panic( "putLV no name" ); 2933829Speter } 2943277Smckusic case PARAMVAR: 2953277Smckusic if ( level == cbn ) { 296*18462Sralph putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 2973277Smckusic } else { 298*18462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_OFFSET 299*18462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3009128Smckusick parts[ level ] |= NONLOCALVAR; 3013277Smckusic } 302*18462Sralph putleaf( PCC_ICON , offset , 0 , PCCT_INT , (char *) 0 ); 303*18462Sralph putop( PCC_PLUS , PCCTM_PTR | PCCT_CHAR ); 3043277Smckusic break; 3053277Smckusic case LOCALVAR: 3063277Smckusic if ( level == cbn ) { 307*18462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3083277Smckusic } else { 309*18462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 310*18462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3119128Smckusick parts[ level ] |= NONLOCALVAR; 3123277Smckusic } 313*18462Sralph putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 ); 314*18462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3153277Smckusic break; 3169128Smckusick case NAMEDLOCALVAR: 3179128Smckusick if ( level == cbn ) { 318*18462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3199128Smckusick } else { 320*18462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 321*18462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3229128Smckusick parts[ level ] |= NONLOCALVAR; 3239128Smckusick } 324*18462Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name ); 325*18462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3269128Smckusick break; 3273277Smckusic } 3283277Smckusic return; 3293277Smckusic } 330762Speter 331762Speter /* 332762Speter * put out a floating point constant leaf node 333762Speter * the constant is declared in aligned data space 334*18462Sralph * and a PCC_NAME leaf put out for it 335762Speter */ 3367924Smckusick putCON8( val ) 3377924Smckusick double val; 338762Speter { 33915953Smckusick char *label; 340762Speter char name[ BUFSIZ ]; 341762Speter 3423316Speter if ( !CGENNING ) 343762Speter return; 34410653Speter label = getlab(); 345762Speter putprintf( " .data" , 0 ); 34610653Speter aligndot(A_DOUBLE); 34715953Smckusick (void) putlab( label ); 34810653Speter # ifdef vax 34910653Speter putprintf( " .double 0d%.20e" , 0 , val ); 35010653Speter # endif vax 35110653Speter # ifdef mc68000 35210653Speter putprintf( " .long 0x%x,0x%x", 0, val); 35310653Speter # endif mc68000 354762Speter putprintf( " .text" , 0 ); 355762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 356*18462Sralph putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name ); 357762Speter } 358762Speter 359762Speter /* 360762Speter * put out either an lvalue or an rvalue for a constant string. 361762Speter * an lvalue (for assignment rhs's) is the name as a constant, 362762Speter * an rvalue (for parameters) is just the name. 363762Speter */ 364762Speter putCONG( string , length , required ) 365762Speter char *string; 366762Speter int length; 367762Speter int required; 368762Speter { 369762Speter char name[ BUFSIZ ]; 37015953Smckusick char *label; 371762Speter char *cp; 372762Speter int pad; 373762Speter int others; 374762Speter 3753316Speter if ( !CGENNING ) 376762Speter return; 377762Speter putprintf( " .data" , 0 ); 37810653Speter aligndot(A_STRUCT); 379762Speter label = getlab(); 38015953Smckusick (void) putlab( label ); 381762Speter cp = string; 382762Speter while ( *cp ) { 383762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 384762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 385762Speter putprintf( ",0%o" , 1 , *cp++ ); 386762Speter } 387762Speter putprintf( "" , 0 ); 388762Speter } 389762Speter pad = length - strlen( string ); 390762Speter while ( pad-- > 0 ) { 391762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 392762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 393762Speter putprintf( ",0%o" , 1 , ' ' ); 394762Speter } 395762Speter putprintf( "" , 0 ); 396762Speter } 397762Speter putprintf( " .byte 0" , 0 ); 398762Speter putprintf( " .text" , 0 ); 399762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 400762Speter if ( required == RREQ ) { 401*18462Sralph putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name ); 402762Speter } else { 403*18462Sralph putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name ); 404762Speter } 405762Speter } 406762Speter 407762Speter /* 408762Speter * map a pascal type to a c type 409762Speter * this would be tail recursive, but i unfolded it into a for (;;). 410762Speter * this is sort of like isa and lwidth 411762Speter * a note on the types used by the portable c compiler: 412762Speter * they are divided into a basic type (char, short, int, long, etc.) 413762Speter * and qualifications on those basic types (pointer, function, array). 414762Speter * the basic type is kept in the low 4 bits of the type descriptor, 415762Speter * and the qualifications are arranged in two bit chunks, with the 416762Speter * most significant on the right, 417762Speter * and the least significant on the left 418762Speter * e.g. int *foo(); 419762Speter * (a function returning a pointer to an integer) 420762Speter * is stored as 421762Speter * <ptr><ftn><int> 422762Speter * so, we build types recursively 4231478Speter * also, we know that /lib/f1 can only deal with 6 qualifications 4241478Speter * so we stop the recursion there. this stops infinite type recursion 4251478Speter * through mutually recursive pointer types. 426762Speter */ 4271478Speter #define MAXQUALS 6 428762Speter int 429762Speter p2type( np ) 43015953Smckusick struct nl *np; 4311478Speter { 4321478Speter 4331478Speter return typerecur( np , 0 ); 4341478Speter } 4351478Speter typerecur( np , quals ) 4361478Speter struct nl *np; 4371478Speter int quals; 438762Speter { 439762Speter 4401478Speter if ( np == NIL || quals > MAXQUALS ) { 441*18462Sralph return PCCT_UNDEF; 4421478Speter } 443762Speter switch ( np -> class ) { 444762Speter case SCAL : 445762Speter case RANGE : 44615974Smckusick case CRANGE : 447762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 448*18462Sralph return PCCT_DOUBLE; 449762Speter } 450762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 451762Speter case 1: 452*18462Sralph return PCCT_CHAR; 453762Speter case 2: 454*18462Sralph return PCCT_SHORT; 455762Speter case 4: 456*18462Sralph return PCCT_INT; 457762Speter default: 458762Speter panic( "p2type int" ); 45915953Smckusick /* NOTREACHED */ 460762Speter } 461762Speter case STR : 462*18462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 463762Speter case RECORD : 464762Speter case SET : 465*18462Sralph return PCCT_STRTY; 466762Speter case FILET : 467*18462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 468762Speter case CONST : 469762Speter case VAR : 470762Speter case FIELD : 471762Speter return p2type( np -> type ); 472762Speter case TYPE : 473762Speter switch ( nloff( np ) ) { 474762Speter case TNIL : 475*18462Sralph return ( PCCTM_PTR | PCCT_UNDEF ); 476762Speter case TSTR : 477*18462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 478762Speter case TSET : 479*18462Sralph return PCCT_STRTY; 480762Speter default : 481762Speter return ( p2type( np -> type ) ); 482762Speter } 483762Speter case REF: 484762Speter case WITHPTR: 485762Speter case PTR : 486*18462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR ); 487762Speter case ARRAY : 488*18462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY ); 489762Speter case FUNC : 490762Speter /* 491762Speter * functions are really pointers to functions 492762Speter * which return their underlying type. 493762Speter */ 494*18462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) , 495*18462Sralph PCCTM_FTN ) , PCCTM_PTR ); 496762Speter case PROC : 497762Speter /* 498762Speter * procedures are pointers to functions 499762Speter * which return integers (whether you look at them or not) 500762Speter */ 501*18462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR ); 5021197Speter case FFUNC : 5031197Speter case FPROC : 5041197Speter /* 5051197Speter * formal procedures and functions are pointers 5061197Speter * to structures which describe their environment. 5071197Speter */ 508*18462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 509762Speter default : 510762Speter panic( "p2type" ); 51115953Smckusick /* NOTREACHED */ 512762Speter } 513762Speter } 514762Speter 515762Speter /* 516762Speter * put a typed operator to the pcstream 517762Speter */ 518762Speter putop( op , type ) 519762Speter int op; 520762Speter int type; 521762Speter { 522*18462Sralph extern char *p2opname(); 523762Speter 5243316Speter if ( !CGENNING ) 525762Speter return; 526*18462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 527762Speter # ifdef DEBUG 528762Speter if ( opt( 'k' ) ) { 5292474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x\n" 530*18462Sralph , p2opname( op ) , op , type ); 531762Speter } 532762Speter # endif 533762Speter } 534762Speter 535762Speter /* 536762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 537762Speter * which looks just like a regular operator, only the size and 538762Speter * alignment go in the next consecutive words 539762Speter */ 540762Speter putstrop( op , type , size , alignment ) 541762Speter int op; 542762Speter int type; 543762Speter int size; 544762Speter int alignment; 545762Speter { 546*18462Sralph extern char *p2opname(); 547762Speter 5483316Speter if ( !CGENNING ) 549762Speter return; 550*18462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 551762Speter p2word( size ); 552762Speter p2word( alignment ); 553762Speter # ifdef DEBUG 554762Speter if ( opt( 'k' ) ) { 5552474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" 556*18462Sralph , p2opname( op ) , op , type , size , alignment ); 557762Speter } 558762Speter # endif 559762Speter } 560762Speter 561762Speter /* 562762Speter * the string names of p2ops 563762Speter */ 564*18462Sralph 565*18462Sralph struct p2op { 566*18462Sralph int op; 567*18462Sralph char *name; 568*18462Sralph }; 569*18462Sralph 570*18462Sralph static struct p2op p2opnames[] = { 571*18462Sralph PCC_ERROR, "PCC_ERROR", 572*18462Sralph PCC_NAME, "PCC_NAME", 573*18462Sralph PCC_STRING, "PCC_STRING", 574*18462Sralph PCC_ICON, "PCC_ICON", 575*18462Sralph PCC_FCON, "PCC_FCON", 576*18462Sralph PCC_PLUS, "PCC_PLUS", 577*18462Sralph PCC_MINUS, "PCC_MINUS", 578*18462Sralph PCC_UMINUS, "PCC_UMINUS", 579*18462Sralph PCC_MUL, "PCC_MUL", 580*18462Sralph PCC_DEREF, "PCC_DEREF", 581*18462Sralph PCC_AND, "PCC_AND", 582*18462Sralph PCC_ADDROF, "PCC_ADDROF", 583*18462Sralph PCC_OR, "PCC_OR", 584*18462Sralph PCC_ER, "PCC_ER", 585*18462Sralph PCC_QUEST, "PCC_QUEST", 586*18462Sralph PCC_COLON, "PCC_COLON", 587*18462Sralph PCC_ANDAND, "PCC_ANDAND", 588*18462Sralph PCC_OROR, "PCC_OROR", 589*18462Sralph PCC_CM, "PCC_CM", 590*18462Sralph PCC_ASSIGN, "PCC_ASSIGN", 591*18462Sralph PCC_COMOP, "PCC_COMOP", 592*18462Sralph PCC_DIV, "PCC_DIV", 593*18462Sralph PCC_MOD, "PCC_MOD", 594*18462Sralph PCC_LS, "PCC_LS", 595*18462Sralph PCC_RS, "PCC_RS", 596*18462Sralph PCC_DOT, "PCC_DOT", 597*18462Sralph PCC_STREF, "PCC_STREF", 598*18462Sralph PCC_CALL, "PCC_CALL", 599*18462Sralph PCC_UCALL, "PCC_UCALL", 600*18462Sralph PCC_FORTCALL, "PCC_FORTCALL", 601*18462Sralph PCC_UFORTCALL, "PCC_UFORTCALL", 602*18462Sralph PCC_NOT, "PCC_NOT", 603*18462Sralph PCC_COMPL, "PCC_COMPL", 604*18462Sralph PCC_INCR, "PCC_INCR", 605*18462Sralph PCC_DECR, "PCC_DECR", 606*18462Sralph PCC_EQ, "PCC_EQ", 607*18462Sralph PCC_NE, "PCC_NE", 608*18462Sralph PCC_LE, "PCC_LE", 609*18462Sralph PCC_LT, "PCC_LT", 610*18462Sralph PCC_GE, "PCC_GE", 611*18462Sralph PCC_GT, "PCC_GT", 612*18462Sralph PCC_ULE, "PCC_ULE", 613*18462Sralph PCC_ULT, "PCC_ULT", 614*18462Sralph PCC_UGE, "PCC_UGE", 615*18462Sralph PCC_UGT, "PCC_UGT", 616*18462Sralph PCC_REG, "PCC_REG", 617*18462Sralph PCC_OREG, "PCC_OREG", 618*18462Sralph PCC_CCODES, "PCC_CCODES", 619*18462Sralph PCC_FREE, "PCC_FREE", 620*18462Sralph PCC_STASG, "PCC_STASG", 621*18462Sralph PCC_STARG, "PCC_STARG", 622*18462Sralph PCC_STCALL, "PCC_STCALL", 623*18462Sralph PCC_USTCALL, "PCC_USTCALL", 624*18462Sralph PCC_FLD, "PCC_FLD", 625*18462Sralph PCC_SCONV, "PCC_SCONV", 626*18462Sralph PCC_PCONV, "PCC_PCONV", 627*18462Sralph PCC_PMCONV, "PCC_PMCONV", 628*18462Sralph PCC_PVCONV, "PCC_PVCONV", 629*18462Sralph PCC_FORCE, "PCC_FORCE", 630*18462Sralph PCC_CBRANCH, "PCC_CBRANCH", 631*18462Sralph PCC_INIT, "PCC_INIT", 632*18462Sralph PCC_CAST, "PCC_CAST", 633*18462Sralph -1, "" 634762Speter }; 635*18462Sralph 636*18462Sralph char * 637*18462Sralph p2opname( op ) 638*18462Sralph register int op; 639*18462Sralph { 640*18462Sralph static char *p2map[PCC_MAXOP+1]; 641*18462Sralph static bool mapready = FALSE; 642*18462Sralph register struct p2op *pp; 643*18462Sralph 644*18462Sralph if ( mapready == FALSE ) { 645*18462Sralph for ( pp = p2opnames; pp->op >= 0; pp++ ) 646*18462Sralph p2map[ pp->op ] = pp->name; 647*18462Sralph mapready = TRUE; 648*18462Sralph } 649*18462Sralph return ( p2map[ op ] ? p2map[ op ] : "unknown" ); 650*18462Sralph } 651762Speter 652762Speter /* 653762Speter * low level routines 654762Speter */ 655762Speter 656762Speter /* 657762Speter * puts a long word on the pcstream 658762Speter */ 659762Speter p2word( word ) 66015953Smckusick int word; 661762Speter { 662762Speter 663762Speter putw( word , pcstream ); 664762Speter } 665762Speter 666762Speter /* 667762Speter * put a length 0 mod 4 null padded string onto the pcstream 668762Speter */ 669762Speter p2string( string ) 670762Speter char *string; 671762Speter { 672762Speter int slen = strlen( string ); 673762Speter int wlen = ( slen + 3 ) / 4; 674762Speter int plen = ( wlen * 4 ) - slen; 675762Speter char *cp; 676762Speter int p; 677762Speter 678762Speter for ( cp = string ; *cp ; cp++ ) 679762Speter putc( *cp , pcstream ); 680762Speter for ( p = 1 ; p <= plen ; p++ ) 681762Speter putc( '\0' , pcstream ); 682762Speter # ifdef DEBUG 683762Speter if ( opt( 'k' ) ) { 684762Speter fprintf( stdout , "\"%s" , string ); 685762Speter for ( p = 1 ; p <= plen ; p++ ) 686762Speter fprintf( stdout , "\\0" ); 687762Speter fprintf( stdout , "\"\n" ); 688762Speter } 689762Speter # endif 690762Speter } 691762Speter 692762Speter /* 693762Speter * puts a name on the pcstream 694762Speter */ 695762Speter p2name( name ) 696762Speter char *name; 697762Speter { 698762Speter int pad; 699762Speter 700762Speter fprintf( pcstream , NAMEFORMAT , name ); 701762Speter pad = strlen( name ) % sizeof (long); 702762Speter for ( ; pad < sizeof (long) ; pad++ ) { 703762Speter putc( '\0' , pcstream ); 704762Speter } 705762Speter # ifdef DEBUG 706762Speter if ( opt( 'k' ) ) { 707762Speter fprintf( stdout , NAMEFORMAT , name ); 708762Speter pad = strlen( name ) % sizeof (long); 709762Speter for ( ; pad < sizeof (long) ; pad++ ) { 710762Speter fprintf( stdout , "\\0" ); 711762Speter } 712762Speter fprintf( stdout , "\n" ); 713762Speter } 714762Speter # endif 715762Speter } 716762Speter 717762Speter /* 718762Speter * put out a jump to a label 719762Speter */ 720762Speter putjbr( label ) 721762Speter long label; 722762Speter { 723762Speter 724762Speter printjbr( LABELPREFIX , label ); 725762Speter } 726762Speter 727762Speter /* 728762Speter * put out a jump to any kind of label 729762Speter */ 730762Speter printjbr( prefix , label ) 731762Speter char *prefix; 732762Speter long label; 733762Speter { 734762Speter 73510653Speter # ifdef vax 73610653Speter putprintf( " jbr " , 1 ); 73710653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 73810653Speter # endif vax 73910653Speter # ifdef mc68000 74010653Speter putprintf( " jra " , 1 ); 74110653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 74210653Speter # endif mc68000 743762Speter } 744762Speter 745762Speter /* 746762Speter * another version of put to catch calls to put 747762Speter */ 74815953Smckusick /* VARARGS */ 74915953Smckusick put() 750762Speter { 751762Speter 75210653Speter panic("put()"); 753762Speter } 754762Speter 755762Speter #endif PC 756