Pristine Ack-5.5
[Ack-5.5.git] / mach / 6809 / as / mach5.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 #define RCSID5 "$Id: mach5.c,v 3.6 1994/06/24 12:56:31 ceriel Exp $"
6
7 /*
8  * Motorola 6809 special routines
9  */
10
11 branch(opc, exp)
12 register int    opc;
13 expr_t          exp;
14 {
15         register int    sm, dist;
16         int             saving;
17
18         dist = exp.val - (DOTVAL + 2);
19         if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
20                 dist -= DOTGAIN;
21         sm = fitb(dist);
22         if ((exp.typ & ~S_DOT) != DOTTYP)
23                 sm = 0;
24         if (opc == 0x8D || opc == 0x20)
25                 saving = 1;
26         else
27                 saving = 2;
28         if ((sm = small(sm,saving)) == 0) {
29                 dist--;
30                 if (opc == 0x8D)        /* bsr */
31                         opc = 0x17;
32                 else if (opc == 0x20)   /* bra */
33                         opc = 0x16;
34                 else {
35                         emit1(0x10);
36                         dist--;
37                 }
38         }
39         emit1(opc);
40         if (sm == 0) {
41 #ifdef RELOCATION
42                 if (rflag != 0 && PASS_RELO)
43                         newrelo(exp.typ, RELPC|RELO2|RELBR);
44 #endif
45                 emit2(dist);
46         } else
47                 emit1(lowb(dist));
48 }
49
50 regno(r) register r; {
51         switch (r) {
52         case X: return 0;
53         case Y: return 0x20;
54         case U: return 0x40;
55         case S: return 0x60;
56         }
57         return -1;
58 }
59
60 emit1or2(n) {
61         if (n & ~0xFF)
62                 emit1(n >> 8);
63         emit1(n);
64 }
65
66 offset(reg, exp, ind)
67 register int    reg, ind;
68 expr_t          exp;
69 {
70         if (reg == PC) {
71                 int     sm, dist;
72
73                 dist = exp.val - (DOTVAL + 2);
74                 if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
75                         dist -= DOTGAIN;
76                 sm = fitb(dist);
77                 if ((exp.typ & S_TYP) != DOTTYP)
78                         sm = 0;
79                 if (small(sm,1)) {
80                         emit1(0x8C + ind);
81                         emit1(dist);
82                 } else {
83                         emit1(0x8D + ind);
84                         emit1((dist-1)>>8);
85                         emit1(dist - 1);
86                 }
87         } else if ((reg = regno(reg)) < 0)
88                 serror("register error");
89         else if ((exp.typ & S_TYP) == S_ABS && exp.val == 0)
90                 emit1(0x84 + reg + ind);        /* XOP 0, REG == XOP , REG */
91         else if (ind == 0 && (exp.typ & S_TYP) == S_ABS &&
92                  -16 <= exp.val && exp.val <= 15
93                 )
94                 emit1(reg + ind + (exp.val & 037));
95         else if ((exp.typ&S_TYP)==S_ABS && -128<=exp.val && exp.val<=127) {
96                 emit1(0x88 + reg + ind);
97                 emit1(exp.val);
98         } else {
99                 emit1(0x89 + reg + ind);
100 #ifdef RELOCATION
101                 if (rflag != 0 && PASS_RELO)
102                         newrelo(exp.typ, RELO2|RELBR);
103 #endif
104                 emit2(exp.val);
105         }
106 }