Skip to content

Commit 3634381

Browse files
author
Marcin Kościelnicki
committed
hwtest/g80_fp: Add f2i test.
1 parent 26099fd commit 3634381

File tree

3 files changed

+105
-3
lines changed

3 files changed

+105
-3
lines changed

hwtest/g80_fp.c

+83
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ static int fp_check_data(struct hwtest_ctx *ctx, uint32_t op1, uint32_t op2, con
182182
int sop;
183183
int rm;
184184
bool neg = false;
185+
uint64_t t64;
185186
switch (op) {
186187
case 0xa2: /* i2f */
187188
case 0xa3: /* i2f */
@@ -239,6 +240,57 @@ static int fp_check_data(struct hwtest_ctx *ctx, uint32_t op1, uint32_t op2, con
239240
ecc = fp32_cmp(exp, 0);
240241
}
241242
break;
243+
case 0xa4: /* f2i */
244+
case 0xa5: /* f2i */
245+
if (!(op2 & 0x00004000))
246+
s1 = fp16_to_fp32(s1);
247+
if (op2 & 0x00100000)
248+
s1 &= ~0x80000000;
249+
if (op2 & 0x20000000)
250+
s1 ^= 0x80000000;
251+
rm = op2 >> 17 & 3;
252+
if (s1 & 0x80000000) {
253+
neg = true;
254+
s1 ^= 0x80000000;
255+
rm = fp_flip_rm(rm);
256+
}
257+
t64 = fp32_to_u64(s1, rm);
258+
if (t64 >> 32)
259+
t64 = 0xffffffff;
260+
exp = t64;
261+
if (op2 & 0x08000000) {
262+
uint32_t limit = op2 & 0x04000000 ? 0x80000000 : 0x8000;
263+
if (neg) {
264+
if (exp > limit)
265+
exp = limit;
266+
exp = -exp;
267+
} else {
268+
if (exp >= limit)
269+
exp = limit - 1;
270+
}
271+
} else if (neg) {
272+
exp = 0;
273+
} else if (!(op2 & 0x04000000) && exp >= 0x10000) {
274+
exp = 0xffff;
275+
}
276+
if (op2 & 0x04000000) {
277+
if (exp & 0x80000000)
278+
ecc = 2;
279+
else if (exp == 0)
280+
ecc = 1;
281+
else
282+
ecc = 0;
283+
} else {
284+
exp &= 0xffff;
285+
real &= 0xffff;
286+
if (exp & 0x8000)
287+
ecc = 2;
288+
else if (exp == 0)
289+
ecc = 1;
290+
else
291+
ecc = 0;
292+
}
293+
break;
242294
case 0xa6: /* f2f */
243295
case 0xa7: /* f2f */
244296
if (!(op2 & 0x00004000))
@@ -740,6 +792,36 @@ static int test_i2f(struct hwtest_ctx *ctx) {
740792
return HWTEST_RES_PASS;
741793
}
742794

795+
static int test_f2i(struct hwtest_ctx *ctx) {
796+
int i;
797+
for (i = 0; i < 100000; i++) {
798+
uint32_t op1 = 0xa0000001 | (jrand48(ctx->rand48) & 0x0fff0000);
799+
uint32_t op2 = 0x800007c0 | (jrand48(ctx->rand48) & 0x3fdff004);
800+
/* Select proper source/destination for fp32 vs fp16 */
801+
if (op2 & 0x04000000)
802+
op1 |= 0x1c;
803+
else
804+
op1 |= 0x38;
805+
if (op2 & 0x00004000)
806+
op1 |= 0x800;
807+
else
808+
op1 |= 0x1000;
809+
/* This bit selects fp64 on G200+ */
810+
if (ctx->chipset >= 0xa0)
811+
op2 &= ~0x00400000;
812+
uint32_t xtra = jrand48(ctx->rand48);
813+
if (fp_prep_grid(ctx, xtra))
814+
return HWTEST_RES_FAIL;
815+
if (fp_prep_code(ctx, op1, op2))
816+
return HWTEST_RES_FAIL;
817+
uint32_t src1[0x200], src2[0x200], src3[0x200];
818+
fp_gen(ctx, src1, src2, src3);
819+
if (fp_test(ctx, op1, op2, src1, src2, src3, xtra))
820+
return HWTEST_RES_FAIL;
821+
}
822+
return HWTEST_RES_PASS;
823+
}
824+
743825
static int test_f2f(struct hwtest_ctx *ctx) {
744826
int i;
745827
for (i = 0; i < 100000; i++) {
@@ -785,5 +867,6 @@ HWTEST_DEF_GROUP(g80_fp,
785867
HWTEST_TEST(test_fmul_i, 0),
786868
HWTEST_TEST(test_fmad_i, 0),
787869
HWTEST_TEST(test_i2f, 0),
870+
HWTEST_TEST(test_f2i, 0),
788871
HWTEST_TEST(test_f2f, 0),
789872
)

include/nvhw/fp.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,13 @@ uint64_t fp16_to_fp64(uint16_t x);
8282
uint16_t fp64_to_fp16(uint64_t x);
8383
#endif
8484

85-
#if 0
8685
/* f2i */
87-
uint64_t fp32_to_u64(uint32_t x);
86+
uint64_t fp32_to_u64(uint32_t x, enum fp_rm rm);
87+
#if 0
8888
uint64_t fp64_to_u64(uint64_t x);
89+
#endif
8990

9091
/* i2f */
91-
#endif
9292
uint32_t fp32_from_u64(uint64_t x, enum fp_rm rm);
9393
#if 0
9494
uint64_t fp64_from_u64(uint64_t x);

nvhw/fp.c

+19
Original file line numberDiff line numberDiff line change
@@ -658,3 +658,22 @@ uint32_t fp32_from_u64(uint64_t x, enum fp_rm rm) {
658658
}
659659
return ex << 23 | fx;
660660
}
661+
662+
uint64_t fp32_to_u64(uint32_t x, enum fp_rm rm) {
663+
x = fp32_rint(x, rm);
664+
bool sx = FP32_SIGN(x);
665+
int ex = FP32_EXP(x);
666+
uint64_t fx = FP32_FRACT(x);
667+
if (ex == FP32_MAXE && fx)
668+
return 0;
669+
if (sx || !ex)
670+
return 0;
671+
fx |= FP32_IONE;
672+
ex -= FP32_MIDE + 23;
673+
if (ex < 0)
674+
return fx >> -ex;
675+
else if (ex <= 40)
676+
return fx << ex;
677+
else
678+
return -1ull;
679+
}

0 commit comments

Comments
 (0)