bug fix: cannot optimize IMUL

This commit is contained in:
ceriel 1990-01-10 11:23:45 +00:00
parent abcaa3e669
commit 776f85238f
2 changed files with 13 additions and 6 deletions

View file

@ -88,9 +88,9 @@ oper : NOOP_1
| IMUL ea_2 | IMUL ea_2
{ reg_1 = IS_R32; imul(0); } { reg_1 = IS_R32; imul(0); }
| IMUL R32 ',' ea_2 | IMUL R32 ',' ea_2
{ reg_1 = $2 | IS_R32; imul($2); } { reg_1 = $2 | IS_R32; imul($2|0x10); }
| IMUL R32 ',' ea_ea | IMUL R32 ',' ea_ea
{ imul($2);} { imul($2|0x10);}
| INT absexp | INT absexp
{ if ($2==3) { if ($2==3)
emit1(0314); emit1(0314);

View file

@ -507,23 +507,30 @@ imul(reg)
if (exp_2.typ == S_ABS && fitb(exp_2.val)) { if (exp_2.typ == S_ABS && fitb(exp_2.val)) {
/* case 1: 1 byte encoding of immediate */ /* case 1: 1 byte encoding of immediate */
emit1(0153); emit1(0153);
ea_1(reg << 3); ea_1((reg & 07) << 3);
emit1((int)(exp_2.val)); emit1((int)(exp_2.val));
} }
else { else {
/* case 2: WORD or DWORD encoding of immediate */ /* case 2: WORD or DWORD encoding of immediate */
emit1(0151); emit1(0151);
ea_1(reg << 3); ea_1((reg & 07) << 3);
RELOMOVE(relonami, rel_2); RELOMOVE(relonami, rel_2);
opsize_exp(exp_2, 1); opsize_exp(exp_2, 1);
} }
} }
else if (is_reg(reg_1) && ((reg_1&7) == reg)) { else if (is_reg(reg_1) && ((reg_1&7) == (reg & 07))) {
/* the "reg" field and the "reg_or_mem" field are the same, /* the "reg" field and the "reg_or_mem" field are the same,
and the 3rd operand is not an immediate ... and the 3rd operand is not an immediate ...
*/ */
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 */
/* However, we cannot make an optimization for f.i.
imul eax, blablabla
because the latter does not affect edx, whereas
imul blablabla
does! Therefore, "reg" is or-ed with 0x10 in the
former case, so that the test above fails.
*/
emit1(0367); emit1(0367);
ea_2(050); ea_2(050);
} }
@ -531,7 +538,7 @@ imul(reg)
/* another register ... */ /* another register ... */
emit1(0xF); emit1(0xF);
emit1(0257); emit1(0257);
ea_2(reg << 3); ea_2((reg & 07) << 3);
} }
} }
else badsyntax(); else badsyntax();