summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2009-03-10 18:50:01 +0100
committerMichael Brown2009-03-26 08:27:19 +0100
commit1c67623e37dada045e9b5d1f5e19b414cc79c3e3 (patch)
tree6baaac3371a85232dbfe0faa5e7530eb76fa7413 /src/include
parent[3c90x] Remove src/drivers/3c90x.txt (diff)
downloadipxe-1c67623e37dada045e9b5d1f5e19b414cc79c3e3.tar.gz
ipxe-1c67623e37dada045e9b5d1f5e19b414cc79c3e3.tar.xz
ipxe-1c67623e37dada045e9b5d1f5e19b414cc79c3e3.zip
[build] Enable building with the Intel C compiler (icc)
Diffstat (limited to 'src/include')
-rw-r--r--src/include/compiler.h3
-rw-r--r--src/include/gpxe/efi/efi.h7
-rw-r--r--src/include/gpxe/tables.h95
3 files changed, 94 insertions, 11 deletions
diff --git a/src/include/compiler.h b/src/include/compiler.h
index 889c24047..be3ce46fc 100644
--- a/src/include/compiler.h
+++ b/src/include/compiler.h
@@ -212,7 +212,8 @@ int __debug_disable;
* @v len Length of data
*/
#define DBG_HD_IF( level, data, len ) do { \
- DBG_HDA_IF ( level, data, data, len ); \
+ const void *_data = data; \
+ DBG_HDA_IF ( level, _data, _data, len ); \
} while ( 0 )
/**
diff --git a/src/include/gpxe/efi/efi.h b/src/include/gpxe/efi/efi.h
index 1f5b88563..a71a29e27 100644
--- a/src/include/gpxe/efi/efi.h
+++ b/src/include/gpxe/efi/efi.h
@@ -31,6 +31,11 @@
/* EFI headers rudely redefine NULL */
#undef NULL
+/* EFI headers expect ICC to define __GNUC__ */
+#if defined ( __ICC ) && ! defined ( __GNUC__ )
+#define __GNUC__ 1
+#endif
+
/* Include the top-level EFI header files */
#include <gpxe/efi/Uefi.h>
#include <gpxe/efi/PiDxe.h>
@@ -69,7 +74,7 @@ struct efi_protocol {
struct efi_protocol __ ## _protocol __efi_protocol = { \
.u.guid = _protocol ## _GUID, \
.protocol = ( ( void ** ) ( void * ) \
- ( ( (_ptr) == ( ( _protocol ** ) NULL ) ) ? \
+ ( ( (_ptr) == ( ( _protocol ** ) (_ptr) ) ) ? \
(_ptr) : (_ptr) ) ), \
}
diff --git a/src/include/gpxe/tables.h b/src/include/gpxe/tables.h
index a0b6f1137..39b4777f2 100644
--- a/src/include/gpxe/tables.h
+++ b/src/include/gpxe/tables.h
@@ -234,10 +234,22 @@
* @endcode
*/
#define __table_entry( table, idx ) \
- __attribute__ (( __section__ ( __table_section ( table, idx ) ) \
+ __attribute__ (( __section__ ( __table_section ( table, idx ) ),\
__aligned__ ( __table_alignment ( table ) ) ))
/**
+ * Get start of linker table entries
+ *
+ * @v table Linker table
+ * @v idx Sub-table index
+ * @ret entries Start of entries
+ */
+#define __table_entries( table, idx ) ( { \
+ static __table_type ( table ) __table_entries[0] \
+ __table_entry ( table, idx ); \
+ __table_entries; } )
+
+/**
* Get start of linker table
*
* @v table Linker table
@@ -253,10 +265,7 @@
*
* @endcode
*/
-#define table_start( table ) ( { \
- static __table_type ( table ) __table_start[0] \
- __table_entry ( table, 00 ); \
- __table_start; } )
+#define table_start( table ) __table_entries ( table, 00 )
/**
* Get end of linker table
@@ -274,10 +283,7 @@
*
* @endcode
*/
-#define table_end( table ) ( { \
- static __table_type ( table ) __table_end[0] \
- __table_entry ( table, 99 ); \
- __table_end; } )
+#define table_end( table ) __table_entries ( table, 99 )
/**
* Get number of entries in linker table
@@ -352,4 +358,75 @@
pointer >= table_start ( table ) ; \
pointer-- )
+/******************************************************************************
+ *
+ * Intel's C compiler chokes on several of the constructs used in this
+ * file. The workarounds are ugly, so we use them only for an icc
+ * build.
+ *
+ */
+#define ICC_ALIGN_HACK_FACTOR 128
+#ifdef __ICC
+
+/*
+ * icc miscompiles zero-length arrays by inserting padding to a length
+ * of two array elements. We therefore have to generate the
+ * __table_entries() symbols by hand in asm.
+ *
+ */
+#undef __table_entries
+#define __table_entries( table, idx ) ( { \
+ extern __table_type ( table ) \
+ __table_temp_sym ( idx, __LINE__ ) [] \
+ __table_entry ( table, idx ) \
+ asm ( __table_entries_sym ( table, idx ) ); \
+ __asm__ ( ".ifndef %c0\n\t" \
+ ".section " __table_section ( table, idx ) "\n\t" \
+ ".align %c1\n\t" \
+ "\n%c0:\n\t" \
+ ".previous\n\t" \
+ ".endif\n\t" \
+ : : "i" ( __table_temp_sym ( idx, __LINE__ ) ), \
+ "i" ( __table_alignment ( table ) ) ); \
+ __table_temp_sym ( idx, __LINE__ ); } )
+#define __table_entries_sym( table, idx ) \
+ "__tbl_" __table_name ( table ) "_" #idx
+#define __table_temp_sym( a, b ) \
+ ___table_temp_sym( __table_, a, _, b )
+#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
+
+/*
+ * icc ignores __attribute__ (( aligned (x) )) when it is used to
+ * decrease the compiler's default choice of alignment (which may be
+ * higher than the alignment actually required by the structure). We
+ * work around this by forcing the alignment to a large multiple of
+ * the required value (so that we are never attempting to decrease the
+ * default alignment) and then postprocessing the object file to
+ * reduce the alignment back down to the "real" value.
+ *
+ */
+#undef __table_alignment
+#define __table_alignment( table ) \
+ ( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
+
+/*
+ * Because of the alignment hack, we must ensure that the compiler
+ * never tries to place multiple objects within the same section,
+ * otherwise the assembler will insert padding to the (incorrect)
+ * alignment boundary. Do this by appending the line number to table
+ * section names.
+ *
+ * Note that we don't need to worry about padding between array
+ * elements, since the alignment is declared on the variable (i.e. the
+ * whole array) rather than on the type (i.e. on all individual array
+ * elements).
+ */
+#undef __table_section
+#define __table_section( table, idx ) \
+ ".tbl." __table_name ( table ) "." __table_str ( idx ) \
+ "." __table_xstr ( __LINE__ )
+#define __table_xstr( x ) __table_str ( x )
+
+#endif /* __ICC */
+
#endif /* _GPXE_TABLES_H */