Преглед изворни кода

riscv32: Fix 64bit comparisons

- Code taken from MIPS backend
- Removed some unused code generated for RV32 64bit integer ops
Jeppe пре 2 година
родитељ
комит
c83e6c34a9
2 измењених фајлова са 109 додато и 6 уклоњено
  1. 0 4
      compiler/riscv32/cgcpu.pas
  2. 109 2
      compiler/riscv32/nrv32add.pas

+ 0 - 4
compiler/riscv32/cgcpu.pas

@@ -383,8 +383,6 @@ unit cgcpu;
                   list.concat(taicpu.op_reg_reg_reg(A_SUB, carry, hreg, carry));
                   list.concat(taicpu.op_reg_reg_reg(A_SUB, carry, hreg, carry));
                   // then add another addend
                   // then add another addend
                   list.concat(taicpu.op_reg_reg_reg(A_ADD, regdst.reghi, tmphi, regsrc1.reghi));
                   list.concat(taicpu.op_reg_reg_reg(A_ADD, regdst.reghi, tmphi, regsrc1.reghi));
-                  list.concat(taicpu.op_reg_reg_reg(A_SLTU, carry, regdst.reghi, tmphi));
-                  list.concat(taicpu.op_reg_reg_reg(A_SUB, carry, hreg, carry));
                 end;
                 end;
             end;
             end;
           OP_SUB:
           OP_SUB:
@@ -412,8 +410,6 @@ unit cgcpu;
                   list.concat(taicpu.op_reg_reg_reg(A_SUB, carry, hreg, carry));
                   list.concat(taicpu.op_reg_reg_reg(A_SUB, carry, hreg, carry));
                   // ...then the subtrahend
                   // ...then the subtrahend
                   list.concat(taicpu.op_reg_reg_reg(A_SUB, regdst.reghi, tmphi, regsrc1.reghi));
                   list.concat(taicpu.op_reg_reg_reg(A_SUB, regdst.reghi, tmphi, regsrc1.reghi));
-                  list.concat(taicpu.op_reg_reg_reg(A_SLTU, carry, tmphi, regdst.reghi));
-                  list.concat(taicpu.op_reg_reg_reg(A_SUB, carry, hreg, carry));
                 end;
                 end;
             end;
             end;
           else
           else

+ 109 - 2
compiler/riscv32/nrv32add.pas

@@ -26,12 +26,18 @@ unit nrv32add;
   interface
   interface
 
 
     uses
     uses
-      node, ncgadd, aasmbase, nrvadd, cpubase;
+      node, ncgadd, aasmbase, nrvadd, cpubase,
+      cgbase;
 
 
     type
     type
       trv32addnode = class(trvaddnode)
       trv32addnode = class(trvaddnode)
+      private
+        procedure cmp64_le(left_reg, right_reg: TRegister64; unsigned: boolean);
+        procedure cmp64_lt(left_reg, right_reg: TRegister64; unsigned: boolean);
       protected
       protected
         function use_generic_mul32to64: boolean; override;
         function use_generic_mul32to64: boolean; override;
+
+        procedure second_cmp64bit; override;
       end;
       end;
 
 
   implementation
   implementation
@@ -41,16 +47,117 @@ unit nrv32add;
       cutils,verbose,
       cutils,verbose,
       paramgr,procinfo,
       paramgr,procinfo,
       aasmtai,aasmdata,aasmcpu,defutil,
       aasmtai,aasmdata,aasmcpu,defutil,
-      cgbase,cgcpu,cgutils,nadd,
+      cgcpu,cgutils,nadd,
       cpupara,
       cpupara,
       ncon,nset,
       ncon,nset,
       hlcgobj, ncgutil,cgobj;
       hlcgobj, ncgutil,cgobj;
 
 
+    const
+      cmpops: array[boolean] of TOpCmp = (OC_LT,OC_B);
+
+    procedure trv32addnode.cmp64_lt(left_reg, right_reg: TRegister64;unsigned: boolean);
+      begin
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cmpops[unsigned],right_reg.reghi,left_reg.reghi,location.truelabel);
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.falselabel);
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_B,right_reg.reglo,left_reg.reglo,location.truelabel);
+        cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
+      end;
+
+
+    procedure trv32addnode.cmp64_le(left_reg, right_reg: TRegister64;unsigned: boolean);
+      begin
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cmpops[unsigned],left_reg.reghi,right_reg.reghi,location.falselabel);
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.truelabel);
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_B,left_reg.reglo,right_reg.reglo,location.falselabel);
+        cg.a_jmp_always(current_asmdata.CurrAsmList,location.truelabel);
+      end;
+
     function trv32addnode.use_generic_mul32to64: boolean;
     function trv32addnode.use_generic_mul32to64: boolean;
       begin
       begin
         result:=true;
         result:=true;
       end;
       end;
 
 
+    procedure trv32addnode.second_cmp64bit;
+      var
+        truelabel,
+        falselabel: tasmlabel;
+        unsigned: boolean;
+        left_reg,right_reg: TRegister64;
+      begin
+        current_asmdata.getjumplabel(truelabel);
+        current_asmdata.getjumplabel(falselabel);
+        location_reset_jump(location,truelabel,falselabel);
+
+        pass_left_right;
+        force_reg_left_right(true,true);
+
+        unsigned:=not(is_signed(left.resultdef)) or
+                  not(is_signed(right.resultdef));
+
+        left_reg:=left.location.register64;
+        if (right.location.loc=LOC_CONSTANT) then
+          begin
+            if lo(right.location.value64)=0 then
+              right_reg.reglo:=NR_X0
+            else
+              begin
+                right_reg.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+                cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,lo(right.location.value64),right_reg.reglo);
+              end;
+            if hi(right.location.value64)=0 then
+              right_reg.reghi:=NR_X0
+            else
+              begin
+                right_reg.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+                cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,hi(right.location.value64),right_reg.reghi);
+              end;
+          end
+        else
+          right_reg:=right.location.register64;
+
+        case NodeType of
+          equaln:
+            begin
+              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.falselabel);
+              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,location.falselabel);
+              cg.a_jmp_always(current_asmdata.CurrAsmList,location.truelabel);
+            end;
+          unequaln:
+            begin
+              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.truelabel);
+              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,location.truelabel);
+              cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
+            end;
+        else
+          if nf_swapped in flags then
+            case NodeType of
+              ltn:
+                cmp64_lt(right_reg, left_reg,unsigned);
+              lten:
+                cmp64_le(right_reg, left_reg,unsigned);
+              gtn:
+                cmp64_lt(left_reg, right_reg,unsigned);
+              gten:
+                cmp64_le(left_reg, right_reg,unsigned);
+              else
+                internalerror(2019051034);
+            end
+          else
+            case NodeType of
+              ltn:
+                cmp64_lt(left_reg, right_reg,unsigned);
+              lten:
+                cmp64_le(left_reg, right_reg,unsigned);
+              gtn:
+                cmp64_lt(right_reg, left_reg,unsigned);
+              gten:
+                cmp64_le(right_reg, left_reg,unsigned);
+              else
+                internalerror(2019051033);
+            end;
+        end;
+      end;
+
 begin
 begin
    caddnode:=trv32addnode;
    caddnode:=trv32addnode;
 end.
 end.