Skip to content

Commit c75b2e0

Browse files
committed
test: Floating point memory instructions
1 parent 4a85bf5 commit c75b2e0

1 file changed

Lines changed: 202 additions & 0 deletions

File tree

test/unittests/execute_floating_point_test.cpp

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,205 @@ TYPED_TEST(execute_floating_point_trunc, trunc)
417417
EXPECT_EQ(result.value.template as<IntT>(), FloatT{-1});
418418
}
419419
}
420+
421+
TEST(execute_floating_point, f32_load)
422+
{
423+
/* wat2wasm
424+
(memory 1 1)
425+
(data (i32.const 0) "\00\00\00\00") ;; 0
426+
(data (i32.const 4) "\b6\f3\9d\3f") ;; 1.234
427+
(data (i32.const 8) "\b6\f3\9d\bf") ;; -1.234
428+
(data (i32.const 12) "\00\00\c0\7f") ;; canonical NaN
429+
(data (i32.const 16) "\01\00\c0\7f") ;; arithmetic NaN
430+
(data (i32.const 20) "\01\00\80\7f") ;; signaling NaN
431+
(func (param i32) (result f32)
432+
(f32.load (local.get 0))
433+
)
434+
*/
435+
const auto wasm = from_hex(
436+
"0061736d0100000001060160017f017d0302010005030100010a0901070020002a02000b0b37060041000b0400"
437+
"0000000041040b04b6f39d3f0041080b04b6f39dbf00410c0b040000c07f0041100b040100c07f0041140b0401"
438+
"00807f");
439+
440+
auto instance = instantiate(parse(wasm));
441+
EXPECT_THAT(execute(*instance, 0, {0}), Result(0.0f));
442+
EXPECT_THAT(execute(*instance, 0, {4}), Result(1.234f));
443+
EXPECT_THAT(execute(*instance, 0, {8}), Result(-1.234f));
444+
EXPECT_THAT(execute(*instance, 0, {12}), Result(FP32::nan(FP32::canon)));
445+
EXPECT_THAT(execute(*instance, 0, {16}), Result(FP32::nan(FP32::canon + 1)));
446+
EXPECT_THAT(execute(*instance, 0, {20}), Result(FP32::nan(1)));
447+
448+
EXPECT_THAT(execute(*instance, 0, {65534}), Traps());
449+
EXPECT_THAT(execute(*instance, 0, {65537}), Traps());
450+
}
451+
452+
TEST(execute_floating_point, f32_load_overflow)
453+
{
454+
/* wat2wasm
455+
(memory 1 1)
456+
(func (param i32) (result f32)
457+
get_local 0
458+
f32.load offset=0x7fffffff
459+
)
460+
*/
461+
const auto wasm = from_hex(
462+
"0061736d0100000001060160017f017d0302010005030100010a0d010b0020002a02ffffffff070b");
463+
464+
auto instance = instantiate(parse(wasm));
465+
466+
// Offset is 0x7fffffff + 0 => 0x7fffffff
467+
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
468+
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
469+
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
470+
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
471+
EXPECT_THAT(execute(*instance, 0, {0x80000001}), Traps());
472+
}
473+
474+
TEST(execute_floating_point, f64_load)
475+
{
476+
/* wat2wasm
477+
(memory 1 1)
478+
(data (i32.const 0) "\00\00\00\00\00\00\00\00") ;; 0
479+
(data (i32.const 8) "\58\39\b4\c8\76\be\f3\3f") ;; 1.234
480+
(data (i32.const 16) "\58\39\b4\c8\76\be\f3\bf") ;; -1.234
481+
(data (i32.const 24) "\00\00\00\00\00\00\f8\7f") ;; canonical NaN
482+
(data (i32.const 32) "\01\00\00\00\00\00\f8\7f") ;; arithmetic NaN
483+
(data (i32.const 40) "\01\00\00\00\00\00\f0\7f") ;; signaling NaN
484+
(func (param i32) (result f64)
485+
(f64.load (local.get 0))
486+
)
487+
*/
488+
const auto wasm = from_hex(
489+
"0061736d0100000001060160017f017c0302010005030100010a0901070020002b03000b0b4f060041000b0800"
490+
"000000000000000041080b085839b4c876bef33f0041100b085839b4c876bef3bf0041180b08000000000000f8"
491+
"7f0041200b08010000000000f87f0041280b08010000000000f07f");
492+
493+
auto instance = instantiate(parse(wasm));
494+
EXPECT_THAT(execute(*instance, 0, {0}), Result(0.0));
495+
EXPECT_THAT(execute(*instance, 0, {8}), Result(1.234));
496+
EXPECT_THAT(execute(*instance, 0, {16}), Result(-1.234));
497+
EXPECT_THAT(execute(*instance, 0, {24}), Result(FP64::nan(FP64::canon)));
498+
EXPECT_THAT(execute(*instance, 0, {32}), Result(FP64::nan(FP64::canon + 1)));
499+
EXPECT_THAT(execute(*instance, 0, {40}), Result(FP64::nan(1)));
500+
501+
EXPECT_THAT(execute(*instance, 0, {65534}), Traps());
502+
EXPECT_THAT(execute(*instance, 0, {65537}), Traps());
503+
}
504+
505+
TEST(execute_floating_point, f64_load_overflow)
506+
{
507+
/* wat2wasm
508+
(memory 1 1)
509+
(func (param i32) (result f64)
510+
get_local 0
511+
f64.load offset=0x7fffffff
512+
)
513+
*/
514+
const auto wasm = from_hex(
515+
"0061736d0100000001060160017f017c0302010005030100010a0d010b0020002b03ffffffff070b");
516+
517+
auto instance = instantiate(parse(wasm));
518+
519+
// Offset is 0x7fffffff + 0 => 0x7fffffff
520+
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
521+
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
522+
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
523+
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
524+
EXPECT_THAT(execute(*instance, 0, {0x80000001}), Traps());
525+
}
526+
527+
TEST(execute_floating_point, f32_store)
528+
{
529+
/* wat2wasm
530+
(memory 1 1)
531+
(data (i32.const 0) "\cc\cc\cc\cc\cc\cc")
532+
(func (param f32 i32)
533+
get_local 1
534+
get_local 0
535+
f32.store
536+
)
537+
*/
538+
const auto wasm = from_hex(
539+
"0061736d0100000001060160027d7f000302010005030100010a0b010900200120003802000b0b0c010041000b"
540+
"06cccccccccccc");
541+
542+
const std::tuple<float, bytes> test_cases[]{
543+
{0.0f, "cc00000000cc"_bytes},
544+
{1.234f, "ccb6f39d3fcc"_bytes},
545+
{-1.234f, "ccb6f39dbfcc"_bytes},
546+
{FP32::nan(FP32::canon), "cc0000c07fcc"_bytes},
547+
{FP32::nan(FP32::canon + 1), "cc0100c07fcc"_bytes},
548+
{FP32::nan(1), "cc0100807fcc"_bytes},
549+
};
550+
551+
for (const auto& [arg, expected] : test_cases)
552+
{
553+
auto instance = instantiate(parse(wasm));
554+
555+
EXPECT_THAT(execute(*instance, 0, {arg, 1}), Result());
556+
EXPECT_EQ(instance->memory->substr(0, 6), expected);
557+
558+
EXPECT_THAT(execute(*instance, 0, {arg, 65534}), Traps());
559+
EXPECT_THAT(execute(*instance, 0, {arg, 65537}), Traps());
560+
}
561+
}
562+
563+
TEST(execute_floating_point, f32_store_overflow)
564+
{
565+
/* wat2wasm
566+
(memory 1 1)
567+
(func (param i32)
568+
get_local 0
569+
f32.const 1.234
570+
f32.store offset=0x7fffffff
571+
)
572+
*/
573+
const auto wasm = from_hex(
574+
"0061736d0100000001050160017f00030201000504010101010a12011000200043b6f39d3f3802ffffffff070"
575+
"b");
576+
577+
auto instance = instantiate(parse(wasm));
578+
579+
// Offset is 0x7fffffff + 0 => 0x7fffffff
580+
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
581+
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
582+
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
583+
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
584+
EXPECT_THAT(execute(*instance, 0, {0x80000001}), Traps());
585+
}
586+
587+
TEST(execute_floating_point, f64_store)
588+
{
589+
/* wat2wasm
590+
(memory 1 1)
591+
(data (i32.const 0) "\cc\cc\cc\cc\cc\cc\cc\cc\cc\cc\cc\cc")
592+
(func (param f64 i32)
593+
get_local 1
594+
get_local 0
595+
f64.store
596+
)
597+
*/
598+
const auto wasm = from_hex(
599+
"0061736d0100000001060160027c7f000302010005030100010a0b010900200120003903000b0b12010041000b"
600+
"0ccccccccccccccccccccccccc");
601+
602+
const std::tuple<double, bytes> test_cases[]{
603+
{0.0, "cc0000000000000000cc"_bytes},
604+
{1.234, "cc5839b4c876bef33fcc"_bytes},
605+
{-1.234, "cc5839b4c876bef3bfcc"_bytes},
606+
{FP64::nan(FP64::canon), "cc000000000000f87fcc"_bytes},
607+
{FP64::nan(FP64::canon + 1), "cc010000000000f87fcc"_bytes},
608+
{FP64::nan(1), "cc010000000000f07fcc"_bytes},
609+
};
610+
611+
for (const auto& [arg, expected] : test_cases)
612+
{
613+
auto instance = instantiate(parse(wasm));
614+
615+
EXPECT_THAT(execute(*instance, 0, {arg, 1}), Result());
616+
EXPECT_EQ(instance->memory->substr(0, 10), expected);
617+
618+
EXPECT_THAT(execute(*instance, 0, {arg, 65534}), Traps());
619+
EXPECT_THAT(execute(*instance, 0, {arg, 65537}), Traps());
620+
}
621+
}

0 commit comments

Comments
 (0)