1/* -*- linux-c -*- */ 2/* 3 * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. 9 * 10 */ 11 12/****************************************************/ 13/****************************************************/ 14/* Begin header file "endian.h" */ 15/****************************************************/ 16/****************************************************/ 17 18#if !defined(_ENDIAN_HP_) 19#define _ENDIAN_HP_ 20 21/****************************************************/ 22/* header files */ 23/****************************************************/ 24 25 26/****************************************************/ 27/* let's see if we know this is a big endian */ 28/****************************************************/ 29#ifndef INLINE 30#define INLINE inline 31#endif 32 33#define fnm_assert_stmt(a) 34 35#ifndef BYTE_ORDER 36#if defined(AMD29K) || defined(mc68000) 37 38#define BIG_ENDIAN 4321 39 40#endif 41 42/****************************************************/ 43/* global macro functions handling endian issues */ 44/****************************************************/ 45 46#if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN) 47#define LITTLE_ENDIAN 1234 48#endif 49#endif 50 51#define fnm_get_i_big_endian(p_uc, x) fnm_get_ui_big_endian(p_uc, x) 52#define fnm_get_s_big_endian(p_uc, x) fnm_get_us_big_endian(p_uc, x) 53#define fnm_get_i_little_endian(p_uc, x) fnm_get_ui_little_endian(p_uc, x) 54#define fnm_get_s_little_endian(p_uc, x) fnm_get_us_little_endian(p_uc, x) 55 56#define fnm_get_ui_big_endian(p_uc, x) \ 57{ \ 58 (x) = (((unsigned int)(*(p_uc)++)) << 24); \ 59 (x) += (((unsigned int)(*(p_uc)++)) << 16); \ 60 (x) += (((unsigned int)(*(p_uc)++)) << 8); \ 61 (x) += ((unsigned int)(*(p_uc)++)); \ 62} 63 64#define fnm_get_us_big_endian(p_uc, x) \ 65{ \ 66 (x) = (((unsigned short)(*(p_uc)++)) << 8); \ 67 (x) += ((unsigned short)(*(p_uc)++)); \ 68} 69 70#define fnm_get_ui_little_endian(p_uc, x) \ 71{ \ 72 (x) = ((unsigned int)(*(p_uc)++)); \ 73 (x) += (((unsigned int)(*(p_uc)++)) << 8); \ 74 (x) += (((unsigned int)(*(p_uc)++)) << 16); \ 75 (x) += (((unsigned int)(*(p_uc)++)) << 24); \ 76} 77 78#define fnm_get_us_little_endian(p_uc, x) \ 79{ \ 80 (x) = ((unsigned short)(*(p_uc)++)); \ 81 (x) += (((unsigned short)(*(p_uc)++)) << 8); \ 82} 83 84#define fnm_store_i_big_endian(p_uc, x) fnm_store_ui_big_endian(p_uc, x) 85#define fnm_store_s_big_endian(p_uc, x) fnm_store_us_big_endian(p_uc, x) 86#define fnm_store_i_little_endian(p_uc, x) fnm_store_ui_little_endian(p_uc, x) 87#define fnm_store_s_little_endian(p_uc, x) fnm_store_us_little_endian(p_uc, x) 88 89#define fnm_store_ui_big_endian(p_uc, x) \ 90{ \ 91 *(p_uc)++ = (((unsigned int)(x)) >> 24); \ 92 *(p_uc)++ = (((unsigned int)(x)) >> 16); \ 93 *(p_uc)++ = (((unsigned int)(x)) >> 8); \ 94 *(p_uc)++ = ((unsigned int)(x)); \ 95} 96 97#define fnm_store_us_big_endian(p_uc, x) \ 98{ \ 99 *(p_uc)++ = (unsigned char) (((unsigned short)(x)) >> 8); \ 100 *(p_uc)++ = (unsigned char) ((unsigned short)(x)); \ 101} 102 103#define fnm_store_ui_little_endian(p_uc, x) \ 104{ \ 105 *(p_uc)++ = ((unsigned int)(x)); \ 106 *(p_uc)++ = (((unsigned int)(x)) >> 8); \ 107 *(p_uc)++ = (((unsigned int)(x)) >> 16); \ 108 *(p_uc)++ = (((unsigned int)(x)) >> 24); \ 109} 110 111#define fnm_store_us_little_endian(p_uc, x) \ 112{ \ 113 *(p_uc)++ = ((unsigned short)(x)); \ 114 *(p_uc)++ = (((unsigned short)(x)) >> 8); \ 115} 116 117/* for now lets always use the macroes instead of the inline procedures 118 so that we are sure they work */ 119 120 121#define fnm_convert_us_endian(x) \ 122 ((unsigned short)((((unsigned short)(x)) << 8) + (((unsigned short)(x)) >> 8))) 123 124#define fnm_convert_ui_endian(x) \ 125 ((unsigned int)((((unsigned int)(x)) >> 24) + ((((unsigned int)(x)) & 0x00ff0000) >> 8) + \ 126 ((((unsigned int)(x)) & 0x0000ff00) << 8) + (((unsigned int)(x)) << 24))) 127 128#define fnm_make_ui_from_2_us(us_high_part, us_low_part) \ 129 ((unsigned int)((((unsigned int)(us_high_part)) << 16) + ((unsigned short)(us_low_part)))) 130 131#define fnm_make_ui_from_4_uc(p1, p2, p3, p4) \ 132 ((unsigned int)(((((((unsigned int)((t_uc)p1) << 8) + ((t_uc)p2)) << 8) \ 133 + ((t_uc)p3)) << 8) + ((t_uc)p4))) 134 135#define fnm_make_us_from_2_uc(uc_high_part, uc_low_part) \ 136 ((unsigned short)((((unsigned short)(uc_high_part)) << 8) + ((t_uc)(uc_low_part)))) 137 138 139#define fnm_convert_s_endian(x) ((short)(fnm_convert_us_endian(x))) 140#define fnm_convert_i_endian(x) ((int)(fnm_convert_ui_endian(x))) 141 142#if defined(BIG_ENDIAN) 143 144#define fnm_convert_us_big_endian(x) ((unsigned short)(x)) 145#define fnm_convert_s_big_endian(x) ((short)(x)) 146#define fnm_convert_ui_big_endian(x) ((unsigned int)(x)) 147#define fnm_convert_i_big_endian(x) ((int)(x)) 148 149#define fnm_convert_us_little_endian(x) fnm_convert_us_endian(x) 150#define fnm_convert_s_little_endian(x) fnm_convert_s_endian(x) 151#define fnm_convert_ui_little_endian(x) fnm_convert_ui_endian(x) 152#define fnm_convert_i_little_endian(x) fnm_convert_i_endian(x) 153 154#else 155 156#define fnm_convert_us_big_endian(x) fnm_convert_us_endian(x) 157#define fnm_convert_s_big_endian(x) fnm_convert_s_endian(x) 158#define fnm_convert_ui_big_endian(x) fnm_convert_ui_endian(x) 159#define fnm_convert_i_big_endian(x) fnm_convert_i_endian(x) 160 161#define fnm_convert_us_little_endian(x) ((unsigned short)(x)) 162#define fnm_convert_s_little_endian(x) ((short)(x)) 163#define fnm_convert_ui_little_endian(x) ((unsigned int)(x)) 164#define fnm_convert_i_little_endian(x) ((int)(x)) 165 166#endif 167 168/****************************************************/ 169/* test macro functions handling endian issues */ 170/****************************************************/ 171 172#if defined(NDEBUG) 173 174#define fnm_test_definitions() 175 176#else 177 178#define fnm_test_definitions() \ 179{ \ 180 union \ 181 { \ 182 t_c a_c[4]; \ 183 unsigned short a_us[2]; \ 184 unsigned int ul; \ 185 \ 186 } t1 = { "\x01\x02\x03\x04" }; \ 187 \ 188 unsigned char *p; \ 189 unsigned short us_one, us_two; \ 190 unsigned int ul_one; \ 191 \ 192 fnm_assert_stmt((t1.a_c[0] == 1) && (t1.a_c[1] == 2) && \ 193 (t1.a_c[2] == 3) && (t1.a_c[3] == 4)); \ 194 \ 195 fnm_assert_stmt(fnm_convert_ui_big_endian(t1.ul) == 0x01020304); \ 196 fnm_assert_stmt(fnm_convert_ui_little_endian(t1.ul) == 0x04030201); \ 197 fnm_assert_stmt(fnm_convert_us_big_endian(t1.a_us[0]) == 0x0102); \ 198 fnm_assert_stmt(fnm_convert_us_little_endian(t1.a_us[0]) == 0x0201); \ 199 \ 200 p = (unsigned char*)(&t1); \ 201 \ 202 fnm_get_us_little_endian(p, us_one); \ 203 fnm_get_us_little_endian(p, us_two); \ 204 \ 205 fnm_assert_stmt((us_one == 0x0201) && (us_two == 0x0403)); \ 206 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 207 \ 208 p = (unsigned char*)(&t1); \ 209 \ 210 fnm_get_us_big_endian(p, us_one); \ 211 fnm_get_us_big_endian(p, us_two); \ 212 \ 213 fnm_assert_stmt((us_one == 0x0102) && (us_two == 0x0304)); \ 214 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 215 \ 216 p = (unsigned char*)(&t1); \ 217 \ 218 fnm_get_ui_little_endian(p, ul_one); \ 219 \ 220 fnm_assert_stmt(ul_one == 0x04030201); \ 221 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 222 \ 223 p = (unsigned char*)(&t1); \ 224 \ 225 fnm_get_ui_big_endian(p, ul_one); \ 226 \ 227 fnm_assert_stmt(ul_one == 0x01020304); \ 228 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 229 \ 230 p = (unsigned char*)(&t1); \ 231 \ 232 fnm_store_us_little_endian(p, 0x1234); \ 233 fnm_store_us_little_endian(p, 0x5678); \ 234 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 235 \ 236 p = (unsigned char*)(&t1); \ 237 \ 238 fnm_get_us_little_endian(p, us_one); \ 239 fnm_get_us_little_endian(p, us_two); \ 240 \ 241 fnm_assert_stmt((us_one == 0x1234) && (us_two == 0x5678)); \ 242 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 243 \ 244 p = (unsigned char*)(&t1); \ 245 \ 246 fnm_store_us_big_endian(p, 0x1234); \ 247 fnm_store_us_big_endian(p, 0x5678); \ 248 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 249 \ 250 p = (unsigned char*)(&t1); \ 251 \ 252 fnm_get_us_big_endian(p, us_one); \ 253 fnm_get_us_big_endian(p, us_two); \ 254 \ 255 fnm_assert_stmt((us_one == 0x1234) && (us_two == 0x5678)); \ 256 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 257 \ 258 p = (unsigned char*)(&t1); \ 259 \ 260 fnm_store_ui_little_endian(p, 0x12345678); \ 261 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 262 \ 263 p = (unsigned char*)(&t1); \ 264 \ 265 fnm_get_ui_little_endian(p, ul_one); \ 266 \ 267 fnm_assert_stmt(ul_one == 0x12345678); \ 268 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 269 \ 270 p = (unsigned char*)(&t1); \ 271 \ 272 fnm_store_ui_big_endian(p, 0x12345678); \ 273 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 274 \ 275 p = (unsigned char*)(&t1); \ 276 \ 277 fnm_get_ui_big_endian(p, ul_one); \ 278 \ 279 fnm_assert_stmt(ul_one == 0x12345678); \ 280 fnm_assert_stmt((p-4) == ((unsigned char*)(&t1))); \ 281 \ 282 fnm_assert_stmt(fnm_make_ui_from_2_us(1, 2) == 0x00010002); \ 283 fnm_assert_stmt(fnm_make_ui_from_4_uc(1, 2, 3, 4) == 0x01020304); \ 284 fnm_assert_stmt(fnm_make_us_from_2_uc(1, 2) == 0x0102); \ 285 \ 286} 287 288#endif 289 290#endif 291 292/****************************************************/ 293/****************************************************/ 294/* End header file "endian.h" */ 295/****************************************************/ 296/****************************************************/ 297