OpenCores
URL https://opencores.org/ocsvn/hf-risc/hf-risc/trunk

Subversion Repositories hf-risc

[/] [hf-risc/] [trunk/] [software/] [lib/] [libc.c] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 serginhofr
/* file:          libc.c
2
 * description:   small C library
3
 * date:          09/2015
4
 * author:        Sergio Johann Filho <sergio.filho@pucrs.br>
5
 */
6
 
7
#include <hf-risc.h>
8
 
9
/*
10
auxiliary routines
11
*/
12
 
13
void uart_init(uint32_t baud){
14
        uint16_t d;
15
 
16
        d = (uint16_t)(CPU_SPEED / baud);
17
        UART_DIVISOR = d;
18
        d = UART;
19
}
20
 
21
void delay_ms(uint32_t msec){
22
        volatile uint32_t cur, last, delta, msecs;
23
        uint32_t cycles_per_msec;
24
 
25
        last = COUNTER;
26
        delta = msecs = 0;
27
        cycles_per_msec = CPU_SPEED / 1000;
28
        while(msec > msecs){
29
                cur = COUNTER;
30
                if (cur < last)
31
                        delta += (cur + (CPU_SPEED - last));
32
                else
33
                        delta += (cur - last);
34
                last = cur;
35
                if (delta >= cycles_per_msec){
36
                        msecs += delta / cycles_per_msec;
37
                        delta %= cycles_per_msec;
38
                }
39
        }
40
}
41
 
42
void delay_us(uint32_t usec){
43
        volatile uint32_t cur, last, delta, usecs;
44
        uint32_t cycles_per_usec;
45
 
46
        last = COUNTER;
47
        delta = usecs = 0;
48
        cycles_per_usec = CPU_SPEED / 1000000;
49
        while(usec > usecs){
50
                cur = COUNTER;
51
                if (cur < last)
52
                        delta += (cur + (CPU_SPEED - last));
53
                else
54
                        delta += (cur - last);
55
                last = cur;
56
                if (delta >= cycles_per_usec){
57
                        usecs += delta / cycles_per_usec;
58
                        delta %= cycles_per_usec;
59
                }
60
        }
61
}
62
 
63
/*
64
interrupt management
65
*/
66
 
67
static funcptr isr[32];
68
 
69
void interrupt_handler(uint32_t cause, uint32_t *stack){                // called from the ISR
70
        int32_t i = 0;
71
 
72
        do {
73
                if(cause & 0x1){
74
                        if(isr[i]){
75
                                isr[i](stack);
76
                        }
77
                }
78
                cause >>= 1;
79
                ++i;
80
        } while(cause);
81
}
82
 
83
void interrupt_register(uint32_t mask, funcptr ptr){
84
        int32_t i;
85
 
86
        for(i=0;i<32;++i)
87
                if(mask & (1<<i))
88
                        isr[i] = ptr;
89
}
90
 
91
void exception_handler(uint32_t epc, uint32_t opcode)
92
{
93
}
94
 
95
/*
96
minimal custom C library
97
*/
98
 
99
#ifndef DEBUG_PORT
100
void putchar(int32_t value){            // polled putchar()
101
        while((IRQ_CAUSE & IRQ_UART_WRITE_AVAILABLE) == 0);
102
        UART = value;
103
}
104
 
105
int32_t kbhit(void){
106
        return IRQ_CAUSE & IRQ_UART_READ_AVAILABLE;
107
}
108
 
109
int32_t getchar(void){                  // polled getch()
110
        while(!kbhit()) ;
111
        return UART;
112
}
113
#else
114
void putchar(int32_t value){            // polled putchar()
115
        DEBUG_ADDR = value;
116
}
117
 
118
int32_t kbhit(void){
119
        return 0;
120
}
121
 
122
int32_t getchar(void){                  // polled getch()
123
        return DEBUG_ADDR;
124
}
125
#endif
126
 
127
int8_t *strcpy(int8_t *dst, const int8_t *src){
128
        int8_t *dstSave=dst;
129
        int32_t c;
130
 
131
        do{
132
                c = *dst++ = *src++;
133
        } while(c);
134
        return dstSave;
135
}
136
 
137
int8_t *strncpy(int8_t *s1, int8_t *s2, int32_t n){
138
        int32_t i;
139
        int8_t *os1;
140
 
141
        os1 = s1;
142
        for (i = 0; i < n; i++)
143
                if ((*s1++ = *s2++) == '\0') {
144
                        while (++i < n)
145
                                *s1++ = '\0';
146
                        return(os1);
147
                }
148
        return(os1);
149
}
150
 
151
int8_t *strcat(int8_t *dst, const int8_t *src){
152
        int32_t c;
153
        int8_t *dstSave=dst;
154
 
155
        while(*dst)
156
                ++dst;
157
        do{
158
                c = *dst++ = *src++;
159
        } while(c);
160
 
161
        return dstSave;
162
}
163
 
164
int8_t *strncat(int8_t *s1, int8_t *s2, int32_t n){
165
        int8_t *os1;
166
 
167
        os1 = s1;
168
        while (*s1++);
169
        --s1;
170
        while ((*s1++ = *s2++))
171
                if (--n < 0) {
172
                        *--s1 = '\0';
173
                        break;
174
                }
175
        return(os1);
176
}
177
 
178
int32_t strcmp(const int8_t *s1, const int8_t *s2){
179
        while (*s1 == *s2++)
180
                if (*s1++ == '\0')
181
                        return(0);
182
 
183
        return(*s1 - *--s2);
184
}
185
 
186
int32_t strncmp(int8_t *s1, int8_t *s2, int32_t n){
187
        while (--n >= 0 && *s1 == *s2++)
188
                if (*s1++ == '\0')
189
                        return(0);
190
 
191
        return(n<0 ? 0 : *s1 - *--s2);
192
}
193
 
194
int8_t *strstr(const int8_t *string, const int8_t *find){
195
        int32_t i;
196 16 serginhofr
 
197 13 serginhofr
        for(;;){
198
                for(i = 0; string[i] == find[i] && find[i]; ++i);
199
                if(find[i] == 0)
200 16 serginhofr
                        return (char *)string;
201 13 serginhofr
                if(*string++ == 0)
202
                        return NULL;
203
        }
204
}
205
 
206
int32_t strlen(const int8_t *s){
207
        int32_t n;
208
 
209
        n = 0;
210
        while (*s++)
211
                n++;
212
 
213
        return(n);
214
}
215
 
216
int8_t *strchr(const int8_t *s, int32_t c){
217
        while (*s != (int8_t)c)
218
                if (!*s++)
219
                        return 0;
220
 
221
        return (int8_t *)s;
222
}
223
 
224
int8_t *strpbrk(int8_t *str, int8_t *set){
225 16 serginhofr
        int8_t c, *p;
226
 
227
        for (c = *str; c != 0; str++, c = *str) {
228
                for (p = set; *p != 0; p++) {
229
                        if (c == *p) {
230
                                return str;
231
                        }
232
                }
233 13 serginhofr
        }
234 16 serginhofr
        return 0;
235
 
236 13 serginhofr
}
237
 
238
int8_t *strsep(int8_t **pp, int8_t *delim){
239
        int8_t *p, *q;
240
 
241
        if (!(p = *pp))
242
                return 0;
243 16 serginhofr
        if ((q = strpbrk (p, delim))){
244 13 serginhofr
                *pp = q + 1;
245
                *q = '\0';
246
        }else   *pp = 0;
247
 
248
        return p;
249
}
250
 
251
int8_t *strtok(int8_t *s, const int8_t *delim){
252
        const int8_t *spanp;
253
        int32_t c, sc;
254
        int8_t *tok;
255
        static int8_t *last;
256
 
257
        if (s == NULL && (s = last) == NULL)
258
                return (NULL);
259
 
260
        cont:
261
        c = *s++;
262
        for (spanp = delim; (sc = *spanp++) != 0;){
263
                if (c == sc)
264
                goto cont;
265
        }
266
 
267
        if (c == 0){
268
                last = NULL;
269
                return (NULL);
270
        }
271
        tok = s - 1;
272
 
273
        for(;;){
274
                c = *s++;
275
                spanp = delim;
276
                do{
277
                        if ((sc = *spanp++) == c){
278
                                if (c == 0)
279
                                        s = NULL;
280
                                else
281
                                        s[-1] = 0;
282
                                last = s;
283
                                return (tok);
284
                        }
285
                }while (sc != 0);
286
        }
287
}
288
 
289
void *memcpy(void *dst, const void *src, uint32_t n){
290
        int8_t *r1 = dst;
291
        const int8_t *r2 = src;
292
 
293
        while (n--)
294
                *r1++ = *r2++;
295
 
296
        return dst;
297
}
298
 
299
void *memmove(void *dst, const void *src, uint32_t n){
300
        int8_t *s = (int8_t *)dst;
301
        const int8_t *p = (const int8_t *)src;
302
 
303
        if (p >= s){
304
                while (n--)
305
                        *s++ = *p++;
306
        }else{
307
                s += n;
308
                p += n;
309
                while (n--)
310
                        *--s = *--p;
311
        }
312
 
313
        return dst;
314
}
315
 
316
int32_t memcmp(const void *cs, const void *ct, uint32_t n){
317
        const uint8_t *r1 = (const uint8_t *)cs;
318
        const uint8_t *r2 = (const uint8_t *)ct;
319
 
320
        while (n && (*r1 == *r2)) {
321
                ++r1;
322
                ++r2;
323
                --n;
324
        }
325
 
326
        return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1);
327
}
328
 
329
void *memset(void *s, int32_t c, uint32_t n){
330
        uint8_t *p = (uint8_t *)s;
331
 
332
        while (n--)
333
                *p++ = (uint8_t)c;
334
 
335
        return s;
336
}
337
 
338
int32_t strtol(const int8_t *s, int8_t **end, int32_t base){
339
        int32_t i;
340
        uint32_t ch, value=0, neg=0;
341
 
342
        if(s[0] == '-'){
343
                neg = 1;
344
                ++s;
345
        }
346
        if(s[0] == '0' && s[1] == 'x'){
347
                base = 16;
348
                s += 2;
349
        }
350
        for(i = 0; i <= 8; ++i){
351
                ch = *s++;
352
                if('0' <= ch && ch <= '9')
353
                        ch -= '0';
354
                else if('A' <= ch && ch <= 'Z')
355
                        ch = ch - 'A' + 10;
356
                else if('a' <= ch && ch <= 'z')
357
                        ch = ch - 'a' + 10;
358
                else
359
                        break;
360
                value = value * base + ch;
361
        }
362
        if(end)
363
                *end = (char*)s - 1;
364
        if(neg)
365
                value = -(int32_t)value;
366
        return value;
367
}
368
 
369
int32_t atoi(const int8_t *s){
370
        int32_t n, f;
371
 
372
        n = 0;
373
        f = 0;
374
        for(;;s++){
375
                switch(*s){
376
                case ' ':
377
                case '\t':
378
                        continue;
379
                case '-':
380
                        f++;
381
                case '+':
382
                        s++;
383
                }
384
                break;
385
        }
386
        while(*s >= '0' && *s <= '9')
387
                n = n*10 + *s++ - '0';
388
        return(f?-n:n);
389
}
390
 
391
int8_t *itoa(int32_t i, int8_t *s, int32_t base){
392
        int8_t *ptr = s, *ptr1 = s, tmp_char;
393
        int32_t tmp_value;
394
 
395
        if (base < 2 || base > 36) {
396
                *s = '\0';
397
                return s;
398
        }
399
        do {
400
                tmp_value = i;
401
                i /= base;
402
                *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - i * base)];
403
        } while (i);
404
        if (tmp_value < 0)
405
                *ptr++ = '-';
406
        *ptr-- = '\0';
407
        while(ptr1 < ptr) {
408
                tmp_char = *ptr;
409
                *ptr--= *ptr1;
410
                *ptr1++ = tmp_char;
411
        }
412
        return s;
413
}
414
 
415
int32_t puts(const int8_t *str){
416
        while(*str)
417
                putchar(*str++);
418
        putchar('\n');
419
 
420
        return 0;
421
}
422
 
423
int8_t *gets(int8_t *s){
424
        int32_t c;
425
        int8_t *cs;
426
 
427
        cs = s;
428
        while ((c = getchar()) != '\n' && c >= 0)
429
                *cs++ = c;
430
        if (c<0 && cs==s)
431
                return(NULL);
432
        *cs++ = '\0';
433
        return(s);
434
}
435
 
436
int32_t abs(int32_t n){
437
        return n>=0 ? n:-n;
438
}
439
 
440
static uint32_t rand1=0xbaadf00d;
441
 
442
int32_t random(void){
443
        rand1 = rand1 * 1103515245 + 12345;
444
        return (uint32_t)(rand1 >> 16) & 32767;
445
}
446
 
447
void srand(uint32_t seed){
448
        rand1 = seed;
449
}
450
 
451
/*
452
printf() and sprintf()
453
*/
454
#include <stdarg.h>
455
#define PAD_RIGHT 1
456
#define PAD_ZERO 2
457
#define PRINT_BUF_LEN 30
458
 
459
static void printchar(int8_t **str, int32_t c){
460
        if (str){
461
                **str = c;
462
                ++(*str);
463
        } else
464
                (void)putchar(c);
465
}
466
 
467
static int32_t prints(int8_t **out, const int8_t *string, int32_t width, int32_t pad){
468
        int32_t pc = 0, padchar = ' ';
469
 
470
        if (width > 0){
471
                int32_t len = 0;
472
                const int8_t *ptr;
473
                for (ptr = string; *ptr; ++ptr) ++len;
474
                if (len >= width) width = 0;
475
                else width -= len;
476
                if (pad & PAD_ZERO) padchar = '0';
477
        }
478
        if (!(pad & PAD_RIGHT)){
479
                for ( ; width > 0; --width){
480
                        printchar (out, padchar);
481
                        ++pc;
482
                }
483
        }
484
        for ( ; *string ; ++string){
485
                printchar (out, *string);
486
                ++pc;
487
        }
488
        for ( ; width > 0; --width){
489
                printchar (out, padchar);
490
                ++pc;
491
        }
492
 
493
        return pc;
494
}
495
 
496
static int32_t printi(int8_t **out, int32_t i, int32_t b, int32_t sg, int32_t width, int32_t pad, int32_t letbase){
497
        int8_t print_buf[PRINT_BUF_LEN];
498
        int8_t *s;
499
        int32_t t, neg = 0, pc = 0;
500
        uint32_t u = i;
501
 
502
        if (i == 0){
503
                print_buf[0] = '0';
504
                print_buf[1] = '\0';
505
                return prints (out, print_buf, width, pad);
506
        }
507
 
508
        if (sg && b == 10 && i < 0){
509
                neg = 1;
510
                u = -i;
511
        }
512
 
513
        s = print_buf + PRINT_BUF_LEN-1;
514
        *s = '\0';
515
 
516
        while (u){
517
                t = u % b;
518
                if( t >= 10 )
519
                        t += letbase - '0' - 10;
520
                *--s = t + '0';
521
                u /= b;
522
        }
523
 
524
        if (neg){
525
                if(width && (pad & PAD_ZERO)){
526
                        printchar (out, '-');
527
                        ++pc;
528
                        --width;
529
                }
530
                else {
531
                        *--s = '-';
532
                }
533
        }
534
 
535
        return pc + prints (out, s, width, pad);
536
}
537
 
538
static int32_t print(int8_t **out, const int8_t *format, va_list args){
539
        int32_t width, pad;
540
        int32_t pc = 0;
541
        int8_t scr[2];
542
 
543
        for (; *format != 0; ++format){
544
                if (*format == '%'){
545
                        ++format;
546
                        width = pad = 0;
547
                        if (*format == '\0') break;
548
                        if (*format == '%') goto out;
549
                        if (*format == '-'){
550
                                ++format;
551
                                pad = PAD_RIGHT;
552
                        }
553
                        while (*format == '0'){
554
                                ++format;
555
                                pad |= PAD_ZERO;
556
                        }
557
                        for (; *format >= '0' && *format <= '9'; ++format){
558
                                width *= 10;
559
                                width += *format - '0';
560
                        }
561
                        if(*format == 's'){
562
                                int8_t *s = (int8_t *)va_arg(args, int32_t);
563
                                pc += prints(out, s?s:"(null)", width, pad);
564
                                continue;
565
                        }
566
                        if(*format == 'd'){
567
                                pc += printi(out, va_arg(args, int32_t), 10, 1, width, pad, 'a');
568
                                continue;
569
                        }
570
                        if(*format == 'x'){
571
                                pc += printi(out, va_arg(args, int32_t), 16, 0, width, pad, 'a');
572
                                continue;
573
                        }
574
                        if(*format == 'X'){
575
                                pc += printi(out, va_arg(args, int32_t), 16, 0, width, pad, 'A');
576
                                continue;
577
                        }
578
                        if(*format == 'u'){
579
                                pc += printi(out, va_arg(args, int32_t), 10, 0, width, pad, 'a');
580
                                continue;
581
                        }
582
                        if(*format == 'c'){
583
                                /* char are converted to int then pushed on the stack */
584
                                scr[0] = (int8_t)va_arg(args, int32_t);
585
                                scr[1] = '\0';
586
                                pc += prints(out, scr, width, pad);
587
                                continue;
588
                        }
589
                }
590
                else {
591
                out:
592
                        printchar(out, *format);
593
                        ++pc;
594
                }
595
        }
596
        if (out) **out = '\0';
597
        va_end( args );
598
        return pc;
599
}
600
 
601
int printf(const int8_t *fmt, ...){
602
        va_list args;
603
 
604
        va_start(args, fmt);
605
        return print(0, fmt, args);
606
}
607
 
608
int sprintf(int8_t *out, const int8_t *fmt, ...){
609
        va_list args;
610
 
611
        va_start(args, fmt);
612
        return print(&out, fmt, args);
613
}
614
 
615
/*
616
software implementation of multiply/divide and 64-bit routines
617
*/
618
 
619
typedef union{
620
        int64_t all;
621
        struct{
622
#if LITTLE_ENDIAN
623
                uint32_t low;
624
                int32_t high;
625
#else
626
                int32_t high;
627
                uint32_t low;
628
#endif
629
        } s;
630
} dwords;
631
 
632
int32_t __mulsi3(uint32_t a, uint32_t b){
633
        uint32_t answer = 0;
634
 
635
        while(b){
636
                if(b & 1)
637
                        answer += a;
638
                a <<= 1;
639
                b >>= 1;
640
        }
641
        return answer;
642
}
643
 
644
int64_t __muldsi3(uint32_t a, uint32_t b){
645
        dwords r;
646
 
647
        const int32_t bits_in_word_2 = (int32_t)(sizeof(int32_t) * 8) / 2;
648
        const uint32_t lower_mask = (uint32_t)~0 >> bits_in_word_2;
649
        r.s.low = (a & lower_mask) * (b & lower_mask);
650
        uint32_t t = r.s.low >> bits_in_word_2;
651
        r.s.low &= lower_mask;
652
        t += (a >> bits_in_word_2) * (b & lower_mask);
653
        r.s.low += (t & lower_mask) << bits_in_word_2;
654
        r.s.high = t >> bits_in_word_2;
655
        t = r.s.low >> bits_in_word_2;
656
        r.s.low &= lower_mask;
657
        t += (b >> bits_in_word_2) * (a & lower_mask);
658
        r.s.low += (t & lower_mask) << bits_in_word_2;
659
        r.s.high += t >> bits_in_word_2;
660
        r.s.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);
661
 
662
        return r.all;
663
}
664
 
665
int64_t __muldi3(int64_t a, int64_t b){
666
        dwords x;
667
        x.all = a;
668
        dwords y;
669
        y.all = b;
670
        dwords r;
671
        r.all = __muldsi3(x.s.low, y.s.low);
672
/*      r.s.high += x.s.high * y.s.low + x.s.low * y.s.high; */
673
        r.s.high += __mulsi3(x.s.high, y.s.low) + __mulsi3(x.s.low, y.s.high);
674
 
675
        return r.all;
676
}
677
 
678
uint32_t __udivmodsi4(uint32_t num, uint32_t den, int32_t modwanted){
679
        uint32_t bit = 1;
680
        uint32_t res = 0;
681
 
682
        while (den < num && bit && !(den & (1L << 31))) {
683
                den <<= 1;
684
                bit <<= 1;
685
        }
686
        while (bit){
687
                if (num >= den){
688
                        num -= den;
689
                        res |= bit;
690
                }
691
                bit >>= 1;
692
                den >>= 1;
693
        }
694
        if (modwanted)
695
                return num;
696
        return res;
697
}
698
 
699
int32_t __divsi3(int32_t a, int32_t b){
700
        int32_t neg = 0;
701
        int32_t res;
702
 
703
        if (a < 0){
704
                a = -a;
705
                neg = !neg;
706
        }
707
 
708
        if (b < 0){
709
                b = -b;
710
                neg = !neg;
711
        }
712
 
713
        res = __udivmodsi4(a, b, 0);
714
 
715
        if (neg)
716
                res = -res;
717
 
718
        return res;
719
}
720
 
721
int32_t __modsi3(int32_t a, int32_t b){
722
        int32_t neg = 0;
723
        int32_t res;
724
 
725
        if (a < 0){
726
                a = -a;
727
                neg = 1;
728
        }
729
 
730
        if (b < 0)
731
                b = -b;
732
 
733
        res = __udivmodsi4(a, b, 1);
734
 
735
        if (neg)
736
                res = -res;
737
 
738
        return res;
739
}
740
 
741
uint32_t __udivsi3 (uint32_t a, uint32_t b){
742
        return __udivmodsi4(a, b, 0);
743
}
744
 
745
uint32_t __umodsi3 (uint32_t a, uint32_t b){
746
        return __udivmodsi4(a, b, 1);
747
}
748
 
749
int64_t __ashldi3(int64_t u, uint32_t b){
750
        dwords uu, w;
751
        uint32_t bm;
752
 
753
        if (b == 0)
754
                return u;
755
 
756
        uu.all = u;
757
        bm = 32 - b;
758
 
759
        if (bm <= 0){
760
                w.s.low = 0;
761
                w.s.high = (uint32_t) uu.s.low << -bm;
762
        }else{
763
                const uint32_t carries = (uint32_t) uu.s.low >> bm;
764
 
765
                w.s.low = (uint32_t) uu.s.low << b;
766
                w.s.high = ((uint32_t) uu.s.high << b) | carries;
767
        }
768
 
769
        return w.all;
770
}
771
 
772
int64_t __ashrdi3(int64_t u, uint32_t b){
773
        dwords uu, w;
774
        uint32_t bm;
775
 
776
        if (b == 0)
777
                return u;
778
 
779
        uu.all = u;
780
        bm = 32 - b;
781
 
782
        if (bm <= 0){
783
                /* w.s.high = 1..1 or 0..0 */
784
                w.s.high = uu.s.high >> 31;
785
                w.s.low = uu.s.low >> -bm;
786
        }else{
787
                const uint32_t carries = (uint32_t) uu.s.high << bm;
788
 
789
                w.s.high = uu.s.high >> b;
790
                w.s.low = ((uint32_t) uu.s.low >> b) | carries;
791
        }
792
 
793
        return w.all;
794
}
795
 
796
int64_t __lshrdi3(int64_t u, uint32_t b){
797
        dwords uu, w;
798
        uint32_t bm;
799
 
800
        if (b == 0)
801
                return u;
802
 
803
        uu.all = u;
804
        bm = 32 - b;
805
 
806
        if (bm <= 0){
807
                w.s.high = 0;
808
                w.s.low = (uint32_t) uu.s.high >> -bm;
809
        }else{
810
                const uint32_t carries = (uint32_t) uu.s.high << bm;
811
 
812
                w.s.high = (uint32_t) uu.s.high >> b;
813
                w.s.low = ((uint32_t) uu.s.low >> b) | carries;
814
        }
815
 
816
        return w.all;
817
}
818
 
819
uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p){
820
        uint64_t quot = 0, qbit = 1;
821
 
822
        if (den == 0){
823
                return 1 / ((uint32_t)den);
824
        }
825
 
826
        while ((int64_t)den >= 0){
827
                den <<= 1;
828
                qbit <<= 1;
829
        }
830
 
831
        while (qbit){
832
                if (den <= num){
833
                        num -= den;
834
                        quot += qbit;
835
                }
836
                den >>= 1;
837
                qbit >>= 1;
838
        }
839
 
840
        if (rem_p)
841
                *rem_p = num;
842
 
843
        return quot;
844
}
845
 
846
uint64_t __umoddi3(uint64_t num, uint64_t den){
847
        uint64_t v;
848
 
849
        (void) __udivmoddi4(num, den, &v);
850
        return v;
851
}
852
 
853
uint64_t __udivdi3(uint64_t num, uint64_t den){
854
        return __udivmoddi4(num, den, NULL);
855
}
856
 
857
int64_t __moddi3(int64_t num, int64_t den){
858
        int minus = 0;
859
        int64_t v;
860
 
861
        if (num < 0){
862
                num = -num;
863
                minus = 1;
864
        }
865
        if (den < 0){
866
                den = -den;
867
                minus ^= 1;
868
        }
869
 
870
        (void) __udivmoddi4(num, den, (uint64_t *)&v);
871
        if (minus)
872
                v = -v;
873
 
874
        return v;
875
}
876
 
877
int64_t __divdi3(int64_t num, int64_t den){
878
        int minus = 0;
879
        int64_t v;
880
 
881
        if (num < 0){
882
                num = -num;
883
                minus = 1;
884
        }
885
        if (den < 0){
886
                den = -den;
887
                minus ^= 1;
888
        }
889
 
890
        v = __udivmoddi4(num, den, NULL);
891
        if (minus)
892
                v = -v;
893
 
894
        return v;
895
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.