#define is_expr(reg) ((reg)&IS_EXPR)
#define is_segreg(reg) ((reg)&IS_RSEG)
#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 {
int mod;
| IMULB ea_1
{ regsize(0); emit1(0366); ea_1($1&070);}
| IMUL ea_2
- { reg_1 = IS_R32; imul(0); }
+ { reg_1 = IS_R32 | (address_long ? 0 : 0310);
+ imul(0);
+ }
| 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($2|0x10);}
| INT absexp
;
mem : '(' expr ')'
- { if (address_long) {
- rm_2 = 05; reg_2 = 05; mod_2 = 0;
- }
- else {
- reg_2 = 06;
- }
+ { if (address_long) reg_2 = 05;
+ else reg_2 = 06;
+ mod_2 = 0;
+ rm_2 = 05;
exp_2 = $2;
RELOMOVE(rel_2, relonami);
}
;
bases : '(' R32 ')'
- { if (address_long) {
- reg_2 = $2; sib_2 = 0; rm_2 = 0;
- }
+ { if (address_long) reg_2 = $2;
else reg_2 = sr_m[$2];
+ sib_2 = 0; rm_2 = 0;
}
| '(' R32 ')' '(' R32 scale ')'
- { if (address_long) {
- rm_2 = 04;
- sib_2 |= regindex_ind[$2][$5];
- reg_2 = $2;
- }
- else {
- reg_2 = dr_m[$2][$5];
- }
+ { if (address_long) reg_2 = $2;
+ else reg_2 = dr_m[$2][$5];
+ rm_2 = 04;
+ sib_2 |= regindex_ind[$2][$5];
}
| '(' R32 '*' absexp ')'
{ if ($4 == 1) {
;
ea_2 : mem
| R8
- { reg_2 = $1 | IS_R8; rm_2 = 0;}
+ { reg_2 = ($1 | IS_R8) | (address_long ? 0 : 0300);
+ rm_2 = 0;
+ }
| R32
- { reg_2 = $1 | IS_R32; rm_2 = 0;}
+ { reg_2 = ($1 | IS_R32) | (address_long ? 0 : 0310);
+ rm_2 = 0;
+ }
| RSEG
- { reg_2 = $1 | IS_RSEG; rm_2 = 0;}
+ { reg_2 = ($1 | IS_RSEG) | (address_long ? 0 : 020);
+ rm_2 = 0;
+ }
| 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);
}
;
ea_1_16(param)
{
+ reg_1 &= 0377;
if ((reg_1 & 070) || (param & ~070)) {
serror("bad operand");
}
if ((is_reg(reg_1) && (reg_1 & IS_R8) != bit) ||
(is_reg(reg_2) && (reg_2 & IS_R8) != bit))
serror("register error");
+ if (! address_long) {
+ reg_1 &= ~010;
+ reg_2 &= ~010;
+ }
}
indexed() {
emit4((long)(exp.val));
}
else {
- if (! fitw(exp.val) && pass == PASS_3) {
- warning("offset does not fit in 2 bytes; remove prefix");
- }
#ifdef RELOCATION
newrelo(exp.typ, RELO2 | relpc);
#endif
oreg = reg_2;
reg_2 = reg_1;
regsize(opc);
- if (oreg == (IS_R8 | 1)) {
+ if (oreg == (IS_R8 | 1 | (address_long ? 0 : 0300))) {
/* cl register */
emit1(0322 | (opc&1)); ea_1(opc&070);
} else if (is_expr(oreg) && exp_2.typ == S_ABS && exp_2.val == 1) {
regsize(opc);
if (is_segreg(reg_1)) {
/* 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)) {
/* 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)) {
/* from immediate */
if (is_reg(reg_1)) {
adsize_exp(exp_2, 0);
} else if (is_reg(reg_2)) {
/* 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)) {
/* 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
badsyntax();
}
regsize(1);
emit1(0xF);
- if (oreg2 == (IS_R8 | 1)) {
+ if (oreg2 == (IS_R8 | 1 | (address_long ? 0 : 0300))) {
/* cl register */
emit1(opc|1);
ea_1(reg << 3);