122180Sdist /* 222180Sdist * Copyright (c) 1980 Regents of the University of California. 322180Sdist * All rights reserved. The Berkeley software License Agreement 422180Sdist * specifies the terms and conditions for redistribution. 522180Sdist */ 6762Speter 715953Smckusick #ifndef lint 8*30035Smckusick static char sccsid[] = "@(#)p2put.c 5.4 (Berkeley) 11/12/86"; 923527Smckusick #endif not lint 1023527Smckusick 11762Speter /* 12762Speter * functions to help pi put out 13762Speter * polish postfix binary portable c compiler intermediate code 14762Speter * thereby becoming the portable pascal compiler 15762Speter */ 16762Speter 17762Speter #include "whoami.h" 18762Speter #ifdef PC 19762Speter #include "0.h" 2010653Speter #include "objfmt.h" 2118462Sralph #include <pcc.h> 22762Speter #include "pc.h" 2310653Speter #include "align.h" 2411329Speter #include "tmps.h" 25762Speter 26762Speter /* 27762Speter * emits an ftext operator and a string to the pcstream 28762Speter */ 29762Speter puttext( string ) 30762Speter char *string; 31762Speter { 32762Speter int length = str4len( string ); 33762Speter 343316Speter if ( !CGENNING ) 35762Speter return; 3618462Sralph p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) ); 37762Speter # ifdef DEBUG 38762Speter if ( opt( 'k' ) ) { 3918462Sralph fprintf( stdout , "PCCF_FTEXT | %3d | 0 " , length ); 40762Speter } 41762Speter # endif 42762Speter p2string( string ); 43762Speter } 44762Speter 45762Speter int 46762Speter str4len( string ) 47762Speter char *string; 48762Speter { 49762Speter 50762Speter return ( ( strlen( string ) + 3 ) / 4 ); 51762Speter } 52762Speter 53762Speter /* 54762Speter * put formatted text into a buffer for printing to the pcstream. 55762Speter * a call to putpflush actually puts out the text. 56762Speter * none of arg1 .. arg5 need be present. 57762Speter * and you can add more if you need them. 58762Speter */ 5915953Smckusick /* VARARGS */ 60762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 ) 61762Speter char *format; 62762Speter int incomplete; 63762Speter { 64762Speter static char ppbuffer[ BUFSIZ ]; 65762Speter static char *ppbufp = ppbuffer; 66762Speter 673316Speter if ( !CGENNING ) 68762Speter return; 69762Speter sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 ); 70762Speter ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] ); 71762Speter if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) ) 72762Speter panic( "putprintf" ); 73762Speter if ( ! incomplete ) { 74762Speter puttext( ppbuffer ); 75762Speter ppbufp = ppbuffer; 76762Speter } 77762Speter } 78762Speter 79762Speter /* 80762Speter * emit a left bracket operator to pcstream 81762Speter * with function number, the maximum temp register, and total local bytes 82762Speter */ 8311329Speter putlbracket(ftnno, sizesp) 8411329Speter int ftnno; 8511329Speter struct om *sizesp; 8611329Speter { 8711329Speter int maxtempreg; 8811329Speter int alignedframesize; 89762Speter 90*30035Smckusick # if defined(vax) || defined(tahoe) 9111329Speter maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL]; 92*30035Smckusick # endif vax || tahoe 9311329Speter # ifdef mc68000 9411329Speter /* 9514906Speter * this is how /lib/f1 wants it. 9611329Speter */ 9714906Speter maxtempreg = (sizesp->curtmps.next_avail[REG_ADDR] << 4) 9814906Speter | (sizesp->curtmps.next_avail[REG_DATA]); 9911329Speter # endif mc68000 10015953Smckusick alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off), 10115953Smckusick (long)(BITSPERBYTE * A_STACK)); 10218462Sralph p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) ); 10311329Speter p2word(alignedframesize); 10411329Speter # ifdef DEBUG 10511329Speter if ( opt( 'k' ) ) { 10618462Sralph fprintf(stdout, "PCCF_FLBRAC | %3d | %d %d\n", 10711329Speter maxtempreg, ftnno, alignedframesize); 10811329Speter } 10911329Speter # endif 11011329Speter } 111762Speter 112762Speter /* 113762Speter * emit a right bracket operator 11414906Speter * which for the binary interface 115762Speter * forces the stack allocate and register mask 116762Speter */ 117762Speter putrbracket( ftnno ) 118762Speter int ftnno; 119762Speter { 120762Speter 12118462Sralph p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) ); 122762Speter # ifdef DEBUG 123762Speter if ( opt( 'k' ) ) { 12418462Sralph fprintf( stdout , "PCCF_FRBRAC | 0 | %d\n" , ftnno ); 125762Speter } 126762Speter # endif 127762Speter } 128762Speter 129762Speter /* 130762Speter * emit an eof operator 131762Speter */ 132762Speter puteof() 133762Speter { 134762Speter 13518462Sralph p2word( PCCF_FEOF ); 136762Speter # ifdef DEBUG 137762Speter if ( opt( 'k' ) ) { 13818462Sralph fprintf( stdout , "PCCF_FEOF\n" ); 139762Speter } 140762Speter # endif 141762Speter } 142762Speter 143762Speter /* 144762Speter * emit a dot operator, 145762Speter * with a source file line number and name 146762Speter * if line is negative, there was an error on that line, but who cares? 147762Speter */ 148762Speter putdot( filename , line ) 149762Speter char *filename; 150762Speter int line; 151762Speter { 152762Speter int length = str4len( filename ); 153762Speter 154762Speter if ( line < 0 ) { 155762Speter line = -line; 156762Speter } 15718462Sralph p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) ); 158762Speter # ifdef DEBUG 159762Speter if ( opt( 'k' ) ) { 16018462Sralph fprintf( stdout , "PCCF_FEXPR | %3d | %d " , length , line ); 161762Speter } 162762Speter # endif 163762Speter p2string( filename ); 164762Speter } 165762Speter 166762Speter /* 167762Speter * put out a leaf node 168762Speter */ 169762Speter putleaf( op , lval , rval , type , name ) 170762Speter int op; 171762Speter int lval; 172762Speter int rval; 173762Speter int type; 174762Speter char *name; 175762Speter { 1763316Speter if ( !CGENNING ) 177762Speter return; 178762Speter switch ( op ) { 179762Speter default: 180762Speter panic( "[putleaf]" ); 18118462Sralph case PCC_ICON: 18218462Sralph p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) ); 183762Speter p2word( lval ); 184762Speter # ifdef DEBUG 185762Speter if ( opt( 'k' ) ) { 18618462Sralph fprintf( stdout , "PCC_ICON | %3d | 0x%x " 187762Speter , name != NIL , type ); 188762Speter fprintf( stdout , "%d\n" , lval ); 189762Speter } 190762Speter # endif 191762Speter if ( name ) 192762Speter p2name( name ); 193762Speter break; 19418462Sralph case PCC_NAME: 19518462Sralph p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) ); 196762Speter if ( lval ) 197762Speter p2word( lval ); 198762Speter # ifdef DEBUG 199762Speter if ( opt( 'k' ) ) { 20018462Sralph fprintf( stdout , "PCC_NAME | %3d | 0x%x " 201762Speter , lval != 0 , type ); 202762Speter if ( lval ) 203762Speter fprintf( stdout , "%d " , lval ); 204762Speter } 205762Speter # endif 206762Speter p2name( name ); 207762Speter break; 20818462Sralph case PCC_REG: 20918462Sralph p2word( PCCM_TRIPLE( PCC_REG , rval , type ) ); 210762Speter # ifdef DEBUG 211762Speter if ( opt( 'k' ) ) { 21218462Sralph fprintf( stdout , "PCC_REG | %3d | 0x%x\n" , 2132474Speter rval , type ); 214762Speter } 215762Speter # endif 216762Speter break; 217762Speter } 218762Speter } 219762Speter 220762Speter /* 221762Speter * rvalues are just lvalues with indirection, except 2223829Speter * special cases for registers and for named globals, 2233829Speter * whose names are their rvalues. 224762Speter */ 2257924Smckusick putRV( name , level , offset , other_flags , type ) 226762Speter char *name; 227762Speter int level; 228762Speter int offset; 2297924Smckusick char other_flags; 230762Speter int type; 231762Speter { 232762Speter char extname[ BUFSIZ ]; 233762Speter char *printname; 234762Speter 2353316Speter if ( !CGENNING ) 236762Speter return; 2377924Smckusick if ( other_flags & NREGVAR ) { 2383829Speter if ( ( offset < 0 ) || ( offset > P2FP ) ) { 2393829Speter panic( "putRV regvar" ); 2403582Speter } 24118462Sralph putleaf( PCC_REG , 0 , offset , type , (char *) 0 ); 2423277Smckusic return; 2433277Smckusic } 24415953Smckusick if ( whereis( offset , other_flags ) == GLOBALVAR ) { 2453829Speter if ( name != 0 ) { 2463829Speter if ( name[0] != '_' ) { 2473829Speter sprintf( extname , EXTFORMAT , name ); 2483829Speter printname = extname; 2493829Speter } else { 2503829Speter printname = name; 2513829Speter } 25218462Sralph putleaf( PCC_NAME , offset , 0 , type , printname ); 2533829Speter return; 254762Speter } else { 2553829Speter panic( "putRV no name" ); 256762Speter } 257762Speter } 2587924Smckusick putLV( name , level , offset , other_flags , type ); 25918462Sralph putop( PCCOM_UNARY PCC_MUL , type ); 260762Speter } 261762Speter 262762Speter /* 263762Speter * put out an lvalue 264762Speter * given a level and offset 265762Speter * special case for 266762Speter * named globals, whose lvalues are just their names as constants. 267762Speter */ 2687924Smckusick putLV( name , level , offset , other_flags , type ) 269762Speter char *name; 270762Speter int level; 271762Speter int offset; 2727924Smckusick char other_flags; 273762Speter int type; 2743277Smckusic { 2753277Smckusic char extname[ BUFSIZ ]; 2763277Smckusic char *printname; 277762Speter 2783316Speter if ( !CGENNING ) 2793277Smckusic return; 2807924Smckusick if ( other_flags & NREGVAR ) { 2813829Speter panic( "putLV regvar" ); 282762Speter } 28315953Smckusick switch ( whereis( offset , other_flags ) ) { 2843829Speter case GLOBALVAR: 2853829Speter if ( ( name != 0 ) ) { 2863829Speter if ( name[0] != '_' ) { 2873829Speter sprintf( extname , EXTFORMAT , name ); 2883829Speter printname = extname; 2893829Speter } else { 2903829Speter printname = name; 2913829Speter } 29218462Sralph putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR ) 2933829Speter , printname ); 2943829Speter return; 2953829Speter } else { 2963829Speter panic( "putLV no name" ); 2973829Speter } 2983277Smckusic case PARAMVAR: 2993277Smckusic if ( level == cbn ) { 30018462Sralph putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3013277Smckusic } else { 30218462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_OFFSET 30318462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3049128Smckusick parts[ level ] |= NONLOCALVAR; 3053277Smckusic } 30618462Sralph putleaf( PCC_ICON , offset , 0 , PCCT_INT , (char *) 0 ); 30718462Sralph putop( PCC_PLUS , PCCTM_PTR | PCCT_CHAR ); 3083277Smckusic break; 3093277Smckusic case LOCALVAR: 3103277Smckusic if ( level == cbn ) { 31118462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3123277Smckusic } else { 31318462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 31418462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3159128Smckusick parts[ level ] |= NONLOCALVAR; 3163277Smckusic } 31718462Sralph putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 ); 31818462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3193277Smckusic break; 3209128Smckusick case NAMEDLOCALVAR: 3219128Smckusick if ( level == cbn ) { 32218462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3239128Smckusick } else { 32418462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 32518462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3269128Smckusick parts[ level ] |= NONLOCALVAR; 3279128Smckusick } 32818462Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name ); 32918462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3309128Smckusick break; 3313277Smckusic } 3323277Smckusic return; 3333277Smckusic } 334762Speter 335762Speter /* 336762Speter * put out a floating point constant leaf node 337762Speter * the constant is declared in aligned data space 33818462Sralph * and a PCC_NAME leaf put out for it 339762Speter */ 3407924Smckusick putCON8( val ) 3417924Smckusick double val; 342762Speter { 34315953Smckusick char *label; 344762Speter char name[ BUFSIZ ]; 345762Speter 3463316Speter if ( !CGENNING ) 347762Speter return; 34810653Speter label = getlab(); 349762Speter putprintf( " .data" , 0 ); 35010653Speter aligndot(A_DOUBLE); 35115953Smckusick (void) putlab( label ); 352*30035Smckusick # if defined(vax) || defined(tahoe) 35310653Speter putprintf( " .double 0d%.20e" , 0 , val ); 354*30035Smckusick # endif vax || tahoe 35510653Speter # ifdef mc68000 35610653Speter putprintf( " .long 0x%x,0x%x", 0, val); 35710653Speter # endif mc68000 358762Speter putprintf( " .text" , 0 ); 359762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 36018462Sralph putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name ); 361762Speter } 362762Speter 363762Speter /* 364762Speter * put out either an lvalue or an rvalue for a constant string. 365762Speter * an lvalue (for assignment rhs's) is the name as a constant, 366762Speter * an rvalue (for parameters) is just the name. 367762Speter */ 368762Speter putCONG( string , length , required ) 369762Speter char *string; 370762Speter int length; 371762Speter int required; 372762Speter { 373762Speter char name[ BUFSIZ ]; 37415953Smckusick char *label; 375762Speter char *cp; 376762Speter int pad; 377762Speter int others; 378762Speter 3793316Speter if ( !CGENNING ) 380762Speter return; 381762Speter putprintf( " .data" , 0 ); 38210653Speter aligndot(A_STRUCT); 383762Speter label = getlab(); 38415953Smckusick (void) putlab( label ); 385762Speter cp = string; 386762Speter while ( *cp ) { 387762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 388762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 389762Speter putprintf( ",0%o" , 1 , *cp++ ); 390762Speter } 391762Speter putprintf( "" , 0 ); 392762Speter } 393762Speter pad = length - strlen( string ); 394762Speter while ( pad-- > 0 ) { 395762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 396762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 397762Speter putprintf( ",0%o" , 1 , ' ' ); 398762Speter } 399762Speter putprintf( "" , 0 ); 400762Speter } 401762Speter putprintf( " .byte 0" , 0 ); 402762Speter putprintf( " .text" , 0 ); 403762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 404762Speter if ( required == RREQ ) { 40518462Sralph putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name ); 406762Speter } else { 40718462Sralph putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name ); 408762Speter } 409762Speter } 410762Speter 411762Speter /* 412762Speter * map a pascal type to a c type 413762Speter * this would be tail recursive, but i unfolded it into a for (;;). 414762Speter * this is sort of like isa and lwidth 415762Speter * a note on the types used by the portable c compiler: 416762Speter * they are divided into a basic type (char, short, int, long, etc.) 417762Speter * and qualifications on those basic types (pointer, function, array). 418762Speter * the basic type is kept in the low 4 bits of the type descriptor, 419762Speter * and the qualifications are arranged in two bit chunks, with the 420762Speter * most significant on the right, 421762Speter * and the least significant on the left 422762Speter * e.g. int *foo(); 423762Speter * (a function returning a pointer to an integer) 424762Speter * is stored as 425762Speter * <ptr><ftn><int> 426762Speter * so, we build types recursively 4271478Speter * also, we know that /lib/f1 can only deal with 6 qualifications 4281478Speter * so we stop the recursion there. this stops infinite type recursion 4291478Speter * through mutually recursive pointer types. 430762Speter */ 4311478Speter #define MAXQUALS 6 432762Speter int 433762Speter p2type( np ) 43415953Smckusick struct nl *np; 4351478Speter { 4361478Speter 4371478Speter return typerecur( np , 0 ); 4381478Speter } 4391478Speter typerecur( np , quals ) 4401478Speter struct nl *np; 4411478Speter int quals; 442762Speter { 443762Speter 4441478Speter if ( np == NIL || quals > MAXQUALS ) { 44518462Sralph return PCCT_UNDEF; 4461478Speter } 447762Speter switch ( np -> class ) { 448762Speter case SCAL : 449762Speter case RANGE : 45015974Smckusick case CRANGE : 451762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 45218462Sralph return PCCT_DOUBLE; 453762Speter } 454762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 455762Speter case 1: 45618462Sralph return PCCT_CHAR; 457762Speter case 2: 45818462Sralph return PCCT_SHORT; 459762Speter case 4: 46018462Sralph return PCCT_INT; 461762Speter default: 462762Speter panic( "p2type int" ); 46315953Smckusick /* NOTREACHED */ 464762Speter } 465762Speter case STR : 46618462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 467762Speter case RECORD : 468762Speter case SET : 46918462Sralph return PCCT_STRTY; 470762Speter case FILET : 47118462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 472762Speter case CONST : 473762Speter case VAR : 474762Speter case FIELD : 475762Speter return p2type( np -> type ); 476762Speter case TYPE : 477762Speter switch ( nloff( np ) ) { 478762Speter case TNIL : 47918462Sralph return ( PCCTM_PTR | PCCT_UNDEF ); 480762Speter case TSTR : 48118462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 482762Speter case TSET : 48318462Sralph return PCCT_STRTY; 484762Speter default : 485762Speter return ( p2type( np -> type ) ); 486762Speter } 487762Speter case REF: 488762Speter case WITHPTR: 489762Speter case PTR : 49018462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR ); 491762Speter case ARRAY : 49218462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY ); 493762Speter case FUNC : 494762Speter /* 495762Speter * functions are really pointers to functions 496762Speter * which return their underlying type. 497762Speter */ 49818462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) , 49918462Sralph PCCTM_FTN ) , PCCTM_PTR ); 500762Speter case PROC : 501762Speter /* 502762Speter * procedures are pointers to functions 503762Speter * which return integers (whether you look at them or not) 504762Speter */ 50518462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR ); 5061197Speter case FFUNC : 5071197Speter case FPROC : 5081197Speter /* 5091197Speter * formal procedures and functions are pointers 5101197Speter * to structures which describe their environment. 5111197Speter */ 51218462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 513762Speter default : 514762Speter panic( "p2type" ); 51515953Smckusick /* NOTREACHED */ 516762Speter } 517762Speter } 518762Speter 519762Speter /* 520762Speter * put a typed operator to the pcstream 521762Speter */ 522762Speter putop( op , type ) 523762Speter int op; 524762Speter int type; 525762Speter { 52618462Sralph extern char *p2opname(); 527762Speter 5283316Speter if ( !CGENNING ) 529762Speter return; 53018462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 531762Speter # ifdef DEBUG 532762Speter if ( opt( 'k' ) ) { 5332474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x\n" 53418462Sralph , p2opname( op ) , op , type ); 535762Speter } 536762Speter # endif 537762Speter } 538762Speter 539762Speter /* 540762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 541762Speter * which looks just like a regular operator, only the size and 542762Speter * alignment go in the next consecutive words 543762Speter */ 544762Speter putstrop( op , type , size , alignment ) 545762Speter int op; 546762Speter int type; 547762Speter int size; 548762Speter int alignment; 549762Speter { 55018462Sralph extern char *p2opname(); 551762Speter 5523316Speter if ( !CGENNING ) 553762Speter return; 55418462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 555762Speter p2word( size ); 556762Speter p2word( alignment ); 557762Speter # ifdef DEBUG 558762Speter if ( opt( 'k' ) ) { 5592474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" 56018462Sralph , p2opname( op ) , op , type , size , alignment ); 561762Speter } 562762Speter # endif 563762Speter } 564762Speter 565762Speter /* 566762Speter * the string names of p2ops 567762Speter */ 56818462Sralph 56918462Sralph struct p2op { 57018462Sralph int op; 57118462Sralph char *name; 57218462Sralph }; 57318462Sralph 57418462Sralph static struct p2op p2opnames[] = { 57518462Sralph PCC_ERROR, "PCC_ERROR", 57618462Sralph PCC_NAME, "PCC_NAME", 57718462Sralph PCC_STRING, "PCC_STRING", 57818462Sralph PCC_ICON, "PCC_ICON", 57918462Sralph PCC_FCON, "PCC_FCON", 58018462Sralph PCC_PLUS, "PCC_PLUS", 58118462Sralph PCC_MINUS, "PCC_MINUS", 58218462Sralph PCC_UMINUS, "PCC_UMINUS", 58318462Sralph PCC_MUL, "PCC_MUL", 58418462Sralph PCC_DEREF, "PCC_DEREF", 58518462Sralph PCC_AND, "PCC_AND", 58618462Sralph PCC_ADDROF, "PCC_ADDROF", 58718462Sralph PCC_OR, "PCC_OR", 58818462Sralph PCC_ER, "PCC_ER", 58918462Sralph PCC_QUEST, "PCC_QUEST", 59018462Sralph PCC_COLON, "PCC_COLON", 59118462Sralph PCC_ANDAND, "PCC_ANDAND", 59218462Sralph PCC_OROR, "PCC_OROR", 59318462Sralph PCC_CM, "PCC_CM", 59418462Sralph PCC_ASSIGN, "PCC_ASSIGN", 59518462Sralph PCC_COMOP, "PCC_COMOP", 59618462Sralph PCC_DIV, "PCC_DIV", 59718462Sralph PCC_MOD, "PCC_MOD", 59818462Sralph PCC_LS, "PCC_LS", 59918462Sralph PCC_RS, "PCC_RS", 60018462Sralph PCC_DOT, "PCC_DOT", 60118462Sralph PCC_STREF, "PCC_STREF", 60218462Sralph PCC_CALL, "PCC_CALL", 60318462Sralph PCC_UCALL, "PCC_UCALL", 60418462Sralph PCC_FORTCALL, "PCC_FORTCALL", 60518462Sralph PCC_UFORTCALL, "PCC_UFORTCALL", 60618462Sralph PCC_NOT, "PCC_NOT", 60718462Sralph PCC_COMPL, "PCC_COMPL", 60818462Sralph PCC_INCR, "PCC_INCR", 60918462Sralph PCC_DECR, "PCC_DECR", 61018462Sralph PCC_EQ, "PCC_EQ", 61118462Sralph PCC_NE, "PCC_NE", 61218462Sralph PCC_LE, "PCC_LE", 61318462Sralph PCC_LT, "PCC_LT", 61418462Sralph PCC_GE, "PCC_GE", 61518462Sralph PCC_GT, "PCC_GT", 61618462Sralph PCC_ULE, "PCC_ULE", 61718462Sralph PCC_ULT, "PCC_ULT", 61818462Sralph PCC_UGE, "PCC_UGE", 61918462Sralph PCC_UGT, "PCC_UGT", 62018462Sralph PCC_REG, "PCC_REG", 62118462Sralph PCC_OREG, "PCC_OREG", 62218462Sralph PCC_CCODES, "PCC_CCODES", 62318462Sralph PCC_FREE, "PCC_FREE", 62418462Sralph PCC_STASG, "PCC_STASG", 62518462Sralph PCC_STARG, "PCC_STARG", 62618462Sralph PCC_STCALL, "PCC_STCALL", 62718462Sralph PCC_USTCALL, "PCC_USTCALL", 62818462Sralph PCC_FLD, "PCC_FLD", 62918462Sralph PCC_SCONV, "PCC_SCONV", 63018462Sralph PCC_PCONV, "PCC_PCONV", 63118462Sralph PCC_PMCONV, "PCC_PMCONV", 63218462Sralph PCC_PVCONV, "PCC_PVCONV", 63318462Sralph PCC_FORCE, "PCC_FORCE", 63418462Sralph PCC_CBRANCH, "PCC_CBRANCH", 63518462Sralph PCC_INIT, "PCC_INIT", 63618462Sralph PCC_CAST, "PCC_CAST", 63718462Sralph -1, "" 638762Speter }; 63918462Sralph 64018462Sralph char * 64118462Sralph p2opname( op ) 64218462Sralph register int op; 64318462Sralph { 64418462Sralph static char *p2map[PCC_MAXOP+1]; 64518462Sralph static bool mapready = FALSE; 64618462Sralph register struct p2op *pp; 64718462Sralph 64818462Sralph if ( mapready == FALSE ) { 64918462Sralph for ( pp = p2opnames; pp->op >= 0; pp++ ) 65018462Sralph p2map[ pp->op ] = pp->name; 65118462Sralph mapready = TRUE; 65218462Sralph } 65318462Sralph return ( p2map[ op ] ? p2map[ op ] : "unknown" ); 65418462Sralph } 655762Speter 656762Speter /* 657762Speter * low level routines 658762Speter */ 659762Speter 660762Speter /* 661762Speter * puts a long word on the pcstream 662762Speter */ 663762Speter p2word( word ) 66415953Smckusick int word; 665762Speter { 666762Speter 667762Speter putw( word , pcstream ); 668762Speter } 669762Speter 670762Speter /* 671762Speter * put a length 0 mod 4 null padded string onto the pcstream 672762Speter */ 673762Speter p2string( string ) 674762Speter char *string; 675762Speter { 676762Speter int slen = strlen( string ); 677762Speter int wlen = ( slen + 3 ) / 4; 678762Speter int plen = ( wlen * 4 ) - slen; 679762Speter char *cp; 680762Speter int p; 681762Speter 682762Speter for ( cp = string ; *cp ; cp++ ) 683762Speter putc( *cp , pcstream ); 684762Speter for ( p = 1 ; p <= plen ; p++ ) 685762Speter putc( '\0' , pcstream ); 686762Speter # ifdef DEBUG 687762Speter if ( opt( 'k' ) ) { 688762Speter fprintf( stdout , "\"%s" , string ); 689762Speter for ( p = 1 ; p <= plen ; p++ ) 690762Speter fprintf( stdout , "\\0" ); 691762Speter fprintf( stdout , "\"\n" ); 692762Speter } 693762Speter # endif 694762Speter } 695762Speter 696762Speter /* 697762Speter * puts a name on the pcstream 698762Speter */ 699762Speter p2name( name ) 700762Speter char *name; 701762Speter { 702762Speter int pad; 703762Speter 704762Speter fprintf( pcstream , NAMEFORMAT , name ); 705762Speter pad = strlen( name ) % sizeof (long); 706762Speter for ( ; pad < sizeof (long) ; pad++ ) { 707762Speter putc( '\0' , pcstream ); 708762Speter } 709762Speter # ifdef DEBUG 710762Speter if ( opt( 'k' ) ) { 711762Speter fprintf( stdout , NAMEFORMAT , name ); 712762Speter pad = strlen( name ) % sizeof (long); 713762Speter for ( ; pad < sizeof (long) ; pad++ ) { 714762Speter fprintf( stdout , "\\0" ); 715762Speter } 716762Speter fprintf( stdout , "\n" ); 717762Speter } 718762Speter # endif 719762Speter } 720762Speter 721762Speter /* 722762Speter * put out a jump to a label 723762Speter */ 724762Speter putjbr( label ) 725762Speter long label; 726762Speter { 727762Speter 728762Speter printjbr( LABELPREFIX , label ); 729762Speter } 730762Speter 731762Speter /* 732762Speter * put out a jump to any kind of label 733762Speter */ 734762Speter printjbr( prefix , label ) 735762Speter char *prefix; 736762Speter long label; 737762Speter { 738762Speter 739*30035Smckusick # if defined(vax) || defined(tahoe) 74010653Speter putprintf( " jbr " , 1 ); 74110653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 742*30035Smckusick # endif vax || tahoe 74310653Speter # ifdef mc68000 74410653Speter putprintf( " jra " , 1 ); 74510653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 74610653Speter # endif mc68000 747762Speter } 748762Speter 749762Speter /* 750762Speter * another version of put to catch calls to put 751762Speter */ 75215953Smckusick /* VARARGS */ 75315953Smckusick put() 754762Speter { 755762Speter 75610653Speter panic("put()"); 757762Speter } 758762Speter 759762Speter #endif PC 760