Pristine Ack-5.5
[Ack-5.5.git] / mach / pdp / as / mach5.c
1 #define RCSID5 "$Id: mach5.c,v 1.8 1994/06/24 13:11:25 ceriel Exp $"
2
3 /*
4  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
5  * See the copyright notice in the ACK home directory, in the file "Copyright".
6  *
7  */
8
9 op1(mode)       {
10         int relpc = 0;
11         if (im1flag)    {
12                 if (mode == 067 || mode == 077) {
13                         exp_1.val = adjust(exp_1);
14                         relpc = RELPC;
15                 }
16 #ifdef RELOCATION
17                 RELOMOVE(relonami, rel_1);
18                 if (rflag != 0 && PASS_RELO)
19                         newrelo(exp_1.typ, RELO2|relpc);
20 #endif
21                 emit2(exp_1.val);
22                 im1flag = 0;
23         }
24 }
25
26 op2(mode)       {
27         int relpc = 0;
28         if (im2flag)    {
29                 if (mode == 067 || mode == 077) {
30                         relpc = RELPC;
31                         exp_2.val = adjust(exp_2);
32                 }
33 #ifdef RELOCATION
34                 RELOMOVE(relonami, rel_2);
35                 if (rflag != 0 && PASS_RELO)
36                         newrelo(exp_2.typ, RELO2|relpc);
37 #endif
38                 emit2(exp_2.val);
39                 im2flag = 0;
40         }
41 }
42
43 branch(opc,exp) expr_t exp; {
44         register eval;
45         register sm;
46
47         eval = adjust(exp) >> 1;
48         sm = fitb(eval);
49         if ((exp.typ & ~S_DOT) != DOTTYP && pass >= PASS_2) sm = 0;
50         if (!sm && pass >= PASS_2) {
51                 serror("label too far");
52         }
53         emit2(opc | lowb(eval));
54 }
55
56 ejump(opc, exp) expr_t exp; {
57         register sm,eval;
58         int gain;
59
60 # ifdef THREE_PASS
61         eval = adjust(exp) >> 1;
62         sm = fitb(eval);
63         if ((exp.typ & ~S_DOT) != DOTTYP)       {
64                 sm = 0;
65         }
66         gain = (opc == OPBRA ? 2 : 4);
67         if (small(sm,gain))     {
68                 emit2( opc | lowb(eval));
69         }
70         else    {
71 # endif
72                 if (opc != OPBRA)       {
73                         emit2((opc^0400) | 02);
74                 }
75
76                 exp_1 = exp;
77                 im1flag = 1;
78                 emit2(0100|067);
79                 op1(067);
80 # ifdef THREE_PASS
81         }
82 # endif
83 }
84
85 sob(reg, exp) expr_t exp; {
86         if ((exp.typ & ~S_DOT) != DOTTYP)       {
87                 serror("error in sob-label");
88         }
89         exp.val = ( - adjust(exp) ) >> 1;
90         fit(fit6(exp.val));
91         emit2( OPSOB | (reg << 6) | exp.val);
92 }
93
94 jump(opc,opr)   {
95         register val;
96
97 # ifdef THREE_PASS
98         if (opr==067) {
99                 register sm = 0;
100
101                 val = adjust(exp_1) >> 1;
102                 if ( fitb(val) && (exp_1.typ & ~S_DOT) == DOTTYP) {
103                         sm = 1;
104                 }
105                 if (small(sm,2)) {
106                         emit2(OPBRA | lowb(val));
107                         im1flag = 0;
108                         return(0);
109                 }
110         }
111 # endif
112         emit2(opc | opr);
113         op1(opr);
114 }
115
116 valu_t adjust(exp) expr_t exp; {
117         valu_t val;
118
119         val = exp.val - DOTVAL - 2;
120 # ifdef THREE_PASS
121         if (pass == PASS_2 && val > 0) val -= DOTGAIN;
122 # endif
123         return(val);
124 }