1 #define RCSID4 "$Id: mach4.c,v 1.16 1996/04/25 08:38:05 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".
12 { use32 = 0; address_long = 0; operand_long = 0; }
15 { use32 = 1; address_long = 1; operand_long = 1; }
17 { address_long = use32; operand_long = use32; }
18 | prefix1 /* to allow for only prefixes on a line */
23 prefix1: prefix PREFIX { emit1($2); }
26 { if ((($2&0200) >> 7) == address_long) {
27 if (pass == PASS_3) warning("address size toggle ignored");
30 address_long = ! address_long;
35 { if ((($2&0200) >> 7) == operand_long) {
36 if (pass == PASS_3) warning("operand size toggle ignored");
39 operand_long = ! operand_long;
59 { if ($2!=2) serror("register error");
71 { regsize($1); emit1(0366|($1&1)); ea_1($1&070);}
74 | CALFOP expr ':' expr
78 newrelo($2.typ, RELO2);
83 { emit1(0377); ea_2($1&0xFF);}
84 | ENTER absexp ',' absexp
85 { fit(fitw($2)); fit(fitb($4));
86 emit1($1); emit2((int)$2); emit1((int)$4);
89 { emit1($1); ea_2($2<<3);}
91 { emit1(0xF); emit1($1); ea_2($2<<3);}
93 { emit1($1); ea_2($4<<3);}
94 | LSHFT ea_1 ',' R32 ',' ea_2
97 { emit1(0xF); emit1($1); ea_2($2<<3);}
99 { emit1(0xF); emit1($1); ea_2($2<<3);}
101 { emit1(0xF); emit1($1&07); ea_1($1&070);}
103 { regsize(0); emit1(0366); ea_1($1&070);}
105 { reg_1 = IS_R32 | (address_long ? 0 : 0310);
109 { reg_1 = $2 | IS_R32 | (address_long ? 0 : 0310);
119 emit1(0315); emit1((int)$2);
127 newrelo($2.typ, RELO2);
129 emit2((int)($2.val));
132 { if (reg_2 & (IS_R32|IS_RSEG)) {
133 serror("register error");
135 emit1(0xF); emit1($1|0x90); ea_2(0);
143 | /* What is really needed is just
145 but this gives a bad yacc conflict
149 if ($1 != 1 || !(reg_1 & IS_R32))
150 serror("syntax error");
151 emit1(0xF); emit1(0x20); emit1(0300|($4<<3)|(reg_1&07));}
152 | MOV ea_1 ',' RSYSDR
154 if ($1 != 1 || !(reg_1 & IS_R32))
155 serror("syntax error");
156 emit1(0xF); emit1(0x21); emit1(0300|($4<<3)|(reg_1&07));}
157 | MOV ea_1 ',' RSYSTR
159 if ($1 != 1 || !(reg_1 & IS_R32))
160 serror("syntax error");
161 emit1(0xF); emit1(0x24); emit1(0300|($4<<3)|(reg_1&07));}
164 if ($1 != 1) serror("syntax error");
165 emit1(0xF); emit1(0x22); emit1(0300|($2<<3)|$4);}
168 if ($1 != 1) serror("syntax error");
169 emit1(0xF); emit1(0x23); emit1(0300|($2<<3)|$4);}
172 if ($1 != 1) serror("syntax error");
173 emit1(0xF); emit1(0x26); emit1(0300|($2<<3)|$4);}
174 /* Intel 80[23]87 coprocessor instructions */
176 { emit1($1); emit1($1>>8);}
178 { emit1($1); ea_2(($1>>8)&070);}
180 { emit1($1); ea_2(($1>>8)&070);}
183 serror("illegal register");
185 emit1(FESC|7); emit1(7<<5);
188 { emit1($1); emit1(($1>>8)|$2); }
190 { emit1($1); emit1($1>>8); }
192 { emit1($1); emit1(($1>>8)|$4); }
193 | FST_ST2 ST ',' st_i
194 { emit1($1); emit1(($1>>8)|$4); }
196 { emit1($1|4); emit1((($1>>8)|$2)); }
197 | FST_ST2 st_i ',' ST
198 { emit1($1|4); emit1((($1>>8)|$2)^010); }
199 /* 486 instructions */
201 { emit1(0xF); emit1($1|$2); }
202 | EXTOPBW ea_2 ',' reg
204 emit1(0xF); emit1($1); ea_2($4<<3);
208 st_i : ST '(' absexp ')'
210 serror("illegal index in FP stack");
218 { if (address_long) reg_2 = 05;
223 RELOMOVE(rel_2, relonami);
227 { exp_2.val = 0; exp_2.typ = S_ABS; indexed();}
229 { exp_2 = $1; indexed();
230 RELOMOVE(rel_2, relonami);
234 { if (address_long) reg_2 = $2;
235 else reg_2 = sr_m[$2];
238 | '(' R32 ')' '(' R32 scale ')'
239 { if (address_long) reg_2 = $2;
240 else reg_2 = dr_m[$2][$5];
242 sib_2 |= regindex_ind[$2][$5];
244 | '(' R32 '*' absexp ')'
246 reg_2 = $2; sib_2 = 0; rm_2 = 0;
250 sib_2 = checkscale($4) | regindex_ind[05][$2];
258 { sib_2 = checkscale($2);}
262 { reg_2 = ($1 | IS_R8) | (address_long ? 0 : 0300);
266 { reg_2 = ($1 | IS_R32) | (address_long ? 0 : 0310);
270 { reg_2 = ($1 | IS_RSEG) | (address_long ? 0 : 020);
274 { reg_2 = IS_EXPR | (address_long ? 0 : 040);
275 exp_2 = $1; rm_2 = 0;
276 RELOMOVE(rel_2, relonami);
279 reg : R8 { reg_1 = ($1 | IS_R8) | (address_long ? 0 : 0300);
284 { reg_1 = ($1 | IS_R32) | (address_long ? 0 : 0310);
291 RELOMOVE(rel_1, rel_2);
294 ea_ea : ea_1 ',' ea_2