1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-30 09:57:11 +00:00

Added automatic type identification to numeric printf handler without %l / %hh.

This commit is contained in:
Jesper Gravgaard 2020-04-21 10:39:07 +02:00
parent 839911e0a0
commit bc70424634
7 changed files with 6118 additions and 3 deletions

View File

@ -8,6 +8,7 @@ import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementCall;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.values.*;
import java.util.Arrays;
@ -156,10 +157,20 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
}
if(lengthField == null) {
// Integer (16bit)
printf_number_procedure = signed ? PRINTF_SINT : PRINTF_UINT;
// Check if the parameter type is 8-bit or 32-bit
RValue paramValue = parameters.get(paramIdx);
SymbolType paramType = SymbolTypeInference.inferType(getScope(), paramValue);
if(SymbolType.BYTE.equals(paramType) || SymbolType.SBYTE.equals(paramType)) {
// Integer (8bit)
printf_number_procedure = signed ? PRINTF_SCHAR : PRINTF_UCHAR;
} else if(SymbolType.DWORD.equals(paramType) || SymbolType.SDWORD.equals(paramType)) {
// Integer (32bit)
printf_number_procedure = signed ? PRINTF_SLONG : PRINTF_ULONG;
} else {
// Integer (16bit)
printf_number_procedure = signed ? PRINTF_SINT : PRINTF_UINT;
}
} else if(lengthField.equals("hh")) {
// TODO: Handle 8-bits in a better way - since KickC does not do integer promotion!
// Integer (8bit)
printf_number_procedure = signed ? PRINTF_SCHAR : PRINTF_UCHAR;
} else if(lengthField.equals("l")) {

View File

@ -45,6 +45,11 @@ public class TestPrograms {
assertError("printf-error-1.c", "Needed printf sub-procedure not found");
}
@Test
public void testPrintf14() throws IOException, URISyntaxException {
compileAndCompare("printf-14.c");
}
@Test
public void testPrintf13() throws IOException, URISyntaxException {
compileAndCompare("printf-13.c");

13
src/test/kc/printf-14.c Normal file
View File

@ -0,0 +1,13 @@
// Tests printf function call rewriting
// Print a char using %d
#include <printf.h>
void main() {
printf_cls();
char c = 7;
printf("%hhu", c);
}

414
src/test/ref/printf-14.asm Normal file
View File

@ -0,0 +1,414 @@
// Tests printf function call rewriting
// Print a char using %d
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
.const OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
.label printf_screen = $400
.const SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
.label printf_line_cursor = 8
.label printf_char_cursor = $a
__bbegin:
// printf_line_cursor = PRINTF_SCREEN_ADDRESS
lda #<$400
sta.z printf_line_cursor
lda #>$400
sta.z printf_line_cursor+1
// printf_char_cursor = PRINTF_SCREEN_ADDRESS
lda #<$400
sta.z printf_char_cursor
lda #>$400
sta.z printf_char_cursor+1
jsr main
rts
main: {
.label c = 7
// printf_cls()
jsr printf_cls
// printf("%hhu", c)
lda #<str
sta.z printf_str.str
lda #>str
sta.z printf_str.str+1
jsr printf_str
// printf("%hhu", c)
jsr printf_uchar
// printf("%hhu", c)
lda #<str
sta.z printf_str.str
lda #>str
sta.z printf_str.str+1
jsr printf_str
// }
rts
str: .text ""
.byte 0
}
// Print a zero-terminated string
// Handles escape codes such as newline
// printf_str(byte* zp(6) str)
printf_str: {
.label str = 6
__b2:
// ch = *str++
ldy #0
lda (str),y
inc.z str
bne !+
inc.z str+1
!:
// if(ch==0)
cmp #0
bne __b3
// }
rts
__b3:
// if(ch=='\n')
cmp #'\n'
beq __b4
// printf_char(ch)
jsr printf_char
jmp __b2
__b4:
// printf_ln()
jsr printf_ln
jmp __b2
}
// Print a newline
printf_ln: {
__b1:
// printf_line_cursor += PRINTF_SCREEN_WIDTH
lda #$28
clc
adc.z printf_line_cursor
sta.z printf_line_cursor
bcc !+
inc.z printf_line_cursor+1
!:
// while (printf_line_cursor<printf_char_cursor)
lda.z printf_line_cursor+1
cmp.z printf_char_cursor+1
bcc __b1
bne !+
lda.z printf_line_cursor
cmp.z printf_char_cursor
bcc __b1
!:
// printf_char_cursor = printf_line_cursor
lda.z printf_line_cursor
sta.z printf_char_cursor
lda.z printf_line_cursor+1
sta.z printf_char_cursor+1
// }
rts
}
// Print a single char
// If the end of the screen is reached scroll it up one char and place the cursor at the
// printf_char(byte register(A) ch)
printf_char: {
.label __8 = $a
// *(printf_char_cursor++) = ch
ldy #0
sta (printf_char_cursor),y
// *(printf_char_cursor++) = ch;
inc.z printf_char_cursor
bne !+
inc.z printf_char_cursor+1
!:
// if(printf_char_cursor>=(printf_screen+PRINTF_SCREEN_BYTES))
lda.z printf_char_cursor+1
cmp #>printf_screen+$28*$19
bcc __breturn
bne !+
lda.z printf_char_cursor
cmp #<printf_screen+$28*$19
bcc __breturn
!:
// memcpy(printf_screen, printf_screen+PRINTF_SCREEN_WIDTH, PRINTF_SCREEN_BYTES-PRINTF_SCREEN_WIDTH)
jsr memcpy
// memset(printf_screen+PRINTF_SCREEN_BYTES-PRINTF_SCREEN_WIDTH, ' ', PRINTF_SCREEN_WIDTH)
ldx #' '
lda #<printf_screen+$28*$19-$28
sta.z memset.str
lda #>printf_screen+$28*$19-$28
sta.z memset.str+1
lda #<$28
sta.z memset.num
lda #>$28
sta.z memset.num+1
jsr memset
// printf_char_cursor-PRINTF_SCREEN_WIDTH
lda.z __8
sec
sbc #<$28
sta.z __8
lda.z __8+1
sbc #>$28
sta.z __8+1
// printf_char_cursor = printf_char_cursor-PRINTF_SCREEN_WIDTH
// printf_line_cursor = printf_char_cursor
lda.z printf_char_cursor
sta.z printf_line_cursor
lda.z printf_char_cursor+1
sta.z printf_line_cursor+1
__breturn:
// }
rts
}
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
// memset(void* zp(2) str, byte register(X) c, word zp(8) num)
memset: {
.label end = 8
.label dst = 2
.label num = 8
.label str = 2
// if(num>0)
lda.z num
bne !+
lda.z num+1
beq __breturn
!:
// end = (char*)str + num
lda.z end
clc
adc.z str
sta.z end
lda.z end+1
adc.z str+1
sta.z end+1
__b2:
// for(char* dst = str; dst!=end; dst++)
lda.z dst+1
cmp.z end+1
bne __b3
lda.z dst
cmp.z end
bne __b3
__breturn:
// }
rts
__b3:
// *dst = c
txa
ldy #0
sta (dst),y
// for(char* dst = str; dst!=end; dst++)
inc.z dst
bne !+
inc.z dst+1
!:
jmp __b2
}
// Copy block of memory (forwards)
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
memcpy: {
.label destination = printf_screen
.const num = $28*$19-$28
.label source = printf_screen+$28
.label src_end = source+num
.label dst = 2
.label src = 8
lda #<destination
sta.z dst
lda #>destination
sta.z dst+1
lda #<source
sta.z src
lda #>source
sta.z src+1
__b1:
// while(src!=src_end)
lda.z src+1
cmp #>src_end
bne __b2
lda.z src
cmp #<src_end
bne __b2
// }
rts
__b2:
// *dst++ = *src++
ldy #0
lda (src),y
sta (dst),y
// *dst++ = *src++;
inc.z dst
bne !+
inc.z dst+1
!:
inc.z src
bne !+
inc.z src+1
!:
jmp __b1
}
// Print an unsigned char using a specific format
printf_uchar: {
// printf_buffer.sign = format.sign_always?'+':0
// Handle any sign
lda #0
sta printf_buffer
// uctoa(uvalue, printf_buffer.digits, format.radix)
// Format number into buffer
jsr uctoa
// printf_number_buffer(printf_buffer, format)
lda printf_buffer
// Print using format
jsr printf_number_buffer
// }
rts
}
// Print the contents of the number buffer using a specific format.
// This handles minimum length, zero-filling, and left/right justification from the format
// printf_number_buffer(byte register(A) buffer_sign)
printf_number_buffer: {
.label buffer_digits = printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
// if(buffer.sign)
cmp #0
beq __b2
// printf_char(buffer.sign)
jsr printf_char
__b2:
// printf_str(buffer.digits)
lda #<buffer_digits
sta.z printf_str.str
lda #>buffer_digits
sta.z printf_str.str+1
jsr printf_str
// }
rts
}
// Converts unsigned number value to a string representing it in RADIX format.
// If the leading digits are zero they are not included in the string.
// - value : The number to be converted to RADIX
// - buffer : receives the string representing the number and zero-termination.
// - radix : The radix to convert the number to (from the enum RADIX)
// uctoa(byte register(X) value, byte* zp(6) buffer)
uctoa: {
.const max_digits = 3
.label digit_value = $c
.label buffer = 6
.label digit = 4
.label started = 5
lda #<printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
sta.z buffer
lda #>printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
sta.z buffer+1
lda #0
sta.z started
ldx #main.c
sta.z digit
__b1:
// for( char digit=0; digit<max_digits-1; digit++ )
lda.z digit
cmp #max_digits-1
bcc __b2
// *buffer++ = DIGITS[(char)value]
lda DIGITS,x
ldy #0
sta (buffer),y
// *buffer++ = DIGITS[(char)value];
inc.z buffer
bne !+
inc.z buffer+1
!:
// *buffer = 0
lda #0
tay
sta (buffer),y
// }
rts
__b2:
// digit_value = digit_values[digit]
ldy.z digit
lda RADIX_DECIMAL_VALUES_CHAR,y
sta.z digit_value
// if (started || value >= digit_value)
lda #0
cmp.z started
bne __b5
cpx.z digit_value
bcs __b5
__b4:
// for( char digit=0; digit<max_digits-1; digit++ )
inc.z digit
jmp __b1
__b5:
// uctoa_append(buffer++, value, digit_value)
jsr uctoa_append
// uctoa_append(buffer++, value, digit_value)
// value = uctoa_append(buffer++, value, digit_value)
// value = uctoa_append(buffer++, value, digit_value);
inc.z buffer
bne !+
inc.z buffer+1
!:
lda #1
sta.z started
jmp __b4
}
// Used to convert a single digit of an unsigned number value to a string representation
// Counts a single digit up from '0' as long as the value is larger than sub.
// Each time the digit is increased sub is subtracted from value.
// - buffer : pointer to the char that receives the digit
// - value : The value where the digit will be derived from
// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased.
// (For decimal the subs used are 10000, 1000, 100, 10, 1)
// returns : the value reduced by sub * digit so that it is less than sub.
// uctoa_append(byte* zp(6) buffer, byte register(X) value, byte zp($c) sub)
uctoa_append: {
.label buffer = 6
.label sub = $c
ldy #0
__b1:
// while (value >= sub)
cpx.z sub
bcs __b2
// *buffer = DIGITS[digit]
lda DIGITS,y
ldy #0
sta (buffer),y
// }
rts
__b2:
// digit++;
iny
// value -= sub
txa
sec
sbc.z sub
tax
jmp __b1
}
// Clear the screen. Also resets current line/char cursor.
printf_cls: {
// memset(printf_screen, ' ', PRINTF_SCREEN_BYTES)
ldx #' '
lda #<printf_screen
sta.z memset.str
lda #>printf_screen
sta.z memset.str+1
lda #<$28*$19
sta.z memset.num
lda #>$28*$19
sta.z memset.num+1
jsr memset
// printf_line_cursor = printf_screen
lda #<printf_screen
sta.z printf_line_cursor
lda #>printf_screen
sta.z printf_line_cursor+1
// printf_char_cursor = printf_line_cursor
lda.z printf_line_cursor
sta.z printf_char_cursor
lda.z printf_line_cursor+1
sta.z printf_char_cursor+1
// }
rts
}
// The digits used for numbers
DIGITS: .text "0123456789abcdef"
// Values of decimal digits
RADIX_DECIMAL_VALUES_CHAR: .byte $64, $a
// Buffer used for stringified number being printed
printf_buffer: .fill SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER, 0

254
src/test/ref/printf-14.cfg Normal file
View File

@ -0,0 +1,254 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] (byte*) printf_line_cursor ← (byte*) 1024
[2] (byte*) printf_char_cursor ← (byte*) 1024
to:@2
@2: scope:[] from @1
[3] phi()
[4] call main
to:@end
@end: scope:[] from @2
[5] phi()
(void()) main()
main: scope:[main] from @2
[6] phi()
[7] call printf_cls
to:main::@1
main::@1: scope:[main] from main
[8] phi()
[9] call printf_str
to:main::@2
main::@2: scope:[main] from main::@1
[10] phi()
[11] call printf_uchar
to:main::@3
main::@3: scope:[main] from main::@2
[12] phi()
[13] call printf_str
to:main::@return
main::@return: scope:[main] from main::@3
[14] return
to:@return
(void()) printf_str((byte*) printf_str::str)
printf_str: scope:[printf_str] from main::@1 main::@3 printf_number_buffer::@2
[15] (byte*) printf_str::str#6 ← phi( main::@1/(const byte*) main::str main::@3/(const byte*) main::str printf_number_buffer::@2/(const byte*) printf_number_buffer::buffer_digits#0 )
to:printf_str::@1
printf_str::@1: scope:[printf_str] from printf_str printf_str::@4 printf_str::@5
[16] (byte*) printf_str::str#4 ← phi( printf_str/(byte*) printf_str::str#6 printf_str::@4/(byte*) printf_str::str#0 printf_str::@5/(byte*) printf_str::str#0 )
to:printf_str::@2
printf_str::@2: scope:[printf_str] from printf_str::@1
[17] (byte) printf_str::ch#0 ← *((byte*) printf_str::str#4)
[18] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#4
[19] if((byte) printf_str::ch#0!=(byte) 0) goto printf_str::@3
to:printf_str::@return
printf_str::@return: scope:[printf_str] from printf_str::@2
[20] return
to:@return
printf_str::@3: scope:[printf_str] from printf_str::@2
[21] if((byte) printf_str::ch#0==(byte) '
') goto printf_str::@4
to:printf_str::@5
printf_str::@5: scope:[printf_str] from printf_str::@3
[22] (byte) printf_char::ch#1 ← (byte) printf_str::ch#0
[23] call printf_char
to:printf_str::@1
printf_str::@4: scope:[printf_str] from printf_str::@3
[24] phi()
[25] call printf_ln
to:printf_str::@1
(void()) printf_ln()
printf_ln: scope:[printf_ln] from printf_str::@4
[26] phi()
to:printf_ln::@1
printf_ln::@1: scope:[printf_ln] from printf_ln printf_ln::@1
[27] (byte*) printf_line_cursor ← (byte*) printf_line_cursor + (byte) $28
[28] if((byte*) printf_line_cursor<(byte*) printf_char_cursor) goto printf_ln::@1
to:printf_ln::@2
printf_ln::@2: scope:[printf_ln] from printf_ln::@1
[29] (byte*) printf_char_cursor ← (byte*) printf_line_cursor
to:printf_ln::@return
printf_ln::@return: scope:[printf_ln] from printf_ln::@2
[30] return
to:@return
(void()) printf_char((byte) printf_char::ch)
printf_char: scope:[printf_char] from printf_number_buffer::@3 printf_str::@5
[31] (byte) printf_char::ch#3 ← phi( printf_number_buffer::@3/(byte) printf_char::ch#2 printf_str::@5/(byte) printf_char::ch#1 )
[32] *((byte*) printf_char_cursor) ← (byte) printf_char::ch#3
[33] (byte*) printf_char_cursor ← ++ (byte*) printf_char_cursor
[34] if((byte*) printf_char_cursor<(const byte*) printf_screen+(word)(number) $28*(number) $19) goto printf_char::@return
to:printf_char::@1
printf_char::@1: scope:[printf_char] from printf_char
[35] phi()
[36] call memcpy
to:printf_char::@2
printf_char::@2: scope:[printf_char] from printf_char::@1
[37] phi()
[38] call memset
to:printf_char::@3
printf_char::@3: scope:[printf_char] from printf_char::@2
[39] (byte*~) printf_char::$8 ← (byte*) printf_char_cursor - (byte) $28
[40] (byte*) printf_char_cursor ← (byte*~) printf_char::$8
[41] (byte*) printf_line_cursor ← (byte*) printf_char_cursor
to:printf_char::@return
printf_char::@return: scope:[printf_char] from printf_char printf_char::@3
[42] return
to:@return
(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num)
memset: scope:[memset] from printf_char::@2 printf_cls
[43] (byte) memset::c#4 ← phi( printf_char::@2/(byte) ' ' printf_cls/(byte) ' ' )
[43] (void*) memset::str#3 ← phi( printf_char::@2/(void*)(const byte*) printf_screen+(word)(number) $28*(number) $19-(byte) $28 printf_cls/(void*)(const byte*) printf_screen )
[43] (word) memset::num#2 ← phi( printf_char::@2/(byte) $28 printf_cls/(word)(number) $28*(number) $19 )
[44] if((word) memset::num#2<=(byte) 0) goto memset::@return
to:memset::@1
memset::@1: scope:[memset] from memset
[45] (byte*) memset::end#0 ← (byte*)(void*) memset::str#3 + (word) memset::num#2
[46] (byte*) memset::dst#4 ← (byte*)(void*) memset::str#3
to:memset::@2
memset::@2: scope:[memset] from memset::@1 memset::@3
[47] (byte*) memset::dst#2 ← phi( memset::@1/(byte*) memset::dst#4 memset::@3/(byte*) memset::dst#1 )
[48] if((byte*) memset::dst#2!=(byte*) memset::end#0) goto memset::@3
to:memset::@return
memset::@return: scope:[memset] from memset memset::@2
[49] return
to:@return
memset::@3: scope:[memset] from memset::@2
[50] *((byte*) memset::dst#2) ← (byte) memset::c#4
[51] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#2
to:memset::@2
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
memcpy: scope:[memcpy] from printf_char::@1
[52] phi()
to:memcpy::@1
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
[53] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*)(const void*) memcpy::destination#0 memcpy::@2/(byte*) memcpy::dst#1 )
[53] (byte*) memcpy::src#2 ← phi( memcpy/(byte*)(const void*) memcpy::source#0 memcpy::@2/(byte*) memcpy::src#1 )
[54] if((byte*) memcpy::src#2!=(const byte*) memcpy::src_end#0) goto memcpy::@2
to:memcpy::@return
memcpy::@return: scope:[memcpy] from memcpy::@1
[55] return
to:@return
memcpy::@2: scope:[memcpy] from memcpy::@1
[56] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
[57] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
[58] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
to:memcpy::@1
(void()) printf_uchar((byte) printf_uchar::uvalue , (byte) printf_uchar::format_min_length , (byte) printf_uchar::format_justify_left , (byte) printf_uchar::format_sign_always , (byte) printf_uchar::format_zero_padding , (byte) printf_uchar::format_radix)
printf_uchar: scope:[printf_uchar] from main::@2
[59] phi()
to:printf_uchar::@1
printf_uchar::@1: scope:[printf_uchar] from printf_uchar
[60] *((byte*)&(struct printf_buffer_number) printf_buffer) ← (byte) 0
[61] call uctoa
to:printf_uchar::@2
printf_uchar::@2: scope:[printf_uchar] from printf_uchar::@1
[62] (byte) printf_number_buffer::buffer_sign#0 ← *((byte*)&(struct printf_buffer_number) printf_buffer)
[63] call printf_number_buffer
to:printf_uchar::@return
printf_uchar::@return: scope:[printf_uchar] from printf_uchar::@2
[64] return
to:@return
(void()) printf_number_buffer((byte) printf_number_buffer::buffer_sign , (byte*) printf_number_buffer::buffer_digits , (byte) printf_number_buffer::format_min_length , (byte) printf_number_buffer::format_justify_left , (byte) printf_number_buffer::format_sign_always , (byte) printf_number_buffer::format_zero_padding , (byte) printf_number_buffer::format_radix)
printf_number_buffer: scope:[printf_number_buffer] from printf_uchar::@2
[65] phi()
to:printf_number_buffer::@1
printf_number_buffer::@1: scope:[printf_number_buffer] from printf_number_buffer
[66] if((byte) 0==(byte) printf_number_buffer::buffer_sign#0) goto printf_number_buffer::@2
to:printf_number_buffer::@3
printf_number_buffer::@3: scope:[printf_number_buffer] from printf_number_buffer::@1
[67] (byte) printf_char::ch#2 ← (byte) printf_number_buffer::buffer_sign#0
[68] call printf_char
to:printf_number_buffer::@2
printf_number_buffer::@2: scope:[printf_number_buffer] from printf_number_buffer::@1 printf_number_buffer::@3
[69] phi()
[70] call printf_str
to:printf_number_buffer::@return
printf_number_buffer::@return: scope:[printf_number_buffer] from printf_number_buffer::@2
[71] return
to:@return
(void()) uctoa((byte) uctoa::value , (byte*) uctoa::buffer , (byte) uctoa::radix)
uctoa: scope:[uctoa] from printf_uchar::@1
[72] phi()
to:uctoa::@1
uctoa::@1: scope:[uctoa] from uctoa uctoa::@4
[73] (byte*) uctoa::buffer#11 ← phi( uctoa::@4/(byte*) uctoa::buffer#14 uctoa/(byte*)&(struct printf_buffer_number) printf_buffer+(const byte) OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
[73] (byte) uctoa::started#2 ← phi( uctoa::@4/(byte) uctoa::started#4 uctoa/(byte) 0 )
[73] (byte) uctoa::value#2 ← phi( uctoa::@4/(byte) uctoa::value#6 uctoa/(const byte) main::c )
[73] (byte) uctoa::digit#2 ← phi( uctoa::@4/(byte) uctoa::digit#1 uctoa/(byte) 0 )
[74] if((byte) uctoa::digit#2<(const byte) uctoa::max_digits#1-(byte) 1) goto uctoa::@2
to:uctoa::@3
uctoa::@3: scope:[uctoa] from uctoa::@1
[75] *((byte*) uctoa::buffer#11) ← *((const byte*) DIGITS + (byte) uctoa::value#2)
[76] (byte*) uctoa::buffer#3 ← ++ (byte*) uctoa::buffer#11
[77] *((byte*) uctoa::buffer#3) ← (byte) 0
to:uctoa::@return
uctoa::@return: scope:[uctoa] from uctoa::@3
[78] return
to:@return
uctoa::@2: scope:[uctoa] from uctoa::@1
[79] (byte) uctoa::digit_value#0 ← *((const byte*) RADIX_DECIMAL_VALUES_CHAR + (byte) uctoa::digit#2)
[80] if((byte) 0!=(byte) uctoa::started#2) goto uctoa::@5
to:uctoa::@7
uctoa::@7: scope:[uctoa] from uctoa::@2
[81] if((byte) uctoa::value#2>=(byte) uctoa::digit_value#0) goto uctoa::@5
to:uctoa::@4
uctoa::@4: scope:[uctoa] from uctoa::@6 uctoa::@7
[82] (byte*) uctoa::buffer#14 ← phi( uctoa::@7/(byte*) uctoa::buffer#11 uctoa::@6/(byte*) uctoa::buffer#4 )
[82] (byte) uctoa::started#4 ← phi( uctoa::@7/(byte) uctoa::started#2 uctoa::@6/(byte) 1 )
[82] (byte) uctoa::value#6 ← phi( uctoa::@7/(byte) uctoa::value#2 uctoa::@6/(byte) uctoa::value#0 )
[83] (byte) uctoa::digit#1 ← ++ (byte) uctoa::digit#2
to:uctoa::@1
uctoa::@5: scope:[uctoa] from uctoa::@2 uctoa::@7
[84] (byte*) uctoa_append::buffer#0 ← (byte*) uctoa::buffer#11
[85] (byte) uctoa_append::value#0 ← (byte) uctoa::value#2
[86] (byte) uctoa_append::sub#0 ← (byte) uctoa::digit_value#0
[87] call uctoa_append
[88] (byte) uctoa_append::return#0 ← (byte) uctoa_append::value#2
to:uctoa::@6
uctoa::@6: scope:[uctoa] from uctoa::@5
[89] (byte) uctoa::value#0 ← (byte) uctoa_append::return#0
[90] (byte*) uctoa::buffer#4 ← ++ (byte*) uctoa::buffer#11
to:uctoa::@4
(byte()) uctoa_append((byte*) uctoa_append::buffer , (byte) uctoa_append::value , (byte) uctoa_append::sub)
uctoa_append: scope:[uctoa_append] from uctoa::@5
[91] phi()
to:uctoa_append::@1
uctoa_append::@1: scope:[uctoa_append] from uctoa_append uctoa_append::@2
[92] (byte) uctoa_append::digit#2 ← phi( uctoa_append/(byte) 0 uctoa_append::@2/(byte) uctoa_append::digit#1 )
[92] (byte) uctoa_append::value#2 ← phi( uctoa_append/(byte) uctoa_append::value#0 uctoa_append::@2/(byte) uctoa_append::value#1 )
[93] if((byte) uctoa_append::value#2>=(byte) uctoa_append::sub#0) goto uctoa_append::@2
to:uctoa_append::@3
uctoa_append::@3: scope:[uctoa_append] from uctoa_append::@1
[94] *((byte*) uctoa_append::buffer#0) ← *((const byte*) DIGITS + (byte) uctoa_append::digit#2)
to:uctoa_append::@return
uctoa_append::@return: scope:[uctoa_append] from uctoa_append::@3
[95] return
to:@return
uctoa_append::@2: scope:[uctoa_append] from uctoa_append::@1
[96] (byte) uctoa_append::digit#1 ← ++ (byte) uctoa_append::digit#2
[97] (byte) uctoa_append::value#1 ← (byte) uctoa_append::value#2 - (byte) uctoa_append::sub#0
to:uctoa_append::@1
(void()) printf_cls()
printf_cls: scope:[printf_cls] from main
[98] phi()
[99] call memset
to:printf_cls::@1
printf_cls::@1: scope:[printf_cls] from printf_cls
[100] (byte*) printf_line_cursor ← (const byte*) printf_screen
[101] (byte*) printf_char_cursor ← (byte*) printf_line_cursor
to:printf_cls::@return
printf_cls::@return: scope:[printf_cls] from printf_cls::@1
[102] return
to:@return

5225
src/test/ref/printf-14.log Normal file

File diff suppressed because it is too large Load Diff

193
src/test/ref/printf-14.sym Normal file
View File

@ -0,0 +1,193 @@
(label) @1
(label) @2
(label) @begin
(label) @end
(const byte*) DIGITS[] = (byte*) "0123456789abcdef"z
(const byte) OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = (byte) 1
(const byte) RADIX::BINARY = (number) 2
(const byte) RADIX::DECIMAL = (number) $a
(const byte) RADIX::HEXADECIMAL = (number) $10
(const byte) RADIX::OCTAL = (number) 8
(const byte*) RADIX_DECIMAL_VALUES_CHAR[] = { (byte) $64, (byte) $a }
(const byte) SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = (byte) $c
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(const byte) main::c = (byte) 7
(const byte*) main::str[(byte) 1] = (byte*) ""
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
(label) memcpy::@1
(label) memcpy::@2
(label) memcpy::@return
(void*) memcpy::destination
(const void*) memcpy::destination#0 destination = (void*)(const byte*) printf_screen
(byte*) memcpy::dst
(byte*) memcpy::dst#1 dst zp[2]:2 1.000000001E9
(byte*) memcpy::dst#2 dst zp[2]:2 1.000000001E9
(word) memcpy::num
(const word) memcpy::num#0 num = (word)(number) $28*(number) $19-(number) $28
(void*) memcpy::return
(void*) memcpy::source
(const void*) memcpy::source#0 source = (void*)(const byte*) printf_screen+(byte) $28
(byte*) memcpy::src
(byte*) memcpy::src#1 src zp[2]:8 2.000000002E9
(byte*) memcpy::src#2 src zp[2]:8 1.000000001E9
(byte*) memcpy::src_end
(const byte*) memcpy::src_end#0 src_end = (byte*)(const void*) memcpy::source#0+(const word) memcpy::num#0
(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num)
(label) memset::@1
(label) memset::@2
(label) memset::@3
(label) memset::@return
(byte) memset::c
(byte) memset::c#4 reg byte x 1.25000000125E8
(byte*) memset::dst
(byte*) memset::dst#1 dst zp[2]:2 2.000000002E9
(byte*) memset::dst#2 dst zp[2]:2 1.3366666683333335E9
(byte*) memset::dst#4 dst zp[2]:2 2.0000002E7
(byte*) memset::end
(byte*) memset::end#0 end zp[2]:8 1.683333336666667E8
(word) memset::num
(word) memset::num#2 num zp[2]:8 1.0000001E7
(void*) memset::return
(void*) memset::str
(void*) memset::str#3 str zp[2]:2
(struct printf_buffer_number) printf_buffer loadstore mem[12] = {}
(const byte*) printf_buffer_number::digits[(number) $b] = { fill( $b, 0) }
(byte) printf_buffer_number::sign
(void()) printf_char((byte) printf_char::ch)
(byte*~) printf_char::$8 zp[2]:10 2000002.0
(label) printf_char::@1
(label) printf_char::@2
(label) printf_char::@3
(label) printf_char::@return
(byte) printf_char::ch
(byte) printf_char::ch#1 reg byte a 200002.0
(byte) printf_char::ch#2 reg byte a 2002.0
(byte) printf_char::ch#3 reg byte a 1101003.0
(byte*) printf_char_cursor loadstore zp[2]:10 2250002.333333332
(void()) printf_cls()
(label) printf_cls::@1
(label) printf_cls::@return
(byte) printf_format_number::justify_left
(byte) printf_format_number::min_length
(byte) printf_format_number::radix
(byte) printf_format_number::sign_always
(byte) printf_format_number::zero_padding
(byte) printf_format_string::justify_left
(byte) printf_format_string::min_length
(byte*) printf_line_cursor loadstore zp[2]:8 6863641.113636365
(void()) printf_ln()
(label) printf_ln::@1
(label) printf_ln::@2
(label) printf_ln::@return
(void()) printf_number_buffer((byte) printf_number_buffer::buffer_sign , (byte*) printf_number_buffer::buffer_digits , (byte) printf_number_buffer::format_min_length , (byte) printf_number_buffer::format_justify_left , (byte) printf_number_buffer::format_sign_always , (byte) printf_number_buffer::format_zero_padding , (byte) printf_number_buffer::format_radix)
(label) printf_number_buffer::@1
(label) printf_number_buffer::@2
(label) printf_number_buffer::@3
(label) printf_number_buffer::@return
(struct printf_buffer_number) printf_number_buffer::buffer
(byte*) printf_number_buffer::buffer_digits
(const byte*) printf_number_buffer::buffer_digits#0 buffer_digits = (byte*)&(struct printf_buffer_number) printf_buffer+(const byte) OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
(byte) printf_number_buffer::buffer_sign
(byte) printf_number_buffer::buffer_sign#0 reg byte a 701.0
(struct printf_format_number) printf_number_buffer::format
(byte) printf_number_buffer::format_justify_left
(byte) printf_number_buffer::format_min_length
(byte) printf_number_buffer::format_radix
(byte) printf_number_buffer::format_sign_always
(byte) printf_number_buffer::format_zero_padding
(signed byte) printf_number_buffer::len
(signed byte) printf_number_buffer::padding
(const byte*) printf_screen = (byte*) 1024
(void()) printf_str((byte*) printf_str::str)
(label) printf_str::@1
(label) printf_str::@2
(label) printf_str::@3
(label) printf_str::@4
(label) printf_str::@5
(label) printf_str::@return
(byte) printf_str::ch
(byte) printf_str::ch#0 reg byte a 100001.0
(byte*) printf_str::str
(byte*) printf_str::str#0 str zp[2]:6 42857.57142857143
(byte*) printf_str::str#4 str zp[2]:6 205002.5
(byte*) printf_str::str#6 str zp[2]:6 10001.0
(void()) printf_uchar((byte) printf_uchar::uvalue , (byte) printf_uchar::format_min_length , (byte) printf_uchar::format_justify_left , (byte) printf_uchar::format_sign_always , (byte) printf_uchar::format_zero_padding , (byte) printf_uchar::format_radix)
(label) printf_uchar::@1
(label) printf_uchar::@2
(label) printf_uchar::@return
(struct printf_format_number) printf_uchar::format
(byte) printf_uchar::format_justify_left
(byte) printf_uchar::format_min_length
(byte) printf_uchar::format_radix
(byte) printf_uchar::format_sign_always
(byte) printf_uchar::format_zero_padding
(byte) printf_uchar::uvalue
(void()) uctoa((byte) uctoa::value , (byte*) uctoa::buffer , (byte) uctoa::radix)
(label) uctoa::@1
(label) uctoa::@2
(label) uctoa::@3
(label) uctoa::@4
(label) uctoa::@5
(label) uctoa::@6
(label) uctoa::@7
(label) uctoa::@return
(byte*) uctoa::buffer
(byte*) uctoa::buffer#11 buffer zp[2]:6 3500.4999999999995
(byte*) uctoa::buffer#14 buffer zp[2]:6 15001.5
(byte*) uctoa::buffer#3 buffer zp[2]:6 2002.0
(byte*) uctoa::buffer#4 buffer zp[2]:6 20002.0
(byte) uctoa::digit
(byte) uctoa::digit#1 digit zp[1]:4 20002.0
(byte) uctoa::digit#2 digit zp[1]:4 3077.230769230769
(byte) uctoa::digit_value
(byte) uctoa::digit_value#0 digit_value zp[1]:12 6000.6
(byte*) uctoa::digit_values
(byte) uctoa::max_digits
(const byte) uctoa::max_digits#1 max_digits = (byte) 3
(byte) uctoa::radix
(byte) uctoa::started
(byte) uctoa::started#2 started zp[1]:5 6000.6
(byte) uctoa::started#4 started zp[1]:5 10001.0
(byte) uctoa::value
(byte) uctoa::value#0 reg byte x 10001.0
(byte) uctoa::value#2 reg byte x 6834.166666666666
(byte) uctoa::value#6 reg byte x 15001.5
(byte()) uctoa_append((byte*) uctoa_append::buffer , (byte) uctoa_append::value , (byte) uctoa_append::sub)
(label) uctoa_append::@1
(label) uctoa_append::@2
(label) uctoa_append::@3
(label) uctoa_append::@return
(byte*) uctoa_append::buffer
(byte*) uctoa_append::buffer#0 buffer zp[2]:6 13750.25
(byte) uctoa_append::digit
(byte) uctoa_append::digit#1 reg byte y 1.0000001E7
(byte) uctoa_append::digit#2 reg byte y 1.00500015E7
(byte) uctoa_append::return
(byte) uctoa_append::return#0 reg byte x 20002.0
(byte) uctoa_append::sub
(byte) uctoa_append::sub#0 sub zp[1]:12 3335000.5
(byte) uctoa_append::value
(byte) uctoa_append::value#0 reg byte x 36667.33333333333
(byte) uctoa_append::value#1 reg byte x 2.0000002E7
(byte) uctoa_append::value#2 reg byte x 5018334.166666666
reg byte a [ printf_char::ch#3 printf_char::ch#2 printf_char::ch#1 ]
reg byte x [ memset::c#4 ]
zp[2]:2 [ memcpy::dst#2 memcpy::dst#1 memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 ]
zp[1]:4 [ uctoa::digit#2 uctoa::digit#1 ]
reg byte x [ uctoa::value#2 uctoa::value#6 uctoa::value#0 ]
zp[1]:5 [ uctoa::started#2 uctoa::started#4 ]
zp[2]:6 [ uctoa::buffer#11 uctoa::buffer#14 uctoa::buffer#4 uctoa::buffer#3 uctoa_append::buffer#0 printf_str::str#4 printf_str::str#6 printf_str::str#0 ]
reg byte x [ uctoa_append::value#2 uctoa_append::value#0 uctoa_append::value#1 ]
reg byte y [ uctoa_append::digit#2 uctoa_append::digit#1 ]
zp[2]:8 [ printf_line_cursor memcpy::src#2 memcpy::src#1 memset::num#2 memset::end#0 ]
zp[2]:10 [ printf_char_cursor printf_char::$8 ]
reg byte a [ printf_str::ch#0 ]
reg byte a [ printf_number_buffer::buffer_sign#0 ]
zp[1]:12 [ uctoa::digit_value#0 uctoa_append::sub#0 ]
reg byte x [ uctoa_append::return#0 ]
mem[12] [ printf_buffer ]