From c2546d5908d2cc6b22cb7e9510e340fe8d3786c2 Mon Sep 17 00:00:00 2001 From: Perry Kivolowitz Date: Tue, 14 Jun 2022 16:07:08 -0500 Subject: [PATCH] added FP project --- projects/PI/.vscode/settings.json | 5 ++ projects/PI/README.md | 102 ++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 projects/PI/.vscode/settings.json create mode 100644 projects/PI/README.md diff --git a/projects/PI/.vscode/settings.json b/projects/PI/.vscode/settings.json new file mode 100644 index 0000000..9783d2e --- /dev/null +++ b/projects/PI/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "scvtf" + ] +} \ No newline at end of file diff --git a/projects/PI/README.md b/projects/PI/README.md new file mode 100644 index 0000000..8c9a792 --- /dev/null +++ b/projects/PI/README.md @@ -0,0 +1,102 @@ +# Floating Point Programming + +As a vehicle to practice using floating point instruction, +this program will throw darts at a square with sides of +two units. It turns out the fraction of darts that fall +within the unit circle is... wait for it... PI. + +The idea is to choose two random numbers from zero to one. +Treat these as an x and y coordinate. Calculate the distance to +the origin. If the distance puts the point inside the unit +circle, record the trial as a hit. + +Finally, divide the number of hits by the number of trials and +multiply by four. The result will be an approximation of PI +using stochastic methods. + +Note this means +we are throwing darts at one quadrant of a square with sides +of 2 units, not the whole square. The difference means we +must multiply by 4 at the end. + +## Number of trials to run + +This will come from the command line as in: + +```text +user@comporg:~/pi $ ./a.out 100000 +Executing: 100000 iterations. +Hits: 78443 +Approximation: 3.137720 +user@comporg:~/pi $ +``` + +If the command line argument is *not* given, use a default of 100000. + +Remember that all AARCH64 instructions are 32 bits long. An implication of this is you can't simply do: + +```text + mov x0, 1000000 +``` + +Since the constant cannot fit along with op codes into four bytes. A way to get around this that comes readily to mind +is to put the constant in RAM and `ldr` it into a register. + +## Vetting the command line argument + +You are not responsible for doing this. Assume that all +command line arguments are valid. + +## Converting command line argument to integer + +`atoi` + +## Seeding the random number generator + +In your previous C and C++ programs, you will have done (code snippets follow): + +```c++ +#include + +srand((unsigned int) time(nullptr)); +``` + +You must seed the RNG in this way. But in assembly language. + +## Getting a random number in the right range + +`rand()` returns an integer between 0 and `RAND_MAX`. In +C and C++ you would do: + +```c++ +// Produces result between 0 and very very close to 1. +float v = float(rand()) / float(RAND_MAX); +``` + +You must do this in your program. What value is RAND_MAX? Write a tiny C++ program on the ARM and print out the value. Or, put +`RANDMAX` into an IDE and ask the IDE to locate the definition. + +You must write a subroutine (function) which returns a random number in the right range. Call it `randf` so I can find it easily. + +## Converting integers to doubles + +In the above, the integers were converted to floats +with a cast. In assembly language you must code the +instructions which perform the cast yourself. +Look up `scvtf` which stands for "signed convert to +float". + +## FP registers + +Just like `x0` through `x30`, there exists `d0` through `d30`. +Among the float registers, `d29` and `d30` are not special. +However, non-scratch float registers must still be saved and +restored in functions. + +## FP ops + +You'll use instructions like `fmul`, `fdiv`, `fsqrt`, `fmov` and `fcmp`. + +## Printing FP + +`printf` will be your friend. Like always, the format string address goes in `x0`. A `%f` found in the format string tells `printf` to look in the FP registers starting with `d0` as the first value.