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*23527Smckusick static char sccsid[] = "@(#)p2put.c 5.2 (Berkeley) 06/18/85"; 9*23527Smckusick #endif not lint 10*23527Smckusick 11*23527Smckusick /* 12*23527Smckusick * Copyright (c) 1980 Regents of the University of California. 13*23527Smckusick * All rights reserved. The Berkeley software License Agreement 14*23527Smckusick * specifies the terms and conditions for redistribution. 15*23527Smckusick */ 16*23527Smckusick 17*23527Smckusick #ifndef lint 1822180Sdist char copyright[] = 1922180Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 2022180Sdist All rights reserved.\n"; 2122180Sdist #endif not lint 22762Speter /* 23762Speter * functions to help pi put out 24762Speter * polish postfix binary portable c compiler intermediate code 25762Speter * thereby becoming the portable pascal compiler 26762Speter */ 27762Speter 28762Speter #include "whoami.h" 29762Speter #ifdef PC 30762Speter #include "0.h" 3110653Speter #include "objfmt.h" 3218462Sralph #include <pcc.h> 33762Speter #include "pc.h" 3410653Speter #include "align.h" 3511329Speter #include "tmps.h" 36762Speter 37762Speter /* 38762Speter * emits an ftext operator and a string to the pcstream 39762Speter */ 40762Speter puttext( string ) 41762Speter char *string; 42762Speter { 43762Speter int length = str4len( string ); 44762Speter 453316Speter if ( !CGENNING ) 46762Speter return; 4718462Sralph p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) ); 48762Speter # ifdef DEBUG 49762Speter if ( opt( 'k' ) ) { 5018462Sralph fprintf( stdout , "PCCF_FTEXT | %3d | 0 " , length ); 51762Speter } 52762Speter # endif 53762Speter p2string( string ); 54762Speter } 55762Speter 56762Speter int 57762Speter str4len( string ) 58762Speter char *string; 59762Speter { 60762Speter 61762Speter return ( ( strlen( string ) + 3 ) / 4 ); 62762Speter } 63762Speter 64762Speter /* 65762Speter * put formatted text into a buffer for printing to the pcstream. 66762Speter * a call to putpflush actually puts out the text. 67762Speter * none of arg1 .. arg5 need be present. 68762Speter * and you can add more if you need them. 69762Speter */ 7015953Smckusick /* VARARGS */ 71762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 ) 72762Speter char *format; 73762Speter int incomplete; 74762Speter { 75762Speter static char ppbuffer[ BUFSIZ ]; 76762Speter static char *ppbufp = ppbuffer; 77762Speter 783316Speter if ( !CGENNING ) 79762Speter return; 80762Speter sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 ); 81762Speter ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] ); 82762Speter if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) ) 83762Speter panic( "putprintf" ); 84762Speter if ( ! incomplete ) { 85762Speter puttext( ppbuffer ); 86762Speter ppbufp = ppbuffer; 87762Speter } 88762Speter } 89762Speter 90762Speter /* 91762Speter * emit a left bracket operator to pcstream 92762Speter * with function number, the maximum temp register, and total local bytes 93762Speter */ 9411329Speter putlbracket(ftnno, sizesp) 9511329Speter int ftnno; 9611329Speter struct om *sizesp; 9711329Speter { 9811329Speter int maxtempreg; 9911329Speter int alignedframesize; 100762Speter 10111329Speter # ifdef vax 10211329Speter maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL]; 10311329Speter # endif vax 10411329Speter # ifdef mc68000 10511329Speter /* 10614906Speter * this is how /lib/f1 wants it. 10711329Speter */ 10814906Speter maxtempreg = (sizesp->curtmps.next_avail[REG_ADDR] << 4) 10914906Speter | (sizesp->curtmps.next_avail[REG_DATA]); 11011329Speter # endif mc68000 11115953Smckusick alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off), 11215953Smckusick (long)(BITSPERBYTE * A_STACK)); 11318462Sralph p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) ); 11411329Speter p2word(alignedframesize); 11511329Speter # ifdef DEBUG 11611329Speter if ( opt( 'k' ) ) { 11718462Sralph fprintf(stdout, "PCCF_FLBRAC | %3d | %d %d\n", 11811329Speter maxtempreg, ftnno, alignedframesize); 11911329Speter } 12011329Speter # endif 12111329Speter } 122762Speter 123762Speter /* 124762Speter * emit a right bracket operator 12514906Speter * which for the binary interface 126762Speter * forces the stack allocate and register mask 127762Speter */ 128762Speter putrbracket( ftnno ) 129762Speter int ftnno; 130762Speter { 131762Speter 13218462Sralph p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) ); 133762Speter # ifdef DEBUG 134762Speter if ( opt( 'k' ) ) { 13518462Sralph fprintf( stdout , "PCCF_FRBRAC | 0 | %d\n" , ftnno ); 136762Speter } 137762Speter # endif 138762Speter } 139762Speter 140762Speter /* 141762Speter * emit an eof operator 142762Speter */ 143762Speter puteof() 144762Speter { 145762Speter 14618462Sralph p2word( PCCF_FEOF ); 147762Speter # ifdef DEBUG 148762Speter if ( opt( 'k' ) ) { 14918462Sralph fprintf( stdout , "PCCF_FEOF\n" ); 150762Speter } 151762Speter # endif 152762Speter } 153762Speter 154762Speter /* 155762Speter * emit a dot operator, 156762Speter * with a source file line number and name 157762Speter * if line is negative, there was an error on that line, but who cares? 158762Speter */ 159762Speter putdot( filename , line ) 160762Speter char *filename; 161762Speter int line; 162762Speter { 163762Speter int length = str4len( filename ); 164762Speter 165762Speter if ( line < 0 ) { 166762Speter line = -line; 167762Speter } 16818462Sralph p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) ); 169762Speter # ifdef DEBUG 170762Speter if ( opt( 'k' ) ) { 17118462Sralph fprintf( stdout , "PCCF_FEXPR | %3d | %d " , length , line ); 172762Speter } 173762Speter # endif 174762Speter p2string( filename ); 175762Speter } 176762Speter 177762Speter /* 178762Speter * put out a leaf node 179762Speter */ 180762Speter putleaf( op , lval , rval , type , name ) 181762Speter int op; 182762Speter int lval; 183762Speter int rval; 184762Speter int type; 185762Speter char *name; 186762Speter { 1873316Speter if ( !CGENNING ) 188762Speter return; 189762Speter switch ( op ) { 190762Speter default: 191762Speter panic( "[putleaf]" ); 19218462Sralph case PCC_ICON: 19318462Sralph p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) ); 194762Speter p2word( lval ); 195762Speter # ifdef DEBUG 196762Speter if ( opt( 'k' ) ) { 19718462Sralph fprintf( stdout , "PCC_ICON | %3d | 0x%x " 198762Speter , name != NIL , type ); 199762Speter fprintf( stdout , "%d\n" , lval ); 200762Speter } 201762Speter # endif 202762Speter if ( name ) 203762Speter p2name( name ); 204762Speter break; 20518462Sralph case PCC_NAME: 20618462Sralph p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) ); 207762Speter if ( lval ) 208762Speter p2word( lval ); 209762Speter # ifdef DEBUG 210762Speter if ( opt( 'k' ) ) { 21118462Sralph fprintf( stdout , "PCC_NAME | %3d | 0x%x " 212762Speter , lval != 0 , type ); 213762Speter if ( lval ) 214762Speter fprintf( stdout , "%d " , lval ); 215762Speter } 216762Speter # endif 217762Speter p2name( name ); 218762Speter break; 21918462Sralph case PCC_REG: 22018462Sralph p2word( PCCM_TRIPLE( PCC_REG , rval , type ) ); 221762Speter # ifdef DEBUG 222762Speter if ( opt( 'k' ) ) { 22318462Sralph fprintf( stdout , "PCC_REG | %3d | 0x%x\n" , 2242474Speter rval , type ); 225762Speter } 226762Speter # endif 227762Speter break; 228762Speter } 229762Speter } 230762Speter 231762Speter /* 232762Speter * rvalues are just lvalues with indirection, except 2333829Speter * special cases for registers and for named globals, 2343829Speter * whose names are their rvalues. 235762Speter */ 2367924Smckusick putRV( name , level , offset , other_flags , type ) 237762Speter char *name; 238762Speter int level; 239762Speter int offset; 2407924Smckusick char other_flags; 241762Speter int type; 242762Speter { 243762Speter char extname[ BUFSIZ ]; 244762Speter char *printname; 245762Speter 2463316Speter if ( !CGENNING ) 247762Speter return; 2487924Smckusick if ( other_flags & NREGVAR ) { 2493829Speter if ( ( offset < 0 ) || ( offset > P2FP ) ) { 2503829Speter panic( "putRV regvar" ); 2513582Speter } 25218462Sralph putleaf( PCC_REG , 0 , offset , type , (char *) 0 ); 2533277Smckusic return; 2543277Smckusic } 25515953Smckusick if ( whereis( offset , other_flags ) == GLOBALVAR ) { 2563829Speter if ( name != 0 ) { 2573829Speter if ( name[0] != '_' ) { 2583829Speter sprintf( extname , EXTFORMAT , name ); 2593829Speter printname = extname; 2603829Speter } else { 2613829Speter printname = name; 2623829Speter } 26318462Sralph putleaf( PCC_NAME , offset , 0 , type , printname ); 2643829Speter return; 265762Speter } else { 2663829Speter panic( "putRV no name" ); 267762Speter } 268762Speter } 2697924Smckusick putLV( name , level , offset , other_flags , type ); 27018462Sralph putop( PCCOM_UNARY PCC_MUL , type ); 271762Speter } 272762Speter 273762Speter /* 274762Speter * put out an lvalue 275762Speter * given a level and offset 276762Speter * special case for 277762Speter * named globals, whose lvalues are just their names as constants. 278762Speter */ 2797924Smckusick putLV( name , level , offset , other_flags , type ) 280762Speter char *name; 281762Speter int level; 282762Speter int offset; 2837924Smckusick char other_flags; 284762Speter int type; 2853277Smckusic { 2863277Smckusic char extname[ BUFSIZ ]; 2873277Smckusic char *printname; 288762Speter 2893316Speter if ( !CGENNING ) 2903277Smckusic return; 2917924Smckusick if ( other_flags & NREGVAR ) { 2923829Speter panic( "putLV regvar" ); 293762Speter } 29415953Smckusick switch ( whereis( offset , other_flags ) ) { 2953829Speter case GLOBALVAR: 2963829Speter if ( ( name != 0 ) ) { 2973829Speter if ( name[0] != '_' ) { 2983829Speter sprintf( extname , EXTFORMAT , name ); 2993829Speter printname = extname; 3003829Speter } else { 3013829Speter printname = name; 3023829Speter } 30318462Sralph putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR ) 3043829Speter , printname ); 3053829Speter return; 3063829Speter } else { 3073829Speter panic( "putLV no name" ); 3083829Speter } 3093277Smckusic case PARAMVAR: 3103277Smckusic if ( level == cbn ) { 31118462Sralph putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3123277Smckusic } else { 31318462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_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_PLUS , PCCTM_PTR | PCCT_CHAR ); 3193277Smckusic break; 3203277Smckusic case LOCALVAR: 3213277Smckusic if ( level == cbn ) { 32218462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3233277Smckusic } else { 32418462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 32518462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3269128Smckusick parts[ level ] |= NONLOCALVAR; 3273277Smckusic } 32818462Sralph putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 ); 32918462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3303277Smckusic break; 3319128Smckusick case NAMEDLOCALVAR: 3329128Smckusick if ( level == cbn ) { 33318462Sralph putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 ); 3349128Smckusick } else { 33518462Sralph putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET 33618462Sralph , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME ); 3379128Smckusick parts[ level ] |= NONLOCALVAR; 3389128Smckusick } 33918462Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name ); 34018462Sralph putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR ); 3419128Smckusick break; 3423277Smckusic } 3433277Smckusic return; 3443277Smckusic } 345762Speter 346762Speter /* 347762Speter * put out a floating point constant leaf node 348762Speter * the constant is declared in aligned data space 34918462Sralph * and a PCC_NAME leaf put out for it 350762Speter */ 3517924Smckusick putCON8( val ) 3527924Smckusick double val; 353762Speter { 35415953Smckusick char *label; 355762Speter char name[ BUFSIZ ]; 356762Speter 3573316Speter if ( !CGENNING ) 358762Speter return; 35910653Speter label = getlab(); 360762Speter putprintf( " .data" , 0 ); 36110653Speter aligndot(A_DOUBLE); 36215953Smckusick (void) putlab( label ); 36310653Speter # ifdef vax 36410653Speter putprintf( " .double 0d%.20e" , 0 , val ); 36510653Speter # endif vax 36610653Speter # ifdef mc68000 36710653Speter putprintf( " .long 0x%x,0x%x", 0, val); 36810653Speter # endif mc68000 369762Speter putprintf( " .text" , 0 ); 370762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 37118462Sralph putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name ); 372762Speter } 373762Speter 374762Speter /* 375762Speter * put out either an lvalue or an rvalue for a constant string. 376762Speter * an lvalue (for assignment rhs's) is the name as a constant, 377762Speter * an rvalue (for parameters) is just the name. 378762Speter */ 379762Speter putCONG( string , length , required ) 380762Speter char *string; 381762Speter int length; 382762Speter int required; 383762Speter { 384762Speter char name[ BUFSIZ ]; 38515953Smckusick char *label; 386762Speter char *cp; 387762Speter int pad; 388762Speter int others; 389762Speter 3903316Speter if ( !CGENNING ) 391762Speter return; 392762Speter putprintf( " .data" , 0 ); 39310653Speter aligndot(A_STRUCT); 394762Speter label = getlab(); 39515953Smckusick (void) putlab( label ); 396762Speter cp = string; 397762Speter while ( *cp ) { 398762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 399762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 400762Speter putprintf( ",0%o" , 1 , *cp++ ); 401762Speter } 402762Speter putprintf( "" , 0 ); 403762Speter } 404762Speter pad = length - strlen( string ); 405762Speter while ( pad-- > 0 ) { 406762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 407762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 408762Speter putprintf( ",0%o" , 1 , ' ' ); 409762Speter } 410762Speter putprintf( "" , 0 ); 411762Speter } 412762Speter putprintf( " .byte 0" , 0 ); 413762Speter putprintf( " .text" , 0 ); 414762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 415762Speter if ( required == RREQ ) { 41618462Sralph putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name ); 417762Speter } else { 41818462Sralph putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name ); 419762Speter } 420762Speter } 421762Speter 422762Speter /* 423762Speter * map a pascal type to a c type 424762Speter * this would be tail recursive, but i unfolded it into a for (;;). 425762Speter * this is sort of like isa and lwidth 426762Speter * a note on the types used by the portable c compiler: 427762Speter * they are divided into a basic type (char, short, int, long, etc.) 428762Speter * and qualifications on those basic types (pointer, function, array). 429762Speter * the basic type is kept in the low 4 bits of the type descriptor, 430762Speter * and the qualifications are arranged in two bit chunks, with the 431762Speter * most significant on the right, 432762Speter * and the least significant on the left 433762Speter * e.g. int *foo(); 434762Speter * (a function returning a pointer to an integer) 435762Speter * is stored as 436762Speter * <ptr><ftn><int> 437762Speter * so, we build types recursively 4381478Speter * also, we know that /lib/f1 can only deal with 6 qualifications 4391478Speter * so we stop the recursion there. this stops infinite type recursion 4401478Speter * through mutually recursive pointer types. 441762Speter */ 4421478Speter #define MAXQUALS 6 443762Speter int 444762Speter p2type( np ) 44515953Smckusick struct nl *np; 4461478Speter { 4471478Speter 4481478Speter return typerecur( np , 0 ); 4491478Speter } 4501478Speter typerecur( np , quals ) 4511478Speter struct nl *np; 4521478Speter int quals; 453762Speter { 454762Speter 4551478Speter if ( np == NIL || quals > MAXQUALS ) { 45618462Sralph return PCCT_UNDEF; 4571478Speter } 458762Speter switch ( np -> class ) { 459762Speter case SCAL : 460762Speter case RANGE : 46115974Smckusick case CRANGE : 462762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 46318462Sralph return PCCT_DOUBLE; 464762Speter } 465762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 466762Speter case 1: 46718462Sralph return PCCT_CHAR; 468762Speter case 2: 46918462Sralph return PCCT_SHORT; 470762Speter case 4: 47118462Sralph return PCCT_INT; 472762Speter default: 473762Speter panic( "p2type int" ); 47415953Smckusick /* NOTREACHED */ 475762Speter } 476762Speter case STR : 47718462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 478762Speter case RECORD : 479762Speter case SET : 48018462Sralph return PCCT_STRTY; 481762Speter case FILET : 48218462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 483762Speter case CONST : 484762Speter case VAR : 485762Speter case FIELD : 486762Speter return p2type( np -> type ); 487762Speter case TYPE : 488762Speter switch ( nloff( np ) ) { 489762Speter case TNIL : 49018462Sralph return ( PCCTM_PTR | PCCT_UNDEF ); 491762Speter case TSTR : 49218462Sralph return ( PCCTM_ARY | PCCT_CHAR ); 493762Speter case TSET : 49418462Sralph return PCCT_STRTY; 495762Speter default : 496762Speter return ( p2type( np -> type ) ); 497762Speter } 498762Speter case REF: 499762Speter case WITHPTR: 500762Speter case PTR : 50118462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR ); 502762Speter case ARRAY : 50318462Sralph return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY ); 504762Speter case FUNC : 505762Speter /* 506762Speter * functions are really pointers to functions 507762Speter * which return their underlying type. 508762Speter */ 50918462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) , 51018462Sralph PCCTM_FTN ) , PCCTM_PTR ); 511762Speter case PROC : 512762Speter /* 513762Speter * procedures are pointers to functions 514762Speter * which return integers (whether you look at them or not) 515762Speter */ 51618462Sralph return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR ); 5171197Speter case FFUNC : 5181197Speter case FPROC : 5191197Speter /* 5201197Speter * formal procedures and functions are pointers 5211197Speter * to structures which describe their environment. 5221197Speter */ 52318462Sralph return ( PCCTM_PTR | PCCT_STRTY ); 524762Speter default : 525762Speter panic( "p2type" ); 52615953Smckusick /* NOTREACHED */ 527762Speter } 528762Speter } 529762Speter 530762Speter /* 531762Speter * put a typed operator to the pcstream 532762Speter */ 533762Speter putop( op , type ) 534762Speter int op; 535762Speter int type; 536762Speter { 53718462Sralph extern char *p2opname(); 538762Speter 5393316Speter if ( !CGENNING ) 540762Speter return; 54118462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 542762Speter # ifdef DEBUG 543762Speter if ( opt( 'k' ) ) { 5442474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x\n" 54518462Sralph , p2opname( op ) , op , type ); 546762Speter } 547762Speter # endif 548762Speter } 549762Speter 550762Speter /* 551762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 552762Speter * which looks just like a regular operator, only the size and 553762Speter * alignment go in the next consecutive words 554762Speter */ 555762Speter putstrop( op , type , size , alignment ) 556762Speter int op; 557762Speter int type; 558762Speter int size; 559762Speter int alignment; 560762Speter { 56118462Sralph extern char *p2opname(); 562762Speter 5633316Speter if ( !CGENNING ) 564762Speter return; 56518462Sralph p2word( PCCM_TRIPLE( op , 0 , type ) ); 566762Speter p2word( size ); 567762Speter p2word( alignment ); 568762Speter # ifdef DEBUG 569762Speter if ( opt( 'k' ) ) { 5702474Speter fprintf( stdout , "%s (%d) | 0 | 0x%x %d %d\n" 57118462Sralph , p2opname( op ) , op , type , size , alignment ); 572762Speter } 573762Speter # endif 574762Speter } 575762Speter 576762Speter /* 577762Speter * the string names of p2ops 578762Speter */ 57918462Sralph 58018462Sralph struct p2op { 58118462Sralph int op; 58218462Sralph char *name; 58318462Sralph }; 58418462Sralph 58518462Sralph static struct p2op p2opnames[] = { 58618462Sralph PCC_ERROR, "PCC_ERROR", 58718462Sralph PCC_NAME, "PCC_NAME", 58818462Sralph PCC_STRING, "PCC_STRING", 58918462Sralph PCC_ICON, "PCC_ICON", 59018462Sralph PCC_FCON, "PCC_FCON", 59118462Sralph PCC_PLUS, "PCC_PLUS", 59218462Sralph PCC_MINUS, "PCC_MINUS", 59318462Sralph PCC_UMINUS, "PCC_UMINUS", 59418462Sralph PCC_MUL, "PCC_MUL", 59518462Sralph PCC_DEREF, "PCC_DEREF", 59618462Sralph PCC_AND, "PCC_AND", 59718462Sralph PCC_ADDROF, "PCC_ADDROF", 59818462Sralph PCC_OR, "PCC_OR", 59918462Sralph PCC_ER, "PCC_ER", 60018462Sralph PCC_QUEST, "PCC_QUEST", 60118462Sralph PCC_COLON, "PCC_COLON", 60218462Sralph PCC_ANDAND, "PCC_ANDAND", 60318462Sralph PCC_OROR, "PCC_OROR", 60418462Sralph PCC_CM, "PCC_CM", 60518462Sralph PCC_ASSIGN, "PCC_ASSIGN", 60618462Sralph PCC_COMOP, "PCC_COMOP", 60718462Sralph PCC_DIV, "PCC_DIV", 60818462Sralph PCC_MOD, "PCC_MOD", 60918462Sralph PCC_LS, "PCC_LS", 61018462Sralph PCC_RS, "PCC_RS", 61118462Sralph PCC_DOT, "PCC_DOT", 61218462Sralph PCC_STREF, "PCC_STREF", 61318462Sralph PCC_CALL, "PCC_CALL", 61418462Sralph PCC_UCALL, "PCC_UCALL", 61518462Sralph PCC_FORTCALL, "PCC_FORTCALL", 61618462Sralph PCC_UFORTCALL, "PCC_UFORTCALL", 61718462Sralph PCC_NOT, "PCC_NOT", 61818462Sralph PCC_COMPL, "PCC_COMPL", 61918462Sralph PCC_INCR, "PCC_INCR", 62018462Sralph PCC_DECR, "PCC_DECR", 62118462Sralph PCC_EQ, "PCC_EQ", 62218462Sralph PCC_NE, "PCC_NE", 62318462Sralph PCC_LE, "PCC_LE", 62418462Sralph PCC_LT, "PCC_LT", 62518462Sralph PCC_GE, "PCC_GE", 62618462Sralph PCC_GT, "PCC_GT", 62718462Sralph PCC_ULE, "PCC_ULE", 62818462Sralph PCC_ULT, "PCC_ULT", 62918462Sralph PCC_UGE, "PCC_UGE", 63018462Sralph PCC_UGT, "PCC_UGT", 63118462Sralph PCC_REG, "PCC_REG", 63218462Sralph PCC_OREG, "PCC_OREG", 63318462Sralph PCC_CCODES, "PCC_CCODES", 63418462Sralph PCC_FREE, "PCC_FREE", 63518462Sralph PCC_STASG, "PCC_STASG", 63618462Sralph PCC_STARG, "PCC_STARG", 63718462Sralph PCC_STCALL, "PCC_STCALL", 63818462Sralph PCC_USTCALL, "PCC_USTCALL", 63918462Sralph PCC_FLD, "PCC_FLD", 64018462Sralph PCC_SCONV, "PCC_SCONV", 64118462Sralph PCC_PCONV, "PCC_PCONV", 64218462Sralph PCC_PMCONV, "PCC_PMCONV", 64318462Sralph PCC_PVCONV, "PCC_PVCONV", 64418462Sralph PCC_FORCE, "PCC_FORCE", 64518462Sralph PCC_CBRANCH, "PCC_CBRANCH", 64618462Sralph PCC_INIT, "PCC_INIT", 64718462Sralph PCC_CAST, "PCC_CAST", 64818462Sralph -1, "" 649762Speter }; 65018462Sralph 65118462Sralph char * 65218462Sralph p2opname( op ) 65318462Sralph register int op; 65418462Sralph { 65518462Sralph static char *p2map[PCC_MAXOP+1]; 65618462Sralph static bool mapready = FALSE; 65718462Sralph register struct p2op *pp; 65818462Sralph 65918462Sralph if ( mapready == FALSE ) { 66018462Sralph for ( pp = p2opnames; pp->op >= 0; pp++ ) 66118462Sralph p2map[ pp->op ] = pp->name; 66218462Sralph mapready = TRUE; 66318462Sralph } 66418462Sralph return ( p2map[ op ] ? p2map[ op ] : "unknown" ); 66518462Sralph } 666762Speter 667762Speter /* 668762Speter * low level routines 669762Speter */ 670762Speter 671762Speter /* 672762Speter * puts a long word on the pcstream 673762Speter */ 674762Speter p2word( word ) 67515953Smckusick int word; 676762Speter { 677762Speter 678762Speter putw( word , pcstream ); 679762Speter } 680762Speter 681762Speter /* 682762Speter * put a length 0 mod 4 null padded string onto the pcstream 683762Speter */ 684762Speter p2string( string ) 685762Speter char *string; 686762Speter { 687762Speter int slen = strlen( string ); 688762Speter int wlen = ( slen + 3 ) / 4; 689762Speter int plen = ( wlen * 4 ) - slen; 690762Speter char *cp; 691762Speter int p; 692762Speter 693762Speter for ( cp = string ; *cp ; cp++ ) 694762Speter putc( *cp , pcstream ); 695762Speter for ( p = 1 ; p <= plen ; p++ ) 696762Speter putc( '\0' , pcstream ); 697762Speter # ifdef DEBUG 698762Speter if ( opt( 'k' ) ) { 699762Speter fprintf( stdout , "\"%s" , string ); 700762Speter for ( p = 1 ; p <= plen ; p++ ) 701762Speter fprintf( stdout , "\\0" ); 702762Speter fprintf( stdout , "\"\n" ); 703762Speter } 704762Speter # endif 705762Speter } 706762Speter 707762Speter /* 708762Speter * puts a name on the pcstream 709762Speter */ 710762Speter p2name( name ) 711762Speter char *name; 712762Speter { 713762Speter int pad; 714762Speter 715762Speter fprintf( pcstream , NAMEFORMAT , name ); 716762Speter pad = strlen( name ) % sizeof (long); 717762Speter for ( ; pad < sizeof (long) ; pad++ ) { 718762Speter putc( '\0' , pcstream ); 719762Speter } 720762Speter # ifdef DEBUG 721762Speter if ( opt( 'k' ) ) { 722762Speter fprintf( stdout , NAMEFORMAT , name ); 723762Speter pad = strlen( name ) % sizeof (long); 724762Speter for ( ; pad < sizeof (long) ; pad++ ) { 725762Speter fprintf( stdout , "\\0" ); 726762Speter } 727762Speter fprintf( stdout , "\n" ); 728762Speter } 729762Speter # endif 730762Speter } 731762Speter 732762Speter /* 733762Speter * put out a jump to a label 734762Speter */ 735762Speter putjbr( label ) 736762Speter long label; 737762Speter { 738762Speter 739762Speter printjbr( LABELPREFIX , label ); 740762Speter } 741762Speter 742762Speter /* 743762Speter * put out a jump to any kind of label 744762Speter */ 745762Speter printjbr( prefix , label ) 746762Speter char *prefix; 747762Speter long label; 748762Speter { 749762Speter 75010653Speter # ifdef vax 75110653Speter putprintf( " jbr " , 1 ); 75210653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 75310653Speter # endif vax 75410653Speter # ifdef mc68000 75510653Speter putprintf( " jra " , 1 ); 75610653Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 75710653Speter # endif mc68000 758762Speter } 759762Speter 760762Speter /* 761762Speter * another version of put to catch calls to put 762762Speter */ 76315953Smckusick /* VARARGS */ 76415953Smckusick put() 765762Speter { 766762Speter 76710653Speter panic("put()"); 768762Speter } 769762Speter 770762Speter #endif PC 771