1762Speter /* Copyright (c) 1979 Regents of the University of California */ 2762Speter 3*1197Speter static char sccsid[] = "@(#)p2put.c 1.2 10/03/80"; 4762Speter 5762Speter /* 6762Speter * functions to help pi put out 7762Speter * polish postfix binary portable c compiler intermediate code 8762Speter * thereby becoming the portable pascal compiler 9762Speter */ 10762Speter 11762Speter #include "whoami.h" 12762Speter #ifdef PC 13762Speter #include "0.h" 14762Speter #include "pcops.h" 15762Speter #include "pc.h" 16762Speter 17762Speter /* 18762Speter * mash into f77's format 19762Speter * lovely, isn't it? 20762Speter */ 21762Speter #define TOF77( fop,val,rest ) ( ( ( (rest) & 0177777 ) << 16 ) \ 22762Speter | ( ( (val) & 0377 ) << 8 ) \ 23762Speter | ( (fop) & 0377 ) ) 24762Speter 25762Speter /* 26762Speter * emits an ftext operator and a string to the pcstream 27762Speter */ 28762Speter puttext( string ) 29762Speter char *string; 30762Speter { 31762Speter int length = str4len( string ); 32762Speter 33762Speter if ( cgenflg ) 34762Speter return; 35762Speter p2word( TOF77( P2FTEXT , length , 0 ) ); 36762Speter # ifdef DEBUG 37762Speter if ( opt( 'k' ) ) { 38762Speter fprintf( stdout , "P2FTEXT | %3d | 0 " , length ); 39762Speter } 40762Speter # endif 41762Speter p2string( string ); 42762Speter } 43762Speter 44762Speter int 45762Speter str4len( string ) 46762Speter char *string; 47762Speter { 48762Speter 49762Speter return ( ( strlen( string ) + 3 ) / 4 ); 50762Speter } 51762Speter 52762Speter /* 53762Speter * put formatted text into a buffer for printing to the pcstream. 54762Speter * a call to putpflush actually puts out the text. 55762Speter * none of arg1 .. arg5 need be present. 56762Speter * and you can add more if you need them. 57762Speter */ 58762Speter /* VARARGS */ 59762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 ) 60762Speter char *format; 61762Speter int incomplete; 62762Speter { 63762Speter static char ppbuffer[ BUFSIZ ]; 64762Speter static char *ppbufp = ppbuffer; 65762Speter 66762Speter if ( cgenflg ) 67762Speter return; 68762Speter sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 ); 69762Speter ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] ); 70762Speter if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) ) 71762Speter panic( "putprintf" ); 72762Speter if ( ! incomplete ) { 73762Speter puttext( ppbuffer ); 74762Speter ppbufp = ppbuffer; 75762Speter } 76762Speter } 77762Speter 78762Speter /* 79762Speter * emit a left bracket operator to pcstream 80762Speter * with function number, the maximum temp register, and total local bytes 81762Speter * until i figure out how to use them, regs 0 .. 11 are free. 82762Speter * one idea for one reg is to save the display pointer on block entry 83762Speter */ 84762Speter putlbracket( ftnno , localbytes ) 85762Speter int ftnno; 86762Speter int localbytes; 87762Speter { 88762Speter # define MAXTP2REG 11 89762Speter 90762Speter p2word( TOF77( P2FLBRAC , MAXTP2REG , ftnno ) ); 91762Speter p2word( BITSPERBYTE * localbytes ); 92762Speter # ifdef DEBUG 93762Speter if ( opt( 'k' ) ) { 94762Speter fprintf( stdout 95762Speter , "P2FLBRAC | %3d | %d " , MAXTP2REG , ftnno ); 96762Speter fprintf( stdout , "%d\n" 97762Speter , BITSPERBYTE * localbytes ); 98762Speter } 99762Speter # endif 100762Speter } 101762Speter 102762Speter /* 103762Speter * emit a right bracket operator 104762Speter * which for the binary (fortran) interface 105762Speter * forces the stack allocate and register mask 106762Speter */ 107762Speter putrbracket( ftnno ) 108762Speter int ftnno; 109762Speter { 110762Speter 111762Speter p2word( TOF77( P2FRBRAC , 0 , ftnno ) ); 112762Speter # ifdef DEBUG 113762Speter if ( opt( 'k' ) ) { 114762Speter fprintf( stdout , "P2FRBRAC | 0 | %d\n" , ftnno ); 115762Speter } 116762Speter # endif 117762Speter } 118762Speter 119762Speter /* 120762Speter * emit an eof operator 121762Speter */ 122762Speter puteof() 123762Speter { 124762Speter 125762Speter p2word( P2FEOF ); 126762Speter # ifdef DEBUG 127762Speter if ( opt( 'k' ) ) { 128762Speter fprintf( stdout , "P2FEOF\n" ); 129762Speter } 130762Speter # endif 131762Speter } 132762Speter 133762Speter /* 134762Speter * emit a dot operator, 135762Speter * with a source file line number and name 136762Speter * if line is negative, there was an error on that line, but who cares? 137762Speter */ 138762Speter putdot( filename , line ) 139762Speter char *filename; 140762Speter int line; 141762Speter { 142762Speter int length = str4len( filename ); 143762Speter 144762Speter if ( line < 0 ) { 145762Speter line = -line; 146762Speter } 147762Speter p2word( TOF77( P2FEXPR , length , line ) ); 148762Speter # ifdef DEBUG 149762Speter if ( opt( 'k' ) ) { 150762Speter fprintf( stdout , "P2FEXPR | %3d | %d " , length , line ); 151762Speter } 152762Speter # endif 153762Speter p2string( filename ); 154762Speter } 155762Speter 156762Speter /* 157762Speter * put out a leaf node 158762Speter */ 159762Speter putleaf( op , lval , rval , type , name ) 160762Speter int op; 161762Speter int lval; 162762Speter int rval; 163762Speter int type; 164762Speter char *name; 165762Speter { 166762Speter if ( cgenflg ) 167762Speter return; 168762Speter switch ( op ) { 169762Speter default: 170762Speter panic( "[putleaf]" ); 171762Speter case P2ICON: 172762Speter p2word( TOF77( P2ICON , name != NIL , type ) ); 173762Speter p2word( lval ); 174762Speter # ifdef DEBUG 175762Speter if ( opt( 'k' ) ) { 176762Speter fprintf( stdout , "P2ICON | %3d | %d " 177762Speter , name != NIL , type ); 178762Speter fprintf( stdout , "%d\n" , lval ); 179762Speter } 180762Speter # endif 181762Speter if ( name ) 182762Speter p2name( name ); 183762Speter break; 184762Speter case P2NAME: 185762Speter p2word( TOF77( P2NAME , lval != 0 , type ) ); 186762Speter if ( lval ) 187762Speter p2word( lval ); 188762Speter # ifdef DEBUG 189762Speter if ( opt( 'k' ) ) { 190762Speter fprintf( stdout , "P2NAME | %3d | %d " 191762Speter , lval != 0 , type ); 192762Speter if ( lval ) 193762Speter fprintf( stdout , "%d " , lval ); 194762Speter } 195762Speter # endif 196762Speter p2name( name ); 197762Speter break; 198762Speter case P2REG: 199762Speter p2word( TOF77( P2REG , rval , type ) ); 200762Speter # ifdef DEBUG 201762Speter if ( opt( 'k' ) ) { 202762Speter fprintf( stdout , "P2REG | %3d | %d\n" , rval , type ); 203762Speter } 204762Speter # endif 205762Speter break; 206762Speter } 207762Speter } 208762Speter 209762Speter /* 210762Speter * rvalues are just lvalues with indirection, except 211762Speter * special case for named globals, whose names are their rvalues 212762Speter */ 213762Speter putRV( name , level , offset , type ) 214762Speter char *name; 215762Speter int level; 216762Speter int offset; 217762Speter int type; 218762Speter { 219762Speter char extname[ BUFSIZ ]; 220762Speter char *printname; 221762Speter 222762Speter if ( cgenflg ) 223762Speter return; 224762Speter if ( ( level <= 1 ) && ( name != 0 ) ) { 225762Speter if ( name[0] != '_' ) { 226762Speter sprintf( extname , EXTFORMAT , name ); 227762Speter printname = extname; 228762Speter } else { 229762Speter printname = name; 230762Speter } 231762Speter putleaf( P2NAME , offset , 0 , type , printname ); 232762Speter return; 233762Speter } 234762Speter putLV( name , level , offset , type ); 235762Speter putop( P2UNARY P2MUL , type ); 236762Speter } 237762Speter 238762Speter /* 239762Speter * put out an lvalue 240762Speter * given a level and offset 241762Speter * special case for 242762Speter * named globals, whose lvalues are just their names as constants. 243762Speter * negative offsets, that are offsets from the frame pointer. 244762Speter * positive offsets, that are offsets from argument pointer. 245762Speter */ 246762Speter putLV( name , level , offset , type ) 247762Speter char *name; 248762Speter int level; 249762Speter int offset; 250762Speter int type; 251762Speter { 252762Speter char extname[ BUFSIZ ]; 253762Speter char *printname; 254762Speter 255762Speter if ( cgenflg ) 256762Speter return; 257762Speter if ( ( level <= 1 ) && ( name != 0 ) ) { 258762Speter if ( name[0] != '_' ) { 259762Speter sprintf( extname , EXTFORMAT , name ); 260762Speter printname = extname; 261762Speter } else { 262762Speter printname = name; 263762Speter } 264762Speter putleaf( P2ICON , offset , 0 , ADDTYPE( type , P2PTR ) 265762Speter , printname ); 266762Speter return; 267762Speter } 268762Speter if ( level == cbn ) { 269762Speter if ( offset < 0 ) { 270762Speter putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 ); 271762Speter } else { 272762Speter putleaf( P2REG , 0 , P2AP , ADDTYPE( type , P2PTR ) , 0 ); 273762Speter } 274762Speter } else { 275762Speter if ( offset < 0 ) { 276762Speter putleaf( P2NAME 277762Speter , ( level * sizeof(struct dispsave) ) + FP_OFFSET 278762Speter , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 279762Speter } else { 280762Speter putleaf( P2NAME 281762Speter , ( level * sizeof(struct dispsave) ) + AP_OFFSET 282762Speter , 0 , P2PTR | P2CHAR , DISPLAYNAME ); 283762Speter } 284762Speter } 285762Speter if ( offset < 0 ) { 286762Speter putleaf( P2ICON , -offset , 0 , P2INT , 0 ); 287762Speter putop( P2MINUS , P2PTR | P2CHAR ); 288762Speter } else { 289762Speter putleaf( P2ICON , offset , 0 , P2INT , 0 ); 290762Speter putop( P2PLUS , P2PTR | P2CHAR ); 291762Speter } 292762Speter return; 293762Speter } 294762Speter 295762Speter /* 296762Speter * put out a floating point constant leaf node 297762Speter * the constant is declared in aligned data space 298762Speter * and a P2NAME leaf put out for it 299762Speter */ 300762Speter putCON8( value ) 301762Speter double value; 302762Speter { 303762Speter int label; 304762Speter char name[ BUFSIZ ]; 305762Speter 306762Speter if ( cgenflg ) 307762Speter return; 308762Speter putprintf( " .data" , 0 ); 309762Speter putprintf( " .align 2" , 0 ); 310762Speter label = getlab(); 311762Speter putlab( label ); 312762Speter putprintf( " .double 0d%.20e" , 0 , value ); 313762Speter putprintf( " .text" , 0 ); 314762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 315762Speter putleaf( P2NAME , 0 , 0 , P2DOUBLE , name ); 316762Speter } 317762Speter 318762Speter /* 319762Speter * put out either an lvalue or an rvalue for a constant string. 320762Speter * an lvalue (for assignment rhs's) is the name as a constant, 321762Speter * an rvalue (for parameters) is just the name. 322762Speter */ 323762Speter putCONG( string , length , required ) 324762Speter char *string; 325762Speter int length; 326762Speter int required; 327762Speter { 328762Speter char name[ BUFSIZ ]; 329762Speter int label; 330762Speter char *cp; 331762Speter int pad; 332762Speter int others; 333762Speter 334762Speter if ( cgenflg ) 335762Speter return; 336762Speter putprintf( " .data" , 0 ); 337762Speter label = getlab(); 338762Speter putlab( label ); 339762Speter cp = string; 340762Speter while ( *cp ) { 341762Speter putprintf( " .byte 0%o" , 1 , *cp ++ ); 342762Speter for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) { 343762Speter putprintf( ",0%o" , 1 , *cp++ ); 344762Speter } 345762Speter putprintf( "" , 0 ); 346762Speter } 347762Speter pad = length - strlen( string ); 348762Speter while ( pad-- > 0 ) { 349762Speter putprintf( " .byte 0%o" , 1 , ' ' ); 350762Speter for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) { 351762Speter putprintf( ",0%o" , 1 , ' ' ); 352762Speter } 353762Speter putprintf( "" , 0 ); 354762Speter } 355762Speter putprintf( " .byte 0" , 0 ); 356762Speter putprintf( " .text" , 0 ); 357762Speter sprintf( name , PREFIXFORMAT , LABELPREFIX , label ); 358762Speter if ( required == RREQ ) { 359762Speter putleaf( P2NAME , 0 , 0 , P2ARY | P2CHAR , name ); 360762Speter } else { 361762Speter putleaf( P2ICON , 0 , 0 , P2PTR | P2CHAR , name ); 362762Speter } 363762Speter } 364762Speter 365762Speter /* 366762Speter * map a pascal type to a c type 367762Speter * this would be tail recursive, but i unfolded it into a for (;;). 368762Speter * this is sort of like isa and lwidth 369762Speter * a note on the types used by the portable c compiler: 370762Speter * they are divided into a basic type (char, short, int, long, etc.) 371762Speter * and qualifications on those basic types (pointer, function, array). 372762Speter * the basic type is kept in the low 4 bits of the type descriptor, 373762Speter * and the qualifications are arranged in two bit chunks, with the 374762Speter * most significant on the right, 375762Speter * and the least significant on the left 376762Speter * e.g. int *foo(); 377762Speter * (a function returning a pointer to an integer) 378762Speter * is stored as 379762Speter * <ptr><ftn><int> 380762Speter * so, we build types recursively 381762Speter */ 382762Speter int 383762Speter p2type( np ) 384762Speter struct nl *np; 385762Speter { 386762Speter 387762Speter if ( np == NIL ) 388762Speter return P2UNDEFINED; 389762Speter switch ( np -> class ) { 390762Speter case SCAL : 391762Speter case RANGE : 392762Speter if ( np -> type == ( nl + TDOUBLE ) ) { 393762Speter return P2DOUBLE; 394762Speter } 395762Speter switch ( bytes( np -> range[0] , np -> range[1] ) ) { 396762Speter case 1: 397762Speter return P2CHAR; 398762Speter case 2: 399762Speter return P2SHORT; 400762Speter case 4: 401762Speter return P2INT; 402762Speter default: 403762Speter panic( "p2type int" ); 404762Speter } 405762Speter case STR : 406762Speter return ( P2ARY | P2CHAR ); 407762Speter /* 408762Speter return P2STRTY; 409762Speter */ 410762Speter case RECORD : 411762Speter case SET : 412762Speter return P2STRTY; 413762Speter case FILET : 414762Speter return ( P2PTR | P2STRTY ); 415762Speter case CONST : 416762Speter case VAR : 417762Speter case FIELD : 418762Speter return p2type( np -> type ); 419762Speter case TYPE : 420762Speter switch ( nloff( np ) ) { 421762Speter case TNIL : 422762Speter return ( P2PTR | P2UNDEFINED ); 423762Speter case TSTR : 424762Speter return ( P2ARY | P2CHAR ); 425762Speter /* 426762Speter return P2STRTY; 427762Speter */ 428762Speter case TSET : 429762Speter return P2STRTY; 430762Speter default : 431762Speter return ( p2type( np -> type ) ); 432762Speter } 433762Speter case REF: 434762Speter case WITHPTR: 435762Speter case PTR : 436762Speter return ADDTYPE( p2type( np -> type ) , P2PTR ); 437762Speter case ARRAY : 438762Speter return ADDTYPE( p2type( np -> type ) , P2ARY ); 439762Speter /* 440762Speter return P2STRTY; 441762Speter */ 442762Speter case FUNC : 443762Speter /* 444762Speter * functions are really pointers to functions 445762Speter * which return their underlying type. 446762Speter */ 447762Speter return ADDTYPE( ADDTYPE( p2type( np -> type ) , P2FTN ) 448762Speter , P2PTR ); 449762Speter case PROC : 450762Speter /* 451762Speter * procedures are pointers to functions 452762Speter * which return integers (whether you look at them or not) 453762Speter */ 454762Speter return ADDTYPE( ADDTYPE( P2INT , P2FTN ) , P2PTR ); 455*1197Speter case FFUNC : 456*1197Speter case FPROC : 457*1197Speter /* 458*1197Speter * formal procedures and functions are pointers 459*1197Speter * to structures which describe their environment. 460*1197Speter */ 461*1197Speter return ADDTYPE( P2PTR , P2STRTY ); 462762Speter default : 463762Speter fprintf( stderr , "[p2type] np -> class %d\n" , np -> class ); 464762Speter panic( "p2type" ); 465762Speter } 466762Speter } 467762Speter 468762Speter /* 469762Speter * add a most significant type modifier to a type 470762Speter */ 471762Speter long 472762Speter addtype( underlying , mtype ) 473762Speter long underlying; 474762Speter long mtype; 475762Speter { 476762Speter return ( ( ( underlying & ~P2BASETYPE ) << P2TYPESHIFT ) 477762Speter | mtype 478762Speter | ( underlying & P2BASETYPE ) ); 479762Speter } 480762Speter 481762Speter /* 482762Speter * put a typed operator to the pcstream 483762Speter */ 484762Speter putop( op , type ) 485762Speter int op; 486762Speter int type; 487762Speter { 488762Speter extern char *p2opnames[]; 489762Speter 490762Speter if ( cgenflg ) 491762Speter return; 492762Speter p2word( TOF77( op , 0 , type ) ); 493762Speter # ifdef DEBUG 494762Speter if ( opt( 'k' ) ) { 495762Speter fprintf( stdout , "%s (%d) | 0 | %d\n" 496762Speter , p2opnames[ op ] , op , type ); 497762Speter } 498762Speter # endif 499762Speter } 500762Speter 501762Speter /* 502762Speter * put out a structure operator (STASG, STARG, STCALL, UNARY STCALL ) 503762Speter * which looks just like a regular operator, only the size and 504762Speter * alignment go in the next consecutive words 505762Speter */ 506762Speter putstrop( op , type , size , alignment ) 507762Speter int op; 508762Speter int type; 509762Speter int size; 510762Speter int alignment; 511762Speter { 512762Speter extern char *p2opnames[]; 513762Speter 514762Speter if ( cgenflg ) 515762Speter return; 516762Speter p2word( TOF77( op , 0 , type ) ); 517762Speter p2word( size ); 518762Speter p2word( alignment ); 519762Speter # ifdef DEBUG 520762Speter if ( opt( 'k' ) ) { 521762Speter fprintf( stdout , "%s (%d) | 0 | %d %d %d\n" 522762Speter , p2opnames[ op ] , op , type , size , alignment ); 523762Speter } 524762Speter # endif 525762Speter } 526762Speter 527762Speter /* 528762Speter * the string names of p2ops 529762Speter */ 530762Speter char *p2opnames[] = { 531762Speter "", 532762Speter "P2UNDEFINED", /* 1 */ 533762Speter "P2NAME", /* 2 */ 534762Speter "P2STRING", /* 3 */ 535762Speter "P2ICON", /* 4 */ 536762Speter "P2FCON", /* 5 */ 537762Speter "P2PLUS", /* 6 */ 538762Speter "", 539762Speter "P2MINUS", /* 8 also unary == P2NEG */ 540762Speter "", 541762Speter "P2NEG", 542762Speter "P2MUL", /* 11 also unary == P2INDIRECT */ 543762Speter "", 544762Speter "P2INDIRECT", 545762Speter "P2AND", /* 14 also unary == P2ADDROF */ 546762Speter "", 547762Speter "P2ADDROF", 548762Speter "P2OR", /* 17 */ 549762Speter "", 550762Speter "P2ER", /* 19 */ 551762Speter "", 552762Speter "P2QUEST", /* 21 */ 553762Speter "P2COLON", /* 22 */ 554762Speter "P2ANDAND", /* 23 */ 555762Speter "P2OROR", /* 24 */ 556762Speter "", /* 25 */ 557762Speter "", /* 26 */ 558762Speter "", /* 27 */ 559762Speter "", /* 28 */ 560762Speter "", /* 29 */ 561762Speter "", /* 30 */ 562762Speter "", /* 31 */ 563762Speter "", /* 32 */ 564762Speter "", /* 33 */ 565762Speter "", /* 34 */ 566762Speter "", /* 35 */ 567762Speter "", /* 36 */ 568762Speter "", /* 37 */ 569762Speter "", /* 38 */ 570762Speter "", /* 39 */ 571762Speter "", /* 40 */ 572762Speter "", /* 41 */ 573762Speter "", /* 42 */ 574762Speter "", /* 43 */ 575762Speter "", /* 44 */ 576762Speter "", /* 45 */ 577762Speter "", /* 46 */ 578762Speter "", /* 47 */ 579762Speter "", /* 48 */ 580762Speter "", /* 49 */ 581762Speter "", /* 50 */ 582762Speter "", /* 51 */ 583762Speter "", /* 52 */ 584762Speter "", /* 53 */ 585762Speter "", /* 54 */ 586762Speter "", /* 55 */ 587762Speter "P2LISTOP", /* 56 */ 588762Speter "", 589762Speter "P2ASSIGN", /* 58 */ 590762Speter "P2COMOP", /* 59 */ 591762Speter "P2DIV", /* 60 */ 592762Speter "", 593762Speter "P2MOD", /* 62 */ 594762Speter "", 595762Speter "P2LS", /* 64 */ 596762Speter "", 597762Speter "P2RS", /* 66 */ 598762Speter "", 599762Speter "P2DOT", /* 68 */ 600762Speter "P2STREF", /* 69 */ 601762Speter "P2CALL", /* 70 also unary */ 602762Speter "", 603762Speter "P2UNARYCALL", 604762Speter "P2FORTCALL", /* 73 also unary */ 605762Speter "", 606762Speter "P2UNARYFORTCALL", 607762Speter "P2NOT", /* 76 */ 608762Speter "P2COMPL", /* 77 */ 609762Speter "P2INCR", /* 78 */ 610762Speter "P2DECR", /* 79 */ 611762Speter "P2EQ", /* 80 */ 612762Speter "P2NE", /* 81 */ 613762Speter "P2LE", /* 82 */ 614762Speter "P2LT", /* 83 */ 615762Speter "P2GE", /* 84 */ 616762Speter "P2GT", /* 85 */ 617762Speter "P2ULE", /* 86 */ 618762Speter "P2ULT", /* 87 */ 619762Speter "P2UGE", /* 88 */ 620762Speter "P2UGT", /* 89 */ 621762Speter "P2SETBIT", /* 90 */ 622762Speter "P2TESTBIT", /* 91 */ 623762Speter "P2RESETBIT", /* 92 */ 624762Speter "P2ARS", /* 93 */ 625762Speter "P2REG", /* 94 */ 626762Speter "P2OREG", /* 95 */ 627762Speter "P2CCODES", /* 96 */ 628762Speter "P2FREE", /* 97 */ 629762Speter "P2STASG", /* 98 */ 630762Speter "P2STARG", /* 99 */ 631762Speter "P2STCALL", /* 100 also unary */ 632762Speter "", 633762Speter "P2UNARYSTCALL", 634762Speter "P2FLD", /* 103 */ 635762Speter "P2SCONV", /* 104 */ 636762Speter "P2PCONV", /* 105 */ 637762Speter "P2PMCONV", /* 106 */ 638762Speter "P2PVCONV", /* 107 */ 639762Speter "P2FORCE", /* 108 */ 640762Speter "P2CBRANCH", /* 109 */ 641762Speter "P2INIT", /* 110 */ 642762Speter "P2CAST", /* 111 */ 643762Speter }; 644762Speter 645762Speter /* 646762Speter * low level routines 647762Speter */ 648762Speter 649762Speter /* 650762Speter * puts a long word on the pcstream 651762Speter */ 652762Speter p2word( word ) 653762Speter long word; 654762Speter { 655762Speter 656762Speter putw( word , pcstream ); 657762Speter } 658762Speter 659762Speter /* 660762Speter * put a length 0 mod 4 null padded string onto the pcstream 661762Speter */ 662762Speter p2string( string ) 663762Speter char *string; 664762Speter { 665762Speter int slen = strlen( string ); 666762Speter int wlen = ( slen + 3 ) / 4; 667762Speter int plen = ( wlen * 4 ) - slen; 668762Speter char *cp; 669762Speter int p; 670762Speter 671762Speter for ( cp = string ; *cp ; cp++ ) 672762Speter putc( *cp , pcstream ); 673762Speter for ( p = 1 ; p <= plen ; p++ ) 674762Speter putc( '\0' , pcstream ); 675762Speter # ifdef DEBUG 676762Speter if ( opt( 'k' ) ) { 677762Speter fprintf( stdout , "\"%s" , string ); 678762Speter for ( p = 1 ; p <= plen ; p++ ) 679762Speter fprintf( stdout , "\\0" ); 680762Speter fprintf( stdout , "\"\n" ); 681762Speter } 682762Speter # endif 683762Speter } 684762Speter 685762Speter /* 686762Speter * puts a name on the pcstream 687762Speter */ 688762Speter p2name( name ) 689762Speter char *name; 690762Speter { 691762Speter int pad; 692762Speter 693762Speter fprintf( pcstream , NAMEFORMAT , name ); 694762Speter pad = strlen( name ) % sizeof (long); 695762Speter for ( ; pad < sizeof (long) ; pad++ ) { 696762Speter putc( '\0' , pcstream ); 697762Speter } 698762Speter # ifdef DEBUG 699762Speter if ( opt( 'k' ) ) { 700762Speter fprintf( stdout , NAMEFORMAT , name ); 701762Speter pad = strlen( name ) % sizeof (long); 702762Speter for ( ; pad < sizeof (long) ; pad++ ) { 703762Speter fprintf( stdout , "\\0" ); 704762Speter } 705762Speter fprintf( stdout , "\n" ); 706762Speter } 707762Speter # endif 708762Speter } 709762Speter 710762Speter /* 711762Speter * put out a jump to a label 712762Speter */ 713762Speter putjbr( label ) 714762Speter long label; 715762Speter { 716762Speter 717762Speter printjbr( LABELPREFIX , label ); 718762Speter } 719762Speter 720762Speter /* 721762Speter * put out a jump to any kind of label 722762Speter */ 723762Speter printjbr( prefix , label ) 724762Speter char *prefix; 725762Speter long label; 726762Speter { 727762Speter 728762Speter putprintf( " jbr " , 1 ); 729762Speter putprintf( PREFIXFORMAT , 0 , prefix , label ); 730762Speter } 731762Speter 732762Speter /* 733762Speter * another version of put to catch calls to put 734762Speter */ 735762Speter put( arg1 , arg2 ) 736762Speter { 737762Speter 738762Speter putprintf( "# PUT CALLED!: arg1 = %d arg2 = 0%o" , 0 , arg1 , arg2 ); 739762Speter } 740762Speter 741762Speter #endif PC 742