diff options
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_bitarit.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c | 24 |
2 files changed, 24 insertions, 8 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c b/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c index 97ae1622c27..9892d7aa2b8 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_bitarit.c @@ -168,6 +168,7 @@ lp_build_not(struct lp_build_context *bld, LLVMValueRef a) /** * Shift left. + * Result is undefined if the shift count is not smaller than the type width. */ LLVMValueRef lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) @@ -189,6 +190,7 @@ lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) /** * Shift right. + * Result is undefined if the shift count is not smaller than the type width. */ LLVMValueRef lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) @@ -214,23 +216,25 @@ lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) /** * Shift left with immediate. + * The immediate shift count must be smaller than the type width. */ LLVMValueRef lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm) { LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm); - assert(imm <= bld->type.width); + assert(imm < bld->type.width); return lp_build_shl(bld, a, b); } /** * Shift right with immediate. + * The immediate shift count must be smaller than the type width. */ LLVMValueRef lp_build_shr_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm) { LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm); - assert(imm <= bld->type.width); + assert(imm < bld->type.width); return lp_build_shr(bld, a, b); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c index d16ccae37fb..f46166101da 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c @@ -1203,8 +1203,12 @@ ishr_emit_cpu( struct lp_build_tgsi_context * bld_base, struct lp_build_emit_data * emit_data) { - emit_data->output[emit_data->chan] = lp_build_shr(&bld_base->int_bld, - emit_data->args[0], emit_data->args[1]); + struct lp_build_context *int_bld = &bld_base->int_bld; + LLVMValueRef mask = lp_build_const_vec(int_bld->gallivm, int_bld->type, + int_bld->type.width - 1); + LLVMValueRef masked_count = lp_build_and(int_bld, emit_data->args[1], mask); + emit_data->output[emit_data->chan] = lp_build_shr(int_bld, emit_data->args[0], + masked_count); } /* TGSI_OPCODE_ISLT (CPU Only) */ @@ -1439,8 +1443,12 @@ shl_emit_cpu( struct lp_build_tgsi_context * bld_base, struct lp_build_emit_data * emit_data) { - emit_data->output[emit_data->chan] = lp_build_shl(&bld_base->uint_bld, - emit_data->args[0], emit_data->args[1]); + struct lp_build_context *uint_bld = &bld_base->uint_bld; + LLVMValueRef mask = lp_build_const_vec(uint_bld->gallivm, uint_bld->type, + uint_bld->type.width - 1); + LLVMValueRef masked_count = lp_build_and(uint_bld, emit_data->args[1], mask); + emit_data->output[emit_data->chan] = lp_build_shl(uint_bld, emit_data->args[0], + masked_count); } /* TGSI_OPCODE_SIN (CPU Only) */ @@ -1647,8 +1655,12 @@ ushr_emit_cpu( struct lp_build_tgsi_context * bld_base, struct lp_build_emit_data * emit_data) { - emit_data->output[emit_data->chan] = lp_build_shr(&bld_base->uint_bld, - emit_data->args[0], emit_data->args[1]); + struct lp_build_context *uint_bld = &bld_base->uint_bld; + LLVMValueRef mask = lp_build_const_vec(uint_bld->gallivm, uint_bld->type, + uint_bld->type.width - 1); + LLVMValueRef masked_count = lp_build_and(uint_bld, emit_data->args[1], mask); + emit_data->output[emit_data->chan] = lp_build_shr(uint_bld, emit_data->args[0], + masked_count); } /* TGSI_OPCODE_ISLT (CPU Only) */ |