1 /* -*-c-*- --------------- mix_types.h: 2 * This file contains declarations for the basic types used in MIX: 3 * mix_byte_t, mix_char_t, mix_short_t and mix_word_t. 4 * ------------------------------------------------------------------ 5 * Copyright (C) 2000, 2001, 2004, 2007 Free Software Foundation, Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 24 #ifndef MIX_TYPES_H 25 #define MIX_TYPES_H 26 27 #include <stdio.h> 28 #include "mix.h" 29 30 /* Initialisation function to be called before using the other 31 * functions in this file 32 */ 33 extern void 34 mix_init_types(void); 35 36 37 /*----------------- m_byte_t --------------------------------------------*/ 38 /* MIX byte type */ 39 typedef guint8 mix_byte_t; 40 41 /* Maximum value stored in an mix_byte_t */ 42 #define MIX_BYTE_MAX ((1L << 6) - 1) 43 44 /* Zero mix byte */ 45 #define MIX_BYTE_ZERO ((mix_byte_t)0) 46 47 /* Create a mix_byte_t from any native type */ 48 #define mix_byte_new(x) ((mix_byte_t)((x) & MIX_BYTE_MAX )) 49 50 /* Operations */ 51 /* Addition */ 52 #define mix_byte_add(x,y) mix_byte_new((x) + (y)) 53 /* Substraction */ 54 #define mix_byte_sub(x,y) mix_byte_new((x) - (y)) 55 /* Product */ 56 #define mix_byte_mul(x,y) mix_byte_new((x) * (y)) 57 /* Quotient */ 58 #define mix_byte_div(x,y) mix_byte_new((x) / (y)) 59 60 61 /*----------------- mix_char_t --------------------------------------------*/ 62 /* MIX char type: chars are coded in MIX from 0 to MIX_CHAR_MAX */ 63 typedef guint8 mix_char_t; 64 65 #define MIX_CHAR_MAX 55 66 67 /* Conversions for mix_char_t's */ 68 #define mix_char_new(l) (((l) < MIX_CHAR_MAX )? (l) : MIX_CHAR_MAX) 69 #define mix_char_to_byte(mchar) mix_byte_new (mchar) 70 #define mix_byte_to_char(byte) mix_char_new (byte) 71 72 extern mix_char_t 73 mix_ascii_to_char(guchar c); 74 75 extern guchar 76 mix_char_to_ascii(mix_char_t c); 77 78 79 /*----------------- mix_word_t --------------------------------------------*/ 80 /* 81 * Represented as a gint32 (glib ensures that this type has 32 82 * bits). Bit 30 is the sign, higher bits are 0, 83 * and bits 0-29 are the magnitude. 84 * Each MIX 'byte' is a 6-bit substring of the magnitude. 85 */ 86 typedef guint32 mix_word_t; 87 88 /* Maximum value stored in an mix_word_t */ 89 #define MIX_WORD_MAX ((1L << 30) - 1) 90 /* Sign bit in a word */ 91 #define MIX_WORD_SIGN_BIT (1L << 30) 92 /* Zero mix word */ 93 #define MIX_WORD_ZERO ((mix_word_t)0) 94 /* Negative zero mix word */ 95 #define MIX_WORD_MINUS_ZERO (MIX_WORD_ZERO | MIX_WORD_SIGN_BIT) 96 97 98 /* Create a mix_word_t from any native type */ 99 #define mix_word_new(x) \ 100 ( (x) < 0 \ 101 ? ( MIX_WORD_SIGN_BIT | ((mix_word_t)(-(x)) & MIX_WORD_MAX) ) \ 102 : ( (mix_word_t)(x) & MIX_WORD_MAX ) \ 103 ) 104 105 /* Create a mix_word_t from individual bytes */ 106 #define mix_word_new_b(b1,b2,b3,b4,b5) \ 107 ((mix_word_t)(mix_byte_new(b5) + (mix_byte_new(b4)<<6) + \ 108 (mix_byte_new(b3)<<12) + (mix_byte_new(b2)<<18) + \ 109 (mix_byte_new(b1)<<24))) 110 111 /* Create a negative mix_word_t from individual bytes */ 112 #define mix_word_new_bn(b1,b2,b3,b4,b5) \ 113 mix_word_negative(mix_word_new_b(b1,b2,b3,b4,b5)) 114 115 /* Create mix_word_t from an array of mix_byte_t */ 116 extern mix_word_t 117 mix_bytes_to_word(mix_byte_t *bytes, guint byteno); 118 119 /* Access byte within a word */ 120 extern mix_byte_t /* byte -idx- or MIX_BYTE_ZERO if -idx- out of range */ 121 mix_word_get_byte(mix_word_t word, /* word parsed */ 122 guint idx /* byte: 1 to 5 */); 123 124 /* Set a byte within a mix_word_t */ 125 extern void 126 mix_word_set_byte(mix_word_t *into, /* word to be modified */ 127 guint idx, /* byte: 1 to 5 */ 128 mix_byte_t value /* byte's value */); 129 130 131 /* Operations */ 132 /* Sign-related definitions */ 133 #define mix_word_negative(word) ( (word) ^ MIX_WORD_SIGN_BIT ) 134 #define mix_word_reverse_sign(word) ( word ^= MIX_WORD_SIGN_BIT ) 135 #define mix_word_sign(word) ( (word) & MIX_WORD_SIGN_BIT ) 136 #define mix_word_magnitude(word) ( (word) & (MIX_WORD_SIGN_BIT - 1) ) 137 #define mix_word_is_positive(word) ( mix_word_sign(word) == 0 ) 138 #define mix_word_is_negative(word) ( mix_word_sign(word) != 0 ) 139 #define mix_word_is_even(word) ( ((word) & 1) == 0 ) 140 #define mix_word_is_odd(word) ( ((word) & 1) == 1 ) 141 142 143 /* Arithmetic operations */ 144 extern mix_word_t 145 mix_word_add(mix_word_t x, mix_word_t y); 146 147 #define mix_word_sub(x,y) ( mix_word_add((x),mix_word_negative(y)) ) 148 149 /* Add two words filling a high word if needed. 150 -high_word- and/or -low_word- can be NULL. 151 */ 152 extern gboolean /* TRUE if overflow */ 153 mix_word_add_and_carry(mix_word_t x, mix_word_t y, 154 mix_word_t *high_word, mix_word_t *low_word); 155 156 /* Product, stored in -high_word- and -low_word-, which 157 can be NULL. 158 */ 159 extern void 160 mix_word_mul(mix_word_t x, mix_word_t y, 161 mix_word_t *high_word, mix_word_t *low_word); 162 163 /* Division. -quotient- and/or -remainder- can be NULL. */ 164 extern gboolean /* TRUE if overflow */ 165 mix_word_div(mix_word_t n1, mix_word_t n0, mix_word_t d, 166 mix_word_t *quotient, mix_word_t *remainder); 167 168 /* Shift operations */ 169 extern void 170 mix_word_shift_left(mix_word_t A, mix_word_t X, gulong count, 171 mix_word_t *pA, mix_word_t *pX); 172 extern void 173 mix_word_shift_right(mix_word_t A, mix_word_t X, gulong count, 174 mix_word_t *pA, mix_word_t *pX); 175 extern void 176 mix_word_shift_left_circular(mix_word_t A, mix_word_t X, gulong count, 177 mix_word_t *pA, mix_word_t *pX); 178 extern void 179 mix_word_shift_right_circular(mix_word_t A, mix_word_t X, gulong count, 180 mix_word_t *pA, mix_word_t *pX); 181 182 extern void 183 mix_word_shift_left_binary(mix_word_t A, mix_word_t X, gulong count, 184 mix_word_t *pA, mix_word_t *pX); 185 186 extern void 187 mix_word_shift_right_binary(mix_word_t A, mix_word_t X, gulong count, 188 mix_word_t *pA, mix_word_t *pX); 189 190 /* 191 * Fields within a word: a word containing the (L:R) 192 * bytes of the original one. L and R (with 0 <= L <= R < 6) 193 * are specified by a mix_fspec_t F = 8*L + R. 194 */ 195 typedef guint8 mix_fspec_t; 196 197 #define mix_fspec_left(f) ( ((f)>>3) & 7 ) 198 #define mix_fspec_right(f) ( (f) & 7 ) 199 #define mix_fspec_new(L,R) ( mix_byte_new(8*(L) + (R)) ) 200 201 extern gboolean 202 mix_fspec_is_valid(mix_fspec_t f); 203 204 extern mix_word_t /* the specified field or 0 if f is not valid */ 205 mix_word_get_field(mix_fspec_t f, mix_word_t word); 206 207 extern mix_word_t /* -to- with the field -f- from -from- or -to- 208 if -f- is not a valid fspec */ 209 mix_word_set_field(mix_fspec_t f, mix_word_t from, mix_word_t to); 210 211 /* set field into a zero word */ 212 #define mix_word_extract_field(fspec,from_word) \ 213 mix_word_set_field(fspec,from_word,MIX_WORD_ZERO) 214 215 /* Store operation: the no. of bytes determined by -f- is taken 216 * from the right of -from- and stored into -to- in the location 217 * specified by -f- 218 */ 219 extern mix_word_t 220 mix_word_store_field(mix_fspec_t f, mix_word_t from, mix_word_t to); 221 222 223 /* Printable representation */ 224 #define mix_word_print(word,message) \ 225 mix_word_print_to_file (word, message, stdout) 226 227 extern void 228 mix_word_print_to_file (mix_word_t word, const char *message, FILE *f); 229 230 extern void 231 mix_word_print_to_buffer (mix_word_t word, gchar *buf); 232 233 234 /*----------------- mix_short_t ------------------------------------------*/ 235 typedef guint16 mix_short_t; 236 237 #define MIX_SHORT_MAX ((1L << 12) - 1) 238 #define MIX_SHORT_SIGN_BIT ((mix_short_t)(1L << 12)) 239 #define MIX_SHORT_ZERO ((mix_short_t)0) 240 #define MIX_SHORT_MINUS_ZERO (MIX_SHORT_ZERO | MIX_SHORT_SIGN_BIT) 241 242 /* Sign-related definitions */ 243 #define mix_short_negative(s) ( (s) ^ MIX_SHORT_SIGN_BIT ) 244 #define mix_short_sign(s) ( (s) & MIX_SHORT_SIGN_BIT ) 245 #define mix_short_magnitude(s) \ 246 ( (s) & (MIX_SHORT_SIGN_BIT - 1) ) 247 #define mix_short_is_positive(s) ( mix_short_sign(s) == 0 ) 248 #define mix_short_is_negative(s) ( mix_short_sign(s) != 0 ) 249 #define mix_short_reverse_sign(s) ( (s) ^= MIX_SHORT_SIGN_BIT ) 250 251 /* create short from a long */ 252 #define mix_short_new(val) \ 253 ((val)>= 0 ? (val)&MIX_SHORT_MAX : mix_short_negative(-(val))) 254 255 /* Create shorts from individual bytes */ 256 #define mix_short_new_b(b1,b2) \ 257 ((mix_short_t)((mix_byte_new(b1)<<6) + mix_byte_new(b2))) 258 259 #define mix_short_new_bn(b1,b2) mix_short_negative(mix_short_new_b(b1,b2)) 260 261 /* Conversions between words and shorts. Arithmetic operations 262 on shorts are not provided but for addition: use words instead. 263 */ 264 /* Make a short taking word's sign and its two least significant 265 bytes (bytes no. 4 and 5) 266 */ 267 extern mix_short_t 268 mix_word_to_short(mix_word_t word); 269 270 extern mix_word_t 271 mix_short_to_word(mix_short_t s); 272 273 /* fast conversion (these macros' argument are evaluated twice */ 274 #define mix_word_to_short_fast(w) \ 275 ( mix_word_is_negative(w) ? \ 276 ((w) & MIX_SHORT_MAX)|MIX_SHORT_SIGN_BIT : (w)&MIX_SHORT_MAX ) 277 278 #define mix_short_to_word_fast(s) \ 279 ( mix_short_is_negative(s) ? \ 280 (mix_word_t) (mix_short_magnitude(s)|MIX_WORD_SIGN_BIT): (mix_word_t)(s) ) 281 282 283 extern mix_short_t 284 mix_short_add(mix_short_t x, mix_short_t y); 285 286 287 /* printable representation */ 288 extern void 289 mix_short_print(mix_short_t s, const gchar *message); 290 291 extern void 292 mix_short_print_to_buffer (mix_short_t s, gchar *buf); 293 294 295 296 #endif /* MIX_TYPES_H */ 297 298 299 300 301