From caba679e56e844c09c217e41a3016fcb0d136ede Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 17 Aug 2022 14:37:57 +0200 Subject: [PATCH] nv50/ir: handle S8/S16 integers converting to S64 We can't convert directly from signed integers smaller 64 bit to signed 64 bit integers. For 32 bit integers this is handled with SHR and MERGE. In order to also support 8/16 bit singed integers convert them to 32 bit first. Reviewed-by: Karol Herbst Signed-off-by: Danilo Krummrich Part-of: --- .../codegen/nv50_ir_lowering_helper.cpp | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/nouveau/codegen/nv50_ir_lowering_helper.cpp b/src/nouveau/codegen/nv50_ir_lowering_helper.cpp index 7d77fcdd6e1..a8f1660325d 100644 --- a/src/nouveau/codegen/nv50_ir_lowering_helper.cpp +++ b/src/nouveau/codegen/nv50_ir_lowering_helper.cpp @@ -129,12 +129,32 @@ LoweringHelper::handleCVT(Instruction *insn) return true; } - if (dTy == TYPE_S64 && sTy == TYPE_S32) { - Value *tmp = bld.getSSA(); - bld.mkOp2(OP_SHR, TYPE_S32, tmp, insn->getSrc(0), bld.loadImm(bld.getSSA(), 31)); + /* We can't convert to signed 64 bit integrers, hence shift the upper word + * and merge. For sources smaller than 32 bit, convert to 32 bit first. + */ + if (dTy == TYPE_S64 && isSignedIntType(sTy) && typeSizeof(sTy) <= 4) { + Value *tmpExtbf; + Value *tmpShr = bld.getSSA(); + + if (typeSizeof(sTy) < 4) { + unsigned int interval = typeSizeof(sTy) == 1 ? 0x800 : 0x1000; + tmpExtbf = bld.getSSA(); + bld.mkOp2(OP_EXTBF, TYPE_S32, tmpExtbf, insn->getSrc(0), + bld.loadImm(bld.getSSA(), interval)); + insn->setSrc(0, tmpExtbf); + } else { + tmpExtbf = insn->getSrc(0); + } + + bld.mkOp2(OP_SHR, TYPE_S32, tmpShr, tmpExtbf, bld.loadImm(bld.getSSA(), 31)); + insn->op = OP_MERGE; - insn->setSrc(1, tmp); - } else if (dTy == TYPE_U64 && sTy == TYPE_U32) { + insn->setSrc(1, tmpShr); + + return true; + } + + if (dTy == TYPE_U64 && sTy == TYPE_U32) { insn->op = OP_MERGE; insn->setSrc(1, bld.loadImm(bld.getSSA(), 0)); }