From 3b06465322c2f57e0d54b65f9b2fdac6d9779c9e Mon Sep 17 00:00:00 2001 From: sergei Date: Wed, 27 Aug 2014 21:26:38 +0000 Subject: [PATCH] + MIPS: support replacement spilling for mov.s, mov.d and (partially) mtc1 instructions. git-svn-id: trunk@28530 - --- compiler/mips/rgcpu.pas | 42 ++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/compiler/mips/rgcpu.pas b/compiler/mips/rgcpu.pas index b022cd5c7c..2378045de0 100644 --- a/compiler/mips/rgcpu.pas +++ b/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