Jelajahi Sumber

Changed order in stack unravelling RTL code, to match the most common cases.
Fixed unsigned conditions for branch conditions.
Added some additional const loading cases.
Changed the temporary register used during calls because it could otherwise clash with the argument passing registers.

git-svn-id: branches/laksen/riscv_new@39492 -

Jeppe Johansen 7 tahun lalu
induk
melakukan
b98eb3daa9
3 mengubah file dengan 60 tambahan dan 56 penghapusan
  1. 41 51
      compiler/riscv/cgrv.pas
  2. 17 3
      compiler/riscv64/cgcpu.pas
  3. 2 2
      rtl/riscv64/riscv64.inc

+ 41 - 51
compiler/riscv/cgrv.pas

@@ -76,7 +76,7 @@ unit cgrv;
 
   const
     TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_NONE,
-                         C_LT,C_GE,C_None,C_NE,C_NONE,C_LT,C_GE,C_NONE);         
+                         C_LT,C_GE,C_None,C_NE,C_NONE,C_LTU,C_GEU,C_NONE);
 
   const
     TOpCG2AsmConstOp: Array[topcg] of TAsmOp = (A_NONE,
@@ -98,7 +98,6 @@ unit cgrv;
 
     procedure tcgrv.a_call_name(list : TAsmList;const s : string; weak: boolean);
       var
-        tmpreg: TRegister;
         href: treference;
         l: TAsmLabel;
       begin
@@ -107,26 +106,20 @@ unit cgrv;
         else
           reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(s,AT_FUNCTION),0,0,[]);
 
-        tmpreg:=getintregister(list,OS_ADDR);
-
         current_asmdata.getjumplabel(l);
 
         a_label(list,l);
 
         href.refaddr:=addr_pcrel_hi20;
-        list.concat(taicpu.op_reg_ref(A_AUIPC,tmpreg,href));
+        list.concat(taicpu.op_reg_ref(A_AUIPC,NR_RETURN_ADDRESS_REG,href));
 
         reference_reset_symbol(href,l,0,0,[]);
         href.refaddr:=addr_pcrel_lo12;
-        list.concat(taicpu.op_reg_reg_ref(A_JALR,NR_RETURN_ADDRESS_REG,tmpreg,href));
-
-         {if not(weak) then
-           list.concat(taicpu.op_reg_sym(A_JAL,NR_RETURN_ADDRESS_REG,current_asmdata.RefAsmSymbol(s,AT_FUNCTION)))
-         else
-           list.concat(taicpu.op_reg_sym(A_JAL,NR_RETURN_ADDRESS_REG,current_asmdata.WeakRefAsmSymbol(s,AT_FUNCTION)));}
-       { not assigned while generating external wrappers }
-       if assigned(current_procinfo) then
-         include(current_procinfo.flags,pi_do_call);
+        list.concat(taicpu.op_reg_reg_ref(A_JALR,NR_RETURN_ADDRESS_REG,NR_RETURN_ADDRESS_REG,href));
+
+        { not assigned while generating external wrappers }
+        if assigned(current_procinfo) then
+          include(current_procinfo.flags,pi_do_call);
       end;
 
 
@@ -239,46 +232,41 @@ unit cgrv;
 
     procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
       begin
-        case op of
-          OP_NOT:
-            begin
-              list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
-              maybeadjustresult(list,op,size,dst);
-            end;
-          OP_NEG:
-            begin
-              list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1));
-              maybeadjustresult(list,op,size,dst);
-            end;
-          OP_MOVE:
-            a_load_reg_reg(list,size,size,src1,dst);
+        if op=OP_NOT then
+          a_op_const_reg_reg(list,OP_XOR,size,-1,src1,dst)
+        else if op=OP_NEG then
+          a_op_reg_reg_reg(list,OP_SUB,size,src1,NR_X0,dst)
         else
-{$ifdef RISCV64}
-          if (op=OP_SHL) and
-             (size in [OS_32,OS_S32]) then
-            begin
-              list.concat(taicpu.op_reg_reg_reg(A_SLLW,dst,src2,src1));
-              maybeadjustresult(list,op,size,dst);
-            end
-          else if (op=OP_SHR) and
-             (size in [OS_32,OS_S32]) then
-            begin
-              list.concat(taicpu.op_reg_reg_reg(A_SRLW,dst,src2,src1));
-              maybeadjustresult(list,op,size,dst);
-            end
-          else if (op=OP_SAR) and
-             (size in [OS_32,OS_S32]) then
-            begin
-              list.concat(taicpu.op_reg_reg_reg(A_SRAW,dst,src2,src1));
-              maybeadjustresult(list,op,size,dst);
-            end
+          case op of
+            OP_MOVE:
+              a_load_reg_reg(list,size,size,src1,dst);
           else
+{$ifdef RISCV64}
+            if (op=OP_SHL) and
+               (size in [OS_32,OS_S32]) then
+              begin
+                list.concat(taicpu.op_reg_reg_reg(A_SLLW,dst,src2,src1));
+                maybeadjustresult(list,op,size,dst);
+              end
+            else if (op=OP_SHR) and
+               (size in [OS_32,OS_S32]) then
+              begin
+                list.concat(taicpu.op_reg_reg_reg(A_SRLW,dst,src2,src1));
+                maybeadjustresult(list,op,size,dst);
+              end
+            else if (op=OP_SAR) and
+               (size in [OS_32,OS_S32]) then
+              begin
+                list.concat(taicpu.op_reg_reg_reg(A_SRAW,dst,src2,src1));
+                maybeadjustresult(list,op,size,dst);
+              end
+            else
 {$endif RISCV64}
-            begin
-              list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
-              maybeadjustresult(list,op,size,dst);
-            end;
-        end;
+              begin
+                list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
+                maybeadjustresult(list,op,size,dst);
+              end;
+          end;
       end;
 
 
@@ -509,6 +497,8 @@ unit cgrv;
         end;
 
         list.concat(taicpu.op_reg_ref(op,reg,href));
+        if fromsize<>tosize then
+          a_load_reg_reg(list,fromsize,tosize,reg,reg);
       end;
 
 

+ 17 - 3
compiler/riscv64/cgcpu.pas

@@ -96,7 +96,11 @@ implementation
       var
         ai: taicpu;
       begin
-        if (tcgsize2size[fromsize] > tcgsize2size[tosize]) or
+        if (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_S32) then
+          list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
+        else if (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_8) then
+          list.Concat(taicpu.op_reg_reg_const(A_ANDI,reg2,reg1,$FF))
+        else if (tcgsize2size[fromsize] > tcgsize2size[tosize]) or
           ((tcgsize2size[fromsize] = tcgsize2size[tosize]) and (fromsize <> tosize)) or
           { do we need to mask out the sign when loading from smaller signed to larger unsigned type? }
           ((tcgsize2unsigned[fromsize]<>fromsize) and ((tcgsize2unsigned[tosize]=tosize)) and
@@ -142,8 +146,7 @@ implementation
               list.concat(taicpu.op_reg_reg_const(A_ADDI,register,NR_X0,a))
             else if is_lui_imm(a) then
               list.concat(taicpu.op_reg_const(A_LUI,register,(a shr 12) and $FFFFF))
-            else if (qword(longint(a))=a) and
-                    (size in [OS_32,OS_S32]) then
+            else if (int64(longint(a))=a) then
               begin
                 if (a and $800)<>0 then
                   list.concat(taicpu.op_reg_const(A_LUI,register,((a shr 12)+1) and $FFFFF))
@@ -227,6 +230,11 @@ implementation
                   jump if not sum<x
                 }
                 tmpreg:=getintregister(list,OS_INT);
+                if size in [OS_S32,OS_32] then
+                  begin
+                    a_load_reg_reg(list,size,OS_64,dst,tmpreg);
+                    dst:=tmpreg;
+                  end;
                 list.Concat(taicpu.op_reg_reg_reg(A_SLTU,tmpreg,dst,src));
                                                                         
                 ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,NR_X0,l,0);
@@ -287,6 +295,12 @@ implementation
                   jump if not sum<x
                 }
                 tmpreg:=getintregister(list,OS_INT);
+                if size in [OS_S32,OS_32] then
+                  begin
+                    a_load_reg_reg(list,size,OS_64,dst,tmpreg);
+                    dst:=tmpreg;
+                  end;
+                tmpreg:=getintregister(list,OS_INT);
                 list.Concat(taicpu.op_reg_reg_reg(A_SLTU,tmpreg,dst,src2));
 
                 ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,NR_X0,l,0);

+ 2 - 2
rtl/riscv64/riscv64.inc

@@ -32,14 +32,14 @@ function get_frame:pointer;assembler;nostackframe;
 {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
 function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
   asm
-    ld a0, -8*2(a0)
+    ld a0, -8*1(a0)
   end;
 
 
 {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
 function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
   asm
-    ld a0, -8*1(a0)
+    ld a0, -8*2(a0)
   end;