1*48116Sbostic /*- 2*48116Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48116Sbostic * All rights reserved. 4*48116Sbostic * 5*48116Sbostic * %sccs.include.redist.c% 622180Sdist */ 7762Speter 815953Smckusick #ifndef lint 9*48116Sbostic static char sccsid[] = "@(#)p2put.c 5.5 (Berkeley) 04/16/91"; 10*48116Sbostic #endif /* not lint */ 1123527Smckusick 12762Speter /* 13762Speter * functions to help pi put out 14762Speter * polish postfix binary portable c compiler intermediate code 15762Speter * thereby becoming the portable pascal compiler 16762Speter */ 17762Speter 18762Speter #include "whoami.h" 19762Speter #ifdef PC 20762Speter #include "0.h" 2110653Speter #include "objfmt.h" 2218462Sralph #include <pcc.h> 23762Speter #include "pc.h" 2410653Speter #include "align.h" 2511329Speter #include "tmps.h" 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; 3718462Sralph p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) ); 38762Speter # ifdef DEBUG 39762Speter if ( opt( 'k' ) ) { 4018462Sralph fprintf( stdout , "PCCF_FTEXT | %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 */ 6015953Smckusick /* 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 */ 8411329Speter putlbracket(ftnno, sizesp) 8511329Speter int ftnno; 8611329Speter struct om *sizesp; 8711329Speter { 8811329Speter int maxtempreg; 8911329Speter int alignedframesize; 90762Speter 9130035Smckusick # if defined(vax) || defined(tahoe) 9211329Speter maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL]; 9330035Smckusick # endif vax || tahoe 9411329Speter # ifdef mc68000 9511329Speter /* 9614906Speter * this is how /lib/f1 wants it. 9711329Speter */ 9814906Speter maxtempreg = (sizesp->curtmps.next_avail[REG_ADDR] << 4) 9914906Speter | (sizesp->curtmps.next_avail[REG_DATA]); 10011329Speter # endif mc68000 10115953Smckusick alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off), 10215953Smckusick (long)(BITSPERBYTE * A_STACK)); 10318462Sralph p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) ); 10411329Speter p2word(alignedframesize); 10511329Speter # ifdef DEBUG 10611329Speter if ( opt( 'k' ) ) { 10718462Sralph fprintf(stdout, "PCCF_FLBRAC | %3d | %d %d\n", 10811329Speter maxtempreg, ftnno, alignedframesize); 10911329Speter } 11011329Speter # endif 11111329Speter } 112762Speter 113762Speter /* 114762Speter * emit a right bracket operator 11514906Speter * which for the binary interface 116762Speter * forces the stack allocate and register mask 117762Speter */ 118762Speter putrbracket( ftnno ) 119762Speter int ftnno; 120762Speter { 121762Speter 12218462Sralph p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) ); 123762Speter # ifdef DEBUG 124762Speter if ( opt( 'k' ) ) { 12518462Sralph fprintf( stdout , "PCCF_FRBRAC | 0 | %d\n" , ftnno ); 126762Speter } 127762Speter # endif 128762Speter } 129762Speter 130762Speter /* 131762Speter * emit an eof operator 132762Speter */ 133762Speter puteof() 134762Speter { 135762Speter 13618462Sralph p2word( PCCF_FEOF ); 137762Speter # ifdef DEBUG 138762Speter if ( opt( 'k' ) ) { 13918462Sralph fprintf( stdout , "PCCF_FEOF\n" ); 140762Speter } 141762Speter # endif 142762Speter } 143762Speter 144762Speter /* 145762Speter * emit a dot operator, 146762Speter * with a source file line number and name 147762Speter * if line is negative, there was an error on that line, but who cares? 148762Speter */ 149762Speter putdot( filename , line ) 150762Speter char *filename; 151762Speter int line; 152762Speter { 153762Speter int length = str4len( filename ); 154762Speter 155762Speter if ( line < 0 ) { 156762Speter line = -line; 157762Speter } 15818462Sralph p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) ); 159762Speter # ifdef DEBUG 160762Speter if ( opt( 'k' ) ) { 16118462Sralph fprintf( stdout , "PCCF_FEXPR | %3d | %d " , length , line ); 162762Speter } 163762Speter # endif 164762Speter p2string( filename ); 165762Speter } 166762Speter 167762Speter /* 168762Speter * put out a leaf node 169762Speter */ 170762Speter putleaf( op , lval , rval , type , name ) 171762Speter int op; 172762Speter int lval; 173762Speter int rval; 174762Speter int type; 175762Speter char *name; 176762Speter { 1773316Speter if ( !CGENNING ) 178762Speter return; 179762Speter switch ( op ) { 180762Speter default: 181762Speter panic( "[putleaf]" ); 18218462Sralph case PCC_ICON: 18318462Sralph p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) ); 184762Speter p2word( lval ); 185762Speter # ifdef DEBUG 186762Speter if ( opt( 'k' ) ) { 18718462Sralph fprintf( stdout , "PCC_ICON | %3d | 0x%x " 188762Speter , name != NIL , type ); 189762Speter fprintf( stdout , "%d\n" , lval ); 190762Speter } 191762Speter # endif 192762Speter if ( name ) 193762Speter p2name( name ); 194762Speter break; 19518462Sralph case PCC_NAME: 19618462Sralph p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) ); 197762Speter if ( lval ) 198762Speter p2word( lval ); 199762Speter # ifdef DEBUG 200762Speter if ( opt( 'k' ) ) { 20118462Sralph fprintf( stdout , "PCC_NAME | %3d | 0x%x " 202762Speter , lval != 0 , type ); 203762Speter if ( lval ) 204762Speter fprintf( stdout , "%d " , lval ); 205762Speter } 206762Speter # endif 207762Speter p2name( name ); 208762Speter break; 20918462Sralph case PCC_REG: 21018462Sralph p2word( PCCM_TRIPLE( PCC_REG , rval , type ) ); 211762Speter # ifdef DEBUG 212762Speter if ( opt( 'k' ) ) { 21318462Sralph fprintf( stdout , "PCC_REG | %3d | 0x%x\n" , 2142474Speter rval , type ); 215762Speter } 216762Speter # endif 217762Speter break; 218762Speter } 219762Speter } 220762Speter 221762Speter /* 222762Speter * rvalues are just lvalues with indirection, except 2233829Speter * special cases for registers and for named globals, 2243829Speter * whose names are their rvalues. 225762Speter */ 2267924Smckusick putRV( name , level , offset , other_flags , type ) 227762Speter char *name; 228762Speter int level; 229762Speter int offset; 2307924Smckusick char other_flags; 231762Speter int type; 232762Speter { 233762Speter char extname[ BUFSIZ ]; 234762Speter char *printname; 235762Speter 2363316Speter if ( !CGENNING ) 237762Speter return; 2387924Smckusick if ( other_flags & NREGVAR ) { 2393829Speter if ( ( offset < 0 ) || ( offset > P2FP ) ) { 2403829Speter panic( "putRV regvar" ); 2413582Speter } 24218462Sralph putleaf( PCC_REG , 0 , offset , type , (char *) 0 ); 2433277Smckusic return; 2443277Smckusic } 24515953Smckusick if ( whereis( offset , other_flags ) == GLOBALVAR ) { 2463829Speter if ( name != 0 ) { 2473829Speter if ( name[0] != '_' ) { 2483829Speter sprintf( extname , EXTFORMAT , name ); 2493829Speter printname = extname; 2503829Speter } else { 2513829Speter printname = name; 2523829Speter } 25318462Sralph putleaf( PCC_NAME , offset , 0 , type , printname ); 2543829Speter return; 255762Speter } else { 2563829Speter panic( "putRV no name" ); 257762Speter } 258762Speter } 2597924Smckusick putLV( name , level , offset , other_flags , type ); 26018462Sralph putop( PCCOM_UNARY PCC_MUL , type ); 261762Speter } 262762Speter 263762Speter /* 264762Speter * put out an lvalue 265762Speter * given a level and offset 266762Speter * special case for 267762Speter * named globals, whose lvalues are just their names as constants. 268762Speter */ 2697924Smckusick putLV( name , level , offset , other_flags , type ) 270762Speter char *name; 271762Speter int level; 272762Speter int offset; 2737924Smckusick char other_flags; 274762Speter int type; 2753277Smckusic { 2763277Smckusic char extname[ BUFSIZ ]; 2773277Smckusic char *printname; 278762Speter 2793316Speter if ( !CGENNING ) 2803277Smckusic return; 2817924Smckusick if ( other_flags & NREGVAR ) { 2823829Speter panic( "putLV regvar" ); 283762Speter } 28415953Smckusick switch ( whereis( offset , other_flags ) ) { 2853829Speter case GLOBALVAR: 2863829Speter if ( ( name != 0 ) ) { 2873829Speter if ( name[0] != '_' ) { 2883829Speter sprintf( extname , EXTFORMAT , name ); 2893829Speter printname = extname; 2903829Speter } else { 2913829Speter printname = name; 2923829Speter } 29318462Sralph putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR ) 2943829Speter , printname ); 2953829Speter return; 2963829Speter } else { 2973829Speter panic( "putLV no name" ); 2983829Speter } 2993277Smckusic case PARAMVAR: 3003277Smckusic if ( level == cbn ) { 30118462Sralph putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3023277Smckusic } else { 30318462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_OFFSET 30418462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3059128Smckusick parts[ level ] |= NONLOCALVAR; 3063277Smckusic } 30718462Sralph putleaf( PCC_ICON , offset , 0 , PCCT_INT , (char *) 0 ); 30818462Sralph putop( PCC_PLUS , PCCTM_PTR | PCCT_CHAR ); 3093277Smckusic break; 3103277Smckusic case LOCALVAR: 3113277Smckusic if ( level == cbn ) { 31218462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3133277Smckusic } else { 31418462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 31518462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3169128Smckusick parts[ level ] |= NONLOCALVAR; 3173277Smckusic } 31818462Sralph putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 ); 31918462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3203277Smckusic break; 3219128Smckusick case NAMEDLOCALVAR: 3229128Smckusick if ( level == cbn ) { 32318462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3249128Smckusick } else { 32518462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 32618462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3279128Smckusick parts[ level ] |= NONLOCALVAR; 3289128Smckusick } 32918462Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name ); 33018462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3319128Smckusick break; 3323277Smckusic } 3333277Smckusic return; 3343277Smckusic } 335762Speter 336762Speter /* 337762Speter * put out a floating point constant leaf node 338762Speter * the constant is declared in aligned data space 33918462Sralph * and a PCC_NAME leaf put out for it 340762Speter */ 3417924Smckusick putCON8( val ) 3427924Smckusick double val; 343762Speter { 34415953Smckusick char *label; 345762Speter char name[ BUFSIZ ]; 346762Speter 3473316Speter if ( !CGENNING ) 348762Speter return; 34910653Speter label = getlab(); 350762Speter putprintf( " .data" , 0 ); 35110653Speter aligndot(A_DOUBLE); 35215953Smckusick (void) putlab( label ); 35330035Smckusick # if defined(vax) || defined(tahoe) 35410653Speter putprintf( " .double 0d%.20e" , 0 , val ); 35530035Smckusick # endif vax || tahoe 35610653Speter # ifdef mc68000 35710653Speter putprintf( " .long 0x%x,0x%x", 0, val); 35810653Speter # endif mc68000 359762Speter putprintf( " .text" , 0 ); 360762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 36118462Sralph putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name ); 362762Speter } 363762Speter 364762Speter /* 365762Speter * put out either an lvalue or an rvalue for a constant string. 366762Speter * an lvalue (for assignment rhs's) is the name as a constant, 367762Speter * an rvalue (for parameters) is just the name. 368762Speter */ 369762Speter putCONG( string , length , required ) 370762Speter char *string; 371762Speter int length; 372762Speter int required; 373762Speter { 374762Speter char name[ BUFSIZ ]; 37515953Smckusick char *label; 376762Speter char *cp; 377762Speter int pad; 378762Speter int others; 379762Speter 3803316Speter if ( !CGENNING ) 381762Speter return; 382762Speter putprintf( " .data" , 0 ); 38310653Speter aligndot(A_STRUCT); 384762Speter label = getlab(); 38515953Smckusick (void) putlab( label ); 386762Speter cp = string; 387762Speter while ( *cp ) { 388762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 389762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 390762Speter putprintf( ",0%o" , 1 , *cp++ ); 391762Speter } 392762Speter putprintf( "" , 0 ); 393762Speter } 394762Speter pad = length - strlen( string ); 395762Speter while ( pad-- > 0 ) { 396762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 397762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 398762Speter putprintf( ",0%o" , 1 , ' ' ); 399762Speter } 400762Speter putprintf( "" , 0 ); 401762Speter } 402762Speter putprintf( " .byte 0" , 0 ); 403762Speter putprintf( " .text" , 0 ); 404762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 405762Speter if ( required == RREQ ) { 40618462Sralph putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name ); 407762Speter } else { 40818462Sralph putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name ); 409762Speter } 410762Speter } 411762Speter 412762Speter /* 413762Speter * map a pascal type to a c type 414762Speter * this would be tail recursive, but i unfolded it into a for (;;). 415762Speter * this is sort of like isa and lwidth 416762Speter * a note on the types used by the portable c compiler: 417762Speter * they are divided into a basic type (char, short, int, long, etc.) 418762Speter * and qualifications on those basic types (pointer, function, array). 419762Speter * the basic type is kept in the low 4 bits of the type descriptor, 420762Speter * and the qualifications are arranged in two bit chunks, with the 421762Speter * most significant on the right, 422762Speter * and the least significant on the left 423762Speter * e.g. int *foo(); 424762Speter * (a function returning a pointer to an integer) 425762Speter * is stored as 426762Speter * <ptr><ftn><int> 427762Speter * so, we build types recursively 4281478Speter * also, we know that /lib/f1 can only deal with 6 qualifications 4291478Speter * so we stop the recursion there. this stops infinite type recursion 4301478Speter * through mutually recursive pointer types. 431762Speter */ 4321478Speter #define MAXQUALS 6 433762Speter int 434762Speter p2type( np ) 43515953Smckusick struct nl *np; 4361478Speter { 4371478Speter 4381478Speter return typerecur( np , 0 ); 4391478Speter } 4401478Speter typerecur( np , quals ) 4411478Speter struct nl *np; 4421478Speter int quals; 443762Speter { 444762Speter 4451478Speter if ( np == NIL || quals > MAXQUALS ) { 44618462Sralph return PCCT_UNDEF; 4471478Speter } 448762Speter switch ( np -> class ) { 449762Speter case SCAL : 450762Speter case RANGE : 45115974Smckusick case CRANGE : 452762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 45318462Sralph return PCCT_DOUBLE; 454762Speter } 455762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 456762Speter case 1: 45718462Sralph return PCCT_CHAR; 458762Speter case 2: 45918462Sralph return PCCT_SHORT; 460762Speter case 4: 46118462Sralph return PCCT_INT; 462762Speter default: 463762Speter panic( "p2type int" ); 46415953Smckusick /* NOTREACHED */ 465762Speter } 466762Speter case STR : 46718462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 468762Speter case RECORD : 469762Speter case SET : 47018462Sralph return PCCT_STRTY; 471762Speter case FILET : 47218462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 473762Speter case CONST : 474762Speter case VAR : 475762Speter case FIELD : 476762Speter return p2type( np -> type ); 477762Speter case TYPE : 478762Speter switch ( nloff( np ) ) { 479762Speter case TNIL : 48018462Sralph return ( PCCTM_PTR | PCCT_UNDEF ); 481762Speter case TSTR : 48218462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 483762Speter case TSET : 48418462Sralph return PCCT_STRTY; 485762Speter default : 486762Speter return ( p2type( np -> type ) ); 487762Speter } 488762Speter case REF: 489762Speter case WITHPTR: 490762Speter case PTR : 49118462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR ); 492762Speter case ARRAY : 49318462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY ); 494762Speter case FUNC : 495762Speter /* 496762Speter * functions are really pointers to functions 497762Speter * which return their underlying type. 498762Speter */ 49918462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) , 50018462Sralph PCCTM_FTN ) , PCCTM_PTR ); 501762Speter case PROC : 502762Speter /* 503762Speter * procedures are pointers to functions 504762Speter * which return integers (whether you look at them or not) 505762Speter */ 50618462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR ); 5071197Speter case FFUNC : 5081197Speter case FPROC : 5091197Speter /* 5101197Speter * formal procedures and functions are pointers 5111197Speter * to structures which describe their environment. 5121197Speter */ 51318462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 514762Speter default : 515762Speter panic( "p2type" ); 51615953Smckusick /* NOTREACHED */ 517762Speter } 518762Speter } 519762Speter 520762Speter /* 521762Speter * put a typed operator to the pcstream 522762Speter */ 523762Speter putop( op , type ) 524762Speter int op; 525762Speter int type; 526762Speter { 52718462Sralph extern char *p2opname(); 528762Speter 5293316Speter if ( !CGENNING ) 530762Speter return; 53118462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 532762Speter # ifdef DEBUG 533762Speter if ( opt( 'k' ) ) { 5342474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x\n" 53518462Sralph , p2opname( op ) , op , type ); 536762Speter } 537762Speter # endif 538762Speter } 539762Speter 540762Speter /* 541762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 542762Speter * which looks just like a regular operator, only the size and 543762Speter * alignment go in the next consecutive words 544762Speter */ 545762Speter putstrop( op , type , size , alignment ) 546762Speter int op; 547762Speter int type; 548762Speter int size; 549762Speter int alignment; 550762Speter { 55118462Sralph extern char *p2opname(); 552762Speter 5533316Speter if ( !CGENNING ) 554762Speter return; 55518462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 556762Speter p2word( size ); 557762Speter p2word( alignment ); 558762Speter # ifdef DEBUG 559762Speter if ( opt( 'k' ) ) { 5602474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" 56118462Sralph , p2opname( op ) , op , type , size , alignment ); 562762Speter } 563762Speter # endif 564762Speter } 565762Speter 566762Speter /* 567762Speter * the string names of p2ops 568762Speter */ 56918462Sralph 57018462Sralph struct p2op { 57118462Sralph int op; 57218462Sralph char *name; 57318462Sralph }; 57418462Sralph 57518462Sralph static struct p2op p2opnames[] = { 57618462Sralph PCC_ERROR, "PCC_ERROR", 57718462Sralph PCC_NAME, "PCC_NAME", 57818462Sralph PCC_STRING, "PCC_STRING", 57918462Sralph PCC_ICON, "PCC_ICON", 58018462Sralph PCC_FCON, "PCC_FCON", 58118462Sralph PCC_PLUS, "PCC_PLUS", 58218462Sralph PCC_MINUS, "PCC_MINUS", 58318462Sralph PCC_UMINUS, "PCC_UMINUS", 58418462Sralph PCC_MUL, "PCC_MUL", 58518462Sralph PCC_DEREF, "PCC_DEREF", 58618462Sralph PCC_AND, "PCC_AND", 58718462Sralph PCC_ADDROF, "PCC_ADDROF", 58818462Sralph PCC_OR, "PCC_OR", 58918462Sralph PCC_ER, "PCC_ER", 59018462Sralph PCC_QUEST, "PCC_QUEST", 59118462Sralph PCC_COLON, "PCC_COLON", 59218462Sralph PCC_ANDAND, "PCC_ANDAND", 59318462Sralph PCC_OROR, "PCC_OROR", 59418462Sralph PCC_CM, "PCC_CM", 59518462Sralph PCC_ASSIGN, "PCC_ASSIGN", 59618462Sralph PCC_COMOP, "PCC_COMOP", 59718462Sralph PCC_DIV, "PCC_DIV", 59818462Sralph PCC_MOD, "PCC_MOD", 59918462Sralph PCC_LS, "PCC_LS", 60018462Sralph PCC_RS, "PCC_RS", 60118462Sralph PCC_DOT, "PCC_DOT", 60218462Sralph PCC_STREF, "PCC_STREF", 60318462Sralph PCC_CALL, "PCC_CALL", 60418462Sralph PCC_UCALL, "PCC_UCALL", 60518462Sralph PCC_FORTCALL, "PCC_FORTCALL", 60618462Sralph PCC_UFORTCALL, "PCC_UFORTCALL", 60718462Sralph PCC_NOT, "PCC_NOT", 60818462Sralph PCC_COMPL, "PCC_COMPL", 60918462Sralph PCC_INCR, "PCC_INCR", 61018462Sralph PCC_DECR, "PCC_DECR", 61118462Sralph PCC_EQ, "PCC_EQ", 61218462Sralph PCC_NE, "PCC_NE", 61318462Sralph PCC_LE, "PCC_LE", 61418462Sralph PCC_LT, "PCC_LT", 61518462Sralph PCC_GE, "PCC_GE", 61618462Sralph PCC_GT, "PCC_GT", 61718462Sralph PCC_ULE, "PCC_ULE", 61818462Sralph PCC_ULT, "PCC_ULT", 61918462Sralph PCC_UGE, "PCC_UGE", 62018462Sralph PCC_UGT, "PCC_UGT", 62118462Sralph PCC_REG, "PCC_REG", 62218462Sralph PCC_OREG, "PCC_OREG", 62318462Sralph PCC_CCODES, "PCC_CCODES", 62418462Sralph PCC_FREE, "PCC_FREE", 62518462Sralph PCC_STASG, "PCC_STASG", 62618462Sralph PCC_STARG, "PCC_STARG", 62718462Sralph PCC_STCALL, "PCC_STCALL", 62818462Sralph PCC_USTCALL, "PCC_USTCALL", 62918462Sralph PCC_FLD, "PCC_FLD", 63018462Sralph PCC_SCONV, "PCC_SCONV", 63118462Sralph PCC_PCONV, "PCC_PCONV", 63218462Sralph PCC_PMCONV, "PCC_PMCONV", 63318462Sralph PCC_PVCONV, "PCC_PVCONV", 63418462Sralph PCC_FORCE, "PCC_FORCE", 63518462Sralph PCC_CBRANCH, "PCC_CBRANCH", 63618462Sralph PCC_INIT, "PCC_INIT", 63718462Sralph PCC_CAST, "PCC_CAST", 63818462Sralph -1, "" 639762Speter }; 64018462Sralph 64118462Sralph char * 64218462Sralph p2opname( op ) 64318462Sralph register int op; 64418462Sralph { 64518462Sralph static char *p2map[PCC_MAXOP+1]; 64618462Sralph static bool mapready = FALSE; 64718462Sralph register struct p2op *pp; 64818462Sralph 64918462Sralph if ( mapready == FALSE ) { 65018462Sralph for ( pp = p2opnames; pp->op >= 0; pp++ ) 65118462Sralph p2map[ pp->op ] = pp->name; 65218462Sralph mapready = TRUE; 65318462Sralph } 65418462Sralph return ( p2map[ op ] ? p2map[ op ] : "unknown" ); 65518462Sralph } 656762Speter 657762Speter /* 658762Speter * low level routines 659762Speter */ 660762Speter 661762Speter /* 662762Speter * puts a long word on the pcstream 663762Speter */ 664762Speter p2word( word ) 66515953Smckusick int word; 666762Speter { 667762Speter 668762Speter putw( word , pcstream ); 669762Speter } 670762Speter 671762Speter /* 672762Speter * put a length 0 mod 4 null padded string onto the pcstream 673762Speter */ 674762Speter p2string( string ) 675762Speter char *string; 676762Speter { 677762Speter int slen = strlen( string ); 678762Speter int wlen = ( slen + 3 ) / 4; 679762Speter int plen = ( wlen * 4 ) - slen; 680762Speter char *cp; 681762Speter int p; 682762Speter 683762Speter for ( cp = string ; *cp ; cp++ ) 684762Speter putc( *cp , pcstream ); 685762Speter for ( p = 1 ; p <= plen ; p++ ) 686762Speter putc( '\0' , pcstream ); 687762Speter # ifdef DEBUG 688762Speter if ( opt( 'k' ) ) { 689762Speter fprintf( stdout , "\"%s" , string ); 690762Speter for ( p = 1 ; p <= plen ; p++ ) 691762Speter fprintf( stdout , "\\0" ); 692762Speter fprintf( stdout , "\"\n" ); 693762Speter } 694762Speter # endif 695762Speter } 696762Speter 697762Speter /* 698762Speter * puts a name on the pcstream 699762Speter */ 700762Speter p2name( name ) 701762Speter char *name; 702762Speter { 703762Speter int pad; 704762Speter 705762Speter fprintf( pcstream , NAMEFORMAT , name ); 706762Speter pad = strlen( name ) % sizeof (long); 707762Speter for ( ; pad < sizeof (long) ; pad++ ) { 708762Speter putc( '\0' , pcstream ); 709762Speter } 710762Speter # ifdef DEBUG 711762Speter if ( opt( 'k' ) ) { 712762Speter fprintf( stdout , NAMEFORMAT , name ); 713762Speter pad = strlen( name ) % sizeof (long); 714762Speter for ( ; pad < sizeof (long) ; pad++ ) { 715762Speter fprintf( stdout , "\\0" ); 716762Speter } 717762Speter fprintf( stdout , "\n" ); 718762Speter } 719762Speter # endif 720762Speter } 721762Speter 722762Speter /* 723762Speter * put out a jump to a label 724762Speter */ 725762Speter putjbr( label ) 726762Speter long label; 727762Speter { 728762Speter 729762Speter printjbr( LABELPREFIX , label ); 730762Speter } 731762Speter 732762Speter /* 733762Speter * put out a jump to any kind of label 734762Speter */ 735762Speter printjbr( prefix , label ) 736762Speter char *prefix; 737762Speter long label; 738762Speter { 739762Speter 74030035Smckusick # if defined(vax) || defined(tahoe) 74110653Speter putprintf( " jbr " , 1 ); 74210653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 74330035Smckusick # endif vax || tahoe 74410653Speter # ifdef mc68000 74510653Speter putprintf( " jra " , 1 ); 74610653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 74710653Speter # endif mc68000 748762Speter } 749762Speter 750762Speter /* 751762Speter * another version of put to catch calls to put 752762Speter */ 75315953Smckusick /* VARARGS */ 75415953Smckusick put() 755762Speter { 756762Speter 75710653Speter panic("put()"); 758762Speter } 759762Speter 760762Speter #endif PC 761