lp_bld_bitarit.c revision 6299f241e9fdd86e705d144a42d9b1979c13f9ad
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 */
40LLVMValueRef
41lp_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
66/**
67 * Return (a & b)
68 */
69LLVMValueRef
70lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
71{
72   LLVMBuilderRef builder = bld->gallivm->builder;
73   const struct lp_type type = bld->type;
74   LLVMValueRef res;
75
76   assert(lp_check_value(type, a));
77   assert(lp_check_value(type, b));
78
79   /* can't do bitwise ops on floating-point values */
80   if (type.floating) {
81      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
82      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
83   }
84
85   res = LLVMBuildAnd(builder, a, b, "");
86
87   if (type.floating) {
88      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
89   }
90
91   return res;
92}
93
94
95/**
96 * Return (a & ~b)
97 */
98LLVMValueRef
99lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
100{
101   LLVMBuilderRef builder = bld->gallivm->builder;
102   const struct lp_type type = bld->type;
103   LLVMValueRef res;
104
105   assert(lp_check_value(type, a));
106   assert(lp_check_value(type, b));
107
108   /* can't do bitwise ops on floating-point values */
109   if (type.floating) {
110      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
111      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
112   }
113
114   res = LLVMBuildNot(builder, b, "");
115   res = LLVMBuildAnd(builder, a, res, "");
116
117   if (type.floating) {
118      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
119   }
120
121   return res;
122}
123
124
125/**
126 * Shift left.
127 */
128LLVMValueRef
129lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
130{
131   LLVMBuilderRef builder = bld->gallivm->builder;
132   const struct lp_type type = bld->type;
133   LLVMValueRef res;
134
135   assert(!type.floating);
136
137   assert(lp_check_value(type, a));
138   assert(lp_check_value(type, b));
139
140   res = LLVMBuildShl(builder, a, b, "");
141
142   return res;
143}
144
145
146/**
147 * Shift right.
148 */
149LLVMValueRef
150lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
151{
152   LLVMBuilderRef builder = bld->gallivm->builder;
153   const struct lp_type type = bld->type;
154   LLVMValueRef res;
155
156   assert(!type.floating);
157
158   assert(lp_check_value(type, a));
159   assert(lp_check_value(type, b));
160
161   if (type.sign) {
162      res = LLVMBuildAShr(builder, a, b, "");
163   } else {
164      res = LLVMBuildLShr(builder, a, b, "");
165   }
166
167   return res;
168}
169
170
171/**
172 * Shift left with immediate.
173 */
174LLVMValueRef
175lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
176{
177   LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
178   assert(imm <= bld->type.width);
179   return lp_build_shl(bld, a, b);
180}
181
182
183/**
184 * Shift right with immediate.
185 */
186LLVMValueRef
187lp_build_shr_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
188{
189   LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
190   assert(imm <= bld->type.width);
191   return lp_build_shr(bld, a, b);
192}
193