Browse Source

* RiscV: integer type conversions fixed

git-svn-id: trunk@48969 -
florian 4 years ago
parent
commit
d1881d0951
1 changed files with 32 additions and 16 deletions
  1. 32 16
      compiler/riscv32/cgcpu.pas

+ 32 - 16
compiler/riscv32/cgcpu.pas

@@ -101,36 +101,52 @@ unit cgcpu;
       end;
       end;
 
 
 
 
+
+
+
+
     procedure tcgrv32.a_load_reg_reg(list : TAsmList;fromsize, tosize : tcgsize;reg1,reg2 : tregister);
     procedure tcgrv32.a_load_reg_reg(list : TAsmList;fromsize, tosize : tcgsize;reg1,reg2 : tregister);
       var
       var
         ai: taicpu;
         ai: taicpu;
       begin
       begin
-        if (fromsize=tosize) or
-           ((tcgsize2unsigned[fromsize]=tcgsize2unsigned[tosize]) and
-            (tcgsize2unsigned[fromsize]=OS_32)) then
+        list.concat(tai_comment.Create(strpnew('Move '+tcgsize2str(fromsize)+'->'+tcgsize2str(tosize))));
+
+        if (tosize=OS_S32) and (fromsize=OS_32) then
           begin
           begin
             ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
             ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
             list.concat(ai);
             list.concat(ai);
             rg[R_INTREGISTER].add_move_instruction(ai);
             rg[R_INTREGISTER].add_move_instruction(ai);
           end
           end
-        else if fromsize=OS_8 then
-          begin
-            list.Concat(taicpu.op_reg_reg_const(A_AND,reg2,reg1,$FF))
-          end
-        else
+        else if (tcgsize2unsigned[tosize]=OS_32) 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
+            (tcgsize2size[fromsize] < tcgsize2size[tosize]) and (tcgsize2size[tosize] <> sizeof(pint)) ) then
           begin
           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*(4-tcgsize2size[fromsize])));
 
 
-            if tcgsize2unsigned[fromsize]<>OS_32 then
-              list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(4-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
             else
-              a_load_reg_reg(list,fromsize,fromsize,reg1,reg2);
+              list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(4-tcgsize2size[tosize])));
 
 
-            if tcgsize2unsigned[fromsize]=fromsize then
-              list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(4-tcgsize2size[fromsize])))
+            if tcgsize2unsigned[tosize]=tosize then
+              list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(4-tcgsize2size[tosize])))
             else
             else
-              list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(4-tcgsize2size[fromsize])));
+              list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(4-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;
       end;
       end;