MHEG5  18.9.0
MHEG5 Documentation
glue_ulong.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2012 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include "glue_ulong.h"
27 
28 /*---constant definitions for this file--------------------------------------*/
29 
30 
31 /*---local typedef structs for this file-------------------------------------*/
32 
33 /*---local function definitions----------------------------------------------*/
34 
35 /*---global function definitions---------------------------------------------*/
36 
37 /*---local (static) variable declarations for this file----------------------*/
38 
39 
40 #ifndef USE_TRUE_64BIT
41 
48 U64BIT ULONG_Add(U64BIT variable, U64BIT value)
49 {
50  U32BIT t = variable.l;
51 
52  variable.l += value.l;
53  if (variable.l < t)
54  {
55  /* overflow */
56  ++variable.h;
57  }
58  variable.h += value.h;
59  return variable;
60 }
61 
68 U64BIT ULONG_Add32(U64BIT variable, U32BIT value)
69 {
70  U32BIT t = variable.l;
71 
72  variable.l += value;
73  if (variable.l < t)
74  {
75  /* overflow */
76  ++variable.h;
77  }
78  return variable;
79 }
80 
89 U64BIT ULONG_Sub(U64BIT variable, U64BIT value)
90 {
91  U32BIT c;
92 
93  c = (value.l > variable.l);
94  variable.l -= value.l;
95  variable.h -= value.h;
96  variable.h -= c;
97  return variable;
98 }
99 
108 U64BIT ULONG_Sub32(U64BIT variable, U32BIT value)
109 {
110  U32BIT c;
111 
112  c = (value > variable.l);
113  variable.l -= value;
114  variable.h -= c;
115  return variable;
116 }
117 
124 U64BIT ULONG_Mul32(U64BIT variable, U32BIT value)
125 {
126  U32BIT t0, t1, t2, t3, t4, t5, t6, c, hw;
127  U16BIT a0, a1, a2, a3;
128  U16BIT b0, b1;
129 
130  /*
131  * 6 5 4 3 2 1 0
132  *
133  * a3 a2 a1 a0
134  * b1 b0 tmp
135  * ------------------- ---
136  * a0xb0 0
137  * a1xb0 1
138  * a2xb0 2
139  * a3xb0 3
140  * a0xb1 4
141  * a1xb1 5
142  * a2xb1 6
143  * a3xb1 7 -- unused
144  * --------------------
145  */
146 
147  a0 = variable.l & 0xffffU;
148  a1 = (variable.l >> 16) & 0xffffU;
149  a2 = variable.h & 0xffffU;
150  a3 = (variable.h >> 16) & 0xffffU;
151  b0 = value & 0xffffU;
152  b1 = (value >> 16) & 0xffffU;
153 
154  t0 = b0 * a0;
155  t1 = b0 * a1;
156  t2 = b0 * a2;
157  t3 = b0 * a3;
158 
159  t4 = b1 * a0;
160  t5 = b1 * a1;
161  t6 = b1 * a2;
162  /* t7 = b1 * a3; -- unused */
163 
164  c = 0;
165 
166  /* Calculate variable.l and remember the carry */
167  variable.l = t0;
168  hw = (t1 << 16) & 0xffff0000U;
169  c += (variable.l + hw < variable.l);
170  variable.l += hw;
171  hw = (t4 << 16) & 0xffff0000U;
172  c += (variable.l + hw < variable.l);
173  variable.l += hw;
174 
175  /* Avoid issues with 64-bit processors */
176  variable.l &= 0xffffffffU;
177 
178  /* Calculate variable.h */
179  variable.h = (t1 >> 16) + t2 + (t3 << 16) + (t4 >> 16) + t5 + (t6 << 16) + c;
180 
181  /* Avoid issues with 64-bit processors */
182  variable.h &= 0xffffffffU;
183 
184  return variable;
185 }
186 
195 U64BIT ULONG_Div32(U64BIT variable, U32BIT value)
196 {
197  U32BIT m, p, acc;
198 
199  /* Calculate MSW */
200  p = variable.h;
201  m = variable.h % value;
202  variable.h = (p - m) / value;
203 
204  /* Calculate LSW (one byte at a time) */
205  m = ((m << 8) | ((variable.l >> 24) & 0xff)) & 0xffffffffU;
206  p = m;
207  m %= value;
208  acc = (p - m) / value;
209 
210  m = ((m << 8) | ((variable.l >> 16) & 0xff)) & 0xffffffffU;
211  p = m;
212  m %= value;
213  acc = acc * 256 + (p - m) / value;
214 
215  m = ((m << 8) | ((variable.l >> 8) & 0xff)) & 0xffffffffU;
216  p = m;
217  m %= value;
218  acc = acc * 256 + (p - m) / value;
219 
220  m = ((m << 8) | (variable.l & 0xff)) & 0xffffffffU;
221  p = m;
222  m %= value;
223  acc = acc * 256 + (p - m) / value;
224 
225  variable.l = acc;
226 
227  return variable;
228 }
229 
237 {
238  U32BIT c;
239  if (value > 63)
240  {
241  variable.l = 0;
242  variable.h = 0;
243  }
244  else if (value > 31)
245  {
246  variable.h = variable.l;
247  variable.h <<= value - 32;
248  variable.l = 0;
249  }
250  else
251  {
252  c = variable.l >> (32 - value);
253  variable.h <<= value;
254  variable.h |= c;
255  variable.l <<= value;
256  }
257  return variable;
258 }
259 
267 {
268  U32BIT c;
269  if (value > 63)
270  {
271  variable.l = 0;
272  variable.h = 0;
273  }
274  else if (value > 31)
275  {
276  variable.l = variable.h;
277  variable.l >>= value - 32;
278  variable.h = 0;
279  }
280  else
281  {
282  c = variable.h << (32 - value);
283  variable.l >>= value;
284  variable.l |= c;
285  variable.h >>= value;
286  }
287  return variable;
288 }
289 
299 U32BIT ULONG_Mod32(U64BIT variable, U32BIT value)
300 {
301  U32BIT acc;
302 
303  acc = variable.h % value;
304  acc = (acc << 8 | ((variable.l >> 24) & 0xff)) % value;
305  acc = (acc << 8 | ((variable.l >> 16) & 0xff)) % value;
306  acc = (acc << 8 | ((variable.l >> 8) & 0xff)) % value;
307  acc = (acc << 8 | (variable.l & 0xff)) % value;
308 
309  return acc;
310 }
311 
322 {
323  S32BIT cmp;
324 
325  /* Avoid problems with signed/unsigned, 64 bit values etc.
326  * Just do a simple, portable, straight-forward comparison.
327  */
328  if (first.h > second.h)
329  {
330  cmp = 1;
331  }
332  else if (first.h == second.h)
333  {
334  if (first.l > second.l)
335  {
336  cmp = 1;
337  }
338  else if (first.l == second.l)
339  {
340  cmp = 0;
341  }
342  else
343  {
344  cmp = -1;
345  }
346  }
347  else
348  {
349  cmp = -1;
350  }
351 
352  return cmp;
353 }
354 
365 {
366  S32BIT cmp;
367 
368  /* Avoid problems with signed/unsigned, 64 bit values etc.
369  * Just do a simple, portable, straight-forward comparison.
370  */
371  if (variable.h > 0)
372  {
373  cmp = 1;
374  }
375  else if (variable.l > value)
376  {
377  cmp = 1;
378  }
379  else if (variable.l == value)
380  {
381  cmp = 0;
382  }
383  else
384  {
385  cmp = -1;
386  }
387 
388  return cmp;
389 }
390 
398 U64BIT ULONG_Atoi(char *str)
399 {
400  U64BIT variable;
401  variable.l = 0;
402  variable.h = 0;
403 
404  if (*str >= '0' && *str <= '9')
405  {
406  variable.l = *str - '0';
407  str++;
408  }
409 
410  while (*str >= '0' && *str <= '9')
411  {
412  variable = ULONG_Mul32(variable, 10);
413  variable = ULONG_Add32(variable, *str - '0');
414  str++;
415  }
416  return variable;
417 }
418 
427 void ULONG_Itoa(U64BIT variable, char *str)
428 {
429  char local[MAX_64BIT_DECIMAL_STRING];
430  U64BIT tmp;
431  int p;
432 
433  if (variable.l == 0 && variable.h == 0)
434  {
435  /* Special case */
436  str[0] = '0';
437  str[1] = '\0';
438  }
439  else
440  {
441  /* Slow and painful */
442  tmp = variable;
443  p = 0;
444  while (tmp.l != 0 || tmp.h != 0)
445  {
446  /* Using mod rules and the fact that 2**32 mod 10 = 6 */
447  local[p] = '0' + (6 * (tmp.h % 10) + (tmp.l % 10)) % 10;
448  tmp = ULONG_Div32(tmp, 10);
449  ++p;
450  }
451 
452  /* Result is reversed */
453  str[p] = '\0';
454  do
455  {
456  --p;
457  *str = local[p];
458  ++str;
459  }
460  while (p > 0);
461  }
462 }
463 
464 #else /*USE_TRUE_64BIT*/
465 
466 
475 U64BIT ULONG_Atoi(char *str )
476 {
477  U64BIT variable = 0;
478  if (*str >= '0' && *str <= '9')
479  {
480  variable = *str - '0';
481  str++;
482  }
483  while (*str >= '0' && *str <= '9')
484  {
485  variable *= 10;
486  variable += *str - '0';
487  str++;
488  }
489  return variable;
490 }
491 
500 void ULONG_Itoa(U64BIT variable, char *str)
501 {
502  char local[MAX_64BIT_DECIMAL_STRING];
503  int p;
504 
505  if (variable == 0)
506  {
507  /* Special case */
508  str[0] = '0';
509  str[1] = '\0';
510  }
511  else
512  {
513  /* Slow and painful */
514  p = 0;
515  while (variable != 0)
516  {
517  local[p] = '0' + variable % 10;
518  variable /= 10;
519  ++p;
520  }
521 
522  /* Result is reversed */
523  str[p] = '\0';
524  do
525  {
526  --p;
527  *str = local[p];
528  ++str;
529  }
530  while (p > 0);
531  }
532 }
533 
534 #endif /*USE_TRUE_64BIT*/
535 
S32BIT ULONG_Compare32(U64BIT variable, U32BIT value)
Compare a variable with a 32-bit value, returning a value that indicates the result of the comparison...
Definition: glue_ulong.c:364
U32BIT h
Definition: glue_ulong.h:109
U32BIT l
Definition: glue_ulong.h:109
U64BIT ULONG_ShiftRight(U64BIT variable, U32BIT value)
Shift bits right on unsigned 64 bit variable by a 32-bit value.
Definition: glue_ulong.c:266
S32BIT ULONG_Compare(U64BIT first, U64BIT second)
Compare two variables, returning a value that indicates the result of the comparison.
Definition: glue_ulong.c:321
U64BIT ULONG_ShiftLeft(U64BIT variable, U32BIT value)
Shift bits left on unsigned 64 bit variable by a 32-bit value.
Definition: glue_ulong.c:236
U64BIT ULONG_Sub32(U64BIT variable, U32BIT value)
Subtract a 32-bit value from a unsigned 64 bit variable. It is the responsibility of the caller to ma...
Definition: glue_ulong.c:108
U64BIT ULONG_Sub(U64BIT variable, U64BIT value)
Subtract a value from a unsigned 64 bit variable. It is the responsibility of the caller to make sure...
Definition: glue_ulong.c:89
int32_t S32BIT
Definition: techtype.h:87
U64BIT ULONG_Div32(U64BIT variable, U32BIT value)
Divide a unsigned 64 bit variable by a 24-bit value. NOTE: This function will produce invalid values ...
Definition: glue_ulong.c:195
uint16_t U16BIT
Definition: techtype.h:84
U64BIT ULONG_Add(U64BIT variable, U64BIT value)
Add a value to a unsigned 64 bit variable.
Definition: glue_ulong.c:48
U64BIT ULONG_Atoi(char *str)
Convert a string to a unsigned 64 bit. Only the numeric part of the string is converted (up to the fi...
Definition: glue_ulong.c:398
U64BIT ULONG_Add32(U64BIT variable, U32BIT value)
Add a 32-bit value to a unsigned 64 bit variable.
Definition: glue_ulong.c:68
#define MAX_64BIT_DECIMAL_STRING
Definition: glue_ulong.h:57
U32BIT ULONG_Mod32(U64BIT variable, U32BIT value)
Find the remainer after dividing a unsigned 64 bit variable by a 24-bit value. NOTE: This function wi...
Definition: glue_ulong.c:299
void ULONG_Itoa(U64BIT variable, char *str)
Convert a unsigned 64 bit to a string. The string should be able to hold at least 21 characters...
Definition: glue_ulong.c:427
uint32_t U32BIT
Definition: techtype.h:86
U64BIT ULONG_Mul32(U64BIT variable, U32BIT value)
Multiply a unsigned 64 bit variable by a 32-bit value.
Definition: glue_ulong.c:124