blob: 7fc2727fc8d230c841e64bda36a771980d0cb1ab [file] [log] [blame]
Nicolas Capens3b0ad202022-06-02 15:02:31 -04001// Copyright 2022 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "SIMD.hpp"
16
Nicolas Capens44f94692022-06-20 23:15:46 -040017#include "Debug.hpp"
18
19#include <cmath>
20
21namespace rr {
22
23SIMD::Int::Int()
24{
25}
26
27SIMD::Int::Int(RValue<SIMD::Float> cast)
28{
29 Value *xyzw = Nucleus::createFPToSI(cast.value(), SIMD::Int::type());
30
31 storeValue(xyzw);
32}
33
34SIMD::Int::Int(int broadcast)
35{
36 std::vector<int64_t> constantVector = { broadcast };
37 storeValue(Nucleus::createConstantVector(constantVector, type()));
38}
Nicolas Capens3b0ad202022-06-02 15:02:31 -040039
40SIMD::Int::Int(RValue<SIMD::Int> rhs)
41{
42 store(rhs);
43}
44
Nicolas Capens44f94692022-06-20 23:15:46 -040045SIMD::Int::Int(const SIMD::Int &rhs)
46{
47 store(rhs.load());
48}
49
Nicolas Capens3b0ad202022-06-02 15:02:31 -040050SIMD::Int::Int(const Reference<SIMD::Int> &rhs)
51{
Nicolas Capens44f94692022-06-20 23:15:46 -040052 store(rhs.load());
53}
54
55SIMD::Int::Int(RValue<SIMD::UInt> rhs)
56{
57 storeValue(rhs.value());
58}
59
60SIMD::Int::Int(const SIMD::UInt &rhs)
61{
Nicolas Capens3b0ad202022-06-02 15:02:31 -040062 storeValue(rhs.loadValue());
63}
64
Nicolas Capens44f94692022-06-20 23:15:46 -040065SIMD::Int::Int(const Reference<SIMD::UInt> &rhs)
66{
67 storeValue(rhs.loadValue());
68}
69
70SIMD::Int::Int(const scalar::Int &rhs)
71{
72 *this = RValue<scalar::Int>(rhs.loadValue());
73}
74
75SIMD::Int::Int(const Reference<scalar::Int> &rhs)
76{
77 *this = RValue<scalar::Int>(rhs.loadValue());
78}
79
80RValue<SIMD::Int> SIMD::Int::operator=(int x)
81{
82 return *this = SIMD::Int(x);
83}
84
85RValue<SIMD::Int> SIMD::Int::operator=(RValue<SIMD::Int> rhs)
86{
87 return store(rhs);
88}
89
90RValue<SIMD::Int> SIMD::Int::operator=(const SIMD::Int &rhs)
91{
92 return store(rhs.load());
93}
94
95RValue<SIMD::Int> SIMD::Int::operator=(const Reference<SIMD::Int> &rhs)
96{
97 return store(rhs.load());
98}
99
Nicolas Capens3b0ad202022-06-02 15:02:31 -0400100RValue<SIMD::Int> operator+(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
101{
102 return RValue<SIMD::Int>(Nucleus::createAdd(lhs.value(), rhs.value()));
103}
104
Nicolas Capens44f94692022-06-20 23:15:46 -0400105RValue<SIMD::Int> operator-(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
106{
107 return RValue<SIMD::Int>(Nucleus::createSub(lhs.value(), rhs.value()));
108}
109
110RValue<SIMD::Int> operator*(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
111{
112 return RValue<SIMD::Int>(Nucleus::createMul(lhs.value(), rhs.value()));
113}
114
115RValue<SIMD::Int> operator/(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
116{
117 return RValue<SIMD::Int>(Nucleus::createSDiv(lhs.value(), rhs.value()));
118}
119
120RValue<SIMD::Int> operator%(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
121{
122 return RValue<SIMD::Int>(Nucleus::createSRem(lhs.value(), rhs.value()));
123}
124
125RValue<SIMD::Int> operator&(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
126{
127 return RValue<SIMD::Int>(Nucleus::createAnd(lhs.value(), rhs.value()));
128}
129
130RValue<SIMD::Int> operator|(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
131{
132 return RValue<SIMD::Int>(Nucleus::createOr(lhs.value(), rhs.value()));
133}
134
135RValue<SIMD::Int> operator^(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
136{
137 return RValue<SIMD::Int>(Nucleus::createXor(lhs.value(), rhs.value()));
138}
139
140RValue<SIMD::Int> operator<<(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
141{
142 return RValue<SIMD::Int>(Nucleus::createShl(lhs.value(), rhs.value()));
143}
144
145RValue<SIMD::Int> operator>>(RValue<SIMD::Int> lhs, RValue<SIMD::Int> rhs)
146{
147 return RValue<SIMD::Int>(Nucleus::createAShr(lhs.value(), rhs.value()));
148}
149
150RValue<SIMD::Int> operator+=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
151{
152 return lhs = lhs + rhs;
153}
154
155RValue<SIMD::Int> operator-=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
156{
157 return lhs = lhs - rhs;
158}
159
160RValue<SIMD::Int> operator*=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
161{
162 return lhs = lhs * rhs;
163}
164
165// RValue<SIMD::Int> operator/=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
166// {
167// return lhs = lhs / rhs;
168// }
169
170// RValue<SIMD::Int> operator%=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
171// {
172// return lhs = lhs % rhs;
173// }
174
175RValue<SIMD::Int> operator&=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
176{
177 return lhs = lhs & rhs;
178}
179
180RValue<SIMD::Int> operator|=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
181{
182 return lhs = lhs | rhs;
183}
184
185RValue<SIMD::Int> operator^=(SIMD::Int &lhs, RValue<SIMD::Int> rhs)
186{
187 return lhs = lhs ^ rhs;
188}
189
190RValue<SIMD::Int> operator<<=(SIMD::Int &lhs, unsigned char rhs)
191{
192 return lhs = lhs << rhs;
193}
194
195RValue<SIMD::Int> operator>>=(SIMD::Int &lhs, unsigned char rhs)
196{
197 return lhs = lhs >> rhs;
198}
199
200RValue<SIMD::Int> operator+(RValue<SIMD::Int> val)
201{
202 return val;
203}
204
205RValue<SIMD::Int> operator-(RValue<SIMD::Int> val)
206{
207 return RValue<SIMD::Int>(Nucleus::createNeg(val.value()));
208}
209
210RValue<SIMD::Int> operator~(RValue<SIMD::Int> val)
211{
212 return RValue<SIMD::Int>(Nucleus::createNot(val.value()));
213}
214
215RValue<scalar::Int> Extract(RValue<SIMD::Int> x, int i)
216{
217 return RValue<scalar::Int>(Nucleus::createExtractElement(x.value(), scalar::Int::type(), i));
218}
219
220RValue<SIMD::Int> Insert(RValue<SIMD::Int> x, RValue<scalar::Int> element, int i)
221{
222 return RValue<SIMD::Int>(Nucleus::createInsertElement(x.value(), element.value(), i));
223}
224
225SIMD::UInt::UInt()
226{
227}
228
229SIMD::UInt::UInt(int broadcast)
230{
231 std::vector<int64_t> constantVector = { broadcast };
232 storeValue(Nucleus::createConstantVector(constantVector, type()));
233}
234
235SIMD::UInt::UInt(RValue<SIMD::UInt> rhs)
236{
237 store(rhs);
238}
239
240SIMD::UInt::UInt(const SIMD::UInt &rhs)
241{
242 store(rhs.load());
243}
244
245SIMD::UInt::UInt(const Reference<SIMD::UInt> &rhs)
246{
247 store(rhs.load());
248}
249
250SIMD::UInt::UInt(RValue<SIMD::Int> rhs)
251{
252 storeValue(rhs.value());
253}
254
255SIMD::UInt::UInt(const SIMD::Int &rhs)
256{
257 storeValue(rhs.loadValue());
258}
259
260SIMD::UInt::UInt(const Reference<SIMD::Int> &rhs)
261{
262 storeValue(rhs.loadValue());
263}
264
265SIMD::UInt::UInt(const scalar::UInt &rhs)
266{
267 *this = RValue<scalar::UInt>(rhs.loadValue());
268}
269
270SIMD::UInt::UInt(const Reference<scalar::UInt> &rhs)
271{
272 *this = RValue<scalar::UInt>(rhs.loadValue());
273}
274
275RValue<SIMD::UInt> SIMD::UInt::operator=(RValue<SIMD::UInt> rhs)
276{
277 return store(rhs);
278}
279
280RValue<SIMD::UInt> SIMD::UInt::operator=(const SIMD::UInt &rhs)
281{
282 return store(rhs.load());
283}
284
285RValue<SIMD::UInt> SIMD::UInt::operator=(const Reference<SIMD::UInt> &rhs)
286{
287 return store(rhs.load());
288}
289
290RValue<SIMD::UInt> operator+(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
291{
292 return RValue<SIMD::UInt>(Nucleus::createAdd(lhs.value(), rhs.value()));
293}
294
295RValue<SIMD::UInt> operator-(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
296{
297 return RValue<SIMD::UInt>(Nucleus::createSub(lhs.value(), rhs.value()));
298}
299
300RValue<SIMD::UInt> operator*(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
301{
302 return RValue<SIMD::UInt>(Nucleus::createMul(lhs.value(), rhs.value()));
303}
304
305RValue<SIMD::UInt> operator/(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
306{
307 return RValue<SIMD::UInt>(Nucleus::createUDiv(lhs.value(), rhs.value()));
308}
309
310RValue<SIMD::UInt> operator%(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
311{
312 return RValue<SIMD::UInt>(Nucleus::createURem(lhs.value(), rhs.value()));
313}
314
315RValue<SIMD::UInt> operator&(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
316{
317 return RValue<SIMD::UInt>(Nucleus::createAnd(lhs.value(), rhs.value()));
318}
319
320RValue<SIMD::UInt> operator|(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
321{
322 return RValue<SIMD::UInt>(Nucleus::createOr(lhs.value(), rhs.value()));
323}
324
325RValue<SIMD::UInt> operator^(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
326{
327 return RValue<SIMD::UInt>(Nucleus::createXor(lhs.value(), rhs.value()));
328}
329
330RValue<SIMD::UInt> operator<<(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
331{
332 return RValue<SIMD::UInt>(Nucleus::createShl(lhs.value(), rhs.value()));
333}
334
335RValue<SIMD::UInt> operator>>(RValue<SIMD::UInt> lhs, RValue<SIMD::UInt> rhs)
336{
337 return RValue<SIMD::UInt>(Nucleus::createLShr(lhs.value(), rhs.value()));
338}
339
340RValue<SIMD::UInt> operator+=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
341{
342 return lhs = lhs + rhs;
343}
344
345RValue<SIMD::UInt> operator-=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
346{
347 return lhs = lhs - rhs;
348}
349
350RValue<SIMD::UInt> operator*=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
351{
352 return lhs = lhs * rhs;
353}
354
355// RValue<SIMD::UInt> operator/=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
356// {
357// return lhs = lhs / rhs;
358// }
359
360// RValue<SIMD::UInt> operator%=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
361// {
362// return lhs = lhs % rhs;
363// }
364
365RValue<SIMD::UInt> operator&=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
366{
367 return lhs = lhs & rhs;
368}
369
370RValue<SIMD::UInt> operator|=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
371{
372 return lhs = lhs | rhs;
373}
374
375RValue<SIMD::UInt> operator^=(SIMD::UInt &lhs, RValue<SIMD::UInt> rhs)
376{
377 return lhs = lhs ^ rhs;
378}
379
380RValue<SIMD::UInt> operator<<=(SIMD::UInt &lhs, unsigned char rhs)
381{
382 return lhs = lhs << rhs;
383}
384
385RValue<SIMD::UInt> operator>>=(SIMD::UInt &lhs, unsigned char rhs)
386{
387 return lhs = lhs >> rhs;
388}
389
390RValue<SIMD::UInt> operator+(RValue<SIMD::UInt> val)
391{
392 return val;
393}
394
395RValue<SIMD::UInt> operator-(RValue<SIMD::UInt> val)
396{
397 return RValue<SIMD::UInt>(Nucleus::createNeg(val.value()));
398}
399
400RValue<SIMD::UInt> operator~(RValue<SIMD::UInt> val)
401{
402 return RValue<SIMD::UInt>(Nucleus::createNot(val.value()));
403}
404
405RValue<scalar::UInt> Extract(RValue<SIMD::UInt> x, int i)
406{
407 return RValue<scalar::UInt>(Nucleus::createExtractElement(x.value(), scalar::Int::type(), i));
408}
409
410RValue<SIMD::UInt> Insert(RValue<SIMD::UInt> x, RValue<scalar::UInt> element, int i)
411{
412 return RValue<SIMD::UInt>(Nucleus::createInsertElement(x.value(), element.value(), i));
413}
414
415SIMD::Float::Float(RValue<SIMD::Int> cast)
416{
417 Value *xyzw = Nucleus::createSIToFP(cast.value(), SIMD::Float::type());
418
419 storeValue(xyzw);
420}
421
422SIMD::Float::Float(RValue<SIMD::UInt> cast)
423{
424 RValue<SIMD::Float> result = SIMD::Float(SIMD::Int(cast & SIMD::UInt(0x7FFFFFFF))) +
425 As<SIMD::Float>((As<SIMD::Int>(cast) >> 31) & As<SIMD::Int>(SIMD::Float(0x80000000u)));
426
427 storeValue(result.value());
428}
429
430SIMD::Float::Float()
431{
432}
433
434SIMD::Float::Float(float broadcast)
435{
436 // See rr::Float(float) constructor for the rationale behind this assert.
437 ASSERT(std::isfinite(broadcast));
438
439 std::vector<double> constantVector = { broadcast };
440 storeValue(Nucleus::createConstantVector(constantVector, type()));
441}
442
443SIMD::Float SIMD::Float::infinity()
444{
445 SIMD::Float result;
446
447 constexpr double inf = std::numeric_limits<double>::infinity();
448 std::vector<double> constantVector = { inf };
449 result.storeValue(Nucleus::createConstantVector(constantVector, type()));
450
451 return result;
452}
453
454SIMD::Float::Float(RValue<SIMD::Float> rhs)
455{
456 store(rhs);
457}
458
459SIMD::Float::Float(const SIMD::Float &rhs)
460{
461 store(rhs.load());
462}
463
464SIMD::Float::Float(const Reference<SIMD::Float> &rhs)
465{
466 store(rhs.load());
467}
468
469SIMD::Float::Float(const scalar::Float &rhs)
470{
471 *this = RValue<scalar::Float>(rhs.loadValue());
472}
473
474SIMD::Float::Float(const Reference<scalar::Float> &rhs)
475{
476 *this = RValue<scalar::Float>(rhs.loadValue());
477}
478
479RValue<SIMD::Float> SIMD::Float::operator=(float x)
480{
481 return *this = SIMD::Float(x);
482}
483
484RValue<SIMD::Float> SIMD::Float::operator=(RValue<SIMD::Float> rhs)
485{
486 return store(rhs);
487}
488
489RValue<SIMD::Float> SIMD::Float::operator=(const SIMD::Float &rhs)
490{
491 return store(rhs.load());
492}
493
494RValue<SIMD::Float> SIMD::Float::operator=(const Reference<SIMD::Float> &rhs)
495{
496 return store(rhs.load());
497}
498
499RValue<SIMD::Float> SIMD::Float::operator=(RValue<scalar::Float> rhs)
500{
501 return *this = SIMD::Float(rhs);
502}
503
504RValue<SIMD::Float> SIMD::Float::operator=(const scalar::Float &rhs)
505{
506 return *this = SIMD::Float(rhs);
507}
508
509RValue<SIMD::Float> SIMD::Float::operator=(const Reference<scalar::Float> &rhs)
510{
511 return *this = SIMD::Float(rhs);
512}
513
514RValue<SIMD::Float> operator+(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
515{
516 return RValue<SIMD::Float>(Nucleus::createFAdd(lhs.value(), rhs.value()));
517}
518
519RValue<SIMD::Float> operator-(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
520{
521 return RValue<SIMD::Float>(Nucleus::createFSub(lhs.value(), rhs.value()));
522}
523
524RValue<SIMD::Float> operator*(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
525{
526 return RValue<SIMD::Float>(Nucleus::createFMul(lhs.value(), rhs.value()));
527}
528
529RValue<SIMD::Float> operator/(RValue<SIMD::Float> lhs, RValue<SIMD::Float> rhs)
530{
531 return RValue<SIMD::Float>(Nucleus::createFDiv(lhs.value(), rhs.value()));
532}
533
534RValue<SIMD::Float> operator+=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
535{
536 return lhs = lhs + rhs;
537}
538
539RValue<SIMD::Float> operator-=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
540{
541 return lhs = lhs - rhs;
542}
543
544RValue<SIMD::Float> operator*=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
545{
546 return lhs = lhs * rhs;
547}
548
549RValue<SIMD::Float> operator/=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
550{
551 return lhs = lhs / rhs;
552}
553
554RValue<SIMD::Float> operator%=(SIMD::Float &lhs, RValue<SIMD::Float> rhs)
555{
556 return lhs = lhs % rhs;
557}
558
559RValue<SIMD::Float> operator+(RValue<SIMD::Float> val)
560{
561 return val;
562}
563
564RValue<SIMD::Float> operator-(RValue<SIMD::Float> val)
565{
566 return RValue<SIMD::Float>(Nucleus::createFNeg(val.value()));
567}
568
569RValue<SIMD::Float> Insert(RValue<SIMD::Float> x, RValue<scalar::Float> element, int i)
570{
571 return RValue<SIMD::Float>(Nucleus::createInsertElement(x.value(), element.value(), i));
572}
573
574RValue<scalar::Float> Extract(RValue<SIMD::Float> x, int i)
575{
576 return RValue<scalar::Float>(Nucleus::createExtractElement(x.value(), scalar::Float::type(), i));
577}
578
579RValue<SIMD::Int> IsInf(RValue<SIMD::Float> x)
580{
581 return CmpEQ(As<SIMD::Int>(x) & SIMD::Int(0x7FFFFFFF), SIMD::Int(0x7F800000));
582}
583
584RValue<SIMD::Int> IsNan(RValue<SIMD::Float> x)
585{
586 return ~CmpEQ(x, x);
587}
588
589RValue<SIMD::Float> Sin(RValue<SIMD::Float> x)
590{
591 return ScalarizeCall(sinf, x);
592}
593
594RValue<SIMD::Float> Cos(RValue<SIMD::Float> x)
595{
596 return ScalarizeCall(cosf, x);
597}
598
599RValue<SIMD::Float> Tan(RValue<SIMD::Float> x)
600{
601 return ScalarizeCall(tanf, x);
602}
603
604RValue<SIMD::Float> Asin(RValue<SIMD::Float> x)
605{
606 return ScalarizeCall(asinf, x);
607}
608
609RValue<SIMD::Float> Acos(RValue<SIMD::Float> x)
610{
611 return ScalarizeCall(acosf, x);
612}
613
614RValue<SIMD::Float> Atan(RValue<SIMD::Float> x)
615{
616 return ScalarizeCall(atanf, x);
617}
618
619RValue<SIMD::Float> Sinh(RValue<SIMD::Float> x)
620{
621 return ScalarizeCall(sinhf, x);
622}
623
624RValue<SIMD::Float> Cosh(RValue<SIMD::Float> x)
625{
626 return ScalarizeCall(coshf, x);
627}
628
629RValue<SIMD::Float> Tanh(RValue<SIMD::Float> x)
630{
631 return ScalarizeCall(tanhf, x);
632}
633
634RValue<SIMD::Float> Asinh(RValue<SIMD::Float> x)
635{
636 return ScalarizeCall(asinhf, x);
637}
638
639RValue<SIMD::Float> Acosh(RValue<SIMD::Float> x)
640{
641 return ScalarizeCall(acoshf, x);
642}
643
644RValue<SIMD::Float> Atanh(RValue<SIMD::Float> x)
645{
646 return ScalarizeCall(atanhf, x);
647}
648
649RValue<SIMD::Float> Atan2(RValue<SIMD::Float> x, RValue<SIMD::Float> y)
650{
651 return ScalarizeCall(atan2f, x, y);
652}
653
654RValue<SIMD::Float> Pow(RValue<SIMD::Float> x, RValue<SIMD::Float> y)
655{
656 return ScalarizeCall(powf, x, y);
657}
658
659RValue<SIMD::Float> Exp(RValue<SIMD::Float> x)
660{
661 return ScalarizeCall(expf, x);
662}
663
664RValue<SIMD::Float> Log(RValue<SIMD::Float> x)
665{
666 return ScalarizeCall(logf, x);
667}
668
669RValue<SIMD::Float> Exp2(RValue<SIMD::Float> x)
670{
671 return ScalarizeCall(exp2f, x);
672}
673
674RValue<SIMD::Float> Log2(RValue<SIMD::Float> x)
675{
676 return ScalarizeCall(log2f, x);
677}
678
679} // namespace rr