Esempio n. 1
0
 void check_sort(sort * s) {
     if (s->get_family_id() == null_family_id) {
         if (!m_uf)
             fail("logic does not support uninterpreted sorts");
     }
     else if (m.is_bool(s)) {
         return;
     }
     else if (m_a_util.is_int(s)) {
         if (!m_ints)
             fail("logic does not support integers");
     }
     else if (m_a_util.is_real(s)) {
         if (!m_reals)
             fail("logic does not support reals");
     }
     else if (m_bv_util.is_bv_sort(s)) {
         if (!m_bvs)
             fail("logic does not support bitvectors");
     }
     else if (m_ar_util.is_array(s)) {
         if (m_arrays) {
             return;
         }
         else if (m_bv_arrays) {
             if (get_array_arity(s) != 1)
                 fail("logic supports only unidimensional arrays");
             if (!m_bv_util.is_bv_sort(get_array_range(s)) || !m_bv_util.is_bv_sort(get_array_domain(s, 0)))
                 fail("logic supports only arrays from bitvectors to bitvectors");
         }
         else {
             fail("logic does not support arrays");
         }
     }
 }
Esempio n. 2
0
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, &reg->Indirect);
		return LLVMBuildExtractElement(builder,
			emit_array_fetch(bld_base, reg->Register.File, type, range, swizzle),
			emit_array_index(bld, &reg->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);
}
Esempio n. 3
0
	TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
		LLVMValueRef value = dst[chan_index];

		if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
			struct lp_build_emit_data clamp_emit_data;

			memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
			clamp_emit_data.arg_count = 3;
			clamp_emit_data.args[0] = value;
			clamp_emit_data.args[2] = base.one;

			switch(inst->Instruction.Saturate) {
			case TGSI_SAT_ZERO_ONE:
				clamp_emit_data.args[1] = base.zero;
				break;
			case TGSI_SAT_MINUS_PLUS_ONE:
				clamp_emit_data.args[1] = LLVMConstReal(
						base.elem_type, -1.0f);
				break;
			default:
				assert(0);
			}
			value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
						&clamp_emit_data);
		}

		if (reg->Register.File == TGSI_FILE_ADDRESS) {
			temp_ptr = bld->addr[reg->Register.Index][chan_index];
			LLVMBuildStore(builder, value, temp_ptr);
			continue;
		}
	
		value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);

		if (reg->Register.Indirect) {
			struct tgsi_declaration_range range = get_array_range(bld_base,
				reg->Register.File, &reg->Indirect);

        		unsigned i, size = range.Last - range.First + 1;
			LLVMValueRef array = LLVMBuildInsertElement(builder,
				emit_array_fetch(bld_base, reg->Register.File, TGSI_TYPE_FLOAT, range, chan_index),
				value,  emit_array_index(bld, &reg->Indirect, reg->Register.Index - range.First), "");

        		for (i = 0; i < size; ++i) {
				switch(reg->Register.File) {
				case TGSI_FILE_OUTPUT:
					temp_ptr = bld->outputs[i + range.First][chan_index];
					break;

				case TGSI_FILE_TEMPORARY:
					temp_ptr = lp_get_temp_ptr_soa(bld, i + range.First, chan_index);
					break;

				default:
					return;
				}
				value = LLVMBuildExtractElement(builder, array, 
					lp_build_const_int32(gallivm, i), "");
				LLVMBuildStore(builder, value, temp_ptr);
			}

		} else {
			switch(reg->Register.File) {
			case TGSI_FILE_OUTPUT:
				temp_ptr = bld->outputs[reg->Register.Index][chan_index];
				break;

			case TGSI_FILE_TEMPORARY:
				temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, chan_index);
				break;

			default:
				return;
			}
			LLVMBuildStore(builder, value, temp_ptr);
		}
	}
Esempio n. 4
0
 // return a term that is different from t.
 bool mk_diff(expr * t, expr_ref & r) {
     sort * s = m().get_sort(t);
     if (m().is_bool(s)) {
         r = m().mk_not(t);
         return true;
     }
     family_id fid = s->get_family_id();
     if (fid == m_a_util.get_family_id()) {
         r = m_a_util.mk_add(t, m_a_util.mk_numeral(rational(1), s));
         return true;
     }
     if (fid == m_bv_util.get_family_id()) {
         r = m().mk_app(m_bv_util.get_family_id(), OP_BNOT, t);
         return true;
     }
     if (fid == m_ar_util.get_family_id()) {
         if (m().is_uninterp(get_array_range(s)))
             return false;
         unsigned arity = get_array_arity(s);
         for (unsigned i = 0; i < arity; i++)
             if (m().is_uninterp(get_array_domain(s, i)))
                 return false;
         // building 
         // r = (store t i1 ... in d)
         // where i1 ... in are arbitrary values
         // and d is a term different from (select t i1 ... in)
         ptr_buffer<expr> new_args;
         new_args.push_back(t);
         for (unsigned i = 0; i < arity; i++)
             new_args.push_back(m().get_some_value(get_array_domain(s, i)));
         expr_ref sel(m());
         sel = m().mk_app(fid, OP_SELECT, new_args.size(), new_args.c_ptr());
         expr_ref diff_sel(m());
         if (!mk_diff(sel, diff_sel))
             return false;
         new_args.push_back(diff_sel);
         r = m().mk_app(fid, OP_STORE, new_args.size(), new_args.c_ptr());
         return true;
     }
     if (fid == m_dt_util.get_family_id()) {
         // In the current implementation, I only handle the case where
         // the datatype has a recursive constructor.
         ptr_vector<func_decl> const & constructors = *m_dt_util.get_datatype_constructors(s);
         for (func_decl * constructor : constructors) {
             unsigned num    = constructor->get_arity();
             unsigned target = UINT_MAX;
             for (unsigned i = 0; i < num; i++) {
                 sort * s_arg = constructor->get_domain(i);
                 if (s == s_arg) {
                     target = i;
                     continue;
                 }
                 if (m().is_uninterp(s_arg))
                     break;
             }
             if (target == UINT_MAX)
                 continue;
             // use the constructor the distinct term constructor(...,t,...)
             ptr_buffer<expr> new_args;
             for (unsigned i = 0; i < num; i++) {
                 if (i == target) {
                     new_args.push_back(t);
                 }
                 else {
                     new_args.push_back(m().get_some_value(constructor->get_domain(i)));
                 }
             }
             r = m().mk_app(constructor, new_args.size(), new_args.c_ptr());
             return true;
         }
         // TODO: handle more cases.
         return false;
     }
     return false;
 }