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 13

Go to most recent revision | 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
        for(;;){
197
                for(i = 0; string[i] == find[i] && find[i]; ++i);
198
                if(find[i] == 0)
199
                        return (char*)string;
200
                if(*string++ == 0)
201
                        return NULL;
202
        }
203
}
204
 
205
int32_t strlen(const int8_t *s){
206
        int32_t n;
207
 
208
        n = 0;
209
        while (*s++)
210
                n++;
211
 
212
        return(n);
213
}
214
 
215
int8_t *strchr(const int8_t *s, int32_t c){
216
        while (*s != (int8_t)c)
217
                if (!*s++)
218
                        return 0;
219
 
220
        return (int8_t *)s;
221
}
222
 
223
int8_t *strpbrk(int8_t *str, int8_t *set){
224
        while (*str != '\0'){
225
                if (strchr(set, *str) == 0)
226
                        ++str;
227
                else
228
                        return (int8_t *) str;
229
                return 0;
230
        }
231
}
232
 
233
int8_t *strsep(int8_t **pp, int8_t *delim){
234
        int8_t *p, *q;
235
 
236
        if (!(p = *pp))
237
                return 0;
238
        if (q = strpbrk (p, delim)){
239
                *pp = q + 1;
240
                *q = '\0';
241
        }else   *pp = 0;
242
 
243
        return p;
244
}
245
 
246
int8_t *strtok(int8_t *s, const int8_t *delim){
247
        const int8_t *spanp;
248
        int32_t c, sc;
249
        int8_t *tok;
250
        static int8_t *last;
251
 
252
        if (s == NULL && (s = last) == NULL)
253
                return (NULL);
254
 
255
        cont:
256
        c = *s++;
257
        for (spanp = delim; (sc = *spanp++) != 0;){
258
                if (c == sc)
259
                goto cont;
260
        }
261
 
262
        if (c == 0){
263
                last = NULL;
264
                return (NULL);
265
        }
266
        tok = s - 1;
267
 
268
        for(;;){
269
                c = *s++;
270
                spanp = delim;
271
                do{
272
                        if ((sc = *spanp++) == c){
273
                                if (c == 0)
274
                                        s = NULL;
275
                                else
276
                                        s[-1] = 0;
277
                                last = s;
278
                                return (tok);
279
                        }
280
                }while (sc != 0);
281
        }
282
}
283
 
284
void *memcpy(void *dst, const void *src, uint32_t n){
285
        int8_t *r1 = dst;
286
        const int8_t *r2 = src;
287
 
288
        while (n--)
289
                *r1++ = *r2++;
290
 
291
        return dst;
292
}
293
 
294
void *memmove(void *dst, const void *src, uint32_t n){
295
        int8_t *s = (int8_t *)dst;
296
        const int8_t *p = (const int8_t *)src;
297
 
298
        if (p >= s){
299
                while (n--)
300
                        *s++ = *p++;
301
        }else{
302
                s += n;
303
                p += n;
304
                while (n--)
305
                        *--s = *--p;
306
        }
307
 
308
        return dst;
309
}
310
 
311
int32_t memcmp(const void *cs, const void *ct, uint32_t n){
312
        const uint8_t *r1 = (const uint8_t *)cs;
313
        const uint8_t *r2 = (const uint8_t *)ct;
314
 
315
        while (n && (*r1 == *r2)) {
316
                ++r1;
317
                ++r2;
318
                --n;
319
        }
320
 
321
        return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1);
322
}
323
 
324
void *memset(void *s, int32_t c, uint32_t n){
325
        uint8_t *p = (uint8_t *)s;
326
 
327
        while (n--)
328
                *p++ = (uint8_t)c;
329
 
330
        return s;
331
}
332
 
333
int32_t strtol(const int8_t *s, int8_t **end, int32_t base){
334
        int32_t i;
335
        uint32_t ch, value=0, neg=0;
336
 
337
        if(s[0] == '-'){
338
                neg = 1;
339
                ++s;
340
        }
341
        if(s[0] == '0' && s[1] == 'x'){
342
                base = 16;
343
                s += 2;
344
        }
345
        for(i = 0; i <= 8; ++i){
346
                ch = *s++;
347
                if('0' <= ch && ch <= '9')
348
                        ch -= '0';
349
                else if('A' <= ch && ch <= 'Z')
350
                        ch = ch - 'A' + 10;
351
                else if('a' <= ch && ch <= 'z')
352
                        ch = ch - 'a' + 10;
353
                else
354
                        break;
355
                value = value * base + ch;
356
        }
357
        if(end)
358
                *end = (char*)s - 1;
359
        if(neg)
360
                value = -(int32_t)value;
361
        return value;
362
}
363
 
364
int32_t atoi(const int8_t *s){
365
        int32_t n, f;
366
 
367
        n = 0;
368
        f = 0;
369
        for(;;s++){
370
                switch(*s){
371
                case ' ':
372
                case '\t':
373
                        continue;
374
                case '-':
375
                        f++;
376
                case '+':
377
                        s++;
378
                }
379
                break;
380
        }
381
        while(*s >= '0' && *s <= '9')
382
                n = n*10 + *s++ - '0';
383
        return(f?-n:n);
384
}
385
 
386
int8_t *itoa(int32_t i, int8_t *s, int32_t base){
387
        int8_t *ptr = s, *ptr1 = s, tmp_char;
388
        int32_t tmp_value;
389
 
390
        if (base < 2 || base > 36) {
391
                *s = '\0';
392
                return s;
393
        }
394
        do {
395
                tmp_value = i;
396
                i /= base;
397
                *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - i * base)];
398
        } while (i);
399
        if (tmp_value < 0)
400
                *ptr++ = '-';
401
        *ptr-- = '\0';
402
        while(ptr1 < ptr) {
403
                tmp_char = *ptr;
404
                *ptr--= *ptr1;
405
                *ptr1++ = tmp_char;
406
        }
407
        return s;
408
}
409
 
410
int32_t puts(const int8_t *str){
411
        while(*str)
412
                putchar(*str++);
413
        putchar('\n');
414
 
415
        return 0;
416
}
417
 
418
int8_t *gets(int8_t *s){
419
        int32_t c;
420
        int8_t *cs;
421
 
422
        cs = s;
423
        while ((c = getchar()) != '\n' && c >= 0)
424
                *cs++ = c;
425
        if (c<0 && cs==s)
426
                return(NULL);
427
        *cs++ = '\0';
428
        return(s);
429
}
430
 
431
int32_t abs(int32_t n){
432
        return n>=0 ? n:-n;
433
}
434
 
435
static uint32_t rand1=0xbaadf00d;
436
 
437
int32_t random(void){
438
        rand1 = rand1 * 1103515245 + 12345;
439
        return (uint32_t)(rand1 >> 16) & 32767;
440
}
441
 
442
void srand(uint32_t seed){
443
        rand1 = seed;
444
}
445
 
446
/*
447
printf() and sprintf()
448
*/
449
#include <stdarg.h>
450
#define PAD_RIGHT 1
451
#define PAD_ZERO 2
452
#define PRINT_BUF_LEN 30
453
 
454
static void printchar(int8_t **str, int32_t c){
455
        if (str){
456
                **str = c;
457
                ++(*str);
458
        } else
459
                (void)putchar(c);
460
}
461
 
462
static int32_t prints(int8_t **out, const int8_t *string, int32_t width, int32_t pad){
463
        int32_t pc = 0, padchar = ' ';
464
 
465
        if (width > 0){
466
                int32_t len = 0;
467
                const int8_t *ptr;
468
                for (ptr = string; *ptr; ++ptr) ++len;
469
                if (len >= width) width = 0;
470
                else width -= len;
471
                if (pad & PAD_ZERO) padchar = '0';
472
        }
473
        if (!(pad & PAD_RIGHT)){
474
                for ( ; width > 0; --width){
475
                        printchar (out, padchar);
476
                        ++pc;
477
                }
478
        }
479
        for ( ; *string ; ++string){
480
                printchar (out, *string);
481
                ++pc;
482
        }
483
        for ( ; width > 0; --width){
484
                printchar (out, padchar);
485
                ++pc;
486
        }
487
 
488
        return pc;
489
}
490
 
491
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){
492
        int8_t print_buf[PRINT_BUF_LEN];
493
        int8_t *s;
494
        int32_t t, neg = 0, pc = 0;
495
        uint32_t u = i;
496
 
497
        if (i == 0){
498
                print_buf[0] = '0';
499
                print_buf[1] = '\0';
500
                return prints (out, print_buf, width, pad);
501
        }
502
 
503
        if (sg && b == 10 && i < 0){
504
                neg = 1;
505
                u = -i;
506
        }
507
 
508
        s = print_buf + PRINT_BUF_LEN-1;
509
        *s = '\0';
510
 
511
        while (u){
512
                t = u % b;
513
                if( t >= 10 )
514
                        t += letbase - '0' - 10;
515
                *--s = t + '0';
516
                u /= b;
517
        }
518
 
519
        if (neg){
520
                if(width && (pad & PAD_ZERO)){
521
                        printchar (out, '-');
522
                        ++pc;
523
                        --width;
524
                }
525
                else {
526
                        *--s = '-';
527
                }
528
        }
529
 
530
        return pc + prints (out, s, width, pad);
531
}
532
 
533
static int32_t print(int8_t **out, const int8_t *format, va_list args){
534
        int32_t width, pad;
535
        int32_t pc = 0;
536
        int8_t scr[2];
537
 
538
        for (; *format != 0; ++format){
539
                if (*format == '%'){
540
                        ++format;
541
                        width = pad = 0;
542
                        if (*format == '\0') break;
543
                        if (*format == '%') goto out;
544
                        if (*format == '-'){
545
                                ++format;
546
                                pad = PAD_RIGHT;
547
                        }
548
                        while (*format == '0'){
549
                                ++format;
550
                                pad |= PAD_ZERO;
551
                        }
552
                        for (; *format >= '0' && *format <= '9'; ++format){
553
                                width *= 10;
554
                                width += *format - '0';
555
                        }
556
                        if(*format == 's'){
557
                                int8_t *s = (int8_t *)va_arg(args, int32_t);
558
                                pc += prints(out, s?s:"(null)", width, pad);
559
                                continue;
560
                        }
561
                        if(*format == 'd'){
562
                                pc += printi(out, va_arg(args, int32_t), 10, 1, width, pad, 'a');
563
                                continue;
564
                        }
565
                        if(*format == 'x'){
566
                                pc += printi(out, va_arg(args, int32_t), 16, 0, width, pad, 'a');
567
                                continue;
568
                        }
569
                        if(*format == 'X'){
570
                                pc += printi(out, va_arg(args, int32_t), 16, 0, width, pad, 'A');
571
                                continue;
572
                        }
573
                        if(*format == 'u'){
574
                                pc += printi(out, va_arg(args, int32_t), 10, 0, width, pad, 'a');
575
                                continue;
576
                        }
577
                        if(*format == 'c'){
578
                                /* char are converted to int then pushed on the stack */
579
                                scr[0] = (int8_t)va_arg(args, int32_t);
580
                                scr[1] = '\0';
581
                                pc += prints(out, scr, width, pad);
582
                                continue;
583
                        }
584
                }
585
                else {
586
                out:
587
                        printchar(out, *format);
588
                        ++pc;
589
                }
590
        }
591
        if (out) **out = '\0';
592
        va_end( args );
593
        return pc;
594
}
595
 
596
int printf(const int8_t *fmt, ...){
597
        va_list args;
598
 
599
        va_start(args, fmt);
600
        return print(0, fmt, args);
601
}
602
 
603
int sprintf(int8_t *out, const int8_t *fmt, ...){
604
        va_list args;
605
 
606
        va_start(args, fmt);
607
        return print(&out, fmt, args);
608
}
609
 
610
/*
611
software implementation of multiply/divide and 64-bit routines
612
*/
613
 
614
typedef union{
615
        int64_t all;
616
        struct{
617
#if LITTLE_ENDIAN
618
                uint32_t low;
619
                int32_t high;
620
#else
621
                int32_t high;
622
                uint32_t low;
623
#endif
624
        } s;
625
} dwords;
626
 
627
int32_t __mulsi3(uint32_t a, uint32_t b){
628
        uint32_t answer = 0;
629
 
630
        while(b){
631
                if(b & 1)
632
                        answer += a;
633
                a <<= 1;
634
                b >>= 1;
635
        }
636
        return answer;
637
}
638
 
639
int64_t __muldsi3(uint32_t a, uint32_t b){
640
        dwords r;
641
 
642
        const int32_t bits_in_word_2 = (int32_t)(sizeof(int32_t) * 8) / 2;
643
        const uint32_t lower_mask = (uint32_t)~0 >> bits_in_word_2;
644
        r.s.low = (a & lower_mask) * (b & lower_mask);
645
        uint32_t t = r.s.low >> bits_in_word_2;
646
        r.s.low &= lower_mask;
647
        t += (a >> bits_in_word_2) * (b & lower_mask);
648
        r.s.low += (t & lower_mask) << bits_in_word_2;
649
        r.s.high = t >> bits_in_word_2;
650
        t = r.s.low >> bits_in_word_2;
651
        r.s.low &= lower_mask;
652
        t += (b >> bits_in_word_2) * (a & lower_mask);
653
        r.s.low += (t & lower_mask) << bits_in_word_2;
654
        r.s.high += t >> bits_in_word_2;
655
        r.s.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);
656
 
657
        return r.all;
658
}
659
 
660
int64_t __muldi3(int64_t a, int64_t b){
661
        dwords x;
662
        x.all = a;
663
        dwords y;
664
        y.all = b;
665
        dwords r;
666
        r.all = __muldsi3(x.s.low, y.s.low);
667
/*      r.s.high += x.s.high * y.s.low + x.s.low * y.s.high; */
668
        r.s.high += __mulsi3(x.s.high, y.s.low) + __mulsi3(x.s.low, y.s.high);
669
 
670
        return r.all;
671
}
672
 
673
uint32_t __udivmodsi4(uint32_t num, uint32_t den, int32_t modwanted){
674
        uint32_t bit = 1;
675
        uint32_t res = 0;
676
 
677
        while (den < num && bit && !(den & (1L << 31))) {
678
                den <<= 1;
679
                bit <<= 1;
680
        }
681
        while (bit){
682
                if (num >= den){
683
                        num -= den;
684
                        res |= bit;
685
                }
686
                bit >>= 1;
687
                den >>= 1;
688
        }
689
        if (modwanted)
690
                return num;
691
        return res;
692
}
693
 
694
int32_t __divsi3(int32_t a, int32_t b){
695
        int32_t neg = 0;
696
        int32_t res;
697
 
698
        if (a < 0){
699
                a = -a;
700
                neg = !neg;
701
        }
702
 
703
        if (b < 0){
704
                b = -b;
705
                neg = !neg;
706
        }
707
 
708
        res = __udivmodsi4(a, b, 0);
709
 
710
        if (neg)
711
                res = -res;
712
 
713
        return res;
714
}
715
 
716
int32_t __modsi3(int32_t a, int32_t b){
717
        int32_t neg = 0;
718
        int32_t res;
719
 
720
        if (a < 0){
721
                a = -a;
722
                neg = 1;
723
        }
724
 
725
        if (b < 0)
726
                b = -b;
727
 
728
        res = __udivmodsi4(a, b, 1);
729
 
730
        if (neg)
731
                res = -res;
732
 
733
        return res;
734
}
735
 
736
uint32_t __udivsi3 (uint32_t a, uint32_t b){
737
        return __udivmodsi4(a, b, 0);
738
}
739
 
740
uint32_t __umodsi3 (uint32_t a, uint32_t b){
741
        return __udivmodsi4(a, b, 1);
742
}
743
 
744
int64_t __ashldi3(int64_t u, uint32_t b){
745
        dwords uu, w;
746
        uint32_t bm;
747
 
748
        if (b == 0)
749
                return u;
750
 
751
        uu.all = u;
752
        bm = 32 - b;
753
 
754
        if (bm <= 0){
755
                w.s.low = 0;
756
                w.s.high = (uint32_t) uu.s.low << -bm;
757
        }else{
758
                const uint32_t carries = (uint32_t) uu.s.low >> bm;
759
 
760
                w.s.low = (uint32_t) uu.s.low << b;
761
                w.s.high = ((uint32_t) uu.s.high << b) | carries;
762
        }
763
 
764
        return w.all;
765
}
766
 
767
int64_t __ashrdi3(int64_t u, uint32_t b){
768
        dwords uu, w;
769
        uint32_t bm;
770
 
771
        if (b == 0)
772
                return u;
773
 
774
        uu.all = u;
775
        bm = 32 - b;
776
 
777
        if (bm <= 0){
778
                /* w.s.high = 1..1 or 0..0 */
779
                w.s.high = uu.s.high >> 31;
780
                w.s.low = uu.s.low >> -bm;
781
        }else{
782
                const uint32_t carries = (uint32_t) uu.s.high << bm;
783
 
784
                w.s.high = uu.s.high >> b;
785
                w.s.low = ((uint32_t) uu.s.low >> b) | carries;
786
        }
787
 
788
        return w.all;
789
}
790
 
791
int64_t __lshrdi3(int64_t u, uint32_t b){
792
        dwords uu, w;
793
        uint32_t bm;
794
 
795
        if (b == 0)
796
                return u;
797
 
798
        uu.all = u;
799
        bm = 32 - b;
800
 
801
        if (bm <= 0){
802
                w.s.high = 0;
803
                w.s.low = (uint32_t) uu.s.high >> -bm;
804
        }else{
805
                const uint32_t carries = (uint32_t) uu.s.high << bm;
806
 
807
                w.s.high = (uint32_t) uu.s.high >> b;
808
                w.s.low = ((uint32_t) uu.s.low >> b) | carries;
809
        }
810
 
811
        return w.all;
812
}
813
 
814
uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p){
815
        uint64_t quot = 0, qbit = 1;
816
 
817
        if (den == 0){
818
                return 1 / ((uint32_t)den);
819
        }
820
 
821
        while ((int64_t)den >= 0){
822
                den <<= 1;
823
                qbit <<= 1;
824
        }
825
 
826
        while (qbit){
827
                if (den <= num){
828
                        num -= den;
829
                        quot += qbit;
830
                }
831
                den >>= 1;
832
                qbit >>= 1;
833
        }
834
 
835
        if (rem_p)
836
                *rem_p = num;
837
 
838
        return quot;
839
}
840
 
841
uint64_t __umoddi3(uint64_t num, uint64_t den){
842
        uint64_t v;
843
 
844
        (void) __udivmoddi4(num, den, &v);
845
        return v;
846
}
847
 
848
uint64_t __udivdi3(uint64_t num, uint64_t den){
849
        return __udivmoddi4(num, den, NULL);
850
}
851
 
852
int64_t __moddi3(int64_t num, int64_t den){
853
        int minus = 0;
854
        int64_t v;
855
 
856
        if (num < 0){
857
                num = -num;
858
                minus = 1;
859
        }
860
        if (den < 0){
861
                den = -den;
862
                minus ^= 1;
863
        }
864
 
865
        (void) __udivmoddi4(num, den, (uint64_t *)&v);
866
        if (minus)
867
                v = -v;
868
 
869
        return v;
870
}
871
 
872
int64_t __divdi3(int64_t num, int64_t den){
873
        int minus = 0;
874
        int64_t v;
875
 
876
        if (num < 0){
877
                num = -num;
878
                minus = 1;
879
        }
880
        if (den < 0){
881
                den = -den;
882
                minus ^= 1;
883
        }
884
 
885
        v = __udivmoddi4(num, den, NULL);
886
        if (minus)
887
                v = -v;
888
 
889
        return v;
890
}

powered by: WebSVN 2.1.0

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