Browse Source

+ MIPS: support replacement spilling for mov.s, mov.d and (partially) mtc1 instructions.

git-svn-id: trunk@28530 -
sergei 11 năm trước cách đây
mục cha
commit
3b06465322
1 tập tin đã thay đổi với 35 bổ sung7 xóa
  1. 35 7
      compiler/mips/rgcpu.pas

+ 35 - 7
compiler/mips/rgcpu.pas

@@ -131,22 +131,50 @@ implementation
         result:=false;
         { Replace 'move  orgreg,src' with 'sw  src,spilltemp'
               and 'move  dst,orgreg' with 'lw  dst,spilltemp' }
-        { TODO: A_MOV_S and A_MOV_D for float registers are also replaceable }
-        if (instr.opcode<>A_MOVE) or (abs(spilltemp.offset)>32767) then
+
+        if (not (instr.opcode in [A_MOVE,A_MOV_S,A_MOV_D,A_MTC1])) or (abs(spilltemp.offset)>32767) then
           exit;
         if (instr.ops<>2) or
            (instr.oper[0]^.typ<>top_reg) or
-           (instr.oper[1]^.typ<>top_reg) or
-           (getregtype(instr.oper[0]^.reg)<>regtype) or
-           (getregtype(instr.oper[1]^.reg)<>regtype) then
+           (instr.oper[1]^.typ<>top_reg) then
           InternalError(2013061001);
+        if (getregtype(instr.oper[0]^.reg)<>regtype) or
+           (getregtype(instr.oper[1]^.reg)<>regtype) then
+          begin
+            if (instr.opcode=A_MTC1) then
+              begin
+                { TODO: MTC1 src,orgreg  ==>  SW    src,0/4(spilltemp) (endian-dependent!!) }
+                if (regtype=R_FPUREGISTER) then
+                  exit;
+              end
+            else
+              InternalError(2013061003);
+          end;
         if get_alias(getsupreg(instr.oper[1]^.reg))=orgreg then
           begin
-            instr.opcode:=A_LW;
+            case instr.opcode of
+              A_MOVE:  instr.opcode:=A_LW;
+              A_MOV_S: instr.opcode:=A_LWC1;
+              A_MOV_D: instr.opcode:=A_LDC1;
+            else
+              InternalError(2013061004);
+            end;
           end
         else if get_alias(getsupreg(instr.oper[0]^.reg))=orgreg then
           begin
-            instr.opcode:=A_SW;
+            case instr.opcode of
+              A_MOVE:  instr.opcode:=A_SW;
+              A_MOV_S: instr.opcode:=A_SWC1;
+              A_MOV_D: instr.opcode:=A_SDC1;
+              A_MTC1:
+                begin
+                  if (getregtype(instr.oper[0]^.reg)<>R_INTREGISTER) then
+                    InternalError(2013061006);
+                  instr.opcode:=A_LWC1;
+                end
+            else
+              InternalError(2013061005);
+            end;
             instr.oper[0]^:=instr.oper[1]^;
           end
         else