فهرست منبع

Pass aggregates larger than 2*XLEN as a reference.
Fix load_reg_reg and make it do proper type conversions.
Added maybeadjust to tcgrv.

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

Jeppe Johansen 7 سال پیش
والد
کامیت
2499129ba5
3فایلهای تغییر یافته به همراه50 افزوده شده و 33 حذف شده
  1. 24 3
      compiler/riscv/cgrv.pas
  2. 25 21
      compiler/riscv64/cgcpu.pas
  3. 1 9
      compiler/riscv64/cpupara.pas

+ 24 - 3
compiler/riscv/cgrv.pas

@@ -71,6 +71,7 @@ unit cgrv;
         procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
       protected
         function  fixref(list: TAsmList; var ref: treference): boolean;
+        procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
       end;
 
   const
@@ -202,7 +203,10 @@ unit cgrv;
 
         if (TOpCG2AsmConstOp[op]<>A_None) and
            is_imm12(a) then
-          list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a))
+          begin
+            list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a));
+            maybeadjustresult(list,op,size,dst);
+          end
         else
           begin
             tmpreg:=getintregister(list,size);
@@ -216,13 +220,20 @@ unit cgrv;
       begin
         case op of
           OP_NOT:
-            list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
+            begin
+              list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
+              maybeadjustresult(list,op,size,dst);
+            end;
           OP_NEG:
-            list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1));
+            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);
         else
           list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
+          maybeadjustresult(list,op,size,dst);
         end;
       end;
 
@@ -652,4 +663,14 @@ unit cgrv;
           end;
       end;
 
+
+    procedure tcgrv.maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
+      const
+        overflowops = [OP_MUL,OP_IMUL,OP_SHL,OP_ADD,OP_SUB,OP_NOT,OP_NEG];
+      begin
+        if (op in overflowops) and
+           (size in [OS_8,OS_S8,OS_16,OS_S16{$ifdef RISCV64},OS_32,OS_S32{$endif RISCV64}]) then
+          a_load_reg_reg(list,OS_INT,size,dst,dst)
+      end;
+
 end.

+ 25 - 21
compiler/riscv64/cgcpu.pas

@@ -96,32 +96,36 @@ implementation
       var
         ai: taicpu;
       begin
-        if (fromsize=tosize) or
-           ((tcgsize2unsigned[fromsize]=tcgsize2unsigned[tosize]) and
-            (tcgsize2unsigned[fromsize]=OS_64)) then
+        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
+            (tcgsize2size[fromsize] < tcgsize2size[tosize]) and (tcgsize2size[tosize] <> sizeof(pint)) ) then
           begin
-            ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
-            list.concat(ai);
-            rg[R_INTREGISTER].add_move_instruction(ai);
-          end
-        {else if (fromsize=OS_S32) then
-          list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
-        else if (fromsize=OS_8) then
-          list.Concat(taicpu.op_reg_reg_const(A_ANDI,reg2,reg1,$FF))}
-        else
-          begin
-            if tcgsize2size[tosize]<tcgsize2size[fromsize] then
-              fromsize:=tosize;
+            if tcgsize2size[fromsize]<tcgsize2size[tosize] then
+              begin
+                list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(8-tcgsize2size[fromsize])));
 
-            if tcgsize2unsigned[fromsize]<>OS_64 then
-              list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(8-tcgsize2size[fromsize])))
+                if tcgsize2unsigned[fromsize]<>fromsize then
+                  list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(tcgsize2size[tosize]-tcgsize2size[fromsize])))
+                else
+                  list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(tcgsize2size[tosize]-tcgsize2size[fromsize])));
+              end
+            else if tcgsize2unsigned[tosize]<>OS_64 then
+              list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(8-tcgsize2size[tosize])))
             else
-              a_load_reg_reg(list,fromsize,fromsize,reg1,reg2);
+              a_load_reg_reg(list,tosize,tosize,reg1,reg2);
 
-            if tcgsize2unsigned[fromsize]=fromsize then
-              list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(8-tcgsize2size[fromsize])))
+            if tcgsize2unsigned[tosize]=tosize then
+              list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(8-tcgsize2size[tosize])))
             else
-              list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(8-tcgsize2size[fromsize])));
+              list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(8-tcgsize2size[tosize])));
+          end
+        else
+          begin
+            ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
+            list.concat(ai);
+            rg[R_INTREGISTER].add_move_instruction(ai);
           end;
       end;
 

+ 1 - 9
compiler/riscv64/cpupara.pas

@@ -172,15 +172,7 @@ implementation
             result := true;
           procvardef,
           recorddef:
-            result :=
-              (varspez = vs_const) and
-              (
-               (
-                (not (calloption in [pocall_cdecl, pocall_cppdecl]) and
-                (def.size > 8))
-               ) or
-               (calloption = pocall_mwpascal)
-              );
+            result := (def.size > 8);
           arraydef:
             result := (tarraydef(def).highrange >= tarraydef(def).lowrange) or
               is_open_array(def) or