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

git-svn-id: trunk@28530 -
This commit is contained in:
sergei 2014-08-27 21:26:38 +00:00
parent 5655baa23a
commit 3b06465322

View File

@ -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