ack/mach/6809/as/mach5.c

107 lines
2 KiB
C
Raw Normal View History

1987-03-09 16:02:32 +00:00
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
1985-06-10 15:32:18 +00:00
#define RCSID5 "$Header$"
/*
* Motorola 6809 special routines
*/
branch(opc, exp)
register int opc;
expr_t exp;
{
register int sm, dist;
int saving;
dist = exp.val - (DOTVAL + 2);
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
dist -= DOTGAIN;
sm = fitb(dist);
if ((exp.typ & ~S_DOT) != DOTTYP)
sm = 0;
if (opc == 0x8D || opc == 0x20)
saving = 1;
else
saving = 2;
if ((sm = small(sm,saving)) == 0) {
dist--;
if (opc == 0x8D) /* bsr */
opc = 0x17;
else if (opc == 0x20) /* bra */
opc = 0x16;
else {
emit1(0x10);
dist--;
}
}
emit1(opc);
if (sm == 0) {
#ifdef RELOCATION
1986-12-08 10:39:13 +00:00
if (rflag != 0 && PASS_RELO)
newrelo(exp.typ, RELPC|RELO2|RELBR);
1985-06-10 15:32:18 +00:00
#endif
emit2(dist);
} else
emit1(lowb(dist));
}
regno(r) register r; {
switch (r) {
case X: return 0;
case Y: return 0x20;
case U: return 0x40;
case S: return 0x60;
}
return -1;
}
emit1or2(n) {
if (n & ~0xFF)
emit1(n >> 8);
emit1(n);
}
offset(reg, exp, ind)
register int reg, ind;
expr_t exp;
{
if (reg == PC) {
int sm, dist;
dist = exp.val - (DOTVAL + 2);
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
dist -= DOTGAIN;
sm = fitb(dist);
if ((exp.typ & S_TYP) != DOTTYP)
sm = 0;
1986-12-05 16:36:40 +00:00
if (small(sm,1)) {
1985-06-10 15:32:18 +00:00
emit1(0x8C + ind);
emit1(dist);
} else {
emit1(0x8D + ind);
1986-12-05 16:36:40 +00:00
emit1((dist-1)>>8);
1985-06-10 15:32:18 +00:00
emit1(dist - 1);
}
} else if ((reg = regno(reg)) < 0)
serror("register error");
else if ((exp.typ & S_TYP) == S_ABS && exp.val == 0)
emit1(0x84 + reg + ind); /* XOP 0, REG == XOP , REG */
else if (ind == 0 && (exp.typ & S_TYP) == S_ABS &&
-16 <= exp.val && exp.val <= 15
)
emit1(reg + ind + (exp.val & 037));
else if ((exp.typ&S_TYP)==S_ABS && -256<=exp.val && exp.val<=255) {
emit1(0x88 + reg + ind);
emit1(exp.val);
} else {
emit1(0x89 + reg + ind);
#ifdef RELOCATION
1986-12-08 10:39:13 +00:00
if (rflag != 0 && PASS_RELO)
newrelo(exp.typ, RELO2|RELBR);
1985-06-10 15:32:18 +00:00
#endif
emit2(exp.val);
}
}