Skip to content

Commit

Permalink
Add vfcvt for single <-> double
Browse files Browse the repository at this point in the history
  • Loading branch information
jiegec committed Dec 12, 2023
1 parent cbdcf78 commit 614b0b1
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 23 deletions.
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Vector Multiplication High

### vfmina.s/d

### vfcvf.h.s/s.d
### vfcvt.h.s

### vffint.s.l

Expand Down Expand Up @@ -282,10 +282,6 @@ Vector Multiplication High

### vfcvth.s.h

### vfcvtl.d.s

### vfcvth.d.s

### vffint.s.w/wu/d.l/d.lu

### vffintl.d.w
Expand Down
2 changes: 2 additions & 0 deletions code/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ clean:

%: %.cpp %.h
$(CXX) $< -mlsx -mlasx -o $@

.SUFFIXES:
61 changes: 43 additions & 18 deletions code/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,23 @@ union v128 {
u16 half[8];
u32 word[4];
u64 dword[2];
__int128 qword[1];
u128 qword[1];

float fp32[4];
double fp64[2];

v128(__m128i other) { m128i = other; }
v128(__m128d other) { m128d = other; }
v128(__m128 other) { m128 = other; }
v128() {
for (int i = 0; i < 8; i++) {
half[i] = rand();
}
}

operator __m128i() { return m128i; }
operator __m128() { return m128; }
operator __m128d() { return m128d; }
// duplicate with __m128i
// operator v2i64() { return __v2i64; }
operator v2u64() { return __v2u64; }
Expand All @@ -77,10 +84,20 @@ union v128 {
bool operator==(const v128 &other) const {
return memcmp(byte, other.byte, 16) == 0;
}
bool operator!=(const v128 &other) const {
return memcmp(byte, other.byte, 16) != 0;
}
};

void test();

void print(const char *s, v128 num) {
printf("v128 as __m128i %s: %016lx %016lx\n", s, num.dword[0], num.dword[1]);
printf("v128 as __m128 %s: %f %f %f %f\n", s, num.fp32[0], num.fp32[1],
num.fp32[2], num.fp32[3]);
printf("v128 as __m128d %s: %lf %lf\n", s, num.fp64[0], num.fp64[1]);
}

void print(const char *s, __m128i num) {
printf("__m128i %s: %016llx %016llx\n", s, num[0], num[1]);
}
Expand All @@ -99,37 +116,45 @@ void print(const char *s, __m128d num) {
do { \
for (int i = 0; i < 64; i++) { \
v128 a; \
PRINT(a); \
PRINT(__lsx_##func(a __VA_OPT__(, ) __VA_ARGS__)); \
PRINT(func(a __VA_OPT__(, ) __VA_ARGS__)); \
assert(func(a __VA_OPT__(, ) __VA_ARGS__) == \
__lsx_##func(a __VA_OPT__(, ) __VA_ARGS__)); \
if (func(a __VA_OPT__(, ) __VA_ARGS__) != \
__lsx_##func(a __VA_OPT__(, ) __VA_ARGS__)) { \
PRINT(a); \
PRINT(__lsx_##func(a __VA_OPT__(, ) __VA_ARGS__)); \
PRINT(func(a __VA_OPT__(, ) __VA_ARGS__)); \
assert(func(a __VA_OPT__(, ) __VA_ARGS__) == \
__lsx_##func(a __VA_OPT__(, ) __VA_ARGS__)); \
} \
} \
} while (0);

#define FUZZ2(func, ...) \
do { \
for (int i = 0; i < 64; i++) { \
v128 a, b; \
PRINT(a); \
PRINT(b); \
PRINT(__lsx_##func(a, b __VA_OPT__(, ) __VA_ARGS__)); \
PRINT(func(a, b __VA_OPT__(, ) __VA_ARGS__)); \
assert(func(a, b __VA_OPT__(, ) __VA_ARGS__) == \
__lsx_##func(a, b __VA_OPT__(, ) __VA_ARGS__)); \
if (func(a, b __VA_OPT__(, ) __VA_ARGS__) != \
__lsx_##func(a, b __VA_OPT__(, ) __VA_ARGS__)) { \
PRINT(a); \
PRINT(b); \
PRINT(__lsx_##func(a, b __VA_OPT__(, ) __VA_ARGS__)); \
PRINT(func(a, b __VA_OPT__(, ) __VA_ARGS__)); \
assert(func(a, b __VA_OPT__(, ) __VA_ARGS__) == \
__lsx_##func(a, b __VA_OPT__(, ) __VA_ARGS__)); \
} \
} \
} while (0);

#define FUZZ3(func) \
do { \
for (int i = 0; i < 64; i++) { \
v128 a, b, c; \
PRINT(a); \
PRINT(b); \
PRINT(c); \
PRINT(__lsx_##func(a, b, c)); \
PRINT(func(a, b, c)); \
assert(func(a, b, c) == __lsx_##func(a, b, c)); \
if (func(a, b, c) != __lsx_##func(a, b, c)) { \
PRINT(a); \
PRINT(b); \
PRINT(c); \
PRINT(__lsx_##func(a, b, c)); \
PRINT(func(a, b, c)); \
assert(func(a, b, c) == __lsx_##func(a, b, c)); \
} \
} \
} while (0);

Expand Down
Empty file added code/vfcmp.h
Empty file.
9 changes: 9 additions & 0 deletions code/vfcvt_s_d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "common.h"

v128 vfcvt_s_d(v128 a, v128 b) {
v128 dst;
#include "vfcvt_s_d.h"
return dst;
}

void test() { FUZZ2(vfcvt_s_d); }
7 changes: 7 additions & 0 deletions code/vfcvt_s_d.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
for (int i = 0; i < 4; i++) {
if (i < 2) {
dst.fp32[i] = b.fp64[i];
} else {
dst.fp32[i] = a.fp64[i - 2];
}
}
9 changes: 9 additions & 0 deletions code/vfcvth_d_s.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "common.h"

v128 vfcvth_d_s(v128 a) {
v128 dst;
#include "vfcvth_d_s.h"
return dst;
}

void test() { FUZZ1(vfcvth_d_s); }
3 changes: 3 additions & 0 deletions code/vfcvth_d_s.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
for (int i = 0; i < 2; i++) {
dst.fp64[i] = a.fp32[2 + i];
}
9 changes: 9 additions & 0 deletions code/vfcvtl_d_s.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "common.h"

v128 vfcvth_d_s(v128 a) {
v128 dst;
#include "vfcvth_d_s.h"
return dst;
}

void test() { FUZZ1(vfcvth_d_s); }
3 changes: 3 additions & 0 deletions code/vfcvtl_d_s.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
for (int i = 0; i < 2; i++) {
dst.fp64[i] = a.fp32[i];
}
Empty file added code/vfmadd.h
Empty file.
Empty file added code/vfmsub.h
Empty file.
Empty file added code/vfnmadd.h
Empty file.
Empty file added code/vfnmsub.h
Empty file.
65 changes: 65 additions & 0 deletions docs/lsx/float_conversion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Floating Point Conversion

## __m128d __lsx_vfcvth_d_s (__m128 a)

### Synopsis

```c++
__m128d __lsx_vfcvth_d_s (__m128 a)
#include <lsxintrin.h>
Instruction: vfcvth.d.s vr, vr
CPU Flags: LSX
```
### Description
Convert single precision floating point elements in higher half of `a` to double precision.
### Operation
```c++
{% include('vfcvth_d_s.h') %}
```

## __m128d __lsx_vfcvtl_d_s (__m128 a)

### Synopsis

```c++
__m128d __lsx_vfcvtl_d_s (__m128 a)
#include <lsxintrin.h>
Instruction: vfcvtl.d.s vr, vr
CPU Flags: LSX
```
### Description
Convert single precision floating point elements in lower half of `a` to double precision.
### Operation
```c++
{% include('vfcvtl_d_s.h') %}
```


## __m128 __lsx_vfcvt_s_d (__m128d a, __m128d b)

### Synopsis

```c++
__m128 __lsx_vfcvt_s_d (__m128a, __m128d b)
#include <lsxintrin.h>
Instruction: vfcvt.s.d vr, vr, vr
CPU Flags: LSX
```
### Description
Convert double precision floating point elements in `a` and `b` to double precision.
### Operation
```c++
{% include('vfcvt_s_d.h') %}
```

0 comments on commit 614b0b1

Please sign in to comment.