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".
5 #define RCSID4 "$Id: mach4.c,v 0.3 1994/06/24 13:56:26 ceriel Exp $"
8 ** Zilog z8000 yacc parsing rules
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;
28 emit2( mode | $1 | $2<<4 );
29 if ( mode>>12 == 4 ) emit_ad( addr_inf );
36 { if ( $3 != 1 && $3 != 2 ) argerr();
37 emit2( $1 | $2<<4 | ($3-1)<<1 );
40 { chtype( DST, TYPE_12 );
42 emit2( mode | $1 | $2<<4 | $3-1 );
43 if ( mode>>12 == 4 ) emit_ad( addr_inf );
47 emit2( $1 | $2<<4 | $4 );
49 | F1_2F6_3 dst ',' src
50 { if ( oprtype[ DST ] == REG && oprtype[ SRC ] == REG )
54 else if ( oprtype[ SRC ] == IM )
55 { chtype( DST, TYPE_1263 );
56 if ((immed.typ & ~S_EXT) != S_ABS) {
57 serror("must be absolute");
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 );
67 { chtype( DST, TYPE_jp );
68 emit2( mode | $1 | $3<<4 | $2 );
69 if ( mode>>12 == 4 ) emit_ad( addr_inf );
72 { emit2( $1 | $3<<4 | $2 ); }
77 { switch( ($1 & 0xF000)>>12 )
78 { case 2: chtype( SRC, TYPE_21a ); break;
79 case 3: chtype( SRC, TYPE_21b ); break;
81 emit2( mode | $1 | $4<<4 | $2 );
82 if ( mode>>12 == 4 ) emit_ad( addr_inf );
84 | F2_1F5_1 dst ',' src
85 { switch( oprtype[ DST ] )
86 { case REG: chtype( SRC, TYPE_2151 );
88 emit2( mode | $1 | $4<<4 | $2 );
90 case IR: case DA: case X:
91 if ( oprtype[ SRC ] == IM
92 && ( $1 == 0x0B00 || $1 == 0x0A00 ) )
95 emit2( mode | $1 + 0x201 | $2<<4 );
100 if ( mode>>12 == 4 ) emit_ad( addr_inf );
101 if ( oprtype[ SRC ] == IM )
102 { if (bitset($1,8)) /* word */ {
104 newrelo(immed.typ, RELO2|RELBR);
106 emit2( (int)immed.val );
108 else if (bitset($1,12)) /* long */ {
110 newrelo(immed.typ, RELO4|RELWR|RELBR);
116 newrelo(immed.typ, RELO1);
118 emit1((int) immed.val);
119 /* emit1((int) immed.val); ??? twice ??? */
124 { switch( oprtype[ SRC ] )
125 { case DA: case X: emit2( 0x7600 | $4<<4 | $2 );
128 case BA: emit2( 0x3400 | $4<<4 | $2 );
130 newrelo(displ.typ,RELO2|RELBR);
132 emit2( (int) displ.val ); break;
133 case BX: emit2( 0x7400 | $4<<4 | $2 );
134 emit2( index<<8 ); break;
139 { chtype( DST, TYPE_pop );
140 emit2( mode | $1 | $4<<4 | $2 );
141 if ( mode>>12 == 4 ) emit_ad( addr_inf );
144 { chtype( SRC, TYPE_push );
145 switch ( oprtype[ SRC ] )
146 { case IM: if ( $1 == 0x1100 ) /* pushl */ argerr();
147 /* { emit2( 0x9109 | $2<<4 );
152 { emit2( 0x0D09 | $2<<4 );
154 newrelo(immed.typ, RELO2|RELBR);
156 emit2( (int)immed.val );
159 default: emit2( mode | $1 | $2<<4 | $4 );
160 if ( mode>>12 == 4 ) emit_ad( addr_inf );
164 { if ( oprtype[ DST ] == REG )
165 { switch( oprtype[ SRC ] )
167 if ( $1 == 0 ) /* ldb: F3.2 */
168 { /* fit(fits8(immed)); */
169 emit1( 0xC000 | $2<<8);
171 newrelo(immed.typ, RELO1);
173 emit1((int) immed.val);
176 { /*fit(fits16(immed));*/
177 emit2( 0x2100 | $2 );
179 newrelo(immed.typ, RELO2|RELBR);
181 emit2( (int)immed.val );
184 case REG: case IR: case DA: case X:
186 emit2( mode | 0x2000 | $1 | $4<<4 | $2 );
187 if ( mode>>12 == 4 ) emit_ad( addr_inf );
189 case BA: emit2( 0x3000 | $1 | $4<<4 | $2 );
191 newrelo(displ.typ,RELO2|RELBR);
193 emit2( (int) displ.val );
195 case BX: emit2( 0x7000 | $1 | $4<<4 | $2 );
202 if ( oprtype[ SRC ] == REG )
203 { switch( oprtype[ DST ] )
204 { case IR: case DA: case X:
206 emit2( mode | 0x2E00 | $1 | $2<<4 | $4 );
207 if ( mode>>12 == 4 ) emit_ad( addr_inf );
209 case BA: emit2( 0x3200 | $1 | $2<<4 | $4 );
211 newrelo(displ.typ,RELO2|RELBR);
213 emit2( (int) displ.val );
215 case BX: emit2( 0x7200 | $1 | $2<<4 | $4 );
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)); */
229 newrelo(immed.typ, RELO1);
231 emit1((int) immed.val);
232 /* emit1((int) immed.val); ??? twice ??? */
235 { /*fit(fits16(immed));*/
237 newrelo(immed.typ, RELO2 | RELBR);
239 emit2( (int)immed.val );
246 { if ( oprtype[ DST ] == REG )
247 { switch( oprtype[ SRC ] )
248 { case IM: emit2( 0x1400 | $2 );
250 newrelo(immed.typ, RELO4|RELBR|RELWR);
254 case REG: case IR: case DA: case X:
256 emit2( mode | 0x1400 | $4<<4 | $2 );
257 if ( mode>>12 == 4 ) emit_ad( addr_inf );
259 case BA: emit2( 0x3500 | $4<<4 | $2 );
261 newrelo(displ.typ,RELO2|RELBR);
263 emit2((int) displ.val );
265 case BX: emit2( 0x7500 | $4<<4 | $2 );
272 if ( oprtype[ SRC ] == REG )
273 { switch( oprtype[ DST ] )
274 { case IR: case DA: case X:
276 emit2( mode | 0x1D00 | $2<<4 | $4 );
277 if ( mode>>12 == 4 ) emit_ad( addr_inf );
279 case BA: emit2( 0x3700 | $2<<4 | $4 );
281 newrelo(displ.typ,RELO2|RELBR);
283 emit2( (int) displ.val );
285 case BX: emit2( 0x7700 | $2<<4 | $4 );
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 );
306 { branch( $1 | $2<<8, $4 ); }
308 { branch( $1 | $2<<8, $3 ); }
310 { branch( $1, $2 ); }
315 { ldrel( $1 | $2, $4 ); }
317 { ldrel( $1 | 0x200 | $4, $2 ); }
319 { ldrel( $1 | $2, $4 ); }
323 f5 : F5_1L reg option
325 { warning( "neg src results in a right shift!" );
326 warning( "warning only");
328 shiftcode( $1 | $2<<4, $3 );
332 { warning( "pos src results in a left shift!" );
333 warning( "warning only");
335 shiftcode( $1 | $2<<4, $3 );
345 f6 : LDM dst ',' src ',' imexpr
346 { switch( oprtype[ DST ] )
347 { case REG: chtype( SRC, TYPE_ldm );
348 ldmcode( $1 | $4<<4, $2, $6 );
350 default: switch( oprtype[ SRC ] )
351 { case REG: chtype( DST, TYPE_ldm );
352 ldmcode($1+8 | $2<<4, $4, $6);
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.
363 if ( ($1 & 0xB8FF) == $1 )
364 { /* translate instruction */
365 emit2( ($1 & ~0xF0) | $2<<4 );
366 emit2( ($1 & 0xF0)>>4 | $6<<8 | $4<<4 );
369 { emit2( ($1 & ~0xF0) | $4<<4 );
370 emit2( ($1 & 0xF0)>>4 | $6<<8 | $2<<4 );
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;
380 emit2( $6<<8 | $2<<4 | $7 );
383 { emit2( $1 | $2<<4 );
390 { emit2( $1 | 0xA04 | $2<<4 );
392 newrelo(adr_inf.typ, RELO2|RELBR);
394 emit2( (short)addr_inf.val ); /* i/o address */
397 { emit2( $1 | 0xA06 | $4<<4 );
399 newrelo(adr_inf.typ, RELO2|RELBR);
401 emit2( (short)addr_inf.val ); /* i/o address */
404 { if ( bitset($1,0) ) argerr();
405 emit2( $1 | 0xC00 | $4<<4 | $2 );
408 { if ( bitset($1,0) ) argerr();
409 emit2( $1 | 0xE00 | $2<<4 | $4 );
415 { emit2( $1 | $2 ); }
417 { emit2( $1 | $2 ); }
419 { emit2( $1 | $2<<4 ); }
421 ctlargs : CTLR ',' R16
422 { $$ = $3<<4 | $1 | 8; }
426 ctlbargs: CTLRFLAGS ',' R8
427 { $$ = $3<<4 | $1 | 8;}
436 { emit2( $1 | $2 ); }
438 { emit2( $1 | $2 ); }
444 { emit2( $1 | $2 ); }
450 flags : flags ',' FLAG
455 ints : ints ',' INTCB
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
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'.
497 dst : { operand = DST;}
501 src : { operand = SRC;}
529 | '$' '<' '<' expr '>' '>' expr
531 immed.typ = combine($4.typ, $7.typ, '+');
532 immed.val = $4.val<<16 | $7.val;
536 { if ( $2 == 0 ) regerr();
544 | '<' '<' expr '>' '>' expr
546 addr_inf.typ = combine( $3.typ, $6.typ, '+' );
547 addr_inf.val = $3.val<<16 | $6.val;
551 { if ( $3 == 0 ) regerr();
555 | '<' '<' expr '>' '>' expr '(' R16 ')'
556 { if ( $8 == 0 ) regerr();
558 addr_inf.typ = combine( $3.typ, $6.typ, '+' );
559 addr_inf.val = $3.val<<16 | $6.val;
562 ba : R32 '(' '$' expr ')'
563 { if ( $1 == 0 ) regerr();
569 { if ( $1 == 0 || $3 == 0 ) regerr();