1 #define RCSID4 "$Id: mach4.c,v 0.3 1994/06/24 13:09:55 ceriel Exp $"
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".
9 /* Author: Ed Keizer */
14 { dot_adjust(&$2) ; form0($1) ; disp(&$2, RELPC) ;}
20 { dot_adjust(&$2) ; form1($1) ; disp(&$2, RELPC) ;}
23 { form1($1) ; disp(&$2, 0) ;}
26 { form1($1) ; emit1(reg_list($2,id_op($1)!=0x6)) ;}
27 | ENTER reg_list ',' expr
29 { form1($1) ; emit1(reg_list($2,0)) ; disp(&$4, 0) ;}
32 { if ( id_op($1)==0x2 ) not_imm(&mode1) ;
33 form2($1,$2) ; gen1($1) ;
37 { form2($1,id_cc($1)) ; gen1($1) ; not_imm(&mode1) ;}
38 | MOVQ absexp ',' gen1
42 serror("Constant too large") ;
44 form2($1,low4($2)) ; gen1($1) ;
45 if ( id_op($1)!=0x1 ) not_imm(&mode1) ; /* !cmp */
47 | ACB absexp ',' gen1 ',' expr
52 serror("Constant too large") ;
54 form2($1,low4($2)) ; gen1($1) ; not_imm(&mode1) ;
60 if ( id_op($1)==0 ) not_imm(&mode1) ; /* cxpd */
61 form3($1) ; gen1($1) ;}
66 if ( mode1.m_mode==0x15 ) { /* Absolute */
67 dot_adjust(&mode1.m_expr1) ;
68 RELOMOVE(relonami, mode1.m_rel1);
69 form1(0) ; disp(&mode1.m_expr1, RELPC) ; /* bsr */
72 { form3($1) ; gen1($1) ; }
79 if ( mode1.m_mode==0x15 ) { /* Absolute */
80 dot_adjust(&mode1.m_expr1) ;
81 RELOMOVE(relonami, mode1.m_rel1);
82 form0(B_TRUE) ; disp(&mode1.m_expr1, RELPC) ; /* br */
85 { form3($1) ; gen1($1) ; }
93 if ( opc==0x9 ) not_imm(&mode1) ; /* addr */
94 if ( opc!=0x1 ) not_imm(&mode2) ; /* !cmp */
96 if ( mode1.m_mode==0x14 && /* Immediate */
97 (mode1.m_expr1.typ & ~S_EXT) == S_ABS &&
99 (fit4(mode1.m_expr1.val) &&
100 (opc==0 || opc==1 || opc==5))
102 (fit4(-mode1.m_expr1.val) &&
107 /* Warning, an absolute expression derived
108 from a symbol that is defined after
109 use might - if the value now suddenly fits -
110 cause failed assertions in newlabel
113 /* added: the subtract of a signed
114 * short is the same as the add
115 * of the negation of that short
116 * so: subi short,x == addqi -short,x
117 * 19/04/85 h.m.kodden,m.j.a.leliveld
119 if (opc==8) /* do the negate */
121 (~mode1.m_expr1.val+1)&0xF;
122 opc=low4(mode1.m_expr1.val) ;
124 form2($1,opc) ; gen1($1) ;
127 { form4($1) ; gengen($1) ; }
134 { form5($1,($2)|id_cc($1)) ;}
137 { form6($1) ; gengen($1) ; not_imm(&mode2) ;}
138 | MUL_I gen1 ',' gen2
141 if ( id_op($1)==0x9 || id_op($1)==0xB ) {
143 switch ( mode2.m_mode ) {
144 case 1 : case 3 : case 5 : case 7 :
145 serror("register must be even") ;
148 form7($1) ; gengen($1) ; not_imm(&mode2) ;
150 | MOVID gen1 ',' gen2
152 { form7x($1,id_g1($1)) ; gengen($1) ; not_imm(&mode2) ;}
153 | MOVM gen1 ',' gen2 ',' expr
157 s_size= id_g1($1)+1 ;
158 /* $6.val= $6.val*s_size - s_size ; */
160 form7($1) ; gengen($1) ; disp(&$6, 0) ;
161 not_imm(&mode1) ; not_imm(&mode2) ;
163 | INSS gen1 ',' gen2 ',' absexp ',' absexp
166 if ( ( $6<0 || $6>7 || $8<1 || $8>32 )
167 ) { serror("Constant out of bounds") ; }
168 form7($1) ; gengen($1) ;
169 if ( id_op($1)==0x3 ) not_imm(&mode1) ; /* exts */
171 emit1((((int)$6)<<5)+(int)$8-1) ;
175 { form8($1,id_cc($1)) ; gengen($1) ; not_imm(&mode2) ;}
176 | CHECK REG ',' gen1 ',' gen2
179 form8($1,$2) ; gengen($1) ;
180 if ( id_op($1)!=0x4 ) {
181 not_imm(&mode1) ; /* check, cvtp */
182 if ( id_op($1)==0x1 ) not_imm(&mode2) ;/*cvtp */
185 | INS REG ',' gen1 ',' gen2 ',' expr
188 form8($1,$2) ; gengen($1) ; disp(&$8, 0) ;
189 if ( id_op($1)==0x0 ) not_imm(&mode1) ;
192 | MOVIF gen1 ',' fgen2
195 assert( id_t1($1)==T_INT && id_t2($1)==T_FL ) ;
196 form9($1,id_g1($1),id_g2($1)) ; gengen($1) ;
199 | MOVFL fgen1 ',' fgen2
202 assert( id_t1($1)==T_FL && id_t2($1)==T_FL ) ;
203 form9($1,id_g1($1),( id_g2($1)==F_LONG?3:2 )) ;
204 gengen($1) ; not_imm(&mode2) ;
206 | TRUNC fgen1 ',' gen2
209 assert( id_t1($1)==T_FL && id_t2($1)==T_INT ) ;
210 form9($1,id_g2($1),id_g1($1)) ; gengen($1) ;
216 if ( id_op($1)==6 ) { /* SFSR */
218 mode2.m_mode=mode1.m_mode ;
224 if ( id_op($1)==6 ) {
225 mode1.m_mode=mode2.m_mode ;
229 | ADD_F fgen1 ',' fgen2
231 { if ( id_op($1)!=0x2 ) not_imm(&mode2) ; /* !CMPF */
232 form11($1) ; gengen($1) ;
236 { form14($1,0) ; gen1($1) ; not_imm(&mode1) ;}
240 form14($1,$2) ; gen1($1) ;
241 if ( id_op($1)==0x3 ) not_imm(&mode1) ;
243 /* All remaining categories are not checked for
244 illegal immediates */
247 { frm15_0($1,$2) ; gen1($1) ;}
250 { frm15_0($1,0) ; gen1($1) ;}
252 /* format 15.1 */ /* Sure? */
253 { mode2.m_mode=0 ; frm15_1($1,0,0) ; gen1($1) ;}
254 | CCVIS gen1 ',' gen2
257 assert( id_t1($1)==T_INT && id_t2($1)==T_SLAVE ) ;
258 frm15_1($1,id_g1($1),id_g2($1)) ; gengen($1) ;
260 | CCVSI gen1 ',' gen2
263 assert( id_t1($1)==T_SLAVE && id_t2($1)==T_INT ) ;
264 frm15_1($1,id_g2($1),id_g1($1)) ; gengen($1) ;
266 | CCVSS gen1 ',' gen2
269 assert( id_t1($1)==T_SLAVE && id_t2($1)==T_SLAVE ) ;
270 frm15_1($1,0,0) ; gengen($1) ; /* Sure? */
274 { frm15_5($1) ; gengen($1) ;}
277 gen1 : { mode_ptr= &mode1 ; clrmode() ; } gen
279 gen2 : { mode_ptr= &mode2 ; clrmode() ; } gen
281 fgen1 : { mode_ptr= &mode1 ; clrmode() ; } fgen
283 fgen2 : { mode_ptr= &mode2 ; clrmode() ; } fgen
286 gen : gen_not_reg /* Every mode except register */
288 { mode_ptr->m_mode= $1 ; }
290 fgen : gen_not_reg /* Every mode except register */
292 { mode_ptr->m_mode= $1 ; }
295 gen_not_reg: gen_a /* general mode with eff. address */
296 | REG { mode_ptr->m_mode=$1 ;} index
297 /* The register is supposed to contain the
300 | gen_a index /* As above, but indexed */
301 | expr /* Immediate */
302 { mode_ptr->m_mode= 0x14 ;
303 mode_ptr->m_expr1= $1 ;
304 RELOMOVE(mode_ptr->m_rel1, relonami);
308 gen_a : expr '(' REG ')' /* Register relative */
309 { mode_ptr->m_mode= 0x8 + $3 ;
310 mode_ptr->m_ndisp= 1 ;
311 mode_ptr->m_expr1= $1 ;
312 RELOMOVE(mode_ptr->m_rel1, relonami);
314 | expr '(' AREG ')' /* Memory space */
315 { if ( $3<0x8 || $3>0xA ) badsyntax() ;
316 mode_ptr->m_mode= 0x18 + ($3&3) ;
317 mode_ptr->m_ndisp= 1 ;
318 mode_ptr->m_expr1= $1 ;
319 RELOMOVE(mode_ptr->m_rel1, relonami);
321 | expr '(' PC ')' /* Memory space */
322 { mode_ptr->m_mode= 0x1B ;
323 mode_ptr->m_ndisp= 1 ;
324 mode_ptr->m_expr1= $1 ;
325 RELOMOVE(mode_ptr->m_rel1, relonami);
326 dot_adjust(&mode_ptr->m_expr1) ;
329 { mode_ptr->m_expr2 = $1;
330 RELOMOVE(mode_ptr->m_rel2, relonami);
332 expr '(' AREG ')' ')' /* Memory relative */
333 { if ( $6<0x8 || $6>0xA ) badsyntax() ;
334 mode_ptr->m_mode= 0x10 + ($6&3) ;
335 mode_ptr->m_ndisp= 2 ;
336 mode_ptr->m_expr1= $4 ;
337 RELOMOVE(mode_ptr->m_rel1, relonami);
339 | '@' expr /* Absolute */
340 { mode_ptr->m_mode= 0x15 ;
341 mode_ptr->m_ndisp= 1 ;
342 mode_ptr->m_expr1= $2 ;
343 RELOMOVE(mode_ptr->m_rel1, relonami);
345 | EXTERNAL '(' expr ')'
346 { mode_ptr->m_mode= 0x16 ;
347 mode_ptr->m_ndisp= 2 ;
348 mode_ptr->m_expr1= $3 ;
349 RELOMOVE(mode_ptr->m_rel1, relonami);
351 '+' expr /* External */
353 mode_ptr->m_expr2= $7 ;
354 RELOMOVE(mode_ptr->m_rel2, relonami);
356 | TOS /* Top Of Stack */
357 { mode_ptr->m_mode= 0x17 ; }
360 index : '[' REG ':' INDICATOR ']' /* Indexed postfix */
361 { mode_ptr->m_index= (mode_ptr->m_mode<<3) | $2 ;
362 mode_ptr->m_mode= ind_mode( $4 ) ;
376 | cpu_list ',' INDICATOR
377 { $$= ($1) | cpu_opt($3) ;}
383 { $$= string_opt($1) ; }
384 | INDICATOR ',' INDICATOR
386 ( $3 != 'u' && $3 != 'w' ) ) {
387 serror("illegal string options") ;
389 $$ = string_opt($1)|string_opt($3) ;
404 { $$= ($1) | ( 1<<($3) ) ;}