Browse Source

* 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 -

nickysn 11 years ago
parent
commit
6d48b32115
1 changed files with 22 additions and 9 deletions
  1. 22 9
      compiler/i8086/cgcpu.pas

+ 22 - 9
compiler/i8086/cgcpu.pas

@@ -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));
-                      add_mov(taicpu.op_reg_reg(A_MOV, S_W, GetNextReg(reg1), GetNextReg(reg2)));
+                      if reg1<>reg2 then
+                        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);