radeon/llvm: add support for AHSR/LSHR/LSHL instructions
authorVadim Girlin <vadimgirlin@gmail.com>
Mon, 7 May 2012 08:50:25 +0000 (12:50 +0400)
committerVadim Girlin <vadimgirlin@gmail.com>
Mon, 7 May 2012 21:18:22 +0000 (01:18 +0400)
Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
src/gallium/drivers/radeon/R600InstrInfo.cpp
src/gallium/drivers/radeon/R600InstrInfo.h
src/gallium/drivers/radeon/R600Instructions.td
src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c

index 0c7ffc4334dac06660f0d209519a97089f1646d2..ed4fcc9ad1efb2682d1529d764fb364715e8459b 100644 (file)
@@ -73,10 +73,22 @@ unsigned R600InstrInfo::getISAOpcode(unsigned opcode) const
     case AMDIL::MOVE_i32:
       return AMDIL::MOV;
     case AMDIL::SHR_i32:
+      return getASHRop();
+    case AMDIL::USHR_i32:
       return getLSHRop();
   }
 }
 
+unsigned R600InstrInfo::getASHRop() const
+{
+       unsigned gen = TM.getSubtarget<AMDILSubtarget>().device()->getGeneration();
+       if (gen < AMDILDeviceInfo::HD5XXX) {
+               return AMDIL::ASHR_r600;
+       } else {
+               return AMDIL::ASHR_eg;
+       }
+}
+
 unsigned R600InstrInfo::getLSHRop() const
 {
   unsigned gen = TM.getSubtarget<AMDILSubtarget>().device()->getGeneration();
index aedaa9f47f3cc36152a36b256cbbc54ddd967ec3..701cf7fedee9b51d24c1b68b47062eb37a767e15 100644 (file)
@@ -52,6 +52,7 @@ namespace llvm {
   bool isTrig(const MachineInstr &MI) const;
 
   unsigned getLSHRop() const;
+  unsigned getASHRop() const;
   unsigned getMULHI_UINT() const;
   unsigned getMULLO_UINT() const;
   unsigned getRECIP_UINT() const;
index 0a73b5cfbf072ebf4d13e5a1ce82e5533408d44b..9df057025f2da88398e3e798947f608f72229242 100644 (file)
@@ -535,6 +535,12 @@ class LSHR_Common <bits<32> inst> : R600_2OP <
   let AMDILOp = AMDILInst.USHR_i32;
 }
 
+class ASHR_Common <bits<32> inst> : R600_2OP <
+  inst, "ASHR $dst, $src0, $src1",
+  [] >{
+  let AMDILOp = AMDILInst.SHR_i32;
+}
+
 class MULHI_INT_Common <bits<32> inst> : R600_2OP <
   inst, "MULHI_INT $dst, $src0, $src1",
   [] >{
@@ -645,6 +651,7 @@ let Gen = AMDGPUGen.R600 in {
   def INT_TO_FLT_r600 : INT_TO_FLT_Common<0x6c>;
   def SIN_r600 : SIN_Common<0x6E>;
   def COS_r600 : COS_Common<0x6F>;
+  def ASHR_r600 : ASHR_Common<0x70>;
   def LSHR_r600 : LSHR_Common<0x71>;
   def LSHL_r600 : LSHL_Common<0x72>;
   def MULLO_INT_r600 : MULLO_INT_Common<0x73>;
@@ -815,6 +822,7 @@ class TRIG_eg <InstR600 trig, Intrinsic intr> : Pat<
 let Gen = AMDGPUGen.EG_CAYMAN in {
 
   def MULADD_eg : MULADD_Common<0x14>;
+  def ASHR_eg : ASHR_Common<0x15>;
   def LSHR_eg : LSHR_Common<0x16>;
   def LSHL_eg : LSHL_Common<0x17>;
   def CNDE_eg : CNDE_Common<0x19>;
index fe5d1b8279f025a468d5d8787544ab9f5c0d7431..2932bdd9490c86fb236c5f33c6b496c706ea4cb2 100644 (file)
@@ -533,6 +533,35 @@ static void tex_fetch_args(
        emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
 }
 
+static void emit_shl(
+               const struct lp_build_tgsi_action * action,
+               struct lp_build_tgsi_context * bld_base,
+               struct lp_build_emit_data * emit_data)
+{
+       LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+       emit_data->output[emit_data->chan] = LLVMBuildShl(builder,
+                       emit_data->args[0], emit_data->args[1], "");
+}
+
+static void emit_ushr(
+               const struct lp_build_tgsi_action * action,
+               struct lp_build_tgsi_context * bld_base,
+               struct lp_build_emit_data * emit_data)
+{
+       LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+       emit_data->output[emit_data->chan] = LLVMBuildLShr(builder,
+                       emit_data->args[0], emit_data->args[1], "");
+}
+static void emit_ishr(
+               const struct lp_build_tgsi_action * action,
+               struct lp_build_tgsi_context * bld_base,
+               struct lp_build_emit_data * emit_data)
+{
+       LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+       emit_data->output[emit_data->chan] = LLVMBuildAShr(builder,
+                       emit_data->args[0], emit_data->args[1], "");
+}
+
 static void emit_immediate(struct lp_build_tgsi_context * bld_base,
                const struct tgsi_full_immediate *imm)
 {
@@ -606,6 +635,9 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
 
        lp_set_default_actions(bld_base);
 
+       bld_base->op_actions[TGSI_OPCODE_SHL].emit = emit_shl;
+       bld_base->op_actions[TGSI_OPCODE_ISHR].emit = emit_ishr;
+       bld_base->op_actions[TGSI_OPCODE_USHR].emit = emit_ushr;
        bld_base->op_actions[TGSI_OPCODE_DDX].intr_name = "llvm.AMDGPU.ddx";
        bld_base->op_actions[TGSI_OPCODE_DDX].fetch_args = tex_fetch_args;
        bld_base->op_actions[TGSI_OPCODE_DDY].intr_name = "llvm.AMDGPU.ddy";