From 036303c4bfce560875fc283e1ab652458f86e01f Mon Sep 17 00:00:00 2001 From: Aaron Watry Date: Thu, 11 Sep 2014 15:02:54 +0000 Subject: [PATCH] R600: Add cmpxchg instruction for evergreen Refactored the R600_LDS_1A2D class a bit to get it to actually work. It seemed to be previously unused and broken. We also have to disable the conversion to the noret variant for now in R600ISelLowering because the getLDSNoRetOp method only handles 1A1D LDS ops. Someone can feel free to modify the AMDGPU::getLDSNoRetOp method to work for more than 1A1D variants of LDS operations. It's being left as a future TODO for now. Signed-off-by: Aaron Watry Reviewed-by: Matt Arsenault git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217596 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/EvergreenInstructions.td | 29 ++++++++++++++++++++---- lib/Target/R600/R600ISelLowering.cpp | 5 +++- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/Target/R600/EvergreenInstructions.td b/lib/Target/R600/EvergreenInstructions.td index 3438244cc42..8117b6065a2 100644 --- a/lib/Target/R600/EvergreenInstructions.td +++ b/lib/Target/R600/EvergreenInstructions.td @@ -474,25 +474,43 @@ class R600_LDS_1A1D_RET lds_op, string name, list pattern> : let DisableEncoding = "$dst"; } -class R600_LDS_1A2D lds_op, string name, list pattern> : +class R600_LDS_1A2D lds_op, dag outs, string name, list pattern, + string dst =""> : R600_LDS < - lds_op, - (outs), + lds_op, outs, (ins R600_Reg32:$src0, REL:$src0_rel, SEL:$src0_sel, R600_Reg32:$src1, REL:$src1_rel, SEL:$src1_sel, R600_Reg32:$src2, REL:$src2_rel, SEL:$src2_sel, LAST:$last, R600_Pred:$pred_sel, BANK_SWIZZLE:$bank_swizzle), - " "#name# "$last $src0$src0_rel, $src1$src1_rel, $src2$src2_rel, $pred_sel", + " "#name# "$last "#dst#"$src0$src0_rel, $src1$src1_rel, $src2$src2_rel, $pred_sel", pattern> { + + field string BaseOp; + + let LDS_1A1D = 0; let LDS_1A2D = 1; } +class R600_LDS_1A2D_NORET lds_op, string name, list pattern> : + R600_LDS_1A2D { + let BaseOp = name; +} + +class R600_LDS_1A2D_RET lds_op, string name, list pattern> : + R600_LDS_1A2D { + + let BaseOp = name; + let usesCustomInserter = 1; + let DisableEncoding = "$dst"; +} + def LDS_ADD : R600_LDS_1A1D_NORET <0x0, "LDS_ADD", [] >; def LDS_SUB : R600_LDS_1A1D_NORET <0x1, "LDS_SUB", [] >; def LDS_AND : R600_LDS_1A1D_NORET <0x9, "LDS_AND", [] >; def LDS_OR : R600_LDS_1A1D_NORET <0xa, "LDS_OR", [] >; def LDS_XOR : R600_LDS_1A1D_NORET <0xb, "LDS_XOR", [] >; def LDS_WRXCHG: R600_LDS_1A1D_NORET <0xd, "LDS_WRXCHG", [] >; +def LDS_CMPST: R600_LDS_1A2D_NORET <0x10, "LDS_CMPST", [] >; def LDS_MIN_INT : R600_LDS_1A1D_NORET <0x5, "LDS_MIN_INT", [] >; def LDS_MAX_INT : R600_LDS_1A1D_NORET <0x6, "LDS_MAX_INT", [] >; def LDS_MIN_UINT : R600_LDS_1A1D_NORET <0x7, "LDS_MIN_UINT", [] >; @@ -536,6 +554,9 @@ def LDS_MAX_UINT_RET : R600_LDS_1A1D_RET <0x28, "LDS_MAX_UINT", def LDS_WRXCHG_RET : R600_LDS_1A1D_RET <0x2d, "LDS_WRXCHG", [(set i32:$dst, (atomic_swap_local i32:$src0, i32:$src1))] >; +def LDS_CMPST_RET : R600_LDS_1A2D_RET <0x30, "LDS_CMPST", + [(set i32:$dst, (atomic_cmp_swap_32_local i32:$src0, i32:$src1, i32:$src2))] +>; def LDS_READ_RET : R600_LDS_1A <0x32, "LDS_READ_RET", [(set (i32 R600_Reg32:$dst), (local_load R600_Reg32:$src0))] >; diff --git a/lib/Target/R600/R600ISelLowering.cpp b/lib/Target/R600/R600ISelLowering.cpp index 3bc8cb99c71..87610e9cc55 100644 --- a/lib/Target/R600/R600ISelLowering.cpp +++ b/lib/Target/R600/R600ISelLowering.cpp @@ -202,7 +202,10 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter( int DstIdx = TII->getOperandIdx(MI->getOpcode(), AMDGPU::OpName::dst); assert(DstIdx != -1); MachineInstrBuilder NewMI; - if (!MRI.use_empty(MI->getOperand(DstIdx).getReg())) + // FIXME: getLDSNoRetOp method only handles LDS_1A1D LDS ops. Add + // LDS_1A2D support and remove this special case. + if (!MRI.use_empty(MI->getOperand(DstIdx).getReg()) || + MI->getOpcode() == AMDGPU::LDS_CMPST_RET) return BB; NewMI = BuildMI(*BB, I, BB->findDebugLoc(I),