1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-13 19:37:19 +00:00

Added support for snprintf(). Closes #698

This commit is contained in:
jespergravgaard 2021-08-13 20:06:59 +02:00
parent 72471bbcd0
commit ea760e4731
43 changed files with 19483 additions and 9176 deletions

View File

@ -1168,6 +1168,18 @@ stz {c1}
lda {c1}
inc
sta {z1}
//FRAGMENT vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
sta {z1}
//FRAGMENT pbuz1_derefidx_vbuz2=vbuz3
lda {z3}
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuc1
lda #{c1}
ldz {z2}
sta ({z1}),z
//FRAGMENT vwuz1=_word_vbuz2
lda {z2}
sta {z1}
@ -1216,17 +1228,6 @@ lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT 0_neq_vbuz1_then_la1
lda {z1}
bne {la1}
//FRAGMENT pbuz1_derefidx_vbuz2=vbuz3
lda {z3}
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuc1
lda #{c1}
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1=pbuz1_plus_vbuc1
lda #{c1}
clc
@ -1235,6 +1236,16 @@ sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT 0_neq_vbuz1_then_la1
lda {z1}
bne {la1}
//FRAGMENT _stackpushbyte_=vbuz1
lda {z1}
pha
//FRAGMENT call_vprc1
jsr {c1}
//FRAGMENT _stackpullbyte_1
pla
//FRAGMENT pvoz1=pvoc1
lda #<{c1}
sta {z1}
@ -1286,6 +1297,36 @@ inc
//FRAGMENT vbuxx=_deref_pbuc1_plus_1
ldx {c1}
inx
//FRAGMENT vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
//FRAGMENT vbuxx=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tax
//FRAGMENT vbuyy=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tay
//FRAGMENT vbuzz=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
taz
//FRAGMENT pbuz1_derefidx_vbuz2=vbuaa
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuxx
txa
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuyy
tya
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuzz
tza
ldz {z2}
sta ({z1}),z
//FRAGMENT vbuz1=vbuxx
stx {z1}
//FRAGMENT vwuz1=_word_vbuxx
@ -1306,23 +1347,8 @@ sta {z1}+1
//FRAGMENT 0_neq_vbuaa_then_la1
cmp #0
bne {la1}
//FRAGMENT vbuz1=vbuaa
sta {z1}
//FRAGMENT pbuz1_derefidx_vbuz2=vbuaa
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuxx
txa
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuyy
tya
ldz {z2}
sta ({z1}),z
//FRAGMENT pbuz1_derefidx_vbuz2=vbuzz
tza
ldz {z2}
sta ({z1}),z
//FRAGMENT _stackpushbyte_=vbuaa
pha
//FRAGMENT _deref_pbuz1=vbuxx
txa
ldy #0
@ -1338,18 +1364,21 @@ sta ({z1}),y
//FRAGMENT 0_neq_vbuxx_then_la1
cpx #0
bne {la1}
//FRAGMENT vbuaa=vbuxx
//FRAGMENT _stackpushbyte_=vbuxx
txa
pha
//FRAGMENT 0_neq_vbuyy_then_la1
cpy #0
bne {la1}
//FRAGMENT vbuaa=vbuyy
//FRAGMENT _stackpushbyte_=vbuyy
tya
pha
//FRAGMENT 0_neq_vbuzz_then_la1
cpz #0
bne {la1}
//FRAGMENT vbuaa=vbuzz
//FRAGMENT _stackpushbyte_=vbuzz
tza
pha
//FRAGMENT vbuz1=vbuyy
sty {z1}
//FRAGMENT vbuz1=vbuzz
@ -2363,6 +2392,8 @@ taz
lda {z1}+1
//FRAGMENT vbuxx=_byte1_vduz1
ldx {z1}+1
//FRAGMENT vbuz1=vbuaa
sta {z1}
//FRAGMENT vbuyy=_byte1_vduz1
ldy {z1}+1
//FRAGMENT vbuzz=_byte1_vduz1
@ -2457,40 +2488,3 @@ sta {z1}+3
NO_SYNTHESIS
//FRAGMENT vduz1=vwsc1
NO_SYNTHESIS
//FRAGMENT vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
sta {z1}
//FRAGMENT _stackpushbyte_=vbuz1
lda {z1}
pha
//FRAGMENT call_vprc1
jsr {c1}
//FRAGMENT _stackpullbyte_1
pla
//FRAGMENT vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
//FRAGMENT vbuxx=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tax
//FRAGMENT vbuyy=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tay
//FRAGMENT vbuzz=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
taz
//FRAGMENT _stackpushbyte_=vbuaa
pha
//FRAGMENT _stackpushbyte_=vbuxx
txa
pha
//FRAGMENT _stackpushbyte_=vbuyy
tya
pha
//FRAGMENT _stackpushbyte_=vbuzz
tza
pha

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
lda {m1}+1
cmp {m2}+1
bne !+
lda {m1}
cmp {m2}
beq {la1}
lda {m2}+1
cmp {m1}+1
bcc !+
bne {la1}
lda {m2}
cmp {m1}
bcs {la1}
!:
bcc {la1}

View File

@ -45,6 +45,7 @@ public class Procedure extends Scope {
/** The names of all legal intrinsic procedures. */
final public static List<String> INTRINSIC_PROCEDURES = Arrays.asList(
Pass1PrintfIntrinsicRewrite.INTRINSIC_PRINTF_NAME,
Pass1PrintfIntrinsicRewrite.INTRINSIC_SNPRINTF_NAME,
Pass1ByteXIntrinsicRewrite.INTRINSIC_MAKELONG4
);

View File

@ -10,7 +10,6 @@ import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypeProcedure;
import dk.camelot64.kickc.model.values.*;
import java.util.Arrays;
@ -27,9 +26,17 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
/** The printf procedure name. */
public static final String INTRINSIC_PRINTF_NAME = "printf";
/** The printf procedure name. */
public static final String INTRINSIC_SNPRINTF_NAME = "snprintf";
/** The printf routine used to print a raw char */
private static final String CPUTC = "cputc";
/** The snprintf routine used to print a raw char */
private static final String SNPUTC = "snputc";
/** The printf routine used to print a raw string */
private static final String SNPRINTF_INIT = "snprintf_init";
/** The printf routine used to print a raw string */
private static final String PRINTF_STR = "printf_str";
/** The printf routine used to print formatted strings. */
@ -61,205 +68,229 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
@Override
public boolean step() {
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
final ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementCall && ((StatementCall) statement).getProcedureName().equals(INTRINSIC_PRINTF_NAME)) {
StatementCall printfCall = (StatementCall) statement;
final List<RValue> parameters = printfCall.getParameters();
final RValue formatParameter = getParameterValue(parameters, 0, printfCall);
if(!(formatParameter instanceof ConstantValue))
throw new CompileError("Only constant printf() format parameter supported!", statement);
final ConstantLiteral formatLiteral = ((ConstantValue) formatParameter).calculateLiteral(getProgram().getScope());
if(!(formatLiteral instanceof ConstantString))
throw new CompileError("printf() format parameter must be a string!", statement);
final String formatString = ((ConstantString) formatLiteral).getString();
final StringEncoding formatEncoding = ((ConstantString) formatLiteral).getEncoding();
Symbol cputcSymbol = getScope().getGlobalSymbol(CPUTC);
ConstantValue CPUTC_REF;
if(cputcSymbol!=null)
CPUTC_REF = new ConstantSymbolPointer(cputcSymbol.getRef());
else
CPUTC_REF = new ConstantPointer(0L, new SymbolTypeProcedure(SymbolType.VOID, Arrays.asList(SymbolType.BYTE)));
// Remove the call to printf()
stmtIt.remove();
// Printf Placeholder Format String - source: https://en.wikipedia.org/wiki/Printf_format_string
// "%" start
// ([1-9][0-9]* "$")? parameter (gives the # of the parameter to use)
// [-+ 0'#]* flags (different flags affecting the formatting "-": left-align, "0": zero-prepend, "+": always sign)
// [1-9][0-9]* width (the minimum number of characters)
// ("hh" | "l" )? length (specifies the type of integer "hh": char "": int, "l": long)
// [%diuxXoscp] type (specifies the type of the parameter/output "d"/"i" decimal signed, "u": decimal unsigned, "x": hexadecimal unsigned (lowercase), "X": hexadecimal unsigned (uppercase), "o": octal unsigned, "s": string, "c": character, "p": pointer, "%": output "%" )
Pattern pattern = Pattern.compile("%([1-9][0-9]*[$])?([-+0#]*)([1-9][0-9]*)?(hh|l)?([%diuxXoscp])");
final Matcher matcher = pattern.matcher(formatString);
// The index for the format field within the string
int formatIdx = 0;
// The index of the parameter being used as value for formatting. Incremented automatically unless field parameter index syntax (eg. %2$d) is used.
int paramIdx = 1;
// True if field parameter index syntax (eg. %2$d) is used.
boolean fieldParamIdx = false;
while(true) {
// Find the next pattern match!
boolean found = matcher.find();
if(!found) {
// No more matching patterns
break;
}
final int start = matcher.start();
final int end = matcher.end();
final String typeField = matcher.group(5);
final String paramField = matcher.group(1);
// Ensure that all fields use parameter index syntax!
if(paramField == null && fieldParamIdx && !typeField.equals("%"))
throw new CompileError("If any single printf() placeholder specifies a parameter, all the rest of the placeholders must also specify a parameter!", statement);
if(paramField != null) {
if(!fieldParamIdx && paramIdx > 1)
throw new CompileError("If any single printf() placeholder specifies a parameter, all the rest of the placeholders must also specify a parameter!", statement);
fieldParamIdx = true;
paramIdx = Integer.parseInt(paramField.substring(0, paramField.length() - 1));
}
final String flagsField = matcher.group(2);
long leftJustify = (flagsField != null && flagsField.contains("-")) ? 1 : 0;
long signAlways = (flagsField != null && flagsField.contains("+")) ? 1 : 0;
long zeroPadding = (flagsField != null && flagsField.contains("0")) ? 1 : 0;
final String widthField = matcher.group(3);
long width = (widthField == null) ? 0 : Integer.parseInt(widthField);
final String lengthField = matcher.group(4);
long upperCase = 0L;
// First output the non-matching part before the pattern
String prefix = formatString.substring(formatIdx, start);
if(prefix.length() > 0) {
addPrintfCall(PRINTF_STR, Arrays.asList(CPUTC_REF, new ConstantString(prefix, formatEncoding, true)), stmtIt, printfCall);
}
formatIdx = end;
if(typeField.equals("%")) {
addPrintfCall(CPUTC, Arrays.asList(new ConstantChar('%', formatEncoding)), stmtIt, printfCall);
} else if(typeField.equals("s")) {
// A formatted string
//struct printf_format_string {
// char min_length; // The minimal number of chars to output (used for padding with spaces or 0).
// char justify_left; // Justify left instead of right, which is the default.
//};
final ValueList format_string_struct =
new ValueList(Arrays.asList(
new ConstantInteger(width, SymbolType.BYTE),
new ConstantInteger(leftJustify, SymbolType.BYTE)
));
addPrintfCall(PRINTF_STRING, Arrays.asList(CPUTC_REF, getParameterValue(parameters, paramIdx, printfCall), format_string_struct), stmtIt, printfCall);
paramIdx++;
} else if("diuxXo".contains(typeField)) {
// A formatted integer
SymbolVariableRef radix;
String printf_number_procedure;
boolean signed;
switch(typeField) {
case "d":
case "i":
radix = getScope().getLocalConstant(DECIMAL).getRef();
signed = true;
break;
case "u":
radix = getScope().getLocalConstant(DECIMAL).getRef();
signed = false;
break;
case "x":
radix = getScope().getLocalConstant(HEXADECIMAL).getRef();
signed = false;
break;
case "X":
radix = getScope().getLocalConstant(HEXADECIMAL).getRef();
signed = false;
upperCase = 1l;
break;
case "o":
radix = getScope().getLocalConstant(OCTAL).getRef();
signed = false;
break;
default:
throw new CompileError("printf type field not supported", printfCall);
}
if(lengthField == null) {
// Check if the parameter type is 8-bit or 32-bit
RValue paramValue = getParameterValue(parameters, paramIdx, printfCall);
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")) {
// Integer (8bit)
printf_number_procedure = signed ? PRINTF_SCHAR : PRINTF_UCHAR;
} else if(lengthField.equals("l")) {
// Integer (32bit)
printf_number_procedure = signed ? PRINTF_SLONG : PRINTF_ULONG;
} else {
throw new CompileError("printf length field not supported", printfCall);
}
// Format specifying how to format a printed number
// struct printf_format_number {
// char min_length; // The minimal number of chars to output (used for padding with spaces or 0)
// char justify_left; // Justify left instead of right, which is the default.
// char sign_always; // Always show a sign for a number, even if is is positive. (Default is to only show sign for negative numbers)
// char zero_padding; // Pad the number with zeros to get the min width
// char upper_case; // Upper-case the letters in the number
// enum RADIX radix; // The number radix to use for formatting
// };
final ValueList format_number_struct =
new ValueList(Arrays.asList(
new ConstantInteger(width, SymbolType.BYTE),
new ConstantInteger(leftJustify, SymbolType.BYTE),
new ConstantInteger(signAlways, SymbolType.BYTE),
new ConstantInteger(zeroPadding, SymbolType.BYTE),
new ConstantInteger(upperCase, SymbolType.BYTE),
radix
));
addPrintfCall(printf_number_procedure, Arrays.asList(CPUTC_REF, getParameterValue(parameters, paramIdx, printfCall), format_number_struct), stmtIt, printfCall);
paramIdx++;
} else if(typeField.equals("c")) {
// Print char
addPrintfCall(CPUTC, Arrays.asList(getParameterValue(parameters, paramIdx, printfCall)), stmtIt, printfCall);
paramIdx++;
} else if(typeField.equals("p")) {
// Print a pointer
final ValueList format_number_struct =
new ValueList(Arrays.asList(
new ConstantInteger(width, SymbolType.BYTE),
new ConstantInteger(leftJustify, SymbolType.BYTE),
new ConstantInteger(signAlways, SymbolType.BYTE),
new ConstantInteger(zeroPadding, SymbolType.BYTE),
new ConstantInteger(upperCase, SymbolType.BYTE),
getScope().getLocalConstant(HEXADECIMAL).getRef()
));
addPrintfCall(PRINTF_UINT, Arrays.asList(CPUTC_REF, new CastValue(SymbolType.WORD, getParameterValue(parameters, paramIdx, printfCall)), format_number_struct), stmtIt, printfCall);
paramIdx++;
}
if(statement instanceof StatementCall) {
if(((StatementCall) statement).getProcedureName().equals(INTRINSIC_PRINTF_NAME)) {
StatementCall call = (StatementCall) statement;
stmtIt.remove();
List<RValue> callParameters = call.getParameters();
final RValue format = getParameterValue(callParameters, 0, call);
List<RValue> formatParameters = callParameters.subList(1, callParameters.size());
addPrintfFormatStatements(stmtIt, call, format, formatParameters, CPUTC);
} else if(((StatementCall) statement).getProcedureName().equals(INTRINSIC_SNPRINTF_NAME)) {
StatementCall call = (StatementCall) statement;
stmtIt.remove();
List<RValue> callParameters = call.getParameters();
final RValue buffer = getParameterValue(callParameters, 0, call);
final RValue capacity = getParameterValue(callParameters, 1, call);
final RValue format = getParameterValue(callParameters, 2, call);
List<RValue> formatParameters = callParameters.subList(3, callParameters.size());
addPrintfCall(SNPRINTF_INIT, Arrays.asList(buffer, capacity), stmtIt, call);
addPrintfFormatStatements(stmtIt, call, format, formatParameters, SNPUTC);
addPrintfCall(SNPUTC, Arrays.asList(new ConstantInteger(0L, SymbolType.BYTE)), stmtIt, call);
}
// Grab the rest
String suffix = formatString.substring(formatIdx);
if(suffix.length() > 0)
addPrintfCall(PRINTF_STR, Arrays.asList(CPUTC_REF, new ConstantString(suffix, formatEncoding, true)), stmtIt, printfCall);
}
}
}
return false;
}
/**
* Add statements to the program printing the formatted string specified
* @param stmtIt Iterator used to add statements
* @param printfCall The original printf() statement
* @param format The format string (must be constant)
* @param parameters The parameters to the printf function (only the ... parameters)
* @param putcName The name of the function to use to output a single character
*/
private StringEncoding addPrintfFormatStatements(ListIterator<Statement> stmtIt, StatementCall printfCall, RValue format, List<RValue> parameters, String putcName) {
if(!(format instanceof ConstantValue))
throw new CompileError("Only constant printf() format parameter supported!", printfCall);
final ConstantLiteral formatLiteral = ((ConstantValue) format).calculateLiteral(getProgram().getScope());
if(!(formatLiteral instanceof ConstantString))
throw new CompileError("printf() format parameter must be a string!", printfCall);
final String formatString = ((ConstantString) formatLiteral).getString();
final StringEncoding formatEncoding = ((ConstantString) formatLiteral).getEncoding();
Symbol putcSymbol = getScope().getGlobalSymbol(putcName);
if(putcSymbol==null)
throw new CompileError("Needed printf sub-procedure not found " + putcName + "().", ((Statement) printfCall).getSource());
ConstantValue putcRef = new ConstantSymbolPointer(putcSymbol.getRef());
// Printf Placeholder Format String - source: https://en.wikipedia.org/wiki/Printf_format_string
// "%" start
// ([1-9][0-9]* "$")? parameter (gives the # of the parameter to use)
// [-+ 0'#]* flags (different flags affecting the formatting "-": left-align, "0": zero-prepend, "+": always sign)
// [1-9][0-9]* width (the minimum number of characters)
// ("hh" | "l" )? length (specifies the type of integer "hh": char "": int, "l": long)
// [%diuxXoscp] type (specifies the type of the parameter/output "d"/"i" decimal signed, "u": decimal unsigned, "x": hexadecimal unsigned (lowercase), "X": hexadecimal unsigned (uppercase), "o": octal unsigned, "s": string, "c": character, "p": pointer, "%": output "%" )
Pattern pattern = Pattern.compile("%([1-9][0-9]*[$])?([-+0#]*)([1-9][0-9]*)?(hh|l)?([%diuxXoscp])");
final Matcher matcher = pattern.matcher(formatString);
// The index for the format field within the string
int formatIdx = 0;
// The index of the parameter being used as value for formatting. Incremented automatically unless field parameter index syntax (eg. %2$d) is used.
int paramIdx = 0;
// True if field parameter index syntax (eg. %2$d) is used.
boolean fieldParamIdx = false;
while(true) {
// Find the next pattern match!
boolean found = matcher.find();
if(!found) {
// No more matching patterns
break;
}
final int start = matcher.start();
final int end = matcher.end();
final String typeField = matcher.group(5);
final String paramField = matcher.group(1);
// Ensure that all fields use parameter index syntax!
if(paramField == null && fieldParamIdx && !typeField.equals("%"))
throw new CompileError("If any single printf() placeholder specifies a parameter, all the rest of the placeholders must also specify a parameter!", printfCall);
if(paramField != null) {
if(!fieldParamIdx && paramIdx > 0)
throw new CompileError("If any single printf() placeholder specifies a parameter, all the rest of the placeholders must also specify a parameter!", printfCall);
fieldParamIdx = true;
paramIdx = Integer.parseInt(paramField.substring(0, paramField.length() - 1))-1;
}
final String flagsField = matcher.group(2);
long leftJustify = (flagsField != null && flagsField.contains("-")) ? 1 : 0;
long signAlways = (flagsField != null && flagsField.contains("+")) ? 1 : 0;
long zeroPadding = (flagsField != null && flagsField.contains("0")) ? 1 : 0;
final String widthField = matcher.group(3);
long width = (widthField == null) ? 0 : Integer.parseInt(widthField);
final String lengthField = matcher.group(4);
long upperCase = 0L;
// First output the non-matching part before the pattern
String prefix = formatString.substring(formatIdx, start);
if(prefix.length() > 0) {
addPrintfCall(PRINTF_STR, Arrays.asList(putcRef, new ConstantString(prefix, formatEncoding, true)), stmtIt, printfCall);
}
formatIdx = end;
if(typeField.equals("%")) {
addPrintfCall(putcName, Arrays.asList(new ConstantChar('%', formatEncoding)), stmtIt, printfCall);
} else if(typeField.equals("s")) {
// A formatted string
//struct printf_format_string {
// char min_length; // The minimal number of chars to output (used for padding with spaces or 0).
// char justify_left; // Justify left instead of right, which is the default.
//};
final ValueList format_string_struct =
new ValueList(Arrays.asList(
new ConstantInteger(width, SymbolType.BYTE),
new ConstantInteger(leftJustify, SymbolType.BYTE)
));
addPrintfCall(PRINTF_STRING, Arrays.asList(putcRef, getParameterValue(parameters, paramIdx, printfCall), format_string_struct), stmtIt, printfCall);
paramIdx++;
} else if("diuxXo".contains(typeField)) {
// A formatted integer
SymbolVariableRef radix;
String printf_number_procedure;
boolean signed;
switch(typeField) {
case "d":
case "i":
radix = getScope().getLocalConstant(DECIMAL).getRef();
signed = true;
break;
case "u":
radix = getScope().getLocalConstant(DECIMAL).getRef();
signed = false;
break;
case "x":
radix = getScope().getLocalConstant(HEXADECIMAL).getRef();
signed = false;
break;
case "X":
radix = getScope().getLocalConstant(HEXADECIMAL).getRef();
signed = false;
upperCase = 1l;
break;
case "o":
radix = getScope().getLocalConstant(OCTAL).getRef();
signed = false;
break;
default:
throw new CompileError("printf type field not supported", printfCall);
}
if(lengthField == null) {
// Check if the parameter type is 8-bit or 32-bit
RValue paramValue = getParameterValue(parameters, paramIdx, printfCall);
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")) {
// Integer (8bit)
printf_number_procedure = signed ? PRINTF_SCHAR : PRINTF_UCHAR;
} else if(lengthField.equals("l")) {
// Integer (32bit)
printf_number_procedure = signed ? PRINTF_SLONG : PRINTF_ULONG;
} else {
throw new CompileError("printf length field not supported", printfCall);
}
// Format specifying how to format a printed number
// struct printf_format_number {
// char min_length; // The minimal number of chars to output (used for padding with spaces or 0)
// char justify_left; // Justify left instead of right, which is the default.
// char sign_always; // Always show a sign for a number, even if is is positive. (Default is to only show sign for negative numbers)
// char zero_padding; // Pad the number with zeros to get the min width
// char upper_case; // Upper-case the letters in the number
// enum RADIX radix; // The number radix to use for formatting
// };
final ValueList format_number_struct =
new ValueList(Arrays.asList(
new ConstantInteger(width, SymbolType.BYTE),
new ConstantInteger(leftJustify, SymbolType.BYTE),
new ConstantInteger(signAlways, SymbolType.BYTE),
new ConstantInteger(zeroPadding, SymbolType.BYTE),
new ConstantInteger(upperCase, SymbolType.BYTE),
radix
));
addPrintfCall(printf_number_procedure, Arrays.asList(putcRef, getParameterValue(parameters, paramIdx, printfCall), format_number_struct), stmtIt, printfCall);
paramIdx++;
} else if(typeField.equals("c")) {
// Print char
addPrintfCall(putcName, Arrays.asList(getParameterValue(parameters, paramIdx, printfCall)), stmtIt, printfCall);
paramIdx++;
} else if(typeField.equals("p")) {
// Print a pointer
final ValueList format_number_struct =
new ValueList(Arrays.asList(
new ConstantInteger(width, SymbolType.BYTE),
new ConstantInteger(leftJustify, SymbolType.BYTE),
new ConstantInteger(signAlways, SymbolType.BYTE),
new ConstantInteger(zeroPadding, SymbolType.BYTE),
new ConstantInteger(upperCase, SymbolType.BYTE),
getScope().getLocalConstant(HEXADECIMAL).getRef()
));
addPrintfCall(PRINTF_UINT, Arrays.asList(putcRef, new CastValue(SymbolType.WORD, getParameterValue(parameters, paramIdx, printfCall)), format_number_struct), stmtIt, printfCall);
paramIdx++;
}
}
// Grab the rest
String suffix = formatString.substring(formatIdx);
if(suffix.length() > 0)
addPrintfCall(PRINTF_STR, Arrays.asList(putcRef, new ConstantString(suffix, formatEncoding, true)), stmtIt, printfCall);
return formatEncoding;
}
/**
* Get a specific parameter value.
* @param parameters The list of parameters
@ -271,7 +302,7 @@ public class Pass1PrintfIntrinsicRewrite extends Pass2SsaOptimization {
*/
private RValue getParameterValue(List<RValue> parameters, int paramIdx, StatementCall printfCall) {
if(parameters.size()<=paramIdx)
throw new CompileError("printf missing parameter with index "+paramIdx, printfCall);
throw new CompileError("printf missing parameter with index "+(paramIdx+1), printfCall);
return parameters.get(paramIdx);
}

View File

@ -0,0 +1,26 @@
#include <stddef.h>
#include <printf.h>
/// Composes a string with the same text that would be printed if format was used on printf(),
/// but instead of being printed, the content is stored as a C string in the buffer pointed by s
/// (taking n as the maximum buffer capacity to fill).
/// @param s Pointer to a buffer where the resulting C-string is stored. The buffer should have a size of at least n characters.
/// @param n Maximum number of bytes to be used in the buffer. The generated string has a length of at most n-1, leaving space for the additional terminating null character.
/// @param format C string that contains a format string that follows the same specifications as format in printf (see printf for details).
/// @param ... Depending on the format string, the function may expect a sequence of additional arguments, each containing a value to be used to replace a format specifier in the format string (or a pointer to a storage location, for n).
/// There should be at least as many of these arguments as the number of values specified in the format specifiers. Additional arguments are ignored by the function.
/// @return The number of characters that would have been written if n had been sufficiently large, not counting the terminating null character.
/// Notice that only when this returned value is non-negative and less than n, the string has been completely written.
int snprintf ( char * s, size_t n, const char * format, ... );
/// Initialize the snprintf() state
/// @param s Pointer to a buffer where the resulting C-string is stored. The buffer should have a size of at least n characters.
/// @param n Maximum number of bytes to be used in the buffer. The generated string has a length of at most n-1, leaving space for the additional terminating null character.
void snprintf_init(char * s, size_t n);
/// Print a character into snprintf buffer
/// Used by snprintf()
/// @param c The character to print
void snputc(char c);

View File

@ -0,0 +1,46 @@
/// Implementation of snprintf
/// Composes a string with the same text that would be printed if format was used on printf(),
/// but instead of being printed, the content is stored as a C string in the buffer pointed by s
/// (taking n as the maximum buffer capacity to fill).
/// @param s Pointer to a buffer where the resulting C-string is stored. The buffer should have a size of at least n characters.
/// @param n Maximum number of bytes to be used in the buffer. The generated string has a length of at most n-1, leaving space for the additional terminating null character.
/// @param format C string that contains a format string that follows the same specifications as format in printf (see printf for details).
/// @param ... Depending on the format string, the function may expect a sequence of additional arguments, each containing a value to be used to replace a format specifier in the format string (or a pointer to a storage location, for n).
/// There should be at least as many of these arguments as the number of values specified in the format specifiers. Additional arguments are ignored by the function.
/// @return The number of characters that would have been written if n had been sufficiently large, not counting the terminating null character.
/// Notice that only when this returned value is non-negative and less than n, the string has been completely written.
__intrinsic int snprintf ( char * s, size_t n, const char * format, ... );
/// The capacity of the buffer (n passed to snprintf())
/// Used to hold state while printing
volatile size_t __snprintf_capacity;
// The number of chars that would have been filled when printing without capacity. Grows even after size>capacity.
/// Used to hold state while printing
volatile size_t __snprintf_size;
/// Current position in the buffer being filled ( initially *s passed to snprintf()
/// Used to hold state while printing
char * __snprintf_buffer;
/// Initialize the snprintf() state
void snprintf_init(char * s, size_t n) {
__snprintf_capacity = n;
__snprintf_size = 0;
__snprintf_buffer = s;
}
/// Print a character into snprintf buffer
/// Used by snprintf()
/// @param c The character to print
void snputc(char c) {
// Increment size
++__snprintf_size;
// If buffer full - do nothing
if(__snprintf_size > __snprintf_capacity)
return;
// If capacity reached append '\0'
if(__snprintf_size==__snprintf_capacity)
c = 0;
// Append char
*(__snprintf_buffer++) = c;
}

View File

@ -879,6 +879,11 @@ public class TestProgramsFast extends TestPrograms {
assertError("printf-error-1.c", "Needed printf sub-procedure not found");
}
@Test
public void testPrintf17() throws IOException {
compileAndCompare("printf-17.c");
}
@Test
public void testPrintf15() throws IOException {
compileAndCompare("printf-15.c");
@ -889,6 +894,11 @@ public class TestProgramsFast extends TestPrograms {
compileAndCompare("printf-14.c");
}
@Test
public void testPrintf12() throws IOException {
compileAndCompare("printf-12.c");
}
@Test
public void testPrintf11() throws IOException {
compileAndCompare("printf-11.c");

View File

@ -12,6 +12,8 @@ void printf_str(void (*putc)(char), char* str) {
}
}
void cputc(char x) {}
// Format specifying how to format a printed string
struct printf_format_string {
// The minimal number of chars to output (used for padding with spaces or 0).

View File

@ -42,6 +42,9 @@ void printf_uint(void (*putc)(char), unsigned int uvalue, struct printf_format_n
*screen++ = printf_hextab[BYTE0(uvalue)&0xf];
}
void cputc(char x) {}
void main() {
unsigned int pct = 342;
printf("Commodore is %x cool", pct);

31
src/test/kc/printf-17.c Normal file
View File

@ -0,0 +1,31 @@
// Tests snprintf function call rewriting
// Test simple formats
#include <snprintf.h>
char BUF[20];
char * screen = (char*)0x0400;
void print(char* msg) {
while(*msg)
*(screen++) = *(msg++);
}
void main() {
// String - no format
snprintf(BUF, 20, "hello world! ");
print(BUF);
// String & char format
snprintf(BUF, 20, "hello %s%c ", "world", '!');
print(BUF);
// Number format
snprintf(BUF, 20, "hello %d+%x! ", 3,11);
print(BUF);
// Shortened
snprintf(BUF, 6, "hi %d! ", 22222);
print(BUF);
}

View File

@ -293,13 +293,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// if(dy<e)
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// x += sx
clc
lda.z x
@ -368,13 +369,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// if(dx < e)
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// y += sy
clc
lda.z y

View File

@ -2743,14 +2743,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// [70] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
lda.z e+1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7_from___b16
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7_from___b16
lda.z dy
cmp.z e
bcs __b7_from___b16
!:
bcc __b7_from___b16
jmp __b8
// bitmap_line::@8
__b8:
@ -2868,14 +2868,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// [87] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
lda.z e1+1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10_from___b17
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10_from___b17
lda.z dx
cmp.z e1
bcs __b10_from___b17
!:
bcc __b10_from___b17
jmp __b11
// bitmap_line::@11
__b11:
@ -3150,8 +3150,6 @@ Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda.z e+1
Removing instruction lda.z e1+1
Removing instruction lda #>-1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __b6_from___b1 with __b2
@ -3433,7 +3431,7 @@ reg byte x [ bitmap_plot::$2 ]
FINAL ASSEMBLER
Score: 30070
Score: 30670
// File Comments
// Illustrates problem with bitmap-draw.kc line()
@ -3880,13 +3878,14 @@ bitmap_line: {
sta.z e+1
// if(dy<e)
// [70] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// bitmap_line::@8
// x += sx
// [71] bitmap_line::x#1 = bitmap_line::x#13 + bitmap_line::sx#0 -- vwuz1=vwuz1_plus_vwuz2
@ -3996,13 +3995,14 @@ bitmap_line: {
sta.z e1+1
// if(dx < e)
// [87] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// bitmap_line::@11
// y += sy
// [88] bitmap_line::y#2 = bitmap_line::y#15 + bitmap_line::sy#0 -- vwuz1=vwuz1_plus_vwuz2

View File

@ -274,13 +274,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// if(dy<e)
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// x += sx
clc
lda.z x
@ -349,13 +350,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// if(dx < e)
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// y += sy
clc
lda.z y

View File

@ -2686,14 +2686,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// [65] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
lda.z e+1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7_from___b16
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7_from___b16
lda.z dy
cmp.z e
bcs __b7_from___b16
!:
bcc __b7_from___b16
jmp __b8
// bitmap_line::@8
__b8:
@ -2811,14 +2811,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// [82] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
lda.z e1+1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10_from___b17
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10_from___b17
lda.z dx
cmp.z e1
bcs __b10_from___b17
!:
bcc __b10_from___b17
jmp __b11
// bitmap_line::@11
__b11:
@ -3094,8 +3094,6 @@ Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda #>0
Removing instruction lda #>0
Removing instruction lda.z e+1
Removing instruction lda.z e1+1
Removing instruction lda #>-1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __b5_from___b4 with __b2
@ -3381,7 +3379,7 @@ reg byte x [ bitmap_plot::$2 ]
FINAL ASSEMBLER
Score: 29778
Score: 30378
// File Comments
// Shows that c64-bitmap.kc line() does not have the same problem as bitmap-draw.kc
@ -3801,13 +3799,14 @@ bitmap_line: {
sta.z e+1
// if(dy<e)
// [65] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// bitmap_line::@8
// x += sx
// [66] bitmap_line::x#1 = bitmap_line::x#13 + bitmap_line::sx#0 -- vwuz1=vwuz1_plus_vwuz2
@ -3917,13 +3916,14 @@ bitmap_line: {
sta.z e1+1
// if(dx < e)
// [82] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// bitmap_line::@11
// y += sy
// [83] bitmap_line::y#2 = bitmap_line::y#15 + bitmap_line::sy#0 -- vwuz1=vwuz1_plus_vwuz2

View File

@ -312,13 +312,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// if(dy<e)
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// x += sx
clc
lda.z x
@ -379,13 +380,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// if(dx < e)
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// y += sy
clc
lda.z y

View File

@ -2961,14 +2961,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// [72] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
lda.z e+1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7_from___b16
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7_from___b16
lda.z dy
cmp.z e
bcs __b7_from___b16
!:
bcc __b7_from___b16
jmp __b8
// bitmap_line::@8
__b8:
@ -3073,14 +3073,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// [89] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
lda.z e1+1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10_from___b17
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10_from___b17
lda.z dx
cmp.z e1
bcs __b10_from___b17
!:
bcc __b10_from___b17
jmp __b11
// bitmap_line::@11
__b11:
@ -3354,8 +3354,6 @@ Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction ldy.z a
Removing instruction lda.z e+1
Removing instruction lda.z e1+1
Removing instruction lda #>-1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __b6_from___b1 with __b2
@ -3647,7 +3645,7 @@ reg byte x [ bitmap_plot::$2 ]
FINAL ASSEMBLER
Score: 26875
Score: 27475
// File Comments
// Tests the simple bitmap plotter
@ -4109,13 +4107,14 @@ bitmap_line: {
sta.z e+1
// if(dy<e)
// [72] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// bitmap_line::@8
// x += sx
// [73] bitmap_line::x#1 = bitmap_line::x#13 + bitmap_line::sx#0 -- vwuz1=vwuz1_plus_vwuz2
@ -4213,13 +4212,14 @@ bitmap_line: {
sta.z e1+1
// if(dx < e)
// [89] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// bitmap_line::@11
// y += sy
// [90] bitmap_line::y#2 = bitmap_line::y#15 + bitmap_line::sy#0 -- vwuz1=vwuz1_plus_vwuz2

View File

@ -570,13 +570,14 @@ utoa: {
// if (started || value >= digit_value)
cpx #0
bne __b5
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
__b4:
// for( char digit=0; digit<max_digits-1; digit++ )
inc.z digit
@ -637,14 +638,14 @@ utoa_append: {
ldx #0
__b1:
// while (value >= sub)
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// *buffer = DIGITS[digit]
lda DIGITS,x
ldy #0

View File

@ -4605,14 +4605,14 @@ utoa: {
// utoa::@7
__b7:
// [137] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
lda.z digit_value+1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [138] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
__b4_from___b7:
// [138] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
@ -4728,14 +4728,14 @@ utoa_append: {
// utoa_append::@1
__b1:
// [157] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
jmp __b3
// utoa_append::@3
__b3:
@ -4938,8 +4938,6 @@ Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b2
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda.z digit_value+1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b3:
Succesful ASM optimization Pass5UnusedLabelElimination
@ -5149,7 +5147,7 @@ mem[12] [ printf_buffer ]
FINAL ASSEMBLER
Score: 74644
Score: 74944
// File Comments
// Demonstrates problem with Casting of negative signed values
@ -5970,13 +5968,14 @@ utoa: {
bne __b5
// utoa::@7
// [137] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [138] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
// [138] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
// [138] phi utoa::started#4 = utoa::started#2 [phi:utoa::@7->utoa::@4#1] -- register_copy
@ -6083,14 +6082,14 @@ utoa_append: {
__b1:
// while (value >= sub)
// [157] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// utoa_append::@3
// *buffer = DIGITS[digit]
// [158] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2] -- _deref_pbuz1=pbuc1_derefidx_vbuxx

View File

@ -372,13 +372,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// if(dy<e)
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// x += sx
clc
lda.z x
@ -439,13 +440,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// if(dx < e)
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// y += sy
clc
lda.z y

View File

@ -2899,14 +2899,14 @@ bitmap_line: {
adc.z dx+1
sta.z e+1
// [89] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
lda.z e+1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7_from___b16
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7_from___b16
lda.z dy
cmp.z e
bcs __b7_from___b16
!:
bcc __b7_from___b16
jmp __b8
// bitmap_line::@8
__b8:
@ -3011,14 +3011,14 @@ bitmap_line: {
adc.z dy+1
sta.z e1+1
// [106] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
lda.z e1+1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10_from___b17
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10_from___b17
lda.z dx
cmp.z e1
bcs __b10_from___b17
!:
bcc __b10_from___b17
jmp __b11
// bitmap_line::@11
__b11:
@ -3236,8 +3236,6 @@ Removing instruction lda #0
Removing instruction ldy.z l
Removing instruction ldy.z l
Removing instruction ldy.z l
Removing instruction lda.z e+1
Removing instruction lda.z e1+1
Removing instruction lda #>-1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __b1_from___b1 with __b1
@ -3530,7 +3528,7 @@ reg byte x [ bitmap_plot::$2 ]
FINAL ASSEMBLER
Score: 246362
Score: 252362
// File Comments
/// @file
@ -4080,13 +4078,14 @@ bitmap_line: {
sta.z e+1
// if(dy<e)
// [89] if(bitmap_line::dy#0>=bitmap_line::e#1) goto bitmap_line::@7 -- vwuz1_ge_vwuz2_then_la1
cmp.z dy+1
bne !+
lda.z e
cmp.z dy
beq __b7
lda.z dy+1
cmp.z e+1
bcc !+
bne __b7
lda.z dy
cmp.z e
bcs __b7
!:
bcc __b7
// bitmap_line::@8
// x += sx
// [90] bitmap_line::x#1 = bitmap_line::x#13 + bitmap_line::sx#0 -- vwuz1=vwuz1_plus_vwuz2
@ -4184,13 +4183,14 @@ bitmap_line: {
sta.z e1+1
// if(dx < e)
// [106] if(bitmap_line::dx#0>=bitmap_line::e1#1) goto bitmap_line::@10 -- vwuz1_ge_vwuz2_then_la1
cmp.z dx+1
bne !+
lda.z e1
cmp.z dx
beq __b10
lda.z dx+1
cmp.z e1+1
bcc !+
bne __b10
lda.z dx
cmp.z e1
bcs __b10
!:
bcc __b10
// bitmap_line::@11
// y += sy
// [107] bitmap_line::y#2 = bitmap_line::y#15 + bitmap_line::sy#0 -- vwuz1=vwuz1_plus_vwuz2

View File

@ -256,13 +256,14 @@ utoa: {
// if (started || value >= digit_value)
cpx #0
bne __b5
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
__b4:
// for( char digit=0; digit<max_digits-1; digit++ )
inc.z digit
@ -348,14 +349,14 @@ utoa_append: {
ldx #0
__b1:
// while (value >= sub)
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// *buffer = DIGITS[digit]
lda DIGITS,x
ldy #0

View File

@ -2475,14 +2475,14 @@ utoa: {
// utoa::@7
__b7:
// [69] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
lda.z digit_value+1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [70] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
__b4_from___b7:
// [70] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
@ -2642,14 +2642,14 @@ utoa_append: {
// utoa_append::@1
__b1:
// [96] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
jmp __b3
// utoa_append::@3
__b3:
@ -2828,8 +2828,6 @@ Relabelling long label __b2_from___b1 to __b3
Succesful ASM optimization Pass5RelabelLongLabels
Removing instruction jmp __b2
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda.z digit_value+1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
FINAL SYMBOL TABLE
__constant char DIGITS[] = "0123456789abcdef"z
@ -2971,7 +2969,7 @@ reg byte x [ print_uchar::$2 ]
FINAL ASSEMBLER
Score: 99334
Score: 99634
// File Comments
/// @file
@ -3375,13 +3373,14 @@ utoa: {
bne __b5
// utoa::@7
// [69] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [70] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
// [70] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
// [70] phi utoa::started#4 = utoa::started#2 [phi:utoa::@7->utoa::@4#1] -- register_copy
@ -3533,14 +3532,14 @@ utoa_append: {
__b1:
// while (value >= sub)
// [96] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// utoa_append::@3
// *buffer = DIGITS[digit]
// [97] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2] -- _deref_pbuz1=pbuc1_derefidx_vbuxx

View File

@ -59,14 +59,14 @@ main: {
tax
jsr mul8u
// if(potential > mul8u(p, p))
lda.z potential+1
cmp.z __0+1
bne !+
lda.z potential
cmp.z __0
beq __b2
lda.z __0+1
cmp.z potential+1
bcc !+
bne __b2
lda.z __0
cmp.z potential
bcs __b2
!:
bcc __b2
// test_last++;
inc.z test_last
__b2:
@ -348,13 +348,14 @@ utoa: {
// if (started || value >= digit_value)
cpx #0
bne __b5
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
__b4:
// for( char digit=0; digit<max_digits-1; digit++ )
inc.z digit
@ -417,14 +418,14 @@ utoa_append: {
ldx #0
__b1:
// while (value >= sub)
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// *buffer = DIGITS[digit]
lda DIGITS,x
ldy #0

View File

@ -2578,14 +2578,14 @@ main: {
__b8:
// [9] main::$0 = mul8u::return#2
// [10] if(potential#15<=main::$0) goto main::@2 -- vwuz1_le_vwuz2_then_la1
lda.z potential+1
cmp.z __0+1
bne !+
lda.z potential
cmp.z __0
beq __b2_from___b8
lda.z __0+1
cmp.z potential+1
bcc !+
bne __b2_from___b8
lda.z __0
cmp.z potential
bcs __b2_from___b8
!:
bcc __b2_from___b8
jmp __b7
// main::@7
__b7:
@ -3055,14 +3055,14 @@ utoa: {
// utoa::@7
__b7:
// [89] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
lda.z digit_value+1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [90] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
__b4_from___b7:
// [90] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
@ -3181,14 +3181,14 @@ utoa_append: {
// utoa_append::@1
__b1:
// [108] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
jmp __b3
// utoa_append::@3
__b3:
@ -3357,7 +3357,6 @@ Removing instruction jmp __b4
Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #<0
Removing instruction lda.z digit_value+1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Fixing long branch [126] bcc __b1 to bcs
Fixing long branch [132] bcc __b1 to bcs
@ -3544,7 +3543,7 @@ zp[2]:19 [ utoa::digit_value#0 utoa_append::sub#0 ]
FINAL ASSEMBLER
Score: 139370
Score: 139670
// File Comments
// Calculates the 1000 first primes
@ -3633,14 +3632,14 @@ main: {
// [9] main::$0 = mul8u::return#2
// if(potential > mul8u(p, p))
// [10] if(potential#15<=main::$0) goto main::@2 -- vwuz1_le_vwuz2_then_la1
lda.z potential+1
cmp.z __0+1
bne !+
lda.z potential
cmp.z __0
beq __b2
lda.z __0+1
cmp.z potential+1
bcc !+
bne __b2
lda.z __0
cmp.z potential
bcs __b2
!:
bcc __b2
// main::@7
// test_last++;
// [11] test_last#1 = ++ test_last#13 -- vbuz1=_inc_vbuz1
@ -4083,13 +4082,14 @@ utoa: {
bne __b5
// utoa::@7
// [89] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [90] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
// [90] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
// [90] phi utoa::started#4 = utoa::started#2 [phi:utoa::@7->utoa::@4#1] -- register_copy
@ -4201,14 +4201,14 @@ utoa_append: {
__b1:
// while (value >= sub)
// [108] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// utoa_append::@3
// *buffer = DIGITS[digit]
// [109] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2] -- _deref_pbuz1=pbuc1_derefidx_vbuxx

View File

@ -8,6 +8,7 @@
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const STACK_BASE = $103
.label screen = 2
.segment Code
main: {

View File

@ -1,6 +1,11 @@
Added struct type cast to parameter value list call printf_string((void (*)(char)) 0, main::name, (struct printf_format_string){ 0, 0 })
Setting inferred __stackcall on procedure affected by address-of __stackcall void cputc(char x) caused by statement call printf_str(&cputc, "Hello, I am ")
Setting inferred __stackcall on procedure affected by address-of __stackcall void cputc(char x) caused by statement call printf_string(&cputc, main::name, { 0, 0 })
Setting inferred __stackcall on procedure affected by address-of __stackcall void cputc(char x) caused by statement call printf_str(&cputc, ". who are you?")
Adding parameter assignment in __stackcall procedure cputc::x = param(cputc::x)
Added struct type cast to parameter value list call printf_string(&cputc, main::name, (struct printf_format_string){ 0, 0 })
Inlined call call __init
Eliminating unused variable with no statement main::$0
Calling convention STACK_CALL replacing param(cputc::x) with stackidx(char,cputc::OFFSET_STACK_X)
CONTROL FLOW GRAPH SSA
@ -28,6 +33,14 @@ printf_str::@return: scope:[printf_str] from printf_str::@1
return
to:@return
__stackcall void cputc(char x)
cputc: scope:[cputc] from
cputc::x#0 = stackidx(char,cputc::OFFSET_STACK_X)
to:cputc::@return
cputc::@return: scope:[cputc] from cputc
return
to:@return
void printf_string(void (*putc)(char) , char *str , char format_min_length , char format_justify_left)
printf_string: scope:[printf_string] from main::@1
screen#22 = phi( main::@1/screen#4 )
@ -50,14 +63,14 @@ printf_string::@return: scope:[printf_string] from printf_string::@1
void main()
main: scope:[main] from __start::@1
screen#23 = phi( __start::@1/screen#24 )
printf_str::putc#1 = (void (*)(char)) 0
printf_str::putc#1 = &cputc
printf_str::str#2 = main::str
call printf_str
to:main::@1
main::@1: scope:[main] from main
screen#15 = phi( main/screen#1 )
screen#4 = screen#15
printf_string::putc#0 = (void (*)(char)) 0
printf_string::putc#0 = &cputc
printf_string::str#0 = main::name
printf_string::format_min_length#0 = 0
printf_string::format_justify_left#0 = 0
@ -66,7 +79,7 @@ main::@1: scope:[main] from main
main::@2: scope:[main] from main::@1
screen#16 = phi( main::@1/screen#3 )
screen#5 = screen#16
printf_str::putc#2 = (void (*)(char)) 0
printf_str::putc#2 = &cputc
printf_str::str#3 = main::str1
call printf_str
to:main::@3
@ -101,7 +114,12 @@ __start::@return: scope:[__start] from __start::@2
to:@return
SYMBOL TABLE SSA
__constant unsigned int STACK_BASE = $103
void __start()
__stackcall void cputc(char x)
__constant char cputc::OFFSET_STACK_X = 0
char cputc::x
char cputc::x#0
void main()
__constant char *main::name = "Jesper"
__constant char main::str[$d] = "Hello, I am "
@ -188,27 +206,33 @@ Identical Phi Values screen#10 screen#17
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition printf_str::$0 [3] if(0!=*printf_str::str#4) goto printf_str::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant printf_str::putc#1 = (void (*)(char)) 0
Constant printf_str::putc#1 = &cputc
Constant printf_str::str#2 = main::str
Constant printf_string::putc#0 = (void (*)(char)) 0
Constant printf_string::putc#0 = &cputc
Constant printf_string::str#0 = main::name
Constant printf_string::format_min_length#0 = 0
Constant printf_string::format_justify_left#0 = 0
Constant printf_str::putc#2 = (void (*)(char)) 0
Constant printf_str::putc#2 = &cputc
Constant printf_str::str#3 = main::str1
Constant screen#24 = (char *) 1024
Successful SSA optimization Pass2ConstantIdentification
Constant printf_str::putc#0 = printf_string::putc#0
Constant printf_str::str#1 = printf_string::str#0
Successful SSA optimization Pass2ConstantIdentification
Eliminating unused variable cputc::x#0 and assignment [7] cputc::x#0 = stackidx(char,cputc::OFFSET_STACK_X)
Eliminating unused constant printf_str::putc#1
Eliminating unused constant printf_str::putc#2
Eliminating unused constant printf_str::putc#0
Eliminating unused constant printf_string::format_min_length#0
Eliminating unused constant printf_string::format_justify_left#0
Successful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant cputc::OFFSET_STACK_X
Eliminating unused constant printf_string::putc#0
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure cputc
Removing unused procedure block cputc
Removing unused procedure block cputc::@return
Successful SSA optimization PassNEliminateEmptyProcedure
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::__init1
@ -357,6 +381,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const STACK_BASE = $103
.label screen = 2
.segment Code
// main
@ -505,6 +530,7 @@ Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant unsigned int STACK_BASE = $103
void main()
__constant char *main::name = "Jesper"
__constant char main::str[$d] = "Hello, I am "
@ -546,6 +572,7 @@ Score: 617
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const STACK_BASE = $103
.label screen = 2
.segment Code
// main

View File

@ -1,3 +1,4 @@
__constant unsigned int STACK_BASE = $103
void main()
__constant char *main::name = "Jesper"
__constant char main::str[$d] = "Hello, I am "

View File

@ -8,6 +8,7 @@
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const STACK_BASE = $103
.label screen = 4
.segment Code
main: {

View File

@ -1,6 +1,11 @@
Added struct type cast to parameter value list call printf_uint((void (*)(char)) 0, main::pct, (struct printf_format_number){ 0, 0, 0, 0, 0, HEXADECIMAL })
Setting inferred __stackcall on procedure affected by address-of __stackcall void cputc(char x) caused by statement call printf_str(&cputc, "Commodore is ")
Setting inferred __stackcall on procedure affected by address-of __stackcall void cputc(char x) caused by statement call printf_uint(&cputc, main::pct, { 0, 0, 0, 0, 0, HEXADECIMAL })
Setting inferred __stackcall on procedure affected by address-of __stackcall void cputc(char x) caused by statement call printf_str(&cputc, " cool")
Adding parameter assignment in __stackcall procedure cputc::x = param(cputc::x)
Added struct type cast to parameter value list call printf_uint(&cputc, main::pct, (struct printf_format_number){ 0, 0, 0, 0, 0, HEXADECIMAL })
Inlined call call __init
Eliminating unused variable with no statement main::$0
Calling convention STACK_CALL replacing param(cputc::x) with stackidx(char,cputc::OFFSET_STACK_X)
CONTROL FLOW GRAPH SSA
@ -55,17 +60,25 @@ printf_uint::@return: scope:[printf_uint] from printf_uint
return
to:@return
__stackcall void cputc(char x)
cputc: scope:[cputc] from
cputc::x#0 = stackidx(char,cputc::OFFSET_STACK_X)
to:cputc::@return
cputc::@return: scope:[cputc] from cputc
return
to:@return
void main()
main: scope:[main] from __start::@1
screen#25 = phi( __start::@1/screen#26 )
printf_str::putc#0 = (void (*)(char)) 0
printf_str::putc#0 = &cputc
printf_str::str#1 = main::str
call printf_str
to:main::@1
main::@1: scope:[main] from main
screen#18 = phi( main/screen#1 )
screen#7 = screen#18
printf_uint::putc#0 = (void (*)(char)) 0
printf_uint::putc#0 = &cputc
printf_uint::uvalue#0 = main::pct
printf_uint::format_min_length#0 = 0
printf_uint::format_justify_left#0 = 0
@ -78,7 +91,7 @@ main::@1: scope:[main] from main
main::@2: scope:[main] from main::@1
screen#19 = phi( main::@1/screen#6 )
screen#8 = screen#19
printf_str::putc#1 = (void (*)(char)) 0
printf_str::putc#1 = &cputc
printf_str::str#2 = main::str1
call printf_str
to:main::@3
@ -118,7 +131,12 @@ __constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
__constant unsigned int STACK_BASE = $103
void __start()
__stackcall void cputc(char x)
__constant char cputc::OFFSET_STACK_X = 0
char cputc::x
char cputc::x#0
void main()
__constant unsigned int main::pct = $156
__constant char main::str[$e] = "Commodore is "
@ -235,9 +253,9 @@ Identical Phi Values screen#12 screen#10
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition printf_str::$0 [3] if(0!=*printf_str::str#3) goto printf_str::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant printf_str::putc#0 = (void (*)(char)) 0
Constant printf_str::putc#0 = &cputc
Constant printf_str::str#1 = main::str
Constant printf_uint::putc#0 = (void (*)(char)) 0
Constant printf_uint::putc#0 = &cputc
Constant printf_uint::uvalue#0 = main::pct
Constant printf_uint::format_min_length#0 = 0
Constant printf_uint::format_justify_left#0 = 0
@ -245,10 +263,11 @@ Constant printf_uint::format_sign_always#0 = 0
Constant printf_uint::format_zero_padding#0 = 0
Constant printf_uint::format_upper_case#0 = 0
Constant printf_uint::format_radix#0 = HEXADECIMAL
Constant printf_str::putc#1 = (void (*)(char)) 0
Constant printf_str::putc#1 = &cputc
Constant printf_str::str#2 = main::str1
Constant screen#11 = (char *) 1024
Successful SSA optimization Pass2ConstantIdentification
Eliminating unused variable cputc::x#0 and assignment [24] cputc::x#0 = stackidx(char,cputc::OFFSET_STACK_X)
Eliminating unused constant printf_str::putc#0
Eliminating unused constant printf_str::putc#1
Eliminating unused constant printf_uint::putc#0
@ -260,7 +279,12 @@ Eliminating unused constant printf_uint::format_upper_case#0
Eliminating unused constant printf_uint::format_radix#0
Successful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant HEXADECIMAL
Eliminating unused constant cputc::OFFSET_STACK_X
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure cputc
Removing unused procedure block cputc
Removing unused procedure block cputc::@return
Successful SSA optimization PassNEliminateEmptyProcedure
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::__init1
@ -483,6 +507,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const STACK_BASE = $103
.label screen = 4
.segment Code
// main
@ -658,6 +683,7 @@ __constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
__constant unsigned int STACK_BASE = $103
void main()
__constant unsigned int main::pct = $156
__constant char main::str[$e] = "Commodore is "
@ -708,6 +734,7 @@ Score: 697
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const STACK_BASE = $103
.label screen = 4
.segment Code
// main

View File

@ -2,6 +2,7 @@ __constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
__constant unsigned int STACK_BASE = $103
void main()
__constant unsigned int main::pct = $156
__constant char main::str[$e] = "Commodore is "

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,442 +1,463 @@
constant byte BINARY = 2
constant byte* const COLORRAM = (byte*) 55296
constant byte DECIMAL = $a
constant byte* const DEFAULT_SCREEN = (byte*) 1024
constant byte* DIGITS[] = "0123456789abcdef"z
constant byte HEXADECIMAL = $10
constant const byte LIGHT_BLUE = $e
constant byte OCTAL = 8
constant byte OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
constant byte RADIX::BINARY = 2
constant byte RADIX::DECIMAL = $a
constant byte RADIX::HEXADECIMAL = $10
constant byte RADIX::OCTAL = 8
constant word* RADIX_BINARY_VALUES[] = { $8000, $4000, $2000, $1000, $800, $400, $200, $100, $80, $40, $20, $10, 8, 4, 2 }
constant word* RADIX_DECIMAL_VALUES[] = { $2710, $3e8, $64, $a }
constant byte* RADIX_DECIMAL_VALUES_CHAR[] = { $64, $a }
constant dword* RADIX_DECIMAL_VALUES_LONG[] = { $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a }
constant word* RADIX_HEXADECIMAL_VALUES[] = { $1000, $100, $10 }
constant word* RADIX_OCTAL_VALUES[] = { $8000, $1000, $200, $40, 8 }
constant byte SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
__constant char BINARY = 2
__constant char * const COLORRAM = (char *) 55296
__constant char DECIMAL = $a
__constant char * const DEFAULT_SCREEN = (char *) 1024
__constant char DIGITS[] = "0123456789abcdef"z
__constant char HEXADECIMAL = $10
__constant const char LIGHT_BLUE = $e
__constant char OCTAL = 8
__constant char OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
__constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
__constant unsigned int RADIX_BINARY_VALUES[] = { $8000, $4000, $2000, $1000, $800, $400, $200, $100, $80, $40, $20, $10, 8, 4, 2 }
__constant unsigned int RADIX_DECIMAL_VALUES[] = { $2710, $3e8, $64, $a }
__constant char RADIX_DECIMAL_VALUES_CHAR[] = { $64, $a }
__constant unsigned long RADIX_DECIMAL_VALUES_LONG[] = { $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a }
__constant unsigned int RADIX_HEXADECIMAL_VALUES[] = { $1000, $100, $10 }
__constant unsigned int RADIX_OCTAL_VALUES[] = { $8000, $1000, $200, $40, 8 }
__constant char SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
__constant unsigned int STACK_BASE = $103
void __start()
void clrscr()
byte clrscr::c
byte clrscr::c#1 reg byte y 20002.0
byte clrscr::c#2 reg byte y 12501.25
byte clrscr::l
byte clrscr::l#1 reg byte x 2002.0
byte clrscr::l#2 reg byte x 333.6666666666667
byte* clrscr::line_cols
byte* clrscr::line_cols#1 line_cols zp[2]:2 1001.0
byte* clrscr::line_cols#5 line_cols zp[2]:2 1500.375
byte* clrscr::line_text
byte* clrscr::line_text#1 line_text zp[2]:8 667.3333333333334
byte* clrscr::line_text#5 line_text zp[2]:8 1714.7142857142858
char clrscr::c
char clrscr::c#1 // reg byte y 20002.0
char clrscr::c#2 // reg byte y 12501.25
char clrscr::l
char clrscr::l#1 // reg byte x 2002.0
char clrscr::l#2 // reg byte x 333.6666666666667
char *clrscr::line_cols
char *clrscr::line_cols#1 // line_cols zp[2]:13 1001.0
char *clrscr::line_cols#5 // line_cols zp[2]:13 1500.375
char *clrscr::line_text
char *clrscr::line_text#1 // line_text zp[2]:6 667.3333333333334
char *clrscr::line_text#5 // line_text zp[2]:6 1714.7142857142858
void conio_c64_init()
constant byte* const conio_c64_init::BASIC_CURSOR_LINE = (byte*) 214
byte conio_c64_init::line
byte conio_c64_init::line#0 reg byte x 11.0
byte conio_c64_init::line#2 reg byte x 22.0
byte conio_cursor_x loadstore zp[1]:17 90910.36363636363
byte conio_cursor_y loadstore zp[1]:18 1767956.9558011051
byte* conio_line_color loadstore zp[2]:21 1234638.039106145
byte* conio_line_text loadstore zp[2]:19 1227778.9388888888
void cputc(byte cputc::c)
byte cputc::c
byte cputc::c#0 reg byte a 200002.0
byte cputc::c#1 reg byte a 200002.0
byte cputc::c#2 reg byte a 2002.0
byte cputc::c#3 reg byte a 22.0
byte cputc::c#5 reg byte a 1100508.0
__constant char * const conio_c64_init::BASIC_CURSOR_LINE = (char *) 214
char conio_c64_init::line
char conio_c64_init::line#0 // reg byte x 11.0
char conio_c64_init::line#2 // reg byte x 22.0
__loadstore char conio_cursor_x // zp[1]:21 50.294117647058826
__loadstore char conio_cursor_y // zp[1]:22 644.1800000000001
__loadstore char *conio_line_color // zp[2]:25 464.77083333333326
__loadstore char *conio_line_text // zp[2]:23 455.28571428571433
__stackcall void cputc(char c)
__constant char cputc::OFFSET_STACK_C = 0
char cputc::c
char cputc::c#0 // reg byte a 151.5
void cputln()
void cputs(const byte* cputs::s)
byte cputs::c
byte cputs::c#1 reg byte a 100001.0
const byte* cputs::s
const byte* cputs::s#0 s zp[2]:8 50000.5
const byte* cputs::s#20 s zp[2]:8 155002.0
const byte* cputs::s#21 s zp[2]:8 10001.0
void cscroll()
void gotoxy(byte gotoxy::x , byte gotoxy::y)
byte*~ gotoxy::$5 zp[2]:28 202.0
byte*~ gotoxy::$6 zp[2]:24 202.0
word~ gotoxy::$7 zp[2]:24 151.5
word~ gotoxy::$8 zp[2]:26 202.0
word~ gotoxy::$9 zp[2]:24 202.0
word gotoxy::line_offset
word gotoxy::line_offset#0 line_offset zp[2]:24 101.0
byte gotoxy::x
constant byte gotoxy::x#2 x = 0
byte gotoxy::y
byte gotoxy::y#2 reg byte x 71.0
byte gotoxy::y#4 reg byte x 67.33333333333333
void gotoxy(char x , char y)
char *gotoxy::$5 // zp[2]:32 202.0
char *gotoxy::$6 // zp[2]:28 202.0
unsigned int gotoxy::$7 // zp[2]:28 151.5
unsigned int gotoxy::$8 // zp[2]:30 202.0
unsigned int gotoxy::$9 // zp[2]:28 202.0
unsigned int gotoxy::line_offset
unsigned int gotoxy::line_offset#0 // line_offset zp[2]:28 101.0
char gotoxy::x
__constant char gotoxy::x#2 = 0 // x
char gotoxy::y
char gotoxy::y#2 // reg byte x 71.0
char gotoxy::y#4 // reg byte x 67.33333333333333
void main()
volatile byte main::c loadstore zp[1]:23 11.0
constant byte* main::s[9] = "A char: "
constant byte* main::s1[2] = "
__loadstore volatile char main::c // zp[1]:27 11.0
__constant char main::s[9] = "A char: "
__constant char main::s1[2] = "
"
constant byte* main::s10[$f] = "A signed int: "
constant byte* main::s12[$12] = "An unsigned int: "
constant byte* main::s14[$10] = "A signed long: "
constant byte* main::s16[$13] = "An unsigned long: "
constant byte* main::s2[$c] = "A pointer: "
constant byte* main::s4[$c] = "A percent: "
constant byte* main::s6[$10] = "A signed char: "
constant byte* main::s8[$13] = "An unsigned char: "
constant signed byte main::sc = -$c
constant signed word main::si = -$4d2
constant signed dword main::sl = -$1e240
constant byte main::uc = $22
constant word main::ui = $162e
constant dword main::ul = $8aa52
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
void* memcpy::destination
void* memcpy::destination#2 destination zp[2]:39
byte* memcpy::dst
byte* memcpy::dst#1 dst zp[2]:39 1.00000000001E11
byte* memcpy::dst#2 dst zp[2]:39 1.0033333333466667E11
byte* memcpy::dst#4 dst zp[2]:39 2.000000002E9
word memcpy::num
void* memcpy::return
void* memcpy::source
void* memcpy::source#2 source zp[2]:30
byte* memcpy::src
byte* memcpy::src#1 src zp[2]:30 2.00000000002E11
byte* memcpy::src#2 src zp[2]:30 1.0025000000125E11
byte* memcpy::src#4 src zp[2]:30 1.000000001E9
byte* memcpy::src_end
byte* memcpy::src_end#0 src_end zp[2]:37 1.262500000025E10
void* memset(void* memset::str , byte memset::c , word memset::num)
byte memset::c
byte memset::c#4 reg byte x 1.4285714285857143E10
byte* memset::dst
byte* memset::dst#1 dst zp[2]:30 2.00000000002E11
byte* memset::dst#2 dst zp[2]:30 1.3366666666833334E11
byte* memset::dst#4 dst zp[2]:30 2.000000002E9
byte* memset::end
byte* memset::end#0 end zp[2]:39 1.6833333333666668E10
word memset::num
void* memset::return
void* memset::str
void* memset::str#3 str zp[2]:30
struct printf_buffer_number printf_buffer loadstore mem[12] = {}
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_upper_case , byte printf_number_buffer::format_radix)
word~ printf_number_buffer::$19 zp[2]:30 1001.0
__constant char main::s10[$f] = "A signed int: "
__constant char main::s12[$12] = "An unsigned int: "
__constant char main::s14[$10] = "A signed long: "
__constant char main::s16[$13] = "An unsigned long: "
__constant char main::s2[$c] = "A pointer: "
__constant char main::s4[$c] = "A percent: "
__constant char main::s6[$10] = "A signed char: "
__constant char main::s8[$13] = "An unsigned char: "
__constant signed char main::sc = -$c
__constant int main::si = -$4d2
__constant long main::sl = -$1e240
__constant char main::uc = $22
__constant unsigned int main::ui = $162e
__constant unsigned long main::ul = $8aa52
void * memcpy(void *destination , void *source , unsigned int num)
void *memcpy::destination
void *memcpy::destination#2 // destination zp[2]:43
char *memcpy::dst
char *memcpy::dst#1 // dst zp[2]:43 1000001.0
char *memcpy::dst#2 // dst zp[2]:43 1033334.6666666667
char *memcpy::dst#4 // dst zp[2]:43 200002.0
unsigned int memcpy::num
void *memcpy::return
void *memcpy::source
void *memcpy::source#2 // source zp[2]:15
char *memcpy::src
char *memcpy::src#1 // src zp[2]:15 2000002.0
char *memcpy::src#2 // src zp[2]:15 1025001.25
char *memcpy::src#4 // src zp[2]:15 100001.0
char *memcpy::src_end
char *memcpy::src_end#0 // src_end zp[2]:41 137500.25
void * memset(void *str , char c , unsigned int num)
char memset::c
char memset::c#4 // reg byte x 142857.2857142857
char *memset::dst
char *memset::dst#1 // dst zp[2]:15 2000002.0
char *memset::dst#2 // dst zp[2]:15 1366668.3333333335
char *memset::dst#4 // dst zp[2]:15 200002.0
char *memset::end
char *memset::end#0 // end zp[2]:43 183333.6666666667
unsigned int memset::num
void *memset::return
void *memset::str
void *memset::str#3 // str zp[2]:15
__loadstore struct printf_buffer_number printf_buffer = {} // mem[12]
void printf_number_buffer(void (*putc)(char) , char buffer_sign , char *buffer_digits , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
unsigned int printf_number_buffer::$19 // zp[2]:34 1001.0
struct printf_buffer_number printf_number_buffer::buffer
byte* printf_number_buffer::buffer_digits
byte printf_number_buffer::buffer_sign
byte printf_number_buffer::buffer_sign#0 buffer_sign zp[1]:6 202.0
byte printf_number_buffer::buffer_sign#1 buffer_sign zp[1]:6 202.0
byte printf_number_buffer::buffer_sign#10 buffer_sign zp[1]:6 180.45
byte printf_number_buffer::buffer_sign#2 buffer_sign zp[1]:6 202.0
byte printf_number_buffer::buffer_sign#3 buffer_sign zp[1]:6 202.0
byte printf_number_buffer::buffer_sign#4 buffer_sign zp[1]:6 202.0
byte printf_number_buffer::buffer_sign#5 buffer_sign zp[1]:6 202.0
char *printf_number_buffer::buffer_digits
char printf_number_buffer::buffer_sign
char printf_number_buffer::buffer_sign#0 // buffer_sign zp[1]:4 202.0
char printf_number_buffer::buffer_sign#1 // buffer_sign zp[1]:4 202.0
char printf_number_buffer::buffer_sign#10 // buffer_sign zp[1]:4 171.85714285714283
char printf_number_buffer::buffer_sign#2 // buffer_sign zp[1]:4 202.0
char printf_number_buffer::buffer_sign#3 // buffer_sign zp[1]:4 202.0
char printf_number_buffer::buffer_sign#4 // buffer_sign zp[1]:4 202.0
char printf_number_buffer::buffer_sign#5 // buffer_sign zp[1]:4 202.0
struct printf_format_number printf_number_buffer::format
byte printf_number_buffer::format_justify_left
byte printf_number_buffer::format_justify_left#10 format_justify_left zp[1]:4 64.58064516129032
byte printf_number_buffer::format_min_length
byte printf_number_buffer::format_min_length#10 reg byte x 100.1
byte printf_number_buffer::format_radix
byte printf_number_buffer::format_sign_always
byte printf_number_buffer::format_upper_case
byte printf_number_buffer::format_upper_case#10 format_upper_case zp[1]:7 38.5
byte printf_number_buffer::format_zero_padding
byte printf_number_buffer::format_zero_padding#10 format_zero_padding zp[1]:5 93.84375
signed byte printf_number_buffer::len
signed byte printf_number_buffer::len#0 reg byte y 1501.5
signed byte printf_number_buffer::len#1 reg byte y 2002.0
signed byte printf_number_buffer::len#2 reg byte y 3003.0
signed byte printf_number_buffer::padding
signed byte printf_number_buffer::padding#1 padding zp[1]:10 1001.0
signed byte printf_number_buffer::padding#10 padding zp[1]:10 190.66666666666666
void printf_padding(byte printf_padding::pad , byte printf_padding::length)
byte printf_padding::i
byte printf_padding::i#1 i zp[1]:16 200002.0
byte printf_padding::i#2 i zp[1]:16 75000.75
byte printf_padding::length
byte printf_padding::length#0 length zp[1]:32 2002.0
byte printf_padding::length#1 length zp[1]:32 2002.0
byte printf_padding::length#2 length zp[1]:32 2002.0
byte printf_padding::length#4 length zp[1]:32 17167.333333333332
byte printf_padding::pad
byte printf_padding::pad#5 pad zp[1]:15 16666.833333333332
void printf_schar(signed byte printf_schar::value , byte printf_schar::format_min_length , byte printf_schar::format_justify_left , byte printf_schar::format_sign_always , byte printf_schar::format_zero_padding , byte printf_schar::format_upper_case , byte printf_schar::format_radix)
char printf_number_buffer::format_justify_left
char printf_number_buffer::format_justify_left#10 // format_justify_left zp[1]:2 60.666666666666664
char printf_number_buffer::format_min_length
char printf_number_buffer::format_min_length#10 // reg byte x 100.1
char printf_number_buffer::format_radix
char printf_number_buffer::format_sign_always
char printf_number_buffer::format_upper_case
char printf_number_buffer::format_upper_case#10 // format_upper_case zp[1]:5 35.75
char printf_number_buffer::format_zero_padding
char printf_number_buffer::format_zero_padding#10 // format_zero_padding zp[1]:3 88.32352941176471
signed char printf_number_buffer::len
signed char printf_number_buffer::len#0 // reg byte y 1501.5
signed char printf_number_buffer::len#1 // reg byte y 2002.0
signed char printf_number_buffer::len#2 // reg byte y 3003.0
signed char printf_number_buffer::padding
signed char printf_number_buffer::padding#1 // padding zp[1]:8 1001.0
signed char printf_number_buffer::padding#10 // padding zp[1]:8 166.83333333333334
void (*printf_number_buffer::putc)(char)
void (*printf_number_buffer::putc#10)(char) // putc zp[2]:6 111.22222222222223
void printf_padding(void (*putc)(char) , char pad , char length)
char printf_padding::i
char printf_padding::i#1 // i zp[1]:18 200002.0
char printf_padding::i#2 // i zp[1]:18 100001.0
char printf_padding::length
char printf_padding::length#0 // length zp[1]:36 2002.0
char printf_padding::length#1 // length zp[1]:36 2002.0
char printf_padding::length#2 // length zp[1]:36 2002.0
char printf_padding::length#4 // length zp[1]:36 20600.8
char printf_padding::pad
char printf_padding::pad#5 // pad zp[1]:17 16666.833333333332
void (*printf_padding::putc)(char)
void (*printf_padding::putc#0)(char) // putc zp[2]:6 1001.0
void (*printf_padding::putc#1)(char) // putc zp[2]:6 1001.0
void (*printf_padding::putc#2)(char) // putc zp[2]:6 1001.0
void (*printf_padding::putc#5)(char) // putc zp[2]:6 30030.0
void printf_schar(void (*putc)(char) , signed char value , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_schar::format
byte printf_schar::format_justify_left
constant byte printf_schar::format_justify_left#0 format_justify_left = 0
byte printf_schar::format_min_length
constant byte printf_schar::format_min_length#0 format_min_length = 0
byte printf_schar::format_radix
byte printf_schar::format_sign_always
byte printf_schar::format_upper_case
constant byte printf_schar::format_upper_case#0 format_upper_case = 0
byte printf_schar::format_zero_padding
constant byte printf_schar::format_zero_padding#0 format_zero_padding = 0
byte printf_schar::uvalue
constant byte printf_schar::uvalue#0 uvalue = (byte)printf_schar::value#0
signed byte printf_schar::value
constant signed byte printf_schar::value#0 value = -main::sc
void printf_sint(signed word printf_sint::value , byte printf_sint::format_min_length , byte printf_sint::format_justify_left , byte printf_sint::format_sign_always , byte printf_sint::format_zero_padding , byte printf_sint::format_upper_case , byte printf_sint::format_radix)
char printf_schar::format_justify_left
__constant char printf_schar::format_justify_left#0 = 0 // format_justify_left
char printf_schar::format_min_length
__constant char printf_schar::format_min_length#0 = 0 // format_min_length
char printf_schar::format_radix
char printf_schar::format_sign_always
char printf_schar::format_upper_case
__constant char printf_schar::format_upper_case#0 = 0 // format_upper_case
char printf_schar::format_zero_padding
__constant char printf_schar::format_zero_padding#0 = 0 // format_zero_padding
void (*printf_schar::putc)(char)
__constant void (*printf_schar::putc#0)(char) = &cputc // putc
char printf_schar::uvalue
__constant char printf_schar::uvalue#0 = (char)printf_schar::value#0 // uvalue
signed char printf_schar::value
__constant signed char printf_schar::value#0 = -main::sc // value
void printf_sint(void (*putc)(char) , int value , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_sint::format
byte printf_sint::format_justify_left
constant byte printf_sint::format_justify_left#0 format_justify_left = 0
byte printf_sint::format_min_length
constant byte printf_sint::format_min_length#0 format_min_length = 0
byte printf_sint::format_radix
byte printf_sint::format_sign_always
byte printf_sint::format_upper_case
constant byte printf_sint::format_upper_case#0 format_upper_case = 0
byte printf_sint::format_zero_padding
constant byte printf_sint::format_zero_padding#0 format_zero_padding = 0
word printf_sint::uvalue
constant word printf_sint::uvalue#0 uvalue = (word)printf_sint::value#0
signed word printf_sint::value
constant signed word printf_sint::value#0 value = -main::si
void printf_slong(signed dword printf_slong::value , byte printf_slong::format_min_length , byte printf_slong::format_justify_left , byte printf_slong::format_sign_always , byte printf_slong::format_zero_padding , byte printf_slong::format_upper_case , byte printf_slong::format_radix)
char printf_sint::format_justify_left
__constant char printf_sint::format_justify_left#0 = 0 // format_justify_left
char printf_sint::format_min_length
__constant char printf_sint::format_min_length#0 = 0 // format_min_length
char printf_sint::format_radix
char printf_sint::format_sign_always
char printf_sint::format_upper_case
__constant char printf_sint::format_upper_case#0 = 0 // format_upper_case
char printf_sint::format_zero_padding
__constant char printf_sint::format_zero_padding#0 = 0 // format_zero_padding
void (*printf_sint::putc)(char)
__constant void (*printf_sint::putc#0)(char) = &cputc // putc
unsigned int printf_sint::uvalue
__constant unsigned int printf_sint::uvalue#0 = (unsigned int)printf_sint::value#0 // uvalue
int printf_sint::value
__constant int printf_sint::value#0 = -main::si // value
void printf_slong(void (*putc)(char) , long value , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_slong::format
byte printf_slong::format_justify_left
constant byte printf_slong::format_justify_left#0 format_justify_left = 0
byte printf_slong::format_min_length
constant byte printf_slong::format_min_length#0 format_min_length = 0
byte printf_slong::format_radix
byte printf_slong::format_sign_always
byte printf_slong::format_upper_case
constant byte printf_slong::format_upper_case#0 format_upper_case = 0
byte printf_slong::format_zero_padding
constant byte printf_slong::format_zero_padding#0 format_zero_padding = 0
dword printf_slong::uvalue
constant dword printf_slong::uvalue#0 uvalue = (dword)printf_slong::value#0
signed dword printf_slong::value
constant signed dword printf_slong::value#0 value = -main::sl
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_upper_case , byte printf_uchar::format_radix)
char printf_slong::format_justify_left
__constant char printf_slong::format_justify_left#0 = 0 // format_justify_left
char printf_slong::format_min_length
__constant char printf_slong::format_min_length#0 = 0 // format_min_length
char printf_slong::format_radix
char printf_slong::format_sign_always
char printf_slong::format_upper_case
__constant char printf_slong::format_upper_case#0 = 0 // format_upper_case
char printf_slong::format_zero_padding
__constant char printf_slong::format_zero_padding#0 = 0 // format_zero_padding
void (*printf_slong::putc)(char)
__constant void (*printf_slong::putc#0)(char) = &cputc // putc
unsigned long printf_slong::uvalue
__constant unsigned long printf_slong::uvalue#0 = (unsigned long)printf_slong::value#0 // uvalue
long printf_slong::value
__constant long printf_slong::value#0 = -main::sl // value
void printf_str(void (*putc)(char) , const char *s)
char printf_str::c
char printf_str::c#1 // reg byte a 100001.0
void (*printf_str::putc)(char)
void (*printf_str::putc#0)(char) // putc zp[2]:6 2002.0
void (*printf_str::putc#21)(char) // putc zp[2]:6 10010.0
const char *printf_str::s
const char *printf_str::s#0 // s zp[2]:13 100001.0
const char *printf_str::s#20 // s zp[2]:13 155002.0
const char *printf_str::s#21 // s zp[2]:13 10001.0
void printf_uchar(void (*putc)(char) , char uvalue , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_uchar::format
byte printf_uchar::format_justify_left
constant byte printf_uchar::format_justify_left#0 format_justify_left = 0
byte printf_uchar::format_min_length
constant byte printf_uchar::format_min_length#0 format_min_length = 0
byte printf_uchar::format_radix
byte printf_uchar::format_sign_always
byte printf_uchar::format_upper_case
constant byte printf_uchar::format_upper_case#0 format_upper_case = 0
byte printf_uchar::format_zero_padding
constant byte printf_uchar::format_zero_padding#0 format_zero_padding = 0
byte printf_uchar::uvalue
void printf_uint(word printf_uint::uvalue , byte printf_uint::format_min_length , byte printf_uint::format_justify_left , byte printf_uint::format_sign_always , byte printf_uint::format_zero_padding , byte printf_uint::format_upper_case , byte printf_uint::format_radix)
char printf_uchar::format_justify_left
__constant char printf_uchar::format_justify_left#0 = 0 // format_justify_left
char printf_uchar::format_min_length
__constant char printf_uchar::format_min_length#0 = 0 // format_min_length
char printf_uchar::format_radix
char printf_uchar::format_sign_always
char printf_uchar::format_upper_case
__constant char printf_uchar::format_upper_case#0 = 0 // format_upper_case
char printf_uchar::format_zero_padding
__constant char printf_uchar::format_zero_padding#0 = 0 // format_zero_padding
void (*printf_uchar::putc)(char)
__constant void (*printf_uchar::putc#0)(char) = &cputc // putc
char printf_uchar::uvalue
void printf_uint(void (*putc)(char) , unsigned int uvalue , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_uint::format
byte printf_uint::format_justify_left
byte printf_uint::format_min_length
byte printf_uint::format_radix
byte printf_uint::format_radix#2 reg byte x 33.666666666666664
byte printf_uint::format_sign_always
byte printf_uint::format_upper_case
byte printf_uint::format_zero_padding
word printf_uint::uvalue
word printf_uint::uvalue#2 uvalue zp[2]:2 50.5
void printf_ulong(dword printf_ulong::uvalue , byte printf_ulong::format_min_length , byte printf_ulong::format_justify_left , byte printf_ulong::format_sign_always , byte printf_ulong::format_zero_padding , byte printf_ulong::format_upper_case , byte printf_ulong::format_radix)
char printf_uint::format_justify_left
char printf_uint::format_min_length
char printf_uint::format_radix
char printf_uint::format_radix#2 // reg byte x 33.666666666666664
char printf_uint::format_sign_always
char printf_uint::format_upper_case
char printf_uint::format_zero_padding
void (*printf_uint::putc)(char)
unsigned int printf_uint::uvalue
unsigned int printf_uint::uvalue#2 // uvalue zp[2]:6 50.5
void printf_ulong(void (*putc)(char) , unsigned long uvalue , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_ulong::format
byte printf_ulong::format_justify_left
constant byte printf_ulong::format_justify_left#0 format_justify_left = 0
byte printf_ulong::format_min_length
constant byte printf_ulong::format_min_length#0 format_min_length = 0
byte printf_ulong::format_radix
byte printf_ulong::format_sign_always
byte printf_ulong::format_upper_case
constant byte printf_ulong::format_upper_case#0 format_upper_case = 0
byte printf_ulong::format_zero_padding
constant byte printf_ulong::format_zero_padding#0 format_zero_padding = 0
dword printf_ulong::uvalue
word strlen(byte* strlen::str)
word strlen::len
word strlen::len#1 len zp[2]:30 100001.0
word strlen::len#2 len zp[2]:30 50250.75
word strlen::return
word strlen::return#2 return zp[2]:30 2002.0
byte* strlen::str
byte* strlen::str#0 str zp[2]:37 200002.0
byte* strlen::str#2 str zp[2]:37 100001.0
byte* strupr(byte* strupr::str)
byte~ strupr::$0 reg byte a 200002.0
byte* strupr::return
byte* strupr::src
byte* strupr::src#1 src zp[2]:37 200002.0
byte* strupr::src#2 src zp[2]:37 71429.28571428571
byte* strupr::str
constant byte* strupr::str#0 str = (byte*)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
byte toupper(byte toupper::ch)
byte toupper::ch
byte toupper::ch#0 reg byte a 1700002.0000000002
byte toupper::return
byte toupper::return#0 reg byte a 2000002.0
byte toupper::return#2 reg byte a 1033334.6666666667
byte toupper::return#3 reg byte a 200002.0
void uctoa(byte uctoa::value , byte* uctoa::buffer , byte uctoa::radix)
byte* uctoa::buffer
byte* uctoa::buffer#10 buffer zp[2]:8 3500.4999999999995
byte* uctoa::buffer#15 buffer zp[2]:8 15001.5
byte* uctoa::buffer#3 buffer zp[2]:8 2002.0
byte* uctoa::buffer#4 buffer zp[2]:8 20002.0
byte uctoa::digit
byte uctoa::digit#1 digit zp[1]:6 20002.0
byte uctoa::digit#2 digit zp[1]:6 3077.230769230769
byte uctoa::digit_value
byte uctoa::digit_value#0 digit_value zp[1]:32 6000.6
byte* uctoa::digit_values
byte uctoa::max_digits
byte uctoa::radix
byte uctoa::started
byte uctoa::started#2 started zp[1]:7 6000.6
byte uctoa::started#4 started zp[1]:7 10001.0
byte uctoa::value
byte uctoa::value#0 reg byte x 10001.0
byte uctoa::value#10 reg byte x 1001.0
byte uctoa::value#3 reg byte x 7000.999999999999
byte uctoa::value#7 reg byte x 15001.5
byte uctoa_append(byte* uctoa_append::buffer , byte uctoa_append::value , byte uctoa_append::sub)
byte* uctoa_append::buffer
byte* uctoa_append::buffer#0 buffer zp[2]:8 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]:32 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
void ultoa(dword ultoa::value , byte* ultoa::buffer , byte ultoa::radix)
byte~ ultoa::$10 reg byte a 20002.0
byte~ ultoa::$11 reg byte a 2002.0
byte* ultoa::buffer
byte* ultoa::buffer#10 buffer zp[2]:37 3000.4285714285716
byte* ultoa::buffer#15 buffer zp[2]:37 15001.5
byte* ultoa::buffer#3 buffer zp[2]:37 2002.0
byte* ultoa::buffer#4 buffer zp[2]:37 20002.0
byte ultoa::digit
byte ultoa::digit#1 digit zp[1]:10 20002.0
byte ultoa::digit#2 digit zp[1]:10 2857.4285714285716
dword ultoa::digit_value
dword ultoa::digit_value#0 digit_value zp[4]:33 6000.6
dword* ultoa::digit_values
byte ultoa::max_digits
byte ultoa::radix
byte ultoa::started
byte ultoa::started#2 reg byte x 5000.5
byte ultoa::started#4 reg byte x 10001.0
dword ultoa::value
dword ultoa::value#0 value zp[4]:11 10001.0
dword ultoa::value#10 value zp[4]:11 1001.0
dword ultoa::value#3 value zp[4]:11 5857.857142857143
dword ultoa::value#7 value zp[4]:11 15001.5
dword ultoa_append(byte* ultoa_append::buffer , dword ultoa_append::value , dword ultoa_append::sub)
byte* ultoa_append::buffer
byte* ultoa_append::buffer#0 buffer zp[2]:37 13750.25
byte ultoa_append::digit
byte ultoa_append::digit#1 reg byte x 1.0000001E7
byte ultoa_append::digit#2 reg byte x 1.00500015E7
dword ultoa_append::return
dword ultoa_append::return#0 return zp[4]:11 20002.0
dword ultoa_append::sub
dword ultoa_append::sub#0 sub zp[4]:33 3335000.5
dword ultoa_append::value
dword ultoa_append::value#0 value zp[4]:11 36667.33333333333
dword ultoa_append::value#1 value zp[4]:11 2.0000002E7
dword ultoa_append::value#2 value zp[4]:11 5018334.166666666
void utoa(word utoa::value , byte* utoa::buffer , byte utoa::radix)
byte~ utoa::$10 reg byte a 20002.0
byte~ utoa::$11 reg byte x 2002.0
byte~ utoa::$4 reg byte a 20002.0
byte* utoa::buffer
byte* utoa::buffer#10 buffer zp[2]:37 2800.4000000000005
byte* utoa::buffer#15 buffer zp[2]:37 15001.5
byte* utoa::buffer#3 buffer zp[2]:37 2002.0
byte* utoa::buffer#4 buffer zp[2]:37 20002.0
byte utoa::digit
byte utoa::digit#1 digit zp[1]:5 20002.0
byte utoa::digit#2 digit zp[1]:5 2666.9333333333334
word utoa::digit_value
word utoa::digit_value#0 digit_value zp[2]:30 6000.6
word* utoa::digit_values
word* utoa::digit_values#8 digit_values zp[2]:8 588.2941176470588
byte utoa::max_digits
byte utoa::max_digits#7 max_digits zp[1]:4 588.2941176470588
byte utoa::radix
byte utoa::radix#1 reg byte x 202.0
byte utoa::radix#2 reg byte x 1026.25
byte utoa::started
byte utoa::started#2 reg byte x 4286.142857142857
byte utoa::started#4 reg byte x 10001.0
word utoa::value
word utoa::value#0 value zp[2]:2 10001.0
word utoa::value#10 value zp[2]:2 183.66666666666669
word utoa::value#2 value zp[2]:2 101.0
word utoa::value#3 value zp[2]:2 5125.625
word utoa::value#7 value zp[2]:2 15001.5
word utoa_append(byte* utoa_append::buffer , word utoa_append::value , word utoa_append::sub)
byte* utoa_append::buffer
byte* utoa_append::buffer#0 buffer zp[2]:37 13750.25
byte utoa_append::digit
byte utoa_append::digit#1 reg byte x 1.0000001E7
byte utoa_append::digit#2 reg byte x 1.00500015E7
word utoa_append::return
word utoa_append::return#0 return zp[2]:2 20002.0
word utoa_append::sub
word utoa_append::sub#0 sub zp[2]:30 3335000.5
word utoa_append::value
word utoa_append::value#0 value zp[2]:2 36667.33333333333
word utoa_append::value#1 value zp[2]:2 2.0000002E7
word utoa_append::value#2 value zp[2]:2 5018334.166666666
char printf_ulong::format_justify_left
__constant char printf_ulong::format_justify_left#0 = 0 // format_justify_left
char printf_ulong::format_min_length
__constant char printf_ulong::format_min_length#0 = 0 // format_min_length
char printf_ulong::format_radix
char printf_ulong::format_sign_always
char printf_ulong::format_upper_case
__constant char printf_ulong::format_upper_case#0 = 0 // format_upper_case
char printf_ulong::format_zero_padding
__constant char printf_ulong::format_zero_padding#0 = 0 // format_zero_padding
void (*printf_ulong::putc)(char)
__constant void (*printf_ulong::putc#0)(char) = &cputc // putc
unsigned long printf_ulong::uvalue
unsigned int strlen(char *str)
unsigned int strlen::len
unsigned int strlen::len#1 // len zp[2]:34 100001.0
unsigned int strlen::len#2 // len zp[2]:34 50250.75
unsigned int strlen::return
unsigned int strlen::return#2 // return zp[2]:34 2002.0
char *strlen::str
char *strlen::str#0 // str zp[2]:19 200002.0
char *strlen::str#2 // str zp[2]:19 100001.0
char * strupr(char *str)
char strupr::$0 // reg byte a 200002.0
char *strupr::return
char *strupr::src
char *strupr::src#1 // src zp[2]:19 200002.0
char *strupr::src#2 // src zp[2]:19 71429.28571428571
char *strupr::str
__constant char *strupr::str#0 = (char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS // str
char toupper(char ch)
char toupper::ch
char toupper::ch#0 // reg byte a 1700002.0000000002
char toupper::return
char toupper::return#0 // reg byte a 2000002.0
char toupper::return#2 // reg byte a 1033334.6666666667
char toupper::return#3 // reg byte a 200002.0
void uctoa(char value , char *buffer , char radix)
char *uctoa::buffer
char *uctoa::buffer#10 // buffer zp[2]:6 3500.4999999999995
char *uctoa::buffer#15 // buffer zp[2]:6 15001.5
char *uctoa::buffer#3 // buffer zp[2]:6 2002.0
char *uctoa::buffer#4 // buffer zp[2]:6 20002.0
char uctoa::digit
char uctoa::digit#1 // digit zp[1]:4 20002.0
char uctoa::digit#2 // digit zp[1]:4 3077.230769230769
char uctoa::digit_value
char uctoa::digit_value#0 // digit_value zp[1]:36 6000.6
char *uctoa::digit_values
char uctoa::max_digits
char uctoa::radix
char uctoa::started
char uctoa::started#2 // started zp[1]:5 6000.6
char uctoa::started#4 // started zp[1]:5 10001.0
char uctoa::value
char uctoa::value#0 // reg byte x 10001.0
char uctoa::value#10 // reg byte x 1001.0
char uctoa::value#3 // reg byte x 7000.999999999999
char uctoa::value#7 // reg byte x 15001.5
char uctoa_append(char *buffer , char value , char sub)
char *uctoa_append::buffer
char *uctoa_append::buffer#0 // buffer zp[2]:6 13750.25
char uctoa_append::digit
char uctoa_append::digit#1 // reg byte y 1.0000001E7
char uctoa_append::digit#2 // reg byte y 1.00500015E7
char uctoa_append::return
char uctoa_append::return#0 // reg byte x 20002.0
char uctoa_append::sub
char uctoa_append::sub#0 // sub zp[1]:36 3335000.5
char uctoa_append::value
char uctoa_append::value#0 // reg byte x 36667.33333333333
char uctoa_append::value#1 // reg byte x 2.0000002E7
char uctoa_append::value#2 // reg byte x 5018334.166666666
void ultoa(unsigned long value , char *buffer , char radix)
char ultoa::$10 // reg byte a 20002.0
char ultoa::$11 // reg byte a 2002.0
char *ultoa::buffer
char *ultoa::buffer#10 // buffer zp[2]:13 3000.4285714285716
char *ultoa::buffer#15 // buffer zp[2]:13 15001.5
char *ultoa::buffer#3 // buffer zp[2]:13 2002.0
char *ultoa::buffer#4 // buffer zp[2]:13 20002.0
char ultoa::digit
char ultoa::digit#1 // digit zp[1]:8 20002.0
char ultoa::digit#2 // digit zp[1]:8 2857.4285714285716
unsigned long ultoa::digit_value
unsigned long ultoa::digit_value#0 // digit_value zp[4]:37 6000.6
unsigned long *ultoa::digit_values
char ultoa::max_digits
char ultoa::radix
char ultoa::started
char ultoa::started#2 // reg byte x 5000.5
char ultoa::started#4 // reg byte x 10001.0
unsigned long ultoa::value
unsigned long ultoa::value#0 // value zp[4]:9 10001.0
unsigned long ultoa::value#10 // value zp[4]:9 1001.0
unsigned long ultoa::value#3 // value zp[4]:9 5857.857142857143
unsigned long ultoa::value#7 // value zp[4]:9 15001.5
unsigned long ultoa_append(char *buffer , unsigned long value , unsigned long sub)
char *ultoa_append::buffer
char *ultoa_append::buffer#0 // buffer zp[2]:13 13750.25
char ultoa_append::digit
char ultoa_append::digit#1 // reg byte x 1.0000001E7
char ultoa_append::digit#2 // reg byte x 1.00500015E7
unsigned long ultoa_append::return
unsigned long ultoa_append::return#0 // return zp[4]:9 20002.0
unsigned long ultoa_append::sub
unsigned long ultoa_append::sub#0 // sub zp[4]:37 3335000.5
unsigned long ultoa_append::value
unsigned long ultoa_append::value#0 // value zp[4]:9 36667.33333333333
unsigned long ultoa_append::value#1 // value zp[4]:9 2.0000002E7
unsigned long ultoa_append::value#2 // value zp[4]:9 5018334.166666666
void utoa(unsigned int value , char *buffer , char radix)
char utoa::$10 // reg byte a 20002.0
char utoa::$11 // reg byte x 2002.0
char utoa::$4 // reg byte a 20002.0
char *utoa::buffer
char *utoa::buffer#10 // buffer zp[2]:19 2800.4000000000005
char *utoa::buffer#15 // buffer zp[2]:19 15001.5
char *utoa::buffer#3 // buffer zp[2]:19 2002.0
char *utoa::buffer#4 // buffer zp[2]:19 20002.0
char utoa::digit
char utoa::digit#1 // digit zp[1]:3 20002.0
char utoa::digit#2 // digit zp[1]:3 2666.9333333333334
unsigned int utoa::digit_value
unsigned int utoa::digit_value#0 // digit_value zp[2]:34 6000.6
unsigned int *utoa::digit_values
unsigned int *utoa::digit_values#8 // digit_values zp[2]:13 588.2941176470588
char utoa::max_digits
char utoa::max_digits#7 // max_digits zp[1]:2 588.2941176470588
char utoa::radix
char utoa::radix#1 // reg byte x 202.0
char utoa::radix#2 // reg byte x 1026.25
char utoa::started
char utoa::started#2 // reg byte x 4286.142857142857
char utoa::started#4 // reg byte x 10001.0
unsigned int utoa::value
unsigned int utoa::value#0 // value zp[2]:6 10001.0
unsigned int utoa::value#10 // value zp[2]:6 183.66666666666669
unsigned int utoa::value#2 // value zp[2]:6 101.0
unsigned int utoa::value#3 // value zp[2]:6 5125.625
unsigned int utoa::value#7 // value zp[2]:6 15001.5
unsigned int utoa_append(char *buffer , unsigned int value , unsigned int sub)
char *utoa_append::buffer
char *utoa_append::buffer#0 // buffer zp[2]:19 13750.25
char utoa_append::digit
char utoa_append::digit#1 // reg byte x 1.0000001E7
char utoa_append::digit#2 // reg byte x 1.00500015E7
unsigned int utoa_append::return
unsigned int utoa_append::return#0 // return zp[2]:6 20002.0
unsigned int utoa_append::sub
unsigned int utoa_append::sub#0 // sub zp[2]:34 3335000.5
unsigned int utoa_append::value
unsigned int utoa_append::value#0 // value zp[2]:6 36667.33333333333
unsigned int utoa_append::value#1 // value zp[2]:6 2.0000002E7
unsigned int utoa_append::value#2 // value zp[2]:6 5018334.166666666
reg byte x [ conio_c64_init::line#2 conio_c64_init::line#0 ]
reg byte x [ gotoxy::y#4 gotoxy::y#2 ]
reg byte x [ clrscr::l#2 clrscr::l#1 ]
reg byte y [ clrscr::c#2 clrscr::c#1 ]
reg byte a [ cputc::c#5 cputc::c#0 cputc::c#3 cputc::c#2 cputc::c#1 ]
zp[2]:2 [ printf_uint::uvalue#2 utoa::value#3 utoa::value#7 utoa::value#10 utoa::value#2 utoa::value#0 utoa_append::value#2 utoa_append::value#0 utoa_append::value#1 utoa_append::return#0 clrscr::line_cols#5 clrscr::line_cols#1 ]
reg byte x [ printf_uint::format_radix#2 ]
reg byte x [ utoa::radix#2 utoa::radix#1 ]
reg byte x [ utoa::started#2 utoa::started#4 ]
reg byte x [ printf_number_buffer::format_min_length#10 ]
zp[1]:4 [ printf_number_buffer::format_justify_left#10 utoa::max_digits#7 ]
zp[1]:5 [ printf_number_buffer::format_zero_padding#10 utoa::digit#2 utoa::digit#1 ]
zp[1]:2 [ printf_number_buffer::format_justify_left#10 utoa::max_digits#7 ]
zp[1]:3 [ printf_number_buffer::format_zero_padding#10 utoa::digit#2 utoa::digit#1 ]
reg byte y [ printf_number_buffer::len#2 printf_number_buffer::len#0 printf_number_buffer::len#1 ]
zp[1]:6 [ uctoa::digit#2 uctoa::digit#1 printf_number_buffer::buffer_sign#10 printf_number_buffer::buffer_sign#4 printf_number_buffer::buffer_sign#2 printf_number_buffer::buffer_sign#0 printf_number_buffer::buffer_sign#5 printf_number_buffer::buffer_sign#3 printf_number_buffer::buffer_sign#1 ]
zp[1]:4 [ uctoa::digit#2 uctoa::digit#1 printf_number_buffer::buffer_sign#10 printf_number_buffer::buffer_sign#4 printf_number_buffer::buffer_sign#2 printf_number_buffer::buffer_sign#0 printf_number_buffer::buffer_sign#5 printf_number_buffer::buffer_sign#3 printf_number_buffer::buffer_sign#1 ]
reg byte x [ uctoa::value#3 uctoa::value#7 uctoa::value#10 uctoa::value#0 ]
zp[1]:7 [ uctoa::started#2 uctoa::started#4 printf_number_buffer::format_upper_case#10 ]
zp[2]:8 [ uctoa::buffer#10 uctoa::buffer#15 uctoa::buffer#4 uctoa::buffer#3 uctoa_append::buffer#0 utoa::digit_values#8 cputs::s#20 cputs::s#21 cputs::s#0 clrscr::line_text#5 clrscr::line_text#1 ]
zp[1]:10 [ ultoa::digit#2 ultoa::digit#1 printf_number_buffer::padding#10 printf_number_buffer::padding#1 ]
zp[4]:11 [ ultoa::value#3 ultoa::value#7 ultoa::value#10 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ]
zp[1]:5 [ uctoa::started#2 uctoa::started#4 printf_number_buffer::format_upper_case#10 ]
zp[2]:6 [ uctoa::buffer#10 uctoa::buffer#15 uctoa::buffer#4 uctoa::buffer#3 uctoa_append::buffer#0 printf_uint::uvalue#2 utoa::value#3 utoa::value#7 utoa::value#10 utoa::value#2 utoa::value#0 utoa_append::value#2 utoa_append::value#0 utoa_append::value#1 utoa_append::return#0 printf_str::putc#21 printf_str::putc#0 printf_number_buffer::putc#10 printf_padding::putc#5 printf_padding::putc#1 printf_padding::putc#2 printf_padding::putc#0 clrscr::line_text#5 clrscr::line_text#1 ]
zp[1]:8 [ ultoa::digit#2 ultoa::digit#1 printf_number_buffer::padding#10 printf_number_buffer::padding#1 ]
zp[4]:9 [ ultoa::value#3 ultoa::value#7 ultoa::value#10 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ]
reg byte x [ ultoa::started#2 ultoa::started#4 ]
zp[2]:13 [ ultoa::buffer#10 ultoa::buffer#15 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 utoa::digit_values#8 printf_str::s#20 printf_str::s#21 printf_str::s#0 clrscr::line_cols#5 clrscr::line_cols#1 ]
zp[2]:15 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
reg byte x [ memset::c#4 ]
reg byte x [ utoa_append::digit#2 utoa_append::digit#1 ]
zp[1]:15 [ printf_padding::pad#5 ]
zp[1]:16 [ printf_padding::i#2 printf_padding::i#1 ]
zp[1]:17 [ printf_padding::pad#5 ]
zp[1]:18 [ printf_padding::i#2 printf_padding::i#1 ]
zp[2]:19 [ strupr::src#2 strupr::src#1 strlen::str#2 strlen::str#0 utoa::buffer#10 utoa::buffer#15 utoa::buffer#4 utoa::buffer#3 utoa_append::buffer#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 ]
reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ]
reg byte x [ memset::c#4 ]
reg byte a [ toupper::return#2 toupper::return#0 toupper::ch#0 ]
zp[1]:17 [ conio_cursor_x ]
zp[1]:18 [ conio_cursor_y ]
zp[2]:19 [ conio_line_text ]
zp[2]:21 [ conio_line_color ]
zp[1]:23 [ main::c ]
zp[2]:24 [ gotoxy::$7 gotoxy::$9 gotoxy::line_offset#0 gotoxy::$6 ]
zp[2]:26 [ gotoxy::$8 ]
zp[2]:28 [ gotoxy::$5 ]
reg byte a [ cputs::c#1 ]
zp[1]:21 [ conio_cursor_x ]
zp[1]:22 [ conio_cursor_y ]
zp[2]:23 [ conio_line_text ]
zp[2]:25 [ conio_line_color ]
reg byte a [ cputc::c#0 ]
zp[1]:27 [ main::c ]
zp[2]:28 [ gotoxy::$7 gotoxy::$9 gotoxy::line_offset#0 gotoxy::$6 ]
zp[2]:30 [ gotoxy::$8 ]
zp[2]:32 [ gotoxy::$5 ]
reg byte a [ printf_str::c#1 ]
reg byte a [ utoa::$4 ]
reg byte x [ utoa::$11 ]
reg byte a [ utoa::$10 ]
zp[2]:30 [ utoa::digit_value#0 utoa_append::sub#0 strlen::len#2 strlen::len#1 strlen::return#2 printf_number_buffer::$19 memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
zp[1]:32 [ uctoa::digit_value#0 uctoa_append::sub#0 printf_padding::length#4 printf_padding::length#1 printf_padding::length#2 printf_padding::length#0 ]
zp[2]:34 [ utoa::digit_value#0 utoa_append::sub#0 strlen::len#2 strlen::len#1 strlen::return#2 printf_number_buffer::$19 ]
zp[1]:36 [ uctoa::digit_value#0 uctoa_append::sub#0 printf_padding::length#4 printf_padding::length#1 printf_padding::length#2 printf_padding::length#0 ]
reg byte x [ uctoa_append::return#0 ]
reg byte a [ ultoa::$11 ]
reg byte a [ ultoa::$10 ]
zp[4]:33 [ ultoa::digit_value#0 ultoa_append::sub#0 ]
zp[4]:37 [ ultoa::digit_value#0 ultoa_append::sub#0 ]
zp[2]:41 [ memcpy::src_end#0 ]
zp[2]:43 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
reg byte a [ toupper::return#3 ]
reg byte a [ strupr::$0 ]
zp[2]:37 [ memcpy::src_end#0 strupr::src#2 strupr::src#1 strlen::str#2 strlen::str#0 ultoa::buffer#10 ultoa::buffer#15 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 utoa::buffer#10 utoa::buffer#15 utoa::buffer#4 utoa::buffer#3 utoa_append::buffer#0 ]
zp[2]:39 [ memset::end#0 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
mem[12] [ printf_buffer ]

871
src/test/ref/printf-17.asm Normal file
View File

@ -0,0 +1,871 @@
// Tests snprintf function call rewriting
// Test simple formats
// Commodore 64 PRG executable file
.file [name="printf-17.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(__start)
.const BINARY = 2
.const OCTAL = 8
.const DECIMAL = $a
.const HEXADECIMAL = $10
.const OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
.const STACK_BASE = $103
.const SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
/// The capacity of the buffer (n passed to snprintf())
/// Used to hold state while printing
.label __snprintf_capacity = $12
// The number of chars that would have been filled when printing without capacity. Grows even after size>capacity.
/// Used to hold state while printing
.label __snprintf_size = $14
/// Current position in the buffer being filled ( initially *s passed to snprintf()
/// Used to hold state while printing
.label __snprintf_buffer = $16
.label screen = 2
.segment Code
__start: {
// volatile size_t __snprintf_capacity
lda #<0
sta.z __snprintf_capacity
sta.z __snprintf_capacity+1
// volatile size_t __snprintf_size
sta.z __snprintf_size
sta.z __snprintf_size+1
// char * __snprintf_buffer
sta.z __snprintf_buffer
sta.z __snprintf_buffer+1
jsr main
rts
}
/// Print a character into snprintf buffer
/// Used by snprintf()
/// @param c The character to print
// void snputc(__register(X) char c)
snputc: {
.const OFFSET_STACK_C = 0
tsx
lda STACK_BASE+OFFSET_STACK_C,x
tax
// ++__snprintf_size;
inc.z __snprintf_size
bne !+
inc.z __snprintf_size+1
!:
// if(__snprintf_size > __snprintf_capacity)
lda.z __snprintf_capacity+1
cmp.z __snprintf_size+1
bcc !+
bne __b1
lda.z __snprintf_capacity
cmp.z __snprintf_size
bcs __b1
!:
// }
rts
__b1:
// if(__snprintf_size==__snprintf_capacity)
lda.z __snprintf_size+1
cmp.z __snprintf_capacity+1
bne __b2
lda.z __snprintf_size
cmp.z __snprintf_capacity
bne __b2
ldx #0
__b2:
// *(__snprintf_buffer++) = c
// Append char
txa
ldy #0
sta (__snprintf_buffer),y
// *(__snprintf_buffer++) = c;
inc.z __snprintf_buffer
bne !+
inc.z __snprintf_buffer+1
!:
rts
}
main: {
// snprintf(BUF, 20, "hello world! ")
lda #<$14
sta.z snprintf_init.n
lda #>$14
sta.z snprintf_init.n+1
jsr snprintf_init
// snprintf(BUF, 20, "hello world! ")
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s
sta.z printf_str.s
lda #>s
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 20, "hello world! ")
lda #0
pha
jsr snputc
pla
// print(BUF)
lda #<$400
sta.z screen
lda #>$400
sta.z screen+1
jsr print
// snprintf(BUF, 20, "hello %s%c ", "world", '!')
lda #<$14
sta.z snprintf_init.n
lda #>$14
sta.z snprintf_init.n+1
jsr snprintf_init
// snprintf(BUF, 20, "hello %s%c ", "world", '!')
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s1
sta.z printf_str.s
lda #>s1
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 20, "hello %s%c ", "world", '!')
jsr printf_string
// snprintf(BUF, 20, "hello %s%c ", "world", '!')
lda #'!'
pha
jsr snputc
pla
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s2
sta.z printf_str.s
lda #>s2
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 20, "hello %s%c ", "world", '!')
lda #0
pha
jsr snputc
pla
// print(BUF)
jsr print
// snprintf(BUF, 20, "hello %d+%x! ", 3,11)
lda #<$14
sta.z snprintf_init.n
lda #>$14
sta.z snprintf_init.n+1
jsr snprintf_init
// snprintf(BUF, 20, "hello %d+%x! ", 3,11)
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s1
sta.z printf_str.s
lda #>s1
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 20, "hello %d+%x! ", 3,11)
lda #<3
sta.z printf_sint.value
lda #>3
sta.z printf_sint.value+1
jsr printf_sint
// snprintf(BUF, 20, "hello %d+%x! ", 3,11)
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s4
sta.z printf_str.s
lda #>s4
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 20, "hello %d+%x! ", 3,11)
jsr printf_uint
// snprintf(BUF, 20, "hello %d+%x! ", 3,11)
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s5
sta.z printf_str.s
lda #>s5
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 20, "hello %d+%x! ", 3,11)
lda #0
pha
jsr snputc
pla
// print(BUF)
jsr print
// snprintf(BUF, 6, "hi %d! ", 22222)
lda #<6
sta.z snprintf_init.n
lda #>6
sta.z snprintf_init.n+1
jsr snprintf_init
// snprintf(BUF, 6, "hi %d! ", 22222)
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s6
sta.z printf_str.s
lda #>s6
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 6, "hi %d! ", 22222)
lda #<$56ce
sta.z printf_sint.value
lda #>$56ce
sta.z printf_sint.value+1
jsr printf_sint
// snprintf(BUF, 6, "hi %d! ", 22222)
lda #<snputc
sta.z printf_str.putc
lda #>snputc
sta.z printf_str.putc+1
lda #<s5
sta.z printf_str.s
lda #>s5
sta.z printf_str.s+1
jsr printf_str
// snprintf(BUF, 6, "hi %d! ", 22222)
lda #0
pha
jsr snputc
pla
// print(BUF)
jsr print
// }
rts
.segment Data
s: .text "hello world! "
.byte 0
s1: .text "hello "
.byte 0
str: .text "world"
.byte 0
s2: .text " "
.byte 0
s4: .text "+"
.byte 0
s5: .text "! "
.byte 0
s6: .text "hi "
.byte 0
}
.segment Code
/// Initialize the snprintf() state
// void snprintf_init(char *s, __zp(4) unsigned int n)
snprintf_init: {
.label n = 4
// __snprintf_capacity = n
lda.z n
sta.z __snprintf_capacity
lda.z n+1
sta.z __snprintf_capacity+1
// __snprintf_size = 0
lda #<0
sta.z __snprintf_size
sta.z __snprintf_size+1
// __snprintf_buffer = s
lda #<BUF
sta.z __snprintf_buffer
lda #>BUF
sta.z __snprintf_buffer+1
// }
rts
}
/// Print a NUL-terminated string
// void printf_str(__zp(4) void (*putc)(char), __zp($b) const char *s)
printf_str: {
.label s = $b
.label putc = 4
__b1:
// while(c=*s++)
ldy #0
lda (s),y
inc.z s
bne !+
inc.z s+1
!:
cmp #0
bne __b2
// }
rts
__b2:
// putc(c)
pha
jsr icall6
pla
jmp __b1
icall6:
jmp (putc)
}
// void print(__zp($b) char *msg)
print: {
.label msg = $b
lda #<BUF
sta.z msg
lda #>BUF
sta.z msg+1
__b1:
// while(*msg)
ldy #0
lda (msg),y
cmp #0
bne __b2
// }
rts
__b2:
// *(screen++) = *(msg++)
ldy #0
lda (msg),y
sta (screen),y
// *(screen++) = *(msg++);
inc.z screen
bne !+
inc.z screen+1
!:
inc.z msg
bne !+
inc.z msg+1
!:
jmp __b1
}
// Print a string value using a specific format
// Handles justification and min length
// void printf_string(void (*putc)(char), char *str, char format_min_length, char format_justify_left)
printf_string: {
.label putc = snputc
// printf_str(putc, str)
lda #<putc
sta.z printf_str.putc
lda #>putc
sta.z printf_str.putc+1
lda #<main.str
sta.z printf_str.s
lda #>main.str
sta.z printf_str.s+1
jsr printf_str
// }
rts
}
// Print a signed integer using a specific format
// void printf_sint(void (*putc)(char), __zp(4) int value, char format_min_length, char format_justify_left, char format_sign_always, char format_zero_padding, char format_upper_case, char format_radix)
printf_sint: {
.label value = 4
// printf_buffer.sign = 0
// Handle any sign
lda #0
sta printf_buffer
// if(value<0)
lda.z value+1
bmi __b1
jmp __b2
__b1:
// value = -value
lda #0
sec
sbc.z value
sta.z value
lda #0
sbc.z value+1
sta.z value+1
// printf_buffer.sign = '-'
lda #'-'
sta printf_buffer
__b2:
// utoa(uvalue, printf_buffer.digits, format.radix)
ldx #DECIMAL
jsr utoa
// printf_number_buffer(putc, printf_buffer, format)
lda printf_buffer
sta.z printf_number_buffer.buffer_sign
// Print using format
lda #0
sta.z printf_number_buffer.format_upper_case
lda #<snputc
sta.z printf_number_buffer.putc
lda #>snputc
sta.z printf_number_buffer.putc+1
lda #0
sta.z printf_number_buffer.format_zero_padding
sta.z printf_number_buffer.format_justify_left
tax
jsr printf_number_buffer
// }
rts
}
// Print an unsigned int using a specific format
// void printf_uint(void (*putc)(char), unsigned int uvalue, char format_min_length, char format_justify_left, char format_sign_always, char format_zero_padding, char format_upper_case, char format_radix)
printf_uint: {
.const uvalue = $b
.const format_min_length = 0
.const format_justify_left = 0
.const format_zero_padding = 0
.const format_upper_case = 0
.label putc = snputc
// printf_buffer.sign = format.sign_always?'+':0
// Handle any sign
lda #0
sta printf_buffer
// utoa(uvalue, printf_buffer.digits, format.radix)
// Format number into buffer
lda #<uvalue
sta.z utoa.value
lda #>uvalue
sta.z utoa.value+1
ldx #HEXADECIMAL
jsr utoa
// printf_number_buffer(putc, printf_buffer, format)
lda printf_buffer
sta.z printf_number_buffer.buffer_sign
// Print using format
lda #format_upper_case
sta.z printf_number_buffer.format_upper_case
lda #<putc
sta.z printf_number_buffer.putc
lda #>putc
sta.z printf_number_buffer.putc+1
lda #format_zero_padding
sta.z printf_number_buffer.format_zero_padding
lda #format_justify_left
sta.z printf_number_buffer.format_justify_left
ldx #format_min_length
jsr printf_number_buffer
// }
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)
// void utoa(__zp(4) unsigned int value, __zp($d) char *buffer, __register(X) char radix)
utoa: {
.label digit_value = $18
.label buffer = $d
.label digit = 7
.label value = 4
.label max_digits = 6
.label digit_values = $b
// if(radix==DECIMAL)
cpx #DECIMAL
beq __b2
// if(radix==HEXADECIMAL)
cpx #HEXADECIMAL
beq __b3
// if(radix==OCTAL)
cpx #OCTAL
beq __b4
// if(radix==BINARY)
cpx #BINARY
beq __b5
// *buffer++ = 'e'
// Unknown radix
lda #'e'
sta printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
// *buffer++ = 'r'
lda #'r'
sta printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS+1
sta printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS+2
// *buffer = 0
lda #0
sta printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS+3
// }
rts
__b2:
lda #<RADIX_DECIMAL_VALUES
sta.z digit_values
lda #>RADIX_DECIMAL_VALUES
sta.z digit_values+1
lda #5
sta.z max_digits
jmp __b1
__b3:
lda #<RADIX_HEXADECIMAL_VALUES
sta.z digit_values
lda #>RADIX_HEXADECIMAL_VALUES
sta.z digit_values+1
lda #4
sta.z max_digits
jmp __b1
__b4:
lda #<RADIX_OCTAL_VALUES
sta.z digit_values
lda #>RADIX_OCTAL_VALUES
sta.z digit_values+1
lda #6
sta.z max_digits
jmp __b1
__b5:
lda #<RADIX_BINARY_VALUES
sta.z digit_values
lda #>RADIX_BINARY_VALUES
sta.z digit_values+1
lda #$10
sta.z max_digits
__b1:
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
ldx #0
txa
sta.z digit
__b6:
// max_digits-1
lda.z max_digits
sec
sbc #1
// for( char digit=0; digit<max_digits-1; digit++ )
cmp.z digit
beq !+
bcs __b7
!:
// *buffer++ = DIGITS[(char)value]
ldx.z 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
__b7:
// unsigned int digit_value = digit_values[digit]
lda.z digit
asl
tay
lda (digit_values),y
sta.z digit_value
iny
lda (digit_values),y
sta.z digit_value+1
// if (started || value >= digit_value)
cpx #0
bne __b10
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b10
lda.z value
cmp.z digit_value
bcs __b10
!:
__b9:
// for( char digit=0; digit<max_digits-1; digit++ )
inc.z digit
jmp __b6
__b10:
// utoa_append(buffer++, value, digit_value)
jsr utoa_append
// utoa_append(buffer++, value, digit_value)
// value = utoa_append(buffer++, value, digit_value)
// value = utoa_append(buffer++, value, digit_value);
inc.z buffer
bne !+
inc.z buffer+1
!:
ldx #1
jmp __b9
}
// Print the contents of the number buffer using a specific format.
// This handles minimum length, zero-filling, and left/right justification from the format
// void printf_number_buffer(__zp(4) void (*putc)(char), __zp(8) char buffer_sign, char *buffer_digits, __register(X) char format_min_length, __zp(6) char format_justify_left, char format_sign_always, __zp(7) char format_zero_padding, __zp(9) char format_upper_case, char format_radix)
printf_number_buffer: {
.label __19 = $d
.label buffer_sign = 8
.label padding = $a
.label putc = 4
.label format_zero_padding = 7
.label format_justify_left = 6
.label format_upper_case = 9
// if(format.min_length)
cpx #0
beq __b6
// strlen(buffer.digits)
jsr strlen
// strlen(buffer.digits)
// signed char len = (signed char)strlen(buffer.digits)
// There is a minimum length - work out the padding
ldy.z __19
// if(buffer.sign)
lda.z buffer_sign
beq __b13
// len++;
iny
__b13:
// padding = (signed char)format.min_length - len
txa
sty.z $ff
sec
sbc.z $ff
sta.z padding
// if(padding<0)
cmp #0
bpl __b1
__b6:
lda #0
sta.z padding
__b1:
// if(!format.justify_left && !format.zero_padding && padding)
lda.z format_justify_left
bne __b2
lda.z format_zero_padding
bne __b2
lda.z padding
cmp #0
bne __b8
jmp __b2
__b8:
// printf_padding(putc, ' ',(char)padding)
lda.z padding
sta.z printf_padding.length
lda #' '
sta.z printf_padding.pad
jsr printf_padding
__b2:
// if(buffer.sign)
lda.z buffer_sign
beq __b3
// putc(buffer.sign)
pha
jsr icall7
pla
__b3:
// if(format.zero_padding && padding)
lda.z format_zero_padding
beq __b4
lda.z padding
cmp #0
bne __b10
jmp __b4
__b10:
// printf_padding(putc, '0',(char)padding)
lda.z padding
sta.z printf_padding.length
lda #'0'
sta.z printf_padding.pad
jsr printf_padding
__b4:
// if(format.upper_case)
lda.z format_upper_case
beq __b5
// strupr(buffer.digits)
jsr strupr
__b5:
// printf_str(putc, buffer.digits)
lda #<printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
sta.z printf_str.s
lda #>printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
sta.z printf_str.s+1
jsr printf_str
// if(format.justify_left && !format.zero_padding && padding)
lda.z format_justify_left
beq __breturn
lda.z format_zero_padding
bne __breturn
lda.z padding
cmp #0
bne __b12
rts
__b12:
// printf_padding(putc, ' ',(char)padding)
lda.z padding
sta.z printf_padding.length
lda #' '
sta.z printf_padding.pad
jsr printf_padding
__breturn:
// }
rts
icall7:
jmp (putc)
}
// 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.
// __zp(4) unsigned int utoa_append(__zp($d) char *buffer, __zp(4) unsigned int value, __zp($18) unsigned int sub)
utoa_append: {
.label buffer = $d
.label value = 4
.label sub = $18
.label return = 4
ldx #0
__b1:
// while (value >= sub)
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
// *buffer = DIGITS[digit]
lda DIGITS,x
ldy #0
sta (buffer),y
// }
rts
__b2:
// digit++;
inx
// value -= sub
lda.z value
sec
sbc.z sub
sta.z value
lda.z value+1
sbc.z sub+1
sta.z value+1
jmp __b1
}
// Computes the length of the string str up to but not including the terminating null character.
// __zp($d) unsigned int strlen(__zp($b) char *str)
strlen: {
.label len = $d
.label str = $b
.label return = $d
lda #<0
sta.z len
sta.z len+1
lda #<printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
sta.z str
lda #>printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
sta.z str+1
__b1:
// while(*str)
ldy #0
lda (str),y
cmp #0
bne __b2
// }
rts
__b2:
// len++;
inc.z len
bne !+
inc.z len+1
!:
// str++;
inc.z str
bne !+
inc.z str+1
!:
jmp __b1
}
// Print a padding char a number of times
// void printf_padding(__zp(4) void (*putc)(char), __zp($10) char pad, __zp($f) char length)
printf_padding: {
.label i = $11
.label putc = 4
.label length = $f
.label pad = $10
lda #0
sta.z i
__b1:
// for(char i=0;i<length; i++)
lda.z i
cmp.z length
bcc __b2
// }
rts
__b2:
// putc(pad)
lda.z pad
pha
jsr icall8
pla
// for(char i=0;i<length; i++)
inc.z i
jmp __b1
icall8:
jmp (putc)
}
// Converts a string to uppercase.
// char * strupr(char *str)
strupr: {
.label str = printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS
.label src = $18
lda #<str
sta.z src
lda #>str
sta.z src+1
__b1:
// while(*src)
ldy #0
lda (src),y
cmp #0
bne __b2
// }
rts
__b2:
// toupper(*src)
ldy #0
lda (src),y
jsr toupper
// *src = toupper(*src)
ldy #0
sta (src),y
// src++;
inc.z src
bne !+
inc.z src+1
!:
jmp __b1
}
// Convert lowercase alphabet to uppercase
// Returns uppercase equivalent to c, if such value exists, else c remains unchanged
// __register(A) char toupper(__register(A) char ch)
toupper: {
// if(ch>='a' && ch<='z')
cmp #'a'
bcc __breturn
cmp #'z'
bcc __b1
beq __b1
rts
__b1:
// return ch + ('A'-'a');
clc
adc #'A'-'a'
__breturn:
// }
rts
}
.segment Data
// The digits used for numbers
DIGITS: .text "0123456789abcdef"
// Values of binary digits
RADIX_BINARY_VALUES: .word $8000, $4000, $2000, $1000, $800, $400, $200, $100, $80, $40, $20, $10, 8, 4, 2
// Values of octal digits
RADIX_OCTAL_VALUES: .word $8000, $1000, $200, $40, 8
// Values of decimal digits
RADIX_DECIMAL_VALUES: .word $2710, $3e8, $64, $a
// Values of hexadecimal digits
RADIX_HEXADECIMAL_VALUES: .word $1000, $100, $10
BUF: .fill $14, 0
// Buffer used for stringified number being printed
printf_buffer: .fill SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER, 0

491
src/test/ref/printf-17.cfg Normal file
View File

@ -0,0 +1,491 @@
void __start()
__start: scope:[__start] from
[0] phi()
to:__start::__init1
__start::__init1: scope:[__start] from __start
[1] __snprintf_capacity = 0
[2] __snprintf_size = 0
[3] __snprintf_buffer = (char *) 0
to:__start::@1
__start::@1: scope:[__start] from __start::__init1
[4] phi()
[5] call main
to:__start::@return
__start::@return: scope:[__start] from __start::@1
[6] return
to:@return
__stackcall void snputc(char c)
snputc: scope:[snputc] from
[7] snputc::c#0 = stackidx(char,snputc::OFFSET_STACK_C)
[8] __snprintf_size = ++ __snprintf_size
[9] if(__snprintf_size<=__snprintf_capacity) goto snputc::@1
to:snputc::@return
snputc::@return: scope:[snputc] from snputc snputc::@2
[10] return
to:@return
snputc::@1: scope:[snputc] from snputc
[11] if(__snprintf_size!=__snprintf_capacity) goto snputc::@3
to:snputc::@2
snputc::@3: scope:[snputc] from snputc::@1
[12] phi()
to:snputc::@2
snputc::@2: scope:[snputc] from snputc::@1 snputc::@3
[13] snputc::c#2 = phi( snputc::@3/snputc::c#0, snputc::@1/0 )
[14] *__snprintf_buffer = snputc::c#2
[15] __snprintf_buffer = ++ __snprintf_buffer
to:snputc::@return
void main()
main: scope:[main] from __start::@1
[16] phi()
[17] call snprintf_init
to:main::@1
main::@1: scope:[main] from main
[18] phi()
[19] call printf_str
to:main::@2
main::@2: scope:[main] from main::@1
[20] stackpush(char) = 0
[21] callexecute snputc
sideeffect stackpullbytes(1)
[23] call print
to:main::@3
main::@3: scope:[main] from main::@2
[24] phi()
[25] call snprintf_init
to:main::@4
main::@4: scope:[main] from main::@3
[26] phi()
[27] call printf_str
to:main::@5
main::@5: scope:[main] from main::@4
[28] phi()
[29] call printf_string
to:main::@6
main::@6: scope:[main] from main::@5
[30] stackpush(char) = '!'
[31] callexecute snputc
sideeffect stackpullbytes(1)
[33] call printf_str
to:main::@7
main::@7: scope:[main] from main::@6
[34] stackpush(char) = 0
[35] callexecute snputc
sideeffect stackpullbytes(1)
[37] call print
to:main::@8
main::@8: scope:[main] from main::@7
[38] phi()
[39] call snprintf_init
to:main::@9
main::@9: scope:[main] from main::@8
[40] phi()
[41] call printf_str
to:main::@10
main::@10: scope:[main] from main::@9
[42] phi()
[43] call printf_sint
to:main::@11
main::@11: scope:[main] from main::@10
[44] phi()
[45] call printf_str
to:main::@12
main::@12: scope:[main] from main::@11
[46] phi()
[47] call printf_uint
to:main::@13
main::@13: scope:[main] from main::@12
[48] phi()
[49] call printf_str
to:main::@14
main::@14: scope:[main] from main::@13
[50] stackpush(char) = 0
[51] callexecute snputc
sideeffect stackpullbytes(1)
[53] call print
to:main::@15
main::@15: scope:[main] from main::@14
[54] phi()
[55] call snprintf_init
to:main::@16
main::@16: scope:[main] from main::@15
[56] phi()
[57] call printf_str
to:main::@17
main::@17: scope:[main] from main::@16
[58] phi()
[59] call printf_sint
to:main::@18
main::@18: scope:[main] from main::@17
[60] phi()
[61] call printf_str
to:main::@19
main::@19: scope:[main] from main::@18
[62] stackpush(char) = 0
[63] callexecute snputc
sideeffect stackpullbytes(1)
[65] call print
to:main::@return
main::@return: scope:[main] from main::@19
[66] return
to:@return
void snprintf_init(char *s , unsigned int n)
snprintf_init: scope:[snprintf_init] from main main::@15 main::@3 main::@8
[67] snprintf_init::n#4 = phi( main/$14, main::@15/6, main::@3/$14, main::@8/$14 )
[68] __snprintf_capacity = snprintf_init::n#4
[69] __snprintf_size = 0
[70] __snprintf_buffer = BUF
to:snprintf_init::@return
snprintf_init::@return: scope:[snprintf_init] from snprintf_init
[71] return
to:@return
void printf_str(void (*putc)(char) , const char *s)
printf_str: scope:[printf_str] from main::@1 main::@11 main::@13 main::@16 main::@18 main::@4 main::@6 main::@9 printf_number_buffer::@5 printf_string::@1
[72] printf_str::putc#12 = phi( main::@1/&snputc, main::@11/&snputc, main::@13/&snputc, main::@16/&snputc, main::@18/&snputc, main::@4/&snputc, main::@6/&snputc, main::@9/&snputc, printf_number_buffer::@5/printf_str::putc#0, printf_string::@1/printf_string::putc#0 )
[72] printf_str::s#12 = phi( main::@1/main::s, main::@11/main::s4, main::@13/main::s5, main::@16/main::s6, main::@18/main::s5, main::@4/main::s1, main::@6/main::s2, main::@9/main::s1, printf_number_buffer::@5/(char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS, printf_string::@1/main::str )
to:printf_str::@1
printf_str::@1: scope:[printf_str] from printf_str printf_str::@2
[73] printf_str::s#11 = phi( printf_str/printf_str::s#12, printf_str::@2/printf_str::s#0 )
[74] printf_str::c#1 = *printf_str::s#11
[75] printf_str::s#0 = ++ printf_str::s#11
[76] if(0!=printf_str::c#1) goto printf_str::@2
to:printf_str::@return
printf_str::@return: scope:[printf_str] from printf_str::@1
[77] return
to:@return
printf_str::@2: scope:[printf_str] from printf_str::@1
[78] stackpush(char) = printf_str::c#1
[79] callexecute *printf_str::putc#12
sideeffect stackpullbytes(1)
to:printf_str::@1
void print(char *msg)
print: scope:[print] from main::@14 main::@19 main::@2 main::@7
[81] screen#25 = phi( main::@14/screen#1, main::@19/screen#1, main::@2/(char *) 1024, main::@7/screen#1 )
to:print::@1
print::@1: scope:[print] from print print::@2
[82] screen#1 = phi( print/screen#25, print::@2/screen#0 )
[82] print::msg#5 = phi( print/BUF, print::@2/print::msg#0 )
[83] if(0!=*print::msg#5) goto print::@2
to:print::@return
print::@return: scope:[print] from print::@1
[84] return
to:@return
print::@2: scope:[print] from print::@1
[85] *screen#1 = *print::msg#5
[86] screen#0 = ++ screen#1
[87] print::msg#0 = ++ print::msg#5
to:print::@1
void printf_string(void (*putc)(char) , char *str , char format_min_length , char format_justify_left)
printf_string: scope:[printf_string] from main::@5
[88] phi()
to:printf_string::@1
printf_string::@1: scope:[printf_string] from printf_string
[89] phi()
[90] call printf_str
to:printf_string::@return
printf_string::@return: scope:[printf_string] from printf_string::@1
[91] return
to:@return
void printf_sint(void (*putc)(char) , int value , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
printf_sint: scope:[printf_sint] from main::@10 main::@17
[92] printf_sint::value#3 = phi( main::@10/3, main::@17/$56ce )
[93] *((char *)&printf_buffer) = 0
[94] if(printf_sint::value#3<0) goto printf_sint::@1
to:printf_sint::@2
printf_sint::@1: scope:[printf_sint] from printf_sint
[95] printf_sint::value#0 = - printf_sint::value#3
[96] *((char *)&printf_buffer) = '-'
to:printf_sint::@2
printf_sint::@2: scope:[printf_sint] from printf_sint printf_sint::@1
[97] printf_sint::value#5 = phi( printf_sint::@1/printf_sint::value#0, printf_sint/printf_sint::value#3 )
[98] utoa::value#1 = (unsigned int)printf_sint::value#5
[99] call utoa
to:printf_sint::@3
printf_sint::@3: scope:[printf_sint] from printf_sint::@2
[100] printf_number_buffer::buffer_sign#0 = *((char *)&printf_buffer)
[101] call printf_number_buffer
to:printf_sint::@return
printf_sint::@return: scope:[printf_sint] from printf_sint::@3
[102] return
to:@return
void printf_uint(void (*putc)(char) , unsigned int uvalue , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
printf_uint: scope:[printf_uint] from main::@12
[103] phi()
to:printf_uint::@1
printf_uint::@1: scope:[printf_uint] from printf_uint
[104] *((char *)&printf_buffer) = 0
[105] call utoa
to:printf_uint::@2
printf_uint::@2: scope:[printf_uint] from printf_uint::@1
[106] printf_number_buffer::buffer_sign#1 = *((char *)&printf_buffer)
[107] call printf_number_buffer
to:printf_uint::@return
printf_uint::@return: scope:[printf_uint] from printf_uint::@2
[108] return
to:@return
void utoa(unsigned int value , char *buffer , char radix)
utoa: scope:[utoa] from printf_sint::@2 printf_uint::@1
[109] utoa::value#10 = phi( printf_sint::@2/utoa::value#1, printf_uint::@1/printf_uint::uvalue#0 )
[109] utoa::radix#2 = phi( printf_sint::@2/DECIMAL, printf_uint::@1/HEXADECIMAL )
[110] if(utoa::radix#2==DECIMAL) goto utoa::@1
to:utoa::@2
utoa::@2: scope:[utoa] from utoa
[111] if(utoa::radix#2==HEXADECIMAL) goto utoa::@1
to:utoa::@3
utoa::@3: scope:[utoa] from utoa::@2
[112] if(utoa::radix#2==OCTAL) goto utoa::@1
to:utoa::@4
utoa::@4: scope:[utoa] from utoa::@3
[113] if(utoa::radix#2==BINARY) goto utoa::@1
to:utoa::@5
utoa::@5: scope:[utoa] from utoa::@4
[114] *((char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS) = 'e'
[115] *((char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS+1) = 'r'
[116] *((char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS+2) = 'r'
[117] *((char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS+3) = 0
to:utoa::@return
utoa::@return: scope:[utoa] from utoa::@5 utoa::@8
[118] return
to:@return
utoa::@1: scope:[utoa] from utoa utoa::@2 utoa::@3 utoa::@4
[119] utoa::digit_values#8 = phi( utoa/RADIX_DECIMAL_VALUES, utoa::@2/RADIX_HEXADECIMAL_VALUES, utoa::@3/RADIX_OCTAL_VALUES, utoa::@4/RADIX_BINARY_VALUES )
[119] utoa::max_digits#7 = phi( utoa/5, utoa::@2/4, utoa::@3/6, utoa::@4/$10 )
to:utoa::@6
utoa::@6: scope:[utoa] from utoa::@1 utoa::@9
[120] utoa::buffer#10 = phi( utoa::@9/utoa::buffer#15, utoa::@1/(char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS )
[120] utoa::started#2 = phi( utoa::@9/utoa::started#4, utoa::@1/0 )
[120] utoa::value#3 = phi( utoa::@9/utoa::value#7, utoa::@1/utoa::value#10 )
[120] utoa::digit#2 = phi( utoa::@9/utoa::digit#1, utoa::@1/0 )
[121] utoa::$4 = utoa::max_digits#7 - 1
[122] if(utoa::digit#2<utoa::$4) goto utoa::@7
to:utoa::@8
utoa::@8: scope:[utoa] from utoa::@6
[123] utoa::$11 = (char)utoa::value#3
[124] *utoa::buffer#10 = DIGITS[utoa::$11]
[125] utoa::buffer#3 = ++ utoa::buffer#10
[126] *utoa::buffer#3 = 0
to:utoa::@return
utoa::@7: scope:[utoa] from utoa::@6
[127] utoa::$10 = utoa::digit#2 << 1
[128] utoa::digit_value#0 = utoa::digit_values#8[utoa::$10]
[129] if(0!=utoa::started#2) goto utoa::@10
to:utoa::@12
utoa::@12: scope:[utoa] from utoa::@7
[130] if(utoa::value#3>=utoa::digit_value#0) goto utoa::@10
to:utoa::@9
utoa::@9: scope:[utoa] from utoa::@11 utoa::@12
[131] utoa::buffer#15 = phi( utoa::@12/utoa::buffer#10, utoa::@11/utoa::buffer#4 )
[131] utoa::started#4 = phi( utoa::@12/utoa::started#2, utoa::@11/1 )
[131] utoa::value#7 = phi( utoa::@12/utoa::value#3, utoa::@11/utoa::value#0 )
[132] utoa::digit#1 = ++ utoa::digit#2
to:utoa::@6
utoa::@10: scope:[utoa] from utoa::@12 utoa::@7
[133] utoa_append::buffer#0 = utoa::buffer#10
[134] utoa_append::value#0 = utoa::value#3
[135] utoa_append::sub#0 = utoa::digit_value#0
[136] call utoa_append
[137] utoa_append::return#0 = utoa_append::value#2
to:utoa::@11
utoa::@11: scope:[utoa] from utoa::@10
[138] utoa::value#0 = utoa_append::return#0
[139] utoa::buffer#4 = ++ utoa::buffer#10
to:utoa::@9
void printf_number_buffer(void (*putc)(char) , char buffer_sign , char *buffer_digits , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
printf_number_buffer: scope:[printf_number_buffer] from printf_sint::@3 printf_uint::@2
[140] printf_number_buffer::format_upper_case#10 = phi( printf_sint::@3/0, printf_uint::@2/printf_uint::format_upper_case#0 )
[140] printf_number_buffer::putc#10 = phi( printf_sint::@3/&snputc, printf_uint::@2/printf_uint::putc#0 )
[140] printf_number_buffer::buffer_sign#10 = phi( printf_sint::@3/printf_number_buffer::buffer_sign#0, printf_uint::@2/printf_number_buffer::buffer_sign#1 )
[140] printf_number_buffer::format_zero_padding#10 = phi( printf_sint::@3/0, printf_uint::@2/printf_uint::format_zero_padding#0 )
[140] printf_number_buffer::format_justify_left#10 = phi( printf_sint::@3/0, printf_uint::@2/printf_uint::format_justify_left#0 )
[140] printf_number_buffer::format_min_length#2 = phi( printf_sint::@3/0, printf_uint::@2/printf_uint::format_min_length#0 )
[141] if(0==printf_number_buffer::format_min_length#2) goto printf_number_buffer::@1
to:printf_number_buffer::@6
printf_number_buffer::@6: scope:[printf_number_buffer] from printf_number_buffer
[142] phi()
[143] call strlen
[144] strlen::return#2 = strlen::len#2
to:printf_number_buffer::@14
printf_number_buffer::@14: scope:[printf_number_buffer] from printf_number_buffer::@6
[145] printf_number_buffer::$19 = strlen::return#2
[146] printf_number_buffer::len#0 = (signed char)printf_number_buffer::$19
[147] if(0==printf_number_buffer::buffer_sign#10) goto printf_number_buffer::@13
to:printf_number_buffer::@7
printf_number_buffer::@7: scope:[printf_number_buffer] from printf_number_buffer::@14
[148] printf_number_buffer::len#1 = ++ printf_number_buffer::len#0
to:printf_number_buffer::@13
printf_number_buffer::@13: scope:[printf_number_buffer] from printf_number_buffer::@14 printf_number_buffer::@7
[149] printf_number_buffer::len#2 = phi( printf_number_buffer::@14/printf_number_buffer::len#0, printf_number_buffer::@7/printf_number_buffer::len#1 )
[150] printf_number_buffer::padding#1 = (signed char)printf_number_buffer::format_min_length#2 - printf_number_buffer::len#2
[151] if(printf_number_buffer::padding#1>=0) goto printf_number_buffer::@21
to:printf_number_buffer::@1
printf_number_buffer::@21: scope:[printf_number_buffer] from printf_number_buffer::@13
[152] phi()
to:printf_number_buffer::@1
printf_number_buffer::@1: scope:[printf_number_buffer] from printf_number_buffer printf_number_buffer::@13 printf_number_buffer::@21
[153] printf_number_buffer::padding#10 = phi( printf_number_buffer/0, printf_number_buffer::@21/printf_number_buffer::padding#1, printf_number_buffer::@13/0 )
[154] if(0!=printf_number_buffer::format_justify_left#10) goto printf_number_buffer::@2
to:printf_number_buffer::@17
printf_number_buffer::@17: scope:[printf_number_buffer] from printf_number_buffer::@1
[155] if(0!=printf_number_buffer::format_zero_padding#10) goto printf_number_buffer::@2
to:printf_number_buffer::@16
printf_number_buffer::@16: scope:[printf_number_buffer] from printf_number_buffer::@17
[156] if(0!=printf_number_buffer::padding#10) goto printf_number_buffer::@8
to:printf_number_buffer::@2
printf_number_buffer::@8: scope:[printf_number_buffer] from printf_number_buffer::@16
[157] printf_padding::putc#0 = printf_number_buffer::putc#10
[158] printf_padding::length#0 = (char)printf_number_buffer::padding#10
[159] call printf_padding
to:printf_number_buffer::@2
printf_number_buffer::@2: scope:[printf_number_buffer] from printf_number_buffer::@1 printf_number_buffer::@16 printf_number_buffer::@17 printf_number_buffer::@8
[160] if(0==printf_number_buffer::buffer_sign#10) goto printf_number_buffer::@3
to:printf_number_buffer::@9
printf_number_buffer::@9: scope:[printf_number_buffer] from printf_number_buffer::@2
[161] stackpush(char) = printf_number_buffer::buffer_sign#10
[162] callexecute *printf_number_buffer::putc#10
sideeffect stackpullbytes(1)
to:printf_number_buffer::@3
printf_number_buffer::@3: scope:[printf_number_buffer] from printf_number_buffer::@2 printf_number_buffer::@9
[164] if(0==printf_number_buffer::format_zero_padding#10) goto printf_number_buffer::@4
to:printf_number_buffer::@18
printf_number_buffer::@18: scope:[printf_number_buffer] from printf_number_buffer::@3
[165] if(0!=printf_number_buffer::padding#10) goto printf_number_buffer::@10
to:printf_number_buffer::@4
printf_number_buffer::@10: scope:[printf_number_buffer] from printf_number_buffer::@18
[166] printf_padding::putc#1 = printf_number_buffer::putc#10
[167] printf_padding::length#1 = (char)printf_number_buffer::padding#10
[168] call printf_padding
to:printf_number_buffer::@4
printf_number_buffer::@4: scope:[printf_number_buffer] from printf_number_buffer::@10 printf_number_buffer::@18 printf_number_buffer::@3
[169] if(0==printf_number_buffer::format_upper_case#10) goto printf_number_buffer::@5
to:printf_number_buffer::@11
printf_number_buffer::@11: scope:[printf_number_buffer] from printf_number_buffer::@4
[170] phi()
[171] call strupr
to:printf_number_buffer::@5
printf_number_buffer::@5: scope:[printf_number_buffer] from printf_number_buffer::@11 printf_number_buffer::@4
[172] printf_str::putc#0 = printf_number_buffer::putc#10
[173] call printf_str
to:printf_number_buffer::@15
printf_number_buffer::@15: scope:[printf_number_buffer] from printf_number_buffer::@5
[174] if(0==printf_number_buffer::format_justify_left#10) goto printf_number_buffer::@return
to:printf_number_buffer::@20
printf_number_buffer::@20: scope:[printf_number_buffer] from printf_number_buffer::@15
[175] if(0!=printf_number_buffer::format_zero_padding#10) goto printf_number_buffer::@return
to:printf_number_buffer::@19
printf_number_buffer::@19: scope:[printf_number_buffer] from printf_number_buffer::@20
[176] if(0!=printf_number_buffer::padding#10) goto printf_number_buffer::@12
to:printf_number_buffer::@return
printf_number_buffer::@12: scope:[printf_number_buffer] from printf_number_buffer::@19
[177] printf_padding::putc#2 = printf_number_buffer::putc#10
[178] printf_padding::length#2 = (char)printf_number_buffer::padding#10
[179] call printf_padding
to:printf_number_buffer::@return
printf_number_buffer::@return: scope:[printf_number_buffer] from printf_number_buffer::@12 printf_number_buffer::@15 printf_number_buffer::@19 printf_number_buffer::@20
[180] return
to:@return
unsigned int utoa_append(char *buffer , unsigned int value , unsigned int sub)
utoa_append: scope:[utoa_append] from utoa::@10
[181] phi()
to:utoa_append::@1
utoa_append::@1: scope:[utoa_append] from utoa_append utoa_append::@2
[182] utoa_append::digit#2 = phi( utoa_append/0, utoa_append::@2/utoa_append::digit#1 )
[182] utoa_append::value#2 = phi( utoa_append/utoa_append::value#0, utoa_append::@2/utoa_append::value#1 )
[183] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2
to:utoa_append::@3
utoa_append::@3: scope:[utoa_append] from utoa_append::@1
[184] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2]
to:utoa_append::@return
utoa_append::@return: scope:[utoa_append] from utoa_append::@3
[185] return
to:@return
utoa_append::@2: scope:[utoa_append] from utoa_append::@1
[186] utoa_append::digit#1 = ++ utoa_append::digit#2
[187] utoa_append::value#1 = utoa_append::value#2 - utoa_append::sub#0
to:utoa_append::@1
unsigned int strlen(char *str)
strlen: scope:[strlen] from printf_number_buffer::@6
[188] phi()
to:strlen::@1
strlen::@1: scope:[strlen] from strlen strlen::@2
[189] strlen::len#2 = phi( strlen/0, strlen::@2/strlen::len#1 )
[189] strlen::str#3 = phi( strlen/(char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS, strlen::@2/strlen::str#0 )
[190] if(0!=*strlen::str#3) goto strlen::@2
to:strlen::@return
strlen::@return: scope:[strlen] from strlen::@1
[191] return
to:@return
strlen::@2: scope:[strlen] from strlen::@1
[192] strlen::len#1 = ++ strlen::len#2
[193] strlen::str#0 = ++ strlen::str#3
to:strlen::@1
void printf_padding(void (*putc)(char) , char pad , char length)
printf_padding: scope:[printf_padding] from printf_number_buffer::@10 printf_number_buffer::@12 printf_number_buffer::@8
[194] printf_padding::putc#7 = phi( printf_number_buffer::@10/printf_padding::putc#1, printf_number_buffer::@12/printf_padding::putc#2, printf_number_buffer::@8/printf_padding::putc#0 )
[194] printf_padding::pad#7 = phi( printf_number_buffer::@10/'0', printf_number_buffer::@12/' ', printf_number_buffer::@8/' ' )
[194] printf_padding::length#6 = phi( printf_number_buffer::@10/printf_padding::length#1, printf_number_buffer::@12/printf_padding::length#2, printf_number_buffer::@8/printf_padding::length#0 )
to:printf_padding::@1
printf_padding::@1: scope:[printf_padding] from printf_padding printf_padding::@3
[195] printf_padding::i#2 = phi( printf_padding/0, printf_padding::@3/printf_padding::i#1 )
[196] if(printf_padding::i#2<printf_padding::length#6) goto printf_padding::@2
to:printf_padding::@return
printf_padding::@return: scope:[printf_padding] from printf_padding::@1
[197] return
to:@return
printf_padding::@2: scope:[printf_padding] from printf_padding::@1
[198] stackpush(char) = printf_padding::pad#7
[199] callexecute *printf_padding::putc#7
sideeffect stackpullbytes(1)
to:printf_padding::@3
printf_padding::@3: scope:[printf_padding] from printf_padding::@2
[201] printf_padding::i#1 = ++ printf_padding::i#2
to:printf_padding::@1
char * strupr(char *str)
strupr: scope:[strupr] from printf_number_buffer::@11
[202] phi()
to:strupr::@1
strupr::@1: scope:[strupr] from strupr strupr::@3
[203] strupr::src#2 = phi( strupr/strupr::str#0, strupr::@3/strupr::src#1 )
[204] if(0!=*strupr::src#2) goto strupr::@2
to:strupr::@return
strupr::@return: scope:[strupr] from strupr::@1
[205] return
to:@return
strupr::@2: scope:[strupr] from strupr::@1
[206] toupper::ch#0 = *strupr::src#2
[207] call toupper
[208] toupper::return#3 = toupper::return#2
to:strupr::@3
strupr::@3: scope:[strupr] from strupr::@2
[209] strupr::$0 = toupper::return#3
[210] *strupr::src#2 = strupr::$0
[211] strupr::src#1 = ++ strupr::src#2
to:strupr::@1
char toupper(char ch)
toupper: scope:[toupper] from strupr::@2
[212] if(toupper::ch#0<'a') goto toupper::@return
to:toupper::@2
toupper::@2: scope:[toupper] from toupper
[213] if(toupper::ch#0<='z') goto toupper::@1
to:toupper::@return
toupper::@1: scope:[toupper] from toupper::@2
[214] toupper::return#0 = toupper::ch#0 + 'A'-'a'
to:toupper::@return
toupper::@return: scope:[toupper] from toupper toupper::@1 toupper::@2
[215] toupper::return#2 = phi( toupper::@1/toupper::return#0, toupper/toupper::ch#0, toupper::@2/toupper::ch#0 )
[216] return
to:@return

7762
src/test/ref/printf-17.log Normal file

File diff suppressed because one or more lines are too long

238
src/test/ref/printf-17.sym Normal file
View File

@ -0,0 +1,238 @@
__constant char BINARY = 2
__constant char BUF[$14] = { fill( $14, 0) }
__constant char DECIMAL = $a
__constant char DIGITS[] = "0123456789abcdef"z
__constant char HEXADECIMAL = $10
__constant char OCTAL = 8
__constant char OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
__constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
__constant unsigned int RADIX_BINARY_VALUES[] = { $8000, $4000, $2000, $1000, $800, $400, $200, $100, $80, $40, $20, $10, 8, 4, 2 }
__constant unsigned int RADIX_DECIMAL_VALUES[] = { $2710, $3e8, $64, $a }
__constant unsigned int RADIX_HEXADECIMAL_VALUES[] = { $1000, $100, $10 }
__constant unsigned int RADIX_OCTAL_VALUES[] = { $8000, $1000, $200, $40, 8 }
__constant char SIZEOF_STRUCT_PRINTF_BUFFER_NUMBER = $c
__constant unsigned int STACK_BASE = $103
__loadstore char *__snprintf_buffer // zp[2]:22 9.022222222222222
__loadstore volatile unsigned int __snprintf_capacity // zp[2]:18 6.48936170212766
__loadstore volatile unsigned int __snprintf_size // zp[2]:20 11.021739130434781
void __start()
void main()
__constant char main::s[$e] = "hello world! "
__constant char main::s1[7] = "hello "
__constant char main::s2[2] = " "
__constant char main::s4[2] = "+"
__constant char main::s5[3] = "! "
__constant char main::s6[4] = "hi "
__constant char main::str[6] = "world"
void print(char *msg)
char *print::msg
char *print::msg#0 // msg zp[2]:11 2002.0
char *print::msg#5 // msg zp[2]:11 1001.0
__loadstore struct printf_buffer_number printf_buffer = {} // mem[12]
void printf_number_buffer(void (*putc)(char) , char buffer_sign , char *buffer_digits , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
unsigned int printf_number_buffer::$19 // zp[2]:13 1001.0
struct printf_buffer_number printf_number_buffer::buffer
char *printf_number_buffer::buffer_digits
char printf_number_buffer::buffer_sign
char printf_number_buffer::buffer_sign#0 // buffer_sign zp[1]:8 202.0
char printf_number_buffer::buffer_sign#1 // buffer_sign zp[1]:8 202.0
char printf_number_buffer::buffer_sign#10 // buffer_sign zp[1]:8 152.61904761904762
struct printf_format_number printf_number_buffer::format
char printf_number_buffer::format_justify_left
char printf_number_buffer::format_justify_left#10 // format_justify_left zp[1]:6 60.666666666666664
char printf_number_buffer::format_min_length
char printf_number_buffer::format_min_length#2 // reg byte x 100.1
char printf_number_buffer::format_radix
char printf_number_buffer::format_sign_always
char printf_number_buffer::format_upper_case
char printf_number_buffer::format_upper_case#10 // format_upper_case zp[1]:9 35.75
char printf_number_buffer::format_zero_padding
char printf_number_buffer::format_zero_padding#10 // format_zero_padding zp[1]:7 88.32352941176471
signed char printf_number_buffer::len
signed char printf_number_buffer::len#0 // reg byte y 1501.5
signed char printf_number_buffer::len#1 // reg byte y 2002.0
signed char printf_number_buffer::len#2 // reg byte y 3003.0
signed char printf_number_buffer::padding
signed char printf_number_buffer::padding#1 // padding zp[1]:10 1001.0
signed char printf_number_buffer::padding#10 // padding zp[1]:10 166.83333333333334
void (*printf_number_buffer::putc)(char)
void (*printf_number_buffer::putc#10)(char) // putc zp[2]:4 111.22222222222223
void printf_padding(void (*putc)(char) , char pad , char length)
char printf_padding::i
char printf_padding::i#1 // i zp[1]:17 200002.0
char printf_padding::i#2 // i zp[1]:17 100001.0
char printf_padding::length
char printf_padding::length#0 // length zp[1]:15 2002.0
char printf_padding::length#1 // length zp[1]:15 2002.0
char printf_padding::length#2 // length zp[1]:15 2002.0
char printf_padding::length#6 // length zp[1]:15 20600.8
char printf_padding::pad
char printf_padding::pad#7 // pad zp[1]:16 16666.833333333332
void (*printf_padding::putc)(char)
void (*printf_padding::putc#0)(char) // putc zp[2]:4 1001.0
void (*printf_padding::putc#1)(char) // putc zp[2]:4 1001.0
void (*printf_padding::putc#2)(char) // putc zp[2]:4 1001.0
void (*printf_padding::putc#7)(char) // putc zp[2]:4 30030.0
void printf_sint(void (*putc)(char) , int value , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_sint::format
char printf_sint::format_justify_left
char printf_sint::format_min_length
char printf_sint::format_radix
char printf_sint::format_sign_always
char printf_sint::format_upper_case
char printf_sint::format_zero_padding
void (*printf_sint::putc)(char)
unsigned int printf_sint::uvalue
int printf_sint::value
int printf_sint::value#0 // value zp[2]:4 101.0
int printf_sint::value#3 // value zp[2]:4 101.0
int printf_sint::value#5 // value zp[2]:4 202.0
void printf_str(void (*putc)(char) , const char *s)
char printf_str::c
char printf_str::c#1 // reg byte a 100001.0
void (*printf_str::putc)(char)
void (*printf_str::putc#0)(char) // putc zp[2]:4 2002.0
void (*printf_str::putc#12)(char) // putc zp[2]:4 10010.0
const char *printf_str::s
const char *printf_str::s#0 // s zp[2]:11 100001.0
const char *printf_str::s#11 // s zp[2]:11 155002.0
const char *printf_str::s#12 // s zp[2]:11 10001.0
void printf_string(void (*putc)(char) , char *str , char format_min_length , char format_justify_left)
struct printf_format_string printf_string::format
char printf_string::format_justify_left
char printf_string::format_min_length
signed char printf_string::len
signed char printf_string::padding
void (*printf_string::putc)(char)
__constant void (*printf_string::putc#0)(char) = &snputc // putc
char *printf_string::str
void printf_uint(void (*putc)(char) , unsigned int uvalue , char format_min_length , char format_justify_left , char format_sign_always , char format_zero_padding , char format_upper_case , char format_radix)
struct printf_format_number printf_uint::format
char printf_uint::format_justify_left
__constant char printf_uint::format_justify_left#0 = 0 // format_justify_left
char printf_uint::format_min_length
__constant char printf_uint::format_min_length#0 = 0 // format_min_length
char printf_uint::format_radix
char printf_uint::format_sign_always
char printf_uint::format_upper_case
__constant char printf_uint::format_upper_case#0 = 0 // format_upper_case
char printf_uint::format_zero_padding
__constant char printf_uint::format_zero_padding#0 = 0 // format_zero_padding
void (*printf_uint::putc)(char)
__constant void (*printf_uint::putc#0)(char) = &snputc // putc
unsigned int printf_uint::uvalue
__constant unsigned int printf_uint::uvalue#0 = $b // uvalue
char *screen
char *screen#0 // screen zp[2]:2 1001.0
char *screen#1 // screen zp[2]:2 68.19565217391305
char *screen#25 // screen zp[2]:2 134.0
void snprintf_init(char *s , unsigned int n)
unsigned int snprintf_init::n
unsigned int snprintf_init::n#4 // n zp[2]:4 101.0
char *snprintf_init::s
__stackcall void snputc(char c)
__constant char snputc::OFFSET_STACK_C = 0
char snputc::c
char snputc::c#0 // reg byte x 40.4
char snputc::c#2 // reg byte x 202.0
unsigned int strlen(char *str)
unsigned int strlen::len
unsigned int strlen::len#1 // len zp[2]:13 100001.0
unsigned int strlen::len#2 // len zp[2]:13 50250.75
unsigned int strlen::return
unsigned int strlen::return#2 // return zp[2]:13 2002.0
char *strlen::str
char *strlen::str#0 // str zp[2]:11 200002.0
char *strlen::str#3 // str zp[2]:11 100001.0
char * strupr(char *str)
char strupr::$0 // reg byte a 200002.0
char *strupr::return
char *strupr::src
char *strupr::src#1 // src zp[2]:24 200002.0
char *strupr::src#2 // src zp[2]:24 71429.28571428571
char *strupr::str
__constant char *strupr::str#0 = (char *)&printf_buffer+OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS // str
char toupper(char ch)
char toupper::ch
char toupper::ch#0 // reg byte a 1700002.0000000002
char toupper::return
char toupper::return#0 // reg byte a 2000002.0
char toupper::return#2 // reg byte a 1033334.6666666667
char toupper::return#3 // reg byte a 200002.0
void utoa(unsigned int value , char *buffer , char radix)
char utoa::$10 // reg byte a 20002.0
char utoa::$11 // reg byte x 2002.0
char utoa::$4 // reg byte a 20002.0
char *utoa::buffer
char *utoa::buffer#10 // buffer zp[2]:13 2800.4000000000005
char *utoa::buffer#15 // buffer zp[2]:13 15001.5
char *utoa::buffer#3 // buffer zp[2]:13 2002.0
char *utoa::buffer#4 // buffer zp[2]:13 20002.0
char utoa::digit
char utoa::digit#1 // digit zp[1]:7 20002.0
char utoa::digit#2 // digit zp[1]:7 2666.9333333333334
unsigned int utoa::digit_value
unsigned int utoa::digit_value#0 // digit_value zp[2]:24 6000.6
unsigned int *utoa::digit_values
unsigned int *utoa::digit_values#8 // digit_values zp[2]:11 588.2941176470588
char utoa::max_digits
char utoa::max_digits#7 // max_digits zp[1]:6 588.2941176470588
char utoa::radix
char utoa::radix#2 // reg byte x 1001.0
char utoa::started
char utoa::started#2 // reg byte x 4286.142857142857
char utoa::started#4 // reg byte x 10001.0
unsigned int utoa::value
unsigned int utoa::value#0 // value zp[2]:4 10001.0
unsigned int utoa::value#1 // value zp[2]:4 202.0
unsigned int utoa::value#10 // value zp[2]:4 183.66666666666669
unsigned int utoa::value#3 // value zp[2]:4 5125.625
unsigned int utoa::value#7 // value zp[2]:4 15001.5
unsigned int utoa_append(char *buffer , unsigned int value , unsigned int sub)
char *utoa_append::buffer
char *utoa_append::buffer#0 // buffer zp[2]:13 13750.25
char utoa_append::digit
char utoa_append::digit#1 // reg byte x 1.0000001E7
char utoa_append::digit#2 // reg byte x 1.00500015E7
unsigned int utoa_append::return
unsigned int utoa_append::return#0 // return zp[2]:4 20002.0
unsigned int utoa_append::sub
unsigned int utoa_append::sub#0 // sub zp[2]:24 3335000.5
unsigned int utoa_append::value
unsigned int utoa_append::value#0 // value zp[2]:4 36667.33333333333
unsigned int utoa_append::value#1 // value zp[2]:4 2.0000002E7
unsigned int utoa_append::value#2 // value zp[2]:4 5018334.166666666
reg byte x [ snputc::c#2 snputc::c#0 ]
zp[2]:2 [ screen#25 screen#1 screen#0 ]
zp[2]:4 [ printf_sint::value#5 printf_sint::value#0 printf_sint::value#3 utoa::value#3 utoa::value#7 utoa::value#10 utoa::value#1 utoa::value#0 utoa_append::value#2 utoa_append::value#0 utoa_append::value#1 utoa_append::return#0 printf_str::putc#12 printf_str::putc#0 printf_number_buffer::putc#10 printf_padding::putc#7 printf_padding::putc#1 printf_padding::putc#2 printf_padding::putc#0 snprintf_init::n#4 ]
reg byte x [ utoa::radix#2 ]
reg byte x [ utoa::started#2 utoa::started#4 ]
reg byte x [ printf_number_buffer::format_min_length#2 ]
zp[1]:6 [ printf_number_buffer::format_justify_left#10 utoa::max_digits#7 ]
zp[1]:7 [ printf_number_buffer::format_zero_padding#10 utoa::digit#2 utoa::digit#1 ]
zp[1]:8 [ printf_number_buffer::buffer_sign#10 printf_number_buffer::buffer_sign#0 printf_number_buffer::buffer_sign#1 ]
zp[1]:9 [ printf_number_buffer::format_upper_case#10 ]
reg byte y [ printf_number_buffer::len#2 printf_number_buffer::len#0 printf_number_buffer::len#1 ]
zp[1]:10 [ printf_number_buffer::padding#10 printf_number_buffer::padding#1 ]
reg byte x [ utoa_append::digit#2 utoa_append::digit#1 ]
zp[2]:11 [ strlen::str#3 strlen::str#0 utoa::digit_values#8 print::msg#5 print::msg#0 printf_str::s#11 printf_str::s#12 printf_str::s#0 ]
zp[2]:13 [ strlen::len#2 strlen::len#1 strlen::return#2 printf_number_buffer::$19 utoa::buffer#10 utoa::buffer#15 utoa::buffer#4 utoa::buffer#3 utoa_append::buffer#0 ]
zp[1]:15 [ printf_padding::length#6 printf_padding::length#1 printf_padding::length#2 printf_padding::length#0 ]
zp[1]:16 [ printf_padding::pad#7 ]
zp[1]:17 [ printf_padding::i#2 printf_padding::i#1 ]
reg byte a [ toupper::return#2 toupper::return#0 toupper::ch#0 ]
zp[2]:18 [ __snprintf_capacity ]
zp[2]:20 [ __snprintf_size ]
zp[2]:22 [ __snprintf_buffer ]
reg byte a [ printf_str::c#1 ]
reg byte a [ utoa::$4 ]
reg byte x [ utoa::$11 ]
reg byte a [ utoa::$10 ]
zp[2]:24 [ utoa::digit_value#0 utoa_append::sub#0 strupr::src#2 strupr::src#1 ]
reg byte a [ toupper::return#3 ]
reg byte a [ strupr::$0 ]
mem[12] [ printf_buffer ]

View File

@ -230,14 +230,14 @@ compare: {
jmp __b6
__b3:
// if(w1>w2)
lda.z w1+1
cmp.z w2+1
bne !+
lda.z w1
cmp.z w2
beq __b11
lda.z w2+1
cmp.z w1+1
bcc !+
bne __b11
lda.z w2
cmp.z w1
bcs __b11
!:
bcc __b11
lda #TT
sta.z r
jmp __b22
@ -274,14 +274,14 @@ compare: {
jmp __b6
__b1:
// if(w1<w2)
lda.z w2+1
cmp.z w1+1
bne !+
lda.z w2
cmp.z w1
beq __b13
lda.z w1+1
cmp.z w2+1
bcc !+
bne __b13
lda.z w1
cmp.z w2
bcs __b13
!:
bcc __b13
lda #TT
sta.z r
jmp __b24

View File

@ -2480,14 +2480,14 @@ compare: {
// compare::@3
__b3:
// [56] if(compare::w1#0<=compare::w2#0) goto compare::@22 -- vwuz1_le_vwuz2_then_la1
lda.z w1+1
cmp.z w2+1
bne !+
lda.z w1
cmp.z w2
beq __b22_from___b3
lda.z w2+1
cmp.z w1+1
bcc !+
bne __b22_from___b3
lda.z w2
cmp.z w1
bcs __b22_from___b3
!:
bcc __b22_from___b3
// [57] phi from compare::@3 to compare::@16 [phi:compare::@3->compare::@16]
__b16_from___b3:
jmp __b16
@ -2558,14 +2558,14 @@ compare: {
// compare::@1
__b1:
// [62] if(compare::w1#0>=compare::w2#0) goto compare::@24 -- vwuz1_ge_vwuz2_then_la1
lda.z w2+1
cmp.z w1+1
bne !+
lda.z w2
cmp.z w1
beq __b24_from___b1
lda.z w1+1
cmp.z w2+1
bcc !+
bne __b24_from___b1
lda.z w1
cmp.z w2
bcs __b24_from___b1
!:
bcc __b24_from___b1
// [63] phi from compare::@1 to compare::@18 [phi:compare::@1->compare::@18]
__b18_from___b1:
jmp __b18
@ -3517,14 +3517,14 @@ compare: {
__b3:
// if(w1>w2)
// [56] if(compare::w1#0<=compare::w2#0) goto compare::@22 -- vwuz1_le_vwuz2_then_la1
lda.z w1+1
cmp.z w2+1
bne !+
lda.z w1
cmp.z w2
beq __b11
lda.z w2+1
cmp.z w1+1
bcc !+
bne __b11
lda.z w2
cmp.z w1
bcs __b11
!:
bcc __b11
// [57] phi from compare::@3 to compare::@16 [phi:compare::@3->compare::@16]
// compare::@16
// [58] phi from compare::@16 to compare::@22 [phi:compare::@16->compare::@22]
@ -3585,14 +3585,14 @@ compare: {
__b1:
// if(w1<w2)
// [62] if(compare::w1#0>=compare::w2#0) goto compare::@24 -- vwuz1_ge_vwuz2_then_la1
lda.z w2+1
cmp.z w1+1
bne !+
lda.z w2
cmp.z w1
beq __b13
lda.z w1+1
cmp.z w2+1
bcc !+
bne __b13
lda.z w1
cmp.z w2
bcs __b13
!:
bcc __b13
// [63] phi from compare::@1 to compare::@18 [phi:compare::@1->compare::@18]
// compare::@18
// [64] phi from compare::@18 to compare::@24 [phi:compare::@18->compare::@24]

View File

@ -466,13 +466,14 @@ utoa: {
// if (started || value >= digit_value)
cpx #0
bne __b5
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
__b4:
// for( char digit=0; digit<max_digits-1; digit++ )
inc.z digit
@ -612,14 +613,14 @@ utoa_append: {
ldx #0
__b1:
// while (value >= sub)
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// *buffer = DIGITS[digit]
lda DIGITS,x
ldy #0

View File

@ -4762,14 +4762,14 @@ utoa: {
// utoa::@7
__b7:
// [108] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
lda.z digit_value+1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [109] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
__b4_from___b7:
// [109] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
@ -4995,14 +4995,14 @@ utoa_append: {
// utoa_append::@1
__b1:
// [146] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
jmp __b3
// utoa_append::@3
__b3:
@ -5310,8 +5310,6 @@ Succesful ASM optimization Pass5DoubleJumpElimination
Removing instruction jmp __b1
Removing instruction jmp __b2
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda.z digit_value+1
Succesful ASM optimization Pass5UnnecesaryLoadElimination
FINAL SYMBOL TABLE
__constant char * const COLORRAM = (char *) 55296
@ -5567,7 +5565,7 @@ mem[12] [ printf_buffer ]
FINAL ASSEMBLER
Score: 71978
Score: 72278
// File Comments
// Test initialization of array of struct with char* elements
@ -6244,13 +6242,14 @@ utoa: {
bne __b5
// utoa::@7
// [108] if(utoa::value#2>=utoa::digit_value#0) goto utoa::@5 -- vwuz1_ge_vwuz2_then_la1
cmp.z value+1
bne !+
lda.z digit_value
cmp.z value
beq __b5
lda.z value+1
cmp.z digit_value+1
bcc !+
bne __b5
lda.z value
cmp.z digit_value
bcs __b5
!:
bcc __b5
// [109] phi from utoa::@7 to utoa::@4 [phi:utoa::@7->utoa::@4]
// [109] phi utoa::buffer#14 = utoa::buffer#11 [phi:utoa::@7->utoa::@4#0] -- register_copy
// [109] phi utoa::started#4 = utoa::started#2 [phi:utoa::@7->utoa::@4#1] -- register_copy
@ -6464,14 +6463,14 @@ utoa_append: {
__b1:
// while (value >= sub)
// [146] if(utoa_append::value#2>=utoa_append::sub#0) goto utoa_append::@2 -- vwuz1_ge_vwuz2_then_la1
lda.z sub+1
cmp.z value+1
bne !+
lda.z sub
cmp.z value
beq __b2
lda.z value+1
cmp.z sub+1
bcc !+
bne __b2
lda.z value
cmp.z sub
bcs __b2
!:
bcc __b2
// utoa_append::@3
// *buffer = DIGITS[digit]
// [147] *utoa_append::buffer#0 = DIGITS[utoa_append::digit#2] -- _deref_pbuz1=pbuc1_derefidx_vbuxx