Initial revision
This commit is contained in:
parent
62746ef4ff
commit
31b5e111bf
6 changed files with 1472 additions and 0 deletions
33
mach/m68020/as/mach0.c
Normal file
33
mach/m68020/as/mach0.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* @(#)mach0.c 1.5 */
|
||||
/*
|
||||
* Motorola 68020 options
|
||||
*/
|
||||
#undef BITMAX
|
||||
#define BITMAX 20000
|
||||
|
||||
#define THREE_PASS /* branch and offset optimization */
|
||||
#define BYTES_REVERSED /* high order byte has lowest address */
|
||||
#define WORDS_REVERSED /* high order word has lowest address */
|
||||
#define LISTING /* enable listing facilities */
|
||||
#define RELOCATION /* generate relocatable code */
|
||||
#define DEBUG 1
|
||||
|
||||
#undef valu_t
|
||||
#define valu_t long
|
||||
#undef addr_t
|
||||
#define addr_t long
|
||||
|
||||
#undef ASC_LPAR
|
||||
#define ASC_LPAR '{'
|
||||
#undef ASC_RPAR
|
||||
#define ASC_RPAR '}'
|
||||
|
||||
#undef ALIGNWORD
|
||||
#define ALIGNWORD 2
|
||||
#undef ALIGNSECT
|
||||
#define ALIGNSECT 2
|
||||
|
||||
#undef VALWIDTH
|
||||
#define VALWIDTH 8
|
||||
|
||||
#define ASLD
|
99
mach/m68020/as/mach1.c
Normal file
99
mach/m68020/as/mach1.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* @(#)mach1.c 1.8 */
|
||||
/*
|
||||
* Motorola 68020 dependent C declarations
|
||||
*/
|
||||
|
||||
#define low3(z) ((short)(z) & 07)
|
||||
#define low4(z) ((short)(z) & 017)
|
||||
#define low5(z) ((short)(z) & 037)
|
||||
#define low6(z) ((short)(z) & 077)
|
||||
|
||||
#define fit3(z) ((((z)-1) & ~07) == 0)
|
||||
#define fit4(z) (((z) & ~017) == 0)
|
||||
#define fit5(z) (((z) & ~037) == 0)
|
||||
#define fit6(z) (((z) & ~077) == 0)
|
||||
#define fit8(z) (((z) & ~0xFF) == 0)
|
||||
#define fit16(z) (((z) & ~0xFFFF) == 0)
|
||||
|
||||
#define SIZE_B 0000
|
||||
#define SIZE_W 0100
|
||||
#define SIZE_L 0200
|
||||
#define SIZE_NON 0300
|
||||
#define SIZE_DEF SIZE_W
|
||||
|
||||
extern int mrg_1,mrg_2; /* Mode and ReGister */
|
||||
extern short ffew_1, ffew_2; /* Full Format Extension Word */
|
||||
extern expr_t bd_1,bd_2,od_1,od_2; /* base and outer displacements */
|
||||
#ifndef ASLD
|
||||
extern valu_t bd_rel1,bd_rel2,od_rel1,od_rel2;
|
||||
#endif
|
||||
|
||||
#ifdef RELOCATION
|
||||
#ifdef ASLD
|
||||
#define T_EMIT2(a,b,c,d) t_emit2(a,b,c,0)
|
||||
#define T_EMIT4(a,b,c,d) t_emit4(a,b,c,0)
|
||||
#else ALSD
|
||||
#define T_EMIT2(a,b,c,d) t_emit2(a,b,c,d)
|
||||
#define T_EMIT4(a,b,c,d) t_emit4(a,b,c,d)
|
||||
#endif ASLD
|
||||
#else
|
||||
#define T_EMIT2(a,b,c,d) t_emit2(a)
|
||||
#define T_EMIT4(a,b,c,d) t_emit4(a)
|
||||
#endif
|
||||
|
||||
struct instr_t {
|
||||
short i_word; /* word to be emitted */
|
||||
#ifdef RELOCATION
|
||||
short i_relotype;
|
||||
int i_reloinfo;
|
||||
valu_t i_relonami;
|
||||
#endif
|
||||
};
|
||||
typedef struct instr_t instr_t;
|
||||
instr_t instr[30]; /* temporary area for instructions */
|
||||
instr_t *instrp; /* index into instr[] */
|
||||
int dot_offset;
|
||||
|
||||
/* flags used when reading effective addresses */
|
||||
#define INDEX 0300
|
||||
#define PRE_INDEX 0100
|
||||
#define POST_INDEX 0200
|
||||
#define DBL_INDEX 0300
|
||||
#define PC_MODE 0400
|
||||
|
||||
/* addressing mode bits */
|
||||
#define DTA 0x01
|
||||
#define MEM 0x02
|
||||
#define CTR 0x04
|
||||
#define ALT 0x08
|
||||
#define FITB 0x10
|
||||
#define FITW 0x20
|
||||
#define PUTW 0x40
|
||||
#define PUTL 0x80
|
||||
|
||||
#ifndef extern
|
||||
extern short eamode[];
|
||||
#else
|
||||
short eamode[] = {
|
||||
/* 00A */ DTA |ALT,
|
||||
/* 01A */ ALT,
|
||||
/* 02A */ DTA|MEM|CTR|ALT,
|
||||
/* 03A */ DTA|MEM |ALT,
|
||||
/* 04A */ DTA|MEM |ALT,
|
||||
/* 05A */ DTA|MEM|CTR|ALT|FITW|PUTW, /* if relocation wanted, use 06A */
|
||||
/* 06A */ DTA|MEM|CTR|ALT |PUTW, /* relocation handled by ea_1() */
|
||||
/* 07x */ 0,
|
||||
/* 070 */ DTA|MEM|CTR|ALT|FITW|PUTW | (RELO2)<<8,
|
||||
/* 071 */ DTA|MEM|CTR|ALT |PUTL | (RELO4)<<8,
|
||||
/* 072 */ DTA|MEM|CTR |FITW|PUTW, /* if relocation wanted, use 073 */
|
||||
/* 073 */ DTA|MEM|CTR |PUTW, /* relocation handled by ea_1() */
|
||||
/* 074x */ 0,
|
||||
/* 074B */ DTA|MEM |FITB|PUTW | (RELO1)<<8,
|
||||
/* 074W */ DTA|MEM |FITW|PUTW | (RELO2)<<8,
|
||||
/* 074L */ DTA|MEM |PUTL | (RELO4)<<8,
|
||||
};
|
||||
/* RELO2 had to go with mode 070, because the assembly
|
||||
* language programmer can use addresses like
|
||||
* '(expression).w', which still have to be relocatable.
|
||||
*/
|
||||
#endif
|
65
mach/m68020/as/mach2.c
Normal file
65
mach/m68020/as/mach2.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* @(#)mach2.c 1.5 */
|
||||
/*
|
||||
* Motorola 68020 tokens
|
||||
*/
|
||||
|
||||
%token <y_word> SIZE
|
||||
%token <y_word> DREG
|
||||
%token <y_word> AREG
|
||||
%token <y_word> PC
|
||||
%token <y_word> ZPC
|
||||
%token <y_word> CREG
|
||||
%token <y_word> SPEC
|
||||
%token <y_word> ABCD
|
||||
%token <y_word> ADDX
|
||||
%token <y_word> ADD
|
||||
%token <y_word> AND
|
||||
%token <y_word> BITOP
|
||||
%token <y_word> BITFIELD
|
||||
%token <y_word> BF_TO_D
|
||||
%token <y_word> BFINS
|
||||
%token <y_word> SHIFT
|
||||
%token <y_word> SZ_EA
|
||||
%token <y_word> OP_EA
|
||||
%token <y_word> OP_NOOP
|
||||
%token <y_word> LEA
|
||||
%token <y_word> DBR
|
||||
%token <y_word> BR
|
||||
%token <y_word> OP_EXT
|
||||
%token <y_word> OP_RANGE
|
||||
%token <y_word> TRAPCC
|
||||
%token <y_word> PACK
|
||||
%token <y_word> RTM
|
||||
%token <y_word> CHK
|
||||
%token <y_word> DIVMUL
|
||||
%token <y_word> DIVL
|
||||
%token <y_word> CMP
|
||||
%token <y_word> MOVE
|
||||
%token <y_word> MOVEP
|
||||
%token <y_word> MOVEM
|
||||
%token <y_word> MOVEC
|
||||
%token <y_word> MOVES
|
||||
%token <y_word> SWAP
|
||||
%token <y_word> LINK
|
||||
%token <y_word> UNLK
|
||||
%token <y_word> TRAP
|
||||
%token <y_word> STOP
|
||||
%token <y_word> EXG
|
||||
%token <y_word> RTD
|
||||
%token <y_word> BKPT
|
||||
%token <y_word> CALLM
|
||||
%token <y_word> CAS
|
||||
%token <y_word> CAS2
|
||||
%token <y_word> CP
|
||||
%token <y_word> CPBCC
|
||||
%token <y_word> CPDBCC
|
||||
%token <y_word> CPGEN
|
||||
%token <y_word> CPRESTORE
|
||||
%token <y_word> CPSAVE
|
||||
%token <y_word> CPSCC
|
||||
%token <y_word> CPTRAPCC
|
||||
|
||||
%type <y_word> bcdx op_ea regs rrange
|
||||
%type <y_word> reg sizedef sizenon creg
|
||||
%type <y_word> off_width abs31 bd_areg_index
|
||||
%type <y_word> areg_index areg scale cp_cond
|
238
mach/m68020/as/mach3.c
Normal file
238
mach/m68020/as/mach3.c
Normal file
|
@ -0,0 +1,238 @@
|
|||
/* @(#)mach3.c 1.4 */
|
||||
/*
|
||||
* Motorola 68020 keywords
|
||||
*/
|
||||
|
||||
0, SIZE, SIZE_B, ".b",
|
||||
0, SIZE, SIZE_W, ".w",
|
||||
0, SIZE, SIZE_L, ".l",
|
||||
|
||||
0, DREG, 00, "d0",
|
||||
0, DREG, 01, "d1",
|
||||
0, DREG, 02, "d2",
|
||||
0, DREG, 03, "d3",
|
||||
0, DREG, 04, "d4",
|
||||
0, DREG, 05, "d5",
|
||||
0, DREG, 06, "d6",
|
||||
0, DREG, 07, "d7",
|
||||
|
||||
0, AREG, 00, "a0",
|
||||
0, AREG, 01, "a1",
|
||||
0, AREG, 02, "a2",
|
||||
0, AREG, 03, "a3",
|
||||
0, AREG, 04, "a4",
|
||||
0, AREG, 05, "a5",
|
||||
0, AREG, 06, "a6",
|
||||
0, AREG, 07, "a7",
|
||||
0, AREG, 07, "sp",
|
||||
|
||||
0, PC, 0, "pc",
|
||||
0, ZPC, 0, "zpc",
|
||||
|
||||
0, CREG, 04001, "vbr",
|
||||
0, CREG, 0, "sfc",
|
||||
0, CREG, 00001, "dfc",
|
||||
0, CREG, 00002, "cacr",
|
||||
0, CREG, 04002, "caar",
|
||||
0, CREG, 04003, "msp",
|
||||
0, CREG, 04004, "isp",
|
||||
|
||||
0, SPEC, 075, "usp",
|
||||
0, SPEC, 076, "ccr",
|
||||
0, SPEC, 077, "sr",
|
||||
|
||||
0, ABCD, 0140400, "abcd",
|
||||
0, ABCD, 0100400, "sbcd",
|
||||
|
||||
0, ADDX, 0150400, "addx",
|
||||
0, ADDX, 0110400, "subx",
|
||||
|
||||
0, ADD, 0153300, "add",
|
||||
0, ADD, 0112700, "sub",
|
||||
|
||||
0, AND, 0141000, "and",
|
||||
0, AND, 0135000, "eor",
|
||||
0, AND, 0100000, "or",
|
||||
|
||||
0, BITOP, 0000, "btst",
|
||||
0, BITOP, 0100, "bchg",
|
||||
0, BITOP, 0200, "bclr",
|
||||
0, BITOP, 0300, "bset",
|
||||
|
||||
0, BITFIELD, 0164300, "bftst",
|
||||
0, BITFIELD, 0165300, "bfchg",
|
||||
0, BITFIELD, 0166300, "bfclr",
|
||||
0, BITFIELD, 0167300, "bfset",
|
||||
0, BF_TO_D, 0164700, "bfextu",
|
||||
0, BF_TO_D, 0164700, "bfexts",
|
||||
0, BF_TO_D, 0164700, "bfffo",
|
||||
0, BFINS, 0167700, "bfins",
|
||||
|
||||
0, SHIFT, 0160340, "asr",
|
||||
0, SHIFT, 0160740, "asl",
|
||||
0, SHIFT, 0161350, "lsr",
|
||||
0, SHIFT, 0161750, "lsl",
|
||||
0, SHIFT, 0162360, "roxr",
|
||||
0, SHIFT, 0162760, "roxl",
|
||||
0, SHIFT, 0163370, "ror",
|
||||
0, SHIFT, 0163770, "rol",
|
||||
|
||||
0, SZ_EA, 041000|DTA|ALT, "clr",
|
||||
0, SZ_EA, 042000|DTA|ALT, "neg",
|
||||
0, SZ_EA, 040000|DTA|ALT, "negx",
|
||||
0, SZ_EA, 043000|DTA|ALT, "not",
|
||||
0, SZ_EA, 045000|DTA, "tst",
|
||||
|
||||
0, OP_EA, 044000|DTA|ALT, "nbcd",
|
||||
0, OP_EA, 045300|DTA|ALT, "tas",
|
||||
0, OP_EA, 047200|CTR, "jsr",
|
||||
0, OP_EA, 047300|CTR, "jmp",
|
||||
0, OP_EA, 044100|CTR, "pea",
|
||||
|
||||
0, OP_EA, 050300, "st",
|
||||
0, OP_EA, 050700, "sf",
|
||||
0, OP_EA, 051300, "shi",
|
||||
0, OP_EA, 051700, "sls",
|
||||
0, OP_EA, 052300, "scc",
|
||||
0, OP_EA, 052700, "scs",
|
||||
0, OP_EA, 053300, "sne",
|
||||
0, OP_EA, 053700, "seq",
|
||||
0, OP_EA, 054300, "svc",
|
||||
0, OP_EA, 054700, "svs",
|
||||
0, OP_EA, 055300, "spl",
|
||||
0, OP_EA, 055700, "smi",
|
||||
0, OP_EA, 056300, "sge",
|
||||
0, OP_EA, 056700, "slt",
|
||||
0, OP_EA, 057300, "sgt",
|
||||
0, OP_EA, 057700, "sle",
|
||||
|
||||
0, OP_NOOP, 047160, "reset",
|
||||
0, OP_NOOP, 047161, "nop",
|
||||
0, OP_NOOP, 047163, "rte",
|
||||
0, OP_NOOP, 047165, "rts",
|
||||
0, OP_NOOP, 047166, "trapv",
|
||||
0, OP_NOOP, 047167, "rtr",
|
||||
0, OP_NOOP, 045374, "illegal",
|
||||
|
||||
0, PACK, 0100500, "pack",
|
||||
0, PACK, 0100600, "unpk",
|
||||
|
||||
0, DIVMUL, 0100, "divu",
|
||||
0, DIVMUL, 0101, "divs",
|
||||
0, DIVMUL, 0000, "mulu",
|
||||
0, DIVMUL, 0001, "muls",
|
||||
|
||||
0, DIVL, 046100, "divul",
|
||||
0, DIVL, 046101, "divsl",
|
||||
|
||||
0, BR, 060000, "bra",
|
||||
0, BR, 060400, "bsr",
|
||||
0, BR, 061000, "bhi",
|
||||
0, BR, 061400, "bls",
|
||||
0, BR, 062000, "bcc",
|
||||
0, BR, 062400, "bcs",
|
||||
0, BR, 063000, "bne",
|
||||
0, BR, 063400, "beq",
|
||||
0, BR, 064000, "bvc",
|
||||
0, BR, 064400, "bvs",
|
||||
0, BR, 065000, "bpl",
|
||||
0, BR, 065400, "bmi",
|
||||
0, BR, 066000, "bge",
|
||||
0, BR, 066400, "blt",
|
||||
0, BR, 067000, "bgt",
|
||||
0, BR, 067400, "ble",
|
||||
|
||||
0, DBR, 050310, "dbt",
|
||||
0, DBR, 050710, "dbf",
|
||||
0, DBR, 050710, "dbra",
|
||||
0, DBR, 051310, "dbhi",
|
||||
0, DBR, 051710, "dbls",
|
||||
0, DBR, 052310, "dbcc",
|
||||
0, DBR, 052710, "dbcs",
|
||||
0, DBR, 053310, "dbne",
|
||||
0, DBR, 053710, "dbeq",
|
||||
0, DBR, 054310, "dbvc",
|
||||
0, DBR, 054710, "dbvs",
|
||||
0, DBR, 055310, "dbpl",
|
||||
0, DBR, 055710, "dbmi",
|
||||
0, DBR, 056310, "dbge",
|
||||
0, DBR, 056710, "dblt",
|
||||
0, DBR, 057310, "dbgt",
|
||||
0, DBR, 057710, "dble",
|
||||
|
||||
0, OP_EXT, 044000, "ext",
|
||||
0, OP_EXT, 044400, "extb",
|
||||
|
||||
0, OP_RANGE, 04000, "chk2",
|
||||
0, OP_RANGE, 0, "cmp2",
|
||||
|
||||
0, TRAPCC, 050370, "trapt",
|
||||
0, TRAPCC, 050770, "trapf",
|
||||
0, TRAPCC, 051370, "traphi",
|
||||
0, TRAPCC, 051770, "trapls",
|
||||
0, TRAPCC, 052370, "trapcc",
|
||||
0, TRAPCC, 052770, "trapcs",
|
||||
0, TRAPCC, 053370, "trapeq",
|
||||
0, TRAPCC, 053770, "trapvc",
|
||||
0, TRAPCC, 054370, "trapvs",
|
||||
0, TRAPCC, 054770, "trappl",
|
||||
0, TRAPCC, 055370, "trapmi",
|
||||
0, TRAPCC, 055770, "trapge",
|
||||
0, TRAPCC, 056370, "traplt",
|
||||
0, TRAPCC, 056770, "trapgt",
|
||||
0, TRAPCC, 057370, "traple",
|
||||
0, TRAPCC, 057770, "trapne",
|
||||
|
||||
0, CMP, 0, "cmp",
|
||||
|
||||
0, MOVE, 0, "move",
|
||||
0, MOVEP, 0, "movep",
|
||||
0, MOVEM, 0, "movem",
|
||||
0, MOVES, 0, "moves",
|
||||
0, MOVEC, 0, "movec",
|
||||
|
||||
0, SWAP, 0, "swap",
|
||||
|
||||
0, LINK, 0, "link",
|
||||
|
||||
0, UNLK, 0, "unlk",
|
||||
|
||||
0, TRAP, 0, "trap",
|
||||
|
||||
0, STOP, 0, "stop",
|
||||
|
||||
0, CHK, 0, "chk",
|
||||
|
||||
0, RTM, 0, "rtm",
|
||||
|
||||
0, EXG, 0, "exg",
|
||||
|
||||
0, LEA, 0, "lea",
|
||||
|
||||
0, RTD, 0, "rtd",
|
||||
|
||||
0, BKPT, 0, "bkpt",
|
||||
|
||||
0, CALLM, 0, "callm",
|
||||
|
||||
0, CAS, 0, "cas",
|
||||
|
||||
0, CAS2, 0, "cas2",
|
||||
|
||||
0, CP, 00000, "c0",
|
||||
0, CP, 01000, "c1",
|
||||
0, CP, 02000, "c2",
|
||||
0, CP, 03000, "c3",
|
||||
0, CP, 04000, "c4",
|
||||
0, CP, 05000, "c5",
|
||||
0, CP, 06000, "c6",
|
||||
0, CP, 07000, "c7",
|
||||
|
||||
0, CPGEN, 0170000, ".gen",
|
||||
0, CPSCC, 0170100, ".s",
|
||||
0, CPDBCC, 0170110, ".db",
|
||||
0, CPTRAPCC, 0170170, ".trap",
|
||||
0, CPBCC, 0170200, ".br", /* 'r' to distinguish from SIZE_B
|
||||
*/
|
||||
0, CPSAVE, 0170400, ".save",
|
||||
0, CPRESTORE, 0170500, ".restore",
|
428
mach/m68020/as/mach4.c
Normal file
428
mach/m68020/as/mach4.c
Normal file
|
@ -0,0 +1,428 @@
|
|||
/* @(#)mach4.c 1.11 */
|
||||
/*
|
||||
* Motorola 68020 syntax rules
|
||||
*/
|
||||
|
||||
operation
|
||||
: { instrp = instr;
|
||||
dot_offset = 0;
|
||||
}
|
||||
instruction
|
||||
{ emit_instr();
|
||||
}
|
||||
;
|
||||
instruction
|
||||
: bcdx DREG ',' DREG
|
||||
{ T_EMIT2($1 | $2 | $4<<9,0,0,0);}
|
||||
| bcdx '-' '(' AREG ')' ',' '-' '(' AREG ')'
|
||||
{ T_EMIT2($1 | $4 | $9<<9 | 010,0,0,0);}
|
||||
| ADD sizedef ea_ea
|
||||
{ add($1, $2);}
|
||||
| AND sizenon ea_ea
|
||||
{ and($1, $2);}
|
||||
| SHIFT sizedef ea_ea
|
||||
{ shift_op($1, $2);}
|
||||
| SHIFT sizedef ea /* This syntax is also allowed */
|
||||
{ checksize($2, 2);
|
||||
T_EMIT2(($1 & 0177700) | mrg_2,0,0,0);
|
||||
ea_2(SIZE_W, MEM|ALT);
|
||||
}
|
||||
| BR expr
|
||||
{ branch($1, $2);}
|
||||
| DBR DREG ',' expr
|
||||
{ T_EMIT2($1 | $2,0,0,0);
|
||||
$4.val -= (DOTVAL+dot_offset);
|
||||
fit(fitw($4.val));
|
||||
T_EMIT2(loww($4.val), $4.typ,
|
||||
RELPC|RELO2, relonami);
|
||||
}
|
||||
| BITOP ea_ea
|
||||
{ bitop($1);}
|
||||
| BITFIELD ea off_width
|
||||
{ bitfield($1, $3);}
|
||||
| BF_TO_D ea off_width ',' DREG
|
||||
{ bitfield($1, $3 | $5<<12);}
|
||||
| BFINS DREG ',' ea off_width
|
||||
{ bitfield($1, $5 | $2<<12);}
|
||||
| DIVMUL sizedef ea ',' DREG
|
||||
{ checksize($2, 2|4);
|
||||
if ($2 == SIZE_W) {
|
||||
T_EMIT2((0140300^($1<<8))|mrg_2|$5<<9,
|
||||
0, 0, 0);
|
||||
ea_2(SIZE_W, DTA);
|
||||
}
|
||||
else { /* 32 bit dividend or product */
|
||||
T_EMIT2((016000 | ($1 & ~1)) | mrg_2,
|
||||
0, 0, 0);
|
||||
T_EMIT2(($1&1)<<11 | $5<<12 | $5,
|
||||
0, 0, 0);
|
||||
ea_2(SIZE_L, DTA);
|
||||
}
|
||||
}
|
||||
| DIVMUL sizedef ea ',' DREG ':' DREG
|
||||
{ /* 64 bit dividend or product */
|
||||
checksize($2, 4);
|
||||
T_EMIT2((016000 | ($1 & ~1)) | mrg_2, 0, 0, 0);
|
||||
T_EMIT2(($1&1)<<11 | $7<<12 | $5 | 02000,0,0,0);
|
||||
ea_2(SIZE_L, DTA);
|
||||
}
|
||||
| DIVL sizedef ea ',' DREG ':' DREG
|
||||
{ /* 32 bit long division with remainder */
|
||||
checksize($2, 4);
|
||||
T_EMIT2(($1 & ~1) | mrg_2, 0, 0, 0);
|
||||
T_EMIT2(($1 & 1)<<11 | $7<<12 | $5, 0, 0, 0);
|
||||
ea_2(SIZE_L, DTA);
|
||||
}
|
||||
| LEA ea ',' AREG
|
||||
{ T_EMIT2(040700 | mrg_2 | $4<<9,0,0,0);
|
||||
ea_2(SIZE_L, CTR);
|
||||
}
|
||||
| op_ea ea
|
||||
{ if (mrg_2==074)
|
||||
serror("bad adressing category");
|
||||
T_EMIT2(($1&0177700) | mrg_2,0,0,0);
|
||||
ea_2($1&0300, $1&017);
|
||||
}
|
||||
| OP_NOOP
|
||||
{ T_EMIT2($1,0,0,0);}
|
||||
| OP_EXT SIZE DREG
|
||||
{ checksize($2, ($1 & 0400) ? 4 : (2|4));
|
||||
T_EMIT2($1 | $2+0100 | $3,0,0,0);
|
||||
}
|
||||
| OP_RANGE sizedef ea ',' reg
|
||||
{ T_EMIT2(0300 | ($2<<3) | mrg_2,0,0,0);
|
||||
T_EMIT2($1 | ($5<<12),0,0,0);
|
||||
ea_2($2, CTR);
|
||||
}
|
||||
| TRAPCC SIZE imm
|
||||
{ checksize($2, 2|4);
|
||||
T_EMIT2($1 | ($2>>6)+1,0,0,0);
|
||||
ea_2($2, 0);
|
||||
}
|
||||
| TRAPCC { T_EMIT2($1 | 4,0,0,0);}
|
||||
| PACK '-' '(' AREG ')' ',' '-' '(' AREG ')' ',' imm
|
||||
{ T_EMIT2($1 | 1 | $4 | $9<<9, 0, 0, 0);
|
||||
ea_2(SIZE_W, 0);
|
||||
}
|
||||
| PACK DREG ',' DREG ',' imm
|
||||
{ T_EMIT2($1 | $2 | $4<<9, 0, 0, 0);
|
||||
ea_2(SIZE_W, 0);
|
||||
}
|
||||
| CMP sizedef ea_ea
|
||||
{ cmp($2);}
|
||||
| CHK sizedef ea ',' DREG
|
||||
{ checksize($2, 2|4);
|
||||
T_EMIT2(040000 | mrg_2 | $5<<9 |
|
||||
($2==SIZE_W ? 0600 : 0400),
|
||||
0, 0, 0);
|
||||
ea_2($2, DTA);
|
||||
}
|
||||
| MOVE sizenon ea_ea
|
||||
{ move($2);}
|
||||
| MOVEP sizedef ea_ea
|
||||
{ movep($2);}
|
||||
| MOVEM sizedef regs ',' notimmreg
|
||||
{ movem(0, $2, $3);}
|
||||
| MOVEM sizedef notimmreg ',' regs
|
||||
{ movem(1, $2, $5);}
|
||||
| MOVES sizedef ea_ea
|
||||
{ if (mrg_1 <= 017) {
|
||||
T_EMIT2(007000 | $2 | mrg_2,0,0,0);
|
||||
T_EMIT2(mrg_1 << 12 | 04000,0,0,0);
|
||||
ea_2($2,ALT|MEM);
|
||||
} else if (mrg_2 <= 017) {
|
||||
T_EMIT2(007000 | $2 | mrg_1,0,0,0);
|
||||
T_EMIT2(mrg_2 << 12,0,0,0);
|
||||
ea_1($2,ALT|MEM);
|
||||
} else
|
||||
badoperand();
|
||||
}
|
||||
| MOVEC creg ',' reg
|
||||
{ T_EMIT2(047172,0,0,0);
|
||||
T_EMIT2($2 | $4<<12,0,0,0);
|
||||
}
|
||||
| MOVEC reg ',' creg
|
||||
{ T_EMIT2(047173,0,0,0);
|
||||
T_EMIT2($4 | $2<<12,0,0,0);
|
||||
}
|
||||
| EXG reg ',' reg
|
||||
{ if (($2 & 010) == 0)
|
||||
T_EMIT2(
|
||||
(0140500|$4|$2<<9)
|
||||
+
|
||||
(($4&010)<<3)
|
||||
,0,0,0);
|
||||
else
|
||||
T_EMIT2(
|
||||
(0140600|$2|($4&07)<<9)
|
||||
-
|
||||
(($4&010)<<3)
|
||||
,0,0,0);
|
||||
}
|
||||
| SWAP DREG
|
||||
{ T_EMIT2(044100 | $2,0,0,0);}
|
||||
| STOP imm
|
||||
{ T_EMIT2(047162, 0, 0, 0);
|
||||
ea_2(SIZE_W, 0);
|
||||
}
|
||||
| LINK sizenon AREG ',' imm
|
||||
{ link($2, $3);}
|
||||
| UNLK AREG
|
||||
{ T_EMIT2(047130 | $2,0,0,0);}
|
||||
| TRAP '#' absexp
|
||||
{ fit(fit4($3));
|
||||
T_EMIT2(047100|low4($3),0,0,0);
|
||||
}
|
||||
| RTD imm
|
||||
{ T_EMIT2(047164,0,0,0);
|
||||
ea_2(SIZE_W, 0);
|
||||
}
|
||||
| BKPT '#' absexp
|
||||
{ fit(($3 & ~07) == 0);
|
||||
T_EMIT2(044110 | low3($3),0,0,0);
|
||||
}
|
||||
| CALLM '#' absexp ',' ea
|
||||
{ fit(fitb($3));
|
||||
T_EMIT2(03300 | mrg_2,0,0,0);
|
||||
T_EMIT2($3,0,0,0);
|
||||
ea_2(SIZE_L, CTR);
|
||||
}
|
||||
| RTM reg
|
||||
{ T_EMIT2(03300 | $2, 0, 0, 0);}
|
||||
| CAS sizedef DREG ',' DREG ',' ea
|
||||
{ T_EMIT2(04300 | (($2+0100)<<3) | mrg_2,0,0,0);
|
||||
T_EMIT2($5 | ($3<<6),0,0,0);
|
||||
ea_2($2, MEM|ALT);
|
||||
}
|
||||
| CAS2 sizedef DREG ':' DREG ',' DREG ':' DREG ','
|
||||
'(' reg ')' ':' '(' reg ')'
|
||||
{ checksize($2 , 2|4);
|
||||
T_EMIT2(04374 | (($2+0100)<<3),0,0,0);
|
||||
T_EMIT2($3 | ($7<<6) | ($12<<12),0,0,0);
|
||||
T_EMIT2($5 | ($9<<6) | ($16<<12),0,0,0);
|
||||
}
|
||||
| /* Coprocessor instructions; syntax may be changed (please).
|
||||
* No coprocessor defined extension words are emitted.
|
||||
*/
|
||||
CP CPBCC cp_cond expr
|
||||
{ cpbcc($2 | $1 | $3, $4);
|
||||
}
|
||||
| CP CPDBCC cp_cond DREG ',' expr
|
||||
{ T_EMIT2($2 | $1 | $4,0,0,0);
|
||||
$6.val -= (DOTVAL+dot_offset);
|
||||
fit(fitw($6.val));
|
||||
T_EMIT2(loww($6.val), $6.typ,
|
||||
RELPC|RELO2, relonami);
|
||||
}
|
||||
| CP CPGEN
|
||||
{ T_EMIT2($2 | $1,0,0,0);
|
||||
/* NO COMMAND WORD IS EMITTED;
|
||||
* THIS INSTRUCTIONS IS (STILL) ONE BIG RIDDLE.
|
||||
* NO EFFECTIVE ADDRESS IS CALCULATED (SYNTAX ?)
|
||||
*/
|
||||
}
|
||||
| CP CPRESTORE ea
|
||||
{ T_EMIT2($2 | $1 | mrg_2,0,0,0);
|
||||
ea_2(SIZE_W, (mrg_2 & 070)==030 ? 0 : CTR);
|
||||
}
|
||||
| CP CPSAVE ea
|
||||
{ T_EMIT2($2 | $1 | mrg_2,0,0,0);
|
||||
ea_2(SIZE_W,(mrg_2 & 070)==020 ? 0 : CTR|ALT);
|
||||
}
|
||||
| CP CPSCC cp_cond ea
|
||||
{ T_EMIT2($2 | $1 | mrg_2,0,0,0);
|
||||
T_EMIT2($3,0,0,0);
|
||||
ea_2(SIZE_B,DTA|ALT);
|
||||
}
|
||||
| CP CPTRAPCC cp_cond SIZE imm
|
||||
{ checksize($4,2|4);
|
||||
T_EMIT2($2 | $1 | ($4>>6)+1,0,0,0);
|
||||
T_EMIT2($3,0,0,0);
|
||||
ea_2($4, 0);
|
||||
}
|
||||
| CP TRAPCC cp_cond
|
||||
{ T_EMIT2($2 | $1 | 4,0,0,0);
|
||||
T_EMIT2($3,0,0,0);
|
||||
}
|
||||
;
|
||||
cp_cond : '.' absexp
|
||||
{ fit(fit6($2));
|
||||
$$ = low6($2);
|
||||
}
|
||||
;
|
||||
bcdx : ABCD
|
||||
| ADDX sizedef
|
||||
{ $$ = $1 | $2;}
|
||||
;
|
||||
creg : CREG
|
||||
| SPEC { if ($1 != 075)
|
||||
badoperand();
|
||||
$$ = 04000;
|
||||
}
|
||||
;
|
||||
off_width /* note: these should be curly brackets, but that would
|
||||
* leave us without brackets for expressions.
|
||||
*/
|
||||
: '[' abs31 ':' abs31 ']'
|
||||
{ $$ = ($2<<6) | $4;
|
||||
}
|
||||
;
|
||||
abs31 : DREG { $$ = 040 | $1;}
|
||||
| absexp { fit(fit5($1));
|
||||
$$ = low5($1);
|
||||
}
|
||||
;
|
||||
op_ea : OP_EA
|
||||
| SZ_EA sizedef
|
||||
{ $$ = $1 | $2;}
|
||||
;
|
||||
regs : rrange
|
||||
| regs '/' rrange
|
||||
{ $$ = $1 | $3;}
|
||||
;
|
||||
rrange : reg
|
||||
{ $$ = 1<<$1;}
|
||||
| reg '-' reg
|
||||
{ if ($1 > $3)
|
||||
badoperand();
|
||||
for ($$ = 0; $1 <= $3; $1++)
|
||||
$$ |= (1<<$1);
|
||||
}
|
||||
;
|
||||
ea : DREG
|
||||
{ mrg_2 = $1;}
|
||||
| AREG
|
||||
{ mrg_2 = 010 | $1;}
|
||||
| SPEC
|
||||
{ mrg_2 = $1;}
|
||||
| { mrg_2 = 0; ffew_2 = 0400; /* initialization */}
|
||||
notimmreg
|
||||
| imm
|
||||
;
|
||||
notimmreg
|
||||
: '(' AREG ')'
|
||||
{ mrg_2 = 020 | $2;}
|
||||
| '(' AREG ')' '+'
|
||||
{ mrg_2 = 030 | $2;}
|
||||
| '-' '(' AREG ')'
|
||||
{ mrg_2 = 040 | $3;}
|
||||
| '(' expr ')' sizenon
|
||||
{ bd_2 = $2; ea7071($4);
|
||||
RELOMOVE(bd_rel2, relonami);
|
||||
}
|
||||
| '(' bd_areg_index ')'
|
||||
{ if ((mrg_2 & INDEX) == 0)
|
||||
ffew_2 |= 0100; /* suppress index */
|
||||
if ( !(mrg_2 & PC_MODE) &&
|
||||
(ffew_2 & 0300) == 0100 &&
|
||||
bd_2.typ==S_ABS && fitw(bd_2.val)
|
||||
)
|
||||
mrg_2 = (loww(bd_2.val)?050:020) | $2;
|
||||
else {
|
||||
mrg_2 = (mrg_2&PC_MODE)?073:(060 | $2);
|
||||
ffew_2 |= 060; /* long displacement */
|
||||
}
|
||||
}
|
||||
| '(' '[' bd_areg_index ']' index_od ')'
|
||||
{ switch(mrg_2 & INDEX) {
|
||||
case 0:
|
||||
ffew_2 |= 0163; /* suppress index */
|
||||
break;
|
||||
case DBL_INDEX:
|
||||
serror("bad indexing");
|
||||
case PRE_INDEX:
|
||||
ffew_2 |= 063; break;
|
||||
case POST_INDEX:
|
||||
ffew_2 |= 067; break;
|
||||
}
|
||||
mrg_2 = (mrg_2 & PC_MODE) ? 073 : (060 | $3);
|
||||
}
|
||||
;
|
||||
imm : '#' expr
|
||||
{ mrg_2 = 074; bd_2 = $2;
|
||||
RELOMOVE(bd_rel2, relonami);
|
||||
}
|
||||
;
|
||||
bd_areg_index
|
||||
: /* empty */
|
||||
{ $$ = 0; ffew_2 |= 0200;
|
||||
/* base-reg suppressed */
|
||||
bd_2.typ = S_ABS; bd_2.val = (valu_t)0;
|
||||
/* zero displacement */
|
||||
}
|
||||
| expr { $$ = 0; ffew_2 |= 0300;
|
||||
bd_2 = $1;
|
||||
RELOMOVE(bd_rel2, relonami);
|
||||
}
|
||||
| areg_index
|
||||
{ bd_2.typ = S_ABS; bd_2.val = (valu_t)0;
|
||||
}
|
||||
| expr ',' areg_index
|
||||
{ $$ = $3; bd_2 = $1;
|
||||
RELOMOVE(bd_rel2, relonami);
|
||||
}
|
||||
;
|
||||
areg_index
|
||||
: areg
|
||||
| index { $$ = 0;
|
||||
ffew_2 |= 0200; /* base-reg suppressed */
|
||||
mrg_2 |= PRE_INDEX;
|
||||
}
|
||||
| areg ',' index
|
||||
{ mrg_2 |= PRE_INDEX;
|
||||
}
|
||||
;
|
||||
areg : AREG
|
||||
| PC { mrg_2 |= PC_MODE;}
|
||||
| ZPC { mrg_2 |= PC_MODE;
|
||||
ffew_2 |= 0200; /* base-reg suppressed */
|
||||
}
|
||||
;
|
||||
index : reg sizedef scale
|
||||
{ checksize($2, 2|4);
|
||||
ffew_2 |= $1<<12 | ($2&0200)<<4 | $3;
|
||||
}
|
||||
;
|
||||
scale : /* empty */
|
||||
{ $$ = 0;}
|
||||
| '*' absexp
|
||||
{ $$ = checkscale($2);}
|
||||
;
|
||||
index_od: /* empty */
|
||||
{ od_2.typ = S_ABS; od_2.val = (valu_t)0;}
|
||||
| ',' index
|
||||
{ od_2.typ = S_ABS; od_2.val = (valu_t)0;
|
||||
mrg_2 |= POST_INDEX;
|
||||
}
|
||||
| ',' expr
|
||||
{ od_2 = $2;
|
||||
RELOMOVE(od_rel2, relonami);
|
||||
}
|
||||
| ',' index ',' expr
|
||||
{ od_2 = $4;
|
||||
mrg_2 |= POST_INDEX;
|
||||
RELOMOVE(od_rel2, relonami);
|
||||
}
|
||||
;
|
||||
reg : DREG
|
||||
| AREG
|
||||
{ $$ = $1 | 010;}
|
||||
;
|
||||
sizedef : /* empty */
|
||||
{ $$ = SIZE_DEF;}
|
||||
| SIZE
|
||||
;
|
||||
sizenon : /* empty */
|
||||
{ $$ = SIZE_NON;}
|
||||
| SIZE
|
||||
;
|
||||
ea_ea : ea ','
|
||||
{ mrg_1 = mrg_2;
|
||||
bd_1 = bd_2;
|
||||
od_1 = od_2;
|
||||
ffew_1 = ffew_2;
|
||||
RELOMOVE(bd_rel1, bd_rel2);
|
||||
RELOMOVE(od_rel1, od_rel2);
|
||||
}
|
||||
ea
|
||||
;
|
609
mach/m68020/as/mach5.c
Normal file
609
mach/m68020/as/mach5.c
Normal file
|
@ -0,0 +1,609 @@
|
|||
/* @(#)mach5.c 1.16 */
|
||||
/*
|
||||
* Motorola 68020 auxiliary functions
|
||||
*/
|
||||
|
||||
/* With pc-relative modes the offset is calulated from the address of the
|
||||
* extension word. This address is not known until the instruction opcode(s)
|
||||
* have been emitted. Since this address is unknown, the offset from pc
|
||||
* cannot be calculated correctly, so it cannot immediately be decided whether
|
||||
* to use mode 072 (pc-relative with 16 bit offset) or mode 073 (pc_relative
|
||||
* with possibly 32 bit offset) Because of this, instruction opcodes
|
||||
* are not really emitted right away, but temporarily stored. This way
|
||||
* the address of the extension word is known so the offset can be calculated
|
||||
* correctly and it then can be decided to use mode 072 or 073; this can be
|
||||
* altered in the instruction opcode, if necessary. For the sake of consistency
|
||||
* the effective address(es) are also stored temporarily. The instruction is
|
||||
* then emitted in one go, by emit_instr().
|
||||
*/
|
||||
|
||||
emit_instr()
|
||||
{
|
||||
register instr_t *ip;
|
||||
|
||||
for (ip=instr; ip<instrp; emit2(ip++->i_word)) {
|
||||
#ifdef RELOCATION
|
||||
RELOMOVE(relonami, ip->i_relonami);
|
||||
if (ip->i_reloinfo)
|
||||
newrelo(ip->i_relotype, ip->i_reloinfo | RELBR | RELWR);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef RELOCATION
|
||||
t_emit2(word, relotype, reloinfo, relnm)
|
||||
short word;
|
||||
short relotype;
|
||||
valu_t relnm;
|
||||
#else
|
||||
t_emit2(word)
|
||||
short word;
|
||||
#endif
|
||||
{
|
||||
#ifdef RELOCATION
|
||||
if (instrp->i_reloinfo = reloinfo) {
|
||||
RELOMOVE(instrp->i_relonami, relnm);
|
||||
instrp->i_relotype = relotype;
|
||||
}
|
||||
#endif
|
||||
instrp++->i_word = word;
|
||||
dot_offset += 2;
|
||||
}
|
||||
|
||||
#ifdef RELOCATION
|
||||
t_emit4(words, relotype, reloinfo, relnm)
|
||||
long words;
|
||||
short relotype;
|
||||
valu_t relnm;
|
||||
#else
|
||||
t_emit4(words)
|
||||
long words;
|
||||
#endif
|
||||
{
|
||||
T_EMIT2((short)(words>>16), relotype, reloinfo, relnm);
|
||||
T_EMIT2((short)(words), 0, 0, 0);
|
||||
}
|
||||
|
||||
ea_1(sz, bits)
|
||||
{
|
||||
/* Because displacements come in three sizes (null displacement,
|
||||
* word and long displacement), each displacement requires
|
||||
* two bits in the bittable, so two calls to small. Sometimes
|
||||
* one of these calls is a dummy call.
|
||||
*/
|
||||
|
||||
register flag;
|
||||
register sm, sm1, sm2;
|
||||
|
||||
if (mrg_1 > 074)
|
||||
serror("no specials");
|
||||
if ((flag = eamode[mrg_1>>3]) == 0)
|
||||
if ((flag = eamode[010 + (mrg_1&07)]) == 0)
|
||||
flag = eamode[015 + (sz>>6)];
|
||||
if ((mrg_1 & 070) == 010)
|
||||
checksize(sz, 2|4);
|
||||
bits &= ~flag;
|
||||
if (bits)
|
||||
serror("bad addressing category");
|
||||
if (mrg_1==073 && (ffew_1 & 0200) == 0 && (bd_1.typ & ~S_DOT) == DOTTYP)
|
||||
bd_1.val -= (DOTVAL + dot_offset);
|
||||
|
||||
if ( (mrg_1==073) || (mrg_1&070)==060 ) {
|
||||
sm = (
|
||||
(mrg_1==073 && (bd_1.typ & ~S_DOT)==DOTTYP)
|
||||
||
|
||||
(bd_1.typ == S_ABS)
|
||||
);
|
||||
if (small(sm && fitw(bd_1.val), 2)) {
|
||||
sm = (
|
||||
(sm1 = ((ffew_1 & 0307)==0 && fitb(bd_1.val)))
|
||||
||
|
||||
(sm2 = ((ffew_1 & 0307)==0100 && mrg_1==073))
|
||||
||
|
||||
(bd_1.val==0)
|
||||
);
|
||||
if (small(sm,2)) {
|
||||
if (sm1) { /* brief format extension */
|
||||
T_EMIT2((ffew_1&0177000) | lowb(bd_1.val),
|
||||
0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (sm2) {
|
||||
/* change mode to 072 in opcode word */
|
||||
instr->i_word &= ~1;
|
||||
T_EMIT2(loww(bd_1.val), 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
ffew_1 &= ~040; /* null displacement */
|
||||
}
|
||||
else
|
||||
ffew_1 &= ~020; /* word displacement */
|
||||
} else
|
||||
sm = small(0,2); /* dummy call */
|
||||
|
||||
if (ffew_1 & 3) {
|
||||
sm = (od_1.typ == S_ABS);
|
||||
if (small(sm && fitw(od_1.val), 2))
|
||||
ffew_1 &= small(od_1.val==0, 2) ? ~2 : ~1;
|
||||
else
|
||||
sm = small(0,2); /* dummy call */
|
||||
}
|
||||
|
||||
assert((ffew_1 & 0410) == 0400);
|
||||
T_EMIT2(ffew_1, 0, 0, 0);
|
||||
|
||||
assert(ffew_1 & 060);
|
||||
switch(ffew_1 & 060) {
|
||||
case 020:
|
||||
break;
|
||||
case 040:
|
||||
T_EMIT2(loww(bd_1.val), 0, 0, 0);
|
||||
break;
|
||||
case 060:
|
||||
T_EMIT4( bd_1.val,
|
||||
bd_1.typ,
|
||||
(mrg_1 == 073 && (ffew_1 & 0200) == 0)
|
||||
? RELPC|RELO4
|
||||
: RELO4,
|
||||
bd_rel1
|
||||
);
|
||||
}
|
||||
|
||||
if (ffew_1 & 3) {
|
||||
switch(ffew_1 & 3) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
T_EMIT2(loww(od_1.val), 0, 0, 0);
|
||||
break;
|
||||
case 3:
|
||||
T_EMIT4(od_1.val, od_1.typ, RELO4, od_rel1);
|
||||
}
|
||||
}
|
||||
return; /* mode 060 and 073 have been dealt with */
|
||||
}
|
||||
|
||||
if (flag & FITW)
|
||||
if (
|
||||
! fitw(bd_1.val)
|
||||
&&
|
||||
(mrg_1 != 074 || ! fit16(bd_1.val))
|
||||
)
|
||||
nofit();
|
||||
if (flag & FITB) {
|
||||
if (
|
||||
! fitb(bd_1.val)
|
||||
&&
|
||||
(mrg_1 != 074 || ! fit8(bd_1.val))
|
||||
)
|
||||
nofit();
|
||||
if (mrg_1 == 074)
|
||||
bd_1.val &= 0xFF;
|
||||
}
|
||||
if (flag & PUTL)
|
||||
T_EMIT4(bd_1.val, bd_1.typ, (flag>>8), bd_rel1);
|
||||
if (flag & PUTW)
|
||||
T_EMIT2(loww(bd_1.val), bd_1.typ, (flag>>8), bd_rel1);
|
||||
}
|
||||
|
||||
ea_2(sz, bits)
|
||||
{
|
||||
mrg_1 = mrg_2;
|
||||
bd_1 = bd_2;
|
||||
od_1 = od_2;
|
||||
ffew_1 = ffew_2;
|
||||
RELOMOVE(bd_rel1, bd_rel2);
|
||||
RELOMOVE(od_rel1, od_rel2);
|
||||
ea_1(sz, bits);
|
||||
}
|
||||
|
||||
checksize(sz, bits)
|
||||
{
|
||||
if ((bits & (1 << (sz>>6))) == 0)
|
||||
serror("bad size");
|
||||
}
|
||||
|
||||
checkscale(val)
|
||||
valu_t val;
|
||||
{
|
||||
switch(val) {
|
||||
case 1: return 0;
|
||||
case 2: return 1<<9;
|
||||
case 4: return 2<<9;
|
||||
case 8: return 3<<9;
|
||||
default: serror("bad scale"); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
badoperand()
|
||||
{
|
||||
serror("bad operands");
|
||||
}
|
||||
|
||||
shift_op(opc, sz)
|
||||
{
|
||||
if (mrg_1 < 010 && mrg_2 < 010) {
|
||||
T_EMIT2((opc & 0170470) | sz | mrg_1<<9 | mrg_2, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (bd_1.typ != S_ABS || mrg_1 != 074) {
|
||||
badoperand();
|
||||
return;
|
||||
}
|
||||
if (mrg_2 < 010) {
|
||||
fit(fit3(bd_1.val));
|
||||
T_EMIT2((opc & 0170430) | sz | low3(bd_1.val)<<9 | mrg_2,0,0,0);
|
||||
return;
|
||||
}
|
||||
checksize(sz, 2);
|
||||
fit(bd_1.val == 1);
|
||||
T_EMIT2((opc & 0177700) | mrg_2, 0, 0, 0);
|
||||
ea_2(SIZE_W, MEM|ALT);
|
||||
}
|
||||
|
||||
bitop(opc)
|
||||
{
|
||||
register bits;
|
||||
|
||||
bits = DTA|ALT;
|
||||
if (opc == 0 && (mrg_1 < 010 || mrg_2 != 074))
|
||||
bits = DTA;
|
||||
if (mrg_1 < 010) {
|
||||
T_EMIT2(opc | 0400 | mrg_1<<9 | mrg_2, 0, 0, 0);
|
||||
ea_2(0, bits);
|
||||
return;
|
||||
}
|
||||
if (mrg_1 == 074) {
|
||||
T_EMIT2(opc | 04000 | mrg_2, 0, 0, 0);
|
||||
ea_1(SIZE_W, 0);
|
||||
ea_2(0, bits);
|
||||
return;
|
||||
}
|
||||
badoperand();
|
||||
}
|
||||
|
||||
bitfield(opc, extension)
|
||||
{
|
||||
T_EMIT2(opc | mrg_2, 0, 0, 0);
|
||||
T_EMIT2(extension, 0, 0, 0);
|
||||
ea_2(SIZE_L, (mrg_2 < 010) ? 0 : (CTR | ALT));
|
||||
}
|
||||
|
||||
add(opc, sz)
|
||||
{
|
||||
if ((mrg_2 & 070) == 010)
|
||||
checksize(sz, 2|4);
|
||||
if (
|
||||
mrg_1 == 074
|
||||
&&
|
||||
small(
|
||||
bd_1.typ==S_ABS && fit3(bd_1.val),
|
||||
sz==SIZE_L ? 4 : 2
|
||||
)
|
||||
) {
|
||||
T_EMIT2((opc&0400) | 050000 | low3(bd_1.val)<<9 | sz | mrg_2,
|
||||
0, 0, 0);
|
||||
ea_2(sz, ALT);
|
||||
return;
|
||||
}
|
||||
if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
|
||||
T_EMIT2((opc&03000) | sz | mrg_2, 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
ea_2(sz, DTA|ALT);
|
||||
return;
|
||||
}
|
||||
if ((mrg_2 & 070) == 010) {
|
||||
T_EMIT2((opc&0170300) | (mrg_2&7)<<9 | sz<<1 | mrg_1, 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
return;
|
||||
}
|
||||
if (to_dreg(opc, sz, 0))
|
||||
return;
|
||||
if (from_dreg(opc, sz, ALT|MEM))
|
||||
return;
|
||||
badoperand();
|
||||
}
|
||||
|
||||
and(opc, sz)
|
||||
{
|
||||
if (mrg_1 == 074 && mrg_2 >= 076) { /* ccr or sr */
|
||||
if (sz != SIZE_NON)
|
||||
checksize(sz, mrg_2==076 ? 1 : 2);
|
||||
else
|
||||
sz = (mrg_2==076 ? SIZE_B : SIZE_W);
|
||||
T_EMIT2((opc&07400) | sz | 074, 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
return;
|
||||
}
|
||||
if (sz == SIZE_NON)
|
||||
sz = SIZE_DEF;
|
||||
if (mrg_1 == 074) {
|
||||
T_EMIT2((opc&07400) | sz | mrg_2, 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
ea_2(sz, DTA|ALT);
|
||||
return;
|
||||
}
|
||||
if ((opc & 010000) == 0 && to_dreg(opc, sz, DTA))
|
||||
return;
|
||||
if (from_dreg(opc, sz, (opc & 010000) ? DTA|ALT : ALT|MEM))
|
||||
return;
|
||||
badoperand();
|
||||
}
|
||||
|
||||
to_dreg(opc, sz, bits)
|
||||
{
|
||||
if ((mrg_2 & 070) != 000)
|
||||
return(0);
|
||||
T_EMIT2((opc & 0170000) | sz | (mrg_2&7)<<9 | mrg_1, 0, 0, 0);
|
||||
ea_1(sz, bits);
|
||||
return(1);
|
||||
}
|
||||
|
||||
from_dreg(opc, sz, bits)
|
||||
{
|
||||
if ((mrg_1 & 070) != 000)
|
||||
return(0);
|
||||
T_EMIT2((opc & 0170000) | sz | (mrg_1&7)<<9 | 0400 | mrg_2, 0, 0, 0);
|
||||
ea_2(sz, bits);
|
||||
return(1);
|
||||
}
|
||||
|
||||
cmp(sz)
|
||||
{
|
||||
register opc;
|
||||
|
||||
if ((mrg_1&070) == 030 && (mrg_2&070) == 030) {
|
||||
T_EMIT2(0130410 | sz | (mrg_1&7) | (mrg_2&7)<<9, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
|
||||
if (mrg_2==074)
|
||||
badoperand();
|
||||
T_EMIT2(06000 | sz | mrg_2, 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
ea_2(sz, DTA);
|
||||
return;
|
||||
}
|
||||
if (mrg_2 < 020) {
|
||||
if (mrg_2 >= 010) {
|
||||
checksize(sz, 2|4);
|
||||
opc = 0130300 | sz<<1;
|
||||
mrg_2 &= 7;
|
||||
} else
|
||||
opc = 0130000 | sz;
|
||||
T_EMIT2(opc | mrg_2<<9 | mrg_1, 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
return;
|
||||
}
|
||||
badoperand();
|
||||
}
|
||||
|
||||
link(sz, areg)
|
||||
{
|
||||
if (sz == SIZE_NON) {
|
||||
if (bd_2.typ == S_ABS && fitw(bd_2.val))
|
||||
sz = SIZE_W;
|
||||
else
|
||||
sz = SIZE_L;
|
||||
}
|
||||
checksize(sz, 2|4);
|
||||
if (sz == SIZE_W)
|
||||
T_EMIT2(047120 | areg, 0, 0, 0);
|
||||
else /* sz == SIZE_L */
|
||||
T_EMIT2(044010 | areg, 0, 0, 0);
|
||||
ea_2(sz, 0);
|
||||
}
|
||||
|
||||
move(sz)
|
||||
{
|
||||
register opc;
|
||||
|
||||
if (mrg_1 > 074 || mrg_2 > 074) {
|
||||
move_special(sz);
|
||||
return;
|
||||
}
|
||||
if (sz == SIZE_NON)
|
||||
sz = SIZE_DEF;
|
||||
if (
|
||||
mrg_2<010
|
||||
&&
|
||||
mrg_1==074
|
||||
&&
|
||||
sz==SIZE_L
|
||||
&&
|
||||
small(bd_1.typ==S_ABS && fitb(bd_1.val), 4)
|
||||
) {
|
||||
T_EMIT2(070000 | mrg_2<<9 | lowb(bd_1.val), 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
switch (sz) {
|
||||
case SIZE_B: opc = 010000; break;
|
||||
case SIZE_W: opc = 030000; break;
|
||||
case SIZE_L: opc = 020000; break;
|
||||
}
|
||||
T_EMIT2(opc | mrg_1 | (mrg_2&7)<<9 | (mrg_2&070)<<3, 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
ea_2(sz, ALT);
|
||||
}
|
||||
|
||||
move_special(sz)
|
||||
{
|
||||
if (mrg_2 >= 076) {
|
||||
if (sz != SIZE_NON)
|
||||
checksize(sz, 2);
|
||||
T_EMIT2(042300 | (mrg_2==076?0:01000) | mrg_1, 0, 0, 0);
|
||||
ea_1(SIZE_W, DTA);
|
||||
return;
|
||||
}
|
||||
if (mrg_1 >= 076) {
|
||||
if (sz != SIZE_NON)
|
||||
checksize(sz, 2);
|
||||
T_EMIT2(040300 | (mrg_1==076?01000:0) | mrg_2, 0, 0, 0);
|
||||
ea_2(SIZE_W, DTA|ALT);
|
||||
return;
|
||||
}
|
||||
if (sz != SIZE_NON)
|
||||
checksize(sz, 4);
|
||||
if (mrg_1==075 && (mrg_2&070)==010) {
|
||||
T_EMIT2(047150 | (mrg_2&7), 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (mrg_2==075 && (mrg_1&070)==010) {
|
||||
T_EMIT2(047140 | (mrg_1&7), 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
badoperand();
|
||||
}
|
||||
|
||||
movem(dr, sz, regs)
|
||||
{
|
||||
register i;
|
||||
register r;
|
||||
|
||||
if ((mrg_2>>3) == 04) {
|
||||
r = regs; regs = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
regs <<= 1;
|
||||
if (r & 1)
|
||||
regs++;
|
||||
r >>= 1;
|
||||
}
|
||||
}
|
||||
checksize(sz, 2|4);
|
||||
if ((mrg_2>>3)-3 == dr)
|
||||
badoperand();
|
||||
T_EMIT2(044200 | dr<<10 | (sz & 0200) >> 1 | mrg_2, 0, 0, 0);
|
||||
T_EMIT2(regs, 0, 0, 0);
|
||||
i = CTR;
|
||||
if (dr == 0 && (mrg_2&070) == 040)
|
||||
i = MEM;
|
||||
if (dr != 0 && (mrg_2&070) == 030)
|
||||
i = MEM;
|
||||
if (dr == 0)
|
||||
i |= ALT;
|
||||
ea_2(sz, i);
|
||||
}
|
||||
|
||||
movep(sz)
|
||||
{
|
||||
checksize(sz, 2|4);
|
||||
if (mrg_1<010 && (mrg_2&070)==050) {
|
||||
T_EMIT2(0610 | (sz & 0200)>>1 | mrg_1<<9 | (mrg_2&7), 0, 0, 0);
|
||||
ea_2(sz, 0);
|
||||
return;
|
||||
}
|
||||
if (mrg_2<010 && (mrg_1&070)==050) {
|
||||
T_EMIT2(0410 | (sz & 0200)>>1 | mrg_2<<9 | (mrg_1&7), 0, 0, 0);
|
||||
ea_1(sz, 0);
|
||||
return;
|
||||
}
|
||||
badoperand();
|
||||
}
|
||||
|
||||
branch(opc, exp)
|
||||
expr_t exp;
|
||||
{
|
||||
register sm;
|
||||
|
||||
exp.val -= (DOTVAL + 2);
|
||||
if ((pass == PASS_2)
|
||||
&&
|
||||
(exp.val > 0)
|
||||
&&
|
||||
((exp.typ & S_DOT) == 0)
|
||||
)
|
||||
exp.val -= DOTGAIN;
|
||||
sm = fitw(exp.val);
|
||||
if ((exp.typ & ~S_DOT) != DOTTYP)
|
||||
sm = 0;
|
||||
if (small(sm,2)) {
|
||||
if (small(fitb(exp.val),2)) {
|
||||
if (exp.val == 0)
|
||||
T_EMIT2(047161, 0, 0, 0); /* NOP */
|
||||
else if (exp.val == -1) {
|
||||
T_EMIT2(047161, 0, 0, 0);
|
||||
serror("bad branch offset");
|
||||
} else
|
||||
T_EMIT2(opc | lowb(exp.val), 0, 0, 0);
|
||||
} else {
|
||||
T_EMIT2(opc, 0, 0, 0);
|
||||
T_EMIT2(loww(exp.val), 0, 0, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
sm = small(0,2); /* dummy call; two calls to small per branch */
|
||||
T_EMIT2(opc | 0377, 0, 0, 0); /* 4 byte offset */
|
||||
T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
|
||||
}
|
||||
|
||||
cpbcc(opc, exp)
|
||||
expr_t exp;
|
||||
{
|
||||
register sm;
|
||||
|
||||
exp.val -= (DOTVAL + 2);
|
||||
if ((pass == PASS_2)
|
||||
&&
|
||||
(exp.val > 0)
|
||||
&&
|
||||
((exp.typ & S_DOT) == 0)
|
||||
)
|
||||
exp.val -= DOTGAIN;
|
||||
sm = fitw(exp.val);
|
||||
if ((exp.typ & ~S_DOT) != DOTTYP)
|
||||
sm = 0;
|
||||
if (small(sm,2)) {
|
||||
T_EMIT2(opc, 0, 0, 0);
|
||||
T_EMIT2(loww(exp.val), 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
T_EMIT2(opc | 0100, 0, 0, 0); /* 4 byte offset */
|
||||
/* NB: no coprocessor defined extension words are emitted */
|
||||
T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
|
||||
}
|
||||
|
||||
ea7071(sz)
|
||||
{
|
||||
mrg_2 = 071;
|
||||
switch (sz) {
|
||||
case SIZE_B:
|
||||
badoperand();
|
||||
case SIZE_W:
|
||||
mrg_2 = 070;
|
||||
case SIZE_L:
|
||||
return;
|
||||
case SIZE_NON:
|
||||
break;
|
||||
}
|
||||
/* If this absolute address is in program space, and if we
|
||||
* can assume that the only references to program space are made
|
||||
* by instructins like 'jsr', 'jmp', 'lea' and 'pea', it might
|
||||
* be possible to use a (PC,d16) effective address mode instead
|
||||
* of absolute long. This is done here. If this scheme is in
|
||||
* some way undesirable (e.g. when references to program space
|
||||
* are made by instructions with more than one opcode word or by
|
||||
* second effective addresses in instructions), the rest
|
||||
* of this routine can simply be removed and replaced by the
|
||||
* next two lines (which of course are in comment brackets now).
|
||||
if (small(bd_2.typ == S_ABS && fitw(bd_2.val), 2))
|
||||
mrg_2 = 070;
|
||||
*/
|
||||
if (pass == PASS_1) {
|
||||
/* Reserve a bit in the bittable; in the following
|
||||
* passes one call to small() will be done, but know yet
|
||||
* which one, because bd_2.typ cannot be trusted yet.
|
||||
*/
|
||||
small(0, 2);
|
||||
return;
|
||||
}
|
||||
if ((bd_2.typ & ~S_DOT) == DOTTYP) {
|
||||
if (small(fitw(bd_2.val-(DOTVAL+2)), 2)) {
|
||||
bd_2.val -= (DOTVAL+2);
|
||||
mrg_2 = 072;
|
||||
}
|
||||
} else
|
||||
if (small(bd_2.typ == S_ABS && fitw(bd_2.val), 2))
|
||||
mrg_2 = 070;
|
||||
}
|
Loading…
Reference in a new issue