* fixes and improvements in tcg8086.a_load_reg_reg for the case when the src and

dest are subregisters of the same superregister, but of different sizes:
   o Do not emit spurious moves from a register to the same register.
   o Correctly support the case when converting from 16-bit to 32-bit int.
     Previously it didn't work correctly, because in this particular case, due
     to the way the GetNextReg scheme works, we have reg1=reg2.

git-svn-id: trunk@26313 -
This commit is contained in:
nickysn 2013-12-29 17:15:58 +00:00
parent 4e795eca99
commit 6d48b32115

View File

@ -1246,12 +1246,15 @@ unit cgcpu;
fromsize:=tosize; fromsize:=tosize;
end; end;
if (reg1<>reg2) then if (reg1<>reg2) or (fromsize<>tosize) then
begin begin
case tosize of case tosize of
OS_8,OS_S8: OS_8,OS_S8:
if fromsize in [OS_8,OS_S8] then if fromsize in [OS_8,OS_S8] then
add_mov(taicpu.op_reg_reg(A_MOV, S_B, reg1, reg2)) begin
if reg1<>reg2 then
add_mov(taicpu.op_reg_reg(A_MOV, S_B, reg1, reg2));
end
else else
internalerror(2013030210); internalerror(2013030210);
OS_16,OS_S16: OS_16,OS_S16:
@ -1259,7 +1262,8 @@ unit cgcpu;
OS_8: OS_8:
begin begin
reg2 := makeregsize(list, reg2, OS_8); reg2 := makeregsize(list, reg2, OS_8);
add_mov(taicpu.op_reg_reg(A_MOV, S_B, reg1, reg2)); if reg1<>reg2 then
add_mov(taicpu.op_reg_reg(A_MOV, S_B, reg1, reg2));
setsubreg(reg2,R_SUBH); setsubreg(reg2,R_SUBH);
list.concat(taicpu.op_const_reg(A_MOV, S_B, 0, reg2)); list.concat(taicpu.op_const_reg(A_MOV, S_B, 0, reg2));
end; end;
@ -1272,7 +1276,10 @@ unit cgcpu;
ungetcpuregister(list, NR_AX); ungetcpuregister(list, NR_AX);
end; end;
OS_16,OS_S16: OS_16,OS_S16:
add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, reg2)); begin
if reg1<>reg2 then
add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, reg2));
end
else else
internalerror(2013030212); internalerror(2013030212);
end; end;
@ -1282,7 +1289,8 @@ unit cgcpu;
begin begin
list.concat(taicpu.op_const_reg(A_MOV, S_W, 0, GetNextReg(reg2))); list.concat(taicpu.op_const_reg(A_MOV, S_W, 0, GetNextReg(reg2)));
reg2 := makeregsize(list, reg2, OS_8); reg2 := makeregsize(list, reg2, OS_8);
add_mov(taicpu.op_reg_reg(A_MOV, S_B, reg1, reg2)); if reg1<>reg2 then
add_mov(taicpu.op_reg_reg(A_MOV, S_B, reg1, reg2));
setsubreg(reg2,R_SUBH); setsubreg(reg2,R_SUBH);
list.concat(taicpu.op_const_reg(A_MOV, S_B, 0, reg2)); list.concat(taicpu.op_const_reg(A_MOV, S_B, 0, reg2));
end; end;
@ -1300,7 +1308,8 @@ unit cgcpu;
end; end;
OS_16: OS_16:
begin begin
add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, reg2)); if reg1<>reg2 then
add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, reg2));
list.concat(taicpu.op_const_reg(A_MOV,S_W,0,GetNextReg(reg2))); list.concat(taicpu.op_const_reg(A_MOV,S_W,0,GetNextReg(reg2)));
end; end;
OS_S16: OS_S16:
@ -1309,15 +1318,19 @@ unit cgcpu;
add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, NR_AX)); add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, NR_AX));
getcpuregister(list, NR_DX); getcpuregister(list, NR_DX);
list.concat(taicpu.op_none(A_CWD)); list.concat(taicpu.op_none(A_CWD));
add_mov(taicpu.op_reg_reg(A_MOV, S_W, NR_AX, reg2)); if reg1<>reg2 then
add_mov(taicpu.op_reg_reg(A_MOV, S_W, NR_AX, reg2));
ungetcpuregister(list, NR_AX); ungetcpuregister(list, NR_AX);
add_mov(taicpu.op_reg_reg(A_MOV, S_W, NR_DX, GetNextReg(reg2))); add_mov(taicpu.op_reg_reg(A_MOV, S_W, NR_DX, GetNextReg(reg2)));
ungetcpuregister(list, NR_DX); ungetcpuregister(list, NR_DX);
end; end;
OS_32,OS_S32: OS_32,OS_S32:
begin begin
add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, reg2)); if reg1<>reg2 then
add_mov(taicpu.op_reg_reg(A_MOV, S_W, GetNextReg(reg1), GetNextReg(reg2))); begin
add_mov(taicpu.op_reg_reg(A_MOV, S_W, reg1, reg2));
add_mov(taicpu.op_reg_reg(A_MOV, S_W, GetNextReg(reg1), GetNextReg(reg2)));
end;
end; end;
else else
internalerror(2013030213); internalerror(2013030213);