Переглянути джерело

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 роки тому
батько
коміт
b98eb3daa9
3 змінених файлів з 60 додано та 56 видалено
  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
   const
     TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_NONE,
     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
   const
     TOpCG2AsmConstOp: Array[topcg] of TAsmOp = (A_NONE,
     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);
     procedure tcgrv.a_call_name(list : TAsmList;const s : string; weak: boolean);
       var
       var
-        tmpreg: TRegister;
         href: treference;
         href: treference;
         l: TAsmLabel;
         l: TAsmLabel;
       begin
       begin
@@ -107,26 +106,20 @@ unit cgrv;
         else
         else
           reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(s,AT_FUNCTION),0,0,[]);
           reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(s,AT_FUNCTION),0,0,[]);
 
 
-        tmpreg:=getintregister(list,OS_ADDR);
-
         current_asmdata.getjumplabel(l);
         current_asmdata.getjumplabel(l);
 
 
         a_label(list,l);
         a_label(list,l);
 
 
         href.refaddr:=addr_pcrel_hi20;
         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,[]);
         reference_reset_symbol(href,l,0,0,[]);
         href.refaddr:=addr_pcrel_lo12;
         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;
       end;
 
 
 
 
@@ -239,46 +232,41 @@ unit cgrv;
 
 
     procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
     procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
       begin
       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
         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
           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}
 {$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;
       end;
 
 
 
 
@@ -509,6 +497,8 @@ unit cgrv;
         end;
         end;
 
 
         list.concat(taicpu.op_reg_ref(op,reg,href));
         list.concat(taicpu.op_reg_ref(op,reg,href));
+        if fromsize<>tosize then
+          a_load_reg_reg(list,fromsize,tosize,reg,reg);
       end;
       end;
 
 
 
 

+ 17 - 3
compiler/riscv64/cgcpu.pas

@@ -96,7 +96,11 @@ implementation
       var
       var
         ai: taicpu;
         ai: taicpu;
       begin
       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
           ((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? }
           { 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
           ((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))
               list.concat(taicpu.op_reg_reg_const(A_ADDI,register,NR_X0,a))
             else if is_lui_imm(a) then
             else if is_lui_imm(a) then
               list.concat(taicpu.op_reg_const(A_LUI,register,(a shr 12) and $FFFFF))
               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
               begin
                 if (a and $800)<>0 then
                 if (a and $800)<>0 then
                   list.concat(taicpu.op_reg_const(A_LUI,register,((a shr 12)+1) and $FFFFF))
                   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
                   jump if not sum<x
                 }
                 }
                 tmpreg:=getintregister(list,OS_INT);
                 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));
                 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);
                 ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,NR_X0,l,0);
@@ -287,6 +295,12 @@ implementation
                   jump if not sum<x
                   jump if not sum<x
                 }
                 }
                 tmpreg:=getintregister(list,OS_INT);
                 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));
                 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);
                 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}
 {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
 function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
 function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
   asm
   asm
-    ld a0, -8*2(a0)
+    ld a0, -8*1(a0)
   end;
   end;
 
 
 
 
 {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
 {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
 function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
 function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
   asm
   asm
-    ld a0, -8*1(a0)
+    ld a0, -8*2(a0)
   end;
   end;