unit emit_VOP3; {$mode objfpc}{$H+} interface uses sysutils, ps4_pssl, spirv, srType, srReg, emit_fetch; type TEmit_VOP3=class(TEmitFetch) procedure emit_VOP3c; procedure emit_VOP3b; procedure emit_VOP3a; procedure emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean); procedure emit_V_CMP_C (r,x:Boolean); procedure emit_V_CMP_CLASS_32(x:Boolean); procedure emit_src_neg_bit(src:PPsrRegNode;count:Byte;rtype:TsrDataType); procedure emit_src_abs_bit(src:PPsrRegNode;count:Byte;rtype:TsrDataType); procedure emit_dst_omod__f(dst:PsrRegSlot;rtype:TsrDataType); procedure emit_dst_clamp_f(dst:PsrRegSlot;rtype:TsrDataType); function get_legacy_cmp(src0,src1,zero:TsrRegNode):TsrRegNode; procedure emit_V_ADDC_U32; procedure emit_V_SUBB_U32; procedure emit_V_ADD_I32; procedure emit_V_SUB_I32; procedure emit_V_CNDMASK_B32; procedure emit_V_MUL_LEGACY_F32; procedure emit_V2_F32(OpId:DWORD;rev:Boolean); procedure emit_V_CVT_PKRTZ_F16_F32; procedure emit_V_MMX(OpId:DWORD;rtype:TsrDataType); procedure emit_V_MMX3(OpId:DWORD;rtype:TsrDataType); procedure emit_V_SH(OpId:DWORD;rtype:TsrDataType;rev:Boolean); procedure emit_V_MUL_LO(rtype:TsrDataType); procedure emit_V_MUL_I32_I24; procedure emit_V_MUL_U32_U24; procedure emit_V_MUL_HI(rtype:TsrDataType); procedure emit_V_MAC_F32; procedure emit_V_LDEXP_F32; procedure emit_V_BCNT_U32_B32; procedure emit_V_MBCNT_LO_U32_B32; procedure emit_V_MBCNT_HI_U32_B32; procedure emit_V_BFE_U32; procedure emit_V_BFE_I32; procedure emit_V_BFI_B32; procedure emit_V_BFM_B32; procedure emit_V_MAD_F32; procedure emit_V_MAD_LEGACY_F32; procedure emit_V_MAD_I32_I24; procedure emit_V_MAD_U32_U24; procedure emit_V_MAD_U64_U32; procedure emit_V_SAD_U32; procedure emit_V_MED3_F32; procedure emit_V_MED3_I32; procedure emit_V_MED3_U32; procedure emit_V_FMA_F32; procedure emit_V_MMX64(OpId:DWORD); function SelectCubeResult(x,y,z,x_res,y_res,z_res:TsrRegNode):TsrRegNode; procedure emit_V_CUBE(OpId:Word); procedure emit_V_MOV_B32; procedure emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType); procedure emit_V_EXT_F32(OpId:DWORD); procedure emit_V_SIN_COS(OpId:DWORD); procedure emit_V_RCP_F32; end; implementation procedure TEmit_VOP3.emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean); Var dst:array[0..1] of PsrRegSlot; src:array[0..1] of TsrRegNode; begin if not get_sdst7_pair(FSPI.VOP3a.VDST,@dst) then Exit; Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype); emit_src_abs_bit(@src,2,rtype); emit_src_neg_bit(@src,2,rtype); OpCmpV(OpId,dst[0],dst[1],src[0],src[1]); if x then begin MakeCopy(get_exec0,dst[0]^.current); MakeCopy(get_exec1,dst[1]^.current); end; end; procedure TEmit_VOP3.emit_V_CMP_C(r,x:Boolean); Var dst:array[0..1] of PsrRegSlot; begin if not get_sdst7_pair(FSPI.VOP3a.VDST,@dst) then Exit; Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); SetThreadBit(dst[0],dst[1],NewImm_b(r)); if x then begin MakeCopy(get_exec0,dst[0]^.current); MakeCopy(get_exec1,dst[1]^.current); end; end; procedure TEmit_VOP3.emit_V_CMP_CLASS_32(x:Boolean); Var dst:array[0..1] of PsrRegSlot; src:array[0..1] of TsrRegNode; begin if not get_sdst7_pair(FSPI.VOP3a.VDST,@dst) then Exit; Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32); emit_src_abs_bit(@src,1,dtFloat32); emit_src_neg_bit(@src,1,dtFloat32); OpCmpClass(dst[0],dst[1],src[0],src[1]); if x then begin MakeCopy(get_exec0,dst[0]^.current); MakeCopy(get_exec1,dst[1]^.current); end; end; procedure TEmit_VOP3.emit_src_neg_bit(src:PPsrRegNode;count:Byte;rtype:TsrDataType); var i:Byte; begin if (FSPI.VOP3a.NEG=0) then Exit; if not rtype.isFloat then Exit; For i:=0 to count-1 do if Byte(FSPI.VOP3a.NEG).TestBit(i) then begin Assert(src[i].dtype=rtype); src[i]:=OpFNegateTo(src[i]); end; end; procedure TEmit_VOP3.emit_src_abs_bit(src:PPsrRegNode;count:Byte;rtype:TsrDataType); var i:Byte; begin if (FSPI.VOP3a.ABS=0) then Exit; if not rtype.isFloat then Exit; For i:=0 to count-1 do if Byte(FSPI.VOP3a.ABS).TestBit(i) then begin Assert(src[i].dtype=rtype); src[i]:=OpFAbsTo(src[i]); end; end; procedure TEmit_VOP3.emit_dst_omod__f(dst:PsrRegSlot;rtype:TsrDataType); var src,tmp:TsrRegNode; begin if not rtype.isFloat then Exit; src:=dst^.current; Case FSPI.VOP3a.OMOD of 0:; 1: // *2 begin tmp:=NewImm_s(rtype,2); Op2(Op.OpFMul,rtype,dst,src,tmp); end; 2: // *4 begin tmp:=NewImm_s(rtype,4); Op2(Op.OpFMul,rtype,dst,src,tmp); end; 3: // /2 begin tmp:=NewImm_s(rtype,2); Op2(Op.OpFDiv,rtype,dst,src,tmp); end; end; end; procedure TEmit_VOP3.emit_dst_clamp_f(dst:PsrRegSlot;rtype:TsrDataType); var src,min,max:TsrRegNode; begin if (FSPI.VOP3a.CLAMP=0) then Exit; if not rtype.isFloat then Exit; src:=dst^.current; min:=NewImm_s(rtype,0); max:=NewImm_s(rtype,1); OpGlsl3(GlslOp.FClamp,rtype,dst,src,min,max); end; function TEmit_VOP3.get_legacy_cmp(src0,src1,zero:TsrRegNode):TsrRegNode; var eql:array[0..1] of TsrRegNode; begin if CompareReg(src0,src1) then begin Result:=NewReg(dtBool); _Op2(line,Op.OpFOrdEqual,Result,src0,zero); end else begin eql[0]:=NewReg(dtBool); eql[1]:=NewReg(dtBool); _Op2(line,Op.OpFOrdEqual,eql[0],src0,zero); _Op2(line,Op.OpFOrdEqual,eql[1],src1,zero); Result:=NewReg(dtBool); _Op2(line,Op.OpLogicalOr,Result,eql[0],eql[1]); end; end; procedure TEmit_VOP3.emit_V_CNDMASK_B32; //vdst = smask[thread_id:] ? vsrc1 : vsrc0 Var dst:PsrRegSlot; src:array[0..2] of TsrRegNode; rtype:TsrDataType; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); if (Byte(FSPI.VOP3a.ABS).TestBit(0)) or (Byte(FSPI.VOP3a.NEG).TestBit(0)) or (Byte(FSPI.VOP3a.ABS).TestBit(1)) or (Byte(FSPI.VOP3a.NEG).TestBit(1)) then begin rtype:=dtFloat32; end else begin rtype:=dtUnknow; end; src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype); src[2]:=GetThreadBit(get_ssrc9(FSPI.VOP3a.SRC2),get_ssrc9(FSPI.VOP3a.SRC2+1),dtBool); emit_src_abs_bit(@src,2,rtype); emit_src_neg_bit(@src,2,rtype); //dst,cond,src_true,src_false OpSelect(dst,src[2],src[1],src[0]); end; procedure TEmit_VOP3.emit_V_MUL_LEGACY_F32; Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; zero:TsrRegNode; cmp:TsrRegNode; mul:TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtFloat32); emit_src_abs_bit(@src,2,dtFloat32); emit_src_neg_bit(@src,2,dtFloat32); zero:=NewImm_s(dtFloat32,0); cmp:=get_legacy_cmp(src[0],src[1],zero); // mul:=NewReg(dtFloat32); _Op2(line,Op.OpFMul,mul,src[0],src[1]); //dst,cond,src_true,src_false OpSelect(dst,cmp,zero,mul); emit_dst_omod__f(dst,dtFloat32); emit_dst_clamp_f(dst,dtFloat32); end; procedure TEmit_VOP3.emit_V2_F32(OpId:DWORD;rev:Boolean); Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtFloat32); emit_src_abs_bit(@src,2,dtFloat32); emit_src_neg_bit(@src,2,dtFloat32); case rev of False:Op2(OpId,dtFloat32,dst,src[0],src[1]); True :Op2(OpId,dtFloat32,dst,src[1],src[0]); end; emit_dst_omod__f(dst,dtFloat32); emit_dst_clamp_f(dst,dtFloat32); end; procedure TEmit_VOP3.emit_V_CVT_PKRTZ_F16_F32; Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtFloat32); emit_src_abs_bit(@src,2,dtFloat32); emit_src_neg_bit(@src,2,dtFloat32); OpConvFloatToHalf2(dst,src[0],src[1]); end; procedure TEmit_VOP3.emit_V_MMX(OpId:DWORD;rtype:TsrDataType); Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype); emit_src_abs_bit(@src,2,rtype); emit_src_neg_bit(@src,2,rtype); OpGlsl2(OpId,rtype,dst,src[0],src[1]); emit_dst_omod__f(dst,rtype); emit_dst_clamp_f(dst,rtype); end; procedure TEmit_VOP3.emit_V_MMX3(OpId:DWORD;rtype:TsrDataType); Var dst:PsrRegSlot; src:array[0..2] of TsrRegNode; mid:TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype); src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,rtype); emit_src_abs_bit(@src,3,rtype); emit_src_neg_bit(@src,3,rtype); OpGlsl2(OpId,rtype,dst,src[0],src[1]); mid:=MakeRead(dst,rtype); OpGlsl2(OpId,rtype,dst,mid,src[2]); emit_dst_omod__f(dst,rtype); emit_dst_clamp_f(dst,rtype); end; procedure TEmit_VOP3.emit_V_SH(OpId:DWORD;rtype:TsrDataType;rev:Boolean); Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); case rev of False: begin src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32); end; True: begin src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUInt32); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype); end; end; src[1]:=OpAndTo(src[1],31); src[1].PrepType(ord(dtUInt32)); Op2(OpId,rtype,dst,src[0],src[1]); end; procedure TEmit_VOP3.emit_V_MUL_LO(rtype:TsrDataType); Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype); OpIMul(dst,src[0],src[1]); end; procedure TEmit_VOP3.emit_V_MUL_I32_I24; //vdst = (vsrc0[23:0].s * vsrc1[23:0].s) Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32); src[0]:=OpBFSETo(src[0],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24)); src[1]:=OpBFSETo(src[1],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24)); OpIMul(dst,src[0],src[1]); end; procedure TEmit_VOP3.emit_V_MUL_U32_U24; Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; bit24:TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUInt32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32); bit24:=NewImm_q(dtUInt32,$FFFFFF); src[0]:=OpAndTo(src[0],bit24); src[0].PrepType(ord(dtUInt32)); src[1]:=OpAndTo(src[1],bit24); src[1].PrepType(ord(dtUInt32)); OpIMul(dst,src[0],src[1]); end; procedure TEmit_VOP3.emit_V_MUL_HI(rtype:TsrDataType); Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; tmp_r,dst_r:TsrRegNode; tst:TsrDataType; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype); tst:=rtype.AsStruct2; Assert(tst<>dtUnknow); tmp_r:=NewReg(tst); if (rtype.Sign=0) then begin _Op2(line,Op.OpUMulExtended,tmp_r,src[0],src[1]); end else begin _Op2(line,Op.OpSMulExtended,tmp_r,src[0],src[1]); end; dst_r:=dst^.New(rtype); OpExtract(line,dst_r,tmp_r,1); end; procedure TEmit_VOP3.emit_V_MAC_F32; //vdst = vsrc0.f * vsrc1.f + vdst.f -> fma Var dst:PsrRegSlot; src:array[0..2] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtFloat32); src[2]:=MakeRead(dst,dtFloat32); emit_src_abs_bit(@src,3,dtFloat32); emit_src_neg_bit(@src,3,dtFloat32); OpFmaF32(dst,src[0],src[1],src[2]); emit_dst_omod__f(dst,dtFloat32); emit_dst_clamp_f(dst,dtFloat32); end; procedure TEmit_VOP3.emit_V_LDEXP_F32; //vdst.f = vsrc0.f * pow(2.0, vsrc1.s) Var dst:PsrRegSlot; src:array[0..2] of TsrRegNode; two:TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32); emit_src_abs_bit(@src,1,dtFloat32); emit_src_neg_bit(@src,1,dtFloat32); two:=NewImm_s(dtFloat32,2); src[1]:=OpSToF(src[1],dtFloat32); src[1]:=OpPowTo(two,src[1]); Op2(Op.OpFMul,dtFloat32,dst,src[0],src[1]); emit_dst_omod__f(dst,dtFloat32); emit_dst_clamp_f(dst,dtFloat32); end; procedure TEmit_VOP3.emit_V_BCNT_U32_B32; //vdst = bit_count(vsrc0) + vsrc1.u Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUint32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32); src[0]:=OpBitCountTo(src[0]); Op2(Op.OpIAdd,dtUint32,dst,src[0],src[1]); end; procedure TEmit_VOP3.emit_V_MBCNT_LO_U32_B32; Var dst:PsrRegSlot; src:array[0..1] of TsrRegNode; begin //V_MBCNT_LO_U32_B32 vdst, vsrc, vaccum //mask_lo_threads_before= (thread_id>32) ? 0xffffffff : (1<32) ? (1<<(thread_id-32))-1 : 0 //vdst = vaccum.u + bit_count(vsrc & mask_hi_threads_before) dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); //src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUint32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32); //only lower thread_id mean MakeCopy(dst,src[1]); end; procedure TEmit_VOP3.emit_V_BFE_U32; Var dst:PsrRegSlot; src:array[0..2] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUint32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32); src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32); OpBFE_32(dst,src[0],src[1],src[2]); end; procedure TEmit_VOP3.emit_V_BFE_I32; Var dst:PsrRegSlot; src:array[0..2] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32); src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32); OpBFE_32(dst,src[0],src[1],src[2]); end; procedure TEmit_VOP3.emit_V_BFI_B32; Var dst:PsrRegSlot; bitmsk:TsrRegNode; src:array[0..1] of TsrRegNode; begin dst:=get_vdst8(FSPI.VOP3a.VDST); Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); bitmsk:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUint32); src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32); OpBFIB32(dst,bitmsk,src[0],src[1]); end; procedure TEmit_VOP3.emit_V_BFM_B32; //vdst = ((1<