123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- {
- Copyright (c) 2024 by Kirill Kranz
- This unit contains the CPU specific part of inserting a NOP on a Read After Write dependency
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- unit cpuext;
- {$i fpcdefs.inc}
- interface
- uses
- cutils,
- globtype, symdef,
- procinfo, cpuinfo, cpupara,
- psub, aasmdata, cgutils, aasmtai;
- procedure resolveReadAfterWrite(list: TAsmList);
- implementation
- uses
- systems, globals, verbose, sysutils, cclasses,
- cpubase, cgbase, cgobj,
- tgobj, paramgr, symconst, symcpu, aasmcpu;
- procedure resolveReadAfterWrite(list: TAsmList);
- label skip;
- var
- p, pp : tai;
- l, x : TLinkedListItem;
- firstReg : tregister;
- begin
- l:= list.first;
- while assigned(l) do begin
-
- p:= tai(l);
- if p.typ = ait_instruction then begin
- if (taicpu(p).opcode = A_LB) or (taicpu(p).opcode = A_LBU) or
- (taicpu(p).opcode = A_LH) or (taicpu(p).opcode = A_LHU) or
- (taicpu(p).opcode = A_LW) or (taicpu(p).opcode = A_LWU) or
- (taicpu(p).opcode = A_LWL) or (taicpu(p).opcode = A_LWR) or
- (taicpu(p).opcode = A_MFC0) {MFC2} {LWC2} then begin
- firstReg:= taicpu(p).oper[0]^.reg;
- x:= l.next;
- pp:= tai(x);
-
- while pp.typ <> ait_instruction do begin
- x:= x.next;
- pp:= tai(x);
- end;
- if pp.typ = ait_instruction then begin
- if (taicpu(p).opcode = A_LWL) and (taicpu(pp).opcode = A_LWR) then goto skip;
- if (taicpu(p).opcode = A_LWR) and (taicpu(pp).opcode = A_LWL) then goto skip;
- if taicpu(pp).ops > 0 then begin
- if taicpu(pp).ops = 1 then
- if (taicpu(pp).oper[0]^.typ = top_reg) and (firstReg = taicpu(pp).oper[0]^.reg) then
- list.insertAfter(taicpu.op_none(A_NOP), l);
- if taicpu(pp).ops = 2 then
- if ((taicpu(pp).oper[0]^.typ = top_reg) and (firstReg = taicpu(pp).oper[0]^.reg))
- or ((taicpu(pp).oper[1]^.typ = top_reg) and (firstReg = taicpu(pp).oper[1]^.reg))
- or ((taicpu(pp).oper[1]^.typ = top_ref) and (firstReg = taicpu(pp).oper[1]^.ref^.base))
- then
- list.insertAfter(taicpu.op_none(A_NOP), l);
- if taicpu(pp).ops = 3 then
- if ((taicpu(pp).oper[0]^.typ = top_reg) and (firstReg = taicpu(pp).oper[0]^.reg)) or
- ((taicpu(pp).oper[1]^.typ = top_reg) and (firstReg = taicpu(pp).oper[1]^.reg)) or
- ((taicpu(pp).oper[2]^.typ = top_reg) and (firstReg = taicpu(pp).oper[2]^.reg))
- then
- list.insertAfter(taicpu.op_none(A_NOP), l);
- end;
- end;
- end;
- end;
- skip:
- l:= l.next;
- end;
- end;
- begin
- end.
|