📄 ccout.c
字号:
/* CCOUT.C - Output pseudo-code to assembler file
**
** (c) Copyright Ken Harrenstien 1989
** All changes after v.259, 11-Aug-1988
** (c) Copyright Ken Harrenstien, SRI International 1985, 1986
** All changes after v.77, 8-Aug-1985
**
** Original version (C) 1981 K. Chen
*/
#include "cc.h"
#include "ccgen.h"
#include "ccchar.h"
#include <string.h>
#include <stdlib.h> /* calloc () */
/* Imported functions */
extern char *estrcpy (char *, char *),
*fstrcpy (char *, char *, char *); /* CCASMB */
extern SYMBOL *symfidstr (char *); /* CCSYM */
extern int foldtrna (PCODE *); /* CCJSKP */
extern void errfopen (char *, char *);
extern void dmpmlbuf (void);
/* Exported functions (defined here and used externally) */
void outinit (void), outdone (int),
outlab (SYMBOL *), outscon (char *, int, int),
outid (char *), outmidef (SYMBOL *), outmiref (SYMBOL *),
outptr (SYMBOL *, int, INT), outstr (char *), outnum (INT),
outsix (unsigned INT);
void realcode (PCODE *);
int codeseg (void), dataseg (void), prevseg (int);
int outflt (int, INT *, int); /* CCGEN */
INT binexp (unsigned INT); /* CCEVAL */
int adjboffset (INT, INT *, int);
void outsix (unsigned INT), outnl (void);
void outpghdr (void); /* KAR, added for mixed listing page header output */
/* profiler functions: 9/15/89 by MVS */
void outprolog (SYMBOL *), outepilog (SYMBOL *);
static int makprefile (void); /* KAR-2/92, create ENTRY list in side .MAC */
/* Internal Functions */
static void outrj6 (unsigned INT);
static char *ahmacs (void);
static char *ahmacdef (char *cp, char **macro);
static void simptrcnv (PCODE *), simsmove (PCODE *),
simufltr (PCODE *), simdsngl (PCODE *), simuidiv (PCODE *),
simsubbp (PCODE *), simdfix (PCODE *);
static void outmpdbl (INT *, int), outpreamble (void),
outlpnum (unsigned INT, int), outinstr (PCODE *),
outpnum (unsigned INT), outop (int), outreg (int),
outpti (int, INT), outaddress (PCODE *), outasmh (void),
outlpnum (unsigned INT, int);
static int fltpow2 (double), outdecl (void),
obplh (INT, INT *, int);
static int directop (int);
static int bigfloat (PCODE *);
static void outfile (void); /* KAR-1/92, output of input filename (for NPD) */
static void outnpd (PCODE *); /* KAR-1/92, added for output of NPD code */
extern char *mlbptr;
extern char mainname[];
int _word_cnt; /* KAR-2/91, function wd cnt stat */
static whichseg; /* 1 = code, -1 = data, 0 = unknown */
/*
* Tables to handle references to built-in C RunTime symbols without
* going through the overhead of using the symbol table.
* Currently this is only used to determine which CRT symbols need to
* be declared EXTERN in the assembly-language output file.
* Note that $$CVER is always defined and declared in every KCC module,
* as are the appropriate $$CPxx symbols.
*/
#ifdef MULTI_SECTION /* FW 2A (51) */
#define crtsyms \
crtsym(CRT_,"") /* avoid zero index */\
crtsym(CRT_CRT, "$$$CRT") /* CRT module "entry point" */\
crtsym(CRT_CPU, "$$$CPU") /* CPU module "entry point" */\
crtsym(CRT_CVER, "$$CVER") /* KCC code & library version # */\
crtsym(CRT_CPUKA, "$$CPKA") /* KCC/CPU type KA-10 */\
crtsym(CRT_CPUKI, "$$CPKI") /* KCC/CPU type KI-10 */\
crtsym(CRT_CPUKS, "$$CPKS") /* KCC/CPU type KS-10 and KL-10A */\
crtsym(CRT_CPUKL0,"$$CPKL") /* KCC/CPU type KL-10B, section 0 */\
crtsym(CRT_CPUKLX,"$$CPKX") /* KCC/CPU type KL-10B, non-0 sect */\
crtsym(CRT_SECT, "$$SECT") /* CPU Section # being loaded into */\
crtsym(CRT_BPH0, "$$BPH0") /* CPU Byte ptr LHs for 18-bit bytes*/\
crtsym(CRT_BPH1, "$$BPH1") /* CPU */\
crtsym(CRT_BP90, "$$BP90") /* CPU Byte ptr LHs for 9-bit bytes */\
crtsym(CRT_BP91, "$$BP91") /* CPU */\
crtsym(CRT_BP92, "$$BP92") /* CPU */\
crtsym(CRT_BP93, "$$BP93") /* CPU */\
crtsym(CRT_BP80, "$$BP80") /* CPU Byte ptr LHs for 8-bit bytes */\
crtsym(CRT_BP81, "$$BP81") /* CPU */\
crtsym(CRT_BP82, "$$BP82") /* CPU */\
crtsym(CRT_BP83, "$$BP83") /* CPU */\
crtsym(CRT_BP70, "$$BP70") /* CPU Byte ptr LHs for 7-bit bytes */\
crtsym(CRT_BP71, "$$BP71") /* CPU */\
crtsym(CRT_BP72, "$$BP72") /* CPU */\
crtsym(CRT_BP73, "$$BP73") /* CPU */\
crtsym(CRT_BP74, "$$BP74") /* CPU */\
crtsym(CRT_BP60, "$$BP60") /* CPU Byte ptr LHs for 6-bit bytes */\
crtsym(CRT_BP61, "$$BP61") /* CPU */\
crtsym(CRT_BP62, "$$BP62") /* CPU */\
crtsym(CRT_BP63, "$$BP63") /* CPU */\
crtsym(CRT_BP64, "$$BP64") /* CPU */\
crtsym(CRT_BP65, "$$BP65") /* CPU */\
crtsym(CRT_BPPS, "$$BPPS") /* CPU Mask for BP P+S field */\
crtsym(CRT_BPSZ, "$$BPSZ") /* CPU BP LH to get BP size field */\
crtsym(CRT_BSHF, "$$BSHF") /* CPU # bits to shift in P_SUBBP */\
crtsym(CRT_BMP6, "$$BMP6") /* CPU val for 6bit MULI in P_SUBBP */\
crtsym(CRT_BMP7, "$$BMP7") /* CPU " " 7-bit " */\
crtsym(CRT_BMP8, "$$BMP8") /* CPU " " 8-bit " */\
crtsym(CRT_BMP9, "$$BMP9") /* CPU " " 9-bit " */\
crtsym(CRT_BMPH, "$$BMPH") /* CPU " " 18-bit " */\
crtsym(CRT_PH90, "$$PH90") /* CPU Instr #0 for 18->9 cnv */\
crtsym(CRT_PH91, "$$PH91") /* CPU Instr #1 for 18->9 cnv */\
crtsym(CRT_P9H0, "$$P9H0") /* CPU Instr #0 for 9->18 cnv */\
crtsym(CRT_P9H1, "$$P9H1") /* CPU Instr #1 for 9->18 cnv */\
crtsym(CRT_P9H2, "$$P9H2") /* CPU Instr #2 for 9->18 cnv */\
crtsym(CRT_START,"$START") /* CRT start location */\
crtsym(CRT_RET, "$RET") /* CRT Convenient return label */\
crtsym(CRT_RETZ, "$RETZ") /* CRT ditto, returns 0 */\
crtsym(CRT_RETF, "$RETF") /* CRT ditto, returns 0 */\
crtsym(CRT_RETP, "$RETP") /* CRT ditto, returns 1 */\
crtsym(CRT_RETT, "$RETT") /* CRT ditto, returns 1 */\
crtsym(CRT_RETN, "$RETN") /* CRT ditto, returns -1 */\
crtsym(CRT_ZERO, "$ZERO") /* CRT Double 0.0 constant */\
crtsym(CRT_ADJBP, "$ADJBP") /* CRT ADJBP simulation rtn (unused)*/\
crtsym(CRT_BPMUL, "$BPMUL") /* CRT BP mul table (for P_SUBBP) */\
crtsym(CRT_BPADT, "$BPADT") /* CRT BP table of $BPADn (for ") */\
crtsym(CRT_BPAD6, "$BPAD6") /* CRT BP 6-bit add table (for ") */\
crtsym(CRT_BPAD7, "$BPAD7") /* CRT BP 7-bit add table (for ") */\
crtsym(CRT_BPAD8, "$BPAD8") /* CRT BP 8-bit add table (for ") */\
crtsym(CRT_BPAD9, "$BPAD9") /* CRT BP 9-bit add table (for ") */\
crtsym(CRT_BPADH, "$BPADH") /* CRT BP 18-bit add table (for ") */\
crtsym(CRT_BPCNT, "$BPCNT") /* CRT Byte ptr auxiliary */\
crtsym(CRT_SUBBP, "$SUBBP") /* CRT Byte ptr subtraction aux */\
crtsym(CRT_DFIX, "$DFIX") /* CRT Aux for (int) (double) cast */\
crtsym(CRT_DFIXS, "$DFIXS") /* CRT Aux for (int) (double) cast */\
crtsym(CRT_DFLTS, "$DFLTS") /* CRT Aux for (double) (int) cast */\
crtsym(CRT_SPUSH, "$NSPUSH") /* CRT Aux to put struct on stack */\
crtsym(CRT_SPOP, "$NSPOP") /* CRT Aux to get struct from stack */\
/* KAR-1/92, added symbol for null pointer det. function */\
crtsym(CRT_NPD, "$CFNP") /* Null pointer det. function */
#else
#define crtsyms \
crtsym(CRT_,"") /* avoid zero index */\
crtsym(CRT_CRT, "$$$CRT") /* CRT module "entry point" */\
crtsym(CRT_CPU, "$$$CPU") /* CPU module "entry point" */\
crtsym(CRT_CVER, "$$CVER") /* KCC code & library version # */\
crtsym(CRT_CPUKS, "$$CPKS") /* KCC/CPU type KS-10 and KL-10A */\
crtsym(CRT_BPH0, "$$BPH0") /* CPU Byte ptr LHs for 18-bit bytes*/\
crtsym(CRT_BPH1, "$$BPH1") /* CPU */\
crtsym(CRT_BP90, "$$BP90") /* CPU Byte ptr LHs for 9-bit bytes */\
crtsym(CRT_BP91, "$$BP91") /* CPU */\
crtsym(CRT_BP92, "$$BP92") /* CPU */\
crtsym(CRT_BP93, "$$BP93") /* CPU */\
crtsym(CRT_BP80, "$$BP80") /* CPU Byte ptr LHs for 8-bit bytes */\
crtsym(CRT_BP81, "$$BP81") /* CPU */\
crtsym(CRT_BP82, "$$BP82") /* CPU */\
crtsym(CRT_BP83, "$$BP83") /* CPU */\
crtsym(CRT_BP70, "$$BP70") /* CPU Byte ptr LHs for 7-bit bytes */\
crtsym(CRT_BP71, "$$BP71") /* CPU */\
crtsym(CRT_BP72, "$$BP72") /* CPU */\
crtsym(CRT_BP73, "$$BP73") /* CPU */\
crtsym(CRT_BP74, "$$BP74") /* CPU */\
crtsym(CRT_BP60, "$$BP60") /* CPU Byte ptr LHs for 6-bit bytes */\
crtsym(CRT_BP61, "$$BP61") /* CPU */\
crtsym(CRT_BP62, "$$BP62") /* CPU */\
crtsym(CRT_BP63, "$$BP63") /* CPU */\
crtsym(CRT_BP64, "$$BP64") /* CPU */\
crtsym(CRT_BP65, "$$BP65") /* CPU */\
crtsym(CRT_BPPS, "$$BPPS") /* CPU Mask for BP P+S field */\
crtsym(CRT_BPSZ, "$$BPSZ") /* CPU BP LH to get BP size field */\
crtsym(CRT_BSHF, "$$BSHF") /* CPU # bits to shift in P_SUBBP */\
crtsym(CRT_BMP6, "$$BMP6") /* CPU val for 6bit MULI in P_SUBBP */\
crtsym(CRT_BMP7, "$$BMP7") /* CPU " " 7-bit " */\
crtsym(CRT_BMP8, "$$BMP8") /* CPU " " 8-bit " */\
crtsym(CRT_BMP9, "$$BMP9") /* CPU " " 9-bit " */\
crtsym(CRT_BMPH, "$$BMPH") /* CPU " " 18-bit " */\
crtsym(CRT_PH90, "$$PH90") /* CPU Instr #0 for 18->9 cnv */\
crtsym(CRT_PH91, "$$PH91") /* CPU Instr #1 for 18->9 cnv */\
crtsym(CRT_P9H0, "$$P9H0") /* CPU Instr #0 for 9->18 cnv */\
crtsym(CRT_P9H1, "$$P9H1") /* CPU Instr #1 for 9->18 cnv */\
crtsym(CRT_P9H2, "$$P9H2") /* CPU Instr #2 for 9->18 cnv */\
crtsym(CRT_START,"$START") /* CRT start location */\
crtsym(CRT_RET, "$RET") /* CRT Convenient return label */\
crtsym(CRT_RETZ, "$RETZ") /* CRT ditto, returns 0 */\
crtsym(CRT_RETF, "$RETF") /* CRT ditto, returns 0 */\
crtsym(CRT_RETP, "$RETP") /* CRT ditto, returns 1 */\
crtsym(CRT_RETT, "$RETT") /* CRT ditto, returns 1 */\
crtsym(CRT_RETN, "$RETN") /* CRT ditto, returns -1 */\
crtsym(CRT_ZERO, "$ZERO") /* CRT Double 0.0 constant */\
crtsym(CRT_ADJBP, "$ADJBP") /* CRT ADJBP simulation rtn (unused)*/\
crtsym(CRT_BPMUL, "$BPMUL") /* CRT BP mul table (for P_SUBBP) */\
crtsym(CRT_BPADT, "$BPADT") /* CRT BP table of $BPADn (for ") */\
crtsym(CRT_BPAD6, "$BPAD6") /* CRT BP 6-bit add table (for ") */\
crtsym(CRT_BPAD7, "$BPAD7") /* CRT BP 7-bit add table (for ") */\
crtsym(CRT_BPAD8, "$BPAD8") /* CRT BP 8-bit add table (for ") */\
crtsym(CRT_BPAD9, "$BPAD9") /* CRT BP 9-bit add table (for ") */\
crtsym(CRT_BPADH, "$BPADH") /* CRT BP 18-bit add table (for ") */\
crtsym(CRT_BPCNT, "$BPCNT") /* CRT Byte ptr auxiliary */\
crtsym(CRT_SUBBP, "$SUBBP") /* CRT Byte ptr subtraction aux */\
crtsym(CRT_DFIX, "$DFIX") /* CRT Aux for (int) (double) cast */\
crtsym(CRT_DFIXS, "$DFIXS") /* CRT Aux for (int) (double) cast */\
crtsym(CRT_DFLTS, "$DFLTS") /* CRT Aux for (double) (int) cast */\
crtsym(CRT_SPUSH, "$NSPUSH") /* CRT Aux to put struct on stack */\
crtsym(CRT_SPOP, "$NSPOP") /* CRT Aux to get struct from stack */\
/* KAR-1/92, added symbol for null pointer det. function */\
crtsym(CRT_NPD, "$CFNP") /* Null pointer det. function */
#endif
#define crtsym(idx, sym) idx,
enum { crtsyms CRT_N }; /* Define the CRT_ indices plus count */
#undef crtsym
static int crtref[CRT_N]; /* Table of CRT sym reference counts */
#define crtsym(idx, sym) sym,
static char *crtsnam[CRT_N] = { crtsyms }; /* Table of CRT symbol names */
#undef crtsym
/*
* outinit
*
* Per-module initialization of MACRO output.
*/
void
outinit (void)
{
int i;
for (i = CRT_N; --i >= 0;) /* Reset reference counts */
crtref[i] = 0;
/*
* These two runtime symbols are ALWAYS implicitly referenced;
* they refer to the CRT and CPU runtime modules.
* See outdone () for a special reset check, though.
*/
++crtref[CRT_CRT];
++crtref[CRT_CPU];
outpreamble (); /* Output assembler preamble */
whichseg = 1; /* Now starting in code section */
}
/*
* outfile
*
* Output filename as data for null pointer detection
*/
static
void
outfile (void)
{
int i = 0;
int slen = strlen (inpfname);
char tmp[4] = {0};
char *tfname = inpfname;
outstr ("\n$NPDFN:");
do
{
if (! (i % 4))
outstr ("\n\tBYTE (9) ");
else
outstr (", ");
sprintf (tmp, "%o", *tfname);
outstr (tmp);
tfname++;
i++;
}
while (i < slen);
}
/*
* outnpd
*
* Output code for Null Pointer Detection; added by KAR-1/92
*/
static
void
outnpd (PCODE *p)
{
char line[20] = {0};
char label[6] = {0};
static int lbl_num = 0;
sprintf (label, "$N%o", lbl_num++);
outstr ("SKIPE\t");
outaddress (p);
outnl ();
outstr ("\t JRST\t");
outstr (label);
outnl ();
outstr ("\tPUSH\t17,[");
sprintf (line, "%o]\n", p->p_im.p_chnl); /* used chnl to store line # */
outstr (line);
#ifdef MULTI_SECTION /* FW 2A (51) */
outstr ("\tPUSH\t17,[$$BP90+$$SECT,,$NPDFN]\n");
#else
outstr ("\tPUSH\t17,[$$BP90,,$NPDFN]\n");
#endif
outstr ("\tPUSHJ\t17,$CFNP\n");
outstr ("\tADJSP\t17,-2\n");
outstr (label);
outstr ("==.");
if (mlist)
oline += 7;
}
/*
* outpreamble
*
* Emit the MACRO "preamble".
*/
static
void
outpreamble (void)
{
outstr ("\tTITLE\t"); /* Make TITLE pseudo-op */
if (module_pragma)
outstr (title);
else
outstr (inpfmodule); /* with name of input file as title */
outnl ();
/*
* Output the assembler header, either by generating it
* ourself or copying it from a user-specified file.
*/
outasmh ();
}
/*
* outdone
*
* Per-module completion
*/
void
outdone (int mainf)
{
register int i;
register SYMBOL *s;
static char old_mainf = 0;
if (old_mainf)
mainf = 0;
else
old_mainf = mainf;
/* KAR-1/92, output string for filename */
/* Output filename string ($NPDFN) if null ptr detection active */
if (debcsi == KCC_DBG_NULL)
outfile ();
outnl ();
codeseg (); /* make sure in code segment */
outstr ("\n\tLIT\n");
if (mlist)
oline += 2;
/* "main" module needs entry vector set. This crock is necessary
** because FAIL requires that the arg to END be defined in the current
** module!
*/
if (mainf)
{
if (mlist)
oline += 4;
outstr ("$$STRT: JRST $START##\n");
outstr ("\tJRST $START+1\n");
outstr ("\t0\n"); /* 3rd wd for T20 ver info */
++crtref[CRT_START];
}
switch (abs (debcsi))
{
void outsymtab (void);
case KCC_DBG_SDBG:
case KCC_DBG_FDBG: /* FW 2A (42) PPS4575 */
outsymtab ();
break;
default:
break;
}
/* Output EXTERN declarations for any C runtime symbols we used */
/* Normally the CPU and CRT modules are always reffed, but just
** to make life easier for us KCC implementors, we check here
** for compiling those modules themselves, and avoid sending out
** an EXTERN if so!
*/
/* EXTERN for $$$CRT */
if ((!mainf) ||
(s = symfidstr ("`$$$CRT")) != NULL && s->Sclass == SC_EXTDEF)
crtref[CRT_CRT] = 0; /* Is defined, pretend not reffed */
if ((s = symfidstr ("`$$$CPU")) != NULL && s->Sclass == SC_EXTDEF)
crtref[CRT_CPU] = 0; /* Is defined, pretend not reffed */
if (debcsi == KCC_DBG_NULL)
{
crtref[CRT_BP90]++;
#ifdef MULTI_SECTION /* FW 2A (51) */
crtref[CRT_SECT]++;
#endif
crtref[CRT_NPD]++;
}
/* Emit symbol requests for all referenced C runtime support stuff */
for (i = CRT_N; --i >= 0; )
{
if (crtref[i] && i != CRT_START)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -