+ added 8086 workaround for the 'imul reg,const' 186+ instruction. The compiler can now generate strict 8086/8088 code.

git-svn-id: trunk@24404 -
This commit is contained in:
nickysn 2013-05-01 19:18:12 +00:00
parent 3ad0de732e
commit 4527fe8fa2

View File

@ -160,6 +160,7 @@ unit cgcpu;
var
tmpreg: tregister;
op1, op2: TAsmOp;
ax_subreg: tregister;
begin
optimize_op_const(op, a);
check_register_size(size,reg);
@ -212,7 +213,53 @@ unit cgcpu;
end;
end
else
inherited a_op_const_reg(list, Op, size, a, reg);
begin
{ size <= 16-bit }
{ 8086 doesn't support 'imul reg,const', so we handle it here }
if (current_settings.cputype<cpu_186) and (op in [OP_MUL,OP_IMUL]) then
begin
{ TODO: also enable the SHL optimization below }
{ if not(cs_check_overflow in current_settings.localswitches) and
ispowerof2(int64(a),power) then
begin
list.concat(taicpu.op_const_reg(A_SHL,TCgSize2OpSize[size],power,reg));
exit;
end;}
if op = OP_IMUL then
begin
if size in [OS_16,OS_S16] then
ax_subreg := NR_AX
else
if size in [OS_8,OS_S8] then
ax_subreg := NR_AL
else
internalerror(2013050102);
getcpuregister(list,NR_AX);
if size in [OS_16,OS_S16] then
getcpuregister(list,NR_DX);
a_load_const_reg(list,size,a,ax_subreg);
list.concat(taicpu.op_reg(A_IMUL,TCgSize2OpSize[size],reg));
a_load_reg_reg(list,size,size,ax_subreg,reg);
ungetcpuregister(list,NR_AX);
if size in [OS_16,OS_S16] then
ungetcpuregister(list,NR_DX);
{ TODO: implement overflow checking? }
exit;
end
else
{ OP_MUL should be handled specifically in the code }
{ generator because of the silly register usage restraints }
internalerror(200109225);
end
else
inherited a_op_const_reg(list, Op, size, a, reg);
end;
end;