unit emit_SOPK; {$mode objfpc}{$H+} interface uses sysutils, spirv, ps4_pssl, srType, srReg, emit_fetch; type TEmit_SOPK=class(TEmitFetch) procedure emit_SOPK; procedure emit_S_MOVK_I32; procedure emit_S_ADDK_I32; procedure emit_S_MULK_I32; procedure emit_S_CMPK_I32(OpId:DWORD); procedure emit_S_CMPK_U32(OpId:DWORD); end; implementation function SignExtend16(W:Word):Integer; inline; begin Result:=SmallInt(W); end; procedure TEmit_SOPK.emit_S_MOVK_I32; //sdst.s = signExtend(imm16) Var dst:PsrRegSlot; begin dst:=get_sdst7(FSPI.SOPK.SDST); SetConst_i(dst,dtInt32,SignExtend16(FSPI.SOPK.SIMM)); end; procedure TEmit_SOPK.emit_S_ADDK_I32; //sdst.s = (sdst.s + signExtend(imm16)); SCC = overflow Var dst:PsrRegSlot; car:PsrRegSlot; src:TsrRegNode; imm:TsrRegNode; a,b:TsrRegNode; i:Integer; begin dst:=get_sdst7(FSPI.SOPK.SDST); car:=get_scc; i:=SignExtend16(FSPI.SOPK.SIMM); src:=fetch_ssrc8(FSPI.SOPK.SDST,dtInt32); imm:=NewImm_i(dtInt32,i); //Force type src:=BitcastList.FetchRead(dtInt32,src); OpIAdd(dst,src,imm); //sign(s) == sign(i) && sign(d) != sign(i) a:=OpIsSSignTo(src); b:=OpIsSSignTo(dst^.current); if (i<0) then begin //sign(s) && !sign(d) b:=OpLogicalNotTo(b); end else begin //!sign(s) && sign(d) a:=OpLogicalNotTo(a); end; OpLogicalAnd(car,a,b); end; procedure TEmit_SOPK.emit_S_MULK_I32; //sdst.s = (sdst.s * signExtend(imm16.s)) & 0xFFFFFFFF Var dst:PsrRegSlot; src:TsrRegNode; imm:TsrRegNode; i:Integer; begin dst:=get_sdst7(FSPI.SOPK.SDST); i:=SignExtend16(FSPI.SOPK.SIMM); src:=fetch_ssrc8(FSPI.SOPK.SDST,dtInt32); imm:=NewImm_i(dtInt32,i); //Force type src:=BitcastList.FetchRead(dtInt32,src); OpIMul(dst,src,imm); end; procedure TEmit_SOPK.emit_S_CMPK_I32(OpId:DWORD); //SCC = compareOp(sdst.s, signExtend(imm16.s)) Var dst:PsrRegSlot; src:TsrRegNode; imm:TsrRegNode; begin dst:=get_scc; src:=fetch_ssrc8(FSPI.SOPK.SDST,dtInt32); imm:=NewImm_i(dtInt32,SignExtend16(FSPI.SOPK.SIMM)); OpCmpS(OpId,dst,src,imm); end; procedure TEmit_SOPK.emit_S_CMPK_U32(OpId:DWORD); //SCC = compareOp(sdst.u, imm16.u) Var dst:PsrRegSlot; src:TsrRegNode; imm:TsrRegNode; begin dst:=get_scc; src:=fetch_ssrc8(FSPI.SOPK.SDST,dtUint32); imm:=NewImm_i(dtUint32,FSPI.SOPK.SIMM); OpCmpS(OpId,dst,src,imm); end; procedure TEmit_SOPK.emit_SOPK; begin Case FSPI.SOPK.OP of S_CMPK_EQ_I32:emit_S_CMPK_I32(Op.OpIEqual); S_CMPK_LG_I32:emit_S_CMPK_I32(Op.OpINotEqual); S_CMPK_GT_I32:emit_S_CMPK_I32(Op.OpSGreaterThan); S_CMPK_GE_I32:emit_S_CMPK_I32(Op.OpSGreaterThanEqual); S_CMPK_LT_I32:emit_S_CMPK_I32(Op.OpSLessThan); S_CMPK_LE_I32:emit_S_CMPK_I32(Op.OpSLessThanEqual); S_CMPK_EQ_U32:emit_S_CMPK_U32(Op.OpIEqual); S_CMPK_LG_U32:emit_S_CMPK_U32(Op.OpINotEqual); S_CMPK_GT_U32:emit_S_CMPK_U32(Op.OpSGreaterThan); S_CMPK_GE_U32:emit_S_CMPK_U32(Op.OpSGreaterThanEqual); S_CMPK_LT_U32:emit_S_CMPK_U32(Op.OpSLessThan); S_CMPK_LE_U32:emit_S_CMPK_U32(Op.OpSLessThanEqual); S_MOVK_I32: emit_S_MOVK_I32; S_ADDK_I32: emit_S_ADDK_I32; S_MULK_I32: emit_S_MULK_I32; else Assert(false,'SOPK?'+IntToStr(FSPI.SOPK.OP)+' '+get_str_spi(FSPI)); end; end; end.