Add alignment macros.

Introduces align_up, align_down and is_aligned macros that use compiler
builtins if available.
Note: when we fallback to the non-builtin case we could cast back from
uintptr_t to the original type using __typeof() if we accept the
non-standard extension.

Change-Id: Ie0c56f19cb0edc8a211d8c1182b9af5eb329cd8c
diff --git a/src/api.c b/src/api.c
index d342bd6..5e7a033 100644
--- a/src/api.c
+++ b/src/api.c
@@ -619,8 +619,8 @@
 	int64_t ret;
 
 	/* Fail if addresses are not page-aligned. */
-	if ((ipa_addr(send) & (PAGE_SIZE - 1)) ||
-	    (ipa_addr(recv) & (PAGE_SIZE - 1))) {
+	if (!is_aligned(ipa_addr(send), PAGE_SIZE) ||
+	    !is_aligned(ipa_addr(recv), PAGE_SIZE)) {
 		return -1;
 	}
 
@@ -1265,8 +1265,8 @@
 	end = ipa_add(addr, size);
 
 	/* Fail if addresses are not page-aligned. */
-	if ((ipa_addr(begin) & (PAGE_SIZE - 1)) ||
-	    (ipa_addr(end) & (PAGE_SIZE - 1))) {
+	if (!is_aligned(ipa_addr(begin), PAGE_SIZE) ||
+	    !is_aligned(ipa_addr(end), PAGE_SIZE)) {
 		return -1;
 	}
 
diff --git a/src/fdt.c b/src/fdt.c
index 697983e..3c06784 100644
--- a/src/fdt.c
+++ b/src/fdt.c
@@ -66,7 +66,7 @@
 
 static void fdt_tokenizer_align(struct fdt_tokenizer *t)
 {
-	t->cur = (char *)(((uintptr_t)t->cur + 3) & ~3);
+	t->cur = (char *)align_up(t->cur, 4);
 }
 
 static bool fdt_tokenizer_uint32(struct fdt_tokenizer *t, uint32_t *res)
diff --git a/src/fdt_handler.c b/src/fdt_handler.c
index 4b0adf9..7afb2b4 100644
--- a/src/fdt_handler.c
+++ b/src/fdt_handler.c
@@ -286,8 +286,9 @@
 	}
 
 	/* Patch fdt to reserve primary VM memory. */
-	fdt_add_mem_reservation(fdt, pa_addr(layout_primary_begin()) & ~0xfffff,
-				0x80000);
+	fdt_add_mem_reservation(
+		fdt, align_down(pa_addr(layout_primary_begin()), 0x100000),
+		0x80000);
 
 	/* Patch fdt to reserve memory for secondary VMs. */
 	for (i = 0; i < p->reserved_ranges_count; ++i) {
diff --git a/src/layout.c b/src/layout.c
index 15dec5d..fe11c91 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -16,6 +16,8 @@
 
 #include "hf/layout.h"
 
+#include "hf/std.h"
+
 /**
  * Get the address the .text section begins at.
  */
@@ -136,5 +138,5 @@
 	/* TODO: This is a hack. We must read the alignment from the binary. */
 	paddr_t bin_end = layout_bin_end();
 
-	return pa_init((pa_addr(bin_end) + 0x80000 - 1) & ~(0x80000 - 1));
+	return pa_init(align_up(pa_addr(bin_end), 0x80000));
 }
diff --git a/src/load.c b/src/load.c
index a9c0e5d..60b4ef4 100644
--- a/src/load.c
+++ b/src/load.c
@@ -273,9 +273,8 @@
 
 	/* Round the last addresses down to the page size. */
 	for (i = 0; i < params->mem_ranges_count; ++i) {
-		mem_ranges_available[i].end =
-			pa_init(pa_addr(mem_ranges_available[i].end) &
-				~(PAGE_SIZE - 1));
+		mem_ranges_available[i].end = pa_init(align_down(
+			pa_addr(mem_ranges_available[i].end), PAGE_SIZE));
 	}
 
 	while (memiter_parse_uint(&it, &mem) && memiter_parse_uint(&it, &cpu) &&