Initial revision
This commit is contained in:
parent
4c76583aba
commit
6833adfb50
6 changed files with 1146 additions and 0 deletions
16
mach/i386/as/mach0.c
Normal file
16
mach/i386/as/mach0.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#define RCSID0 "$Header$"
|
||||
|
||||
/*
|
||||
* INTEL 80386 options
|
||||
*/
|
||||
#define THREE_PASS /* branch and offset optimization */
|
||||
#define LISTING /* enable listing facilities */
|
||||
#define RELOCATION /* generate relocation info */
|
||||
#define DEBUG 2
|
||||
|
||||
#undef valu_t
|
||||
#define valu_t long
|
73
mach/i386/as/mach1.c
Normal file
73
mach/i386/as/mach1.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#define RCSID1 "$Header$"
|
||||
|
||||
/*
|
||||
* INTEL 80386 C declarations
|
||||
*/
|
||||
|
||||
#define low6(z) (z & 077)
|
||||
#define fit6(z) (low6(z) == z)
|
||||
|
||||
#define ufitb(z) ((unsigned)(z) <= 255)
|
||||
|
||||
#define IS_R8 0x100
|
||||
#define IS_R32 0x200
|
||||
#define IS_EXPR 0x400
|
||||
#define IS_RSEG 0x800
|
||||
|
||||
#define is_expr(reg) ((reg)&IS_EXPR)
|
||||
#define is_segreg(reg) ((reg)&IS_RSEG)
|
||||
#define is_reg(reg) (((reg)&(IS_R8|IS_R32)) != 0)
|
||||
#define is_acc(reg) (((reg)&(IS_R8|IS_R32)) == (reg))
|
||||
|
||||
struct operand {
|
||||
int mod;
|
||||
int rm;
|
||||
int reg;
|
||||
int sib; /* scale-index-base */
|
||||
expr_t exp;
|
||||
};
|
||||
|
||||
extern struct operand op_1, op_2;
|
||||
|
||||
#define mod_1 op_1.mod
|
||||
#define mod_2 op_2.mod
|
||||
#define rm_1 op_1.rm
|
||||
#define rm_2 op_2.rm
|
||||
#define reg_1 op_1.reg
|
||||
#define reg_2 op_2.reg
|
||||
#define sib_1 op_1.sib
|
||||
#define sib_2 op_2.sib
|
||||
#define exp_1 op_1.exp
|
||||
#define exp_2 op_2.exp
|
||||
|
||||
#ifdef RELOCATION
|
||||
extern int rel_1, rel_2;
|
||||
#endif
|
||||
|
||||
#ifndef extern
|
||||
extern char regindex_ind[8][8];
|
||||
#else
|
||||
/* First index is base register; second index is index register;
|
||||
sp cannot be an index register.
|
||||
For base and index register indirect mode, bp cannot be the
|
||||
base register, but this info is not included in this array.
|
||||
This can always be handled by using the base and index register with
|
||||
displacement mode.
|
||||
*/
|
||||
char regindex_ind[8][8] = {
|
||||
000, 010, 020, 030, -1, 050, 060, 070,
|
||||
001, 011, 021, 031, -1, 051, 061, 071,
|
||||
002, 012, 022, 032, -1, 052, 062, 072,
|
||||
003, 013, 023, 033, -1, 053, 063, 073,
|
||||
004, 014, 024, 034, -1, 054, 064, 074,
|
||||
005, 015, 025, 035, -1, 055, 065, 075,
|
||||
006, 016, 026, 036, -1, 056, 066, 076,
|
||||
007, 017, 027, 037, -1, 057, 067, 077,
|
||||
};
|
||||
#endif
|
||||
|
||||
extern int address_long INIT(1), operand_long INIT(1);
|
47
mach/i386/as/mach2.c
Normal file
47
mach/i386/as/mach2.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#define RCSID2 "$Header$"
|
||||
|
||||
/*
|
||||
* INTEL 80386 tokens
|
||||
*/
|
||||
|
||||
%token <y_word> R32
|
||||
%token <y_word> R16
|
||||
%token <y_word> R8
|
||||
%token <y_word> RSEG
|
||||
%token <y_word> RSYSCR
|
||||
%token <y_word> RSYSDR
|
||||
%token <y_word> RSYSTR
|
||||
%token <y_word> PREFIX
|
||||
%token <y_word> ADDOP
|
||||
%token <y_word> BITTEST
|
||||
%token <y_word> BOUND
|
||||
%token <y_word> CALFOP
|
||||
%token <y_word> CALLOP
|
||||
%token <y_word> ENTER
|
||||
%token <y_word> EXTEND
|
||||
%token <y_word> EXTOP
|
||||
%token <y_word> EXTOP1
|
||||
%token <y_word> IMUL
|
||||
%token <y_word> IMULB
|
||||
%token <y_word> INCOP
|
||||
%token <y_word> INT
|
||||
%token <y_word> IOOP
|
||||
%token <y_word> JOP
|
||||
%token <y_word> JOP2
|
||||
%token <y_word> LEAOP
|
||||
%token <y_word> LEAOP2
|
||||
%token <y_word> LSHFT
|
||||
%token <y_word> MOV
|
||||
%token <y_word> NOOP_1
|
||||
%token <y_word> NOOP_2
|
||||
%token <y_word> NOTOP
|
||||
%token <y_word> PUSHOP
|
||||
%token <y_word> RET
|
||||
%token <y_word> ROLOP
|
||||
%token <y_word> SETCC
|
||||
%token <y_word> TEST
|
||||
%token <y_word> XCHG
|
279
mach/i386/as/mach3.c
Normal file
279
mach/i386/as/mach3.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#define RCSID3 "$Header$"
|
||||
|
||||
/*
|
||||
* INTEL 80386 keywords
|
||||
*
|
||||
* No system registers for now ...
|
||||
*/
|
||||
|
||||
0, R32, 0, "ax",
|
||||
0, R32, 1, "cx",
|
||||
0, R32, 2, "dx",
|
||||
0, R32, 3, "bx",
|
||||
0, R32, 4, "sp",
|
||||
0, R32, 5, "bp",
|
||||
0, R32, 6, "si",
|
||||
0, R32, 7, "di",
|
||||
0, R32, 0, "eax",
|
||||
0, R32, 1, "ecx",
|
||||
0, R32, 2, "edx",
|
||||
0, R32, 3, "ebx",
|
||||
0, R32, 4, "esp",
|
||||
0, R32, 5, "ebp",
|
||||
0, R32, 6, "esi",
|
||||
0, R32, 7, "edi",
|
||||
0, R8, 0, "al",
|
||||
0, R8, 1, "cl",
|
||||
0, R8, 2, "dl",
|
||||
0, R8, 3, "bl",
|
||||
0, R8, 4, "ah",
|
||||
0, R8, 5, "ch",
|
||||
0, R8, 6, "dh",
|
||||
0, R8, 7, "bh",
|
||||
0, RSEG, 0, "es",
|
||||
0, RSEG, 1, "cs",
|
||||
0, RSEG, 2, "ss",
|
||||
0, RSEG, 3, "ds",
|
||||
0, RSEG, 4, "fs",
|
||||
0, RSEG, 5, "gs",
|
||||
0, RSYSCR, 0, "cr0",
|
||||
0, RSYSCR, 2, "cr2",
|
||||
0, RSYSCR, 3, "cr3",
|
||||
0, RSYSDR, 0, "dr0",
|
||||
0, RSYSDR, 1, "dr1",
|
||||
0, RSYSDR, 2, "dr2",
|
||||
0, RSYSDR, 3, "dr3",
|
||||
0, RSYSDR, 6, "dr6",
|
||||
0, RSYSDR, 7, "dr7",
|
||||
0, RSYSTR, 6, "tr6",
|
||||
0, RSYSTR, 7, "tr7",
|
||||
0, ADDOP, 000, "addb",
|
||||
0, ADDOP, 001, "add",
|
||||
0, ADDOP, 010, "orb",
|
||||
0, ADDOP, 011, "or",
|
||||
0, ADDOP, 020, "adcb",
|
||||
0, ADDOP, 021, "adc",
|
||||
0, ADDOP, 030, "sbbb",
|
||||
0, ADDOP, 031, "sbb",
|
||||
0, ADDOP, 040, "andb",
|
||||
0, ADDOP, 041, "and",
|
||||
0, ADDOP, 050, "subb",
|
||||
0, ADDOP, 051, "sub",
|
||||
0, ADDOP, 060, "xorb",
|
||||
0, ADDOP, 061, "xor",
|
||||
0, ADDOP, 070, "cmpb",
|
||||
0, ADDOP, 071, "cmp",
|
||||
0, BITTEST, 04, "bt",
|
||||
0, BITTEST, 05, "bts",
|
||||
0, BITTEST, 06, "btr",
|
||||
0, BITTEST, 07, "btc",
|
||||
0, CALFOP, 030+(0232<<8), "callf",
|
||||
0, CALFOP, 050+(0352<<8), "jmpf",
|
||||
0, CALLOP, 020+(0350<<8), "call",
|
||||
0, CALLOP, 040+(0351<<8), "jmp",
|
||||
0, ENTER, 0310, "enter",
|
||||
0, EXTEND, 0266, "movzx",
|
||||
0, EXTEND, 0276, "movsx",
|
||||
0, EXTOP, 0002, "lar",
|
||||
0, EXTOP, 0003, "lsl",
|
||||
0, EXTOP, 0274, "bsf",
|
||||
0, EXTOP, 0275, "bsr",
|
||||
0, EXTOP1, 0000, "sldt",
|
||||
0, EXTOP1, 0001, "sgdt",
|
||||
0, EXTOP1, 0010, "str",
|
||||
0, EXTOP1, 0011, "sidt",
|
||||
0, EXTOP1, 0020, "lldt",
|
||||
0, EXTOP1, 0021, "lgdt",
|
||||
0, EXTOP1, 0030, "ltr",
|
||||
0, EXTOP1, 0031, "lidt",
|
||||
0, EXTOP1, 0040, "verr",
|
||||
0, EXTOP1, 0041, "smsw",
|
||||
0, EXTOP1, 0050, "verw",
|
||||
0, EXTOP1, 0061, "lmsw",
|
||||
0, IMUL, 0, "imul",
|
||||
0, IMULB, 0, "imulb",
|
||||
0, INCOP, 000, "incb",
|
||||
0, INCOP, 001, "inc",
|
||||
0, INCOP, 010, "decb",
|
||||
0, INCOP, 011, "dec",
|
||||
0, INT, 0, "int",
|
||||
0, IOOP, 0344, "inb",
|
||||
0, IOOP, 0345, "in",
|
||||
0, IOOP, 0346, "outb",
|
||||
0, IOOP, 0347, "out",
|
||||
0, JOP, 0340, "loopne",
|
||||
0, JOP, 0340, "loopnz",
|
||||
0, JOP, 0341, "loope",
|
||||
0, JOP, 0341, "loopz",
|
||||
0, JOP, 0342, "loop",
|
||||
0, JOP, 0343, "jcxz",
|
||||
0, JOP, 0343, "jecxz",
|
||||
0, JOP2, 0000, "jo",
|
||||
0, JOP2, 0001, "jno",
|
||||
0, JOP2, 0002, "jb",
|
||||
0, JOP2, 0002, "jnae",
|
||||
0, JOP2, 0003, "jae",
|
||||
0, JOP2, 0003, "jnb",
|
||||
0, JOP2, 0004, "je",
|
||||
0, JOP2, 0004, "jz",
|
||||
0, JOP2, 0005, "jne",
|
||||
0, JOP2, 0005, "jnz",
|
||||
0, JOP2, 0006, "jbe",
|
||||
0, JOP2, 0006, "jna",
|
||||
0, JOP2, 0007, "ja",
|
||||
0, JOP2, 0007, "jnbe",
|
||||
0, JOP2, 0010, "js",
|
||||
0, JOP2, 0011, "jns",
|
||||
0, JOP2, 0012, "jp",
|
||||
0, JOP2, 0012, "jpe",
|
||||
0, JOP2, 0013, "jnp",
|
||||
0, JOP2, 0013, "jpo",
|
||||
0, JOP2, 0014, "jl",
|
||||
0, JOP2, 0014, "jnge",
|
||||
0, JOP2, 0015, "jge",
|
||||
0, JOP2, 0015, "jnl",
|
||||
0, JOP2, 0016, "jle",
|
||||
0, JOP2, 0016, "jng",
|
||||
0, JOP2, 0017, "jg",
|
||||
0, JOP2, 0017, "jnle",
|
||||
0, LEAOP, 0142, "bound",
|
||||
0, LEAOP, 0215, "lea",
|
||||
0, LEAOP, 0304, "les",
|
||||
0, LEAOP, 0305, "lds",
|
||||
0, LEAOP2, 0262, "lss",
|
||||
0, LEAOP2, 0264, "lfs",
|
||||
0, LEAOP2, 0265, "lgs",
|
||||
0, LSHFT, 0244, "shld",
|
||||
0, LSHFT, 0254, "shrd",
|
||||
0, MOV, 0, "movb",
|
||||
0, MOV, 1, "mov",
|
||||
0, NOOP_1, 0140, "pusha",
|
||||
0, NOOP_1, 0140, "pushad",
|
||||
0, NOOP_1, 0141, "popa",
|
||||
0, NOOP_1, 0141, "popad",
|
||||
0, NOOP_1, 0156, "outsb",
|
||||
0, NOOP_1, 0157, "outs",
|
||||
0, NOOP_1, 0220, "nop",
|
||||
0, NOOP_1, 0230, "cbw",
|
||||
0, NOOP_1, 0230, "cwde", /* same opcode as cbw! */
|
||||
0, NOOP_1, 0231, "cdq", /* same opcode as cwd! */
|
||||
0, NOOP_1, 0231, "cwd",
|
||||
0, NOOP_1, 0233, "wait",
|
||||
0, NOOP_1, 0234, "pushf",
|
||||
0, NOOP_1, 0235, "popf",
|
||||
0, NOOP_1, 0236, "sahf",
|
||||
0, NOOP_1, 0237, "lahf",
|
||||
0, NOOP_1, 0244, "movsb",
|
||||
0, NOOP_1, 0245, "movs",
|
||||
0, NOOP_1, 0246, "cmpsb",
|
||||
0, NOOP_1, 0246, "insb",
|
||||
0, NOOP_1, 0247, "cmps",
|
||||
0, NOOP_1, 0247, "ins",
|
||||
0, NOOP_1, 0252, "stosb",
|
||||
0, NOOP_1, 0253, "stos",
|
||||
0, NOOP_1, 0254, "lodsb",
|
||||
0, NOOP_1, 0255, "lods",
|
||||
0, NOOP_1, 0256, "scasb",
|
||||
0, NOOP_1, 0257, "scas",
|
||||
0, NOOP_1, 0311, "leave",
|
||||
0, NOOP_1, 0316, "into",
|
||||
0, NOOP_1, 0317, "iret",
|
||||
0, NOOP_1, 0317, "iretd",
|
||||
0, NOOP_1, 0327, "xlat",
|
||||
0, NOOP_1, 0364, "hlt",
|
||||
0, NOOP_1, 0365, "cmc",
|
||||
0, NOOP_1, 0370, "clc",
|
||||
0, NOOP_1, 0371, "stc",
|
||||
0, NOOP_1, 0372, "cli",
|
||||
0, NOOP_1, 0373, "sti",
|
||||
0, NOOP_1, 0374, "cld",
|
||||
0, NOOP_1, 0375, "std",
|
||||
0, NOOP_1, 047, "daa",
|
||||
0, NOOP_1, 057, "das",
|
||||
0, NOOP_1, 067, "aaa",
|
||||
0, NOOP_1, 077, "aas",
|
||||
0, NOOP_2, 017+06<<8, "clts",
|
||||
0, NOOP_2, 0324+012<<8, "aam",
|
||||
0, NOOP_2, 0325+012<<8, "aad",
|
||||
0, NOTOP, 020, "notb",
|
||||
0, NOTOP, 021, "not",
|
||||
0, NOTOP, 030, "negb",
|
||||
0, NOTOP, 031, "neg",
|
||||
0, NOTOP, 040, "mulb",
|
||||
0, NOTOP, 041, "mul",
|
||||
0, NOTOP, 060, "divb",
|
||||
0, NOTOP, 061, "div",
|
||||
0, NOTOP, 070, "idivb",
|
||||
0, NOTOP, 071, "idiv",
|
||||
0, PREFIX, 0144, "fseg",
|
||||
0, PREFIX, 0145, "gseg",
|
||||
0, PREFIX, 0146, "o16", /* operand size toggle */
|
||||
0, PREFIX, 0146, "o32", /* operand size toggle */
|
||||
0, PREFIX, 0147, "a16", /* address size toggle */
|
||||
0, PREFIX, 0147, "a32", /* address size toggle */
|
||||
0, PREFIX, 0360, "lock",
|
||||
0, PREFIX, 0362, "rep",
|
||||
0, PREFIX, 0362, "repne",
|
||||
0, PREFIX, 0362, "repnz",
|
||||
0, PREFIX, 0363, "repe",
|
||||
0, PREFIX, 0363, "repz",
|
||||
0, PREFIX, 046, "eseg",
|
||||
0, PREFIX, 056, "cseg",
|
||||
0, PREFIX, 066, "sseg",
|
||||
0, PREFIX, 076, "dseg",
|
||||
0, PUSHOP, 0, "push",
|
||||
0, PUSHOP, 1, "pop",
|
||||
0, RET, 0303, "ret",
|
||||
0, RET, 0313, "retf",
|
||||
0, ROLOP, 000, "rolb",
|
||||
0, ROLOP, 001, "rol",
|
||||
0, ROLOP, 010, "rorb",
|
||||
0, ROLOP, 011, "ror",
|
||||
0, ROLOP, 020, "rclb",
|
||||
0, ROLOP, 021, "rcl",
|
||||
0, ROLOP, 030, "rcrb",
|
||||
0, ROLOP, 031, "rcr",
|
||||
0, ROLOP, 040, "salb",
|
||||
0, ROLOP, 040, "shlb",
|
||||
0, ROLOP, 041, "sal",
|
||||
0, ROLOP, 041, "shl",
|
||||
0, ROLOP, 050, "shrb",
|
||||
0, ROLOP, 051, "shr",
|
||||
0, ROLOP, 070, "sarb",
|
||||
0, ROLOP, 071, "sar",
|
||||
0, SETCC, 0000, "seto",
|
||||
0, SETCC, 0001, "setno",
|
||||
0, SETCC, 0002, "setb",
|
||||
0, SETCC, 0002, "setnae",
|
||||
0, SETCC, 0003, "setae",
|
||||
0, SETCC, 0003, "setnb",
|
||||
0, SETCC, 0004, "sete",
|
||||
0, SETCC, 0004, "setz",
|
||||
0, SETCC, 0005, "setne",
|
||||
0, SETCC, 0005, "setnz",
|
||||
0, SETCC, 0006, "setbe",
|
||||
0, SETCC, 0006, "setna",
|
||||
0, SETCC, 0007, "seta",
|
||||
0, SETCC, 0007, "setnbe",
|
||||
0, SETCC, 0010, "sets",
|
||||
0, SETCC, 0011, "setns",
|
||||
0, SETCC, 0012, "setp",
|
||||
0, SETCC, 0012, "setpe",
|
||||
0, SETCC, 0013, "setnp",
|
||||
0, SETCC, 0013, "setpo",
|
||||
0, SETCC, 0014, "setl",
|
||||
0, SETCC, 0014, "setnge",
|
||||
0, SETCC, 0015, "setge",
|
||||
0, SETCC, 0015, "setnl",
|
||||
0, SETCC, 0016, "setle",
|
||||
0, SETCC, 0016, "setng",
|
||||
0, SETCC, 0017, "setg",
|
||||
0, SETCC, 0017, "setnle",
|
||||
0, TEST, 0, "testb",
|
||||
0, TEST, 1, "test",
|
||||
0, XCHG, 0, "xchgb",
|
||||
0, XCHG, 1, "xchg",
|
198
mach/i386/as/mach4.c
Normal file
198
mach/i386/as/mach4.c
Normal file
|
@ -0,0 +1,198 @@
|
|||
#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
|
||||
: { address_long = 1; operand_long = 1; }
|
||||
prefix oper
|
||||
;
|
||||
prefix : /* empty */
|
||||
| prefix PREFIX
|
||||
{ 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);}
|
||||
| BOUND R32 ',' mem
|
||||
{ emit1($1); ea_2($2<<3); }
|
||||
| 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);
|
||||
#ifdef RELOCATION
|
||||
newrelo($4.typ, RELO4);
|
||||
#endif
|
||||
emit4((long)($4.val));
|
||||
#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);}
|
||||
| LSHFT ea_1 ',' R32 ',' ea_2
|
||||
{ extshft($1, $4);}
|
||||
| EXTEND R32 ',' ea_2
|
||||
{ emit1(0xF); emit1($1|1); ea_2($2<<3);}
|
||||
| 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
|
||||
{ reg_1 = $2 | IS_R32; imul($2); }
|
||||
| IMUL R32 ',' ea_ea
|
||||
{ imul($2);}
|
||||
| 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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
if ($1 != 1 || !(reg_1 & IS_R32))
|
||||
serror("syntax error");
|
||||
emit1(0xF); emit1(046); emit1(0200|($4<<3)|(reg_1&07));}
|
||||
| MOV RSYSCR ',' R32
|
||||
{
|
||||
if ($1 != 1) serror("syntax error");
|
||||
emit1(0xF); emit1(040); emit1(0200|($4<<3)|$2);}
|
||||
| MOV RSYSDR ',' R32
|
||||
{
|
||||
if ($1 != 1) serror("syntax error");
|
||||
emit1(0xF); emit1(041); emit1(0200|($4<<3)|$2);}
|
||||
| MOV RSYSTR ',' R32
|
||||
{
|
||||
if ($1 != 1) serror("syntax error");
|
||||
emit1(0xF); emit1(044); emit1(0200|($4<<3)|$2);}
|
||||
;
|
||||
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
|
||||
;
|
533
mach/i386/as/mach5.c
Normal file
533
mach/i386/as/mach5.c
Normal file
|
@ -0,0 +1,533 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#define RCSID5 "$Header$"
|
||||
|
||||
/*
|
||||
* INTEL 80386 special routines
|
||||
*/
|
||||
|
||||
ea_1(param) {
|
||||
if (is_expr(reg_1)) {
|
||||
serror("bad operand");
|
||||
return;
|
||||
}
|
||||
if (is_reg(reg_1)) {
|
||||
switch(reg_1&07) {
|
||||
case 4:
|
||||
emit1(0300 | param | 04);
|
||||
emit1(0300 | 0100);
|
||||
default:
|
||||
emit1(0300 | param | (reg_1&07));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (rm_1 == 04) {
|
||||
/* sib field use here */
|
||||
emit1(mod_1 << 6 | param | 04);
|
||||
emit1(sib_1 | reg_1);
|
||||
if ((mod_1 == 0 && reg_1 == 5) || mod_1 == 2) {
|
||||
#ifdef RELOCATION
|
||||
RELOMOVE(relonami, rel_1);
|
||||
newrelo(exp_1.typ, RELO4);
|
||||
#endif
|
||||
emit4((long)(exp_1.val));
|
||||
}
|
||||
else if (mod_1 == 1) emit1((int)(exp_1.val));
|
||||
return;
|
||||
}
|
||||
emit1(mod_1<<6 | param | (reg_1&07));
|
||||
if ((mod_1 == 0 && reg_1 == 5) || mod_1 == 2) {
|
||||
#ifdef RELOCATION
|
||||
RELOMOVE(relonami, rel_1);
|
||||
newrelo(exp_1.typ, RELO4);
|
||||
#endif
|
||||
emit4((long)(exp_1.val));
|
||||
}
|
||||
else if (mod_1 == 1) {
|
||||
emit1((int)(exp_1.val));
|
||||
}
|
||||
}
|
||||
|
||||
ea_2(param) {
|
||||
|
||||
op_1 = op_2;
|
||||
RELOMOVE(rel_1, rel_2);
|
||||
ea_1(param);
|
||||
}
|
||||
|
||||
int
|
||||
checkscale(val)
|
||||
valu_t val;
|
||||
{
|
||||
int v = val;
|
||||
|
||||
if (v != val) v = 0;
|
||||
switch(v) {
|
||||
case 1:
|
||||
return 0;
|
||||
case 2:
|
||||
return 1 << 6;
|
||||
case 4:
|
||||
return 2 << 6;
|
||||
case 8:
|
||||
return 3 << 6;
|
||||
default:
|
||||
serror("bad scale");
|
||||
return 0;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
reverse() {
|
||||
struct operand op;
|
||||
#ifdef RELOCATION
|
||||
int r = rel_1;
|
||||
|
||||
rel_1 = rel_2; rel_2 = r;
|
||||
#endif
|
||||
op = op_1; op_1 = op_2; op_2 = op;
|
||||
}
|
||||
|
||||
badsyntax() {
|
||||
|
||||
serror("bad operands");
|
||||
}
|
||||
|
||||
regsize(sz)
|
||||
int sz;
|
||||
{
|
||||
register int bit;
|
||||
|
||||
bit = (sz&1) ? 0 : IS_R8;
|
||||
if ((is_reg(reg_1) && (reg_1 & IS_R8) != bit) ||
|
||||
(is_reg(reg_2) && (reg_2 & IS_R8) != bit))
|
||||
serror("register error");
|
||||
}
|
||||
|
||||
indexed() {
|
||||
mod_2 = 0;
|
||||
if (sib_2 == -1)
|
||||
serror("register error");
|
||||
if (rm_2 == 0 && reg_2 == 4) {
|
||||
/* base register sp, no index register; use
|
||||
indexed mode without index register
|
||||
*/
|
||||
rm_2 = 04;
|
||||
sib_2 = 044;
|
||||
}
|
||||
if (reg_2 == 015) {
|
||||
reg_2 = 05;
|
||||
return;
|
||||
}
|
||||
if (exp_2.typ != S_ABS || fitb(exp_2.val) == 0)
|
||||
mod_2 = 02;
|
||||
else if (exp_2.val != 0 || reg_2 == 5)
|
||||
mod_2 = 01;
|
||||
}
|
||||
|
||||
ebranch(opc,exp)
|
||||
register int opc;
|
||||
expr_t exp;
|
||||
{
|
||||
/* Conditional branching; Full displacements are available
|
||||
on the 80386, so the welknown trick with the reverse branch
|
||||
over a jump is not needed here.
|
||||
The only complication here is with the address size, which
|
||||
can be set with a prefix. In this case, the user gets what
|
||||
he asked for.
|
||||
*/
|
||||
register int sm;
|
||||
register long dist;
|
||||
int saving = address_long ? 4 : 2;
|
||||
|
||||
dist = exp.val - (DOTVAL + 2);
|
||||
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
|
||||
dist -= DOTGAIN;
|
||||
sm = dist > 0 ? fitb(dist-saving) : fitb(dist);
|
||||
if ((exp.typ & ~S_DOT) != DOTTYP)
|
||||
sm = 0;
|
||||
if ((sm = small(sm,saving)) == 0) {
|
||||
emit1(0xF);
|
||||
emit1(opc | 0x80);
|
||||
dist -= 2;
|
||||
exp.val = dist;
|
||||
adsize_exp(exp);
|
||||
}
|
||||
else {
|
||||
emit1(opc | 0x70);
|
||||
emit1((int)dist);
|
||||
}
|
||||
}
|
||||
|
||||
branch(opc,exp)
|
||||
register int opc;
|
||||
expr_t exp;
|
||||
{
|
||||
/* LOOP, JCXZ, etc. branch instructions.
|
||||
Here, the offset just must fit in a byte.
|
||||
*/
|
||||
register long dist;
|
||||
|
||||
dist = exp.val - (DOTVAL + 2);
|
||||
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
|
||||
dist -= DOTGAIN;
|
||||
fit((exp.typ & ~S_DOT) == DOTTYP && fitb(dist));
|
||||
emit1(opc);
|
||||
emit1((int)dist);
|
||||
}
|
||||
|
||||
pushop(opc)
|
||||
register int opc;
|
||||
{
|
||||
|
||||
regsize(1);
|
||||
if (is_segreg(reg_1)) {
|
||||
/* segment register */
|
||||
if ((reg_1 & 07) <= 3)
|
||||
emit1(6 | opc | (reg_1&7)<<3);
|
||||
else {
|
||||
emit1(0xF);
|
||||
emit1(0200 | opc | ((reg_1&7)<<3));
|
||||
}
|
||||
} else if (is_reg(reg_1)) {
|
||||
/* normal register */
|
||||
emit1(0120 | opc<<3 | (reg_1&7));
|
||||
} else if (opc == 0) {
|
||||
if (is_expr(reg_1)) {
|
||||
if (exp_1.typ == S_ABS && fitb(exp_1.val)) {
|
||||
emit1(0152);
|
||||
emit1((int)(exp_1.val));
|
||||
}
|
||||
else {
|
||||
emit1(0150);
|
||||
RELOMOVE(relonami, rel_1);
|
||||
opsize_exp(exp_1, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emit1(0377); ea_1(6<<3);
|
||||
}
|
||||
} else {
|
||||
emit1(0217); ea_1(0<<3);
|
||||
}
|
||||
}
|
||||
|
||||
opsize_exp(exp, nobyte)
|
||||
expr_t exp;
|
||||
{
|
||||
if (! nobyte) {
|
||||
#ifdef RELOCATION
|
||||
newrelo(exp.typ, RELO1);
|
||||
#endif
|
||||
emit1((int)(exp.val));
|
||||
}
|
||||
else if (operand_long) {
|
||||
#ifdef RELOCATION
|
||||
newrelo(exp.typ, RELO4);
|
||||
#endif
|
||||
emit4((long)(exp.val));
|
||||
}
|
||||
else {
|
||||
#ifdef RELOCATION
|
||||
newrelo(exp.typ, RELO2);
|
||||
#endif
|
||||
emit2((int)(exp.val));
|
||||
}
|
||||
}
|
||||
|
||||
adsize_exp(exp)
|
||||
expr_t exp;
|
||||
{
|
||||
if (address_long) {
|
||||
#ifdef RELOCATION
|
||||
newrelo(exp.typ, RELO4 | RELPC);
|
||||
#endif
|
||||
emit4((long)(exp.val));
|
||||
}
|
||||
else {
|
||||
if (! fitw(exp.val)) {
|
||||
warning("offset does not fit in 2 bytes; remove prefix");
|
||||
}
|
||||
#ifdef RELOCATION
|
||||
newrelo(exp.typ, RELO2 | RELPC);
|
||||
#endif
|
||||
emit2((int)(exp.val));
|
||||
}
|
||||
}
|
||||
|
||||
addop(opc)
|
||||
register int opc;
|
||||
{
|
||||
|
||||
regsize(opc);
|
||||
if (is_reg(reg_2)) {
|
||||
/* Add register to register or memory */
|
||||
emit1(opc); ea_1((reg_2&7)<<3);
|
||||
} else if (is_acc(reg_1) && is_expr(reg_2)) {
|
||||
/* Add immediate to accumulator */
|
||||
emit1(opc | 4);
|
||||
RELOMOVE(relonami, rel_2);
|
||||
opsize_exp(exp_2, (opc&1));
|
||||
} else if (is_expr(reg_2)) {
|
||||
/* Add immediate to register or memory */
|
||||
if ((opc&1) == 0) {
|
||||
emit1(0200);
|
||||
} else if (exp_2.typ != S_ABS || fitb(exp_2.val) == 0) {
|
||||
emit1(0201);
|
||||
} else {
|
||||
emit1(0203); opc &= ~1;
|
||||
}
|
||||
ea_1(opc & 070);
|
||||
RELOMOVE(relonami, rel_2);
|
||||
opsize_exp(exp_2, (opc&1));
|
||||
} else if (is_reg(reg_1)) {
|
||||
/* Add register or memory to register */
|
||||
emit1(opc | 2);
|
||||
ea_2((reg_1&7)<<3);
|
||||
} else
|
||||
badsyntax();
|
||||
}
|
||||
|
||||
rolop(opc)
|
||||
register int opc;
|
||||
{
|
||||
register int oreg;
|
||||
|
||||
oreg = reg_2;
|
||||
reg_2 = reg_1;
|
||||
regsize(opc);
|
||||
if (oreg == (IS_R8 | 1)) {
|
||||
/* cl register */
|
||||
emit1(0322 | (opc&1)); ea_1(opc&070);
|
||||
} else if (is_expr(oreg) && exp_2.typ == S_ABS && exp_2.val == 1) {
|
||||
/* shift by 1 */
|
||||
emit1(0320 | (opc&1)); ea_1(opc&070);
|
||||
} else if (is_expr(oreg)) {
|
||||
/* shift by byte count */
|
||||
emit1(0300 | (opc & 1));
|
||||
ea_1(opc & 070);
|
||||
#ifdef RELOCATION
|
||||
RELOMOVE(relonami, rel_2);
|
||||
newrelo(exp_2.typ, RELO1);
|
||||
#endif
|
||||
emit1((int)(exp_2.val));
|
||||
}
|
||||
else
|
||||
badsyntax();
|
||||
}
|
||||
|
||||
incop(opc)
|
||||
register int opc;
|
||||
{
|
||||
|
||||
regsize(opc);
|
||||
if ((opc&1) && is_reg(reg_1)) {
|
||||
/* word register */
|
||||
emit1(0100 | (opc&010) | (reg_1&7));
|
||||
} else {
|
||||
emit1(0376 | (opc&1));
|
||||
ea_1(opc & 010);
|
||||
}
|
||||
}
|
||||
|
||||
callop(opc)
|
||||
register int opc;
|
||||
{
|
||||
|
||||
regsize(1);
|
||||
if (is_expr(reg_1)) {
|
||||
if (opc == (040+(0351<<8))) {
|
||||
RELOMOVE(relonami, rel_1);
|
||||
ebranch(0353,exp_1);
|
||||
} else {
|
||||
exp_1.val -= (DOTVAL+3);
|
||||
emit1(opc>>8);
|
||||
RELOMOVE(relonami, rel_1);
|
||||
adsize_exp(exp_1);
|
||||
}
|
||||
} else {
|
||||
emit1(0377); ea_1(opc&070);
|
||||
}
|
||||
}
|
||||
|
||||
xchg(opc)
|
||||
register int opc;
|
||||
{
|
||||
|
||||
regsize(opc);
|
||||
if (! is_reg(reg_1) || is_acc(reg_2)) {
|
||||
reverse();
|
||||
}
|
||||
if (opc == 1 && is_acc(reg_1) && is_reg(reg_2)) {
|
||||
emit1(0220 | (reg_2&7));
|
||||
} else if (is_reg(reg_1)) {
|
||||
emit1(0206 | opc); ea_2((reg_1&7)<<3);
|
||||
} else
|
||||
badsyntax();
|
||||
}
|
||||
|
||||
test(opc)
|
||||
register int opc;
|
||||
{
|
||||
|
||||
regsize(opc);
|
||||
if (is_reg(reg_2) || is_expr(reg_1))
|
||||
reverse();
|
||||
if (is_expr(reg_2)) {
|
||||
if (is_acc(reg_1)) {
|
||||
emit1(0250 | opc);
|
||||
RELOMOVE(relonami, rel_2);
|
||||
opsize_exp(exp_2, (opc&1));
|
||||
}
|
||||
else {
|
||||
emit1(0366 | opc);
|
||||
ea_1(0<<3);
|
||||
RELOMOVE(relonami, rel_2);
|
||||
opsize_exp(exp_2, (opc&1));
|
||||
}
|
||||
} else if (is_reg(reg_1)) {
|
||||
emit1(0204 | opc); ea_2((reg_1&7)<<3);
|
||||
} else
|
||||
badsyntax();
|
||||
}
|
||||
|
||||
mov(opc)
|
||||
register int opc;
|
||||
{
|
||||
|
||||
regsize(opc);
|
||||
if (is_segreg(reg_1)) {
|
||||
/* to segment register */
|
||||
emit1(0216); ea_2((reg_1&3)<<3);
|
||||
} else if (is_segreg(reg_2)) {
|
||||
/* from segment register */
|
||||
emit1(0214); ea_1((reg_2&3)<<3);
|
||||
} else if (is_expr(reg_2)) {
|
||||
/* from immediate */
|
||||
if (is_reg(reg_1)) {
|
||||
/* to register */
|
||||
emit1(0260 | opc<<3 | (reg_1&7));
|
||||
} else {
|
||||
/* to memory */
|
||||
emit1(0306 | opc); ea_1(0<<3);
|
||||
}
|
||||
RELOMOVE(relonami, rel_2);
|
||||
opsize_exp(exp_2, (opc&1));
|
||||
} else if (rm_1 == 05 && is_acc(reg_2)) {
|
||||
/* from accumulator to memory (displacement) */
|
||||
emit1(0242 | opc);
|
||||
RELOMOVE(relonami, rel_1);
|
||||
adsize_exp(exp_1);
|
||||
} else if (rm_2 == 05 && is_acc(reg_1)) {
|
||||
/* from memory (displacement) to accumulator */
|
||||
emit1(0240 | opc);
|
||||
RELOMOVE(relonami, rel_2);
|
||||
adsize_exp(exp_2);
|
||||
} else if (is_reg(reg_2)) {
|
||||
/* from register to memory or register */
|
||||
emit1(0210 | opc); ea_1((reg_2&7)<<3);
|
||||
} else if (is_reg(reg_1)) {
|
||||
/* from memory or register to register */
|
||||
emit1(0212 | opc); ea_2((reg_1&7)<<3);
|
||||
} else
|
||||
badsyntax();
|
||||
}
|
||||
|
||||
extshft(opc, reg)
|
||||
int opc;
|
||||
{
|
||||
int oreg2 = reg_2;
|
||||
|
||||
reg_2 = reg_1;
|
||||
regsize(1);
|
||||
|
||||
emit1(0xF);
|
||||
if (oreg2 == (IS_R8 | 1)) {
|
||||
/* cl register */
|
||||
emit1(opc|1);
|
||||
ea_1(reg << 3);
|
||||
}
|
||||
else if (is_expr(oreg2)) {
|
||||
emit1(opc);
|
||||
ea_1(reg << 3);
|
||||
#ifdef RELOCATION
|
||||
RELOMOVE(relonami, rel_2);
|
||||
newrelo(exp_2.typ, RELO1);
|
||||
#endif
|
||||
emit1((int)(exp_2.val));
|
||||
}
|
||||
else badsyntax();
|
||||
}
|
||||
|
||||
bittestop(opc)
|
||||
int opc;
|
||||
{
|
||||
regsize(1);
|
||||
emit1(0xF);
|
||||
if (is_expr(reg_2)) {
|
||||
emit1(0272);
|
||||
ea_1(opc << 3);
|
||||
#ifdef RELOCATION
|
||||
RELOMOVE(relonami, rel_2);
|
||||
newrelo(exp_2.typ, RELO1);
|
||||
#endif
|
||||
emit1((int)(exp_2.val));
|
||||
}
|
||||
else if (is_reg(reg_2)) {
|
||||
emit1(0203 | opc);
|
||||
ea_1((reg_2&7)<<3);
|
||||
}
|
||||
else badsyntax();
|
||||
}
|
||||
|
||||
imul(reg)
|
||||
int reg;
|
||||
{
|
||||
/* This instruction is more elaborate on the 80386. Its most
|
||||
general form is:
|
||||
imul reg, reg_or_mem, immediate.
|
||||
This is the form processed here.
|
||||
*/
|
||||
regsize(1);
|
||||
if (is_expr(reg_1)) {
|
||||
/* To also handle
|
||||
imul reg, immediate, reg_or_mem
|
||||
*/
|
||||
reverse();
|
||||
}
|
||||
if (is_expr(reg_2)) {
|
||||
/* The immediate form; two cases: */
|
||||
if (exp_2.typ == S_ABS && fitb(exp_2.val)) {
|
||||
/* case 1: 1 byte encoding of immediate */
|
||||
emit1(0153);
|
||||
ea_1(reg << 3);
|
||||
emit1((int)(exp_2.val));
|
||||
}
|
||||
else {
|
||||
/* case 2: WORD or DWORD encoding of immediate */
|
||||
emit1(0151);
|
||||
ea_1(reg << 3);
|
||||
RELOMOVE(relonami, rel_2);
|
||||
opsize_exp(exp_2, 1);
|
||||
}
|
||||
}
|
||||
else if (is_reg(reg_1) && ((reg_1&7) == reg)) {
|
||||
/* the "reg" field and the "reg_or_mem" field are the same,
|
||||
and the 3rd operand is not an immediate ...
|
||||
*/
|
||||
if (reg == 0) {
|
||||
/* how lucky we are, the target is the ax register */
|
||||
emit1(0367);
|
||||
ea_2(06 << 3);
|
||||
}
|
||||
else {
|
||||
/* another register ... */
|
||||
emit1(0xF);
|
||||
emit1(0257);
|
||||
ea_2(reg << 3);
|
||||
}
|
||||
}
|
||||
else badsyntax();
|
||||
}
|
Loading…
Reference in a new issue