mirror of
https://github.com/PDP-10/PCC20.git
synced 2026-05-02 14:40:13 +00:00
298 lines
6.5 KiB
C
298 lines
6.5 KiB
C
/* cc86.c -- Code generator TOPS-20 (contd) (C) 1981 K. Chen */
|
||
|
||
#define sd extern
|
||
#include "cc.g"
|
||
|
||
/* --------------------------------- */
|
||
/* register-register codes */
|
||
/* --------------------------------- */
|
||
|
||
code0(op, r, s)
|
||
{
|
||
struct PSEUDO *p, *q;
|
||
int ty, qt, more;
|
||
|
||
if (op == LSHFT || op == RSHFT) { /* direct operand DEC-20 codes */
|
||
code4(op, r, s);
|
||
return;
|
||
~
|
||
|
||
p = previous;
|
||
if (op == LDB) {
|
||
if (p->pop == RELEASE) p = before(p);
|
||
if (p->pop == IDENT && p->ptype == INDEXED && p->preg == s) {
|
||
p->pop = LDB;
|
||
p->preg = r;
|
||
return;
|
||
~
|
||
~
|
||
|
||
if (p != NULL && optimize) {
|
||
if ((op == LDB || op == DPB) && p->pop == IBP) {
|
||
q = before(p);
|
||
if (q->ptype == GLOBAL && q->pop == IDENT && q->preg == s) {
|
||
|
||
/* fold: MOVE S,ident */
|
||
/* IBP ident */
|
||
/* DPB R,S */
|
||
/* */
|
||
/* into: DPB R,ident */
|
||
/* IBP ident */
|
||
|
||
if (s != r) release(s);
|
||
q->preg = r;
|
||
q->pop = op;
|
||
return;
|
||
~
|
||
~
|
||
if (p->pop == IDENT && p->preg == s) {
|
||
ty = p->ptype;
|
||
if (ty == GLOBAL || ty == IMMED ||
|
||
ty == BYTEPOINT || ty == INDEXED ||
|
||
(codesection==0 && (ty == GLOBAL || ty == IINDEXED))) {
|
||
|
||
/* fold: MOVE(*) S,ident */
|
||
/* OP R,S */
|
||
/* */
|
||
/* into: OP(*) R,ident */
|
||
|
||
p->pop = op;
|
||
p->preg = r;
|
||
if (op == FNARG) return;
|
||
if (s != r) regis[s] = -1;
|
||
q = before(p);
|
||
|
||
if (p->pop == IDENT && p->ptype == IMMED &&
|
||
q->ptype == GADDR && q->pop == IDENT && q->preg == r) {
|
||
p->pop = NOP;
|
||
q->poffset += p->pvalue;
|
||
previous = q;
|
||
return;
|
||
~
|
||
|
||
if (q->pop == SETZ && q->ptype == ONEREG && q->preg == r) {
|
||
if (op == ADJBP) {
|
||
|
||
/* fold: SETZ S, */
|
||
/* ADJBP R,a */
|
||
/* */
|
||
/* into: MOVE R,a */
|
||
|
||
q->pop = NOP; /* poof! */
|
||
p->pop = IDENT;
|
||
return;
|
||
~
|
||
~
|
||
if (q->pop == PLUS && op == PLUS && q->preg == r) {
|
||
switch (q->ptype) {
|
||
case IMMED:
|
||
switch (ty) {
|
||
case GADDR:
|
||
|
||
/* fold: ADDI R,5 */
|
||
/* ADDI R,ident */
|
||
/* */
|
||
/* into: ADDI R,ident+5 */
|
||
|
||
p->pop = NOP; /* poof! */
|
||
q->ptype = GADDR;
|
||
q->pptr = p->pptr;
|
||
q->poffset = q->poffset + p->poffset;
|
||
previous = q;
|
||
return;
|
||
|
||
case IMMED:
|
||
/* fold: ADDI R,5 */
|
||
/* ADDI R,6 */
|
||
/* */
|
||
/* into: ADDI R,6+5 */
|
||
|
||
case IINDEXED:
|
||
|
||
/* fold: ADDI R,5 */
|
||
/* ADDI R,4(SP) */
|
||
/* */
|
||
/* into: ADDI R,9(SP) */
|
||
|
||
q->pop = NOP; /* poof! */
|
||
p->pvalue = q->pvalue + p->pvalue;
|
||
return;
|
||
default:
|
||
fprintf(stderr,"Problem 1\n");
|
||
~
|
||
break;
|
||
|
||
case GADDR:
|
||
if (ty == IMMED) {
|
||
|
||
/* fold: ADDI R,ident+d */
|
||
/* ADDI R,c */
|
||
/* */
|
||
/* into: ADDI R,ident+c+d */
|
||
|
||
p->pop = NOP; /* poof! */
|
||
q->poffset = q->poffset + p->pvalue;
|
||
previous = q;
|
||
return;
|
||
~
|
||
~
|
||
~
|
||
return;
|
||
~
|
||
~
|
||
~
|
||
|
||
if (p != NULL && p->pop == SETZ && p->ptype == ONEREG && p->preg == s) {
|
||
if (op == PLUS || op == MINUS) {
|
||
|
||
/* fold: SETZ S, */
|
||
/* ADD R,S */
|
||
/* */
|
||
/* into: null */
|
||
|
||
p->pop = NOP; /* poof! */
|
||
previous = before(p);
|
||
release(s);
|
||
return;
|
||
~
|
||
~
|
||
p = previous;
|
||
|
||
/* fold: MOVE S,ident */
|
||
/* ... */
|
||
/* ADDI S,const */
|
||
/* ... */
|
||
/* ADD R,S */
|
||
/* */
|
||
/* into: ADD R,ident */
|
||
/* ... */
|
||
/* ADDI S,const */
|
||
|
||
if (optimize && codesection==0 && op==PLUS) {
|
||
more = 1;
|
||
while (more) {
|
||
if (p->preg == r || p->pop == GLABEL || p->pop == CLABEL) break;
|
||
if (p->preg == s) {
|
||
switch (p->pop) {
|
||
case IDENT:
|
||
p->pop = PLUS;
|
||
p->preg = r;
|
||
release(s);
|
||
return;
|
||
case PLUS:
|
||
p->preg = r;
|
||
break;
|
||
default:
|
||
more = 0;
|
||
~
|
||
~
|
||
if ((p = before(p)) == NULL) break;
|
||
~
|
||
~
|
||
/* fold: MOVE S,ident */
|
||
/* ... */
|
||
/* LDB R,S */
|
||
/* */
|
||
/* into: LDB R,ident */
|
||
/* ... */
|
||
|
||
/* fold: IBP ident */
|
||
/* ... */
|
||
/* MOVE S,ident */
|
||
/* ... */
|
||
/* LDB R,S */
|
||
/* */
|
||
/* into: ... */
|
||
/* ILDB R,ident */
|
||
/* ... */
|
||
|
||
if (optimize && (op==LDB || op==DPB)) {
|
||
while (p != NULL) {
|
||
if (p->preg == r || p->pop == GLABEL || p->pop == CLABEL) break;
|
||
if (p->preg == s) {
|
||
if (p->pop == IDENT) {
|
||
p->pop = op;
|
||
p->preg = r;
|
||
release(s);
|
||
q=p;
|
||
while ((q = before(q)) != NULL) {
|
||
if (q->preg == r || q->pop == CLABEL ||
|
||
q->pop == GLABEL) break;
|
||
if (q->ptype == SINGLE && q->pop == IBP &&
|
||
p->pptr == q->pptr && q->poffset == p->poffset) {
|
||
q->pop = (p->pop==LDB) ? ILDB : IDPB;
|
||
q->preg = r;
|
||
q->ptype = p->ptype;
|
||
p->pop = NOP;
|
||
~
|
||
~
|
||
return;
|
||
~
|
||
else break;
|
||
~
|
||
p = before(p);
|
||
~
|
||
~
|
||
|
||
previous = &codes[maxcode&(MAXCODE-1)];
|
||
previous->ptype = REGIS;
|
||
previous->pop = op;
|
||
previous->pr1 = r;
|
||
previous->pr2 = s;
|
||
maxcode++;
|
||
release(s);
|
||
~
|
||
|
||
/* --------------------------------- */
|
||
/* register-constant codes */
|
||
/* --------------------------------- */
|
||
|
||
code1(op, r, s)
|
||
{
|
||
struct PSEUDO *p;
|
||
|
||
if (!s && op != IDENT) return;
|
||
p = previous;
|
||
|
||
if (p->ptype == GADDR && p->preg == r && optimize) {
|
||
if (op == HRL && p->pop == IDENT) {
|
||
p->poffset += s;
|
||
p->ptype = BYTEPOINT;
|
||
return;
|
||
~
|
||
else if (op == PLUS) {
|
||
p->poffset = p->poffset + s;
|
||
return;
|
||
~
|
||
~
|
||
if (op == IDENT && s == 0) return code5(SETZ, r);
|
||
|
||
previous = &codes[maxcode&(MAXCODE-1)];
|
||
previous->ptype = IMMED;
|
||
previous->pop = op;
|
||
previous->preg = r;
|
||
previous->pvalue = s;
|
||
maxcode++;
|
||
~
|
||
|
||
/* ------------------------------------------ */
|
||
/* register-global identifier codes */
|
||
/* ------------------------------------------ */
|
||
|
||
code2(op, r, s)
|
||
struct SYMBOL *s;
|
||
{
|
||
struct PSEUDO *p, *b;
|
||
|
||
b = previous;
|
||
previous = &codes[maxcode&(MAXCODE-1)];
|
||
previous->ptype = GLOBAL;
|
||
previous->pop = op;
|
||
previous->preg = r;
|
||
previous->pptr = s;
|
||
previous->poffset = 0;
|
||
previous->pindex = 0;
|
||
if (b->pop == SETZ && b->pop == ONEREG) swappseudo(p,b);
|
||
maxcode++;
|
||
~
|
||
|