From: ceriel Date: Fri, 5 Dec 1986 16:58:29 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-5-5~5120 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=28036b374178b6220dc3b8c9b723456b55e3953d;p=ack.git Initial revision --- diff --git a/mach/6805/as/mach0.c b/mach/6805/as/mach0.c new file mode 100644 index 000000000..1d3ae708b --- /dev/null +++ b/mach/6805/as/mach0.c @@ -0,0 +1,11 @@ +#define RCSID0 "$Header$" + +/* + * Motorola 6805 options + */ + +#define BYTES_REVERSED +#define WORDS_REVERSED +#define THREE_PASS +#define LISTING +#define RELOCATION diff --git a/mach/6805/as/mach1.c b/mach/6805/as/mach1.c new file mode 100644 index 000000000..836201835 --- /dev/null +++ b/mach/6805/as/mach1.c @@ -0,0 +1,9 @@ +#define RCSID1 "$Header$" + +/* + * Motorola 6805 C declarations + */ + +extern int opt_cmos; + +#define fitj(z) ((unsigned)z + 0x80 <= 0xFF) diff --git a/mach/6805/as/mach2.c b/mach/6805/as/mach2.c new file mode 100644 index 000000000..6948f5c6c --- /dev/null +++ b/mach/6805/as/mach2.c @@ -0,0 +1,17 @@ +#define RCSID2 "$Header$" + +/* + * Motorola 6805 tokens + */ + +%token X +%token A +%token NOARG +%token BRANCH +%token BBRANCH +%token BIT +%token RMR +%token RM +%token CMOS +%type expr8 +%type bitexp diff --git a/mach/6805/as/mach3.c b/mach/6805/as/mach3.c new file mode 100644 index 000000000..58e4d1ce0 --- /dev/null +++ b/mach/6805/as/mach3.c @@ -0,0 +1,123 @@ +#define RCSID3 "$Header$" + +/* + * Motorola 6805 keywords + */ +/* + * The X register + */ +0, X, 0, "x", +/* + * Bit test and branch + */ +0, BBRANCH, 0x00, "brset", +0, BBRANCH, 0x01, "brclr", +/* + * Bit manipulation + */ +0, BIT, 0x10, "bset", +0, BIT, 0x11, "bclr", +/* + * Branches + */ +0, BRANCH, 0x20, "bra", +0, BRANCH, 0x21, "brn", +0, BRANCH, 0x22, "bhi", +0, BRANCH, 0x23, "bls", +0, BRANCH, 0x24, "bcc", +0, BRANCH, 0x25, "bcs", +0, BRANCH, 0x26, "bne", +0, BRANCH, 0x27, "beq", +0, BRANCH, 0x28, "bhcc", +0, BRANCH, 0x29, "bhcs", +0, BRANCH, 0x2a, "bpl", +0, BRANCH, 0x2b, "bmi", +0, BRANCH, 0x2c, "bmc", +0, BRANCH, 0x2d, "bms", +0, BRANCH, 0x2e, "bil", +0, BRANCH, 0x2f, "bih", +/* + * Read modify write on anything but registers + */ +0, RMR, 0x30, "neg", +0, RMR, 0x33, "com", +0, RMR, 0x34, "lsr", +0, RMR, 0x36, "ror", +0, RMR, 0x36, "asr", +0, RMR, 0x38, "lsl", +0, RMR, 0x39, "rol", +0, RMR, 0x3a, "dec", +0, RMR, 0x3c, "inc", +0, RMR, 0x3d, "tst", +0, RMR, 0x3f, "clr", +/* + * Implied stuff + */ +0, NOARG, 0x80, "rti", +0, NOARG, 0x81, "rts", +0, NOARG, 0x83, "swi", +0, NOARG, 0x97, "tax", +0, NOARG, 0x98, "clc", +0, NOARG, 0x99, "sec", +0, NOARG, 0x9a, "cli", +0, NOARG, 0x9b, "sei", +0, NOARG, 0x9c, "rsp", +0, NOARG, 0x9d, "nop", +0, NOARG, 0x9f, "txa", +/* + * Register memory. + * Warning. Some imediate opcodes excluded in parser actions. + */ +0, RM, 0xa0, "sub", +0, RM, 0xa1, "cmp", +0, RM, 0xa2, "sbc", +0, RM, 0xa3, "cpx", +0, RM, 0xa4, "and", +0, RM, 0xa5, "bit", +0, RM, 0xa6, "lda", +0, RM, 0xa7, "sta", +0, RM, 0xa8, "eor", +0, RM, 0xa9, "adc", +0, RM, 0xaa, "ora", +0, RM, 0xab, "add", +0, RM, 0xac, "jmp", +0, BRANCH, 0xad, "bsr", +0, RM, 0xad, "jsr", +0, RM, 0xae, "ldx", +0, RM, 0xaf, "stx", +/* + * Branch synonyms + */ +0, BRANCH, 0x24, "bhs", /* bcc */ +0, BRANCH, 0x25, "blo", /* bcs */ +/* + * Brain damaged concatenated opcodes for RMR on registers + */ +0, NOARG, 0x40, "nega", +0, NOARG, 0x43, "coma", +0, NOARG, 0x44, "lsra", +0, NOARG, 0x46, "rora", +0, NOARG, 0x47, "asra", +0, NOARG, 0x48, "lsla", +0, NOARG, 0x49, "rola", +0, NOARG, 0x4a, "deca", +0, NOARG, 0x4c, "inca", +0, NOARG, 0x4d, "tsta", +0, NOARG, 0x4f, "clra", +0, NOARG, 0x50, "negx", +0, NOARG, 0x53, "comx", +0, NOARG, 0x54, "lsrx", +0, NOARG, 0x56, "rorx", +0, NOARG, 0x57, "asrx", +0, NOARG, 0x58, "lslx", +0, NOARG, 0x59, "rolx", +0, NOARG, 0x5a, "decx", +0, NOARG, 0x5c, "incx", +0, NOARG, 0x5d, "tstx", +0, NOARG, 0x5f, "clrx", +/* + * CMOS support + */ +0, CMOS, 0, ".cmos", +0, CMOS, 0x8e, "stop", +0, CMOS, 0x8f, "wait", diff --git a/mach/6805/as/mach4.c b/mach/6805/as/mach4.c new file mode 100644 index 000000000..6f2d21817 --- /dev/null +++ b/mach/6805/as/mach4.c @@ -0,0 +1,205 @@ +#define RCSID4 "$Header$" + +/* + * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. + * + * This product is part of the Amsterdam Compiler Kit. + * + * Permission to use, sell, duplicate or disclose this software must be + * obtained in writing. Requests for such permissions may be sent to + * + * Dr. Andrew S. Tanenbaum + * Wiskundig Seminarium + * Vrije Universiteit + * Postbox 7161 + * 1007 MC Amsterdam + * The Netherlands + * + */ + +/* + * Motorola 6805 parsing rules + */ + +expr8 + : + expr + { + fit(fitb($1.val)); + } + ; +bitexp + : + absexp + { + fit((unsigned) $1 <= 7); + $$ = $1 & 07; + } + ; +operation + : + NOARG + { emit1($1);} + | + BRANCH expr + { branch($1,$2);} + | + BBRANCH bitexp ',' expr8 ',' expr + { + branch($1+($2 << 1), $6, $4); + } + | + BIT bitexp ',' expr8 + { + emit1($1+($2 << 1)); +#ifdef RELOCATION + newrelo($4.typ, RELO1); +#endif + emit1($4.val); + } + | + RMR '<' expr8 + | + RMR expr8 + { + emit1($1); +#ifdef RELOCATION + newrelo($2.typ, RELO1); +#endif + emit1($2.val); + } + | + RMR expr8 ',' X + { + if(small($2.val == 0 && + ($2.typ & ~S_DOT) == DOTTYP && + pass == PASS_2, 1)) + emit1($1+0x40); + else + { + emit1($1+0x30); +#ifdef RELOCATION + newrelo($2.typ, RELO1); +#endif + emit1($2.val); + } + } + | + RMR ',' X + { emit1($1+0x40); } + | + RM '#' expr8 + { + switch($1) { + case 0xa7: + case 0xac: + case 0xad: + case 0xaf: + serror("mode error"); + default: + emit1($1); + } +#ifdef RELOCATION + newrelo($3.typ, RELO1); +#endif + emit1($3.val); + } + | + RM '<' expr8 + { + emit1($1+0x10); +#ifdef RELOCATION + newrelo($3.typ, RELO1); +#endif + emit1($3.val); + } + | + RM expr + { + if(small(pass == PASS_2 && + ($2.typ & ~S_DOT) == DOTTYP && + fitb($2.val),1)) { + emit1($1+0x10); +#ifdef RELOCATION + newrelo($2.typ, RELO1); +#endif + emit1($2.val); + } else { + emit1($1+0x20); +#ifdef RELOCATION + newrelo($2.typ, RELO2|RELBR); +#endif + emit2($2.val); + } + } + | + RM '>' expr + { + emit1($1+0x20); +#ifdef RELOCATION + newrelo($3.typ, RELO2|RELBR); +#endif + emit2($3.val); + } + | + RM '>' expr ',' X + { + emit1($1+0x30); +#ifdef RELOCATION + newrelo($3.typ, RELO2|RELBR); +#endif + emit2($3.val); + } + | + RM expr ',' X + { + if(small(pass == PASS_2 && + ($2.typ & ~S_DOT) == DOTTYP && + fitb($2.val),1)) { + if(small(pass == PASS_2 && + ($2.typ & ~S_DOT) == DOTTYP && + $2.val == 0,1)) + emit1($1+0x50); + else { + emit1($1+0x40); +#ifdef RELOCATION + newrelo($2.typ, RELO1); +#endif + emit1($2.val); + } + } else { + small(0,1); /* dummy */ + emit1($1+0x30); +#ifdef RELOCATION + newrelo($2.typ, RELO2|RELBR); +#endif + emit2($2.val); + } + } + | + RM '<' expr8 ',' X + { + emit1($1+0x40); +#ifdef RELOCATION + newrelo($3.typ, RELO1); +#endif + emit1($3.val); + } + | + RM ',' X + { emit1($1+0x50); } + | + CMOS + { + switch($1) { + case 0: + opt_cmos = 1; + break; + case 0x8e: + case 0x8f: + if(! opt_cmos) + serror("bad opcode"); + emit1($1); + } + } + ; diff --git a/mach/6805/as/mach5.c b/mach/6805/as/mach5.c new file mode 100644 index 000000000..33c41278e --- /dev/null +++ b/mach/6805/as/mach5.c @@ -0,0 +1,51 @@ +#define RCSID5 "$Header$" + +/* + * Motorola 6805 special routines + */ + +/* VARARGS2 */ +branch(opc,exp,cell) register opc; expr_t cell; expr_t exp; { + register sm, dist; + int saving; + + dist = exp.val - (DOTVAL + 2); + if((opc & 0xf0) == 0) dist -= 1; /* bitbranch */ + if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT)) + dist -= DOTGAIN; + sm = fitj(dist); + if ((exp.typ & ~S_DOT) != DOTTYP) + sm = 0; + if (opc == 0x20 || opc == 0xAD) + saving = 1; + else + saving = 3; + if (small(sm,saving)) { + emit1(opc); + if((opc & 0xF0) == 0) /* bit branch */ + emit1(cell.val); +#ifdef RELOCATION + newrelo(exp.typ, RELPC|RELO1); +#endif + emit1(dist); + } else { + if (opc == 0xAD) /* bsr */ + emit1(0xBD); /* jsr */ + else { + if (opc != 0x20) { /* bra */ + + /* reverse condition : */ + + emit1(opc ^ 1); + if((opc & 0xF0) == 0) /* bitbranch */ + emit1(cell.val); + emit1(3); + } + emit1(0xCC); /* jmp */ + } +#ifdef RELOCATION + newrelo(exp.typ, RELPC|RELO2|RELBR); +#endif + emit2(exp.val); + } +} diff --git a/mach/ns/as/mach0.c b/mach/ns/as/mach0.c new file mode 100644 index 000000000..8ead9e5fd --- /dev/null +++ b/mach/ns/as/mach0.c @@ -0,0 +1,21 @@ +#define RCSID0 "$Header$" + +/* + * NS 16032 options + */ +#define THREE_PASS /* branch and offset optimization */ +#define LISTING /* enable listing facilities */ + +#undef valu_t +#define valu_t long +#undef addr_t +#define addr_t long +#undef ALIGNSECT +#define ALIGNSECT 2 + +#undef VALWIDTH +#define VALWIDTH 8 + +#define RELOCATION + +#define UNUSED /* Assemble the 'unused' instructions like bfalse */ diff --git a/mach/ns/as/mach1.c b/mach/ns/as/mach1.c new file mode 100644 index 000000000..6c8ae00b8 --- /dev/null +++ b/mach/ns/as/mach1.c @@ -0,0 +1,113 @@ +#define RCSID1 "$Header$" + +/* + * NS 16032 C declarations + */ + +#define low4(val) ((int)(val&0xF)) + +/* signed value fits in ? bits */ +#define fit32(val) ( (val)>= -2147483648 && (val)<=2147483647 ) +#define fit16(val) ( (val)>= -32768 && (val)<=32767 ) +#define fit8(val) ( (val)>= -128 && (val)<=127 ) +#define fit4(val) ( (val)>= -8 && (val)<=7 ) + +/* Fits in byte, word displacement */ +#define fitd_b(val) ( (val)>= -64 && (val)<=63 ) +#define fitd_w(val) ( (val)>= -8192 && (val)<=8191 ) + +/* Assemble and disassemble operator id's */ +/* the i_value's in the instruction keyword table + contain five bit fields: + 0-3 Opcode used in format indicated by the i_type field + 4-7 Condition Code field. B_?? Also used for reg in FFS type. + 8-11 The type of the first addressing mode gen1 + 12-15 The type of the second addressing mode gen2 + The integer type T_???? + The custom Slave type S_???? + The Floating point type F_???? +*/ + +#define MK_op(op) (op) +#define MK_cc(cc) ( (cc)<<4 ) +#define MK_g1(g1) ( (g1)<<8 ) +#define MK_g2(g2) ( (g2)<<12 ) + +#define mk_op(o) (MK_op(o)|MK_g1(X_ILLGL)|MK_g2(X_ILLGL)) +#define mk_op1(o,g1) (MK_op(o)|MK_g1(g1)|MK_g2(X_ILLGL)) +#define mk_op2(o,g1,g2) (MK_op(o)|MK_g1(g1)|MK_g2(g2)) +#define mk_c(c) MK_cc(c) +#define mk_op1c(o,g1,c) (MK_op(o)|MK_g1(g1)|MK_g2(X_ILLGL)|MK_cc(c)) +#define mk_op2c(o,g1,g2,c) (MK_op(o)|MK_g1(g1)|MK_g2(g2)|MK_cc(c)) + +#define id_op(id) ((id) &0xF) +#define id_cc(id) (((id)>>4) &0xF) +#define id_g1(id) (((id)>>8) &3) +#define id_g2(id) (((id)>>12)&3) +#define id_t1(id) (((id)>>10)&3) +#define id_t2(id) (((id)>>14)&3) + +/* Type definitions */ +#define T_INT 0 +#define T_FL 1 +#define T_SLAVE 2 +#define T_ILLGL 3 + +#define I_BYTE (T_INT<<2) | 0 +#define I_WORD (T_INT<<2) | 1 +#define I_DOUBLE (T_INT<<2) | 3 + +#define F_FLOAT (T_FL<<2) | 1 +#define F_LONG (T_FL<<2) | 0 + +#define S_DOUBLE (T_SLAVE<<2) | 1 +#define S_QUAD (T_SLAVE<<2) | 0 + +#define X_ILLGL (T_ILLGL<<2) | 2 + +#define B_EQ 0x0 +#define B_NE 0x1 +#define B_CS 0x2 +#define B_CC 0x3 +#define B_HI 0x4 +#define B_LS 0x5 +#define B_GT 0x6 +#define B_LE 0x7 +#define B_FS 0x8 +#define B_FC 0x9 +#define B_LO 0xA +#define B_HS 0xB +#define B_LT 0xC +#define B_GE 0xD +#define B_TRUE 0xE +#define B_FALSE 0xF + +/* String option bits */ +#define SO_UNTIL 0xC +#define SO_WHILE 0x4 +#define SO_BACKW 0x2 +#define SO_TRANS 0x1 + +/* output definitions */ +#define form0(id) emit1(0xA + (id_cc(id)<<4) ) +#define form1(id) emit1(0x2 + (id_op(id)<<4) ) +#define form6(id) emit1(0x4E) ; form4(id) +#define form7(id) emit1(0xCE) ; form4(id) + + +/* Structure contains information for generation of an addressing mode */ +/* The size of immediates is not stored in here and must be fetched from + a id-field +*/ +extern struct { + int m_mode; /* The main mode bits */ + int m_index ; /* m_mode= index mode, m_index has index byte */ + int m_ndisp ; /* The number of displacements */ + expr_t m_expr1 ; /* The first expression */ +#ifdef RELOCATION + int m_rel1, m_rel2; /* relocation */ +#endif + expr_t m_expr2 ; /* The second expression */ +} mode1, mode2, *mode_ptr ; + +#define not_imm(mode_ptr) if ( (mode_ptr)->m_mode==0x14 ) ill_imm() ; diff --git a/mach/ns/as/mach2.c b/mach/ns/as/mach2.c new file mode 100644 index 000000000..27444aacc --- /dev/null +++ b/mach/ns/as/mach2.c @@ -0,0 +1,59 @@ +#define RCSID2 "$Header$" + +/* + * NS 16032 tokens + */ + +%token REG +%token AREG +%token FREG +%token MREG +%token CREG +%token EXTERNAL +%token TOS +%token PC +%token INDICATOR + +/* + * Instruction types + */ +%token SETCFG +%token LPR +%token LCR +%token BR +%token RET +%token BSR +%token RDVAL +%token CATST +%token LCSR +%token SEQ +%token ADJSP +%token JSR +%token JUMP +%token LFSR +%token ADD_F +%token CCVIS +%token CCVSI +%token CCVSS +%token CMOV +%token ADD_I +%token COM +%token MUL_I +%token MOVID +%token FFS +%token MOVIF +%token MOVFL +%token TRUNC +%token MOVM +%token INSS +%token SAVE +%token ENTER +%token LMR +%token MOVS +%token CHECK +%token INS +%token MOVQ +%token ACB +%token WAIT + +%type cpu_opts, cpu_list, string_opts, reg_list, reg_items diff --git a/mach/ns/as/mach3.c b/mach/ns/as/mach3.c new file mode 100644 index 000000000..cad692613 --- /dev/null +++ b/mach/ns/as/mach3.c @@ -0,0 +1,453 @@ +#define RCSID3 "$Header$" + +/* + * NS 16032 keywords + */ + +/* Registers */ +0, REG, 0, "r0", +0, REG, 1, "r1", +0, REG, 2, "r2", +0, REG, 3, "r3", +0, REG, 4, "r4", +0, REG, 5, "r5", +0, REG, 6, "r6", +0, REG, 7, "r7", +0, FREG, 0, "f0", +0, FREG, 1, "f1", +0, FREG, 2, "f2", +0, FREG, 3, "f3", +0, FREG, 4, "f4", +0, FREG, 5, "f5", +0, FREG, 6, "f6", +0, FREG, 7, "f7", +/* CPU dedicated registers */ +0, AREG, 0x0, "us", +0, AREG, 0x8, "fp", +0, AREG, 0x9, "sp", +0, AREG, 0xA, "sb", +0, AREG, 0xD, "psr", +0, AREG, 0xE, "intbase", +0, AREG, 0xF, "mod", +/* Tokens dedicated to addressing modes */ +0, TOS, 0x17, "tos", +0, EXTERNAL, 0x16, "external", +0, PC, 0, "pc", +0, INDICATOR, 'b', "b", +0, INDICATOR, 'c', "c", +0, INDICATOR, 'd', "d", +0, INDICATOR, 'f', "f", +0, INDICATOR, 'i', "i", +0, INDICATOR, 'm', "m", +0, INDICATOR, 'q', "q", +0, INDICATOR, 'u', "u", +0, INDICATOR, 'w', "w", +/* Memory management registers */ +0, MREG, 0x0, "bpr0", +0, MREG, 0x1, "bpr1", +0, MREG, 0x4, "pf0", +0, MREG, 0x5, "pf1", +0, MREG, 0x8, "sc", +0, MREG, 0xA, "msr", +0, MREG, 0xB, "bcnt", +0, MREG, 0xC, "ptb0", +0, MREG, 0xD, "ptb1", +0, MREG, 0xF, "eia", +/* Instruction types */ +/* Integer instructions */ +0, ADD_I, mk_op2(0x5,I_BYTE,I_BYTE), "movb", +0, ADD_I, mk_op2(0x5,I_WORD,I_WORD), "movw", +0, ADD_I, mk_op2(0x5,I_DOUBLE,I_DOUBLE), "movd", +0, ADD_I, mk_op2(0x1,I_BYTE,I_BYTE), "cmpb", +0, ADD_I, mk_op2(0x1,I_WORD,I_WORD), "cmpw", +0, ADD_I, mk_op2(0x1,I_DOUBLE,I_DOUBLE), "cmpd", +0, ADD_I, mk_op2(0x0,I_BYTE,I_BYTE), "addb", +0, ADD_I, mk_op2(0x0,I_WORD,I_WORD), "addw", +0, ADD_I, mk_op2(0x0,I_DOUBLE,I_DOUBLE), "addd", +0, ADD_I, mk_op2(0x4,I_BYTE,I_BYTE), "addcb", +0, ADD_I, mk_op2(0x4,I_WORD,I_WORD), "addcw", +0, ADD_I, mk_op2(0x4,I_DOUBLE,I_DOUBLE), "addcd", +0, ADD_I, mk_op2(0x8,I_BYTE,I_BYTE), "subb", +0, ADD_I, mk_op2(0x8,I_WORD,I_WORD), "subw", +0, ADD_I, mk_op2(0x8,I_DOUBLE,I_DOUBLE), "subd", +0, ADD_I, mk_op2(0xC,I_BYTE,I_BYTE), "subcb", +0, ADD_I, mk_op2(0xC,I_WORD,I_WORD), "subcw", +0, ADD_I, mk_op2(0xC,I_DOUBLE,I_DOUBLE), "subcd", +0, COM, mk_op2(0x8,I_BYTE,I_BYTE), "negb", +0, COM, mk_op2(0x8,I_WORD,I_WORD), "negw", +0, COM, mk_op2(0x8,I_DOUBLE,I_DOUBLE), "negd", +0, COM, mk_op2(0xC,I_BYTE,I_BYTE), "absb", +0, COM, mk_op2(0xC,I_WORD,I_WORD), "absw", +0, COM, mk_op2(0xC,I_DOUBLE,I_DOUBLE), "absd", +0, MUL_I, mk_op2(0x8,I_BYTE,I_BYTE), "mulb", +0, MUL_I, mk_op2(0x8,I_WORD,I_WORD), "mulw", +0, MUL_I, mk_op2(0x8,I_DOUBLE,I_DOUBLE), "muld", +0, MUL_I, mk_op2(0xF,I_BYTE,I_BYTE), "divb", +0, MUL_I, mk_op2(0xF,I_WORD,I_WORD), "divw", +0, MUL_I, mk_op2(0xF,I_DOUBLE,I_DOUBLE), "divd", +0, MUL_I, mk_op2(0xE,I_BYTE,I_BYTE), "modb", +0, MUL_I, mk_op2(0xE,I_WORD,I_WORD), "modw", +0, MUL_I, mk_op2(0xE,I_DOUBLE,I_DOUBLE), "modd", +0, MUL_I, mk_op2(0xC,I_BYTE,I_BYTE), "quob", +0, MUL_I, mk_op2(0xC,I_WORD,I_WORD), "quow", +0, MUL_I, mk_op2(0xC,I_DOUBLE,I_DOUBLE), "quod", +0, MUL_I, mk_op2(0xD,I_BYTE,I_BYTE), "remb", +0, MUL_I, mk_op2(0xD,I_WORD,I_WORD), "remw", +0, MUL_I, mk_op2(0xD,I_DOUBLE,I_DOUBLE), "remd", +0, ADD_I, mk_op2(0xA,I_BYTE,I_BYTE), "andb", +0, ADD_I, mk_op2(0xA,I_WORD,I_WORD), "andw", +0, ADD_I, mk_op2(0xA,I_DOUBLE,I_DOUBLE), "andd", +0, ADD_I, mk_op2(0x6,I_BYTE,I_BYTE), "orb", +0, ADD_I, mk_op2(0x6,I_WORD,I_WORD), "orw", +0, ADD_I, mk_op2(0x6,I_DOUBLE,I_DOUBLE), "ord", +0, ADD_I, mk_op2(0x2,I_BYTE,I_BYTE), "bicb", +0, ADD_I, mk_op2(0x2,I_WORD,I_WORD), "bicw", +0, ADD_I, mk_op2(0x2,I_DOUBLE,I_DOUBLE), "bicd", +0, ADD_I, mk_op2(0xE,I_BYTE,I_BYTE), "xorb", +0, ADD_I, mk_op2(0xE,I_WORD,I_WORD), "xorw", +0, ADD_I, mk_op2(0xE,I_DOUBLE,I_DOUBLE), "xord", +0, COM, mk_op2(0xD,I_BYTE,I_BYTE), "comb", +0, COM, mk_op2(0xD,I_WORD,I_WORD), "comw", +0, COM, mk_op2(0xD,I_DOUBLE,I_DOUBLE), "comd", +0, COM, mk_op2(0x1,I_BYTE,I_BYTE), "ashb", +0, COM, mk_op2(0x1,I_BYTE,I_WORD), "ashw", +0, COM, mk_op2(0x1,I_BYTE,I_DOUBLE), "ashd", +0, COM, mk_op2(0x5,I_BYTE,I_BYTE), "lshb", +0, COM, mk_op2(0x5,I_BYTE,I_WORD), "lshw", +0, COM, mk_op2(0x5,I_BYTE,I_DOUBLE), "lshd", +0, COM, mk_op2(0x0,I_BYTE,I_BYTE), "rotb", +0, COM, mk_op2(0x0,I_BYTE,I_WORD), "rotw", +0, COM, mk_op2(0x0,I_BYTE,I_DOUBLE), "rotd", +0, MOVID, mk_op2(0x4,I_BYTE,I_WORD), "movxbw", +0, MOVID, mk_op2(0x7,I_BYTE,I_DOUBLE), "movxbd", +0, MOVID, mk_op2(0x7,I_WORD,I_DOUBLE), "movxwd", +0, MOVID, mk_op2(0x5,I_BYTE,I_WORD), "movzbw", +0, MOVID, mk_op2(0x6,I_BYTE,I_DOUBLE), "movzbd", +0, MOVID, mk_op2(0x6,I_WORD,I_DOUBLE), "movzwd", +#ifdef UNUSED +0, MOVID, mk_op2(0x7,I_DOUBLE,I_DOUBLE), "movxdd", +0, MOVID, mk_op2(0x6,I_DOUBLE,I_DOUBLE), "movzdd", +#endif +0, ADD_I, mk_op2(0x9,I_DOUBLE,I_DOUBLE), "addr", +/* Quick integer instructions */ +0, MOVQ, mk_op1(0x5,I_BYTE), "movqb", +0, MOVQ, mk_op1(0x5,I_WORD), "movqw", +0, MOVQ, mk_op1(0x5,I_DOUBLE), "movqd", +0, MOVQ, mk_op1(0x1,I_BYTE), "cmpqb", +0, MOVQ, mk_op1(0x1,I_WORD), "cmpqw", +0, MOVQ, mk_op1(0x1,I_DOUBLE), "cmpqd", +0, MOVQ, mk_op1(0x0,I_BYTE), "addqb", +0, MOVQ, mk_op1(0x0,I_WORD), "addqw", +0, MOVQ, mk_op1(0x0,I_DOUBLE), "addqd", +/* Extended integer instructions */ +0, MUL_I, mk_op2(0x9,I_BYTE,I_BYTE), "meib", +0, MUL_I, mk_op2(0x9,I_WORD,I_WORD), "meiw", +0, MUL_I, mk_op2(0x9,I_DOUBLE,I_DOUBLE), "meid", +0, MUL_I, mk_op2(0xB,I_BYTE,I_BYTE), "deib", +0, MUL_I, mk_op2(0xB,I_WORD,I_WORD), "deiw", +0, MUL_I, mk_op2(0xB,I_DOUBLE,I_DOUBLE), "deid", +/* Boolean instructions */ +0, COM, mk_op2(0x9,I_BYTE,I_BYTE), "notb", +0, COM, mk_op2(0x9,I_WORD,I_WORD), "notw", +0, COM, mk_op2(0x9,I_DOUBLE,I_DOUBLE), "notd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_EQ), "seqb", +0, SEQ, mk_op1c(0x3,I_WORD,B_EQ), "seqw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_EQ), "seqd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_NE), "sneb", +0, SEQ, mk_op1c(0x3,I_WORD,B_NE), "snew", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_NE), "sned", +0, SEQ, mk_op1c(0x3,I_BYTE,B_CS), "scsb", +0, SEQ, mk_op1c(0x3,I_WORD,B_CS), "scsw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_CS), "scsd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_CC), "sccb", +0, SEQ, mk_op1c(0x3,I_WORD,B_CC), "sccw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_CC), "sccd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_HI), "shib", +0, SEQ, mk_op1c(0x3,I_WORD,B_HI), "shiw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_HI), "shid", +0, SEQ, mk_op1c(0x3,I_BYTE,B_LS), "slsb", +0, SEQ, mk_op1c(0x3,I_WORD,B_LS), "slsw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_LS), "slsd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_GT), "sgtb", +0, SEQ, mk_op1c(0x3,I_WORD,B_GT), "sgtw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_GT), "sgtd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_LE), "sleb", +0, SEQ, mk_op1c(0x3,I_WORD,B_LE), "slew", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_LE), "sled", +0, SEQ, mk_op1c(0x3,I_BYTE,B_FS), "sfsb", +0, SEQ, mk_op1c(0x3,I_WORD,B_FS), "sfsw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_FS), "sfsd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_FC), "sfcb", +0, SEQ, mk_op1c(0x3,I_WORD,B_FC), "sfcw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_FC), "sfcd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_LO), "slob", +0, SEQ, mk_op1c(0x3,I_WORD,B_LO), "slow", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_LO), "slod", +0, SEQ, mk_op1c(0x3,I_BYTE,B_HS), "shsb", +0, SEQ, mk_op1c(0x3,I_WORD,B_HS), "shsw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_HS), "shsd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_LT), "sltb", +0, SEQ, mk_op1c(0x3,I_WORD,B_LT), "sltw", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_LT), "sltd", +0, SEQ, mk_op1c(0x3,I_BYTE,B_GE), "sgeb", +0, SEQ, mk_op1c(0x3,I_WORD,B_GE), "sgew", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_GE), "sged", +#ifdef UNUSED +0, SEQ, mk_op1c(0x3,I_BYTE,B_TRUE), "strueb", +0, SEQ, mk_op1c(0x3,I_WORD,B_TRUE), "struew", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_TRUE), "strued", +0, SEQ, mk_op1c(0x3,I_BYTE,B_FALSE), "sfalseb", +0, SEQ, mk_op1c(0x3,I_WORD,B_FALSE), "sfalsew", +0, SEQ, mk_op1c(0x3,I_DOUBLE,B_FALSE), "sfalsed", +#endif +/* Bit instructions */ +0, ADD_I, mk_op2(0xD,I_BYTE,I_BYTE), "tbitb", +0, ADD_I, mk_op2(0xD,I_WORD,I_WORD), "tbitw", +0, ADD_I, mk_op2(0xD,I_DOUBLE,I_DOUBLE), "tbitd", +0, COM, mk_op2(0x6,I_BYTE,I_BYTE), "sbitb", +0, COM, mk_op2(0x6,I_WORD,I_WORD), "sbitw", +0, COM, mk_op2(0x6,I_DOUBLE,I_DOUBLE), "sbitd", +0, COM, mk_op2(0x7,I_BYTE,I_BYTE), "sbitib", +0, COM, mk_op2(0x7,I_WORD,I_WORD), "sbitiw", +0, COM, mk_op2(0x7,I_DOUBLE,I_DOUBLE), "sbitid", +0, COM, mk_op2(0x2,I_BYTE,I_BYTE), "cbitb", +0, COM, mk_op2(0x2,I_WORD,I_WORD), "cbitw", +0, COM, mk_op2(0x2,I_DOUBLE,I_DOUBLE), "cbitd", +0, COM, mk_op2(0x3,I_BYTE,I_BYTE), "cbitib", +0, COM, mk_op2(0x3,I_WORD,I_WORD), "cbitiw", +0, COM, mk_op2(0x3,I_DOUBLE,I_DOUBLE), "cbitid", +0, COM, mk_op2(0xE,I_BYTE,I_BYTE), "ibitb", +0, COM, mk_op2(0xE,I_WORD,I_WORD), "ibitw", +0, COM, mk_op2(0xE,I_DOUBLE,I_DOUBLE), "ibitd", +0, CHECK, mk_op1(0x1,I_DOUBLE), "cvtp", +0, FFS, mk_op2c(0x5,I_BYTE,I_BYTE,0), "ffsb", +0, FFS, mk_op2c(0x5,I_WORD,I_BYTE,0), "ffsw", +0, FFS, mk_op2c(0x5,I_DOUBLE,I_BYTE,0), "ffsd", +/* Field instructions */ +0, INS, mk_op2(0x0,I_BYTE,I_BYTE), "extb", +0, INS, mk_op2(0x0,I_WORD,I_WORD), "extw", +0, INS, mk_op2(0x0,I_DOUBLE,I_DOUBLE), "extd", +0, INSS, mk_op2(0x3,I_BYTE,I_BYTE), "extsb", +0, INSS, mk_op2(0x3,I_WORD,I_WORD), "extsw", +0, INSS, mk_op2(0x3,I_DOUBLE,I_DOUBLE), "extsd", +0, INS, mk_op2(0x2,I_BYTE,I_BYTE), "insb", +0, INS, mk_op2(0x2,I_WORD,I_WORD), "insw", +0, INS, mk_op2(0x2,I_DOUBLE,I_DOUBLE), "insd", +0, INSS, mk_op2(0x2,I_BYTE,I_BYTE), "inssb", +0, INSS, mk_op2(0x2,I_WORD,I_WORD), "inssw", +0, INSS, mk_op2(0x2,I_DOUBLE,I_DOUBLE), "inssd", +/* String instructions */ +0, MOVS, mk_op1c(0x0,I_BYTE,0), "movsb", +0, MOVS, mk_op1c(0x0,I_WORD,0), "movsw", +0, MOVS, mk_op1c(0x0,I_DOUBLE,0), "movsd", +0, MOVS, mk_op1c(0x0,I_BYTE,SO_TRANS), "movst", +0, MOVS, mk_op1c(0x1,I_BYTE,0), "cmpsb", +0, MOVS, mk_op1c(0x1,I_WORD,0), "cmpsw", +0, MOVS, mk_op1c(0x1,I_DOUBLE,0), "cmpsd", +0, MOVS, mk_op1c(0x1,I_BYTE,SO_TRANS), "cmpst", +0, MOVS, mk_op1c(0x3,I_BYTE,0), "skpsb", +0, MOVS, mk_op1c(0x3,I_WORD,0), "skpsw", +0, MOVS, mk_op1c(0x3,I_DOUBLE,0), "skpsd", +0, MOVS, mk_op1c(0x3,I_BYTE,SO_TRANS), "skpst", +/* Block instructions */ +0, MOVM, mk_op2(0x0,I_BYTE,I_BYTE), "movmb", +0, MOVM, mk_op2(0x0,I_WORD,I_WORD), "movmw", +0, MOVM, mk_op2(0x0,I_DOUBLE,I_DOUBLE), "movmd", +0, MOVM, mk_op2(0x1,I_BYTE,I_BYTE), "cmpmb", +0, MOVM, mk_op2(0x1,I_WORD,I_WORD), "cmpmw", +0, MOVM, mk_op2(0x1,I_DOUBLE,I_DOUBLE), "cmpmd", +/* Packed decimal instructions */ +0, COM, mk_op2(0xF,I_BYTE,I_BYTE), "addpb", +0, COM, mk_op2(0xF,I_WORD,I_WORD), "addpw", +0, COM, mk_op2(0xF,I_DOUBLE,I_DOUBLE), "addpd", +0, COM, mk_op2(0xB,I_BYTE,I_BYTE), "subpb", +0, COM, mk_op2(0xB,I_WORD,I_WORD), "subpw", +0, COM, mk_op2(0xB,I_DOUBLE,I_DOUBLE), "subpd", +/* Array instructions */ +0, CHECK, mk_op2(0x4,I_BYTE,I_BYTE), "indexb", +0, CHECK, mk_op2(0x4,I_WORD,I_WORD), "indexw", +0, CHECK, mk_op2(0x4,I_DOUBLE,I_DOUBLE), "indexd", +0, CHECK, mk_op2(0x3,I_BYTE,I_BYTE), "checkb", +0, CHECK, mk_op2(0x3,I_WORD,I_WORD), "checkw", +0, CHECK, mk_op2(0x3,I_DOUBLE,I_DOUBLE), "checkd", +/* Processor control instructions */ +0, JUMP, mk_op1(0x4,I_DOUBLE), "jump", +0, BR, mk_c(B_EQ), "beq", +0, BR, mk_c(B_NE), "bne", +0, BR, mk_c(B_CS), "bcs", +0, BR, mk_c(B_CC), "bcc", +0, BR, mk_c(B_HI), "bhi", +0, BR, mk_c(B_LS), "bls", +0, BR, mk_c(B_GT), "bgt", +0, BR, mk_c(B_LE), "ble", +0, BR, mk_c(B_FS), "bfs", +0, BR, mk_c(B_FC), "bfc", +0, BR, mk_c(B_LO), "blo", +0, BR, mk_c(B_HS), "bhs", +0, BR, mk_c(B_LT), "blt", +0, BR, mk_c(B_GE), "bge", +0, BR, mk_c(B_TRUE), "br", +#ifdef UNUSED +0, BR, mk_c(B_FALSE), "bfalse", +#endif +0, ADJSP, mk_op1(0xE,I_BYTE), "caseb", +0, ADJSP, mk_op1(0xE,I_WORD), "casew", +0, ADJSP, mk_op1(0xE,I_DOUBLE), "cased", +0, ACB, mk_op1(0x4,I_BYTE), "acbb", +0, ACB, mk_op1(0x4,I_WORD), "acbw", +0, ACB, mk_op1(0x4,I_DOUBLE), "acbd", +0, JSR, mk_op1(0xC,I_DOUBLE), "jsr", +0, BSR, mk_op(0x0), "bsr", +0, RET, mk_op(0x1), "ret", +0, RET, mk_op(0x2), "cxp", +0, ADJSP, mk_op1(0x0,I_DOUBLE), "cxpd", +0, RET, mk_op(0x3), "rxp", +0, RET, mk_op(0x4), "rett", +0, WAIT, mk_op(0x5), "reti", +0, WAIT, mk_op(0xC), "dia", +/* Processor service instructions */ +0, ADJSP, mk_op1(0xA,I_BYTE), "adjspb", +0, ADJSP, mk_op1(0xA,I_WORD), "adjspw", +0, ADJSP, mk_op1(0xA,I_DOUBLE), "adjspd", +0, ADJSP, mk_op1(0x2,I_BYTE), "bicpsrb", +0, ADJSP, mk_op1(0x2,I_WORD), "bicpsrw", +0, ADJSP, mk_op1(0x6,I_BYTE), "bispsrb", +0, ADJSP, mk_op1(0x6,I_WORD), "bispsrw", +#ifdef UNUSED +0, ADJSP, mk_op1(0x2,I_DOUBLE), "bicpsrd", +0, ADJSP, mk_op1(0x6,I_DOUBLE), "bispsrd", +#endif +0, SAVE, mk_op(0x6), "save", +0, SAVE, mk_op(0x7), "restore", +0, ENTER, mk_op(0x8), "enter", +0, SAVE, mk_op(0x9), "exit", +0, LPR, mk_op1(0x6,I_BYTE), "lprb", +0, LPR, mk_op1(0x6,I_WORD), "lprw", +0, LPR, mk_op1(0x6,I_DOUBLE), "lprd", +0, LPR, mk_op1(0x2,I_BYTE), "sprb", +0, LPR, mk_op1(0x2,I_WORD), "sprw", +0, LPR, mk_op1(0x2,I_DOUBLE), "sprd", +0, SETCFG, mk_op1(0x2,I_DOUBLE), "setcfg", +0, WAIT, mk_op(0xF), "bpt", +0, WAIT, mk_op(0xD), "flag", +0, WAIT, mk_op(0xE), "svc", +0, WAIT, mk_op(0xA), "nop", +0, WAIT, mk_op(0xB), "wait", +/* Memory management instructions */ +0, LMR, mk_op1(0x2,I_DOUBLE), "lmr", +0, LMR, mk_op1(0x3,I_DOUBLE), "smr", +0, RDVAL, mk_op1(0x0,I_DOUBLE), "rdval", +0, RDVAL, mk_op1(0x1,I_DOUBLE), "wrval", +#ifdef SU_ASSEM +/* The assembler ref. man and the CPU description booklet differ + in the encoding of these instructions +*/ +0, FFS, mk_op2c(0x6,I_BYTE,I_BYTE,1), "movsub", +0, FFS, mk_op2c(0x6,I_WORD,I_WORD,1), "movsuw", +0, FFS, mk_op2c(0x6,I_DOUBLE,I_DOUBLE,1),"movsud", +0, FFS, mk_op2c(0x6,I_BYTE,I_BYTE,3), "movusb", +0, FFS, mk_op2c(0x6,I_WORD,I_WORD,3), "movusw", +0, FFS, mk_op2c(0x6,I_DOUBLE,I_DOUBLE,3),"movusd", +#else +/* assembler reference manual version */ +0, FFS, mk_op2c(0x7,I_BYTE,I_BYTE,0), "movsub", +0, FFS, mk_op2c(0x7,I_WORD,I_WORD,0), "movsuw", +0, FFS, mk_op2c(0x7,I_DOUBLE,I_DOUBLE,0),"movsud", +0, FFS, mk_op2c(0x6,I_BYTE,I_BYTE,0), "movusb", +0, FFS, mk_op2c(0x6,I_WORD,I_WORD,0), "movusw", +0, FFS, mk_op2c(0x6,I_DOUBLE,I_DOUBLE,0),"movusd", +#endif +/* Floating point instructions */ +0, ADD_F, mk_op2(0xD,F_FLOAT,F_FLOAT), "absf", +0, ADD_F, mk_op2(0xD,F_LONG,F_LONG), "absl", +0, ADD_F, mk_op2(0x0,F_FLOAT,F_FLOAT), "addf", +0, ADD_F, mk_op2(0x0,F_LONG,F_LONG), "addl", +0, ADD_F, mk_op2(0x2,F_FLOAT,F_FLOAT), "cmpf", +0, ADD_F, mk_op2(0x2,F_LONG,F_LONG), "cmpl", +0, ADD_F, mk_op2(0x8,F_FLOAT,F_FLOAT), "divf", +0, ADD_F, mk_op2(0x8,F_LONG,F_LONG), "divl", +0, ADD_F, mk_op2(0xC,F_FLOAT,F_FLOAT), "mulf", +0, ADD_F, mk_op2(0xC,F_LONG,F_LONG), "mull", +0, ADD_F, mk_op2(0x4,F_FLOAT,F_FLOAT), "subf", +0, ADD_F, mk_op2(0x4,F_LONG,F_LONG), "subl", +0, ADD_F, mk_op2(0x5,F_FLOAT,F_FLOAT), "negf", +0, ADD_F, mk_op2(0x5,F_LONG,F_LONG), "negl", +0, ADD_F, mk_op2(0x1,F_FLOAT,F_FLOAT), "movf", +0, ADD_F, mk_op2(0x1,F_LONG,F_LONG), "movl", +0, MOVIF, mk_op2(0x0,I_BYTE,F_FLOAT), "movbf", +0, MOVIF, mk_op2(0x0,I_WORD,F_FLOAT), "movwf", +0, MOVIF, mk_op2(0x0,I_DOUBLE,F_FLOAT), "movdf", +0, MOVIF, mk_op2(0x0,I_BYTE,F_LONG), "movbl", +0, MOVIF, mk_op2(0x0,I_WORD,F_LONG), "movwl", +0, MOVIF, mk_op2(0x0,I_DOUBLE,F_LONG), "movdl", +0, MOVFL, mk_op2(0x3,F_FLOAT,F_LONG), "movfl", +0, MOVFL, mk_op2(0x2,F_LONG,F_FLOAT), "movlf", +0, TRUNC, mk_op2(0x7,F_FLOAT,I_BYTE), "floorfb", +0, TRUNC, mk_op2(0x7,F_FLOAT,I_WORD), "floorfw", +0, TRUNC, mk_op2(0x7,F_FLOAT,I_DOUBLE), "floorfd", +0, TRUNC, mk_op2(0x7,F_LONG,I_BYTE), "floorlb", +0, TRUNC, mk_op2(0x7,F_LONG,I_WORD), "floorlw", +0, TRUNC, mk_op2(0x7,F_LONG,I_DOUBLE), "floorld", +0, TRUNC, mk_op2(0x4,F_FLOAT,I_BYTE), "roundfb", +0, TRUNC, mk_op2(0x4,F_FLOAT,I_WORD), "roundfw", +0, TRUNC, mk_op2(0x4,F_FLOAT,I_DOUBLE), "roundfd", +0, TRUNC, mk_op2(0x4,F_LONG,I_BYTE), "roundlb", +0, TRUNC, mk_op2(0x4,F_LONG,I_WORD), "roundlw", +0, TRUNC, mk_op2(0x4,F_LONG,I_DOUBLE), "roundld", +0, TRUNC, mk_op2(0x5,F_FLOAT,I_BYTE), "truncfb", +0, TRUNC, mk_op2(0x5,F_FLOAT,I_WORD), "truncfw", +0, TRUNC, mk_op2(0x5,F_FLOAT,I_DOUBLE), "truncfd", +0, TRUNC, mk_op2(0x5,F_LONG,I_BYTE), "trunclb", +0, TRUNC, mk_op2(0x5,F_LONG,I_WORD), "trunclw", +0, TRUNC, mk_op2(0x5,F_LONG,I_DOUBLE), "truncld", +0, LFSR, mk_op(0x1), "lfsr", +0, LFSR, mk_op(0x6), "sfsr", +/* Slave processor instructions */ +0, LCR, mk_op1(0x2,I_DOUBLE), "lcr", /* Sure ? */ +0, LCR, mk_op1(0x3,I_DOUBLE), "scr", /* Sure ? */ +0, CATST, mk_op1(0x0,I_DOUBLE), "catst0",/* Sure ? */ +0, CATST, mk_op1(0x1,I_DOUBLE), "catst1",/* Sure ? */ +0, LCSR, mk_op1(0x1,S_DOUBLE), "lcsr", /* Sure ? */ +0, LCSR, mk_op1(0x6,S_DOUBLE), "scsr", /* Sure ? */ +0, CCVSI, mk_op2(0x7,S_DOUBLE,I_BYTE), "ccv0db", +0, CCVSI, mk_op2(0x7,S_DOUBLE,I_WORD), "ccv0dw", +0, CCVSI, mk_op2(0x7,S_DOUBLE,I_DOUBLE), "ccv0dd", +0, CCVSI, mk_op2(0x7,S_QUAD,I_BYTE), "ccv0qb", +0, CCVSI, mk_op2(0x7,S_QUAD,I_WORD), "ccv0qw", +0, CCVSI, mk_op2(0x7,S_QUAD,I_DOUBLE), "ccv0qd", +0, CCVSI, mk_op2(0x5,S_DOUBLE,I_BYTE), "ccv1db", +0, CCVSI, mk_op2(0x5,S_DOUBLE,I_WORD), "ccv1dw", +0, CCVSI, mk_op2(0x5,S_DOUBLE,I_DOUBLE), "ccv1dd", +0, CCVSI, mk_op2(0x5,S_QUAD,I_BYTE), "ccv1qb", +0, CCVSI, mk_op2(0x5,S_QUAD,I_WORD), "ccv1qw", +0, CCVSI, mk_op2(0x5,S_QUAD,I_DOUBLE), "ccv1qd", +0, CCVSI, mk_op2(0x4,S_DOUBLE,I_BYTE), "ccv2db", +0, CCVSI, mk_op2(0x4,S_DOUBLE,I_WORD), "ccv2dw", +0, CCVSI, mk_op2(0x4,S_DOUBLE,I_DOUBLE), "ccv2dd", +0, CCVSI, mk_op2(0x4,S_QUAD,I_BYTE), "ccv2qb", +0, CCVSI, mk_op2(0x4,S_QUAD,I_WORD), "ccv2qw", +0, CCVSI, mk_op2(0x4,S_QUAD,I_DOUBLE), "ccv2qd", +0, CCVIS, mk_op2(0x0,I_BYTE,S_DOUBLE), "ccv3bd", +0, CCVIS, mk_op2(0x0,I_WORD,S_DOUBLE), "ccv3wd", +0, CCVIS, mk_op2(0x0,I_DOUBLE,S_DOUBLE), "ccv3dd", +0, CCVIS, mk_op2(0x0,I_BYTE,S_QUAD), "ccv3bq", +0, CCVIS, mk_op2(0x0,I_WORD,S_QUAD), "ccv3wq", +0, CCVIS, mk_op2(0x0,I_DOUBLE,S_QUAD), "ccv3dq", +0, CCVSS, mk_op2(0x3,S_DOUBLE,S_QUAD), "ccv4dq", +0, CCVSS, mk_op2(0x2,S_QUAD,S_DOUBLE), "ccv5qd", +0, CMOV, mk_op2(0x0,S_DOUBLE,S_DOUBLE), "ccal0d", +0, CMOV, mk_op2(0x0,S_QUAD,S_QUAD), "ccal0q", +0, CMOV, mk_op2(0x4,S_DOUBLE,S_DOUBLE), "ccal1d", +0, CMOV, mk_op2(0x4,S_QUAD,S_QUAD), "ccal1q", +0, CMOV, mk_op2(0xC,S_DOUBLE,S_DOUBLE), "ccal2d", +0, CMOV, mk_op2(0xC,S_QUAD,S_QUAD), "ccal2q", +0, CMOV, mk_op2(0x8,S_DOUBLE,S_DOUBLE), "ccal3d", +0, CMOV, mk_op2(0x8,S_QUAD,S_QUAD), "ccal3q", +0, CMOV, mk_op2(0x2,S_DOUBLE,S_DOUBLE), "ccmpd", +0, CMOV, mk_op2(0x2,S_QUAD,S_QUAD), "ccmpq", +0, CMOV, mk_op2(0x1,S_DOUBLE,S_DOUBLE), "cmov0d", +0, CMOV, mk_op2(0x1,S_QUAD,S_QUAD), "cmov0q", +0, CMOV, mk_op2(0xD,S_DOUBLE,S_DOUBLE), "cmov1d", +0, CMOV, mk_op2(0xD,S_QUAD,S_QUAD), "cmov1q", +0, CMOV, mk_op2(0x5,S_DOUBLE,S_DOUBLE), "cmov2d", +0, CMOV, mk_op2(0x5,S_QUAD,S_QUAD), "cmov2q", diff --git a/mach/ns/as/mach4.c b/mach/ns/as/mach4.c new file mode 100644 index 000000000..74772fcd7 --- /dev/null +++ b/mach/ns/as/mach4.c @@ -0,0 +1,416 @@ +#define RCSID4 "$Header$" + +/* + * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. + * + * This product is part of the Amsterdam Compiler Kit. + * + * Permission to use, sell, duplicate or disclose this software must be + * obtained in writing. Requests for such permissions may be sent to + * + * Dr. Andrew S. Tanenbaum + * Wiskundig Seminarium + * Vrije Universiteit + * Postbox 7161 + * 1007 MC Amsterdam + * The Netherlands + * + */ + +/* Author: Ed Keizer */ + +operation: + BR expr + /* format 0 */ + { dot_adjust(&$2) ; form0($1) ; disp(&$2, RELPC) ;} + | WAIT + /* format 1 */ + { form1($1) ;} + | BSR expr + /* format 1 */ + { dot_adjust(&$2) ; form1($1) ; disp(&$2, RELPC) ;} + | RET expr + /* format 1 */ + { form1($1) ; disp(&$2, 0) ;} + | SAVE reg_list + /* format 1 */ + { form1($1) ; emit1(reg_list($2,id_op($1)!=0x6)) ;} + | ENTER reg_list ',' expr + /* format 1 */ + { form1($1) ; emit1(reg_list($2,0)) ; disp(&$4, 0) ;} + | LPR AREG ',' gen1 + /* format 2 */ + { if ( id_op($1)==0x2 ) not_imm(&mode1) ; + form2($1,$2) ; gen1($1) ; + } + | SEQ gen1 + /* format 2 */ + { form2($1,id_cc($1)) ; gen1($1) ; not_imm(&mode1) ;} + | MOVQ absexp ',' gen1 + /* format 2 */ + { + if ( !fit4($2) ) { + serror("Constant too large") ; + } + form2($1,low4($2)) ; gen1($1) ; + if ( id_op($1)!=0x1 ) not_imm(&mode1) ; /* !cmp */ + } + | ACB absexp ',' gen1 ',' expr + /* format 2 */ + { + dot_adjust(&$6) ; + if (!fit4($2) ) { + serror("Constant too large") ; + } + form2($1,low4($2)) ; gen1($1) ; not_imm(&mode1) ; + disp(&$6, RELPC) ; + } + | ADJSP gen1 + /* format 3 */ + { + if ( id_op($1)==0 ) not_imm(&mode1) ; /* cxpd */ + form3($1) ; gen1($1) ;} + | JSR gen1 + /* format 3 */ + { +#ifndef NO_OPTIM + if ( mode1.m_mode==0x15 ) { /* Absolute */ + dot_adjust(&mode1.m_expr1) ; + RELOMOVE(relonami, mode1.m_rel1); + form1(0) ; disp(&mode1.m_expr1, RELPC) ; /* bsr */ + } else +#endif + { form3($1) ; gen1($1) ; } + not_imm(&mode1) ; + } + | JUMP gen1 + /* format 3 */ + { +#ifndef NO_OPTIM + if ( mode1.m_mode==0x15 ) { /* Absolute */ + dot_adjust(&mode1.m_expr1) ; + RELOMOVE(relonami, mode1.m_rel1); + form0(B_TRUE) ; disp(&mode1.m_expr1, RELPC) ; /* br */ + } else +#endif + { form3($1) ; gen1($1) ; } + not_imm(&mode1) ; + } + | ADD_I gen1 ',' gen2 + /* format 4 */ + { + register opc ; + opc=id_op($1) ; + if ( opc==0x9 ) not_imm(&mode1) ; /* addr */ + if ( opc!=0x1 ) not_imm(&mode2) ; /* !cmp */ +#ifndef NO_OPTIM + if ( mode1.m_mode==0x14 && /* Immediate */ + (mode1.m_expr1.typ & ~S_EXT) == S_ABS && + ( + (fit4(mode1.m_expr1.val) && + (opc==0 || opc==1 || opc==5)) + || + (fit4(-mode1.m_expr1.val) && + (opc==8)) + ) + ) + { + /* Warning, an absolute expression derived + from a symbol that is defined after + use might - if the value now suddenly fits - + cause failed assertions in newlabel + */ + /* add, cmp, mov */ + /* added: the subtract of a signed + * short is the same as the add + * of the negation of that short + * so: subi short,x == addqi -short,x + * 19/04/85 h.m.kodden,m.j.a.leliveld + */ + if (opc==8) /* do the negate */ + mode1.m_expr1.val = + (~mode1.m_expr1.val+1)&0xF; + opc=low4(mode1.m_expr1.val) ; + mode1= mode2 ; + form2($1,opc) ; gen1($1) ; + } else +#endif + { form4($1) ; gengen($1) ; } + } + | SETCFG cpu_opts + /* format 5 */ + { form5($1,$2) ;} + | MOVS string_opts + /* format 5 */ + { form5($1,($2)|id_cc($1)) ;} + | COM gen1 ',' gen2 + /* format 6 */ + { form6($1) ; gengen($1) ; not_imm(&mode2) ;} + | MUL_I gen1 ',' gen2 + /* format 7 */ + { + if ( id_op($1)==0x9 || id_op($1)==0xB ) { + /* mei or dei */ + switch ( mode2.m_mode ) { + case 1 : case 3 : case 5 : case 7 : + serror("register must be even") ; + } + } + form7($1) ; gengen($1) ; not_imm(&mode2) ; + } + | MOVID gen1 ',' gen2 + /* format 7 */ + { form7x($1,id_g1($1)) ; gengen($1) ; not_imm(&mode2) ;} + | MOVM gen1 ',' gen2 ',' expr + /* format 7 */ + { + register s_size ; + s_size= id_g1($1)+1 ; + /* $6.val= $6.val*s_size - s_size ; */ + $6.val= $6.val -1 ; + form7($1) ; gengen($1) ; disp(&$6, 0) ; + not_imm(&mode1) ; not_imm(&mode2) ; + } + | INSS gen1 ',' gen2 ',' absexp ',' absexp + /* format 7 */ + { + if ( ( $6<0 || $6>7 || $8<1 || $8>32 ) + ) { serror("Constant out of bounds") ; } + form7($1) ; gengen($1) ; + if ( id_op($1)==0x3 ) not_imm(&mode1) ; /* exts */ + not_imm(&mode2) ; + emit1((((int)$6)<<5)+(int)$8-1) ; + } + | FFS gen1 ',' gen2 + /* format 8 */ + { form8($1,id_cc($1)) ; gengen($1) ; not_imm(&mode2) ;} + | CHECK REG ',' gen1 ',' gen2 + /* format 8 */ + { + form8($1,$2) ; gengen($1) ; + if ( id_op($1)!=0x4 ) { + not_imm(&mode1) ; /* check, cvtp */ + if ( id_op($1)==0x1 ) not_imm(&mode2) ;/*cvtp */ + } + } + | INS REG ',' gen1 ',' gen2 ',' expr + /* format 8 */ + { + form8($1,$2) ; gengen($1) ; disp(&$8, 0) ; + if ( id_op($1)==0x0 ) not_imm(&mode1) ; + not_imm(&mode2) ; + } + | MOVIF gen1 ',' fgen2 + /* format 9 */ + { + assert( id_t1($1)==T_INT && id_t2($1)==T_FL ) ; + form9($1,id_g1($1),id_g2($1)) ; gengen($1) ; + not_imm(&mode2) ; + } + | MOVFL fgen1 ',' fgen2 + /* format 9 */ + { + assert( id_t1($1)==T_FL && id_t2($1)==T_FL ) ; + form9($1,id_g1($1),( id_g2($1)==F_LONG?3:2 )) ; + gengen($1) ; not_imm(&mode2) ; + } + | TRUNC fgen1 ',' gen2 + /* format 9 */ + { + assert( id_t1($1)==T_FL && id_t2($1)==T_INT ) ; + form9($1,id_g2($1),id_g1($1)) ; gengen($1) ; + not_imm(&mode2) ; + } + | LFSR gen1 + /* format 9 */ + { + if ( id_op($1)==6 ) { /* SFSR */ + not_imm(&mode1) ; + mode2.m_mode=mode1.m_mode ; + mode1.m_mode=0 ; + } else { + mode2.m_mode=0 ; + } + form9($1,0,0) ; + if ( id_op($1)==6 ) { + mode1.m_mode=mode2.m_mode ; + } + gen1($1) ; + } + | ADD_F fgen1 ',' fgen2 + /* format 11 */ + { if ( id_op($1)!=0x2 ) not_imm(&mode2) ; /* !CMPF */ + form11($1) ; gengen($1) ; + } + | RDVAL gen1 + /* format 14 */ + { form14($1,0) ; gen1($1) ; not_imm(&mode1) ;} + | LMR MREG ',' gen1 + /* format 14 */ + { + form14($1,$2) ; gen1($1) ; + if ( id_op($1)==0x3 ) not_imm(&mode1) ; + } + /* All remaining categories are not checked for + illegal immediates */ + | LCR CREG ',' gen1 + /* format 15.0 */ + { frm15_0($1,$2) ; gen1($1) ;} + | CATST gen1 + /* format 15.0 */ + { frm15_0($1,0) ; gen1($1) ;} + | LCSR gen1 + /* format 15.1 */ /* Sure? */ + { mode2.m_mode=0 ; frm15_1($1,0,0) ; gen1($1) ;} + | CCVIS gen1 ',' gen2 + /* format 15.1 */ + { + assert( id_t1($1)==T_INT && id_t2($1)==T_SLAVE ) ; + frm15_1($1,id_g1($1),id_g2($1)) ; gengen($1) ; + } + | CCVSI gen1 ',' gen2 + /* format 15.1 */ + { + assert( id_t1($1)==T_SLAVE && id_t2($1)==T_INT ) ; + frm15_1($1,id_g2($1),id_g1($1)) ; gengen($1) ; + } + | CCVSS gen1 ',' gen2 + /* format 15.1 */ + { + assert( id_t1($1)==T_SLAVE && id_t2($1)==T_SLAVE ) ; + frm15_1($1,0,0) ; gengen($1) ; /* Sure? */ + } + | CMOV gen1 ',' gen2 + /* format 15.5 */ + { frm15_5($1) ; gengen($1) ;} + ; + +gen1 : { mode_ptr= &mode1 ; clrmode() ; } gen + ; +gen2 : { mode_ptr= &mode2 ; clrmode() ; } gen + ; +fgen1 : { mode_ptr= &mode1 ; clrmode() ; } fgen + ; +fgen2 : { mode_ptr= &mode2 ; clrmode() ; } fgen + ; + +gen : gen_not_reg /* Every mode except register */ + | REG + { mode_ptr->m_mode= $1 ; } + ; +fgen : gen_not_reg /* Every mode except register */ + | FREG + { mode_ptr->m_mode= $1 ; } + ; + +gen_not_reg: gen_a /* general mode with eff. address */ + | REG { mode_ptr->m_mode=$1 ;} index + /* The register is supposed to contain the + address + */ + | gen_a index /* As above, but indexed */ + | expr /* Immediate */ + { mode_ptr->m_mode= 0x14 ; + mode_ptr->m_expr1= $1 ; + RELOMOVE(mode_ptr->m_rel1, relonami); + } + ; + +gen_a : expr '(' REG ')' /* Register relative */ + { mode_ptr->m_mode= 0x8 + $3 ; + mode_ptr->m_ndisp= 1 ; + mode_ptr->m_expr1= $1 ; + RELOMOVE(mode_ptr->m_rel1, relonami); + } + | expr '(' AREG ')' /* Memory space */ + { if ( $3<0x8 || $3>0xA ) badsyntax() ; + mode_ptr->m_mode= 0x18 + ($3&3) ; + mode_ptr->m_ndisp= 1 ; + mode_ptr->m_expr1= $1 ; + RELOMOVE(mode_ptr->m_rel1, relonami); + } + | expr '(' PC ')' /* Memory space */ + { mode_ptr->m_mode= 0x1B ; + mode_ptr->m_ndisp= 1 ; + mode_ptr->m_expr1= $1 ; + RELOMOVE(mode_ptr->m_rel1, relonami); + dot_adjust(&mode_ptr->m_expr1) ; + } + | expr '(' + { mode_ptr->m_expr2 = $1; + RELOMOVE(mode_ptr->m_rel2, relonami); + } + expr '(' AREG ')' ')' /* Memory relative */ + { if ( $6<0x8 || $6>0xA ) badsyntax() ; + mode_ptr->m_mode= 0x10 + ($6&3) ; + mode_ptr->m_ndisp= 2 ; + mode_ptr->m_expr1= $4 ; + RELOMOVE(mode_ptr->m_rel1, relonami); + } + | '@' expr /* Absolute */ + { mode_ptr->m_mode= 0x15 ; + mode_ptr->m_ndisp= 1 ; + mode_ptr->m_expr1= $2 ; + RELOMOVE(mode_ptr->m_rel1, relonami); + } + | EXTERNAL '(' expr ')' + { mode_ptr->m_mode= 0x16 ; + mode_ptr->m_ndisp= 2 ; + mode_ptr->m_expr1= $3 ; + RELOMOVE(mode_ptr->m_rel1, relonami); + } + '+' expr /* External */ + { + mode_ptr->m_expr2= $7 ; + RELOMOVE(mode_ptr->m_rel2, relonami); + } + | TOS /* Top Of Stack */ + { mode_ptr->m_mode= 0x17 ; } + ; + +index : '[' REG ':' INDICATOR ']' /* Indexed postfix */ + { mode_ptr->m_index= (mode_ptr->m_mode<<3) | $2 ; + mode_ptr->m_mode= ind_mode( $4 ) ; + } + ; + +cpu_opts: + '[' ']' + { $$=0 ;} + | '[' cpu_list ']' + { $$= $2 ;} + ; + +cpu_list: + INDICATOR + { $$=cpu_opt($1) ; } + | cpu_list ',' INDICATOR + { $$= ($1) | cpu_opt($3) ;} + ; + +string_opts: + { $$=0 ;} + | INDICATOR + { $$= string_opt($1) ; } + | INDICATOR ',' INDICATOR + { if ( $1 != 'b' || + ( $3 != 'u' && $3 != 'w' ) ) { + serror("illegal string options") ; + } + $$ = string_opt($1)|string_opt($3) ; + } + ; + +reg_list: + '[' ']' + { $$=0 ;} + | '[' reg_items ']' + { $$= $2 ;} + ; + +reg_items: + REG + { $$= 1<<($1) ; } + | reg_items ',' REG + { $$= ($1) | ( 1<<($3) ) ;} + ; diff --git a/mach/ns/as/mach5.c b/mach/ns/as/mach5.c new file mode 100644 index 000000000..b61ccb18c --- /dev/null +++ b/mach/ns/as/mach5.c @@ -0,0 +1,311 @@ +#define RCSID5 "$Header$" + +/* + * NS 16032 special routines + */ + +clrmode() { /* clear the current mode */ + mode_ptr->m_ndisp = 0 ; +} + +int ind_mode(type) { + switch ( type ) { + case 'b' : return 0x1C ; + case 'w' : return 0x1D ; + case 'd' : return 0x1E ; + case 'q' : return 0x1F ; + default : + serror("illegal size indicator") ; + return 0x1F ; + } +} + +badsyntax() { + + serror("bad operands"); +} + +ill_imm() { + serror("immediate operand not allowed") ; +} +/* Create the output formats */ +form2(id,sval) { + assert ( id_t1(id)==T_INT ) ; + emit1( id_g1(id) | 0xC | (id_op(id)<<4) | ((sval&1)<<7 ) ) ; + emit1( (sval>>1) | (mode1.m_mode<<3) ) ; +} + +form3(id) { + assert ( id_t1(id)==T_INT ) ; + emit1( id_g1(id) | 0x7C | ((id_op(id)&1)<<7) ) ; + emit1( (id_op(id)>>1) | (mode1.m_mode<<3) ) ; +} + +form4(id) { + assert ( id_t1(id)==T_INT && id_t2(id)==T_INT ); + emit1( id_g2(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ; + emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ; +} + +form5(id,sval) { + assert ( id_t1(id)==T_INT ) ; + emit1(0xE) ; + emit1( id_g1(id) | (id_op(id)<<2) | ((sval&1)<<7 ) ) ; + emit1( (sval>>1) ) ; +} + +form7x(id,i_type) { + assert ( id_t1(id)==T_INT && id_t2(id)==T_INT ); + emit1(0xCE) ; + emit1( i_type | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ; + emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ; +} + +form8(id,reg) { + assert ( id_t1(id)==T_INT ) ; + emit1( 0x2E | ((id_op(id)&3)<<6) ) ; + emit1( id_g1(id) | (id_op(id)&04) | (reg<<3) | ((mode2.m_mode&03)<<6) ) ; + emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ; +} + +form9(id,i_type,f_type) { + emit1(0x3E) ; + emit1( i_type | (f_type<<2) | (id_op(id)<<3) | ((mode2.m_mode&03)<<6) ) ; + emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ; +} + +form11(id) { + assert ( id_t1(id)==T_FL && id_t2(id)==T_FL && id_g1(id)==id_g2(id) ); + emit1(0xBE) ; + emit1( id_g1(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ; + emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ; +} + +form14(id,reg) { + assert ( id_t1(id)==T_INT ) ; + emit1(0x1E) ; + emit1( id_g1(id) | (id_op(id)<<2) | ((reg&1)<<7 ) ) ; + emit1( (reg>>1) | (mode1.m_mode<<3) ) ; +} + +frm15_0(id,reg) { + assert ( id_t1(id)==T_INT ) ; + emit1(0x16 /* + slave<<5 */ ) ; + emit1( id_g1(id) | (id_op(id)<<2) | ((reg&1)<<7 ) ) ; + emit1( (reg>>1) | (mode1.m_mode<<3) ) ; +} + +frm15_1(id,i_type,s_type) { + emit1(0x16 /* + slave<<5 */ ) ; + emit1( i_type | (s_type<<2) | (id_op(id)<<3) | ((mode2.m_mode&03)<<6) ) ; + emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ; +} + +frm15_5(id) { + assert(id_t1(id)==T_SLAVE&& id_t2(id)==T_SLAVE&& id_g1(id)==id_g2(id) ); + emit1(0x16 /* + slave<<5 */ ) ; + emit1( id_g1(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ; + emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ; +} + +gen1(id) { + if ( (mode1.m_mode&0x1C)==0x1C ) { + emit1(mode1.m_index) ; + } + if ( mode1.m_mode==0x14 ) { /* Immediate */ + RELOMOVE(relonami, mode1.m_rel1); + imm(id_g1(id),&mode1.m_expr1) ; + } else + if ( mode1.m_ndisp >0 ) { + RELOMOVE(relonami, mode1.m_rel1); + disp(&mode1.m_expr1, mode1.m_mode == 0x1B ? RELPC : 0) ; + if ( mode1.m_ndisp >1 ) { + RELOMOVE(relonami, mode1.m_rel2); + disp(&mode1.m_expr2, 0) ; + } + } +} + +gengen(id) { + if ( (mode1.m_mode&0x1C)==0x1C ) { + emit1(mode1.m_index) ; + } + if ( (mode2.m_mode&0x1C)==0x1C ) { + emit1(mode2.m_index) ; + } + if ( mode1.m_mode==0x14 ) { /* Immediate */ + RELOMOVE(relonami, mode1.m_rel1); + imm(id_g1(id),&mode1.m_expr1) ; + } else + if ( mode1.m_ndisp >0 ) { + RELOMOVE(relonami, mode1.m_rel1); + disp(&mode1.m_expr1, mode1.m_mode == 0x1B ? RELPC : 0) ; + if ( mode1.m_ndisp >1 ) { + RELOMOVE(relonami, mode1.m_rel2); + disp(&mode1.m_expr2, 0) ; + } + } + if ( mode2.m_mode==0x14 ) { /* Immediate */ + RELOMOVE(relonami, mode2.m_rel1); + imm(id_g2(id),&mode2.m_expr1) ; + } else + if ( mode2.m_ndisp >0 ) { + RELOMOVE(relonami, mode2.m_rel1); + disp(&mode2.m_expr1, mode2.m_mode == 0x1B ? RELPC : 0) ; + if ( mode2.m_ndisp >1 ) { + RELOMOVE(relonami, mode2.m_rel2); + disp(&mode2.m_expr2, 0) ; + } + } +} + +disp(expr, relpc) register expr_t *expr ; { + register sm1, sm2 ; + + sm1=0 ; sm2=0 ; + if (DOTTYP >= 0x2 && DOTTYP<=0x7F && +#ifdef ASLD + (pass==PASS_1 ? expr->typ==S_ABS : expr->typ!=S_VAR ) ) { +#else + expr->typ == S_ABS) { +#endif + /* All non-text displacements are quad-sized. + The algorithm currently used for minimizing the size + (See CACM article) might generate assertion failures if + any displacement it is trying to minimize increases during + the assembly process. The only way to avoid increases + like that is to fix the sizes of all displacements in + non-text segments. + If the framework included enough information one + might detect in the first pass (0) whether the value + of the expression depends on any symbols whose value + might alter later on in the assembly process. In that case + one could determine the right size in the first pass in + most cases. + */ + if ( fitd_b(expr->val) ) { + sm1=1 ; sm2= 1 ; + } else { + if ( fitd_w(expr->val) ) sm2=1 ; + } + } + sm1=small(sm1,1) ; sm2=small(sm2,2) ; +#ifdef RELOCATION + newrelo(expr->typ, RELO4|RELBR|RELWR|relpc); +#endif + if ( sm1 ) putdisp(expr->val,1) ; + else if ( sm2 ) putdisp(expr->val,2) ; + else putdisp(expr->val,4) ; +} + +putdisp(val,size) valu_t val ; { + switch ( size ) { + case 1 : + emit1( ((int)val)&0x7F ) ; + break ; + case 2 : + emit1( ( (((int)val)>>8)&0x3F ) | 0x80 ) ; + emit1( ((int)val)&0xFF ) ; + break ; + case 4 : + emit1( (((int)(val>>24)) | 0xC0) & 0xFF ) ; + emit1( ((int)(val>>16)) & 0xFF ) ; + emit1( (((int)val)>>8) & 0xFF ) ; + emit1( ((int)val)&0xFF ) ; + break ; + } +} + +dot_adjust(expr) register expr_t *expr ; { + expr->val -= DOTVAL ; + if ( pass==PASS_2 ) { + if ( (expr->typ&S_DOT) == 0 && expr->val>0 ) { + expr->val -= DOTGAIN; + } + } + if ( (expr->typ & ~S_DOT) == DOTTYP ) { + expr->typ=S_ABS ; + } else { + expr->typ=S_VAR ; + } +} + +/* The idea of the following is: + * Give the assembler programmer a warning if he tries to store + * an immediate value in a field which is too small to fit in. + */ + +testsize(type,val) { +/* check if value fits in type */ + switch( type ) { + case I_DOUBLE : return fit32(val); + case I_WORD : return fit16(val); + case I_BYTE : return fit8(val); + } +} + +imm(i_type,expr) register expr_t *expr ; { +/* emit value of immediate expression , after check on FIT */ + if (!testsize(i_type,(int)expr->val)) + warning("immediate operand too large"); + switch( i_type ) { + case I_DOUBLE : +#ifdef RELOCATION + newrelo(expr->typ, RELO4|RELBR|RELWR); +#endif + emit1( ((int)(expr->val>>24)) & 0xFF ) ; + emit1( ((int)(expr->val>>16)) & 0xFF ) ; + emit1( (((int)expr->val)>>8) & 0xFF ) ; + emit1( ((int)expr->val) & 0xFF ) ; + break; + case I_WORD: +#ifdef RELOCATION + newrelo(expr->typ, RELO2|RELBR); +#endif + emit1( (((int)expr->val)>>8) & 0xFF ) ; + emit1( ((int)expr->val) & 0xFF ) ; + break; + case I_BYTE: +#ifdef RELOCATION + newrelo(expr->typ, RELO1); +#endif + emit1( ((int)expr->val) & 0xFF ) ; + } +} + + +reg_list(list,reverse) { + register rev_list, i ; + if ( !reverse ) { + return list ; + } + rev_list= 0 ; + for ( i=0 ; i<8 ; i++ ) { + if ( list & (1<