From bc699a9e2727f26f84e0b3612265fc6101cf3092 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Mon, 20 May 2019 23:41:58 +0200 Subject: [PATCH] Added utoa16(). Fixed early constant identification not taking procedure parameters into account. --- .../Pass1EarlyConstantIdentification.java | 46 +++-- src/test/kc/hex2dec.kc | 91 ++++------ src/test/ref/hex2dec.asm | 166 ++++++++++++------ 3 files changed, 187 insertions(+), 116 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java index faceeca37..8c8339dd9 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java @@ -6,12 +6,15 @@ import dk.camelot64.kickc.model.operators.OperatorCastPtr; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementLValue; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.values.ConstantValue; import dk.camelot64.kickc.model.values.VariableRef; import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** Identify any variable that are clearly constant. */ public class Pass1EarlyConstantIdentification extends Pass1Base { @@ -26,18 +29,20 @@ public class Pass1EarlyConstantIdentification extends Pass1Base { for(Variable variable : getProgram().getScope().getAllVariables(true)) { VariableRef variableRef = variable.getRef(); if(!variable.isDeclaredConstant() && !variable.isDeclaredVolatile() && !variableRef.isIntermediate()) { - Collection assignments = getAssignments(variable); - if(assignments.size() == 1) { - if(!Pass2ConstantIdentification.isAddressOfUsed(variableRef, getProgram())) { - StatementLValue assignment = assignments.iterator().next(); - if(assignment instanceof StatementAssignment) { - StatementAssignment assign = (StatementAssignment) assignment; - if(assign.getrValue1() == null && assign.getOperator() == null && assign.getrValue2() instanceof ConstantValue) { - getLog().append("Identified constant variable " + variable.toString(getProgram())); - earlyConstants.add(variableRef); - } else if(assign.getrValue1() == null && assign.getOperator() instanceof OperatorCastPtr && assign.getrValue2() instanceof ConstantValue) { - getLog().append("Identified constant variable " + variable.toString(getProgram())); - earlyConstants.add(variableRef); + if(!isParameter(variableRef)) { + Collection assignments = getAssignments(variable); + if(assignments.size() == 1) { + if(!Pass2ConstantIdentification.isAddressOfUsed(variableRef, getProgram())) { + StatementLValue assignment = assignments.iterator().next(); + if(assignment instanceof StatementAssignment) { + StatementAssignment assign = (StatementAssignment) assignment; + if(assign.getrValue1() == null && assign.getOperator() == null && assign.getrValue2() instanceof ConstantValue) { + getLog().append("Identified constant variable " + variable.toString(getProgram())); + earlyConstants.add(variableRef); + } else if(assign.getrValue1() == null && assign.getOperator() instanceof OperatorCastPtr && assign.getrValue2() instanceof ConstantValue) { + getLog().append("Identified constant variable " + variable.toString(getProgram())); + earlyConstants.add(variableRef); + } } } } @@ -48,6 +53,23 @@ public class Pass1EarlyConstantIdentification extends Pass1Base { return false; } + /** + * Examines whether a variale is a procedure parameter + * @param variableRef The variable + * @return true if the variable is a procedure parameter + */ + public boolean isParameter(VariableRef variableRef) { + Variable var = getScope().getVariable(variableRef); + Scope varScope = var.getScope(); + if(varScope instanceof Procedure) { + List parameters = ((Procedure) varScope).getParameters(); + if(parameters.contains(var)) + return true; + + } + return false; + } + /** * Find all assignments of a variable. * diff --git a/src/test/kc/hex2dec.kc b/src/test/kc/hex2dec.kc index f27a6e7d4..d44d936df 100644 --- a/src/test/kc/hex2dec.kc +++ b/src/test/kc/hex2dec.kc @@ -14,15 +14,15 @@ void main() { unsigned char *screen = 0x0400; *bordercol = 1; unsigned char time_start = *raster; - utoa10b(00000, screen); (*bordercol)++; screen += 40; - utoa10b(01234, screen); (*bordercol)++; screen += 40; - utoa10b(05678, screen); (*bordercol)++; screen += 40; - utoa10b(09999, screen); (*bordercol)++; screen += 40; - utoa10b(58888, screen); + utoa16w(00000, screen); (*bordercol)++; screen += 40; + utoa16w(01234, screen); (*bordercol)++; screen += 40; + utoa16w(05678, screen); (*bordercol)++; screen += 40; + utoa16w(09999, screen); (*bordercol)++; screen += 40; + utoa16w(58888, screen); unsigned char time_end = *raster; *bordercol = 0; unsigned char time = time_end - time_start; - utoa10b((unsigned int)time, screen+80); + utoa10w((unsigned int)time, screen+80); byte[] msg = "raster lines"; for( byte i=0; msg[i]!=0; i++ ) (screen+80+3)[i] = msg[i]; //for( byte* m="lines", s=screen+80+6 ;*m!=0;m++,s++) *s = *m; @@ -40,58 +40,20 @@ const unsigned char RADIX_OCTAL = 8; const unsigned char RADIX_DECIMAL = 10; const unsigned char RADIX_HEX = 16; -// simple 'utoa' without using multiply or divide -unsigned int utoa_digit(unsigned char *dst, unsigned int value, unsigned int sub){ - unsigned char digit = 0; - unsigned int sub3 = sub*2+sub; - while (value >= sub3){ digit += 3; value -= sub3; } - while (value >= sub){ ++digit; value -= sub; } - *dst = DIGITS[digit]; - return value; -} - -void utoa(unsigned int value, unsigned char *dst){ - unsigned char bStarted = 0; - if (bStarted == 1 || value >= 10000){ value = utoa_digit(dst++, value, 10000); bStarted = 1; } - if (bStarted == 1 || value >= 1000){ value = utoa_digit(dst++, value, 1000); bStarted = 1; } - if (bStarted == 1 || value >= 100){ value = utoa_digit(dst++, value, 100); bStarted = 1; } - if (bStarted == 1 || value >= 10){ value = utoa_digit(dst++, value, 10); bStarted = 1; } - *dst++ = '0' + (unsigned char) value; - //*dst = 0; -} - +// Digits used for utoa() unsigned char[] DIGITS = "0123456789abcdef"; -unsigned int[] SUB3 = { 30000, 3000, 300, 30 }; -unsigned int[] SUB1 = { 10000, 1000, 100, 10 }; -// Simple decimal utoa() without using multiply or divide -void utoa10(unsigned int value, unsigned char* dst) { - unsigned char bStarted = 0; - for( unsigned char i: 0..3) { - unsigned char digit = 0; - unsigned int sub1 = SUB1[i]; - if(value>=sub1) { - unsigned int sub3 = SUB3[i]; - while(value>=sub3) { digit += 3; value -= sub3; bStarted = 1; } - while(value>=sub1) { digit += 1; value -= sub1; bStarted = 1; } - } - if(bStarted!=0) { - *dst++ = DIGITS[digit]; - } - } - *dst++ = DIGITS[(unsigned char) value]; - //*dst = 0; -} - -unsigned int[] SUB = { 30000, 10000, 3000, 1000, 300, 100, 30, 10 }; -unsigned char[] VAL = { 3, 1, 3, 1, 3, 1, 3, 1 }; +// Subtraction values used for decimal utoa() +unsigned int[] UTOA10_SUB = { 30000, 10000, 3000, 1000, 300, 100, 30, 10 }; +// Digit addition values used for decimal utoa() +unsigned char[] UTOA10_VAL = { 3, 1, 3, 1, 3, 1, 3, 1 }; // Decimal utoa() without using multiply or divide -void utoa10b(unsigned int value, unsigned char* dst) { +void utoa10w(unsigned int value, unsigned char* dst) { unsigned char bStarted = 0; unsigned char digit = 0; for( unsigned char i: 0..7) { - while(value>=SUB[i]) { digit += VAL[i]; value -= SUB[i]; bStarted = 1; } + while(value>=UTOA10_SUB[i]) { digit += UTOA10_VAL[i]; value -= UTOA10_SUB[i]; bStarted = 1; } if((i&1)!=0) { if(bStarted!=0) { *dst++ = DIGITS[digit]; @@ -101,4 +63,29 @@ void utoa10b(unsigned int value, unsigned char* dst) { } *dst++ = DIGITS[(unsigned char) value]; *dst = 0; -} \ No newline at end of file +} + +// Holds the destination address for the hexadecimal utoa() +unsigned char* utoa16_dst; +// Holds whether the hexadecimal utoa() has started outputting digits +unsigned char utoa16_started; + +// Hexadecimal utoa() for an unsigned int (16bits) +void utoa16w(unsigned int value, unsigned char* dst) { + utoa16_dst = dst; + utoa16_started = 0; + utoa16n((>value)>>4); + utoa16n((>value)&0x0f); + utoa16n((>4); + utoa16_started = 1; + utoa16n(($400 - sta utoa10b.dst+1 lda #0 - sta utoa10b.value - sta utoa10b.value+1 - jsr utoa10b + sta utoa16w.value + sta utoa16w.value+1 + lda #<$400 + sta utoa16w.dst + lda #>$400 + sta utoa16w.dst+1 + jsr utoa16w inc bordercol - lda #<$400+$28 - sta utoa10b.dst - lda #>$400+$28 - sta utoa10b.dst+1 lda #<$4d2 - sta utoa10b.value + sta utoa16w.value lda #>$4d2 - sta utoa10b.value+1 - jsr utoa10b + sta utoa16w.value+1 + lda #<$400+$28 + sta utoa16w.dst + lda #>$400+$28 + sta utoa16w.dst+1 + jsr utoa16w inc bordercol - lda #<$400+$28+$28 - sta utoa10b.dst - lda #>$400+$28+$28 - sta utoa10b.dst+1 lda #<$162e - sta utoa10b.value + sta utoa16w.value lda #>$162e - sta utoa10b.value+1 - jsr utoa10b + sta utoa16w.value+1 + lda #<$400+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28 + sta utoa16w.dst+1 + jsr utoa16w inc bordercol - lda #<$400+$28+$28+$28 - sta utoa10b.dst - lda #>$400+$28+$28+$28 - sta utoa10b.dst+1 lda #<$270f - sta utoa10b.value + sta utoa16w.value lda #>$270f - sta utoa10b.value+1 - jsr utoa10b + sta utoa16w.value+1 + lda #<$400+$28+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28+$28 + sta utoa16w.dst+1 + jsr utoa16w inc bordercol - lda #<$400+$28+$28+$28+$28 - sta utoa10b.dst - lda #>$400+$28+$28+$28+$28 - sta utoa10b.dst+1 lda #<$e608 - sta utoa10b.value + sta utoa16w.value lda #>$e608 - sta utoa10b.value+1 - jsr utoa10b + sta utoa16w.value+1 + lda #<$400+$28+$28+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28+$28+$28 + sta utoa16w.dst+1 + jsr utoa16w ldx raster lda #0 sta bordercol txa sec sbc time_start - sta utoa10b.value + sta utoa10w.value lda #0 - sta utoa10b.value+1 - lda #<$400+$28+$28+$28+$28+$50 - sta utoa10b.dst - lda #>$400+$28+$28+$28+$28+$50 - sta utoa10b.dst+1 - jsr utoa10b + sta utoa10w.value+1 + jsr utoa10w ldx #0 b3: lda msg,x @@ -97,12 +95,16 @@ main: { msg: .text "raster lines@" } // Decimal utoa() without using multiply or divide -// utoa10b(word zeropage(2) value, byte* zeropage(6) dst) -utoa10b: { +// utoa10w(word zeropage(2) value, byte* zeropage(6) dst) +utoa10w: { .label value = 2 .label digit = 4 .label dst = 6 .label bStarted = 5 + lda #<$400+$28+$28+$28+$28+$50 + sta dst + lda #>$400+$28+$28+$28+$28+$50 + sta dst+1 lda #0 sta bStarted sta digit @@ -111,10 +113,10 @@ utoa10b: { txa asl tay - lda SUB+1,y + lda UTOA10_SUB+1,y cmp value+1 bne !+ - lda SUB,y + lda UTOA10_SUB,y cmp value beq b2 !: @@ -155,7 +157,7 @@ utoa10b: { sta (dst),y rts b2: - lda VAL,x + lda UTOA10_VAL,x clc adc digit sta digit @@ -164,15 +166,72 @@ utoa10b: { tay sec lda value - sbc SUB,y + sbc UTOA10_SUB,y sta value lda value+1 - sbc SUB+1,y + sbc UTOA10_SUB+1,y sta value+1 lda #1 sta bStarted jmp b1 } +// Hexadecimal utoa() for an unsigned int (16bits) +// utoa16w(word zeropage(6) value, byte* zeropage(2) dst) +utoa16w: { + .label dst = 2 + .label value = 6 + lda value+1 + lsr + lsr + lsr + lsr + tax + lda #0 + sta utoa16_started + jsr utoa16n + lda value+1 + ldx #$f + axs #0 + jsr utoa16n + lda value + lsr + lsr + lsr + lsr + tax + jsr utoa16n + lda value + ldx #$f + axs #0 + lda #1 + sta utoa16_started + jsr utoa16n + lda #0 + tay + sta (utoa16_dst),y + rts +} +// Hexadecimal utoa() for a single nybble +// utoa16n(byte register(X) nybble) +utoa16n: { + cpx #0 + beq b1 + lda #1 + sta utoa16_started + b1: + lda utoa16_started + cmp #0 + beq breturn + lda DIGITS,x + ldy #0 + sta (utoa16_dst),y + inc utoa16_dst + bne !+ + inc utoa16_dst+1 + !: + breturn: + rts +} cls: { .label screen = $400 .label sc = 2 @@ -196,6 +255,9 @@ cls: { bne b1 rts } + // Digits used for utoa() DIGITS: .text "0123456789abcdef@" - SUB: .word $7530, $2710, $bb8, $3e8, $12c, $64, $1e, $a - VAL: .byte 3, 1, 3, 1, 3, 1, 3, 1 + // Subtraction values used for decimal utoa() + UTOA10_SUB: .word $7530, $2710, $bb8, $3e8, $12c, $64, $1e, $a + // Digit addition values used for decimal utoa() + UTOA10_VAL: .byte 3, 1, 3, 1, 3, 1, 3, 1