1762Speter /* Copyright (c) 1979 Regents of the University of California */ 2762Speter 3*10653Speter static char sccsid[] = "@(#)p2put.c 1.12 02/01/83"; 4762Speter 5762Speter /* 6762Speter * functions to help pi put out 7762Speter * polish postfix binary portable c compiler intermediate code 8762Speter * thereby becoming the portable pascal compiler 9762Speter */ 10762Speter 11762Speter #include "whoami.h" 12762Speter #ifdef PC 13762Speter #include "0.h" 14*10653Speter #include "objfmt.h" 15762Speter #include "pcops.h" 16762Speter #include "pc.h" 17*10653Speter #include "align.h" 18762Speter 19762Speter /* 20762Speter * mash into f77's format 21762Speter * lovely, isn't it? 22762Speter */ 23762Speter #define TOF77( fop,val,rest ) ( ( ( (rest) & 0177777 ) << 16 ) \ 24762Speter | ( ( (val) & 0377 ) << 8 ) \ 25762Speter | ( (fop) & 0377 ) ) 26762Speter 27762Speter /* 28762Speter * emits an ftext operator and a string to the pcstream 29762Speter */ 30762Speter puttext( string ) 31762Speter char *string; 32762Speter { 33762Speter int length = str4len( string ); 34762Speter 353316Speter if ( !CGENNING ) 36762Speter return; 37762Speter p2word( TOF77( P2FTEXT , length , 0 ) ); 38762Speter # ifdef DEBUG 39762Speter if ( opt( 'k' ) ) { 40762Speter fprintf( stdout , "P2FTEXT | %3d | 0 " , length ); 41762Speter } 42762Speter # endif 43762Speter p2string( string ); 44762Speter } 45762Speter 46762Speter int 47762Speter str4len( string ) 48762Speter char *string; 49762Speter { 50762Speter 51762Speter return ( ( strlen( string ) + 3 ) / 4 ); 52762Speter } 53762Speter 54762Speter /* 55762Speter * put formatted text into a buffer for printing to the pcstream. 56762Speter * a call to putpflush actually puts out the text. 57762Speter * none of arg1 .. arg5 need be present. 58762Speter * and you can add more if you need them. 59762Speter */ 60762Speter /* VARARGS */ 61762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 ) 62762Speter char *format; 63762Speter int incomplete; 64762Speter { 65762Speter static char ppbuffer[ BUFSIZ ]; 66762Speter static char *ppbufp = ppbuffer; 67762Speter 683316Speter if ( !CGENNING ) 69762Speter return; 70762Speter sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 ); 71762Speter ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] ); 72762Speter if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) ) 73762Speter panic( "putprintf" ); 74762Speter if ( ! incomplete ) { 75762Speter puttext( ppbuffer ); 76762Speter ppbufp = ppbuffer; 77762Speter } 78762Speter } 79762Speter 80762Speter /* 81762Speter * emit a left bracket operator to pcstream 82762Speter * with function number, the maximum temp register, and total local bytes 83762Speter * until i figure out how to use them, regs 0 .. 11 are free. 84762Speter * one idea for one reg is to save the display pointer on block entry 85762Speter */ 86762Speter putlbracket( ftnno , localbytes ) 87762Speter int ftnno; 88762Speter int localbytes; 89762Speter { 90762Speter # define MAXTP2REG 11 91762Speter 92762Speter p2word( TOF77( P2FLBRAC , MAXTP2REG , ftnno ) ); 93*10653Speter p2word( roundup(BITSPERBYTE * localbytes, BITSPERBYTE * A_STACK)); 94762Speter # ifdef DEBUG 95762Speter if ( opt( 'k' ) ) { 96762Speter fprintf( stdout 97762Speter , "P2FLBRAC | %3d | %d " , MAXTP2REG , ftnno ); 98762Speter fprintf( stdout , "%d\n" 99762Speter , BITSPERBYTE * localbytes ); 100762Speter } 101762Speter # endif 102762Speter } 103762Speter 104762Speter /* 105762Speter * emit a right bracket operator 106762Speter * which for the binary (fortran) interface 107762Speter * forces the stack allocate and register mask 108762Speter */ 109762Speter putrbracket( ftnno ) 110762Speter int ftnno; 111762Speter { 112762Speter 113762Speter p2word( TOF77( P2FRBRAC , 0 , ftnno ) ); 114762Speter # ifdef DEBUG 115762Speter if ( opt( 'k' ) ) { 116762Speter fprintf( stdout , "P2FRBRAC | 0 | %d\n" , ftnno ); 117762Speter } 118762Speter # endif 119762Speter } 120762Speter 121762Speter /* 122762Speter * emit an eof operator 123762Speter */ 124762Speter puteof() 125762Speter { 126762Speter 127762Speter p2word( P2FEOF ); 128762Speter # ifdef DEBUG 129762Speter if ( opt( 'k' ) ) { 130762Speter fprintf( stdout , "P2FEOF\n" ); 131762Speter } 132762Speter # endif 133762Speter } 134762Speter 135762Speter /* 136762Speter * emit a dot operator, 137762Speter * with a source file line number and name 138762Speter * if line is negative, there was an error on that line, but who cares? 139762Speter */ 140762Speter putdot( filename , line ) 141762Speter char *filename; 142762Speter int line; 143762Speter { 144762Speter int length = str4len( filename ); 145762Speter 146762Speter if ( line < 0 ) { 147762Speter line = -line; 148762Speter } 149762Speter p2word( TOF77( P2FEXPR , length , line ) ); 150762Speter # ifdef DEBUG 151762Speter if ( opt( 'k' ) ) { 152762Speter fprintf( stdout , "P2FEXPR | %3d | %d " , length , line ); 153762Speter } 154762Speter # endif 155762Speter p2string( filename ); 156762Speter } 157762Speter 158762Speter /* 159762Speter * put out a leaf node 160762Speter */ 161762Speter putleaf( op , lval , rval , type , name ) 162762Speter int op; 163762Speter int lval; 164762Speter int rval; 165762Speter int type; 166762Speter char *name; 167762Speter { 1683316Speter if ( !CGENNING ) 169762Speter return; 170762Speter switch ( op ) { 171762Speter default: 172762Speter panic( "[putleaf]" ); 173762Speter case P2ICON: 174762Speter p2word( TOF77( P2ICON , name != NIL , type ) ); 175762Speter p2word( lval ); 176762Speter # ifdef DEBUG 177762Speter if ( opt( 'k' ) ) { 1782474Speter fprintf( stdout , "P2ICON | %3d | 0x%x " 179762Speter , name != NIL , type ); 180762Speter fprintf( stdout , "%d\n" , lval ); 181762Speter } 182762Speter # endif 183762Speter if ( name ) 184762Speter p2name( name ); 185762Speter break; 186762Speter case P2NAME: 187762Speter p2word( TOF77( P2NAME , lval != 0 , type ) ); 188762Speter if ( lval ) 189762Speter p2word( lval ); 190762Speter # ifdef DEBUG 191762Speter if ( opt( 'k' ) ) { 1922474Speter fprintf( stdout , "P2NAME | %3d | 0x%x " 193762Speter , lval != 0 , type ); 194762Speter if ( lval ) 195762Speter fprintf( stdout , "%d " , lval ); 196762Speter } 197762Speter # endif 198762Speter p2name( name ); 199762Speter break; 200762Speter case P2REG: 201762Speter p2word( TOF77( P2REG , rval , type ) ); 202762Speter # ifdef DEBUG 203762Speter if ( opt( 'k' ) ) { 2042474Speter fprintf( stdout , "P2REG | %3d | 0x%x\n" , 2052474Speter rval , type ); 206762Speter } 207762Speter # endif 208762Speter break; 209762Speter } 210762Speter } 211762Speter 212762Speter /* 213762Speter * rvalues are just lvalues with indirection, except 2143829Speter * special cases for registers and for named globals, 2153829Speter * whose names are their rvalues. 216762Speter */ 2177924Smckusick putRV( name , level , offset , other_flags , type ) 218762Speter char *name; 219762Speter int level; 220762Speter int offset; 2217924Smckusick char other_flags; 222762Speter int type; 223762Speter { 224762Speter char extname[ BUFSIZ ]; 225762Speter char *printname; 2263582Speter int regnumber; 227762Speter 2283316Speter if ( !CGENNING ) 229762Speter return; 2307924Smckusick if ( other_flags & NREGVAR ) { 2313829Speter if ( ( offset < 0 ) || ( offset > P2FP ) ) { 2323829Speter panic( "putRV regvar" ); 2333582Speter } 2343829Speter putleaf( P2REG , 0 , offset , type , 0 ); 2353277Smckusic return; 2363277Smckusic } 2377924Smckusick if ( whereis( level , offset , other_flags ) == GLOBALVAR ) { 2383829Speter if ( name != 0 ) { 2393829Speter if ( name[0] != '_' ) { 2403829Speter sprintf( extname , EXTFORMAT , name ); 2413829Speter printname = extname; 2423829Speter } else { 2433829Speter printname = name; 2443829Speter } 2453829Speter putleaf( P2NAME , offset , 0 , type , printname ); 2463829Speter return; 247762Speter } else { 2483829Speter panic( "putRV no name" ); 249762Speter } 250762Speter } 2517924Smckusick putLV( name , level , offset , other_flags , type ); 252762Speter putop( P2UNARY P2MUL , type ); 253762Speter } 254762Speter 255762Speter /* 256762Speter * put out an lvalue 257762Speter * given a level and offset 258762Speter * special case for 259762Speter * named globals, whose lvalues are just their names as constants. 260762Speter */ 2617924Smckusick putLV( name , level , offset , other_flags , type ) 262762Speter char *name; 263762Speter int level; 264762Speter int offset; 2657924Smckusick char other_flags; 266762Speter int type; 2673277Smckusic { 2683277Smckusic char extname[ BUFSIZ ]; 2693277Smckusic char *printname; 270762Speter 2713316Speter if ( !CGENNING ) 2723277Smckusic return; 2737924Smckusick if ( other_flags & NREGVAR ) { 2743829Speter panic( "putLV regvar" ); 275762Speter } 2767924Smckusick switch ( whereis( level , offset , other_flags ) ) { 2773829Speter case GLOBALVAR: 2783829Speter if ( ( name != 0 ) ) { 2793829Speter if ( name[0] != '_' ) { 2803829Speter sprintf( extname , EXTFORMAT , name ); 2813829Speter printname = extname; 2823829Speter } else { 2833829Speter printname = name; 2843829Speter } 2853829Speter putleaf( P2ICON , offset , 0 , ADDTYPE( type , P2PTR ) 2863829Speter , printname ); 2873829Speter return; 2883829Speter } else { 2893829Speter panic( "putLV no name" ); 2903829Speter } 2913277Smckusic case PARAMVAR: 2923277Smckusic if ( level == cbn ) { 2933277Smckusic putleaf( P2REG , 0 , P2AP , ADDTYPE( type , P2PTR ) , 0 ); 2943277Smckusic } else { 2953277Smckusic putleaf( P2NAME , (level * sizeof(struct dispsave)) + AP_OFFSET 2963277Smckusic , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 2979128Smckusick parts[ level ] |= NONLOCALVAR; 2983277Smckusic } 2993277Smckusic putleaf( P2ICON , offset , 0 , P2INT , 0 ); 3003277Smckusic putop( P2PLUS , P2PTR | P2CHAR ); 3013277Smckusic break; 3023277Smckusic case LOCALVAR: 3033277Smckusic if ( level == cbn ) { 3043277Smckusic putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 ); 3053277Smckusic } else { 3063277Smckusic putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 3073277Smckusic , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3089128Smckusick parts[ level ] |= NONLOCALVAR; 3093277Smckusic } 3103277Smckusic putleaf( P2ICON , -offset , 0 , P2INT , 0 ); 3113277Smckusic putop( P2MINUS , P2PTR | P2CHAR ); 3123277Smckusic break; 3139128Smckusick case NAMEDLOCALVAR: 3149128Smckusick if ( level == cbn ) { 3159128Smckusick putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 ); 3169128Smckusick } else { 3179128Smckusick putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 3189128Smckusick , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3199128Smckusick parts[ level ] |= NONLOCALVAR; 3209128Smckusick } 3219128Smckusick putleaf( P2ICON , 0 , 0 , P2INT , name ); 3229128Smckusick putop( P2MINUS , P2PTR | P2CHAR ); 3239128Smckusick break; 3243277Smckusic } 3253277Smckusic return; 3263277Smckusic } 327762Speter 328762Speter /* 329762Speter * put out a floating point constant leaf node 330762Speter * the constant is declared in aligned data space 331762Speter * and a P2NAME leaf put out for it 332762Speter */ 3337924Smckusick putCON8( val ) 3347924Smckusick double val; 335762Speter { 336762Speter int label; 337762Speter char name[ BUFSIZ ]; 338762Speter 3393316Speter if ( !CGENNING ) 340762Speter return; 341*10653Speter label = getlab(); 342762Speter putprintf( " .data" , 0 ); 343*10653Speter aligndot(A_DOUBLE); 344762Speter putlab( label ); 345*10653Speter # ifdef vax 346*10653Speter putprintf( " .double 0d%.20e" , 0 , val ); 347*10653Speter # endif vax 348*10653Speter # ifdef mc68000 349*10653Speter putprintf( " .long 0x%x,0x%x", 0, val); 350*10653Speter # endif mc68000 351762Speter putprintf( " .text" , 0 ); 352762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 353762Speter putleaf( P2NAME , 0 , 0 , P2DOUBLE , name ); 354762Speter } 355762Speter 356762Speter /* 357762Speter * put out either an lvalue or an rvalue for a constant string. 358762Speter * an lvalue (for assignment rhs's) is the name as a constant, 359762Speter * an rvalue (for parameters) is just the name. 360762Speter */ 361762Speter putCONG( string , length , required ) 362762Speter char *string; 363762Speter int length; 364762Speter int required; 365762Speter { 366762Speter char name[ BUFSIZ ]; 367762Speter int label; 368762Speter char *cp; 369762Speter int pad; 370762Speter int others; 371762Speter 3723316Speter if ( !CGENNING ) 373762Speter return; 374762Speter putprintf( " .data" , 0 ); 375*10653Speter aligndot(A_STRUCT); 376762Speter label = getlab(); 377762Speter putlab( label ); 378762Speter cp = string; 379762Speter while ( *cp ) { 380762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 381762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 382762Speter putprintf( ",0%o" , 1 , *cp++ ); 383762Speter } 384762Speter putprintf( "" , 0 ); 385762Speter } 386762Speter pad = length - strlen( string ); 387762Speter while ( pad-- > 0 ) { 388762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 389762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 390762Speter putprintf( ",0%o" , 1 , ' ' ); 391762Speter } 392762Speter putprintf( "" , 0 ); 393762Speter } 394762Speter putprintf( " .byte 0" , 0 ); 395762Speter putprintf( " .text" , 0 ); 396762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 397762Speter if ( required == RREQ ) { 398762Speter putleaf( P2NAME , 0 , 0 , P2ARY | P2CHAR , name ); 399762Speter } else { 400762Speter putleaf( P2ICON , 0 , 0 , P2PTR | P2CHAR , name ); 401762Speter } 402762Speter } 403762Speter 404762Speter /* 405762Speter * map a pascal type to a c type 406762Speter * this would be tail recursive, but i unfolded it into a for (;;). 407762Speter * this is sort of like isa and lwidth 408762Speter * a note on the types used by the portable c compiler: 409762Speter * they are divided into a basic type (char, short, int, long, etc.) 410762Speter * and qualifications on those basic types (pointer, function, array). 411762Speter * the basic type is kept in the low 4 bits of the type descriptor, 412762Speter * and the qualifications are arranged in two bit chunks, with the 413762Speter * most significant on the right, 414762Speter * and the least significant on the left 415762Speter * e.g. int *foo(); 416762Speter * (a function returning a pointer to an integer) 417762Speter * is stored as 418762Speter * <ptr><ftn><int> 419762Speter * so, we build types recursively 4201478Speter * also, we know that /lib/f1 can only deal with 6 qualifications 4211478Speter * so we stop the recursion there. this stops infinite type recursion 4221478Speter * through mutually recursive pointer types. 423762Speter */ 4241478Speter #define MAXQUALS 6 425762Speter int 426762Speter p2type( np ) 4271478Speter { 4281478Speter 4291478Speter return typerecur( np , 0 ); 4301478Speter } 4311478Speter typerecur( np , quals ) 4321478Speter struct nl *np; 4331478Speter int quals; 434762Speter { 435762Speter 4361478Speter if ( np == NIL || quals > MAXQUALS ) { 4371478Speter return P2UNDEF; 4381478Speter } 439762Speter switch ( np -> class ) { 440762Speter case SCAL : 441762Speter case RANGE : 442762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 443762Speter return P2DOUBLE; 444762Speter } 445762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 446762Speter case 1: 447762Speter return P2CHAR; 448762Speter case 2: 449762Speter return P2SHORT; 450762Speter case 4: 451762Speter return P2INT; 452762Speter default: 453762Speter panic( "p2type int" ); 454762Speter } 455762Speter case STR : 456762Speter return ( P2ARY | P2CHAR ); 457762Speter case RECORD : 458762Speter case SET : 459762Speter return P2STRTY; 460762Speter case FILET : 461762Speter return ( P2PTR | P2STRTY ); 462762Speter case CONST : 463762Speter case VAR : 464762Speter case FIELD : 465762Speter return p2type( np -> type ); 466762Speter case TYPE : 467762Speter switch ( nloff( np ) ) { 468762Speter case TNIL : 4691478Speter return ( P2PTR | P2UNDEF ); 470762Speter case TSTR : 471762Speter return ( P2ARY | P2CHAR ); 472762Speter case TSET : 473762Speter return P2STRTY; 474762Speter default : 475762Speter return ( p2type( np -> type ) ); 476762Speter } 477762Speter case REF: 478762Speter case WITHPTR: 479762Speter case PTR : 4801478Speter return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2PTR ); 481762Speter case ARRAY : 4821478Speter return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2ARY ); 483762Speter case FUNC : 484762Speter /* 485762Speter * functions are really pointers to functions 486762Speter * which return their underlying type. 487762Speter */ 4881478Speter return ADDTYPE( ADDTYPE( typerecur( np -> type , quals + 2 ) , 4891478Speter P2FTN ) , P2PTR ); 490762Speter case PROC : 491762Speter /* 492762Speter * procedures are pointers to functions 493762Speter * which return integers (whether you look at them or not) 494762Speter */ 495762Speter return ADDTYPE( ADDTYPE( P2INT , P2FTN ) , P2PTR ); 4961197Speter case FFUNC : 4971197Speter case FPROC : 4981197Speter /* 4991197Speter * formal procedures and functions are pointers 5001197Speter * to structures which describe their environment. 5011197Speter */ 5022474Speter return ( P2PTR | P2STRTY ); 503762Speter default : 504762Speter panic( "p2type" ); 505762Speter } 506762Speter } 507762Speter 508762Speter /* 509762Speter * add a most significant type modifier to a type 510762Speter */ 511762Speter long 512762Speter addtype( underlying , mtype ) 513762Speter long underlying; 514762Speter long mtype; 515762Speter { 516762Speter return ( ( ( underlying & ~P2BASETYPE ) << P2TYPESHIFT ) 517762Speter | mtype 518762Speter | ( underlying & P2BASETYPE ) ); 519762Speter } 520762Speter 521762Speter /* 522762Speter * put a typed operator to the pcstream 523762Speter */ 524762Speter putop( op , type ) 525762Speter int op; 526762Speter int type; 527762Speter { 528762Speter extern char *p2opnames[]; 529762Speter 5303316Speter if ( !CGENNING ) 531762Speter return; 532762Speter p2word( TOF77( op , 0 , type ) ); 533762Speter # ifdef DEBUG 534762Speter if ( opt( 'k' ) ) { 5352474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x\n" 536762Speter , p2opnames[ op ] , op , type ); 537762Speter } 538762Speter # endif 539762Speter } 540762Speter 541762Speter /* 542762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 543762Speter * which looks just like a regular operator, only the size and 544762Speter * alignment go in the next consecutive words 545762Speter */ 546762Speter putstrop( op , type , size , alignment ) 547762Speter int op; 548762Speter int type; 549762Speter int size; 550762Speter int alignment; 551762Speter { 552762Speter extern char *p2opnames[]; 553762Speter 5543316Speter if ( !CGENNING ) 555762Speter return; 556762Speter p2word( TOF77( op , 0 , type ) ); 557762Speter p2word( size ); 558762Speter p2word( alignment ); 559762Speter # ifdef DEBUG 560762Speter if ( opt( 'k' ) ) { 5612474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" 562762Speter , p2opnames[ op ] , op , type , size , alignment ); 563762Speter } 564762Speter # endif 565762Speter } 566762Speter 567762Speter /* 568762Speter * the string names of p2ops 569762Speter */ 570762Speter char *p2opnames[] = { 571762Speter "", 572762Speter "P2UNDEFINED", /* 1 */ 573762Speter "P2NAME", /* 2 */ 574762Speter "P2STRING", /* 3 */ 575762Speter "P2ICON", /* 4 */ 576762Speter "P2FCON", /* 5 */ 577762Speter "P2PLUS", /* 6 */ 578762Speter "", 579762Speter "P2MINUS", /* 8 also unary == P2NEG */ 580762Speter "", 581762Speter "P2NEG", 582762Speter "P2MUL", /* 11 also unary == P2INDIRECT */ 583762Speter "", 584762Speter "P2INDIRECT", 585762Speter "P2AND", /* 14 also unary == P2ADDROF */ 586762Speter "", 587762Speter "P2ADDROF", 588762Speter "P2OR", /* 17 */ 589762Speter "", 590762Speter "P2ER", /* 19 */ 591762Speter "", 592762Speter "P2QUEST", /* 21 */ 593762Speter "P2COLON", /* 22 */ 594762Speter "P2ANDAND", /* 23 */ 595762Speter "P2OROR", /* 24 */ 596762Speter "", /* 25 */ 597762Speter "", /* 26 */ 598762Speter "", /* 27 */ 599762Speter "", /* 28 */ 600762Speter "", /* 29 */ 601762Speter "", /* 30 */ 602762Speter "", /* 31 */ 603762Speter "", /* 32 */ 604762Speter "", /* 33 */ 605762Speter "", /* 34 */ 606762Speter "", /* 35 */ 607762Speter "", /* 36 */ 608762Speter "", /* 37 */ 609762Speter "", /* 38 */ 610762Speter "", /* 39 */ 611762Speter "", /* 40 */ 612762Speter "", /* 41 */ 613762Speter "", /* 42 */ 614762Speter "", /* 43 */ 615762Speter "", /* 44 */ 616762Speter "", /* 45 */ 617762Speter "", /* 46 */ 618762Speter "", /* 47 */ 619762Speter "", /* 48 */ 620762Speter "", /* 49 */ 621762Speter "", /* 50 */ 622762Speter "", /* 51 */ 623762Speter "", /* 52 */ 624762Speter "", /* 53 */ 625762Speter "", /* 54 */ 626762Speter "", /* 55 */ 627762Speter "P2LISTOP", /* 56 */ 628762Speter "", 629762Speter "P2ASSIGN", /* 58 */ 630762Speter "P2COMOP", /* 59 */ 631762Speter "P2DIV", /* 60 */ 632762Speter "", 633762Speter "P2MOD", /* 62 */ 634762Speter "", 635762Speter "P2LS", /* 64 */ 636762Speter "", 637762Speter "P2RS", /* 66 */ 638762Speter "", 639762Speter "P2DOT", /* 68 */ 640762Speter "P2STREF", /* 69 */ 641762Speter "P2CALL", /* 70 also unary */ 642762Speter "", 643762Speter "P2UNARYCALL", 644762Speter "P2FORTCALL", /* 73 also unary */ 645762Speter "", 646762Speter "P2UNARYFORTCALL", 647762Speter "P2NOT", /* 76 */ 648762Speter "P2COMPL", /* 77 */ 649762Speter "P2INCR", /* 78 */ 650762Speter "P2DECR", /* 79 */ 651762Speter "P2EQ", /* 80 */ 652762Speter "P2NE", /* 81 */ 653762Speter "P2LE", /* 82 */ 654762Speter "P2LT", /* 83 */ 655762Speter "P2GE", /* 84 */ 656762Speter "P2GT", /* 85 */ 657762Speter "P2ULE", /* 86 */ 658762Speter "P2ULT", /* 87 */ 659762Speter "P2UGE", /* 88 */ 660762Speter "P2UGT", /* 89 */ 661762Speter "P2SETBIT", /* 90 */ 662762Speter "P2TESTBIT", /* 91 */ 663762Speter "P2RESETBIT", /* 92 */ 664762Speter "P2ARS", /* 93 */ 665762Speter "P2REG", /* 94 */ 666762Speter "P2OREG", /* 95 */ 667762Speter "P2CCODES", /* 96 */ 668762Speter "P2FREE", /* 97 */ 669762Speter "P2STASG", /* 98 */ 670762Speter "P2STARG", /* 99 */ 671762Speter "P2STCALL", /* 100 also unary */ 672762Speter "", 673762Speter "P2UNARYSTCALL", 674762Speter "P2FLD", /* 103 */ 675762Speter "P2SCONV", /* 104 */ 676762Speter "P2PCONV", /* 105 */ 677762Speter "P2PMCONV", /* 106 */ 678762Speter "P2PVCONV", /* 107 */ 679762Speter "P2FORCE", /* 108 */ 680762Speter "P2CBRANCH", /* 109 */ 681762Speter "P2INIT", /* 110 */ 682762Speter "P2CAST", /* 111 */ 683762Speter }; 684762Speter 685762Speter /* 686762Speter * low level routines 687762Speter */ 688762Speter 689762Speter /* 690762Speter * puts a long word on the pcstream 691762Speter */ 692762Speter p2word( word ) 693762Speter long word; 694762Speter { 695762Speter 696762Speter putw( word , pcstream ); 697762Speter } 698762Speter 699762Speter /* 700762Speter * put a length 0 mod 4 null padded string onto the pcstream 701762Speter */ 702762Speter p2string( string ) 703762Speter char *string; 704762Speter { 705762Speter int slen = strlen( string ); 706762Speter int wlen = ( slen + 3 ) / 4; 707762Speter int plen = ( wlen * 4 ) - slen; 708762Speter char *cp; 709762Speter int p; 710762Speter 711762Speter for ( cp = string ; *cp ; cp++ ) 712762Speter putc( *cp , pcstream ); 713762Speter for ( p = 1 ; p <= plen ; p++ ) 714762Speter putc( '\0' , pcstream ); 715762Speter # ifdef DEBUG 716762Speter if ( opt( 'k' ) ) { 717762Speter fprintf( stdout , "\"%s" , string ); 718762Speter for ( p = 1 ; p <= plen ; p++ ) 719762Speter fprintf( stdout , "\\0" ); 720762Speter fprintf( stdout , "\"\n" ); 721762Speter } 722762Speter # endif 723762Speter } 724762Speter 725762Speter /* 726762Speter * puts a name on the pcstream 727762Speter */ 728762Speter p2name( name ) 729762Speter char *name; 730762Speter { 731762Speter int pad; 732762Speter 733762Speter fprintf( pcstream , NAMEFORMAT , name ); 734762Speter pad = strlen( name ) % sizeof (long); 735762Speter for ( ; pad < sizeof (long) ; pad++ ) { 736762Speter putc( '\0' , pcstream ); 737762Speter } 738762Speter # ifdef DEBUG 739762Speter if ( opt( 'k' ) ) { 740762Speter fprintf( stdout , NAMEFORMAT , name ); 741762Speter pad = strlen( name ) % sizeof (long); 742762Speter for ( ; pad < sizeof (long) ; pad++ ) { 743762Speter fprintf( stdout , "\\0" ); 744762Speter } 745762Speter fprintf( stdout , "\n" ); 746762Speter } 747762Speter # endif 748762Speter } 749762Speter 750762Speter /* 751762Speter * put out a jump to a label 752762Speter */ 753762Speter putjbr( label ) 754762Speter long label; 755762Speter { 756762Speter 757762Speter printjbr( LABELPREFIX , label ); 758762Speter } 759762Speter 760762Speter /* 761762Speter * put out a jump to any kind of label 762762Speter */ 763762Speter printjbr( prefix , label ) 764762Speter char *prefix; 765762Speter long label; 766762Speter { 767762Speter 768*10653Speter # ifdef vax 769*10653Speter putprintf( " jbr " , 1 ); 770*10653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 771*10653Speter # endif vax 772*10653Speter # ifdef mc68000 773*10653Speter putprintf( " jra " , 1 ); 774*10653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 775*10653Speter # endif mc68000 776762Speter } 777762Speter 778762Speter /* 779762Speter * another version of put to catch calls to put 780762Speter */ 781762Speter put( arg1 , arg2 ) 782762Speter { 783762Speter 784*10653Speter panic("put()"); 785762Speter } 786762Speter 787762Speter #endif PC 788