Fixed 16-bit address mode bugs
This commit is contained in:
parent
0b95807664
commit
71156a48ae
3 changed files with 39 additions and 33 deletions
|
@ -25,7 +25,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) != 0 && ((reg)&(IS_R8|IS_R32)) == (reg))
|
#define is_acc(reg) (is_reg(reg) && ((reg & 07) == 0))
|
||||||
|
|
||||||
struct operand {
|
struct operand {
|
||||||
int mod;
|
int mod;
|
||||||
|
|
|
@ -102,9 +102,13 @@ oper : NOOP_1
|
||||||
| IMULB ea_1
|
| IMULB ea_1
|
||||||
{ regsize(0); emit1(0366); ea_1($1&070);}
|
{ regsize(0); emit1(0366); ea_1($1&070);}
|
||||||
| IMUL ea_2
|
| IMUL ea_2
|
||||||
{ reg_1 = IS_R32; imul(0); }
|
{ reg_1 = IS_R32 | (address_long ? 0 : 0310);
|
||||||
|
imul(0);
|
||||||
|
}
|
||||||
| IMUL R32 ',' ea_2
|
| IMUL R32 ',' ea_2
|
||||||
{ reg_1 = $2 | IS_R32; imul($2|0x10); }
|
{ reg_1 = $2 | IS_R32 | (address_long ? 0 : 0310);
|
||||||
|
imul($2|0x10);
|
||||||
|
}
|
||||||
| IMUL R32 ',' ea_ea
|
| IMUL R32 ',' ea_ea
|
||||||
{ imul($2|0x10);}
|
{ imul($2|0x10);}
|
||||||
| INT absexp
|
| INT absexp
|
||||||
|
@ -196,12 +200,10 @@ st_i : ST '(' absexp ')'
|
||||||
|
|
||||||
;
|
;
|
||||||
mem : '(' expr ')'
|
mem : '(' expr ')'
|
||||||
{ if (address_long) {
|
{ if (address_long) reg_2 = 05;
|
||||||
rm_2 = 05; reg_2 = 05; mod_2 = 0;
|
else reg_2 = 06;
|
||||||
}
|
mod_2 = 0;
|
||||||
else {
|
rm_2 = 05;
|
||||||
reg_2 = 06;
|
|
||||||
}
|
|
||||||
exp_2 = $2;
|
exp_2 = $2;
|
||||||
RELOMOVE(rel_2, relonami);
|
RELOMOVE(rel_2, relonami);
|
||||||
|
|
||||||
|
@ -214,20 +216,15 @@ mem : '(' expr ')'
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
bases : '(' R32 ')'
|
bases : '(' R32 ')'
|
||||||
{ if (address_long) {
|
{ if (address_long) reg_2 = $2;
|
||||||
reg_2 = $2; sib_2 = 0; rm_2 = 0;
|
|
||||||
}
|
|
||||||
else reg_2 = sr_m[$2];
|
else reg_2 = sr_m[$2];
|
||||||
|
sib_2 = 0; rm_2 = 0;
|
||||||
}
|
}
|
||||||
| '(' R32 ')' '(' R32 scale ')'
|
| '(' R32 ')' '(' R32 scale ')'
|
||||||
{ if (address_long) {
|
{ if (address_long) reg_2 = $2;
|
||||||
rm_2 = 04;
|
else reg_2 = dr_m[$2][$5];
|
||||||
sib_2 |= regindex_ind[$2][$5];
|
rm_2 = 04;
|
||||||
reg_2 = $2;
|
sib_2 |= regindex_ind[$2][$5];
|
||||||
}
|
|
||||||
else {
|
|
||||||
reg_2 = dr_m[$2][$5];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
| '(' R32 '*' absexp ')'
|
| '(' R32 '*' absexp ')'
|
||||||
{ if ($4 == 1) {
|
{ if ($4 == 1) {
|
||||||
|
@ -247,13 +244,20 @@ scale : /* empty */
|
||||||
;
|
;
|
||||||
ea_2 : mem
|
ea_2 : mem
|
||||||
| R8
|
| R8
|
||||||
{ reg_2 = $1 | IS_R8; rm_2 = 0;}
|
{ reg_2 = ($1 | IS_R8) | (address_long ? 0 : 0300);
|
||||||
|
rm_2 = 0;
|
||||||
|
}
|
||||||
| R32
|
| R32
|
||||||
{ reg_2 = $1 | IS_R32; rm_2 = 0;}
|
{ reg_2 = ($1 | IS_R32) | (address_long ? 0 : 0310);
|
||||||
|
rm_2 = 0;
|
||||||
|
}
|
||||||
| RSEG
|
| RSEG
|
||||||
{ reg_2 = $1 | IS_RSEG; rm_2 = 0;}
|
{ reg_2 = ($1 | IS_RSEG) | (address_long ? 0 : 020);
|
||||||
|
rm_2 = 0;
|
||||||
|
}
|
||||||
| expr
|
| expr
|
||||||
{ reg_2 = IS_EXPR; exp_2 = $1; rm_2 = 0;
|
{ reg_2 = IS_EXPR | (address_long ? 0 : 040);
|
||||||
|
exp_2 = $1; rm_2 = 0;
|
||||||
RELOMOVE(rel_2, relonami);
|
RELOMOVE(rel_2, relonami);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
ea_1_16(param)
|
ea_1_16(param)
|
||||||
{
|
{
|
||||||
|
reg_1 &= 0377;
|
||||||
if ((reg_1 & 070) || (param & ~070)) {
|
if ((reg_1 & 070) || (param & ~070)) {
|
||||||
serror("bad operand");
|
serror("bad operand");
|
||||||
}
|
}
|
||||||
|
@ -127,6 +128,10 @@ regsize(sz)
|
||||||
if ((is_reg(reg_1) && (reg_1 & IS_R8) != bit) ||
|
if ((is_reg(reg_1) && (reg_1 & IS_R8) != bit) ||
|
||||||
(is_reg(reg_2) && (reg_2 & IS_R8) != bit))
|
(is_reg(reg_2) && (reg_2 & IS_R8) != bit))
|
||||||
serror("register error");
|
serror("register error");
|
||||||
|
if (! address_long) {
|
||||||
|
reg_1 &= ~010;
|
||||||
|
reg_2 &= ~010;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
indexed() {
|
indexed() {
|
||||||
|
@ -292,9 +297,6 @@ adsize_exp(exp, relpc)
|
||||||
emit4((long)(exp.val));
|
emit4((long)(exp.val));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (! fitw(exp.val) && pass == PASS_3) {
|
|
||||||
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
|
||||||
|
@ -344,7 +346,7 @@ rolop(opc)
|
||||||
oreg = reg_2;
|
oreg = reg_2;
|
||||||
reg_2 = reg_1;
|
reg_2 = reg_1;
|
||||||
regsize(opc);
|
regsize(opc);
|
||||||
if (oreg == (IS_R8 | 1)) {
|
if (oreg == (IS_R8 | 1 | (address_long ? 0 : 0300))) {
|
||||||
/* cl register */
|
/* cl register */
|
||||||
emit1(0322 | (opc&1)); ea_1(opc&070);
|
emit1(0322 | (opc&1)); ea_1(opc&070);
|
||||||
} else if (is_expr(oreg) && exp_2.typ == S_ABS && exp_2.val == 1) {
|
} else if (is_expr(oreg) && exp_2.typ == S_ABS && exp_2.val == 1) {
|
||||||
|
@ -446,10 +448,10 @@ mov(opc)
|
||||||
regsize(opc);
|
regsize(opc);
|
||||||
if (is_segreg(reg_1)) {
|
if (is_segreg(reg_1)) {
|
||||||
/* to segment register */
|
/* to segment register */
|
||||||
emit1(0216); ea_2((reg_1&3)<<3);
|
emit1(0216); ea_2((reg_1&07)<<3);
|
||||||
} else if (is_segreg(reg_2)) {
|
} else if (is_segreg(reg_2)) {
|
||||||
/* from segment register */
|
/* from segment register */
|
||||||
emit1(0214); ea_1((reg_2&3)<<3);
|
emit1(0214); ea_1((reg_2&07)<<3);
|
||||||
} else if (is_expr(reg_2)) {
|
} else if (is_expr(reg_2)) {
|
||||||
/* from immediate */
|
/* from immediate */
|
||||||
if (is_reg(reg_1)) {
|
if (is_reg(reg_1)) {
|
||||||
|
@ -473,10 +475,10 @@ mov(opc)
|
||||||
adsize_exp(exp_2, 0);
|
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&07)<<3);
|
||||||
} else if (is_reg(reg_1)) {
|
} else if (is_reg(reg_1)) {
|
||||||
/* from memory or register to register */
|
/* from memory or register to register */
|
||||||
emit1(0212 | opc); ea_2((reg_1&7)<<3);
|
emit1(0212 | opc); ea_2((reg_1&07)<<3);
|
||||||
} else
|
} else
|
||||||
badsyntax();
|
badsyntax();
|
||||||
}
|
}
|
||||||
|
@ -490,7 +492,7 @@ extshft(opc, reg)
|
||||||
regsize(1);
|
regsize(1);
|
||||||
|
|
||||||
emit1(0xF);
|
emit1(0xF);
|
||||||
if (oreg2 == (IS_R8 | 1)) {
|
if (oreg2 == (IS_R8 | 1 | (address_long ? 0 : 0300))) {
|
||||||
/* cl register */
|
/* cl register */
|
||||||
emit1(opc|1);
|
emit1(opc|1);
|
||||||
ea_1(reg << 3);
|
ea_1(reg << 3);
|
||||||
|
|
Loading…
Reference in a new issue