unit srBitcast; {$mode ObjFPC}{$H+} interface uses ginodes, srNode, srType, srConst, srReg; type PsrBitcast=^TsrBitcast; TsrBitcast=object pLeft,pRight:PsrBitcast; //---- key:packed record dtype:TsrDataType; src:PsrRegNode; end; dst:PsrRegNode; function c(n1,n2:PsrBitcast):Integer; static; end; PsrBitcastList=^TsrBitcastList; TsrBitcastList=object type TNodeFetch=specialize TNodeFetch; var FNTree:TNodeFetch; rSlot:TsrRegSlot; procedure Init(Emit:TCustomEmit); inline; function _Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast; function Find(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; Procedure Save(dtype:TsrDataType;src,dst:PsrRegNode); function FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; function FetchDstr(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; function FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; end; implementation function TsrBitcast.c(n1,n2:PsrBitcast):Integer; begin //first dtype Result:=Integer(n1^.key.dtype>n2^.key.dtype)-Integer(n1^.key.dtype0) then Exit; //second src Result:=Integer(n1^.key.src>n2^.key.src)-Integer(n1^.key.srcnil) then begin Result:=node^.dst; end; end; Procedure TsrBitcastList.Save(dtype:TsrDataType;src,dst:PsrRegNode); var node:PsrBitcast; begin node:=rSlot.Emit.Alloc(SizeOf(TsrBitcast)); node^:=Default(TsrBitcast); node^.key.dtype:=dtype; node^.key.src:=src; node^.dst:=dst; FNTree.Insert(node); end; function TsrBitcastList.FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; var pConstList:PsrConstList; dst:PsrRegNode; pConst:PsrConst; begin Result:=src; if (src=nil) then Exit; if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit; if src^.is_const then begin //only from consts, first dst:=Find(dtype,src); if (dst<>nil) then Exit(dst); pConst:=src^.AsConst; pConstList:=rSlot.Emit.GetConstList; pConst:=pConstList^.Bitcast(dtype,pConst); dst:=rSlot.New(src^.pLine,dtype); dst^.pWriter:=pConst; // Save(dtype,src,dst); end else begin dst:=rSlot.New(src^.pLine,dtype); dst^.pWriter:=src; end; Result:=dst; end; function TsrBitcastList.FetchDstr(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; var dst:PsrRegNode; begin Result:=src; if (src=nil) then Exit; if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit; dst:=rSlot.New(src^.pLine,dtype); dst^.pWriter:=src^.pWriter; src^.pWriter:=dst; Result:=dst; end; function TsrBitcastList.FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; var pConstList:PsrConstList; dst:PsrRegNode; pConst:PsrConst; begin Result:=src; if (src=nil) then Exit; if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit; dst:=nil; // dst:=Find(dtype,src); if (dst<>nil) then Exit(dst); if src^.is_const then begin pConst:=src^.AsConst; pConstList:=rSlot.Emit.GetConstList; pConst:=pConstList^.Bitcast(dtype,pConst); dst:=rSlot.New(src^.pLine,dtype); dst^.pWriter:=pConst; end else begin if TryBitcastType(src^.dtype,dtype) then begin dst:=rSlot.New(src^.pLine,dtype); rSlot.Emit.OpCast(src^.pLine,dst,src) end else begin Assert(false,'bitcast'); end; end; // Save(dtype,src,dst); Result:=dst; end; end.