Pristine Ack-5.5
[Ack-5.5.git] / mach / i386 / ce / as.c
1 #include "arg_type.h"
2 #include "as.h"
3
4 #define last( s)        ( s + strlen( s) - 1)
5 #define LEFT    '('
6 #define RIGHT   ')'
7 #define DOLLAR  '$'
8
9 block_assemble( instr, nr, first, Last)
10 char **instr;
11 int nr, first, Last;
12 {
13         int i;
14
15 /*
16         if ( first) {
17                 if( strncmp( instr[0], "pop", 3) == 0) {
18                         *instr[0] = 'P';
19                         *( instr[0]+1) = 'O';
20                         *( instr[0]+2) = 'P';
21                 }
22                 else
23                         @clean_push_buf();
24         }
25         if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
26                         *instr[nr-1] = 'P';
27                         *( instr[nr-1]+1) = 'U';
28                         *( instr[nr-1]+2) = 'S';
29                         *( instr[nr-1]+3) = 'H';
30         }
31 */
32         for( i=0; i<nr; i++)
33                 assemble( instr[i]);
34 }
35
36
37 process_label( l)
38 char *l;
39 {
40 }
41
42
43 process_mnemonic( m)
44 char *m;
45 {
46 }
47
48
49 process_operand( str, op)
50 char *str;
51 struct t_operand *op;
52
53 /*      expr            ->      IS_DATA en IS_LABEL
54  *      reg             ->      IS_REG en IS_ACCU
55  *      (expr)          ->      IS_ADDR
56  *      expr(reg)       ->      IS_MEM
57  */
58 {
59         char *ptr, *strindex();
60
61         op->type = UNKNOWN;
62         if ( *last( str) == RIGHT) {
63                 ptr = strindex( str, LEFT);
64                 *last( str) = '\0';
65                 *ptr = '\0';
66                 if ( is_reg( ptr+1, op)) {
67                         op->type = IS_MEM;
68                         op->expr = ( *str == '\0' ? "0" : str);
69                 }
70                 else {
71                         set_label( ptr+1, op);
72                         op->type = IS_ADDR;
73                 }
74         }
75         else
76                 if ( is_reg( str, op))
77                         op->type = IS_REG;
78                 else {
79                         if ( contains_label( str))
80                                 set_label( str, op);
81                         else {
82                                 op->type = IS_DATA;
83                                 op->expr = str;
84                         }
85                 }
86 }
87
88 static struct regnam {
89         char *regstr;
90         int regval;
91 } regnam[] = {
92         { "eax", 0 },
93         { "ebx", 3 },
94         { "ecx", 1 },
95         { "edx", 2 },
96         { "esp", 4 },
97         { "ebp", 5 },
98         { "esi", 6 },
99         { "edi", 7 },
100         { "al", 0 },
101         { "bl", 3 },
102         { "cl", 1 },
103         { "dl", 2 },
104         { "ah", 4 },
105         { "bh", 7 },
106         { "ch", 5 },
107         { "dh", 6 },
108         { 0, 0}
109 }
110 ;
111
112 int is_reg( str, op)
113 char *str;
114 struct t_operand *op;
115 {
116         register struct regnam *p = regnam;
117
118         while (p->regstr) {
119                 if (! strcmp(p->regstr, str)) {
120                         op->reg = p->regval;
121                         return TRUE;
122                 }
123                 p++;
124         }
125         return FALSE;
126 }
127
128 #include <ctype.h>
129 #define  isletter( c)   ( isalpha( c) || c == '_')
130
131 int contains_label( str)
132 char *str;
133 {
134         while( !isletter( *str) && *str != '\0')
135                 if ( *str == '$')
136                         if ( arg_type( str) == STRING)
137                                 return( TRUE);
138                         else
139                                 str += 2;
140                 else
141                         str++;
142
143         return( isletter( *str));
144 }
145
146 set_label( str, op)
147 char *str;
148 struct t_operand *op;
149 {
150         char *ptr, *strindex(), *sprint();
151         static char buf[256];
152
153         ptr = strindex( str, '+');
154
155         if ( ptr == 0)
156                 op->off = "0";
157         else {
158                 *ptr = '\0';
159                 op->off = ptr + 1;
160         }
161
162         if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
163              *(str+2) == '\0') {
164                 *(str+1) = '\0';        /* remove b or f! */
165                 op->lab = str;
166                 op->type = IS_ILB;
167         }
168         else {
169                 op->type = IS_LABEL;
170                 if ( strindex( str, DOLLAR) != 0)
171                         op->lab = str;
172                 else 
173                         op->lab = sprint( buf, "\"%s\"", str);
174         }
175 }
176
177
178 /******************************************************************************/
179
180
181
182 mod_RM( reg, op)
183 int reg;
184 struct t_operand *op;
185 {
186         if ( REG( op))
187                 R233( 0x3, reg, op->reg);
188         else if ( ADDR( op)) {
189                 R233( 0x0, reg, 0x5);
190                 @reloc4( %$(op->lab), %$(op->off), ABSOLUTE);
191         }
192         else if ( strcmp( op->expr, "0") == 0)
193                 switch( op->reg) {
194                   case AX:
195                   case BX:
196                   case CX:
197                   case DX:
198                   case DI:
199                   case SI:  R233( 0x0, reg, op->reg);
200                             break;
201
202                   case BP : R233( 0x1, reg, 0x6);       /* Exception! */
203                             @text1( 0);
204                             break;
205
206                   default : fprint( STDERR, "Wrong index register %d\n",
207                                     op->reg);
208                 }
209         else {
210             if (isdigit(op->expr[0])) {
211                 long l, atol();
212
213                 l = atol(op->expr);
214                 if ( l <= 127 && l >= -128) {
215                         switch( op->reg) {
216                           case AX:
217                           case BX:
218                           case CX:
219                           case DX:
220                           case DI:
221                           case BP:
222                           case SI : R233( 0x1, reg, op->reg);
223                                     break;
224         
225                           default : fprint( STDERR, "Wrong index register %d\n",
226                                             op->reg);
227                         }
228                         @text1( %$(op->expr));
229                 } else {
230                         switch( op->reg) {
231                           case AX:
232                           case BX:
233                           case CX:
234                           case DX:
235                           case DI:
236                           case BP:
237                           case SI : R233( 0x2, reg, op->reg);
238                                     break;
239         
240                           default : fprint( STDERR, "Wrong index register %d\n",
241                                             op->reg);
242                         }
243                         @text4( %$(op->expr));
244                 }
245             } else {
246                 @if ( fit_byte( %$(op->expr)))
247                         switch( op->reg) {
248                           case AX:
249                           case BX:
250                           case CX:
251                           case DX:
252                           case DI:
253                           case BP:
254                           case SI : R233( 0x1, reg, op->reg);
255                                     break;
256         
257                           default : fprint( STDERR, "Wrong index register %d\n",
258                                             op->reg);
259                         }
260                         @text1( %$(op->expr));
261                 @else
262                         switch( op->reg) {
263                           case AX:
264                           case BX:
265                           case CX:
266                           case DX:
267                           case DI:
268                           case BP:
269                           case SI : R233( 0x2, reg, op->reg);
270                                     break;
271         
272                           default : fprint( STDERR, "Wrong index register %d\n",
273                                             op->reg);
274                         }
275                         @text4( %$(op->expr));
276                 @fi
277             }
278         }
279 }
280
281 mv_RG_EADDR( dst, src)
282 struct t_operand *dst, *src;
283 {
284         if ( REG(src) && dst->reg == src->reg)
285                 ; /* Nothing!! result of push/pop optimization */
286         else {
287                 @text1( 0x8b);
288                 mod_RM( dst->reg, src);
289         }
290 }
291
292
293 R233( a, b, c)
294 int a,b,c;
295 {
296         @text1( %d( (a << 6) | ( b << 3) | c));
297 }
298
299
300 R53( a, b)
301 int a,b;
302 {
303         @text1( %d( (a << 3) | b));
304 }
305
306 small_const(opc, src)
307         struct t_operand *src;
308 {
309         if (isdigit(src->expr[0])) {
310                 long l, atol();
311
312                 l = atol(src->expr);
313                 if (l >= -128 && l <= 127) {
314                         @text1(%d(opc|02));
315                         @text1(%$(src->expr));
316                 }
317                 else {
318                         @text1(%d(opc));
319                         @text4(%$(src->expr));
320                 }
321         }
322         else {
323                 @if (fit_byte(%$(src->expr)))
324                         @text1(%d(opc|02));
325                         @text1(%$(src->expr));
326                 @else
327                         @text1(%d(opc));
328                         @text4(%$(src->expr));
329                 @fi
330         }
331 }
332
333 small_RMconst(opc, reg, dst, src)
334         struct t_operand *dst, *src;
335 {
336         if (isdigit(src->expr[0])) {
337                 long l, atol();
338
339                 l = atol(src->expr);
340                 if (l >= -128 && l <= 127) {
341                         @text1(%d(opc|02));
342                         mod_RM(reg, dst);
343                         @text1(%$(src->expr));
344                 }
345                 else {
346                         @text1(%d(opc));
347                         mod_RM(reg, dst);
348                         @text4(%$(src->expr));
349                 }
350         }
351         else {
352                 @if (fit_byte(%$(src->expr)))
353                         @text1(%d(opc|02));
354                         mod_RM(reg, dst);
355                         @text1(%$(src->expr));
356                 @else
357                         @text1(%d(opc));
358                         mod_RM(reg, dst);
359                         @text4(%$(src->expr));
360                 @fi
361         }
362 }