123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- /*
- * (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 "$Id$"
- /*
- * INTEL 8086 special routines
- */
- void ea_1(int param)
- {
- if ((mrg_1 & 070) || (param & ~070)) {
- serror("bad operand");
- }
- emit1(mrg_1 | param);
- switch(mrg_1 >> 6) {
- case 0:
- if (mrg_1 == 6 || (mrg_1 & 040)) {
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_1);
- newrelo(exp_1.typ, RELO2);
- #endif
- emit2(exp_1.val);
- }
- break;
- case 1:
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_1);
- newrelo(exp_1.typ, RELO1);
- #endif
- emit1(exp_1.val);
- break;
- case 2:
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_1);
- newrelo(exp_1.typ, RELO2);
- #endif
- emit2(exp_1.val);
- break;
- }
- }
- void ea_2(int param)
- {
- mrg_1 = mrg_2;
- exp_1 = exp_2;
- RELOMOVE(rel_1, rel_2);
- ea_1(param);
- }
- void reverse()
- {
- int m, r; expr_t e;
- m = mrg_1; mrg_1 = mrg_2; mrg_2 = m;
- e = exp_1; exp_1 = exp_2; exp_2 = e;
- #ifndef ASLD
- r = rel_1; rel_1 = rel_2; rel_2 = r;
- #endif
- }
- void badsyntax()
- {
- serror("bad operands");
- }
- void regsize(int sz)
- {
- int bit;
- sz <<= 3;
- bit = 010;
- sz &= bit;
- if ((mrg_1 >= 0300 && (mrg_1 & bit) != sz) ||
- (mrg_2 >= 0300 && (mrg_2 & bit) != sz))
- serror("register error");
- mrg_1 &= ~bit;
- mrg_2 &= ~bit;
- }
- void indexed()
- {
- int sm1, sm2;
- if (mrg_2 & ~7)
- serror("register error");
- sm1 = exp_2.typ == S_ABS && fitb((short)(exp_2.val));
- if (sm1) {
- sm2 = exp_2.val == 0 && mrg_2 != 6;
- }
- else sm2 = 0;
- if (small(sm1, 1)) {
- if (small(sm2, 1)) {
- }
- else mrg_2 |= 0100;
- }
- else {
- if (small(0, 1)) {}
- mrg_2 |= 0200;
- }
- }
- void branch(int opc, expr_t exp)
- {
- int sm,dist;
- int saving = opc == 0353 ? 1 : 3;
- 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 ((opc & 0370) == 0340) {
- fit(sm);
- sm = 1;
- } else {
- if ((sm = small(sm,saving)) == 0) {
- if (opc != 0353) {
- emit1(opc^1);
- emit1(3);
- dist -= 2;
- }
- opc = 0351;
- dist--;
- }
- }
- emit1(opc);
- if (sm == 0) {
- #ifdef RELOCATION
- newrelo(exp.typ, RELPC | RELO2);
- #endif
- emit2(dist);
- } else
- emit1(dist);
- }
- void pushop(int opc)
- {
- regsize(1);
- if (mrg_1 & 020) {
- if ( (mrg_1&3) == 1 && opc==1 ) badsyntax() ;
- emit1(6 | opc | (mrg_1&3)<<3);
- } else if (mrg_1 >= 0300) {
- emit1(0120 | opc<<3 | (mrg_1&7));
- } else if (opc == 0) {
- if (mrg_1 & 040) { /* 070 ??? */
- if (small(exp_1.typ == S_ABS && fitb((short)exp_1.val),1)) {
- emit1(0152);
- emit1((int) exp_1.val);
- } else {
- emit1(0150);
- RELOMOVE(relonami, rel_1);
- #ifdef RELOCATION
- newrelo(exp_1.typ, RELO2);
- emit2((int) exp_1.val);
- #endif
- }
- } else {
- emit1(0377); ea_1(6<<3);
- }
- } else {
- emit1(0217); ea_1(0<<3);
- }
- }
- void addop(int opc)
- {
- regsize(opc);
- if (mrg_2 >= 0300) {
- emit1(opc); ea_1((mrg_2&7)<<3);
- } else if ((mrg_2 & 040) && mrg_1 == 0300) {
- emit1(opc | 4);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_2);
- newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
- #endif
- emitx(exp_2.val, (opc&1)+1);
- } else if (mrg_2 & 040) {
- if ((opc&1) == 0) {
- emit1(0200);
- } else {
- int sm = exp_2.typ == S_ABS && fitb((short)exp_2.val) &&
- opc != 011 && opc != 041 && opc != 061;
- if (small(sm, 1)) {
- emit1(0203); opc &= ~1;
- }
- else emit1(0201);
- }
- ea_1(opc & 070);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_2);
- newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
- #endif
- emitx(exp_2.val, (opc&1)+1);
- } else if (mrg_1 >= 0300) {
- emit1(opc | 2);
- ea_2((mrg_1&7)<<3);
- } else
- badsyntax();
- }
- void rolop(int opc)
- {
- int cmrg;
- cmrg = mrg_2;
- mrg_2 = mrg_1;
- regsize(opc);
- if (cmrg == 0301) {
- emit1(0322 | (opc&1)); ea_1(opc&070);
- } else if (cmrg & 040) {
- if (small(exp_2.val == 1, 1)) {
- emit1(0320 | (opc&1)); ea_1(opc&070);
- } else {
- fit(fitb(exp_2.val));
- emit1(0300|(opc&1)); ea_1(opc&070);
- emit1((int)exp_2.val);
- }
- } else
- badsyntax();
- }
- void incop(int opc)
- {
- regsize(opc);
- if ((opc&1) && mrg_1>=0300) {
- emit1(0100 | (opc&010) | (mrg_1&7));
- } else {
- emit1(0376 | (opc&1));
- ea_1(opc & 010);
- }
- }
- void callop(int opc)
- {
- regsize(1);
- if (mrg_1 & 040) {
- if (opc == (040+(0351<<8))) {
- RELOMOVE(relonami, rel_1);
- branch(0353,exp_1);
- } else {
- exp_1.val -= (DOTVAL+3);
- emit1(opc>>8);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_1);
- newrelo(exp_1.typ, RELPC | RELO2);
- #endif
- emit2(exp_1.val);
- }
- } else {
- emit1(0377); ea_1(opc&070);
- }
- }
- void xchg(int opc)
- {
- regsize(opc);
- if (mrg_2 == 0300 || mrg_1 < 0300)
- reverse();
- if (opc == 1 && mrg_1 == 0300 && mrg_2 >= 0300) {
- emit1(0220 | (mrg_2&7));
- } else if (mrg_1 >= 0300) {
- emit1(0206 | opc); ea_2((mrg_1&7)<<3);
- } else
- badsyntax();
- }
- void test(int opc)
- {
- regsize(opc);
- if ((mrg_1 & 040) || mrg_2 >= 0300)
- reverse();
- if ((mrg_2 & 040) && mrg_1 == 0300) {
- emit1(0250 | opc);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_2);
- newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
- #endif
- emitx(exp_2.val, (opc&1)+1);
- } else if (mrg_2 & 040) {
- emit1(0366 | opc);
- ea_1(0<<3);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_2);
- newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
- #endif
- emitx(exp_2.val, (opc&1)+1);
- } else if (mrg_1 >= 0300) {
- emit1(0204 | opc); ea_2((mrg_1&7)<<3);
- } else
- badsyntax();
- }
- void mov(int opc)
- {
- regsize(opc);
- if (mrg_1 & 020) {
- emit1(0216); ea_2((mrg_1&3)<<3);
- } else if (mrg_2 & 020) {
- emit1(0214); ea_1((mrg_2&3)<<3);
- } else if (mrg_2 & 040) {
- if (mrg_1 >= 0300) {
- emit1(0260 | opc<<3 | (mrg_1&7));
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_2);
- newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
- #endif
- emitx(exp_2.val, (opc&1)+1);
- } else {
- emit1(0306 | opc); ea_1(0<<3);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_2);
- newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
- #endif
- emitx(exp_2.val, (opc&1)+1);
- }
- } else if (mrg_2 == 0300 && mrg_1 == 6) {
- emit1(0242 | opc);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_1);
- newrelo(exp_1.typ, RELO2);
- #endif
- emit2(exp_1.val);
- } else if (mrg_1 == 0300 && mrg_2 == 6) {
- emit1(0240 | opc);
- #ifdef RELOCATION
- RELOMOVE(relonami, rel_2);
- newrelo(exp_2.typ, RELO2);
- #endif
- emit2(exp_2.val);
- } else if (mrg_2 >= 0300) {
- emit1(0210 | opc); ea_1((mrg_2&7)<<3);
- } else if (mrg_1 >= 0300) {
- emit1(0212 | opc); ea_2((mrg_1&7)<<3);
- } else {
- badsyntax();
- }
- }
- void imul(int opc)
- {
- regsize(opc);
- if (exp_2.typ != S_ABS || ((mrg_2 & 040) == 0)) {
- serror("bad operand");
- } else {
- if (small(exp_2.typ == S_ABS && fitb((short)exp_2.val),1)) {
- emit1(0153);
- ea_1((mrg_2&7)<<3);
- emit1((int)exp_2.val);
- } else {
- emit1(0151);
- ea_1((mrg_2&7)<<3);
- RELOMOVE(relonami, rel_2);
- #ifdef RELOCATION
- newrelo(exp_2.typ, RELO2);
- emit2((int) exp_2.val);
- #endif
- }
- }
- }
|