OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [libraries/] [print_integer_light.as] - Blame information for rev 168

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 98 Agner
/***************************  print_integer_light.as **************************
2
* Author:        Agner Fog
3
* date created:  2021-05-16
4
* Last modified: 2021-05-16
5
* Version:       1.11
6
* Project:       ForwardCom library libc_light.li
7
* Description:   puts: print a string to stdout. Does not append linefeed
8
* This version is for CPUs with limited capabilities
9
* C declaration: void print_integer(int32_t i);
10
* C declaration: void print_unsigned(uint32_t i);
11
*
12
* Copyright 2021 GNU General Public License http://www.gnu.org/licenses
13
******************************************************************************/
14
 
15
code section execute align = 4                   // code section
16
 
17
// Print a 32-bit signed integer as decimal number to stdout
18
_print_integer function public reguse=3,0
19
 
20
if (int32 r0 < 0) {
21
    int32 r0 = -r0
22
    int8+ r1 = '-'
23
    int8 output(r1, r1, 10)  // print '-'
24
}
25
// continue in _print_unsigned
26
 
27
// Print a 32-bit unsigned integer as decimal number to stdout
28
_print_unsigned function public reguse=3,0
29
 
30
// This function is using the double dabble algorithm for binary to BCD conversion.
31
// This method is slow, but it is used here because it does not require division
32
// or multiplication. This makes sure it will work on small cores without mul and div instructions.
33
 
34
// save r2-r5
35
int64 sp -= 4*8
36
int64 [sp]      = r2
37
int64 [sp+8]    = r3
38
int64 [sp+0x10] = r4
39
int64 [sp+0x18] = r5
40
 
41
// First two BCD digits are made with simple subtraction to avoid the need for a larger bit field
42
int r5 = 0
43
while (uint32 r0 >= 1000000000) {
44
    uint32 r0 -= 1000000000
45
    uint32 r5 += 0x10
46
}
47
while (uint32 r0 >= 100000000) {
48
    uint32 r0 -= 100000000
49
    uint32 r5 += 0x01
50
}
51
uint32 r5 <<= 24
52
 
53
// Generate 8 BCD digits using double dabble algorithm
54
int32 r1 = 0
55
for (int r2 = 0; r2 < 32; r2++) {           // loop for 32 bits
56
    int32 r3 = r1 + 0x33333333              // digit values 5-9 will set bit 3 in each 4-bit nibble
57
    int32 r3 &= 0x88888888                  // isolate bit 3 in each nibble
58
    int32 r4 = r3 >> 3                      // generate value 3 in nibbles with value 5-9
59
    int32 r3 >>= 2
60
    int32 r3 |= r4                          // this will have 3 for each nibble with a value 5-9
61
    int32 r1 += r3                          // add 3 to nibble values 5-9 to generate 8-12
62
    int32 r1 = funnel_shift(r0, r1, 31)     // shift most significant bit of r0 into r1
63
    int32 r0 <<= 1
64
}
65
 
66
// r5:r1 = BCD value
67
 
68
int r4 = 0                                  // remember if first digit has been printed
69
 
70
for (int r2 = 2; r2 > 0; r2--) {
71
    int32 r5 = rotate(r5, 4)                // get most significant digit first
72
    int8 r3 = r5 & 0x0F
73
    int r4 = (r3 != 0) || r4                // digit has been printed
74
    int8 r3 += '0'
75
    if (int r4 != 0) {
76
        int8 output(r3, r3, 10)             // print character to stdout
77
    }
78
}
79
 
80
// print 8 decimal digits
81
for (int r2 = 8; r2 > 0; r2--) {
82
    int32 r1 = rotate(r1, 4)                // get most significant digit first
83
    int8 r3 = r1 & 0x0F
84
    int r4 = (r3 != 0) || r4                // digit has been printed
85
    int r4 = (r2 == 1) || r4                // last digit must be printed
86
    int8 r3 += '0'
87
    if (int r4 != 0) {
88
        int8 output(r3, r3, 10)             // print character to stdout
89
    }
90
}
91
 
92
// restore r2-r5
93
int64 r2 = [sp]
94
int64 r3 = [sp+8]
95
int64 r4 = [sp+0x10]
96
int64 r5 = [sp+0x18]
97
int64 sp += 4*8
98
return
99
_print_integer end
100
 
101
code end

powered by: WebSVN 2.1.0

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