1762Speter /* Copyright (c) 1979 Regents of the University of California */ 2762Speter 3*14906Speter static char sccsid[] = "@(#)p2put.c 1.14 09/05/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" 1410653Speter #include "objfmt.h" 15762Speter #include "pcops.h" 16762Speter #include "pc.h" 1710653Speter #include "align.h" 1811329Speter #include "tmps.h" 19762Speter 20762Speter /* 21762Speter * mash into f77's format 22762Speter * lovely, isn't it? 23762Speter */ 24762Speter #define TOF77( fop,val,rest ) ( ( ( (rest) & 0177777 ) << 16 ) \ 25762Speter | ( ( (val) & 0377 ) << 8 ) \ 26762Speter | ( (fop) & 0377 ) ) 27762Speter 28762Speter /* 29762Speter * emits an ftext operator and a string to the pcstream 30762Speter */ 31762Speter puttext( string ) 32762Speter char *string; 33762Speter { 34762Speter int length = str4len( string ); 35762Speter 363316Speter if ( !CGENNING ) 37762Speter return; 38762Speter p2word( TOF77( P2FTEXT , length , 0 ) ); 39762Speter # ifdef DEBUG 40762Speter if ( opt( 'k' ) ) { 41762Speter fprintf( stdout , "P2FTEXT | %3d | 0 " , length ); 42762Speter } 43762Speter # endif 44762Speter p2string( string ); 45762Speter } 46762Speter 47762Speter int 48762Speter str4len( string ) 49762Speter char *string; 50762Speter { 51762Speter 52762Speter return ( ( strlen( string ) + 3 ) / 4 ); 53762Speter } 54762Speter 55762Speter /* 56762Speter * put formatted text into a buffer for printing to the pcstream. 57762Speter * a call to putpflush actually puts out the text. 58762Speter * none of arg1 .. arg5 need be present. 59762Speter * and you can add more if you need them. 60762Speter */ 61762Speter /* VARARGS */ 62762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 ) 63762Speter char *format; 64762Speter int incomplete; 65762Speter { 66762Speter static char ppbuffer[ BUFSIZ ]; 67762Speter static char *ppbufp = ppbuffer; 68762Speter 693316Speter if ( !CGENNING ) 70762Speter return; 71762Speter sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 ); 72762Speter ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] ); 73762Speter if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) ) 74762Speter panic( "putprintf" ); 75762Speter if ( ! incomplete ) { 76762Speter puttext( ppbuffer ); 77762Speter ppbufp = ppbuffer; 78762Speter } 79762Speter } 80762Speter 81762Speter /* 82762Speter * emit a left bracket operator to pcstream 83762Speter * with function number, the maximum temp register, and total local bytes 84762Speter */ 8511329Speter putlbracket(ftnno, sizesp) 8611329Speter int ftnno; 8711329Speter struct om *sizesp; 8811329Speter { 8911329Speter int maxtempreg; 9011329Speter int alignedframesize; 91762Speter 9211329Speter # ifdef vax 9311329Speter maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL]; 9411329Speter # endif vax 9511329Speter # ifdef mc68000 9611329Speter /* 97*14906Speter * this is how /lib/f1 wants it. 9811329Speter */ 99*14906Speter maxtempreg = (sizesp->curtmps.next_avail[REG_ADDR] << 4) 100*14906Speter | (sizesp->curtmps.next_avail[REG_DATA]); 10111329Speter # endif mc68000 10211329Speter alignedframesize = 10311329Speter roundup(BITSPERBYTE * -sizesp->curtmps.om_off, BITSPERBYTE * A_STACK); 10411329Speter p2word( TOF77( P2FLBRAC , maxtempreg , ftnno ) ); 10511329Speter p2word(alignedframesize); 10611329Speter # ifdef DEBUG 10711329Speter if ( opt( 'k' ) ) { 10811329Speter fprintf(stdout, "P2FLBRAC | %3d | %d %d\n", 10911329Speter maxtempreg, ftnno, alignedframesize); 11011329Speter } 11111329Speter # endif 11211329Speter } 113762Speter 114762Speter /* 115762Speter * emit a right bracket operator 116*14906Speter * which for the binary interface 117762Speter * forces the stack allocate and register mask 118762Speter */ 119762Speter putrbracket( ftnno ) 120762Speter int ftnno; 121762Speter { 122762Speter 123762Speter p2word( TOF77( P2FRBRAC , 0 , ftnno ) ); 124762Speter # ifdef DEBUG 125762Speter if ( opt( 'k' ) ) { 126762Speter fprintf( stdout , "P2FRBRAC | 0 | %d\n" , ftnno ); 127762Speter } 128762Speter # endif 129762Speter } 130762Speter 131762Speter /* 132762Speter * emit an eof operator 133762Speter */ 134762Speter puteof() 135762Speter { 136762Speter 137762Speter p2word( P2FEOF ); 138762Speter # ifdef DEBUG 139762Speter if ( opt( 'k' ) ) { 140762Speter fprintf( stdout , "P2FEOF\n" ); 141762Speter } 142762Speter # endif 143762Speter } 144762Speter 145762Speter /* 146762Speter * emit a dot operator, 147762Speter * with a source file line number and name 148762Speter * if line is negative, there was an error on that line, but who cares? 149762Speter */ 150762Speter putdot( filename , line ) 151762Speter char *filename; 152762Speter int line; 153762Speter { 154762Speter int length = str4len( filename ); 155762Speter 156762Speter if ( line < 0 ) { 157762Speter line = -line; 158762Speter } 159762Speter p2word( TOF77( P2FEXPR , length , line ) ); 160762Speter # ifdef DEBUG 161762Speter if ( opt( 'k' ) ) { 162762Speter fprintf( stdout , "P2FEXPR | %3d | %d " , length , line ); 163762Speter } 164762Speter # endif 165762Speter p2string( filename ); 166762Speter } 167762Speter 168762Speter /* 169762Speter * put out a leaf node 170762Speter */ 171762Speter putleaf( op , lval , rval , type , name ) 172762Speter int op; 173762Speter int lval; 174762Speter int rval; 175762Speter int type; 176762Speter char *name; 177762Speter { 1783316Speter if ( !CGENNING ) 179762Speter return; 180762Speter switch ( op ) { 181762Speter default: 182762Speter panic( "[putleaf]" ); 183762Speter case P2ICON: 184762Speter p2word( TOF77( P2ICON , name != NIL , type ) ); 185762Speter p2word( lval ); 186762Speter # ifdef DEBUG 187762Speter if ( opt( 'k' ) ) { 1882474Speter fprintf( stdout , "P2ICON | %3d | 0x%x " 189762Speter , name != NIL , type ); 190762Speter fprintf( stdout , "%d\n" , lval ); 191762Speter } 192762Speter # endif 193762Speter if ( name ) 194762Speter p2name( name ); 195762Speter break; 196762Speter case P2NAME: 197762Speter p2word( TOF77( P2NAME , lval != 0 , type ) ); 198762Speter if ( lval ) 199762Speter p2word( lval ); 200762Speter # ifdef DEBUG 201762Speter if ( opt( 'k' ) ) { 2022474Speter fprintf( stdout , "P2NAME | %3d | 0x%x " 203762Speter , lval != 0 , type ); 204762Speter if ( lval ) 205762Speter fprintf( stdout , "%d " , lval ); 206762Speter } 207762Speter # endif 208762Speter p2name( name ); 209762Speter break; 210762Speter case P2REG: 211762Speter p2word( TOF77( P2REG , rval , type ) ); 212762Speter # ifdef DEBUG 213762Speter if ( opt( 'k' ) ) { 2142474Speter fprintf( stdout , "P2REG | %3d | 0x%x\n" , 2152474Speter rval , type ); 216762Speter } 217762Speter # endif 218762Speter break; 219762Speter } 220762Speter } 221762Speter 222762Speter /* 223762Speter * rvalues are just lvalues with indirection, except 2243829Speter * special cases for registers and for named globals, 2253829Speter * whose names are their rvalues. 226762Speter */ 2277924Smckusick putRV( name , level , offset , other_flags , type ) 228762Speter char *name; 229762Speter int level; 230762Speter int offset; 2317924Smckusick char other_flags; 232762Speter int type; 233762Speter { 234762Speter char extname[ BUFSIZ ]; 235762Speter char *printname; 2363582Speter int regnumber; 237762Speter 2383316Speter if ( !CGENNING ) 239762Speter return; 2407924Smckusick if ( other_flags & NREGVAR ) { 2413829Speter if ( ( offset < 0 ) || ( offset > P2FP ) ) { 2423829Speter panic( "putRV regvar" ); 2433582Speter } 2443829Speter putleaf( P2REG , 0 , offset , type , 0 ); 2453277Smckusic return; 2463277Smckusic } 2477924Smckusick if ( whereis( level , offset , other_flags ) == GLOBALVAR ) { 2483829Speter if ( name != 0 ) { 2493829Speter if ( name[0] != '_' ) { 2503829Speter sprintf( extname , EXTFORMAT , name ); 2513829Speter printname = extname; 2523829Speter } else { 2533829Speter printname = name; 2543829Speter } 2553829Speter putleaf( P2NAME , offset , 0 , type , printname ); 2563829Speter return; 257762Speter } else { 2583829Speter panic( "putRV no name" ); 259762Speter } 260762Speter } 2617924Smckusick putLV( name , level , offset , other_flags , type ); 262762Speter putop( P2UNARY P2MUL , type ); 263762Speter } 264762Speter 265762Speter /* 266762Speter * put out an lvalue 267762Speter * given a level and offset 268762Speter * special case for 269762Speter * named globals, whose lvalues are just their names as constants. 270762Speter */ 2717924Smckusick putLV( name , level , offset , other_flags , type ) 272762Speter char *name; 273762Speter int level; 274762Speter int offset; 2757924Smckusick char other_flags; 276762Speter int type; 2773277Smckusic { 2783277Smckusic char extname[ BUFSIZ ]; 2793277Smckusic char *printname; 280762Speter 2813316Speter if ( !CGENNING ) 2823277Smckusic return; 2837924Smckusick if ( other_flags & NREGVAR ) { 2843829Speter panic( "putLV regvar" ); 285762Speter } 2867924Smckusick switch ( whereis( level , offset , other_flags ) ) { 2873829Speter case GLOBALVAR: 2883829Speter if ( ( name != 0 ) ) { 2893829Speter if ( name[0] != '_' ) { 2903829Speter sprintf( extname , EXTFORMAT , name ); 2913829Speter printname = extname; 2923829Speter } else { 2933829Speter printname = name; 2943829Speter } 2953829Speter putleaf( P2ICON , offset , 0 , ADDTYPE( type , P2PTR ) 2963829Speter , printname ); 2973829Speter return; 2983829Speter } else { 2993829Speter panic( "putLV no name" ); 3003829Speter } 3013277Smckusic case PARAMVAR: 3023277Smckusic if ( level == cbn ) { 3033277Smckusic putleaf( P2REG , 0 , P2AP , ADDTYPE( type , P2PTR ) , 0 ); 3043277Smckusic } else { 3053277Smckusic putleaf( P2NAME , (level * sizeof(struct dispsave)) + AP_OFFSET 3063277Smckusic , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3079128Smckusick parts[ level ] |= NONLOCALVAR; 3083277Smckusic } 3093277Smckusic putleaf( P2ICON , offset , 0 , P2INT , 0 ); 3103277Smckusic putop( P2PLUS , P2PTR | P2CHAR ); 3113277Smckusic break; 3123277Smckusic case LOCALVAR: 3133277Smckusic if ( level == cbn ) { 3143277Smckusic putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 ); 3153277Smckusic } else { 3163277Smckusic putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 3173277Smckusic , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3189128Smckusick parts[ level ] |= NONLOCALVAR; 3193277Smckusic } 3203277Smckusic putleaf( P2ICON , -offset , 0 , P2INT , 0 ); 3213277Smckusic putop( P2MINUS , P2PTR | P2CHAR ); 3223277Smckusic break; 3239128Smckusick case NAMEDLOCALVAR: 3249128Smckusick if ( level == cbn ) { 3259128Smckusick putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 ); 3269128Smckusick } else { 3279128Smckusick putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 3289128Smckusick , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3299128Smckusick parts[ level ] |= NONLOCALVAR; 3309128Smckusick } 3319128Smckusick putleaf( P2ICON , 0 , 0 , P2INT , name ); 3329128Smckusick putop( P2MINUS , P2PTR | P2CHAR ); 3339128Smckusick break; 3343277Smckusic } 3353277Smckusic return; 3363277Smckusic } 337762Speter 338762Speter /* 339762Speter * put out a floating point constant leaf node 340762Speter * the constant is declared in aligned data space 341762Speter * and a P2NAME leaf put out for it 342762Speter */ 3437924Smckusick putCON8( val ) 3447924Smckusick double val; 345762Speter { 346762Speter int label; 347762Speter char name[ BUFSIZ ]; 348762Speter 3493316Speter if ( !CGENNING ) 350762Speter return; 35110653Speter label = getlab(); 352762Speter putprintf( " .data" , 0 ); 35310653Speter aligndot(A_DOUBLE); 354762Speter putlab( label ); 35510653Speter # ifdef vax 35610653Speter putprintf( " .double 0d%.20e" , 0 , val ); 35710653Speter # endif vax 35810653Speter # ifdef mc68000 35910653Speter putprintf( " .long 0x%x,0x%x", 0, val); 36010653Speter # endif mc68000 361762Speter putprintf( " .text" , 0 ); 362762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 363762Speter putleaf( P2NAME , 0 , 0 , P2DOUBLE , name ); 364762Speter } 365762Speter 366762Speter /* 367762Speter * put out either an lvalue or an rvalue for a constant string. 368762Speter * an lvalue (for assignment rhs's) is the name as a constant, 369762Speter * an rvalue (for parameters) is just the name. 370762Speter */ 371762Speter putCONG( string , length , required ) 372762Speter char *string; 373762Speter int length; 374762Speter int required; 375762Speter { 376762Speter char name[ BUFSIZ ]; 377762Speter int label; 378762Speter char *cp; 379762Speter int pad; 380762Speter int others; 381762Speter 3823316Speter if ( !CGENNING ) 383762Speter return; 384762Speter putprintf( " .data" , 0 ); 38510653Speter aligndot(A_STRUCT); 386762Speter label = getlab(); 387762Speter putlab( label ); 388762Speter cp = string; 389762Speter while ( *cp ) { 390762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 391762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 392762Speter putprintf( ",0%o" , 1 , *cp++ ); 393762Speter } 394762Speter putprintf( "" , 0 ); 395762Speter } 396762Speter pad = length - strlen( string ); 397762Speter while ( pad-- > 0 ) { 398762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 399762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 400762Speter putprintf( ",0%o" , 1 , ' ' ); 401762Speter } 402762Speter putprintf( "" , 0 ); 403762Speter } 404762Speter putprintf( " .byte 0" , 0 ); 405762Speter putprintf( " .text" , 0 ); 406762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 407762Speter if ( required == RREQ ) { 408762Speter putleaf( P2NAME , 0 , 0 , P2ARY | P2CHAR , name ); 409762Speter } else { 410762Speter putleaf( P2ICON , 0 , 0 , P2PTR | P2CHAR , name ); 411762Speter } 412762Speter } 413762Speter 414762Speter /* 415762Speter * map a pascal type to a c type 416762Speter * this would be tail recursive, but i unfolded it into a for (;;). 417762Speter * this is sort of like isa and lwidth 418762Speter * a note on the types used by the portable c compiler: 419762Speter * they are divided into a basic type (char, short, int, long, etc.) 420762Speter * and qualifications on those basic types (pointer, function, array). 421762Speter * the basic type is kept in the low 4 bits of the type descriptor, 422762Speter * and the qualifications are arranged in two bit chunks, with the 423762Speter * most significant on the right, 424762Speter * and the least significant on the left 425762Speter * e.g. int *foo(); 426762Speter * (a function returning a pointer to an integer) 427762Speter * is stored as 428762Speter * <ptr><ftn><int> 429762Speter * so, we build types recursively 4301478Speter * also, we know that /lib/f1 can only deal with 6 qualifications 4311478Speter * so we stop the recursion there. this stops infinite type recursion 4321478Speter * through mutually recursive pointer types. 433762Speter */ 4341478Speter #define MAXQUALS 6 435762Speter int 436762Speter p2type( np ) 4371478Speter { 4381478Speter 4391478Speter return typerecur( np , 0 ); 4401478Speter } 4411478Speter typerecur( np , quals ) 4421478Speter struct nl *np; 4431478Speter int quals; 444762Speter { 445762Speter 4461478Speter if ( np == NIL || quals > MAXQUALS ) { 4471478Speter return P2UNDEF; 4481478Speter } 449762Speter switch ( np -> class ) { 450762Speter case SCAL : 451762Speter case RANGE : 452762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 453762Speter return P2DOUBLE; 454762Speter } 455762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 456762Speter case 1: 457762Speter return P2CHAR; 458762Speter case 2: 459762Speter return P2SHORT; 460762Speter case 4: 461762Speter return P2INT; 462762Speter default: 463762Speter panic( "p2type int" ); 464762Speter } 465762Speter case STR : 466762Speter return ( P2ARY | P2CHAR ); 467762Speter case RECORD : 468762Speter case SET : 469762Speter return P2STRTY; 470762Speter case FILET : 471762Speter return ( P2PTR | P2STRTY ); 472762Speter case CONST : 473762Speter case VAR : 474762Speter case FIELD : 475762Speter return p2type( np -> type ); 476762Speter case TYPE : 477762Speter switch ( nloff( np ) ) { 478762Speter case TNIL : 4791478Speter return ( P2PTR | P2UNDEF ); 480762Speter case TSTR : 481762Speter return ( P2ARY | P2CHAR ); 482762Speter case TSET : 483762Speter return P2STRTY; 484762Speter default : 485762Speter return ( p2type( np -> type ) ); 486762Speter } 487762Speter case REF: 488762Speter case WITHPTR: 489762Speter case PTR : 4901478Speter return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2PTR ); 491762Speter case ARRAY : 4921478Speter return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2ARY ); 493762Speter case FUNC : 494762Speter /* 495762Speter * functions are really pointers to functions 496762Speter * which return their underlying type. 497762Speter */ 4981478Speter return ADDTYPE( ADDTYPE( typerecur( np -> type , quals + 2 ) , 4991478Speter P2FTN ) , P2PTR ); 500762Speter case PROC : 501762Speter /* 502762Speter * procedures are pointers to functions 503762Speter * which return integers (whether you look at them or not) 504762Speter */ 505762Speter return ADDTYPE( ADDTYPE( P2INT , P2FTN ) , P2PTR ); 5061197Speter case FFUNC : 5071197Speter case FPROC : 5081197Speter /* 5091197Speter * formal procedures and functions are pointers 5101197Speter * to structures which describe their environment. 5111197Speter */ 5122474Speter return ( P2PTR | P2STRTY ); 513762Speter default : 514762Speter panic( "p2type" ); 515762Speter } 516762Speter } 517762Speter 518762Speter /* 519762Speter * add a most significant type modifier to a type 520762Speter */ 521762Speter long 522762Speter addtype( underlying , mtype ) 523762Speter long underlying; 524762Speter long mtype; 525762Speter { 526762Speter return ( ( ( underlying & ~P2BASETYPE ) << P2TYPESHIFT ) 527762Speter | mtype 528762Speter | ( underlying & P2BASETYPE ) ); 529762Speter } 530762Speter 531762Speter /* 532762Speter * put a typed operator to the pcstream 533762Speter */ 534762Speter putop( op , type ) 535762Speter int op; 536762Speter int type; 537762Speter { 538762Speter extern char *p2opnames[]; 539762Speter 5403316Speter if ( !CGENNING ) 541762Speter return; 542762Speter p2word( TOF77( op , 0 , type ) ); 543762Speter # ifdef DEBUG 544762Speter if ( opt( 'k' ) ) { 5452474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x\n" 546762Speter , p2opnames[ op ] , op , type ); 547762Speter } 548762Speter # endif 549762Speter } 550762Speter 551762Speter /* 552762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 553762Speter * which looks just like a regular operator, only the size and 554762Speter * alignment go in the next consecutive words 555762Speter */ 556762Speter putstrop( op , type , size , alignment ) 557762Speter int op; 558762Speter int type; 559762Speter int size; 560762Speter int alignment; 561762Speter { 562762Speter extern char *p2opnames[]; 563762Speter 5643316Speter if ( !CGENNING ) 565762Speter return; 566762Speter p2word( TOF77( op , 0 , type ) ); 567762Speter p2word( size ); 568762Speter p2word( alignment ); 569762Speter # ifdef DEBUG 570762Speter if ( opt( 'k' ) ) { 5712474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" 572762Speter , p2opnames[ op ] , op , type , size , alignment ); 573762Speter } 574762Speter # endif 575762Speter } 576762Speter 577762Speter /* 578762Speter * the string names of p2ops 579762Speter */ 580762Speter char *p2opnames[] = { 581762Speter "", 582762Speter "P2UNDEFINED", /* 1 */ 583762Speter "P2NAME", /* 2 */ 584762Speter "P2STRING", /* 3 */ 585762Speter "P2ICON", /* 4 */ 586762Speter "P2FCON", /* 5 */ 587762Speter "P2PLUS", /* 6 */ 588762Speter "", 589762Speter "P2MINUS", /* 8 also unary == P2NEG */ 590762Speter "", 591762Speter "P2NEG", 592762Speter "P2MUL", /* 11 also unary == P2INDIRECT */ 593762Speter "", 594762Speter "P2INDIRECT", 595762Speter "P2AND", /* 14 also unary == P2ADDROF */ 596762Speter "", 597762Speter "P2ADDROF", 598762Speter "P2OR", /* 17 */ 599762Speter "", 600762Speter "P2ER", /* 19 */ 601762Speter "", 602762Speter "P2QUEST", /* 21 */ 603762Speter "P2COLON", /* 22 */ 604762Speter "P2ANDAND", /* 23 */ 605762Speter "P2OROR", /* 24 */ 606762Speter "", /* 25 */ 607762Speter "", /* 26 */ 608762Speter "", /* 27 */ 609762Speter "", /* 28 */ 610762Speter "", /* 29 */ 611762Speter "", /* 30 */ 612762Speter "", /* 31 */ 613762Speter "", /* 32 */ 614762Speter "", /* 33 */ 615762Speter "", /* 34 */ 616762Speter "", /* 35 */ 617762Speter "", /* 36 */ 618762Speter "", /* 37 */ 619762Speter "", /* 38 */ 620762Speter "", /* 39 */ 621762Speter "", /* 40 */ 622762Speter "", /* 41 */ 623762Speter "", /* 42 */ 624762Speter "", /* 43 */ 625762Speter "", /* 44 */ 626762Speter "", /* 45 */ 627762Speter "", /* 46 */ 628762Speter "", /* 47 */ 629762Speter "", /* 48 */ 630762Speter "", /* 49 */ 631762Speter "", /* 50 */ 632762Speter "", /* 51 */ 633762Speter "", /* 52 */ 634762Speter "", /* 53 */ 635762Speter "", /* 54 */ 636762Speter "", /* 55 */ 637762Speter "P2LISTOP", /* 56 */ 638762Speter "", 639762Speter "P2ASSIGN", /* 58 */ 640762Speter "P2COMOP", /* 59 */ 641762Speter "P2DIV", /* 60 */ 642762Speter "", 643762Speter "P2MOD", /* 62 */ 644762Speter "", 645762Speter "P2LS", /* 64 */ 646762Speter "", 647762Speter "P2RS", /* 66 */ 648762Speter "", 649762Speter "P2DOT", /* 68 */ 650762Speter "P2STREF", /* 69 */ 651762Speter "P2CALL", /* 70 also unary */ 652762Speter "", 653762Speter "P2UNARYCALL", 654762Speter "P2FORTCALL", /* 73 also unary */ 655762Speter "", 656762Speter "P2UNARYFORTCALL", 657762Speter "P2NOT", /* 76 */ 658762Speter "P2COMPL", /* 77 */ 659762Speter "P2INCR", /* 78 */ 660762Speter "P2DECR", /* 79 */ 661762Speter "P2EQ", /* 80 */ 662762Speter "P2NE", /* 81 */ 663762Speter "P2LE", /* 82 */ 664762Speter "P2LT", /* 83 */ 665762Speter "P2GE", /* 84 */ 666762Speter "P2GT", /* 85 */ 667762Speter "P2ULE", /* 86 */ 668762Speter "P2ULT", /* 87 */ 669762Speter "P2UGE", /* 88 */ 670762Speter "P2UGT", /* 89 */ 671762Speter "P2SETBIT", /* 90 */ 672762Speter "P2TESTBIT", /* 91 */ 673762Speter "P2RESETBIT", /* 92 */ 674762Speter "P2ARS", /* 93 */ 675762Speter "P2REG", /* 94 */ 676762Speter "P2OREG", /* 95 */ 677762Speter "P2CCODES", /* 96 */ 678762Speter "P2FREE", /* 97 */ 679762Speter "P2STASG", /* 98 */ 680762Speter "P2STARG", /* 99 */ 681762Speter "P2STCALL", /* 100 also unary */ 682762Speter "", 683762Speter "P2UNARYSTCALL", 684762Speter "P2FLD", /* 103 */ 685762Speter "P2SCONV", /* 104 */ 686762Speter "P2PCONV", /* 105 */ 687762Speter "P2PMCONV", /* 106 */ 688762Speter "P2PVCONV", /* 107 */ 689762Speter "P2FORCE", /* 108 */ 690762Speter "P2CBRANCH", /* 109 */ 691762Speter "P2INIT", /* 110 */ 692762Speter "P2CAST", /* 111 */ 693762Speter }; 694762Speter 695762Speter /* 696762Speter * low level routines 697762Speter */ 698762Speter 699762Speter /* 700762Speter * puts a long word on the pcstream 701762Speter */ 702762Speter p2word( word ) 703762Speter long word; 704762Speter { 705762Speter 706762Speter putw( word , pcstream ); 707762Speter } 708762Speter 709762Speter /* 710762Speter * put a length 0 mod 4 null padded string onto the pcstream 711762Speter */ 712762Speter p2string( string ) 713762Speter char *string; 714762Speter { 715762Speter int slen = strlen( string ); 716762Speter int wlen = ( slen + 3 ) / 4; 717762Speter int plen = ( wlen * 4 ) - slen; 718762Speter char *cp; 719762Speter int p; 720762Speter 721762Speter for ( cp = string ; *cp ; cp++ ) 722762Speter putc( *cp , pcstream ); 723762Speter for ( p = 1 ; p <= plen ; p++ ) 724762Speter putc( '\0' , pcstream ); 725762Speter # ifdef DEBUG 726762Speter if ( opt( 'k' ) ) { 727762Speter fprintf( stdout , "\"%s" , string ); 728762Speter for ( p = 1 ; p <= plen ; p++ ) 729762Speter fprintf( stdout , "\\0" ); 730762Speter fprintf( stdout , "\"\n" ); 731762Speter } 732762Speter # endif 733762Speter } 734762Speter 735762Speter /* 736762Speter * puts a name on the pcstream 737762Speter */ 738762Speter p2name( name ) 739762Speter char *name; 740762Speter { 741762Speter int pad; 742762Speter 743762Speter fprintf( pcstream , NAMEFORMAT , name ); 744762Speter pad = strlen( name ) % sizeof (long); 745762Speter for ( ; pad < sizeof (long) ; pad++ ) { 746762Speter putc( '\0' , pcstream ); 747762Speter } 748762Speter # ifdef DEBUG 749762Speter if ( opt( 'k' ) ) { 750762Speter fprintf( stdout , NAMEFORMAT , name ); 751762Speter pad = strlen( name ) % sizeof (long); 752762Speter for ( ; pad < sizeof (long) ; pad++ ) { 753762Speter fprintf( stdout , "\\0" ); 754762Speter } 755762Speter fprintf( stdout , "\n" ); 756762Speter } 757762Speter # endif 758762Speter } 759762Speter 760762Speter /* 761762Speter * put out a jump to a label 762762Speter */ 763762Speter putjbr( label ) 764762Speter long label; 765762Speter { 766762Speter 767762Speter printjbr( LABELPREFIX , label ); 768762Speter } 769762Speter 770762Speter /* 771762Speter * put out a jump to any kind of label 772762Speter */ 773762Speter printjbr( prefix , label ) 774762Speter char *prefix; 775762Speter long label; 776762Speter { 777762Speter 77810653Speter # ifdef vax 77910653Speter putprintf( " jbr " , 1 ); 78010653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 78110653Speter # endif vax 78210653Speter # ifdef mc68000 78310653Speter putprintf( " jra " , 1 ); 78410653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 78510653Speter # endif mc68000 786762Speter } 787762Speter 788762Speter /* 789762Speter * another version of put to catch calls to put 790762Speter */ 791762Speter put( arg1 , arg2 ) 792762Speter { 793762Speter 79410653Speter panic("put()"); 795762Speter } 796762Speter 797762Speter #endif PC 798