mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-10 10:31:27 +00:00
Added utoa16(). Fixed early constant identification not taking procedure parameters into account.
This commit is contained in:
parent
2b26c813d9
commit
bc699a9e27
@ -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<StatementLValue> 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<StatementLValue> 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<Variable> parameters = ((Procedure) varScope).getParameters();
|
||||
if(parameters.contains(var))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all assignments of a variable.
|
||||
*
|
||||
|
@ -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];
|
||||
@ -102,3 +64,28 @@ void utoa10b(unsigned int value, unsigned char* dst) {
|
||||
*dst++ = DIGITS[(unsigned char) value];
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
// 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((<value)>>4);
|
||||
utoa16_started = 1;
|
||||
utoa16n((<value)&0x0f);
|
||||
*utoa16_dst = 0;
|
||||
}
|
||||
|
||||
// Hexadecimal utoa() for a single nybble
|
||||
void utoa16n(unsigned char nybble) {
|
||||
if(nybble!=0) utoa16_started=1;
|
||||
if(utoa16_started!=0) {
|
||||
*utoa16_dst++ = DIGITS[nybble];
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,11 @@
|
||||
.label control = $d011
|
||||
.label raster = $d012
|
||||
.label bordercol = $d020
|
||||
.label utoa16_dst = 2
|
||||
.label utoa16_started = 4
|
||||
main: {
|
||||
.label _1 = 4
|
||||
.label time_start = 8
|
||||
.label time_start = 5
|
||||
sei
|
||||
jsr cls
|
||||
b1:
|
||||
@ -23,68 +25,64 @@ main: {
|
||||
sta bordercol
|
||||
lda raster
|
||||
sta time_start
|
||||
lda #<$400
|
||||
sta utoa10b.dst
|
||||
lda #>$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
|
||||
|
Loading…
x
Reference in New Issue
Block a user