summaryrefslogtreecommitdiff
path: root/3/6_control
diff options
context:
space:
mode:
Diffstat (limited to '3/6_control')
-rw-r--r--3/6_control/27_while_for.c46
-rw-r--r--3/6_control/28_fun_b.c33
-rw-r--r--3/6_control/29_continue.c5
-rw-r--r--3/6_control/30_switch2.c37
-rw-r--r--3/6_control/31_the_switcher.c29
5 files changed, 150 insertions, 0 deletions
diff --git a/3/6_control/27_while_for.c b/3/6_control/27_while_for.c
new file mode 100644
index 0000000..f7f73f7
--- /dev/null
+++ b/3/6_control/27_while_for.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+long fact_for(long n) {
+ long i;
+ long result = 1;
+ for (i = 2; i <= n; i++) {
+ result *= i;
+ }
+ return result;
+}
+
+// guarded do
+//
+// init-s
+// t = test-e;
+// if (!t) goto done;
+//
+// loop:
+// body-s
+// update-e;
+// t = test-e;
+// if (t) goto loop;
+//
+// done:
+
+long fact_for_gd_goto(long n) {
+ long i = 2;
+ long result = 1;
+
+ int t = i<=n;
+ if (!t) {
+ goto done;
+ }
+loop:
+ result *= i;
+ i++;
+ t = i<=n;
+ if (t) goto loop;
+done:
+ return result;
+}
+
+int main() {
+ printf("for: %ld, goto: %ld\n", fact_for(5), fact_for_gd_goto(5));
+ return 0;
+}
diff --git a/3/6_control/28_fun_b.c b/3/6_control/28_fun_b.c
new file mode 100644
index 0000000..5ecf7d2
--- /dev/null
+++ b/3/6_control/28_fun_b.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+// x in rdi
+// fun_b:
+// movl $64, %edx i <- 64 (32 bits?, long presumably)
+// movl $0, %eax val <- 0
+// .L10:
+// movq %rdi, %rcx tmp <- x
+// andl $1, %ecx tmp <- tmp & 1
+// addq %rax, %rax val <- val + val
+// orq %rcx, %rax val <- val | tmp
+// shrq %rdi
+// subq $1, %rdx i <- i-1
+// jne .L10 if i != 0 then goto .L10
+// rep; ret
+long fun_b(unsigned long x) {
+ long val = 0;
+ long i;
+ for (i = 64; i!=0; i--) {
+ long tmp = x;
+ tmp &= 1; // check 1 bit
+ val += val; // multiply by two
+ val |= tmp; // add 1 bit if present
+ x >>= 1; // shift next bit into 1 bit
+ }
+ return val;
+}
+
+// Seems to compute the value shifted to the left (63 - nbit), (or in other words the mirror image)
+int main() {
+ printf("val: %ld, computed: %ld, bits: %lb\n", fun_b(10), (long) 10 << 59, 10);
+ return 0;
+}
diff --git a/3/6_control/29_continue.c b/3/6_control/29_continue.c
new file mode 100644
index 0000000..175f57b
--- /dev/null
+++ b/3/6_control/29_continue.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main() {
+ return 0;
+}
diff --git a/3/6_control/30_switch2.c b/3/6_control/30_switch2.c
new file mode 100644
index 0000000..0c8cc85
--- /dev/null
+++ b/3/6_control/30_switch2.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+// x in %rdi
+// switch2:
+// addq $1, %rdi
+// cmpq $8, %rdi
+// ja .L2 if (x + 1) > 8 then goto default
+// jmp *.L4(,%rdi,8) take the address at x*8 from .L4
+void switch2(long x, long *dest) {
+ long val = 0;
+ switch (x) {
+ case -1:
+ printf(".L9");
+ break;
+ case 0:
+ case 7:
+ printf(".L5");
+ break;
+ case 1:
+ printf(".L6");
+ break;
+ case 2:
+ case 4:
+ printf(".L7");
+ break;
+ case 5:
+ printf(".L8");
+ break;
+
+ }
+ *dest = val;
+}
+
+int main(void) {
+ printf("val: %ld\n");
+ return 0;
+}
diff --git a/3/6_control/31_the_switcher.c b/3/6_control/31_the_switcher.c
new file mode 100644
index 0000000..c8b0a4a
--- /dev/null
+++ b/3/6_control/31_the_switcher.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+// a in %rdi, b in %rsi, c in %rdx, dest in %rcx
+void switcher(long a, long b, long c, long *dest) {
+ long val;
+ switch (a) {
+ case 5: /* Case A .L7 */
+ c = 15 ^ a;
+ /* Fall through */
+ case 0: /* Case B .L3 */
+ val = 112 + c;
+ break;
+ case 2: /* Case C .L5 */
+ case 7: /* Case D .L5 */
+ val = (c + b)<<2;
+ break;
+ case 4: /* Case E */
+ val = a;
+ break;
+ default: /* .L2 */
+ val = b;
+ }
+ *dest = val; /* .L6 */
+}
+
+int main(void) {
+ printf("val: %ld\n");
+ return 0;
+}