diff options
author | Léo Gourdin <leo.gourdin@univ-grenoble-alpes.fr> | 2020-10-29 14:15:19 +0100 |
---|---|---|
committer | Léo Gourdin <leo.gourdin@univ-grenoble-alpes.fr> | 2020-10-29 14:15:19 +0100 |
commit | 8de1a1f5811470bc1d7d1a7b2f0e5193de40698e (patch) | |
tree | fccc46231cadc14956a1c50828626433a1c69512 | |
parent | aabfd379b2d58afc5b89dfa2d753e56354c1fccb (diff) | |
download | compcert-kvx-8de1a1f5811470bc1d7d1a7b2f0e5193de40698e.tar.gz compcert-kvx-8de1a1f5811470bc1d7d1a7b2f0e5193de40698e.zip |
End of Asmblock translation
-rw-r--r-- | aarch64/Asmblockgen.v | 74 | ||||
-rw-r--r-- | test/aarch64/README.md | 15 | ||||
-rwxr-xr-x | test/aarch64/asmb_aarch64_gen_test.sh | 111 | ||||
-rw-r--r-- | test/aarch64/c/addresses.c | 32 | ||||
-rw-r--r-- | test/aarch64/c/array1.c | 64 | ||||
-rw-r--r-- | test/aarch64/c/array2.c | 74 | ||||
-rw-r--r-- | test/aarch64/c/cpintarray.c | 108 | ||||
-rw-r--r-- | test/aarch64/c/enum1.c | 52 | ||||
-rw-r--r-- | test/aarch64/c/enum2.c | 50 | ||||
-rw-r--r-- | test/aarch64/c/funcs.c | 2 | ||||
-rw-r--r-- | test/aarch64/c/power2.c | 42 | ||||
-rw-r--r-- | test/aarch64/c/random.c | 50 |
12 files changed, 613 insertions, 61 deletions
diff --git a/aarch64/Asmblockgen.v b/aarch64/Asmblockgen.v index 8e095553..fc356d52 100644 --- a/aarch64/Asmblockgen.v +++ b/aarch64/Asmblockgen.v @@ -298,12 +298,23 @@ Definition make_epilogue (f: Machblock.function) : bcode := (** Add immediate *) +Definition addimm_aux (insn: Z -> arith_pp) + (rd r1: iregsp) (n: Z) (k: bcode) := + let nlo := Zzero_ext 12 n in + let nhi := n - nlo in + if Z.eqb nhi 0 then + insn nlo rd r1 ::bi k + else if Z.eqb nlo 0 then + insn nhi rd r1 ::bi k + else + insn nhi rd r1 ::bi insn nlo rd rd ::bi k. + Definition addimm32 (rd r1: ireg) (n: int) (k: bcode) : bcode := let m := Int.neg n in if Int.eq n (Int.zero_ext 24 n) then - Paddimm W (Int.unsigned n) rd r1 ::bi k + addimm_aux (Paddimm W) rd r1 (Int.unsigned n) k else if Int.eq m (Int.zero_ext 24 m) then - Psubimm W (Int.unsigned m) rd r1 ::bi k + addimm_aux (Psubimm W) rd r1 (Int.unsigned m) k else if Int.lt n Int.zero then loadimm32 X16 m (Psub W SOnone rd r1 X16 ::bi k) else @@ -312,9 +323,9 @@ Definition addimm32 (rd r1: ireg) (n: int) (k: bcode) : bcode := Definition addimm64 (rd r1: iregsp) (n: int64) (k: bcode) : bcode := let m := Int64.neg n in if Int64.eq n (Int64.zero_ext 24 n) then - Paddimm X (Int64.unsigned n) rd r1 ::bi k + addimm_aux (Paddimm X) rd r1 (Int64.unsigned n) k else if Int64.eq m (Int64.zero_ext 24 m) then - Psubimm X (Int64.unsigned m) rd r1 ::bi k + addimm_aux (Psubimm X) rd r1 (Int64.unsigned m) k else if Int64.lt n Int64.zero then loadimm64 X16 m (Psubext (EOuxtx Int.zero) rd r1 X16 ::bi k) else @@ -1120,42 +1131,26 @@ Definition transl_instr_basic (f: Machblock.function) (i: Machblock.basic_inst) loadind XSP ofs ty dst k | MBsetstack src ofs ty => storeind src XSP ofs ty k + | MBgetparam ofs ty dst => + do c <- loadind X29 ofs ty dst k; + OK (if ep then c else loadptr_bc XSP f.(fn_link_ofs) X29 c) | MBop op args res => transl_op op args res k | MBload _ chunk addr args dst => transl_load chunk addr args dst k - (*| MBstore chunk addr args src =>*) - (*transl_store chunk addr args src k*) - | _ => Error(msg "Not implemented yet") - (*| MBgetparam ofs ty dst =>*) - (*[> load via the frame pointer if it is valid <]*) - (*do c <- loadind FP ofs ty dst k;*) - (*OK (if ep then c*) - (*else (loadind_ptr SP f.(fn_link_ofs) FP) ::i c)*) - (*| MBop op args res =>*) - (*transl_op op args res k*) + | MBstore chunk addr args src => + transl_store chunk addr args src k end. (** Translation of a code sequence *) -(* TODO to remove ? *) -(*Definition fp_is_parent (before: bool) (i: Machblock.basic_inst) : bool :=*) - (*match i with*) - (*| MBgetstack ofs ty dst => before && negb (mreg_eq dst MFP)*) - (*| MBsetstack src ofs ty => before*) - (*| MBgetparam ofs ty dst => negb (mreg_eq dst MFP)*) - (*| MBop op args res => before && negb (mreg_eq res MFP)*) - (*| MBload trapping_mode chunk addr args dst => before && negb (mreg_eq dst MFP)*) - (*| MBstore chunk addr args res => before*) - (*end.*) - Definition it1_is_parent (before: bool) (i: Machblock.basic_inst) : bool := match i with - | MBgetstack ofs ty dst => before && negb (mreg_eq dst R29) - (*| Msetstack src ofs ty => before*) - (*| Mgetparam ofs ty dst => negb (mreg_eq dst R29)*) + (*| MBgetstack ofs ty dst => before && negb (mreg_eq dst R29)*) + | MBsetstack src ofs ty => before + | MBgetparam ofs ty dst => negb (mreg_eq dst R29) | MBop op args res => before && negb (mreg_eq res R29) - | MBload trapping_mode chunk addr args dst => before && negb (mreg_eq dst R29) + (*| MBload trapping_mode chunk addr args dst => before && negb (mreg_eq dst R29)*) | _ => false end. @@ -1204,28 +1199,31 @@ Obligation 1. rewrite <- Heq_anonymous. constructor. Qed. -Definition transl_control (f: Machblock.function) (ctl: control_flow_inst) (ep: bool) : res (bcode*control) := +Definition transl_control (f: Machblock.function) (ctl: control_flow_inst) : res (bcode*control) := match ctl with - | MBcall sig (inl r) => do r1 <- ireg_of r; OK (nil, PCtlFlow (Pblr r1 sig)) + | MBcall sig (inl r) => do r1 <- ireg_of r; + OK (nil, PCtlFlow (Pblr r1 sig)) | MBcall sig (inr symb) => OK (nil, PCtlFlow (Pbl symb sig)) - | MBtailcall sig (inr symb) => Error (msg "NYI MBtailcall sig (inr symb)") - | MBtailcall sig (inl r) => Error (msg "NYI MBtailcall sig (inl r)") - | MBbuiltin ef args res => Error (msg "NYI MBbuiltin ef args res") + | MBtailcall sig (inr symb) => OK(make_epilogue f, PCtlFlow (Pbs symb sig)) + | MBtailcall sig (inl r) => do r1 <- ireg_of r; + OK (make_epilogue f, PCtlFlow (Pbr r1 sig)) + | MBbuiltin ef args res => OK (nil, Pbuiltin ef (List.map (map_builtin_arg dreg_of) args) (map_builtin_res dreg_of res)) | MBgoto lbl => OK (nil, PCtlFlow (Pb lbl)) | MBcond cond args lbl => transl_cond_branch cond args lbl nil | MBreturn => OK (make_epilogue f, PCtlFlow (Pret RA)) - | MBjumptable arg tbl => Error (msg "NYI MBjumptable arg tbl") + | MBjumptable arg tbl => do r <- ireg_of arg; + OK (nil, PCtlFlow (Pbtbl r tbl)) end. -Definition transl_exit (f: Machblock.function) (ext: option control_flow_inst) (ep: bool) : res (bcode*option control) := +Definition transl_exit (f: Machblock.function) (ext: option control_flow_inst) : res (bcode*option control) := match ext with - Some ctl => do (b,c) <- transl_control f ctl ep; OK (b, Some c) + Some ctl => do (b,c) <- transl_control f ctl; OK (b, Some c) | None => OK (nil, None) end. Definition transl_block (f: Machblock.function) (fb: Machblock.bblock) (ep: bool) (k:bblocks): res (list bblock) := let stub := false in (* TODO: FIXME *) - do (bdy, ex) <- transl_exit f fb.(Machblock.exit) stub; + do (bdy, ex) <- transl_exit f fb.(Machblock.exit); do bdy' <- transl_basic_code f fb.(Machblock.body) ep bdy; OK (cons_bblocks fb.(Machblock.header) bdy' ex k) . diff --git a/test/aarch64/README.md b/test/aarch64/README.md new file mode 100644 index 00000000..f943489c --- /dev/null +++ b/test/aarch64/README.md @@ -0,0 +1,15 @@ +# Testing the Machblock --> Asmblock translation +1. Get the reference version of compcert-aarch in the father's directory if this repo (checkout `aarch64-ref`) +2. Compile both repo for aarch64 +3. CD in this folder (`test/aarch64`) +4. Launch `./asmb_aarch64_gen_test.sh` + +## Options +The script takes following options : +- `-c` to clear generated files at the end +- `-w` to suppress warnings from Compcert + +## Tests files +The variable `DIRS` in the script takes the list of directories containing c files. +The tests under `test/aarch64/c` are simpler and useful to debug only one feature at a time. +Most of them comes from [here](https://cis.temple.edu/~ingargio/cis71/code/). diff --git a/test/aarch64/asmb_aarch64_gen_test.sh b/test/aarch64/asmb_aarch64_gen_test.sh index 19149265..f816204e 100755 --- a/test/aarch64/asmb_aarch64_gen_test.sh +++ b/test/aarch64/asmb_aarch64_gen_test.sh @@ -1,38 +1,105 @@ #!/bin/bash CLEAN=0 -while getopts ':c' 'OPTKEY'; do +WOFF=0 +while getopts ':cw' 'OPTKEY'; do case ${OPTKEY} in c) CLEAN=1;; + w) WOFF=1;; esac done -FILES=c/* +DIRS=( + c/*.c # Special simple tests + ../c/*.c + ../clightgen/*.c + ../compression/*.c + ../cse2/*.c + + # Monniaux test directory + ../monniaux/binary_search/*.c + ../monniaux/complex/*.c + #../monniaux/crypto-algorithms/*.c # Warnings + ../monniaux/cse2/*.c + #../monniaux/des/*.c # Unsupported feature? + ../monniaux/expect/*.c + ../monniaux/fill_buffer/*.c + ../monniaux/genann/*.c + #../monniaux/heptagon_radio_transmitter/*.c # Warnings + ../monniaux/idea/*.c + ../monniaux/jumptable/*.c + ../monniaux/licm/*.c + ../monniaux/longjmp/*.c + ../monniaux/loop/*.c + ../monniaux/lustrev4_lustrec_heater_control/*.c + ../monniaux/lustrev4_lv4_heater_control/*.c + ../monniaux/lustrev4_lv6-en-2cgc_heater_control/*.c + #../monniaux/lustrev6-carlightV2/*.c # Warnings + #../monniaux/lustrev6-convertible-2cgc/*.c # Unsupported feature? + ../monniaux/lustrev6-convertible-en-2cgc/*.c + #../monniaux/lustrev6-convertible/*.c # Warnings + ../monniaux/madd/*.c + #../monniaux/math/*.c # Unsupported feature? + ../monniaux/memcpy/*.c + #../monniaux/micro-bunzip/*.c # Warnings + ../monniaux/moves/*.c + ../monniaux/multithreaded_volatile/*.c + ../monniaux/nand/*.c + #../monniaux/ncompress/*.c # Warnings + ../monniaux/number_theoretic_transform/*.c + ../monniaux/predicated/*.c + ../monniaux/regalloc/*.c + ../monniaux/rotate/*.c + ../monniaux/scheduling/*.c + ../monniaux/send_through/*.c + ../monniaux/tiny-AES-c/*.c + ../monniaux/varargs/*.c + ../monniaux/xor_and_mat/*.c + #../monniaux/zlib-1.2.11/*.c # Warnings +) +#FILES=../c/*.c CCOMP_BBLOCKS="../../ccomp" CCOMP_REF="../../../CompCert_master/ccomp" -for f in $FILES +COUNT=0 + +if [ $WOFF -eq 1 ] +then + CCOMP_BBLOCKS="${CCOMP_BBLOCKS} -w" + CCOMP_REF="${CCOMP_REF} -w" +fi + +for files in ${DIRS[@]} do - BNAME=$(basename -s .c $f) - SNAME="$BNAME".s - SREFNAME="$BNAME"_ref.s - ./$CCOMP_BBLOCKS -S $f -o $SNAME - ./$CCOMP_REF -dmach -S $f -o $SREFNAME - #diff -I '^//*' <(cut -c-5 $SNAME) <(cut -c-5 $SREFNAME) > /dev/null 2>&1 - diff -I '^//*' $SNAME $SREFNAME > /dev/null 2>&1 - - error=$? - if [ $error -eq 0 ] - then - echo "[$BNAME] OK" - elif [ $error -eq 1 ] - then - echo "[$BNAME] FAIL" - diff -I '^//*' -y $SNAME $SREFNAME - else - echo "[WARNING] There was something wrong with the diff command !" - fi + for f in $files + do + BNAME=$(basename -s .c $f) + SNAME="$BNAME".s + SREFNAME="$BNAME"_ref.s + ./$CCOMP_BBLOCKS -S $f -o $SNAME + ./$CCOMP_REF -dmach -S $f -o $SREFNAME + #diff -I '^//*' <(cut -c-5 $SNAME) <(cut -c-5 $SREFNAME) > /dev/null 2>&1 + diff -I '^//*' $SNAME $SREFNAME > /dev/null 2>&1 + + error=$? + if [ $error -eq 0 ] + then + echo "[$BNAME] OK" + COUNT=$((COUNT + 1)) + elif [ $error -eq 1 ] + then + echo "[$BNAME] FAIL" + diff -I '^//*' -y $SNAME $SREFNAME + exit 1 + else + echo "[$BNAME] FAIL" + echo "[WARNING] There was something wrong with the diff command !" + exit 1 + fi + done done +echo "[TOTAL] $COUNT tests PASSED" + if [ $CLEAN -eq 1 ] then rm *.s *.mach diff --git a/test/aarch64/c/addresses.c b/test/aarch64/c/addresses.c new file mode 100644 index 00000000..e3cb5201 --- /dev/null +++ b/test/aarch64/c/addresses.c @@ -0,0 +1,32 @@ +/* addresses.c -- Playing with addresses of variables and their contents: + * what is done by C with variables, addresses, and values. + */ + +#include <stdio.h> + +void moo(int a, int * b); + +int main(void) { + int x; + int *y; + + x=1; + y=&x; + printf("Address of x = %d, value of x = %d\n", &x, x); + printf("Address of y = %d, value of y = %d, value of *y = %d\n", &y, y, *y); + moo(9,y); +} + +void moo(int a, int *b){ + printf("Address of a = %d, value of a = %d\n", &a, a); + printf("Address of b = %d, value of b = %d, value of *b = %d\n", &b, b, *b); +} + +/* Output from running this program on my computer: + +Address of x = 536869640, value of x = 1 +Address of y = 536869632, value of y = 536869640, value of *y = 1 +Address of a = 536869608, value of a = 9 +Address of b = 536869600, value of b = 536869640, value of *b = 1 + + */ diff --git a/test/aarch64/c/array1.c b/test/aarch64/c/array1.c new file mode 100644 index 00000000..5840ca66 --- /dev/null +++ b/test/aarch64/c/array1.c @@ -0,0 +1,64 @@ +/* array1.c -- Simple operations with arrays. + */ + +#include <stdio.h> +#define N 10 + +void oneWay(void); +void anotherWay(void); + +int main(void) { + printf("\noneWay:\n"); + oneWay(); + printf("\nantherWay:\n"); + anotherWay(); +} + +/*Array initialized with aggregate */ +void oneWay(void) { + int vect[N] = {1,2,3,4,5,6,7,8,9,0}; + int i; + + for (i=0; i<N; i++) + printf("i = %2d vect[i] = %2d\n", i, vect[i]); +} + +/*Array initialized with loop */ +void anotherWay(void) { + int vect[N]; + int i; + + for (i=0; i<N; i++) + vect[i] = i+1; + + for (i=0; i<N; i++) + printf("i = %2d vect[i] = %2d\n", i, vect[i]); +} + +/* The output of this program is + +oneWay: +i = 0 vect[i] = 1 +i = 1 vect[i] = 2 +i = 2 vect[i] = 3 +i = 3 vect[i] = 4 +i = 4 vect[i] = 5 +i = 5 vect[i] = 6 +i = 6 vect[i] = 7 +i = 7 vect[i] = 8 +i = 8 vect[i] = 9 +i = 9 vect[i] = 0 + +antherWay: +i = 0 vect[i] = 1 +i = 1 vect[i] = 2 +i = 2 vect[i] = 3 +i = 3 vect[i] = 4 +i = 4 vect[i] = 5 +i = 5 vect[i] = 6 +i = 6 vect[i] = 7 +i = 7 vect[i] = 8 +i = 8 vect[i] = 9 +i = 9 vect[i] = 10 + + */ diff --git a/test/aarch64/c/array2.c b/test/aarch64/c/array2.c new file mode 100644 index 00000000..389e1596 --- /dev/null +++ b/test/aarch64/c/array2.c @@ -0,0 +1,74 @@ +/* array2.c -- Read/writing/reversing integer arrays + */ + +#include <stdio.h> + +#define NMAX 10 + +void intSwap(int *x, int *y); +int getIntArray(int a[], int nmax, int sentinel); +void printIntArray(int a[], int n); +void reverseIntArray(int a[], int n); + +int main(void) { + int x[NMAX]; + int hmny; + + hmny = getIntArray(x, NMAX, 0); + printf("The array was: \n"); + printIntArray(x,hmny); + reverseIntArray(x,hmny); + printf("after reverse it is:\n"); + printIntArray(x,hmny); +} + +void intSwap(int *x, int *y) + /* It swaps the content of x and y */ +{ + int temp = *x; + *x = *y; + *y = temp; +} + +void printIntArray(int a[], int n) + /* n is the number of elements in the array a. + * These values are printed out, five per line. */ +{ + int i; + + for (i=0; i<n; ){ + printf("\t%d ", a[i++]); + if (i%5==0) + printf("\n"); + } + printf("\n"); +} + +int getIntArray(int a[], int nmax, int sentinel) + /* It reads up to nmax integers and stores then in a; sentinel + * terminates input. */ +{ + int n = 0; + int temp; + + do { + printf("Enter integer [%d to terminate] : ", sentinel); + scanf("%d", &temp); + if (temp==sentinel) break; + if (n==nmax) + printf("array is full\n"); + else + a[n++] = temp; + }while (1); + return n; +} + +void reverseIntArray(int a[], int n) + /* It reverse the order of the first n elements of a */ +{ + int i; + + for(i=0;i<n/2;i++){ + intSwap(&a[i],&a[n-i-1]); + } +} diff --git a/test/aarch64/c/cpintarray.c b/test/aarch64/c/cpintarray.c new file mode 100644 index 00000000..8049fdfb --- /dev/null +++ b/test/aarch64/c/cpintarray.c @@ -0,0 +1,108 @@ +/* cpintarray.c -- Example showing how addresses and arrays are alike + */ + +#include <stdio.h> +#define SIZE 8 + +void cpIntArray(int *a, int *b, int n) +/*It copies n integers starting at b into a*/ +{ + for(;n>0;n--) + *a++=*b++; +} + + +void printIntArray(int a[], int n) + /* n is the number of elements in the array a. + * These values are printed out, five per line. */ +{ + int i; + + for (i=0; i<n; ){ + printf("\t%d ", a[i++]); + if (i%5==0) + printf("\n"); + } + printf("\n"); +} + +int getIntArray(int a[], int nmax, int sentinel) + /* It reads up to nmax integers and stores then in a; sentinel + * terminates input. */ +{ + int n = 0; + int temp; + + do { + printf("Enter integer [%d to terminate] : ", sentinel); + scanf("%d", &temp); + if (temp==sentinel) break; + if (n==nmax) + printf("array is full\n"); + else + a[n++] = temp; + }while (1); + return n; +} + +int main(void){ + int x[SIZE], nx; + int y[SIZE], ny; + + printf("Read the x array:\n"); + nx = getIntArray(x,SIZE,0); + printf("The x array is:\n"); + printIntArray(x,nx); + + printf("Read the y array:\n"); + ny = getIntArray(y,SIZE,0); + printf("The y array is:\n"); + printIntArray(y,ny); + + cpIntArray(x+2,y+3,4); + /*Notice the expression 'x+2'. x is interpreted as the address for + the beginning of the x array. +2 sais to increment that address + by two units, in accordance with the type of x, which is + an integer array. Thus we move from x to two integer locations + past it, that is to the location of x[2]. The same reasoning applied + to 'y+3'. + */ + printf("Printing x after having copied 4 elements\n" + "from y starting at y[3] into x starting at x[2]\n"); + printIntArray(x,nx); +} + +/* Here is the interaction in a run of this program: + +Read the x array: +Enter integer [0 to terminate] : 1 +Enter integer [0 to terminate] : 3 +Enter integer [0 to terminate] : 5 +Enter integer [0 to terminate] : 7 +Enter integer [0 to terminate] : 9 +Enter integer [0 to terminate] : 11 +Enter integer [0 to terminate] : 13 +Enter integer [0 to terminate] : 15 +Enter integer [0 to terminate] : 0 +The x array is: + 1 3 5 7 9 + 11 13 15 +Read the y array: +Enter integer [0 to terminate] : 2 +Enter integer [0 to terminate] : 4 +Enter integer [0 to terminate] : 6 +Enter integer [0 to terminate] : 8 +Enter integer [0 to terminate] : 10 +Enter integer [0 to terminate] : 12 +Enter integer [0 to terminate] : 14 +Enter integer [0 to terminate] : 16 +Enter integer [0 to terminate] : 0 +The y array is: + 2 4 6 8 10 + 12 14 16 +Printing x after having copied 4 elements +from y starting at y[3] into x starting at x[2] + 1 3 8 10 12 + 14 13 15 + + */ diff --git a/test/aarch64/c/enum1.c b/test/aarch64/c/enum1.c new file mode 100644 index 00000000..d1f6b48d --- /dev/null +++ b/test/aarch64/c/enum1.c @@ -0,0 +1,52 @@ +/* enum1.c -- Starting to use enumerated types: Printing for each + * day of the week, today, yesterday, and tomorrow, both + * as a string and as a number. + */ + +#include <stdio.h> + +/* Introducing an enumerated data type */ +enum days {monday,tuesday,wednesday,thursday,friday,saturday,sunday}; +typedef enum days days; // This allows us to use "days" as an abbreviation + // for "enum days" + +/* Two useful functions */ +days yesterday(days today){ + return (today+6)%7; +} +days tomorrow(days today){ + return (today+1)%7; +} + +// A useful array: thedays is an array of constant (i.e you cannot +// modify them) pointers to constant (i.e. you cannot modify them) strings +const char * const thedays[] = + {"monday", "tuesday", "wednesday", "thursday", + "friday", "saturday", "sunday"}; + +int main(void){ + days today; + + printf("today \tyesterday \ttomorrow\n" + "============================================\n"); + for (today=monday;today<=sunday;today++) + printf("%s = %d \t %s = %d \t %s = %d\n", + thedays[today], today, + thedays[yesterday(today)], yesterday(today), + thedays[tomorrow(today)], tomorrow(today)); +} + +/* + The output is: + +today yesterday tomorrow +============================================ +monday = 0 sunday = 6 tuesday = 1 +tuesday = 1 monday = 0 wednesday = 2 +wednesday = 2 tuesday = 1 thursday = 3 +thursday = 3 wednesday = 2 friday = 4 +friday = 4 thursday = 3 saturday = 5 +saturday = 5 friday = 4 sunday = 6 +sunday = 6 saturday = 5 monday = 0 + +*/ diff --git a/test/aarch64/c/enum2.c b/test/aarch64/c/enum2.c new file mode 100644 index 00000000..a18acb80 --- /dev/null +++ b/test/aarch64/c/enum2.c @@ -0,0 +1,50 @@ +/* enum2.c -- Starting to use enumerated types: Printing for each + * day of the week, today, yesterday, and tomorrow, both + * as a string and as a number. We use typedef + */ + +#include <stdio.h> + +/* Introducing an enumerated data type */ +typedef enum {monday,tuesday,wednesday,thursday,friday,saturday,sunday} days; + +/* Two useful functions */ +days yesterday(days today); +days tomorrow(days today); + +char *thedays[] = {"monday", "tuesday", "wednesday", "thursday", + "friday", "saturday", "sunday"}; + +int main(void){ + days today; + + printf("today \tyesterday \ttomorrow\n" + "============================================\n"); + for (today=monday;today<=sunday;today++) + printf("%s = %d \t %s = %d \t %s = %d\n", + thedays[today], today, + thedays[yesterday(today)], yesterday(today), + thedays[tomorrow(today)], tomorrow(today)); +} + +days yesterday(days today){ + return (today+6)%7; +} +days tomorrow(days today){ + return (today+1)%7; +} + +/* + The output is: + +today yesterday tomorrow +============================================ +monday = 0 sunday = 6 tuesday = 1 +tuesday = 1 monday = 0 wednesday = 2 +wednesday = 2 tuesday = 1 thursday = 3 +thursday = 3 wednesday = 2 friday = 4 +friday = 4 thursday = 3 saturday = 5 +saturday = 5 friday = 4 sunday = 6 +sunday = 6 saturday = 5 monday = 0 + +*/ diff --git a/test/aarch64/c/funcs.c b/test/aarch64/c/funcs.c index fba46033..49e610d6 100644 --- a/test/aarch64/c/funcs.c +++ b/test/aarch64/c/funcs.c @@ -20,7 +20,7 @@ int main (void) { int getint(void) { int a; - /*printf("Please enter an integer > ");*/ + printf("Please enter an integer > "); scanf("%d", &a); return(a); } diff --git a/test/aarch64/c/power2.c b/test/aarch64/c/power2.c new file mode 100644 index 00000000..64707df9 --- /dev/null +++ b/test/aarch64/c/power2.c @@ -0,0 +1,42 @@ +/* power2.c -- Print out powers of 2: 1, 2, 4, 8, .. up to 2^N + */ + +#include <stdio.h> +#define N 16 + +int main(void) { + int n; /* The current exponent */ + int val = 1; /* The current power of 2 */ + + printf("\t n \t 2^n\n"); + printf("\t================\n"); + for (n=0; n<=N; n++) { + printf("\t%3d \t %6d\n", n, val); + val = 2*val; + } + return 0; +} + +/* It prints out : + + n 2^n + ================ + 0 1 + 1 2 + 2 4 + 3 8 + 4 16 + 5 32 + 6 64 + 7 128 + 8 256 + 9 512 + 10 1024 + 11 2048 + 12 4096 + 13 8192 + 14 16384 + 15 32768 + 16 65536 + +*/ diff --git a/test/aarch64/c/random.c b/test/aarch64/c/random.c new file mode 100644 index 00000000..50aa5737 --- /dev/null +++ b/test/aarch64/c/random.c @@ -0,0 +1,50 @@ +/* Generating random number sequences using the formula (linear congruence) + x[k+1] = (a*x[k] + c)mod m + where a, c, and m are parameters set by the user and passed as command line + parameters together with a seed i.e. x[0] + As a simple example try a=7, c=1, m=13, and seed=5 + A more sophisticated selection would be a=69069, c=0, + m=2^32=4294967296, and seed=31 + It will print out, in a sort of random order, up to m-1 distinct values. + Then it loops. + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +static long seed = 13; +static long a; +static long c; +static long m; + +void random_init(long s) { + if (s != 0) seed = s; +} + +long random() { + seed = (a*seed + c)%m; + return seed; + } + +int main(int argc, char * argv[]) { + if (argc != 5) { + printf("usage: %s a, c, m, seed\n", argv[0]); + return 1; + } + a = atoi(argv[1]); + c = atoi(argv[2]); + m = atoi(argv[3]); + long s = atoi(argv[4]); + random_init(s); + int k; + for (k = 0; k < m-1; k++) { + printf("%8ld", random()); + if (k % 8 == 7) { // after 8 elements go to a new line + printf("\n"); + sleep(1); // sleep for a second + } + } + printf("\n"); + return 0; +} |