many fixes, found by actually running the code it produces

This commit is contained in:
ceriel 1989-10-10 10:54:20 +00:00
parent d25472bbfb
commit e713e6f8fe
4 changed files with 31 additions and 24 deletions

View file

@ -21,7 +21,7 @@
#define is_expr(reg) ((reg)&IS_EXPR) #define is_expr(reg) ((reg)&IS_EXPR)
#define is_segreg(reg) ((reg)&IS_RSEG) #define is_segreg(reg) ((reg)&IS_RSEG)
#define is_reg(reg) (((reg)&(IS_R8|IS_R32)) != 0) #define is_reg(reg) (((reg)&(IS_R8|IS_R32)) != 0)
#define is_acc(reg) (((reg)&(IS_R8|IS_R32)) == (reg)) #define is_acc(reg) ((reg) != 0 && ((reg)&(IS_R8|IS_R32)) == (reg))
struct operand { struct operand {
int mod; int mod;

View file

@ -76,8 +76,10 @@
0, CALLOP, 020+(0350<<8), "call", 0, CALLOP, 020+(0350<<8), "call",
0, CALLOP, 040+(0351<<8), "jmp", 0, CALLOP, 040+(0351<<8), "jmp",
0, ENTER, 0310, "enter", 0, ENTER, 0310, "enter",
0, EXTEND, 0266, "movzx", 0, EXTEND, 0267, "movzx",
0, EXTEND, 0276, "movsx", 0, EXTEND, 0266, "movzxb",
0, EXTEND, 0277, "movsx",
0, EXTEND, 0276, "movsxb",
0, EXTOP, 0002, "lar", 0, EXTOP, 0002, "lar",
0, EXTOP, 0003, "lsl", 0, EXTOP, 0003, "lsl",
0, EXTOP, 0274, "bsf", 0, EXTOP, 0274, "bsf",

View file

@ -78,7 +78,7 @@ oper : NOOP_1
| LSHFT ea_1 ',' R32 ',' ea_2 | LSHFT ea_1 ',' R32 ',' ea_2
{ extshft($1, $4);} { extshft($1, $4);}
| EXTEND R32 ',' ea_2 | EXTEND R32 ',' ea_2
{ emit1(0xF); emit1($1|1); ea_2($2<<3);} { emit1(0xF); emit1($1); ea_2($2<<3);}
| EXTOP R32 ',' ea_2 | EXTOP R32 ',' ea_2
{ emit1(0xF); emit1($1); ea_2($2<<3);} { emit1(0xF); emit1($1); ea_2($2<<3);}
| EXTOP1 ea_1 | EXTOP1 ea_1

View file

@ -14,13 +14,7 @@ ea_1(param) {
return; return;
} }
if (is_reg(reg_1)) { if (is_reg(reg_1)) {
switch(reg_1&07) { emit1(0300 | param | (reg_1&07));
case 4:
emit1(0300 | param | 04);
emit1(0300 | 0100);
default:
emit1(0300 | param | (reg_1&07));
}
return; return;
} }
if (rm_1 == 04) { if (rm_1 == 04) {
@ -142,6 +136,7 @@ ebranch(opc,exp)
register long dist; register long dist;
int saving = address_long ? 4 : 2; int saving = address_long ? 4 : 2;
if (opc == 0353) saving--;
dist = exp.val - (DOTVAL + 2); dist = exp.val - (DOTVAL + 2);
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT)) if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
dist -= DOTGAIN; dist -= DOTGAIN;
@ -149,14 +144,24 @@ ebranch(opc,exp)
if ((exp.typ & ~S_DOT) != DOTTYP) if ((exp.typ & ~S_DOT) != DOTTYP)
sm = 0; sm = 0;
if ((sm = small(sm,saving)) == 0) { if ((sm = small(sm,saving)) == 0) {
emit1(0xF); if (opc == 0353) {
emit1(opc | 0x80); emit1(0xe9);
dist -= 2; }
else {
emit1(0xF);
emit1(opc | 0x80);
}
dist -= saving;
exp.val = dist; exp.val = dist;
adsize_exp(exp); adsize_exp(exp, RELPC);
} }
else { else {
emit1(opc | 0x70); if (opc == 0353) {
emit1(opc);
}
else {
emit1(opc | 0x70);
}
emit1((int)dist); emit1((int)dist);
} }
} }
@ -237,12 +242,12 @@ opsize_exp(exp, nobyte)
} }
} }
adsize_exp(exp) adsize_exp(exp, relpc)
expr_t exp; expr_t exp;
{ {
if (address_long) { if (address_long) {
#ifdef RELOCATION #ifdef RELOCATION
newrelo(exp.typ, RELO4 | RELPC); newrelo(exp.typ, RELO4 | relpc);
#endif #endif
emit4((long)(exp.val)); emit4((long)(exp.val));
} }
@ -251,7 +256,7 @@ adsize_exp(exp)
warning("offset does not fit in 2 bytes; remove prefix"); warning("offset does not fit in 2 bytes; remove prefix");
} }
#ifdef RELOCATION #ifdef RELOCATION
newrelo(exp.typ, RELO2 | RELPC); newrelo(exp.typ, RELO2 | relpc);
#endif #endif
emit2((int)(exp.val)); emit2((int)(exp.val));
} }
@ -342,10 +347,10 @@ callop(opc)
RELOMOVE(relonami, rel_1); RELOMOVE(relonami, rel_1);
ebranch(0353,exp_1); ebranch(0353,exp_1);
} else { } else {
exp_1.val -= (DOTVAL+3); exp_1.val -= (DOTVAL+3 + (address_long ? 2 : 0));
emit1(opc>>8); emit1(opc>>8);
RELOMOVE(relonami, rel_1); RELOMOVE(relonami, rel_1);
adsize_exp(exp_1); adsize_exp(exp_1, RELPC);
} }
} else { } else {
emit1(0377); ea_1(opc&070); emit1(0377); ea_1(opc&070);
@ -419,12 +424,12 @@ mov(opc)
/* from accumulator to memory (displacement) */ /* from accumulator to memory (displacement) */
emit1(0242 | opc); emit1(0242 | opc);
RELOMOVE(relonami, rel_1); RELOMOVE(relonami, rel_1);
adsize_exp(exp_1); adsize_exp(exp_1, 0);
} else if (rm_2 == 05 && is_acc(reg_1)) { } else if (rm_2 == 05 && is_acc(reg_1)) {
/* from memory (displacement) to accumulator */ /* from memory (displacement) to accumulator */
emit1(0240 | opc); emit1(0240 | opc);
RELOMOVE(relonami, rel_2); RELOMOVE(relonami, rel_2);
adsize_exp(exp_2); adsize_exp(exp_2, 0);
} else if (is_reg(reg_2)) { } else if (is_reg(reg_2)) {
/* from register to memory or register */ /* from register to memory or register */
emit1(0210 | opc); ea_1((reg_2&7)<<3); emit1(0210 | opc); ea_1((reg_2&7)<<3);
@ -520,7 +525,7 @@ imul(reg)
if (reg == 0) { if (reg == 0) {
/* how lucky we are, the target is the ax register */ /* how lucky we are, the target is the ax register */
emit1(0367); emit1(0367);
ea_2(06 << 3); ea_2(050);
} }
else { else {
/* another register ... */ /* another register ... */