Pristine Ack-5.5
[Ack-5.5.git] / mach / z8000 / as / mach4.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 RCSID4 "$Id: mach4.c,v 0.3 1994/06/24 13:56:26 ceriel Exp $"
6
7 /*
8 ** Zilog z8000 yacc parsing rules
9 */
10 operation
11         : f1
12         | f2
13         | f3
14         | f4
15         | f5
16         | f6
17         | f7
18         | f8
19         | f9
20         ;
21
22
23 f1      : F1_1F2_3  dst
24                 { switch( ($1 & 0x0F00)>>8 ) {
25                   case 9:   case 0xF: chtype( DST, TYPE_11a23 );  break;
26                   case 0xC: case 0xD: chtype( DST, TYPE_11b23 );  break;
27                   }
28                   emit2( mode | $1 | $2<<4 );
29                   if ( mode>>12 == 4 ) emit_ad( addr_inf );
30                 }
31         | F1_1a  reg
32                 { chreg( $1, $2 );
33                   emit2( $1 | $2<<4 );
34                 }
35         | F1_1b  reg  option
36                 { if ( $3 != 1 && $3 != 2 )  argerr();
37                   emit2( $1 | $2<<4 | ($3-1)<<1 );
38                 }
39         | F1_2  dst  option
40                 { chtype( DST, TYPE_12 );
41                   fit(fit4($3-1));
42                   emit2( mode | $1 | $2<<4 | $3-1 );
43                   if ( mode>>12 == 4 ) emit_ad( addr_inf );
44                 }
45         | LDK  reg  ','  imexpr
46                 { fit(fit4($4));
47                   emit2( $1 | $2<<4 | $4 );
48                 }
49         | F1_2F6_3  dst  ','  src
50                 { if ( oprtype[ DST ] == REG && oprtype[ SRC ] == REG )
51                   {   emit2( $1 | $4 );
52                       emit2( $2<<8 );
53                   }
54                   else if ( oprtype[ SRC ] == IM )
55                   {   chtype( DST, TYPE_1263 );
56                       if ((immed.typ & ~S_EXT) != S_ABS) {
57                         serror("must be absolute");
58                       }
59                       if ( bitset($1,8) ) /* word */  fit(fit4(immed.val));
60                       else /* byte */  fit(fit3(immed.val));
61                       emit2( mode | $1 | $2<<4 | (int)immed.val );
62                       if ( mode>>12 == 4 ) emit_ad( addr_inf );
63                   }
64                   else  argerr();
65                 }
66         | JP  coco1  dst
67                 { chtype( DST, TYPE_jp );
68                   emit2( mode | $1 | $3<<4 | $2 );
69                   if ( mode>>12 == 4 ) emit_ad( addr_inf );
70                 }
71         | TCC  coco1  reg
72                 { emit2( $1 | $3<<4 | $2 );     }
73         ;
74
75
76 f2      : F2_1  reg  ','  src
77                 { switch( ($1 & 0xF000)>>12 )
78                   {   case 2: chtype( SRC, TYPE_21a );  break;
79                       case 3: chtype( SRC, TYPE_21b );  break;
80                   }
81                   emit2( mode | $1 | $4<<4 | $2 );
82                   if ( mode>>12 == 4 ) emit_ad( addr_inf );
83                 }
84         | F2_1F5_1  dst  ','  src
85                 { switch( oprtype[ DST ] )
86                   { case REG: chtype( SRC, TYPE_2151 );
87                               chreg( $1, $2 );
88                               emit2( mode | $1 | $4<<4 | $2 );
89                               break;
90                     case IR: case DA: case X:
91                               if ( oprtype[ SRC ] == IM
92                                 && ( $1 == 0x0B00 || $1 == 0x0A00   ) )
93                                     /* cp or cpb */
94                               {   setmode( DST );
95                                   emit2( mode | $1 + 0x201 | $2<<4 );
96                                   break;
97                               }
98                     default: argerr();
99                   }
100                   if ( mode>>12 == 4 ) emit_ad( addr_inf );
101                   if ( oprtype[ SRC ] == IM )
102                   {   if (bitset($1,8)) /* word */ {
103 #ifdef RELOCATION
104                         newrelo(immed.typ, RELO2|RELBR);
105 #endif
106                         emit2( (int)immed.val );
107                       }
108                       else if (bitset($1,12)) /* long */ {
109 #ifdef RELOCATION
110                         newrelo(immed.typ, RELO4|RELWR|RELBR);
111 #endif
112                         emit4( immed.val );
113                       }
114                       else /* byte */ {
115 #ifdef RELOCATION
116                         newrelo(immed.typ, RELO1);
117 #endif
118                         emit1((int) immed.val);
119                         /* emit1((int) immed.val); ??? twice ??? */
120                       }
121                   }
122                 }
123         | LDA  R32  ','  src
124                 { switch( oprtype[ SRC ] )
125                   {   case DA: case X: emit2( 0x7600 | $4<<4 | $2 );
126                                        emit_ad( addr_inf );
127                                        break;
128                       case BA:  emit2( 0x3400 | $4<<4 | $2 );
129 #ifdef RELOCATION
130                                 newrelo(displ.typ,RELO2|RELBR);
131 #endif
132                                 emit2( (int) displ.val );  break;
133                       case BX:  emit2( 0x7400 | $4<<4 | $2 );
134                                 emit2( index<<8 );  break;
135                       default:  argerr();
136                   }
137                 }
138         | POP  dst  ','  ir
139                 { chtype( DST, TYPE_pop );
140                   emit2( mode | $1 | $4<<4 | $2 );
141                   if ( mode>>12 == 4 ) emit_ad( addr_inf );
142                 }
143         | PUSH  ir  ','  src
144                 { chtype( SRC, TYPE_push );
145                   switch ( oprtype[ SRC ] )
146                   {   case IM: if ( $1 == 0x1100 ) /* pushl */ argerr();
147                             /* {   emit2( 0x9109 | $2<<4 );
148                             **     emit4( immed );
149                             ** }
150                             */
151                                else
152                                {   emit2( 0x0D09 | $2<<4 );
153 #ifdef RELOCATION
154                                    newrelo(immed.typ, RELO2|RELBR);
155 #endif
156                                    emit2( (int)immed.val );
157                                }
158                                break;
159                       default: emit2( mode | $1 | $2<<4 | $4 );
160                                if ( mode>>12 == 4 ) emit_ad( addr_inf );
161                   }
162                 }
163         | LD  dst  ','  src
164                 { if ( oprtype[ DST ] == REG )
165                   {   switch( oprtype[ SRC ] )
166                       {   case IM:
167                                if ( $1 == 0 )  /* ldb: F3.2 */
168                                {   /* fit(fits8(immed)); */
169                                    emit1( 0xC000 | $2<<8);
170 #ifdef RELOCATION
171                                    newrelo(immed.typ, RELO1);
172 #endif
173                                    emit1((int) immed.val);
174                                }
175                                else
176                                {   /*fit(fits16(immed));*/
177                                    emit2( 0x2100 | $2 );
178 #ifdef RELOCATION
179                                    newrelo(immed.typ, RELO2|RELBR);
180 #endif
181                                    emit2( (int)immed.val );
182                                }
183                                break;
184                           case REG: case IR: case DA: case X:
185                                setmode( SRC );
186                                emit2( mode | 0x2000 | $1 | $4<<4 | $2 );
187                                if ( mode>>12 == 4 ) emit_ad( addr_inf );
188                                break;
189                           case BA: emit2( 0x3000 | $1 | $4<<4 | $2 );
190 #ifdef RELOCATION
191                                    newrelo(displ.typ,RELO2|RELBR);
192 #endif
193                                    emit2( (int) displ.val );
194                                    break;
195                           case BX: emit2( 0x7000 | $1 | $4<<4 | $2 );
196                                    emit2( index<<8 );
197                                    break;
198                           default: argerr();
199                       }
200                       break;
201                   }
202                   if ( oprtype[ SRC ] == REG )
203                   {   switch( oprtype[ DST ] )
204                       {   case IR: case DA: case X:
205                                setmode( DST );
206                                emit2( mode | 0x2E00 | $1 | $2<<4 | $4 );
207                                if ( mode>>12 == 4 ) emit_ad( addr_inf );
208                                break;
209                           case BA: emit2( 0x3200 | $1 | $2<<4 | $4 );
210 #ifdef RELOCATION
211                                    newrelo(displ.typ,RELO2|RELBR);
212 #endif
213                                    emit2( (int) displ.val );
214                                    break;
215                           case BX: emit2( 0x7200 | $1 | $2<<4 | $4 );
216                                    emit2( index<<8 );
217                                    break;
218                           default: argerr();
219                       }
220                       break;
221                   }
222                   if ( oprtype[ SRC ] == IM )   /* F5.1 */
223                   {   chtype( DST, TYPE_ld );
224                       emit2( mode | 0xC05 | $1 | $2<<4 );
225                       if ( mode>>12 == 4 ) emit_ad( addr_inf );
226                       if ( $1 == 0 ) /* ldb */
227                       {   /* fit(fits8(immed)); */
228 #ifdef RELOCATION
229                           newrelo(immed.typ, RELO1);
230 #endif
231                           emit1((int) immed.val);
232                           /* emit1((int) immed.val); ??? twice ??? */
233                       }
234                       else /* ld */
235                       {   /*fit(fits16(immed));*/
236 #ifdef RELOCATION
237                           newrelo(immed.typ, RELO2 | RELBR);
238 #endif
239                           emit2( (int)immed.val );
240                       }
241                       break;
242                   }
243                   argerr();
244                 }
245         | LDL  dst  ','  src
246                 { if ( oprtype[ DST ] == REG )
247                   {   switch( oprtype[ SRC ] )
248                       {   case IM: emit2( 0x1400 | $2 );
249 #ifdef RELOCATION
250                                    newrelo(immed.typ, RELO4|RELBR|RELWR);
251 #endif
252                                    emit4( immed.val );
253                                    break;
254                           case REG: case IR: case DA: case X:
255                                setmode( SRC );
256                                emit2( mode | 0x1400 | $4<<4 | $2 );
257                                if ( mode>>12 == 4 ) emit_ad( addr_inf );
258                                break;
259                           case BA: emit2( 0x3500 | $4<<4 | $2 );
260 #ifdef RELOCATION
261                                    newrelo(displ.typ,RELO2|RELBR);
262 #endif
263                                    emit2((int) displ.val );
264                                    break;
265                           case BX: emit2( 0x7500 | $4<<4 | $2 );
266                                    emit2( index<<8 );
267                                    break;
268                           default: argerr();
269                       }
270                       break;
271                   }
272                   if ( oprtype[ SRC ] == REG )
273                   {   switch( oprtype[ DST ] )
274                       {   case IR: case DA: case X:
275                                setmode( DST );
276                                emit2( mode | 0x1D00 | $2<<4 | $4 );
277                                if ( mode>>12 == 4 ) emit_ad( addr_inf );
278                                break;
279                           case BA: emit2( 0x3700 | $2<<4 | $4 );
280 #ifdef RELOCATION
281                                    newrelo(displ.typ,RELO2|RELBR);
282 #endif
283                                    emit2( (int) displ.val );
284                                    break;
285                           case BX: emit2( 0x7700 | $2<<4 | $4 );
286                                    emit2( index<<8 );
287                                    break;
288                           default: argerr();
289                       }
290                       break;
291                   }
292             /*    if ( oprtype[ SRC ] == IM )
293             **    {   chtype( DST, TYPE_ld );
294             **        emit2( mode | 0xD07 | $2<<4 );
295             **        if ( mode>>12 == 4 ) emit_ad( addr_inf );
296             **        emit4( immed );
297             **        break;
298             **    }
299             */
300                   argerr();
301                 }
302         ;
303
304
305 f3      : DJNZ  reg  ','  ra
306                 { branch( $1 | $2<<8, $4 );     }
307         | JR  coco1  ra
308                 { branch( $1 | $2<<8, $3 );     }
309         | CALR  ra
310                 { branch( $1, $2 );     }
311         ;
312
313
314 f4      : LDR  reg  ','  ra
315                 { ldrel( $1 | $2, $4 );         }
316         | LDR  ra  ','  reg
317                 { ldrel( $1 | 0x200 | $4, $2 ); }
318         | LDAR  R32  ','  ra
319                 { ldrel( $1 | $2, $4 );         }
320         ;
321
322
323 f5      : F5_1L  reg  option
324                 {   if ( $3 < 0 )
325                     {   warning( "neg src results in a right shift!" );
326                         warning( "warning only");
327                     }
328                     shiftcode( $1 | $2<<4, $3 );
329                 }
330         | F5_1R  reg  option2
331                 {   if ( $3 > 0 )
332                     {   warning( "pos src results in a left shift!" );
333                         warning( "warning only");
334                     }
335                     shiftcode( $1 | $2<<4, $3 );
336                 }
337         ;
338
339 option2 : ',' imexpr
340                 { $$ = $2;      }
341         |  /* empty */
342                 { $$ = -1;      }
343         ;
344
345 f6      : LDM  dst  ','  src  ','  imexpr
346                 { switch( oprtype[ DST ] )
347                   { case REG: chtype( SRC, TYPE_ldm );
348                               ldmcode( $1 | $4<<4, $2, $6 );
349                               break;
350                     default:  switch( oprtype[ SRC ] )
351                               { case REG: chtype( DST, TYPE_ldm );
352                                           ldmcode($1+8 | $2<<4, $4, $6);
353                                           break;
354                                 default:  argerr();
355                               }
356                   }
357                 }
358         | F6_4  ir  ','  ir  ','  R16
359                 { /* For translate instructions the roles of $2 and $4
360                   ** are interchanged with respect to the other
361                   ** instructions of this group.
362                   */
363                   if ( ($1 & 0xB8FF) == $1 )
364                   {     /* translate instruction        */
365                         emit2( ($1 & ~0xF0) | $2<<4 );
366                         emit2( ($1 & 0xF0)>>4 | $6<<8 | $4<<4 );
367                   }
368                   else
369                   {     emit2( ($1 & ~0xF0) | $4<<4 );
370                         emit2( ($1 & 0xF0)>>4 | $6<<8 | $2<<4 );
371                   }
372                 }
373         | F6_5  dst  ','  ir  ','  R16  coco2
374                 { switch( oprtype[ DST ] )
375                   {   case REG: if ( bitset($1,1) )  argerr();  break;
376                       case IR : if ( !bitset($1,1) )  argerr();  break;
377                       default : argerr();
378                   }
379                   emit2( $1 | $4<<4 );
380                   emit2( $6<<8 | $2<<4 | $7 );
381                 }
382         | F6_6  reg  ','  R16
383                 { emit2( $1 | $2<<4 );
384                   emit2( $4<<8 );
385                 }
386         ;
387
388
389 f7      : IN  reg  ','  da
390                 { emit2( $1 | 0xA04 | $2<<4 );
391 #ifdef RELOCATION
392                   newrelo(adr_inf.typ, RELO2|RELBR);
393 #endif
394                   emit2( (short)addr_inf.val );    /* i/o address */
395                 }
396         | OUT  da  ','  reg
397                 { emit2( $1 | 0xA06 | $4<<4 );
398 #ifdef RELOCATION
399                   newrelo(adr_inf.typ, RELO2|RELBR);
400 #endif
401                   emit2( (short)addr_inf.val );    /* i/o address */
402                 }
403         | IN  reg  ','  ir
404                 { if ( bitset($1,0) )   argerr();
405                   emit2( $1 | 0xC00 | $4<<4 | $2 );
406                 }
407         | OUT  ir  ','  reg
408                 { if ( bitset($1,0) )   argerr();
409                   emit2( $1 | 0xE00 | $2<<4 | $4 );
410                 }
411         ;
412
413
414 f8      : LDCTL  ctlargs
415                 { emit2( $1 | $2 );     }
416         | LDCTLB  ctlbargs
417                 { emit2( $1 | $2 );     }
418         | MREQ  reg
419                 { emit2( $1 | $2<<4 );  }
420         ;
421 ctlargs : CTLR  ','  R16
422                 { $$ = $3<<4 | $1 | 8;  }
423         | R16  ','  CTLR
424                 { $$ = $1<<4 | $3;      }
425         ;
426 ctlbargs: CTLRFLAGS  ','  R8
427                 { $$ = $3<<4 | $1 | 8;}
428         | R8  ','  CTLRFLAGS
429                 { $$ = $1<<4 | $3;      }
430         ;
431
432
433
434
435 f9      : F9_1  flags
436                 { emit2( $1 | $2 );     }
437         | F9_2  ints
438                 { emit2( $1 | $2 );     }
439         | F9_3
440                 { emit2( $1 );  }
441         | RET
442                 { emit2( $1 | 8 );      }
443         | RET  CC
444                 { emit2( $1 | $2 );     }
445         | SC  imexpr
446                 { fit(fit8($2));
447                   emit2( $1 | $2 );
448                 }
449         ;
450 flags   : flags  ','  FLAG
451                 { $$ = $1 | $3; }
452         | FLAG
453                 { $$ = $1;      }
454         ;
455 ints    : ints  ','  INTCB
456                 { $$ = $1 | $3; }
457         | INTCB
458                 { $$ = $1;      }
459         ;
460
461
462
463
464 coco1   : CC  ','
465                 { $$ = $1;      }
466         | /* empty */
467                 { $$ = 8;       }
468         ;
469 coco2   : ','  CC
470                 { $$ = $2;      }
471         | /* empty */
472                 { $$ = 8;       }
473         ;
474 option  : ','  imexpr
475                 { $$ = $2;      }
476         |  /* empty */
477                 { $$ = 1;       }
478         ;
479 /*    `imexpr', just as `im', is used to implement immediate data.
480 ** But `imexpr' is used in those cases where the  immediate  value
481 ** always  will fit into 16 bits, so (long) `immed' is not needed.
482 ** Those cases are in `option', `option2', f9-`SC',  f6-`LDM'  and
483 ** f1-`LDK'.
484 */
485 imexpr  : '$'  absexp
486                 { $$ = $2;      }
487         ;
488 /*     Destination (dst) as well as source  (src)  operands  never
489 ** have RA as addressing mode, except for some instructions of the
490 ** F3 and F4 instruction format group.   In those cases RA is even
491 ** the  only  addressing mode which is allowed.   This is why `ra'
492 ** has a yacc-rule not being part of `opr'.
493 */
494 ra      : expr
495                 { $$ = $1;      }
496         ;
497 dst     :       { operand = DST;}
498           opr
499                 { $$ = $2;      }
500         ;
501 src     :       { operand = SRC;}
502           opr
503                 { $$ = $2;      }
504         ;
505 opr     : reg
506                 { settype( REG );       }
507         | im
508                 { settype( IM );        }
509         | ir
510                 { settype( IR );        }
511         | da
512                 { settype( DA );        }
513         | x
514                 { settype( X );         }
515         | ba
516                 { settype( BA );        }
517         | bx
518                 { settype( BX );        }
519         ;
520 reg     : R8
521         | R16
522         | R32
523         | R64
524         ;
525 im      : '$'  expr
526                 { $$ = 0;
527                   immed = $2;
528                 }
529         | '$' '<' '<' expr '>' '>' expr
530                 { $$ = 0;
531                   immed.typ = combine($4.typ, $7.typ, '+');
532                   immed.val = $4.val<<16 | $7.val;
533                 }
534         ;
535 ir      : '*'  R32
536                 { if ( $2 == 0 ) regerr();
537                   $$ = $2;
538                 }
539         ;
540 da      : expr
541                 { $$ = 0;
542                   addr_inf = $1;
543                 }
544         | '<' '<' expr '>' '>' expr
545                 { $$ = 0;
546                   addr_inf.typ = combine( $3.typ, $6.typ, '+' );
547                   addr_inf.val = $3.val<<16 | $6.val;
548                 }
549         ;
550 x       : expr  '('  R16  ')'
551                 { if ( $3 == 0 ) regerr();
552                   $$ = $3;
553                   addr_inf = $1;
554                 }
555         | '<' '<'  expr  '>' '>'  expr  '('  R16  ')'
556                 { if ( $8 == 0 ) regerr();
557                   $$ = $8;
558                   addr_inf.typ = combine( $3.typ, $6.typ, '+' );
559                   addr_inf.val = $3.val<<16 | $6.val;
560                 }
561         ;
562 ba      : R32  '('  '$'  expr  ')'
563                 { if ( $1 == 0 ) regerr();
564                   $$ = $1;
565                   displ = $4;
566                 }
567         ;
568 bx      : R32  '('  R16  ')'
569                 { if ( $1 == 0 || $3 == 0 ) regerr();
570                   $$ = $1;
571                   index = $3;
572                 }
573         ;