diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-01-21 23:28:34 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-01-21 23:28:34 +0000 |
commit | 1903b037de2fb3e75826406b46f055acb70963fa (patch) | |
tree | 604cd8b790fe14e5fbe441d4cd647c80d2a36a9a /compiler/mips/rgcpu.pas | |
parent | ad1141d52f8353457053b925cd674fe1d5c4eafc (diff) | |
parent | 953d907e4d6c3a5c2f8aaee6e5e4f73c55ce5985 (diff) | |
download | fpc-blocks.tar.gz |
* synchronised with trunk till r29513blocks
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/blocks@29516 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/mips/rgcpu.pas')
-rw-r--r-- | compiler/mips/rgcpu.pas | 42 |
1 files 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 |