ソースを参照

m68k: generate smarter shifting/rotation code on 68k, for example by utilizing the SWAP instruction

git-svn-id: trunk@28617 -
Károly Balogh 11 年 前
コミット
d561e8ab57
2 ファイル変更28 行追加2 行削除
  1. 1 1
      compiler/m68k/aasmcpu.pas
  2. 27 1
      compiler/m68k/cgcpu.pas

+ 1 - 1
compiler/m68k/aasmcpu.pas

@@ -479,7 +479,7 @@ type
           A_CLR, A_SXX, A_SEQ, A_SNE, A_SLT, A_SLE, A_SGT, A_SGE, A_SCS, A_SCC,
           A_SMI, A_SPL, A_SF, A_ST, A_SVS, A_SVC, A_SHI, A_SLS:
             result:=operand_write;
-          A_NEG, A_NEGX, A_EXT, A_EXTB, A_NOT:
+          A_NEG, A_NEGX, A_EXT, A_EXTB, A_NOT, A_SWAP:
             result:=operand_readwrite;
           A_TST,A_CMP,A_CMPI:
             begin end; { Do nothing, default operand_read is fine here. }

+ 27 - 1
compiler/m68k/cgcpu.pas

@@ -1123,10 +1123,36 @@ unit cgcpu;
               begin
                 scratch_reg := force_to_dataregister(list, size, reg);
                 sign_extend(list, size, scratch_reg);
-                if (a >= 1) and (a <= 8) then
+
+                { some special cases which can generate smarter code 
+                  using the SWAP instruction }
+                if (a = 16) then
+                  begin
+                    if (op = OP_SHL) then
+                      begin
+                        list.concat(taicpu.op_reg(A_SWAP,S_NO,scratch_reg));
+                        list.concat(taicpu.op_reg(A_CLR,S_W,scratch_reg));
+                      end
+                    else if (op = OP_SHR) then
+                      begin
+                        list.concat(taicpu.op_reg(A_CLR,S_W,scratch_reg));
+                        list.concat(taicpu.op_reg(A_SWAP,S_NO,scratch_reg));
+                      end
+                    else if (op = OP_ROR) or (op = OP_ROL) then
+                      list.concat(taicpu.op_reg(A_SWAP,S_NO,scratch_reg))
+                  end
+                else if (a >= 1) and (a <= 8) then
                   begin
                     list.concat(taicpu.op_const_reg(opcode, S_L, a, scratch_reg));
                   end
+                else if (a >= 9) and (a < 16) then
+                  begin
+                    { Use two ops instead of const -> reg + shift with reg, because
+                      this way is the same in length and speed but has less register
+                      pressure }
+                    list.concat(taicpu.op_const_reg(opcode, S_L, 8, scratch_reg));
+                    list.concat(taicpu.op_const_reg(opcode, S_L, a-8, scratch_reg));
+                  end
                 else
                   begin
                     { move const to a register first }