* Make pointer values work better by treating them uniformly as 64 bit values.
[oota-llvm.git] / tools / lli / RuntimeLib.lc
1 //===-- RuntimeLib.lc - LLVM Standard C Runtime Library -----------*- C -*-===//
2 // 
3 // This file contains definitions of C functions that are useful to get LLVM
4 // programs up and running.  This library of functions is automatically linked
5 // into programs loaded into LLI.
6 //
7 // This file is compiled by the LLVM port of GCC to get LLVM code.
8 //
9 // A lot of this code is ripped gratuitously from glibc and libiberty.
10 //
11 //===----------------------------------------------------------------------===//
12
13
14 // Prototypes for functions exported by LLI directly.
15 void exit(int Code);
16 int putchar(int);
17 void *malloc(unsigned);
18 void free(void *);
19
20 #define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
21 #define isdigit(x) ((x) >= '0' || (x) <= '9')
22 #define isupper(x) ((x) >= 'A' || (x) <= 'Z')
23 #define islower(x) ((x) >= 'a' || (x) <= 'z')
24 #define isalpha(x) (isupper(x) || islower(x))
25
26 // The puts() function writes the string pointed to by s, followed by a 
27 // NEWLINE character, to the standard output stream stdout. On success the 
28 // number of characters written is returned; otherwise they return EOF.
29 //
30 int puts(const char *S) {
31   const char *Str = S;
32   while (*Str) putchar(*Str++);
33   putchar('\n');
34   return Str+1-S;
35 }
36
37
38 #ifndef ULONG_MAX
39 #define ULONG_MAX       ((unsigned long)(~0L))          /* 0xFFFFFFFF */
40 #endif
41
42 #ifndef LONG_MAX
43 #define LONG_MAX        ((long)(ULONG_MAX >> 1))        /* 0x7FFFFFFF */
44 #endif
45
46 #ifndef LONG_MIN
47 #define LONG_MIN        ((long)(~LONG_MAX))             /* 0x80000000 */
48 #endif
49
50 /*
51  * Convert a string to a long integer.
52  *
53  * Ignores `locale' stuff.  Assumes that the upper and lower case
54  * alphabets and digits are each contiguous.
55  */
56 long strtol(const char *nptr, char **endptr, int base) {
57         register const char *s = nptr;
58         register unsigned long acc;
59         register int c;
60         register unsigned long cutoff;
61         register int neg = 0, any, cutlim;
62
63         /*
64          * Skip white space and pick up leading +/- sign if any.
65          * If base is 0, allow 0x for hex and 0 for octal, else
66          * assume decimal; if base is already 16, allow 0x.
67          */
68         do {
69                 c = *s++;
70         } while (isspace(c));
71         if (c == '-') {
72                 neg = 1;
73                 c = *s++;
74         } else if (c == '+')
75                 c = *s++;
76         if ((base == 0 || base == 16) &&
77             c == '0' && (*s == 'x' || *s == 'X')) {
78                 c = s[1];
79                 s += 2;
80                 base = 16;
81         }
82         if (base == 0)
83                 base = c == '0' ? 8 : 10;
84
85         /*
86          * Compute the cutoff value between legal numbers and illegal
87          * numbers.  That is the largest legal value, divided by the
88          * base.  An input number that is greater than this value, if
89          * followed by a legal input character, is too big.  One that
90          * is equal to this value may be valid or not; the limit
91          * between valid and invalid numbers is then based on the last
92          * digit.  For instance, if the range for longs is
93          * [-2147483648..2147483647] and the input base is 10,
94          * cutoff will be set to 214748364 and cutlim to either
95          * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
96          * a value > 214748364, or equal but the next digit is > 7 (or 8),
97          * the number is too big, and we will return a range error.
98          *
99          * Set any if any `digits' consumed; make it negative to indicate
100          * overflow.
101          */
102         cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
103         cutlim = cutoff % (unsigned long)base;
104         cutoff /= (unsigned long)base;
105         for (acc = 0, any = 0;; c = *s++) {
106                 if (isdigit(c))
107                         c -= '0';
108                 else if (isalpha(c))
109                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
110                 else
111                         break;
112                 if (c >= base)
113                         break;
114                 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
115                         any = -1;
116                 else {
117                         any = 1;
118                         acc *= base;
119                         acc += c;
120                 }
121         }
122         if (any < 0) {
123                 acc = neg ? LONG_MIN : LONG_MAX;
124         } else if (neg)
125                 acc = -acc;
126         if (endptr != 0)
127                 *endptr = (char *) (any ? s - 1 : nptr);
128         return (acc);
129 }
130
131
132 /* Convert a string to an int.  */
133 int atoi(const char *nptr) {
134   return (int)strtol(nptr, 0, 10);
135 }
136
137 /* Convert a string to a long int.  */
138 long int atol(const char *nptr) {
139   return strtol(nptr, 0, 10);
140 }
141
142
143
144
145
146
147 //===----------------------------------------------------------------------===//
148 // libm stuff...
149 //===----------------------------------------------------------------------===//
150