📄 put.c
字号:
/*- * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)put.c 8.1 (Berkeley) 6/6/93";#endif /* not lint */#include "whoami.h"#include "opcode.h"#include "0.h"#include "objfmt.h"#ifdef PC# include "pc.h"# include "align.h"#else short *obufp = obuf;#endif/* * If DEBUG is defined, include the table * of the printing opcode names. */#ifdef DEBUG#include "OPnames.h"#endifchar showit[] = "'x'";#ifdef OBJ/* * Put is responsible for the interpreter equivalent of code * generation. Since the interpreter is specifically designed * for Pascal, little work is required here. * * FIXME, this should be converted to use <varargs.h> or <stdarg.h>. *//*VARARGS*/put(a){ register int *p, i; register char *cp; register short *sp; register long *lp; int n, subop, suboppr, op, oldlc; char *string; static int casewrd; /* * It would be nice to do some more * optimizations here. The work * done to collapse offsets in lval * should be done here, the IFEQ etc * relational operators could be used * etc. */ oldlc = (int) lc; /* its either this or change put to return a char * */ if ( !CGENNING ) /* * code disabled - do nothing */ return (oldlc); p = &a; n = *p++; suboppr = subop = (*p >> 8) & 0377; op = *p & 0377; string = 0;#ifdef DEBUG if ((cp = otext[op]) == NIL) { printf("op= %o\n", op); panic("put"); }#endif switch (op) { case O_ABORT: cp = "*"; break; case O_AS: switch(p[1]) { case 0: break; case 2: op = O_AS2; n = 1; break; case 4: op = O_AS4; n = 1; break; case 8: op = O_AS8; n = 1; break; default: goto pack; }# ifdef DEBUG cp = otext[op];# endif DEBUG break; case O_FOR1U: case O_FOR2U: case O_FOR4U: case O_FOR1D: case O_FOR2D: case O_FOR4D: /* relative addressing */ p[1] -= ( unsigned ) lc + sizeof(short); /* try to pack the jump */ if (p[1] <= 127 && p[1] >= -128) { suboppr = subop = p[1]; p++; n--; } else { /* have to allow for extra displacement */ p[1] -= sizeof(short); } break; case O_CONG: case O_LVCON: case O_CON: case O_LINO: case O_NEW: case O_DISPOSE: case O_DFDISP: case O_IND: case O_OFF: case O_INX2: case O_INX4: case O_CARD: case O_ADDT: case O_SUBT: case O_MULT: case O_IN: case O_CASE1OP: case O_CASE2OP: case O_CASE4OP: case O_FRTN: case O_WRITES: case O_WRITEC: case O_WRITEF: case O_MAX: case O_MIN: case O_ARGV: case O_CTTOT: case O_INCT: case O_RANG2: case O_RSNG2: case O_RANG42: case O_RSNG42: case O_SUCC2: case O_SUCC24: case O_PRED2: case O_PRED24: if (p[1] == 0) break; case O_CON2: case O_CON24: pack: if (p[1] <= 127 && p[1] >= -128) { suboppr = subop = p[1]; p++; n--; if (op == O_CON2) { op = O_CON1;# ifdef DEBUG cp = otext[O_CON1];# endif DEBUG } if (op == O_CON24) { op = O_CON14;# ifdef DEBUG cp = otext[O_CON14];# endif DEBUG } } break; case O_CON8: { short *sp = (short *) (&p[1]);#ifdef DEBUG if ( opt( 'k' ) ) printf ( "%5d\tCON8\t%22.14e\n" , lc - HEADER_BYTES , * ( ( double * ) &p[1] ) );#endif# ifdef DEC11 word(op);# else word(op << 8);# endif DEC11 for ( i = 1 ; i <= 4 ; i ++ ) word ( *sp ++ ); return ( oldlc ); } default: if (op >= O_REL2 && op <= O_REL84) { if ((i = (subop >> INDX) * 5 ) >= 30) i -= 30; else i += 2;#ifdef DEBUG string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i];#endif suboppr = 0; } break; case O_IF: case O_TRA:/***** codeline = 0;*****/ /* relative addressing */ p[1] -= ( unsigned ) lc + sizeof(short); break; case O_CONC:#ifdef DEBUG (string = showit)[1] = p[1];#endif suboppr = 0; op = O_CON1;# ifdef DEBUG cp = otext[O_CON1];# endif DEBUG subop = p[1]; goto around; case O_CONC4:#ifdef DEBUG (string = showit)[1] = p[1];#endif suboppr = 0; op = O_CON14; subop = p[1]; goto around; case O_CON1: case O_CON14: suboppr = subop = p[1];around: n--; break; case O_CASEBEG: casewrd = 0; return (oldlc); case O_CASEEND: if ((unsigned) lc & 1) { lc--; word(casewrd); } return (oldlc); case O_CASE1:#ifdef DEBUG if (opt('k')) printf("%5d\tCASE1\t%d\n" , lc - HEADER_BYTES, p[1]);#endif /* * this to build a byte size case table * saving bytes across calls in casewrd * so they can be put out by word() */ lc++; if ((unsigned) lc & 1)# ifdef DEC11 casewrd = p[1] & 0377;# else casewrd = (p[1] & 0377) << 8;# endif DEC11 else { lc -= 2;# ifdef DEC11 word(((p[1] & 0377) << 8) | casewrd);# else word((p[1] & 0377) | casewrd);# endif DEC11 } return (oldlc); case O_CASE2:#ifdef DEBUG if (opt('k')) printf("%5d\tCASE2\t%d\n" , lc - HEADER_BYTES , p[1]);#endif word(p[1]); return (oldlc); case O_PUSH: lp = (long *)&p[1]; if (*lp == 0) return (oldlc); /* and fall through */ case O_RANG4: case O_RANG24: case O_RSNG4: case O_RSNG24: case O_SUCC4: case O_PRED4: /* sub opcode optimization */ lp = (long *)&p[1]; if (*lp < 128 && *lp >= -128 && *lp != 0) { suboppr = subop = *lp; p += (sizeof(long) / sizeof(int)); n--; } goto longgen; case O_TRA4: case O_CALL: case O_FSAV: case O_GOTO: case O_NAM: case O_READE: /* absolute long addressing */ lp = (long *)&p[1]; *lp -= HEADER_BYTES; goto longgen; case O_RV1: case O_RV14: case O_RV2: case O_RV24: case O_RV4: case O_RV8: case O_RV: case O_LV: /* * positive offsets represent arguments * and must use "ap" display entry rather * than the "fp" entry */ if (p[1] >= 0) { subop++; suboppr++; }# ifdef PDP11 break;# else /* * offsets out of range of word addressing * must use long offset opcodes */ if (p[1] < SHORTADDR && p[1] >= -SHORTADDR) break; else { op += O_LRV - O_RV;# ifdef DEBUG cp = otext[op];# endif DEBUG } /* and fall through */# endif PDP11 case O_BEG: case O_NODUMP: case O_CON4: case O_CASE4: longgen: n = (n << 1) - 1; if ( op == O_LRV ) { n--;# if defined(ADDR32) && !defined(DEC11) p[n / 2] <<= 16;# endif }#ifdef DEBUG if (opt('k')) { printf("%5d\t%s", lc - HEADER_BYTES, cp+1); if (suboppr) printf(":%d", suboppr); for ( i = 2, lp = (long *)&p[1]; i < n ; i += sizeof ( long )/sizeof ( short ) ) printf( "\t%D " , *lp ++ ); if (i == n) { sp = (short *)lp; printf( "\t%d ", *sp ); } pchr ( '\n' ); }#endif if ( op != O_CASE4 )# ifdef DEC11 word((op & 0377) | subop << 8);# else word(op << 8 | (subop & 0377));# endif DEC11 for ( i = 1, sp = (short *)&p[1]; i < n; i++) word ( *sp ++ );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -