瀏覽代碼

+ added another helper tcgz80.a_jmp_signed_cmp_3way

git-svn-id: branches/z80@44979 -
nickysn 5 年之前
父節點
當前提交
ce8ed9efa8
共有 1 個文件被更改,包括 113 次插入0 次删除
  1. 113 0
      compiler/z80/cgcpu.pas

+ 113 - 0
compiler/z80/cgcpu.pas

@@ -87,6 +87,9 @@ unit cgcpu;
 
         { Z80-specific unsigned comparison code generation jmp helper }
         procedure a_jmp_unsigned_cmp_3way(list : TAsmList;onbelow,onequal,onabove: tasmlabel);
+        { Z80-specific signed comparison code generation jmp helper. Should follow a SUB instruction,
+          and the A register must still contain the result. }
+        procedure a_jmp_signed_cmp_3way(list : TAsmList;onless,onequal,ongreater: tasmlabel);
 
         procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister); override;
 
@@ -1752,6 +1755,116 @@ unit cgcpu;
           end;
       end;
 
+    procedure tcgz80.a_jmp_signed_cmp_3way(list: TAsmList; onless, onequal, ongreater: tasmlabel);
+      var
+        l, skiplabel: TAsmLabel;
+      begin
+        if      (onless= nil) and (onequal= nil) and (ongreater= nil) then
+          {nothing}
+        else if (onless= nil) and (onequal= nil) and (ongreater<>nil) then
+          begin
+            current_asmdata.getjumplabel(skiplabel);
+            a_jmp_flags(list,F_E,skiplabel);
+            current_asmdata.getjumplabel(l);
+            a_jmp_flags(list,F_PO,l);
+            current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+            cg.a_label(current_asmdata.CurrAsmList,l);
+            a_jmp_flags(list,F_P,ongreater);
+            cg.a_label(list,skiplabel);
+          end
+        else if (onless= nil) and (onequal<>nil) and (ongreater= nil) then
+          a_jmp_flags(list,F_E,onequal)
+        else if (onless= nil) and (onequal<>nil) and (ongreater<>nil) then
+          begin
+            if onequal<>ongreater then
+              a_jmp_flags(list,F_E,onequal);
+            current_asmdata.getjumplabel(l);
+            a_jmp_flags(list,F_PO,l);
+            current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+            cg.a_label(current_asmdata.CurrAsmList,l);
+            a_jmp_flags(list,F_P,ongreater);
+          end
+        else if (onless<>nil) and (onequal= nil) and (ongreater= nil) then
+          begin
+            current_asmdata.getjumplabel(l);
+            a_jmp_flags(list,F_PO,l);
+            current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+            cg.a_label(current_asmdata.CurrAsmList,l);
+            a_jmp_flags(list,F_M,onless);
+          end
+        else if (onless<>nil) and (onequal= nil) and (ongreater<>nil) then
+          begin
+            if onless=ongreater then
+              a_jmp_flags(list,F_NE,onless)
+            else
+              begin
+                current_asmdata.getjumplabel(skiplabel);
+                a_jmp_flags(list,F_E,skiplabel);
+                current_asmdata.getjumplabel(l);
+                a_jmp_flags(list,F_PO,l);
+                current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+                cg.a_label(current_asmdata.CurrAsmList,l);
+                a_jmp_flags(list,F_M,onless);
+                a_jmp_always(list,ongreater);
+                cg.a_label(list,skiplabel);
+              end;
+          end
+        else if (onless<>nil) and (onequal<>nil) and (ongreater= nil) then
+          begin
+            a_jmp_flags(list,F_E,onequal);
+            current_asmdata.getjumplabel(l);
+            a_jmp_flags(list,F_PO,l);
+            current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+            cg.a_label(current_asmdata.CurrAsmList,l);
+            a_jmp_flags(list,F_M,onless);
+          end
+        else if (onless<>nil) and (onequal<>nil) and (ongreater<>nil) then
+          begin
+            if (onless=onequal) and (onequal=ongreater) then
+              a_jmp_always(list,onless)
+            else if onequal=ongreater then
+              begin
+                current_asmdata.getjumplabel(l);
+                a_jmp_flags(list,F_PO,l);
+                current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+                cg.a_label(current_asmdata.CurrAsmList,l);
+                a_jmp_flags(list,F_M,onless);
+                a_jmp_always(list,ongreater);
+              end
+            else if onless=onequal then
+              begin
+                a_jmp_flags(list,F_E,onequal);
+                current_asmdata.getjumplabel(l);
+                a_jmp_flags(list,F_PO,l);
+                current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+                cg.a_label(current_asmdata.CurrAsmList,l);
+                a_jmp_flags(list,F_M,onless);
+                a_jmp_always(list,ongreater);
+              end
+            else if onless=ongreater then
+              begin
+                a_jmp_flags(list,F_E,onequal);
+                a_jmp_always(list,ongreater);
+              end
+            else
+              begin
+                { the generic case - all 3 are different labels }
+                a_jmp_flags(list,F_E,onequal);
+                current_asmdata.getjumplabel(l);
+                a_jmp_flags(list,F_PO,l);
+                current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
+                cg.a_label(current_asmdata.CurrAsmList,l);
+                a_jmp_flags(list,F_M,onless);
+                a_jmp_always(list,ongreater);
+              end;
+          end
+        else
+          begin
+            { Shouldn't happen! All possible combinations are handled by the above code. }
+            internalerror(2020042204);
+          end;
+      end;
+
 
     procedure tcgz80.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
       var