strtol.c 1.7 KB

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