URL
https://opencores.org/ocsvn/forwardcom/forwardcom/trunk
Subversion Repositories forwardcom
[/] [forwardcom/] [libraries/] [print_integer_light.as] - Rev 98
Compare with Previous | Blame | View Log
/*************************** print_integer_light.as *************************** Author: Agner Fog* date created: 2021-05-16* Last modified: 2021-05-16* Version: 1.11* Project: ForwardCom library libc_light.li* Description: puts: print a string to stdout. Does not append linefeed* This version is for CPUs with limited capabilities* C declaration: void print_integer(int32_t i);* C declaration: void print_unsigned(uint32_t i);** Copyright 2021 GNU General Public License http://www.gnu.org/licenses******************************************************************************/code section execute align = 4 // code section// Print a 32-bit signed integer as decimal number to stdout_print_integer function public reguse=3,0if (int32 r0 < 0) {int32 r0 = -r0int8+ r1 = '-'int8 output(r1, r1, 10) // print '-'}// continue in _print_unsigned// Print a 32-bit unsigned integer as decimal number to stdout_print_unsigned function public reguse=3,0// This function is using the double dabble algorithm for binary to BCD conversion.// This method is slow, but it is used here because it does not require division// or multiplication. This makes sure it will work on small cores without mul and div instructions.// save r2-r5int64 sp -= 4*8int64 [sp] = r2int64 [sp+8] = r3int64 [sp+0x10] = r4int64 [sp+0x18] = r5// First two BCD digits are made with simple subtraction to avoid the need for a larger bit fieldint r5 = 0while (uint32 r0 >= 1000000000) {uint32 r0 -= 1000000000uint32 r5 += 0x10}while (uint32 r0 >= 100000000) {uint32 r0 -= 100000000uint32 r5 += 0x01}uint32 r5 <<= 24// Generate 8 BCD digits using double dabble algorithmint32 r1 = 0for (int r2 = 0; r2 < 32; r2++) { // loop for 32 bitsint32 r3 = r1 + 0x33333333 // digit values 5-9 will set bit 3 in each 4-bit nibbleint32 r3 &= 0x88888888 // isolate bit 3 in each nibbleint32 r4 = r3 >> 3 // generate value 3 in nibbles with value 5-9int32 r3 >>= 2int32 r3 |= r4 // this will have 3 for each nibble with a value 5-9int32 r1 += r3 // add 3 to nibble values 5-9 to generate 8-12int32 r1 = funnel_shift(r0, r1, 31) // shift most significant bit of r0 into r1int32 r0 <<= 1}// r5:r1 = BCD valueint r4 = 0 // remember if first digit has been printedfor (int r2 = 2; r2 > 0; r2--) {int32 r5 = rotate(r5, 4) // get most significant digit firstint8 r3 = r5 & 0x0Fint r4 = (r3 != 0) || r4 // digit has been printedint8 r3 += '0'if (int r4 != 0) {int8 output(r3, r3, 10) // print character to stdout}}// print 8 decimal digitsfor (int r2 = 8; r2 > 0; r2--) {int32 r1 = rotate(r1, 4) // get most significant digit firstint8 r3 = r1 & 0x0Fint r4 = (r3 != 0) || r4 // digit has been printedint r4 = (r2 == 1) || r4 // last digit must be printedint8 r3 += '0'if (int r4 != 0) {int8 output(r3, r3, 10) // print character to stdout}}// restore r2-r5int64 r2 = [sp]int64 r3 = [sp+8]int64 r4 = [sp+0x10]int64 r5 = [sp+0x18]int64 sp += 4*8return_print_integer endcode end
