static LLVMValueRef emit_fetch( struct lp_build_tgsi_context *bld_base, const struct tgsi_full_src_register *reg, enum tgsi_opcode_type type, unsigned swizzle) { struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); LLVMBuilderRef builder = bld_base->base.gallivm->builder; LLVMValueRef result, ptr; if (swizzle == ~0) { LLVMValueRef values[TGSI_NUM_CHANNELS]; unsigned chan; for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { values[chan] = emit_fetch(bld_base, reg, type, chan); } return lp_build_gather_values(bld_base->base.gallivm, values, TGSI_NUM_CHANNELS); } if (reg->Register.Indirect) { struct tgsi_declaration_range range = get_array_range(bld_base, reg->Register.File, ®->Indirect); return LLVMBuildExtractElement(builder, emit_array_fetch(bld_base, reg->Register.File, type, range, swizzle), emit_array_index(bld, ®->Indirect, reg->Register.Index - range.First), ""); } switch(reg->Register.File) { case TGSI_FILE_IMMEDIATE: { LLVMTypeRef ctype = tgsi2llvmtype(bld_base, type); return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype); } case TGSI_FILE_INPUT: result = ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)]; break; case TGSI_FILE_TEMPORARY: ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle); result = LLVMBuildLoad(builder, ptr, ""); break; case TGSI_FILE_OUTPUT: ptr = lp_get_output_ptr(bld, reg->Register.Index, swizzle); result = LLVMBuildLoad(builder, ptr, ""); break; default: return LLVMGetUndef(tgsi2llvmtype(bld_base, type)); } return bitcast(bld_base, type, result); }
static LLVMValueRef emit_fetch_output( struct lp_build_tgsi_context *bld_base, const struct tgsi_full_src_register *reg, enum tgsi_opcode_type type, unsigned swizzle) { struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); LLVMBuilderRef builder = bld_base->base.gallivm->builder; if (reg->Register.Indirect) { LLVMValueRef array_index = emit_array_index(bld, reg, swizzle); LLVMValueRef ptr = LLVMBuildGEP(builder, bld->outputs_array, &array_index, 1, ""); return LLVMBuildLoad(builder, ptr, ""); } else { LLVMValueRef temp_ptr; temp_ptr = lp_get_output_ptr(bld, reg->Register.Index, swizzle); return LLVMBuildLoad(builder, temp_ptr, ""); } }