// cmathProbe.cpp - exercise the <cmath> C++ shim.
//
// Computes a handful of math functions via std::-prefixed names to verify
// that runtime/include/c++/cmath correctly re-exports the libc math surface
// into namespace std::.
//
// Marker layout (16-bit little-endian where noted):
//   $025000 = 0xC0DE  reached end-of-main (sentinel for runInGno --check)
//   $025010 = 0xBEEF  main entered
//   $025012 = (uint16_t)std::sqrt(2025.0)      -> 45
//   $025014 = (uint16_t)std::floor(3.7)        -> 3
//   $025016 = (uint16_t)std::ceil(3.2)         -> 4
//   $025018 = (uint16_t)(std::fabs(-7.5)*2)    -> 15  (avoid FP-fraction loss)
//   $02501A = (uint16_t)std::fmod(17.0, 5.0)   -> 2
//   $02501C = (uint16_t)std::isnan(0.0)        -> 0
//   $02501E = (uint16_t)std::isinf(0.0)        -> 0
//   $025020 = (uint16_t)(std::pow(2.0, 10.0))  -> 1024
//
// Also dumps a printf so the host can eyeball the sqrt value.
#include <stdint.h>
#include <stdio.h>
#include <cmath>

int main(void) {
    *(volatile uint16_t *)0x025010UL = 0xBEEF;

    double r = std::sqrt(2025.0);
    *(volatile uint16_t *)0x025012UL = (uint16_t)r;

    *(volatile uint16_t *)0x025014UL = (uint16_t)std::floor(3.7);
    *(volatile uint16_t *)0x025016UL = (uint16_t)std::ceil(3.2);
    *(volatile uint16_t *)0x025018UL = (uint16_t)(std::fabs(-7.5) * 2.0);
    *(volatile uint16_t *)0x02501AUL = (uint16_t)std::fmod(17.0, 5.0);
    *(volatile uint16_t *)0x02501CUL = (uint16_t)(std::isnan(0.0) ? 1 : 0);
    *(volatile uint16_t *)0x02501EUL = (uint16_t)(std::isinf(0.0) ? 1 : 0);
    *(volatile uint16_t *)0x025020UL = (uint16_t)std::pow(2.0, 10.0);

    // printf goes via stdout (GNO redirects to fd 1).  Avoid %g (FP printf
    // not wired up here); cast to int and print.
    printf("sqrt(2025) = %d\n", (int)r);
    printf("pow(2, 10) = %d\n", (int)std::pow(2.0, 10.0));

    *(volatile uint16_t *)0x025000UL = 0xC0DE;
    return 0;
}
