ack/mach/i386/as/mach4.c

231 lines
4.9 KiB
C
Raw Normal View History

1989-01-19 16:20:46 +00:00
#define RCSID4 "$Header$"
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
*/
operation
1989-01-24 13:51:05 +00:00
:
1989-11-29 09:49:35 +00:00
prefix oper
1989-01-24 13:51:05 +00:00
{ address_long = 1; operand_long = 1; }
| prefix1 /* to allow for only prefixes on a line */
1989-01-19 16:20:46 +00:00
;
prefix : /* empty */
1989-01-24 13:51:05 +00:00
| prefix1
;
prefix1: prefix PREFIX
1989-01-19 16:20:46 +00:00
{ if ($2 == 0146) operand_long = ! operand_long;
if ($2 == 0147) address_long = ! address_long;
emit1($2);
}
;
oper : NOOP_1
{ emit1($1);}
| NOOP_2
{ emit2($1);}
| JOP expr
{ branch($1,$2);}
| JOP2 expr
{ ebranch($1,$2);}
| PUSHOP ea_1
{ pushop($1);}
| IOOP absexp
{ emit1($1);
fit(ufitb($2));
emit1((int)$2);
}
| IOOP R32
{ if ($2!=2) serror("register error");
emit1($1+010);
}
| BITTEST ea_ea
{ bittestop($1);}
| ADDOP ea_ea
{ addop($1);}
| ROLOP ea_ea
{ rolop($1);}
| INCOP ea_1
{ incop($1);}
| NOTOP ea_1
{ regsize($1); emit1(0366|($1&1)); ea_1($1&070);}
| CALLOP ea_1
{ callop($1&0xFFFF);}
| CALFOP expr ':' expr
{ emit1($1>>8);
adsize_exp($4, 0);
1989-01-19 16:20:46 +00:00
#ifdef RELOCATION
newrelo($2.typ, RELO2);
#endif
emit2((int)($2.val));
}
| CALFOP mem
{ emit1(0377); ea_2($1&0xFF);}
| ENTER absexp ',' absexp
{ fit(fitw($2)); fit(fitb($4));
emit1($1); emit2((int)$2); emit1((int)$4);
}
| LEAOP R32 ',' mem
{ emit1($1); ea_2($2<<3);}
| LEAOP2 R32 ',' mem
{ emit1(0xF); emit1($1); ea_2($2<<3);}
1990-03-09 11:07:43 +00:00
| ARPLOP mem ',' R32
{ emit1($1); ea_2($4<<3);}
1989-01-19 16:20:46 +00:00
| LSHFT ea_1 ',' R32 ',' ea_2
{ extshft($1, $4);}
| EXTEND R32 ',' ea_2
{ emit1(0xF); emit1($1); ea_2($2<<3);}
1989-01-19 16:20:46 +00:00
| EXTOP R32 ',' ea_2
{ emit1(0xF); emit1($1); ea_2($2<<3);}
| EXTOP1 ea_1
{ emit1(0xF); emit1($1&07); ea_1($1&070);}
| IMULB ea_1
{ regsize(0); emit1(0366); ea_1($1&070);}
| IMUL ea_2
{ reg_1 = IS_R32; imul(0); }
| IMUL R32 ',' ea_2
1990-01-10 11:23:45 +00:00
{ reg_1 = $2 | IS_R32; imul($2|0x10); }
1989-01-19 16:20:46 +00:00
| IMUL R32 ',' ea_ea
1990-01-10 11:23:45 +00:00
{ imul($2|0x10);}
1989-01-19 16:20:46 +00:00
| INT absexp
{ if ($2==3)
emit1(0314);
else {
fit(ufitb($2));
emit1(0315); emit1((int)$2);
}
}
| RET
{ emit1($1);}
| RET expr
{ emit1($1-1);
#ifdef RELOCATION
newrelo($2.typ, RELO2);
#endif
emit2((int)($2.val));
}
| SETCC ea_2
{ emit1(0xF); emit1($1); ea_2(0);}
| XCHG ea_ea
{ xchg($1);}
| TEST ea_ea
{ test($1);}
| MOV ea_ea
{ mov($1);}
| /* What is really needed is just
MOV R32 ',' RSYSCR
but this gives a bad yacc conflict
*/
MOV ea_1 ',' RSYSCR
1989-11-29 09:49:35 +00:00
{
1989-01-19 16:20:46 +00:00
if ($1 != 1 || !(reg_1 & IS_R32))
serror("syntax error");
emit1(0xF); emit1(042); emit1(0200|($4<<3)|(reg_1&07));}
| MOV ea_1 ',' RSYSDR
1989-11-29 09:49:35 +00:00
{
1989-01-19 16:20:46 +00:00
if ($1 != 1 || !(reg_1 & IS_R32))
serror("syntax error");
emit1(0xF); emit1(043); emit1(0200|($4<<3)|(reg_1&07));}
| MOV ea_1 ',' RSYSTR
1989-11-29 09:49:35 +00:00
{
1989-01-19 16:20:46 +00:00
if ($1 != 1 || !(reg_1 & IS_R32))
serror("syntax error");
emit1(0xF); emit1(046); emit1(0200|($4<<3)|(reg_1&07));}
| MOV RSYSCR ',' R32
1989-11-29 09:49:35 +00:00
{
1989-01-19 16:20:46 +00:00
if ($1 != 1) serror("syntax error");
emit1(0xF); emit1(040); emit1(0200|($4<<3)|$2);}
| MOV RSYSDR ',' R32
1989-11-29 09:49:35 +00:00
{
1989-01-19 16:20:46 +00:00
if ($1 != 1) serror("syntax error");
emit1(0xF); emit1(041); emit1(0200|($4<<3)|$2);}
| MOV RSYSTR ',' R32
1989-11-29 09:49:35 +00:00
{
1989-01-19 16:20:46 +00:00
if ($1 != 1) serror("syntax error");
emit1(0xF); emit1(044); emit1(0200|($4<<3)|$2);}
1989-11-29 09:49:35 +00:00
/* Intel 80[23]87 coprocessor instructions */
| FNOOP
{ emit1($1); emit1($1>>8);}
| FMEM mem
{ emit1($1); ea_2(($1>>8)&070);}
| FMEM_AX R32
{ if ($2 != 0) {
serror("illegal register");
}
emit1(FESC|7); emit1(7<<5);
}
| FST_I st_i
{ emit1($1); emit1(($1>>8)|$2); }
| FST_I ST
{ emit1($1); emit1($1>>8); }
| FST_ST ST ',' st_i
{ emit1($1); emit1(($1>>8)|$4); }
| FST_ST st_i ',' ST
{ emit1($1|4); emit1((($1>>8)|$2)); }
| FST_ST2 st_i ',' ST
{ emit1($1|4); emit1((($1>>8)|$2)^010); }
;
st_i : ST '(' absexp ')'
{ if (!fit3($3)) {
serror("illegal index in FP stack");
}
$$ = $3;
}
;
1989-01-19 16:20:46 +00:00
;
mem : '(' expr ')'
{ rm_2 = 05; exp_2 = $2; reg_2 = 05; mod_2 = 0;
RELOMOVE(rel_2, relonami);
}
| bases
{ exp_2.val = 0; exp_2.typ = S_ABS; indexed();}
| expr bases
{ exp_2 = $1; indexed();
RELOMOVE(rel_2, relonami);
}
;
bases : '(' R32 ')'
{ reg_2 = $2; sib_2 = 0; rm_2 = 0;}
| '(' R32 ')' '(' R32 scale ')'
{ rm_2 = 04; sib_2 |= regindex_ind[$2][$5];
reg_2 = $2;
}
| '(' R32 '*' absexp ')'
{ if ($4 == 1) {
reg_2 = $2; sib_2 = 0; rm_2 = 0;
}
else {
rm_2 = 04;
sib_2 = checkscale($4) | regindex_ind[05][$2];
reg_2 = 015;
}
}
;
scale : /* empty */
{ sib_2 = 0;}
| '*' absexp
{ sib_2 = checkscale($2);}
;
ea_2 : mem
| R8
{ reg_2 = $1 | IS_R8; rm_2 = 0;}
| R32
{ reg_2 = $1 | IS_R32; rm_2 = 0;}
| RSEG
{ reg_2 = $1 | IS_RSEG; rm_2 = 0;}
| expr
{ reg_2 = IS_EXPR; exp_2 = $1; rm_2 = 0;
RELOMOVE(rel_2, relonami);
}
;
ea_1 : ea_2
{ op_1 = op_2;
RELOMOVE(rel_1, rel_2);
}
;
ea_ea : ea_1 ',' ea_2
;