133 lines
2.2 KiB
C
133 lines
2.2 KiB
C
#define RCSID5 "$Id$"
|
|
|
|
/*
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
*
|
|
*/
|
|
|
|
void op1(int mode)
|
|
{
|
|
int relpc = 0;
|
|
if (im1flag) {
|
|
if (mode == 067 || mode == 077) {
|
|
exp_1.val = adjust(exp_1);
|
|
relpc = RELPC;
|
|
}
|
|
#ifdef RELOCATION
|
|
RELOMOVE(relonami, rel_1);
|
|
if (rflag != 0 && PASS_RELO)
|
|
newrelo(exp_1.typ, RELO2|relpc);
|
|
#endif
|
|
emit2(exp_1.val);
|
|
im1flag = 0;
|
|
}
|
|
}
|
|
|
|
void op2(int mode)
|
|
{
|
|
int relpc = 0;
|
|
if (im2flag) {
|
|
if (mode == 067 || mode == 077) {
|
|
relpc = RELPC;
|
|
exp_2.val = adjust(exp_2);
|
|
}
|
|
#ifdef RELOCATION
|
|
RELOMOVE(relonami, rel_2);
|
|
if (rflag != 0 && PASS_RELO)
|
|
newrelo(exp_2.typ, RELO2|relpc);
|
|
#endif
|
|
emit2(exp_2.val);
|
|
im2flag = 0;
|
|
}
|
|
}
|
|
|
|
void branch(int opc,expr_t exp)
|
|
{
|
|
register int eval;
|
|
register int sm;
|
|
|
|
eval = adjust(exp) >> 1;
|
|
sm = fitb(eval);
|
|
if ((exp.typ & ~S_DOT) != DOTTYP && pass >= PASS_2) sm = 0;
|
|
if (!sm && pass >= PASS_2) {
|
|
serror("label too far");
|
|
}
|
|
emit2(opc | lowb(eval));
|
|
}
|
|
|
|
void ejump(int opc, expr_t exp)
|
|
{
|
|
register int sm,eval;
|
|
int gain;
|
|
|
|
# ifdef THREE_PASS
|
|
eval = adjust(exp) >> 1;
|
|
sm = fitb(eval);
|
|
if ((exp.typ & ~S_DOT) != DOTTYP) {
|
|
sm = 0;
|
|
}
|
|
gain = (opc == OPBRA ? 2 : 4);
|
|
if (small(sm,gain)) {
|
|
emit2( opc | lowb(eval));
|
|
}
|
|
else {
|
|
# endif
|
|
if (opc != OPBRA) {
|
|
emit2((opc^0400) | 02);
|
|
}
|
|
|
|
exp_1 = exp;
|
|
im1flag = 1;
|
|
emit2(0100|067);
|
|
op1(067);
|
|
# ifdef THREE_PASS
|
|
}
|
|
# endif
|
|
}
|
|
|
|
void sob(int reg, expr_t exp)
|
|
{
|
|
if ((exp.typ & ~S_DOT) != DOTTYP) {
|
|
serror("error in sob-label");
|
|
}
|
|
exp.val = ( - adjust(exp) ) >> 1;
|
|
fit(fit6(exp.val));
|
|
emit2( OPSOB | (reg << 6) | exp.val);
|
|
}
|
|
|
|
int jump(int opc,int opr)
|
|
{
|
|
register int val;
|
|
|
|
# ifdef THREE_PASS
|
|
if (opr==067) {
|
|
register int sm = 0;
|
|
|
|
val = adjust(exp_1) >> 1;
|
|
if ( fitb(val) && (exp_1.typ & ~S_DOT) == DOTTYP) {
|
|
sm = 1;
|
|
}
|
|
if (small(sm,2)) {
|
|
emit2(OPBRA | lowb(val));
|
|
im1flag = 0;
|
|
return(0);
|
|
}
|
|
}
|
|
# endif
|
|
emit2(opc | opr);
|
|
op1(opr);
|
|
return(0);
|
|
}
|
|
|
|
valu_t adjust(expr_t exp)
|
|
{
|
|
valu_t val;
|
|
|
|
val = exp.val - DOTVAL - 2;
|
|
# ifdef THREE_PASS
|
|
if (pass == PASS_2 && val > 0) val -= DOTGAIN;
|
|
# endif
|
|
return(val);
|
|
}
|