summaryrefslogtreecommitdiff
path: root/compiler/mips/rgcpu.pas
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-01-21 23:28:34 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-01-21 23:28:34 +0000
commit1903b037de2fb3e75826406b46f055acb70963fa (patch)
tree604cd8b790fe14e5fbe441d4cd647c80d2a36a9a /compiler/mips/rgcpu.pas
parentad1141d52f8353457053b925cd674fe1d5c4eafc (diff)
parent953d907e4d6c3a5c2f8aaee6e5e4f73c55ce5985 (diff)
downloadfpc-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.pas42
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