1762Speter /* Copyright (c) 1979 Regents of the University of California */ 2762Speter 3*15953Smckusick #ifndef lint 4*15953Smckusick static char sccsid[] = "@(#)p2put.c 1.15 02/07/84"; 5*15953Smckusick #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" 17762Speter #include "pcops.h" 18762Speter #include "pc.h" 1910653Speter #include "align.h" 2011329Speter #include "tmps.h" 21762Speter 22762Speter /* 23762Speter * mash into f77's format 24762Speter * lovely, isn't it? 25762Speter */ 26762Speter #define TOF77( fop,val,rest ) ( ( ( (rest) & 0177777 ) << 16 ) \ 27762Speter | ( ( (val) & 0377 ) << 8 ) \ 28762Speter | ( (fop) & 0377 ) ) 29762Speter 30762Speter /* 31762Speter * emits an ftext operator and a string to the pcstream 32762Speter */ 33762Speter puttext( string ) 34762Speter char *string; 35762Speter { 36762Speter int length = str4len( string ); 37762Speter 383316Speter if ( !CGENNING ) 39762Speter return; 40762Speter p2word( TOF77( P2FTEXT , length , 0 ) ); 41762Speter # ifdef DEBUG 42762Speter if ( opt( 'k' ) ) { 43762Speter fprintf( stdout , "P2FTEXT | %3d | 0 " , length ); 44762Speter } 45762Speter # endif 46762Speter p2string( string ); 47762Speter } 48762Speter 49762Speter int 50762Speter str4len( string ) 51762Speter char *string; 52762Speter { 53762Speter 54762Speter return ( ( strlen( string ) + 3 ) / 4 ); 55762Speter } 56762Speter 57762Speter /* 58762Speter * put formatted text into a buffer for printing to the pcstream. 59762Speter * a call to putpflush actually puts out the text. 60762Speter * none of arg1 .. arg5 need be present. 61762Speter * and you can add more if you need them. 62762Speter */ 63*15953Smckusick /* VARARGS */ 64762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 ) 65762Speter char *format; 66762Speter int incomplete; 67762Speter { 68762Speter static char ppbuffer[ BUFSIZ ]; 69762Speter static char *ppbufp = ppbuffer; 70762Speter 713316Speter if ( !CGENNING ) 72762Speter return; 73762Speter sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 ); 74762Speter ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] ); 75762Speter if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) ) 76762Speter panic( "putprintf" ); 77762Speter if ( ! incomplete ) { 78762Speter puttext( ppbuffer ); 79762Speter ppbufp = ppbuffer; 80762Speter } 81762Speter } 82762Speter 83762Speter /* 84762Speter * emit a left bracket operator to pcstream 85762Speter * with function number, the maximum temp register, and total local bytes 86762Speter */ 8711329Speter putlbracket(ftnno, sizesp) 8811329Speter int ftnno; 8911329Speter struct om *sizesp; 9011329Speter { 9111329Speter int maxtempreg; 9211329Speter int alignedframesize; 93762Speter 9411329Speter # ifdef vax 9511329Speter maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL]; 9611329Speter # endif vax 9711329Speter # ifdef mc68000 9811329Speter /* 9914906Speter * this is how /lib/f1 wants it. 10011329Speter */ 10114906Speter maxtempreg = (sizesp->curtmps.next_avail[REG_ADDR] << 4) 10214906Speter | (sizesp->curtmps.next_avail[REG_DATA]); 10311329Speter # endif mc68000 104*15953Smckusick alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off), 105*15953Smckusick (long)(BITSPERBYTE * A_STACK)); 10611329Speter p2word( TOF77( P2FLBRAC , maxtempreg , ftnno ) ); 10711329Speter p2word(alignedframesize); 10811329Speter # ifdef DEBUG 10911329Speter if ( opt( 'k' ) ) { 11011329Speter fprintf(stdout, "P2FLBRAC | %3d | %d %d\n", 11111329Speter maxtempreg, ftnno, alignedframesize); 11211329Speter } 11311329Speter # endif 11411329Speter } 115762Speter 116762Speter /* 117762Speter * emit a right bracket operator 11814906Speter * which for the binary interface 119762Speter * forces the stack allocate and register mask 120762Speter */ 121762Speter putrbracket( ftnno ) 122762Speter int ftnno; 123762Speter { 124762Speter 125762Speter p2word( TOF77( P2FRBRAC , 0 , ftnno ) ); 126762Speter # ifdef DEBUG 127762Speter if ( opt( 'k' ) ) { 128762Speter fprintf( stdout , "P2FRBRAC | 0 | %d\n" , ftnno ); 129762Speter } 130762Speter # endif 131762Speter } 132762Speter 133762Speter /* 134762Speter * emit an eof operator 135762Speter */ 136762Speter puteof() 137762Speter { 138762Speter 139762Speter p2word( P2FEOF ); 140762Speter # ifdef DEBUG 141762Speter if ( opt( 'k' ) ) { 142762Speter fprintf( stdout , "P2FEOF\n" ); 143762Speter } 144762Speter # endif 145762Speter } 146762Speter 147762Speter /* 148762Speter * emit a dot operator, 149762Speter * with a source file line number and name 150762Speter * if line is negative, there was an error on that line, but who cares? 151762Speter */ 152762Speter putdot( filename , line ) 153762Speter char *filename; 154762Speter int line; 155762Speter { 156762Speter int length = str4len( filename ); 157762Speter 158762Speter if ( line < 0 ) { 159762Speter line = -line; 160762Speter } 161762Speter p2word( TOF77( P2FEXPR , length , line ) ); 162762Speter # ifdef DEBUG 163762Speter if ( opt( 'k' ) ) { 164762Speter fprintf( stdout , "P2FEXPR | %3d | %d " , length , line ); 165762Speter } 166762Speter # endif 167762Speter p2string( filename ); 168762Speter } 169762Speter 170762Speter /* 171762Speter * put out a leaf node 172762Speter */ 173762Speter putleaf( op , lval , rval , type , name ) 174762Speter int op; 175762Speter int lval; 176762Speter int rval; 177762Speter int type; 178762Speter char *name; 179762Speter { 1803316Speter if ( !CGENNING ) 181762Speter return; 182762Speter switch ( op ) { 183762Speter default: 184762Speter panic( "[putleaf]" ); 185762Speter case P2ICON: 186762Speter p2word( TOF77( P2ICON , name != NIL , type ) ); 187762Speter p2word( lval ); 188762Speter # ifdef DEBUG 189762Speter if ( opt( 'k' ) ) { 1902474Speter fprintf( stdout , "P2ICON | %3d | 0x%x " 191762Speter , name != NIL , type ); 192762Speter fprintf( stdout , "%d\n" , lval ); 193762Speter } 194762Speter # endif 195762Speter if ( name ) 196762Speter p2name( name ); 197762Speter break; 198762Speter case P2NAME: 199762Speter p2word( TOF77( P2NAME , lval != 0 , type ) ); 200762Speter if ( lval ) 201762Speter p2word( lval ); 202762Speter # ifdef DEBUG 203762Speter if ( opt( 'k' ) ) { 2042474Speter fprintf( stdout , "P2NAME | %3d | 0x%x " 205762Speter , lval != 0 , type ); 206762Speter if ( lval ) 207762Speter fprintf( stdout , "%d " , lval ); 208762Speter } 209762Speter # endif 210762Speter p2name( name ); 211762Speter break; 212762Speter case P2REG: 213762Speter p2word( TOF77( P2REG , rval , type ) ); 214762Speter # ifdef DEBUG 215762Speter if ( opt( 'k' ) ) { 2162474Speter fprintf( stdout , "P2REG | %3d | 0x%x\n" , 2172474Speter rval , type ); 218762Speter } 219762Speter # endif 220762Speter break; 221762Speter } 222762Speter } 223762Speter 224762Speter /* 225762Speter * rvalues are just lvalues with indirection, except 2263829Speter * special cases for registers and for named globals, 2273829Speter * whose names are their rvalues. 228762Speter */ 2297924Smckusick putRV( name , level , offset , other_flags , type ) 230762Speter char *name; 231762Speter int level; 232762Speter int offset; 2337924Smckusick char other_flags; 234762Speter int type; 235762Speter { 236762Speter char extname[ BUFSIZ ]; 237762Speter char *printname; 238762Speter 2393316Speter if ( !CGENNING ) 240762Speter return; 2417924Smckusick if ( other_flags & NREGVAR ) { 2423829Speter if ( ( offset < 0 ) || ( offset > P2FP ) ) { 2433829Speter panic( "putRV regvar" ); 2443582Speter } 245*15953Smckusick putleaf( P2REG , 0 , offset , type , (char *) 0 ); 2463277Smckusic return; 2473277Smckusic } 248*15953Smckusick if ( whereis( offset , other_flags ) == GLOBALVAR ) { 2493829Speter if ( name != 0 ) { 2503829Speter if ( name[0] != '_' ) { 2513829Speter sprintf( extname , EXTFORMAT , name ); 2523829Speter printname = extname; 2533829Speter } else { 2543829Speter printname = name; 2553829Speter } 2563829Speter putleaf( P2NAME , offset , 0 , type , printname ); 2573829Speter return; 258762Speter } else { 2593829Speter panic( "putRV no name" ); 260762Speter } 261762Speter } 2627924Smckusick putLV( name , level , offset , other_flags , type ); 263762Speter putop( P2UNARY P2MUL , type ); 264762Speter } 265762Speter 266762Speter /* 267762Speter * put out an lvalue 268762Speter * given a level and offset 269762Speter * special case for 270762Speter * named globals, whose lvalues are just their names as constants. 271762Speter */ 2727924Smckusick putLV( name , level , offset , other_flags , type ) 273762Speter char *name; 274762Speter int level; 275762Speter int offset; 2767924Smckusick char other_flags; 277762Speter int type; 2783277Smckusic { 2793277Smckusic char extname[ BUFSIZ ]; 2803277Smckusic char *printname; 281762Speter 2823316Speter if ( !CGENNING ) 2833277Smckusic return; 2847924Smckusick if ( other_flags & NREGVAR ) { 2853829Speter panic( "putLV regvar" ); 286762Speter } 287*15953Smckusick switch ( whereis( offset , other_flags ) ) { 2883829Speter case GLOBALVAR: 2893829Speter if ( ( name != 0 ) ) { 2903829Speter if ( name[0] != '_' ) { 2913829Speter sprintf( extname , EXTFORMAT , name ); 2923829Speter printname = extname; 2933829Speter } else { 2943829Speter printname = name; 2953829Speter } 2963829Speter putleaf( P2ICON , offset , 0 , ADDTYPE( type , P2PTR ) 2973829Speter , printname ); 2983829Speter return; 2993829Speter } else { 3003829Speter panic( "putLV no name" ); 3013829Speter } 3023277Smckusic case PARAMVAR: 3033277Smckusic if ( level == cbn ) { 304*15953Smckusick putleaf( P2REG, 0, P2AP, ADDTYPE( type , P2PTR ), (char *) 0 ); 3053277Smckusic } else { 3063277Smckusic putleaf( P2NAME , (level * sizeof(struct dispsave)) + AP_OFFSET 3073277Smckusic , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3089128Smckusick parts[ level ] |= NONLOCALVAR; 3093277Smckusic } 310*15953Smckusick putleaf( P2ICON , offset , 0 , P2INT , (char *) 0 ); 3113277Smckusic putop( P2PLUS , P2PTR | P2CHAR ); 3123277Smckusic break; 3133277Smckusic case LOCALVAR: 3143277Smckusic if ( level == cbn ) { 315*15953Smckusick putleaf( P2REG, 0, P2FP, ADDTYPE( type , P2PTR ), (char *) 0 ); 3163277Smckusic } else { 3173277Smckusic putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 3183277Smckusic , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3199128Smckusick parts[ level ] |= NONLOCALVAR; 3203277Smckusic } 321*15953Smckusick putleaf( P2ICON , -offset , 0 , P2INT , (char *) 0 ); 3223277Smckusic putop( P2MINUS , P2PTR | P2CHAR ); 3233277Smckusic break; 3249128Smckusick case NAMEDLOCALVAR: 3259128Smckusick if ( level == cbn ) { 326*15953Smckusick putleaf( P2REG, 0, P2FP, ADDTYPE( type , P2PTR ), (char *) 0 ); 3279128Smckusick } else { 3289128Smckusick putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 3299128Smckusick , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 3309128Smckusick parts[ level ] |= NONLOCALVAR; 3319128Smckusick } 3329128Smckusick putleaf( P2ICON , 0 , 0 , P2INT , name ); 3339128Smckusick putop( P2MINUS , P2PTR | P2CHAR ); 3349128Smckusick break; 3353277Smckusic } 3363277Smckusic return; 3373277Smckusic } 338762Speter 339762Speter /* 340762Speter * put out a floating point constant leaf node 341762Speter * the constant is declared in aligned data space 342762Speter * and a P2NAME leaf put out for it 343762Speter */ 3447924Smckusick putCON8( val ) 3457924Smckusick double val; 346762Speter { 347*15953Smckusick char *label; 348762Speter char name[ BUFSIZ ]; 349762Speter 3503316Speter if ( !CGENNING ) 351762Speter return; 35210653Speter label = getlab(); 353762Speter putprintf( " .data" , 0 ); 35410653Speter aligndot(A_DOUBLE); 355*15953Smckusick (void) putlab( label ); 35610653Speter # ifdef vax 35710653Speter putprintf( " .double 0d%.20e" , 0 , val ); 35810653Speter # endif vax 35910653Speter # ifdef mc68000 36010653Speter putprintf( " .long 0x%x,0x%x", 0, val); 36110653Speter # endif mc68000 362762Speter putprintf( " .text" , 0 ); 363762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 364762Speter putleaf( P2NAME , 0 , 0 , P2DOUBLE , name ); 365762Speter } 366762Speter 367762Speter /* 368762Speter * put out either an lvalue or an rvalue for a constant string. 369762Speter * an lvalue (for assignment rhs's) is the name as a constant, 370762Speter * an rvalue (for parameters) is just the name. 371762Speter */ 372762Speter putCONG( string , length , required ) 373762Speter char *string; 374762Speter int length; 375762Speter int required; 376762Speter { 377762Speter char name[ BUFSIZ ]; 378*15953Smckusick char *label; 379762Speter char *cp; 380762Speter int pad; 381762Speter int others; 382762Speter 3833316Speter if ( !CGENNING ) 384762Speter return; 385762Speter putprintf( " .data" , 0 ); 38610653Speter aligndot(A_STRUCT); 387762Speter label = getlab(); 388*15953Smckusick (void) putlab( label ); 389762Speter cp = string; 390762Speter while ( *cp ) { 391762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 392762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 393762Speter putprintf( ",0%o" , 1 , *cp++ ); 394762Speter } 395762Speter putprintf( "" , 0 ); 396762Speter } 397762Speter pad = length - strlen( string ); 398762Speter while ( pad-- > 0 ) { 399762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 400762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 401762Speter putprintf( ",0%o" , 1 , ' ' ); 402762Speter } 403762Speter putprintf( "" , 0 ); 404762Speter } 405762Speter putprintf( " .byte 0" , 0 ); 406762Speter putprintf( " .text" , 0 ); 407762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 408762Speter if ( required == RREQ ) { 409762Speter putleaf( P2NAME , 0 , 0 , P2ARY | P2CHAR , name ); 410762Speter } else { 411762Speter putleaf( P2ICON , 0 , 0 , P2PTR | P2CHAR , name ); 412762Speter } 413762Speter } 414762Speter 415762Speter /* 416762Speter * map a pascal type to a c type 417762Speter * this would be tail recursive, but i unfolded it into a for (;;). 418762Speter * this is sort of like isa and lwidth 419762Speter * a note on the types used by the portable c compiler: 420762Speter * they are divided into a basic type (char, short, int, long, etc.) 421762Speter * and qualifications on those basic types (pointer, function, array). 422762Speter * the basic type is kept in the low 4 bits of the type descriptor, 423762Speter * and the qualifications are arranged in two bit chunks, with the 424762Speter * most significant on the right, 425762Speter * and the least significant on the left 426762Speter * e.g. int *foo(); 427762Speter * (a function returning a pointer to an integer) 428762Speter * is stored as 429762Speter * <ptr><ftn><int> 430762Speter * so, we build types recursively 4311478Speter * also, we know that /lib/f1 can only deal with 6 qualifications 4321478Speter * so we stop the recursion there. this stops infinite type recursion 4331478Speter * through mutually recursive pointer types. 434762Speter */ 4351478Speter #define MAXQUALS 6 436762Speter int 437762Speter p2type( np ) 438*15953Smckusick struct nl *np; 4391478Speter { 4401478Speter 4411478Speter return typerecur( np , 0 ); 4421478Speter } 4431478Speter typerecur( np , quals ) 4441478Speter struct nl *np; 4451478Speter int quals; 446762Speter { 447762Speter 4481478Speter if ( np == NIL || quals > MAXQUALS ) { 4491478Speter return P2UNDEF; 4501478Speter } 451762Speter switch ( np -> class ) { 452762Speter case SCAL : 453762Speter case RANGE : 454762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 455762Speter return P2DOUBLE; 456762Speter } 457762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 458762Speter case 1: 459762Speter return P2CHAR; 460762Speter case 2: 461762Speter return P2SHORT; 462762Speter case 4: 463762Speter return P2INT; 464762Speter default: 465762Speter panic( "p2type int" ); 466*15953Smckusick /* NOTREACHED */ 467762Speter } 468762Speter case STR : 469762Speter return ( P2ARY | P2CHAR ); 470762Speter case RECORD : 471762Speter case SET : 472762Speter return P2STRTY; 473762Speter case FILET : 474762Speter return ( P2PTR | P2STRTY ); 475762Speter case CONST : 476762Speter case VAR : 477762Speter case FIELD : 478762Speter return p2type( np -> type ); 479762Speter case TYPE : 480762Speter switch ( nloff( np ) ) { 481762Speter case TNIL : 4821478Speter return ( P2PTR | P2UNDEF ); 483762Speter case TSTR : 484762Speter return ( P2ARY | P2CHAR ); 485762Speter case TSET : 486762Speter return P2STRTY; 487762Speter default : 488762Speter return ( p2type( np -> type ) ); 489762Speter } 490762Speter case REF: 491762Speter case WITHPTR: 492762Speter case PTR : 4931478Speter return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2PTR ); 494762Speter case ARRAY : 4951478Speter return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2ARY ); 496762Speter case FUNC : 497762Speter /* 498762Speter * functions are really pointers to functions 499762Speter * which return their underlying type. 500762Speter */ 5011478Speter return ADDTYPE( ADDTYPE( typerecur( np -> type , quals + 2 ) , 5021478Speter P2FTN ) , P2PTR ); 503762Speter case PROC : 504762Speter /* 505762Speter * procedures are pointers to functions 506762Speter * which return integers (whether you look at them or not) 507762Speter */ 508762Speter return ADDTYPE( ADDTYPE( P2INT , P2FTN ) , P2PTR ); 5091197Speter case FFUNC : 5101197Speter case FPROC : 5111197Speter /* 5121197Speter * formal procedures and functions are pointers 5131197Speter * to structures which describe their environment. 5141197Speter */ 5152474Speter return ( P2PTR | P2STRTY ); 516762Speter default : 517762Speter panic( "p2type" ); 518*15953Smckusick /* NOTREACHED */ 519762Speter } 520762Speter } 521762Speter 522762Speter /* 523762Speter * put a typed operator to the pcstream 524762Speter */ 525762Speter putop( op , type ) 526762Speter int op; 527762Speter int type; 528762Speter { 529762Speter extern char *p2opnames[]; 530762Speter 5313316Speter if ( !CGENNING ) 532762Speter return; 533762Speter p2word( TOF77( op , 0 , type ) ); 534762Speter # ifdef DEBUG 535762Speter if ( opt( 'k' ) ) { 5362474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x\n" 537762Speter , p2opnames[ op ] , op , type ); 538762Speter } 539762Speter # endif 540762Speter } 541762Speter 542762Speter /* 543762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 544762Speter * which looks just like a regular operator, only the size and 545762Speter * alignment go in the next consecutive words 546762Speter */ 547762Speter putstrop( op , type , size , alignment ) 548762Speter int op; 549762Speter int type; 550762Speter int size; 551762Speter int alignment; 552762Speter { 553762Speter extern char *p2opnames[]; 554762Speter 5553316Speter if ( !CGENNING ) 556762Speter return; 557762Speter p2word( TOF77( op , 0 , type ) ); 558762Speter p2word( size ); 559762Speter p2word( alignment ); 560762Speter # ifdef DEBUG 561762Speter if ( opt( 'k' ) ) { 5622474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" 563762Speter , p2opnames[ op ] , op , type , size , alignment ); 564762Speter } 565762Speter # endif 566762Speter } 567762Speter 568762Speter /* 569762Speter * the string names of p2ops 570762Speter */ 571762Speter char *p2opnames[] = { 572762Speter "", 573762Speter "P2UNDEFINED", /* 1 */ 574762Speter "P2NAME", /* 2 */ 575762Speter "P2STRING", /* 3 */ 576762Speter "P2ICON", /* 4 */ 577762Speter "P2FCON", /* 5 */ 578762Speter "P2PLUS", /* 6 */ 579762Speter "", 580762Speter "P2MINUS", /* 8 also unary == P2NEG */ 581762Speter "", 582762Speter "P2NEG", 583762Speter "P2MUL", /* 11 also unary == P2INDIRECT */ 584762Speter "", 585762Speter "P2INDIRECT", 586762Speter "P2AND", /* 14 also unary == P2ADDROF */ 587762Speter "", 588762Speter "P2ADDROF", 589762Speter "P2OR", /* 17 */ 590762Speter "", 591762Speter "P2ER", /* 19 */ 592762Speter "", 593762Speter "P2QUEST", /* 21 */ 594762Speter "P2COLON", /* 22 */ 595762Speter "P2ANDAND", /* 23 */ 596762Speter "P2OROR", /* 24 */ 597762Speter "", /* 25 */ 598762Speter "", /* 26 */ 599762Speter "", /* 27 */ 600762Speter "", /* 28 */ 601762Speter "", /* 29 */ 602762Speter "", /* 30 */ 603762Speter "", /* 31 */ 604762Speter "", /* 32 */ 605762Speter "", /* 33 */ 606762Speter "", /* 34 */ 607762Speter "", /* 35 */ 608762Speter "", /* 36 */ 609762Speter "", /* 37 */ 610762Speter "", /* 38 */ 611762Speter "", /* 39 */ 612762Speter "", /* 40 */ 613762Speter "", /* 41 */ 614762Speter "", /* 42 */ 615762Speter "", /* 43 */ 616762Speter "", /* 44 */ 617762Speter "", /* 45 */ 618762Speter "", /* 46 */ 619762Speter "", /* 47 */ 620762Speter "", /* 48 */ 621762Speter "", /* 49 */ 622762Speter "", /* 50 */ 623762Speter "", /* 51 */ 624762Speter "", /* 52 */ 625762Speter "", /* 53 */ 626762Speter "", /* 54 */ 627762Speter "", /* 55 */ 628762Speter "P2LISTOP", /* 56 */ 629762Speter "", 630762Speter "P2ASSIGN", /* 58 */ 631762Speter "P2COMOP", /* 59 */ 632762Speter "P2DIV", /* 60 */ 633762Speter "", 634762Speter "P2MOD", /* 62 */ 635762Speter "", 636762Speter "P2LS", /* 64 */ 637762Speter "", 638762Speter "P2RS", /* 66 */ 639762Speter "", 640762Speter "P2DOT", /* 68 */ 641762Speter "P2STREF", /* 69 */ 642762Speter "P2CALL", /* 70 also unary */ 643762Speter "", 644762Speter "P2UNARYCALL", 645762Speter "P2FORTCALL", /* 73 also unary */ 646762Speter "", 647762Speter "P2UNARYFORTCALL", 648762Speter "P2NOT", /* 76 */ 649762Speter "P2COMPL", /* 77 */ 650762Speter "P2INCR", /* 78 */ 651762Speter "P2DECR", /* 79 */ 652762Speter "P2EQ", /* 80 */ 653762Speter "P2NE", /* 81 */ 654762Speter "P2LE", /* 82 */ 655762Speter "P2LT", /* 83 */ 656762Speter "P2GE", /* 84 */ 657762Speter "P2GT", /* 85 */ 658762Speter "P2ULE", /* 86 */ 659762Speter "P2ULT", /* 87 */ 660762Speter "P2UGE", /* 88 */ 661762Speter "P2UGT", /* 89 */ 662762Speter "P2SETBIT", /* 90 */ 663762Speter "P2TESTBIT", /* 91 */ 664762Speter "P2RESETBIT", /* 92 */ 665762Speter "P2ARS", /* 93 */ 666762Speter "P2REG", /* 94 */ 667762Speter "P2OREG", /* 95 */ 668762Speter "P2CCODES", /* 96 */ 669762Speter "P2FREE", /* 97 */ 670762Speter "P2STASG", /* 98 */ 671762Speter "P2STARG", /* 99 */ 672762Speter "P2STCALL", /* 100 also unary */ 673762Speter "", 674762Speter "P2UNARYSTCALL", 675762Speter "P2FLD", /* 103 */ 676762Speter "P2SCONV", /* 104 */ 677762Speter "P2PCONV", /* 105 */ 678762Speter "P2PMCONV", /* 106 */ 679762Speter "P2PVCONV", /* 107 */ 680762Speter "P2FORCE", /* 108 */ 681762Speter "P2CBRANCH", /* 109 */ 682762Speter "P2INIT", /* 110 */ 683762Speter "P2CAST", /* 111 */ 684762Speter }; 685762Speter 686762Speter /* 687762Speter * low level routines 688762Speter */ 689762Speter 690762Speter /* 691762Speter * puts a long word on the pcstream 692762Speter */ 693762Speter p2word( word ) 694*15953Smckusick int word; 695762Speter { 696762Speter 697762Speter putw( word , pcstream ); 698762Speter } 699762Speter 700762Speter /* 701762Speter * put a length 0 mod 4 null padded string onto the pcstream 702762Speter */ 703762Speter p2string( string ) 704762Speter char *string; 705762Speter { 706762Speter int slen = strlen( string ); 707762Speter int wlen = ( slen + 3 ) / 4; 708762Speter int plen = ( wlen * 4 ) - slen; 709762Speter char *cp; 710762Speter int p; 711762Speter 712762Speter for ( cp = string ; *cp ; cp++ ) 713762Speter putc( *cp , pcstream ); 714762Speter for ( p = 1 ; p <= plen ; p++ ) 715762Speter putc( '\0' , pcstream ); 716762Speter # ifdef DEBUG 717762Speter if ( opt( 'k' ) ) { 718762Speter fprintf( stdout , "\"%s" , string ); 719762Speter for ( p = 1 ; p <= plen ; p++ ) 720762Speter fprintf( stdout , "\\0" ); 721762Speter fprintf( stdout , "\"\n" ); 722762Speter } 723762Speter # endif 724762Speter } 725762Speter 726762Speter /* 727762Speter * puts a name on the pcstream 728762Speter */ 729762Speter p2name( name ) 730762Speter char *name; 731762Speter { 732762Speter int pad; 733762Speter 734762Speter fprintf( pcstream , NAMEFORMAT , name ); 735762Speter pad = strlen( name ) % sizeof (long); 736762Speter for ( ; pad < sizeof (long) ; pad++ ) { 737762Speter putc( '\0' , pcstream ); 738762Speter } 739762Speter # ifdef DEBUG 740762Speter if ( opt( 'k' ) ) { 741762Speter fprintf( stdout , NAMEFORMAT , name ); 742762Speter pad = strlen( name ) % sizeof (long); 743762Speter for ( ; pad < sizeof (long) ; pad++ ) { 744762Speter fprintf( stdout , "\\0" ); 745762Speter } 746762Speter fprintf( stdout , "\n" ); 747762Speter } 748762Speter # endif 749762Speter } 750762Speter 751762Speter /* 752762Speter * put out a jump to a label 753762Speter */ 754762Speter putjbr( label ) 755762Speter long label; 756762Speter { 757762Speter 758762Speter printjbr( LABELPREFIX , label ); 759762Speter } 760762Speter 761762Speter /* 762762Speter * put out a jump to any kind of label 763762Speter */ 764762Speter printjbr( prefix , label ) 765762Speter char *prefix; 766762Speter long label; 767762Speter { 768762Speter 76910653Speter # ifdef vax 77010653Speter putprintf( " jbr " , 1 ); 77110653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 77210653Speter # endif vax 77310653Speter # ifdef mc68000 77410653Speter putprintf( " jra " , 1 ); 77510653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 77610653Speter # endif mc68000 777762Speter } 778762Speter 779762Speter /* 780762Speter * another version of put to catch calls to put 781762Speter */ 782*15953Smckusick /* VARARGS */ 783*15953Smckusick put() 784762Speter { 785762Speter 78610653Speter panic("put()"); 787762Speter } 788762Speter 789762Speter #endif PC 790