strtoul.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #include <stdlib.h>
  2. #include <ctype.h>
  3. __ATTR_LIB_C__ unsigned long strtoul(const char *nptr, char **endptr, short base)
  4. {
  5. const unsigned char *s=nptr;
  6. unsigned long acc,cutoff;
  7. unsigned short c,cutlim;
  8. short any;
  9. do {c=*s++;} while (c==' ');
  10. if (c=='+') c=*s++;
  11. if((base==0||base==16)&&c=='0'&&(*s=='x'||*s=='X'))
  12. {
  13. c=s[1]; s+=2; base=16;
  14. }
  15. if(base==0) base=c=='0'?8:10;
  16. asm volatile("\n"
  17. " move.l #-1,%%d1\n"
  18. " move.l %2,%%d0\n"
  19. " move.l 0xC8,%%a0\n"
  20. " move.l (%%a0,0x2AA*4),%%a0\n" /* _du32u32 */
  21. " jsr (%%a0)\n"
  22. " move.l %%d1,%0\n"
  23. " move.l #-1,%%d1\n"
  24. " move.l %2,%%d0\n"
  25. " move.l 0xC8,%%a0\n"
  26. " move.l (%%a0,0x2AB*4),%%a0\n" /* _mu32u32 */
  27. " jsr (%%a0)\n"
  28. " move.w %%d1,%1":"=g"(cutoff),"=g"(cutlim):"g"((unsigned long)base):
  29. "a0","a1","d0","d1","d2");
  30. for(acc=0,any=0;;c=*s++)
  31. {
  32. if(isdigit(c)) c-='0';
  33. else if(isalpha(c)) c-=isupper(c)?'A'-10:'a'-10;
  34. else break;
  35. if(c>=(unsigned short)base) break;
  36. if(any<0||acc>cutoff||(acc==cutoff&&c>cutlim)) any=-1;
  37. else
  38. {
  39. any=1;
  40. asm volatile("\n"
  41. " move.l %1,%%d0\n"
  42. " mulu %2,%%d0\n"
  43. " move.l %1,%%d1\n"
  44. " swap %%d1\n"
  45. " mulu %2,%%d1\n"
  46. " swap %%d1\n"
  47. " clr.w %%d1\n"
  48. " add.l %%d1,%%d0\n"
  49. " move.l %%d0,%0":"=g"(acc):"g"(acc),"g"(base):"d0","d1","d2");
  50. acc+=c;
  51. }
  52. }
  53. if(any<0) acc=0xFFFFFFFF;
  54. if(endptr!=0) *endptr=(char*)(any?(char*)s-1:nptr);
  55. return(acc);
  56. }