Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  17.  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  18.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  21.  *
  22.  * The above copyright notice and this permission notice (including the
  23.  * next paragraph) shall be included in all copies or substantial portions
  24.  * of the Software.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  
  29. #include "util/u_debug.h"
  30.  
  31. #include "lp_bld_type.h"
  32. #include "lp_bld_debug.h"
  33. #include "lp_bld_const.h"
  34. #include "lp_bld_bitarit.h"
  35.  
  36.  
  37. /**
  38.  * Return (a | b)
  39.  */
  40. LLVMValueRef
  41. lp_build_or(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
  42. {
  43.    LLVMBuilderRef builder = bld->gallivm->builder;
  44.    const struct lp_type type = bld->type;
  45.    LLVMValueRef res;
  46.  
  47.    assert(lp_check_value(type, a));
  48.    assert(lp_check_value(type, b));
  49.  
  50.    /* can't do bitwise ops on floating-point values */
  51.    if (type.floating) {
  52.       a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
  53.       b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
  54.    }
  55.  
  56.    res = LLVMBuildOr(builder, a, b, "");
  57.  
  58.    if (type.floating) {
  59.       res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
  60.    }
  61.  
  62.    return res;
  63. }
  64.  
  65. /* bitwise XOR (a ^ b) */
  66. LLVMValueRef
  67. lp_build_xor(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
  68. {
  69.    LLVMBuilderRef builder = bld->gallivm->builder;
  70.    const struct lp_type type = bld->type;
  71.    LLVMValueRef res;
  72.  
  73.    assert(lp_check_value(type, a));
  74.    assert(lp_check_value(type, b));
  75.  
  76.    /* can't do bitwise ops on floating-point values */
  77.    if (type.floating) {
  78.       a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
  79.       b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
  80.    }
  81.  
  82.    res = LLVMBuildXor(builder, a, b, "");
  83.  
  84.    if (type.floating) {
  85.       res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
  86.    }
  87.  
  88.    return res;
  89. }
  90.  
  91. /**
  92.  * Return (a & b)
  93.  */
  94. LLVMValueRef
  95. lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
  96. {
  97.    LLVMBuilderRef builder = bld->gallivm->builder;
  98.    const struct lp_type type = bld->type;
  99.    LLVMValueRef res;
  100.  
  101.    assert(lp_check_value(type, a));
  102.    assert(lp_check_value(type, b));
  103.  
  104.    /* can't do bitwise ops on floating-point values */
  105.    if (type.floating) {
  106.       a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
  107.       b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
  108.    }
  109.  
  110.    res = LLVMBuildAnd(builder, a, b, "");
  111.  
  112.    if (type.floating) {
  113.       res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
  114.    }
  115.  
  116.    return res;
  117. }
  118.  
  119.  
  120. /**
  121.  * Return (a & ~b)
  122.  */
  123. LLVMValueRef
  124. lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
  125. {
  126.    LLVMBuilderRef builder = bld->gallivm->builder;
  127.    const struct lp_type type = bld->type;
  128.    LLVMValueRef res;
  129.  
  130.    assert(lp_check_value(type, a));
  131.    assert(lp_check_value(type, b));
  132.  
  133.    /* can't do bitwise ops on floating-point values */
  134.    if (type.floating) {
  135.       a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
  136.       b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
  137.    }
  138.  
  139.    res = LLVMBuildNot(builder, b, "");
  140.    res = LLVMBuildAnd(builder, a, res, "");
  141.  
  142.    if (type.floating) {
  143.       res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
  144.    }
  145.  
  146.    return res;
  147. }
  148.  
  149. /* bitwise NOT */
  150. LLVMValueRef
  151. lp_build_not(struct lp_build_context *bld, LLVMValueRef a)
  152. {
  153.    LLVMBuilderRef builder = bld->gallivm->builder;
  154.    const struct lp_type type = bld->type;
  155.    LLVMValueRef res;
  156.  
  157.    assert(lp_check_value(type, a));
  158.  
  159.    if (type.floating) {
  160.       a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
  161.    }
  162.    res = LLVMBuildNot(builder, a, "");
  163.    if (type.floating) {
  164.       res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
  165.    }
  166.    return res;
  167. }
  168.  
  169. /**
  170.  * Shift left.
  171.  * Result is undefined if the shift count is not smaller than the type width.
  172.  */
  173. LLVMValueRef
  174. lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
  175. {
  176.    LLVMBuilderRef builder = bld->gallivm->builder;
  177.    const struct lp_type type = bld->type;
  178.    LLVMValueRef res;
  179.  
  180.    assert(!type.floating);
  181.  
  182.    assert(lp_check_value(type, a));
  183.    assert(lp_check_value(type, b));
  184.  
  185.    (void)type;
  186.  
  187.    res = LLVMBuildShl(builder, a, b, "");
  188.  
  189.    return res;
  190. }
  191.  
  192.  
  193. /**
  194.  * Shift right.
  195.  * Result is undefined if the shift count is not smaller than the type width.
  196.  */
  197. LLVMValueRef
  198. lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
  199. {
  200.    LLVMBuilderRef builder = bld->gallivm->builder;
  201.    const struct lp_type type = bld->type;
  202.    LLVMValueRef res;
  203.  
  204.    assert(!type.floating);
  205.  
  206.    assert(lp_check_value(type, a));
  207.    assert(lp_check_value(type, b));
  208.  
  209.    if (type.sign) {
  210.       res = LLVMBuildAShr(builder, a, b, "");
  211.    } else {
  212.       res = LLVMBuildLShr(builder, a, b, "");
  213.    }
  214.  
  215.    return res;
  216. }
  217.  
  218.  
  219. /**
  220.  * Shift left with immediate.
  221.  * The immediate shift count must be smaller than the type width.
  222.  */
  223. LLVMValueRef
  224. lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
  225. {
  226.    LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
  227.    assert(imm < bld->type.width);
  228.    return lp_build_shl(bld, a, b);
  229. }
  230.  
  231.  
  232. /**
  233.  * Shift right with immediate.
  234.  * The immediate shift count must be smaller than the type width.
  235.  */
  236. LLVMValueRef
  237. lp_build_shr_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
  238. {
  239.    LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
  240.    assert(imm < bld->type.width);
  241.    return lp_build_shr(bld, a, b);
  242. }
  243.