mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-09 21:37:31 +00:00
Added malloc tests. Improved cast handing in ASM fragments. Optimized screen center distance calculation (implemented table-based sqr() and sqrt() using binary search).
This commit is contained in:
parent
306bbc381f
commit
20ec350ca5
10
src/main/fragment/_deref_pwuz1_le_vwuz2_then_la1.asm
Normal file
10
src/main/fragment/_deref_pwuz1_le_vwuz2_then_la1.asm
Normal file
@ -0,0 +1,10 @@
|
||||
ldy #1
|
||||
lda ({z1}),y
|
||||
cmp {z2}+1
|
||||
bne !+
|
||||
dey
|
||||
lda ({z1}),y
|
||||
cmp {z2}
|
||||
beq {la1}
|
||||
!:
|
||||
bcc {la1}
|
4
src/main/fragment/pwuz1=pbuc1.asm
Normal file
4
src/main/fragment/pwuz1=pbuc1.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda #<{c1}
|
||||
sta {z1}
|
||||
lda #>{c1}
|
||||
sta {z1}+1
|
4
src/main/fragment/pwuz1=pwuz2.asm
Normal file
4
src/main/fragment/pwuz1=pwuz2.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
@ -1,3 +1,3 @@
|
||||
eor #$ff
|
||||
tax
|
||||
axs #{c1}+1
|
||||
axs #-{c1}-1
|
9
src/main/fragment/vwsz1=_deref_pwsz2_minus_vwsz3.asm
Normal file
9
src/main/fragment/vwsz1=_deref_pwsz2_minus_vwsz3.asm
Normal file
@ -0,0 +1,9 @@
|
||||
sec
|
||||
ldy #0
|
||||
lda ({z2}),y
|
||||
sbc {z3}
|
||||
sta {z1}
|
||||
iny
|
||||
lda ({z2}),y
|
||||
sbc {z3}+1
|
||||
sta {z1}+1
|
9
src/main/fragment/vwsz1=vwsz2_minus__deref_pwsz3.asm
Normal file
9
src/main/fragment/vwsz1=vwsz2_minus__deref_pwsz3.asm
Normal file
@ -0,0 +1,9 @@
|
||||
sec
|
||||
lda {z2}
|
||||
ldy #0
|
||||
sbc ({z3}),y
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
iny
|
||||
sbc ({z3}),y
|
||||
sta {z1}+1
|
4
src/main/fragment/vwsz1_neq_0_then_la1.asm
Normal file
4
src/main/fragment/vwsz1_neq_0_then_la1.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {z1}+1
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
bne {la1}
|
5
src/main/fragment/vwuz1_gt_0_then_la1.asm
Normal file
5
src/main/fragment/vwuz1_gt_0_then_la1.asm
Normal file
@ -0,0 +1,5 @@
|
||||
lda {z1}+1
|
||||
bne {la1}
|
||||
lda {z1}
|
||||
bne {la1}
|
||||
!:
|
@ -7,7 +7,10 @@ import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
@ -223,13 +226,29 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
if(value instanceof CastValue) {
|
||||
CastValue cast = (CastValue) value;
|
||||
SymbolType toType = cast.getToType();
|
||||
OperatorUnary castUnary = Operators.getCastUnary(toType);
|
||||
RValue castValue = cast.getValue();
|
||||
SymbolType castValueType = SymbolTypeInference.inferType(this.program.getScope(), castValue);
|
||||
if(castValueType.getSizeBytes() == toType.getSizeBytes()) {
|
||||
return bind(castValue, toType);
|
||||
if(castType != null) {
|
||||
if(castType.getSizeBytes() == toType.getSizeBytes()) {
|
||||
return bind(castValue, castType);
|
||||
} else {
|
||||
OperatorUnary castUnary = Operators.getCastUnary(castType);
|
||||
return getOperatorFragmentName(castUnary) + bind(castValue, toType);
|
||||
}
|
||||
} else {
|
||||
return bind(castValue, toType);
|
||||
}
|
||||
} else {
|
||||
return getOperatorFragmentName(castUnary) + bind(castValue);
|
||||
// Size of inner value and inner cast type mismatches - require explicit conversion
|
||||
if(castType != null) {
|
||||
OperatorUnary castUnaryInner = Operators.getCastUnary(toType);
|
||||
OperatorUnary castUnaryOuter = Operators.getCastUnary(castType);
|
||||
return getOperatorFragmentName(castUnaryOuter) + getOperatorFragmentName(castUnaryInner) + bind(castValue);
|
||||
} else {
|
||||
OperatorUnary castUnaryInner = Operators.getCastUnary(toType);
|
||||
return getOperatorFragmentName(castUnaryInner) + bind(castValue);
|
||||
}
|
||||
}
|
||||
} else if(value instanceof ConstantCastValue) {
|
||||
ConstantCastValue castVal = (ConstantCastValue) value;
|
||||
|
@ -1298,7 +1298,12 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
} else {
|
||||
simpleTypeName = "int";
|
||||
}
|
||||
return SymbolType.get(signedness + " " + simpleTypeName);
|
||||
String fullName = signedness + " " + simpleTypeName;
|
||||
SymbolType symbolType = SymbolType.get(fullName);
|
||||
if(symbolType==null) {
|
||||
throw new CompileError("Unknown type "+fullName, new StatementSource(ctx));
|
||||
}
|
||||
return symbolType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,6 +35,16 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsignedVoidError() throws IOException, URISyntaxException {
|
||||
assertError("unsigned-void-error", "Unknown type unsigned void");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScreenCenterDistance() throws IOException, URISyntaxException {
|
||||
compileAndCompare("screen-center-distance");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontHexShow() throws IOException, URISyntaxException {
|
||||
compileAndCompare("font-hex-show");
|
||||
@ -502,6 +512,16 @@ public class TestPrograms {
|
||||
compileAndCompare("memory-heap");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalloc1() throws IOException, URISyntaxException {
|
||||
compileAndCompare("malloc-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalloc0() throws IOException, URISyntaxException {
|
||||
compileAndCompare("malloc-0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryInference() throws IOException, URISyntaxException {
|
||||
compileAndCompare("ternary-inference");
|
||||
|
11
src/test/kc/malloc-0.kc
Normal file
11
src/test/kc/malloc-0.kc
Normal file
@ -0,0 +1,11 @@
|
||||
// Experiments with malloc() - a byte array
|
||||
|
||||
import "stdlib"
|
||||
|
||||
byte* BYTES = malloc(0x100);
|
||||
|
||||
void main() {
|
||||
for( byte i: 0..255) {
|
||||
BYTES[i] = i;
|
||||
}
|
||||
}
|
12
src/test/kc/malloc-1.kc
Normal file
12
src/test/kc/malloc-1.kc
Normal file
@ -0,0 +1,12 @@
|
||||
// Experiments with malloc() - a word array
|
||||
|
||||
import "stdlib"
|
||||
|
||||
word* WORDS = malloc(0x200);
|
||||
|
||||
void main() {
|
||||
word* w = WORDS;
|
||||
for( byte i: 0..255) {
|
||||
*w++ = i;
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
import "stdlib"
|
||||
|
||||
void main() {
|
||||
unsigned char* buf1 = (unsigned char*) malloc(100);
|
||||
unsigned char* buf2 = (unsigned char*) malloc(100);
|
||||
unsigned char* buf1 = malloc(100);
|
||||
unsigned char* buf2 = malloc(100);
|
||||
for(unsigned char i:0..99) {
|
||||
buf1[i] = i;
|
||||
buf2[i] = 255-i;
|
||||
|
86
src/test/kc/screen-center-distance.kc
Normal file
86
src/test/kc/screen-center-distance.kc
Normal file
@ -0,0 +1,86 @@
|
||||
// Calculate the distance to the center of the screen - and show it using font-hex
|
||||
|
||||
import "stdlib"
|
||||
import "c64"
|
||||
import "font-hex"
|
||||
|
||||
#reserve(08)
|
||||
|
||||
const byte* CHARSET = 0x2000;
|
||||
const byte* SCREEN = 0x2800;
|
||||
|
||||
void main() {
|
||||
init_font_hex(CHARSET);
|
||||
*D018 = toD018(SCREEN, CHARSET);
|
||||
NUM_SQUARES = 0x30;
|
||||
init_squares();
|
||||
byte* screen = SCREEN;
|
||||
for(byte y: 0..24) {
|
||||
byte y2 = y*2;
|
||||
byte yd = (y2>=24)?(y2-24):(24-y2);
|
||||
word yds = sqr(yd);
|
||||
for(byte x: 0..39) {
|
||||
byte x2 = x*2;
|
||||
byte xd = (x2>=39)?(x2-39):(39-x2);
|
||||
word xds = sqr(xd);
|
||||
word ds = xds+yds;
|
||||
byte d = sqrt(ds);
|
||||
*screen++ = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The number of squares to pre-calculate. Limits what values sqr() can calculate and the result of sqrt()
|
||||
byte NUM_SQUARES = 0xff;
|
||||
|
||||
// Squares for each byte value SQUARES[i] = i*i
|
||||
// Initialized by init_squares()
|
||||
word* SQUARES;
|
||||
|
||||
// Initialize squares table
|
||||
// Uses iterative formula (x+1)^2 = x^2 + 2*x + 1
|
||||
void init_squares() {
|
||||
SQUARES = malloc(NUM_SQUARES*sizeof(word));
|
||||
word* squares = SQUARES;
|
||||
word sqr = 0;
|
||||
for( byte i: 0..NUM_SQUARES-1) {
|
||||
*squares++ = sqr;
|
||||
sqr += i*2+1;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the square of a byte value
|
||||
// Uses a table of squares that must be initialized by calling init_squares()
|
||||
word sqr(byte val) {
|
||||
return SQUARES[val];
|
||||
}
|
||||
|
||||
// Find the (integer) square root of a word value
|
||||
// If the square is not an integer then it returns the largest integer N where N*N <= val
|
||||
// Uses a table of squares that must be initialized by calling init_squares()
|
||||
byte sqrt(word val) {
|
||||
word* found = bsearch16u(val, SQUARES, NUM_SQUARES);
|
||||
byte sqr1 = (byte)((byte*)found-(byte*)SQUARES)/2;
|
||||
return sqr1;
|
||||
}
|
||||
|
||||
// Searches an array of nitems unsigned words, the initial member of which is pointed to by base, for a member that matches the value key.
|
||||
// - key - The value to look for
|
||||
// - items - Pointer to the start of the array to search in
|
||||
// - num - The number of items in the array
|
||||
// Returns pointer to an entry in the array that matches the search key
|
||||
word* bsearch16u(word key, word* items, byte num) {
|
||||
while (num > 0) {
|
||||
word* pivot = items + (num >> 1);
|
||||
signed word result = (signed word)key-(signed word)*pivot;
|
||||
if (result == 0)
|
||||
return pivot;
|
||||
if (result > 0) {
|
||||
items = pivot+1;
|
||||
num--;
|
||||
}
|
||||
num >>= 1;
|
||||
}
|
||||
// not found - return closest lower value
|
||||
return *items<=key?items:items-1;
|
||||
}
|
11
src/test/kc/unsigned-void-error.kc
Normal file
11
src/test/kc/unsigned-void-error.kc
Normal file
@ -0,0 +1,11 @@
|
||||
// Tests that unsigned void produces an error
|
||||
|
||||
void main() {
|
||||
getNull();
|
||||
}
|
||||
|
||||
unsigned void* getNull() {
|
||||
return (byte*) 0;
|
||||
}
|
||||
|
||||
|
@ -264,13 +264,13 @@ mulf_init: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #1+1
|
||||
axs #-1-1
|
||||
lda val
|
||||
sta mulf_sqr2,x
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #1+1
|
||||
axs #-1-1
|
||||
lda val
|
||||
sta mulf_sqr2+$100,x
|
||||
lda sqr
|
||||
|
@ -3003,7 +3003,7 @@ mulf_init: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #1+1
|
||||
axs #-1-1
|
||||
//SEG201 [96] *((const byte[$200]) mulf_sqr2#0 + (byte~) mulf_init::$8) ← (byte) mulf_init::val#0 -- pbuc1_derefidx_vbuxx=vbuz1
|
||||
lda val
|
||||
sta mulf_sqr2,x
|
||||
@ -3011,7 +3011,7 @@ mulf_init: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #1+1
|
||||
axs #-1-1
|
||||
//SEG203 [98] *((const byte[$200]) mulf_sqr2#0+(word) $100 + (byte~) mulf_init::$10) ← (byte) mulf_init::val#0 -- pbuc1_derefidx_vbuxx=vbuz1
|
||||
lda val
|
||||
sta mulf_sqr2+$100,x
|
||||
@ -3829,7 +3829,7 @@ mulf_init: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #1+1
|
||||
axs #-1-1
|
||||
//SEG201 [96] *((const byte[$200]) mulf_sqr2#0 + (byte~) mulf_init::$8) ← (byte) mulf_init::val#0 -- pbuc1_derefidx_vbuxx=vbuz1
|
||||
lda val
|
||||
sta mulf_sqr2,x
|
||||
@ -3837,7 +3837,7 @@ mulf_init: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #1+1
|
||||
axs #-1-1
|
||||
//SEG203 [98] *((const byte[$200]) mulf_sqr2#0+(word) $100 + (byte~) mulf_init::$10) ← (byte) mulf_init::val#0 -- pbuc1_derefidx_vbuxx=vbuz1
|
||||
lda val
|
||||
sta mulf_sqr2+$100,x
|
||||
|
@ -2229,7 +2229,7 @@ anim: {
|
||||
jmp mulf8s_prepare1
|
||||
//SEG38 anim::mulf8s_prepare1
|
||||
mulf8s_prepare1:
|
||||
//SEG39 [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) -- vbuz1=pbsc1_derefidx_vbuz2
|
||||
//SEG39 [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) -- vbuz1=pbuc1_derefidx_vbuz2
|
||||
ldy angle
|
||||
lda COS,y
|
||||
sta mulf8u_prepare.a
|
||||
@ -2280,7 +2280,7 @@ anim: {
|
||||
jmp mulf8s_prepare2
|
||||
//SEG56 anim::mulf8s_prepare2
|
||||
mulf8s_prepare2:
|
||||
//SEG57 [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) -- vbuz1=pbsc1_derefidx_vbuz2
|
||||
//SEG57 [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) -- vbuz1=pbuc1_derefidx_vbuz2
|
||||
ldy angle
|
||||
lda SIN,y
|
||||
sta mulf8u_prepare.a
|
||||
@ -2866,14 +2866,12 @@ REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Equivalence Class zp ZP_BYTE:42 [ anim::$22 ] has ALU potential.
|
||||
Statement [12] if(*((const byte*) RASTER#0)!=(byte) $ff) goto anim::@2 [ anim::angle#6 ] ( main:3::anim:8 [ anim::angle#6 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ anim::angle#6 anim::angle#1 ]
|
||||
Statement [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 mulf8u_prepare::a#3 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 mulf8u_prepare::a#3 ] ) always clobbers reg byte a
|
||||
Statement [21] (signed word) anim::xr#0 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ anim::i#10 anim::i#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ anim::sprite_msb#10 anim::sprite_msb#5 anim::sprite_msb#2 anim::sprite_msb#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:24 [ anim::x#0 ]
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:25 [ anim::y#0 ]
|
||||
Statement [21] (signed word) anim::xr#0 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 ] ) always clobbers reg byte a
|
||||
Statement [24] (signed word) anim::yr#0 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 ] ) always clobbers reg byte a
|
||||
Statement [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 mulf8u_prepare::a#4 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 mulf8u_prepare::a#4 ] ) always clobbers reg byte a
|
||||
Statement [29] (signed word~) anim::$10 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::xr#0 anim::yr#0 anim::$10 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::xr#0 anim::yr#0 anim::$10 ] ) always clobbers reg byte a
|
||||
Statement [30] (signed word) anim::xr#1 ← (signed word) anim::xr#0 - (signed word~) anim::$10 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::yr#0 anim::xr#1 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::yr#0 anim::xr#1 ] ) always clobbers reg byte a
|
||||
Statement [33] (signed word~) anim::$12 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::yr#0 anim::xr#1 anim::$12 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::yr#0 anim::xr#1 anim::$12 ] ) always clobbers reg byte a
|
||||
@ -2930,10 +2928,8 @@ Statement [110] if((byte*) mulf_init::sqr2_lo#1!=(const byte[$200]) mulf_sqr2_lo
|
||||
Statement [111] *((const byte[$200]) mulf_sqr2_lo#0+(word) $1ff) ← *((const byte[$200]) mulf_sqr1_lo#0+(word) $100) [ ] ( main:3::init:6::mulf_init:77 [ ] ) always clobbers reg byte a
|
||||
Statement [112] *((const byte[$200]) mulf_sqr2_hi#0+(word) $1ff) ← *((const byte[$200]) mulf_sqr1_hi#0+(word) $100) [ ] ( main:3::init:6::mulf_init:77 [ ] ) always clobbers reg byte a
|
||||
Statement [12] if(*((const byte*) RASTER#0)!=(byte) $ff) goto anim::@2 [ anim::angle#6 ] ( main:3::anim:8 [ anim::angle#6 ] ) always clobbers reg byte a
|
||||
Statement [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 mulf8u_prepare::a#3 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 mulf8u_prepare::a#3 ] ) always clobbers reg byte a
|
||||
Statement [21] (signed word) anim::xr#0 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 ] ) always clobbers reg byte a
|
||||
Statement [24] (signed word) anim::yr#0 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 ] ) always clobbers reg byte a
|
||||
Statement [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 mulf8u_prepare::a#4 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::y#0 anim::xr#0 anim::yr#0 mulf8u_prepare::a#4 ] ) always clobbers reg byte a
|
||||
Statement [29] (signed word~) anim::$10 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::xr#0 anim::yr#0 anim::$10 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::xr#0 anim::yr#0 anim::$10 ] ) always clobbers reg byte a
|
||||
Statement [30] (signed word) anim::xr#1 ← (signed word) anim::xr#0 - (signed word~) anim::$10 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::yr#0 anim::xr#1 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::x#0 anim::yr#0 anim::xr#1 ] ) always clobbers reg byte a
|
||||
Statement [33] (signed word~) anim::$12 ← (signed word)(word) mulf8s_prepared::m#4 << (byte) 1 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::yr#0 anim::xr#1 anim::$12 ] ( main:3::anim:8 [ anim::angle#6 anim::i#10 anim::sprite_msb#10 anim::yr#0 anim::xr#1 anim::$12 ] ) always clobbers reg byte a
|
||||
@ -3204,7 +3200,7 @@ anim: {
|
||||
jmp mulf8s_prepare1
|
||||
//SEG38 anim::mulf8s_prepare1
|
||||
mulf8s_prepare1:
|
||||
//SEG39 [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) -- vbuaa=pbsc1_derefidx_vbuz1
|
||||
//SEG39 [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) -- vbuaa=pbuc1_derefidx_vbuz1
|
||||
ldy angle
|
||||
lda COS,y
|
||||
//SEG40 [18] call mulf8u_prepare
|
||||
@ -3252,7 +3248,7 @@ anim: {
|
||||
jmp mulf8s_prepare2
|
||||
//SEG56 anim::mulf8s_prepare2
|
||||
mulf8s_prepare2:
|
||||
//SEG57 [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) -- vbuaa=pbsc1_derefidx_vbuz1
|
||||
//SEG57 [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) -- vbuaa=pbuc1_derefidx_vbuz1
|
||||
ldy angle
|
||||
lda SIN,y
|
||||
//SEG58 [26] call mulf8u_prepare
|
||||
@ -4237,7 +4233,7 @@ anim: {
|
||||
lda ys,y
|
||||
sta y
|
||||
//SEG38 anim::mulf8s_prepare1
|
||||
//SEG39 [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) -- vbuaa=pbsc1_derefidx_vbuz1
|
||||
//SEG39 [17] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte)*((const byte*) COS#0 + (byte) anim::angle#6) -- vbuaa=pbuc1_derefidx_vbuz1
|
||||
ldy angle
|
||||
lda COS,y
|
||||
//SEG40 [18] call mulf8u_prepare
|
||||
@ -4274,7 +4270,7 @@ anim: {
|
||||
rol
|
||||
sta yr+1
|
||||
//SEG56 anim::mulf8s_prepare2
|
||||
//SEG57 [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) -- vbuaa=pbsc1_derefidx_vbuz1
|
||||
//SEG57 [25] (byte~) mulf8u_prepare::a#4 ← (byte)(signed byte)*((const byte*) SIN#0 + (byte) anim::angle#6) -- vbuaa=pbuc1_derefidx_vbuz1
|
||||
ldy angle
|
||||
lda SIN,y
|
||||
//SEG58 [26] call mulf8u_prepare
|
||||
|
25
src/test/ref/malloc-0.asm
Normal file
25
src/test/ref/malloc-0.asm
Normal file
@ -0,0 +1,25 @@
|
||||
// Experiments with malloc() - a byte array
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
bbegin:
|
||||
jsr malloc
|
||||
jsr main
|
||||
rts
|
||||
main: {
|
||||
ldx #0
|
||||
b1:
|
||||
txa
|
||||
sta HEAP_START,x
|
||||
inx
|
||||
cpx #0
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
rts
|
||||
}
|
31
src/test/ref/malloc-0.cfg
Normal file
31
src/test/ref/malloc-0.cfg
Normal file
@ -0,0 +1,31 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call malloc
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[7] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[8] *((const byte*) HEAP_START#0 + (byte) main::i#2) ← (byte) main::i#2
|
||||
[9] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[10] if((byte) main::i#1!=(byte) 0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[11] return
|
||||
to:@return
|
||||
malloc: scope:[malloc] from @1
|
||||
[12] phi()
|
||||
to:malloc::@return
|
||||
malloc::@return: scope:[malloc] from malloc
|
||||
[13] return
|
||||
to:@return
|
516
src/test/ref/malloc-0.log
Normal file
516
src/test/ref/malloc-0.log
Normal file
@ -0,0 +1,516 @@
|
||||
Adding pointer type conversion cast (byte*) HEAP_START in (byte*) HEAP_START ← (number) $c000
|
||||
Identified constant variable (byte*) HEAP_START
|
||||
Culled Empty Block (label) malloc::@1
|
||||
Culled Empty Block (label) @1
|
||||
Culled Empty Block (label) main::@2
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte*) HEAP_START#0 ← ((byte*)) (number) $c000
|
||||
(byte*) heap_head#0 ← (byte*) HEAP_START#0
|
||||
to:@2
|
||||
malloc: scope:[malloc] from @2
|
||||
(word) malloc::size#1 ← phi( @2/(word) malloc::size#0 )
|
||||
(byte*) heap_head#4 ← phi( @2/(byte*) heap_head#7 )
|
||||
(byte*) malloc::mem#0 ← (byte*) heap_head#4
|
||||
(byte*) heap_head#1 ← (byte*) heap_head#4 + (word) malloc::size#1
|
||||
(byte*) malloc::return#0 ← (byte*) malloc::mem#0
|
||||
to:malloc::@return
|
||||
malloc::@return: scope:[malloc] from malloc
|
||||
(byte*) heap_head#5 ← phi( malloc/(byte*) heap_head#1 )
|
||||
(byte*) malloc::return#3 ← phi( malloc/(byte*) malloc::return#0 )
|
||||
(byte*) malloc::return#1 ← (byte*) malloc::return#3
|
||||
(byte*) heap_head#2 ← (byte*) heap_head#5
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
(byte*) heap_head#7 ← phi( @begin/(byte*) heap_head#0 )
|
||||
(word) malloc::size#0 ← (number) $100
|
||||
call malloc
|
||||
(byte*) malloc::return#2 ← (byte*) malloc::return#1
|
||||
to:@4
|
||||
@4: scope:[] from @2
|
||||
(byte*) heap_head#6 ← phi( @2/(byte*) heap_head#2 )
|
||||
(byte*) malloc::return#4 ← phi( @2/(byte*) malloc::return#2 )
|
||||
(byte*~) $0 ← (byte*) malloc::return#4
|
||||
(byte*) heap_head#3 ← (byte*) heap_head#6
|
||||
(byte*) BYTES#0 ← (byte*~) $0
|
||||
to:@3
|
||||
main: scope:[main] from @3
|
||||
(byte*) BYTES#2 ← phi( @3/(byte*) BYTES#3 )
|
||||
(byte) main::i#0 ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte*) BYTES#1 ← phi( main/(byte*) BYTES#2 main::@1/(byte*) BYTES#1 )
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
*((byte*) BYTES#1 + (byte) main::i#2) ← (byte) main::i#2
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,$ff)
|
||||
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,$ff)
|
||||
if((bool~) main::$0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@3: scope:[] from @4
|
||||
(byte*) BYTES#3 ← phi( @4/(byte*) BYTES#0 )
|
||||
call main
|
||||
to:@5
|
||||
@5: scope:[] from @3
|
||||
to:@end
|
||||
@end: scope:[] from @5
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(byte*~) $0
|
||||
(label) @2
|
||||
(label) @3
|
||||
(label) @4
|
||||
(label) @5
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BYTES
|
||||
(byte*) BYTES#0
|
||||
(byte*) BYTES#1
|
||||
(byte*) BYTES#2
|
||||
(byte*) BYTES#3
|
||||
(byte*) HEAP_START
|
||||
(byte*) HEAP_START#0
|
||||
(byte*) heap_head
|
||||
(byte*) heap_head#0
|
||||
(byte*) heap_head#1
|
||||
(byte*) heap_head#2
|
||||
(byte*) heap_head#3
|
||||
(byte*) heap_head#4
|
||||
(byte*) heap_head#5
|
||||
(byte*) heap_head#6
|
||||
(byte*) heap_head#7
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#0
|
||||
(byte) main::i#1
|
||||
(byte) main::i#2
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(label) malloc::@return
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::mem#0
|
||||
(byte*) malloc::return
|
||||
(byte*) malloc::return#0
|
||||
(byte*) malloc::return#1
|
||||
(byte*) malloc::return#2
|
||||
(byte*) malloc::return#3
|
||||
(byte*) malloc::return#4
|
||||
(word) malloc::size
|
||||
(word) malloc::size#0
|
||||
(word) malloc::size#1
|
||||
|
||||
Adding number conversion cast (unumber) $100 in (word) malloc::size#0 ← (number) $100
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Inlining cast (byte*) HEAP_START#0 ← (byte*)(number) $c000
|
||||
Inlining cast (word) malloc::size#0 ← (unumber)(number) $100
|
||||
Successful SSA optimization Pass2InlineCast
|
||||
Simplifying constant pointer cast (byte*) 49152
|
||||
Simplifying constant integer cast $100
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (word) $100
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias (byte*) HEAP_START#0 = (byte*) heap_head#0 (byte*) heap_head#7
|
||||
Alias (byte*) malloc::return#0 = (byte*) malloc::mem#0 (byte*) malloc::return#3 (byte*) malloc::return#1
|
||||
Alias (byte*) heap_head#1 = (byte*) heap_head#5 (byte*) heap_head#2
|
||||
Alias (byte*) malloc::return#2 = (byte*) malloc::return#4
|
||||
Alias (byte*) heap_head#3 = (byte*) heap_head#6
|
||||
Alias (byte*) BYTES#0 = (byte*~) $0 (byte*) BYTES#3
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Self Phi Eliminated (byte*) BYTES#1
|
||||
Successful SSA optimization Pass2SelfPhiElimination
|
||||
Identical Phi Values (byte*) heap_head#4 (byte*) HEAP_START#0
|
||||
Identical Phi Values (word) malloc::size#1 (word) malloc::size#0
|
||||
Identical Phi Values (byte*) heap_head#3 (byte*) heap_head#1
|
||||
Identical Phi Values (byte*) BYTES#2 (byte*) BYTES#0
|
||||
Identical Phi Values (byte*) BYTES#1 (byte*) BYTES#2
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition (bool~) main::$0 [24] if((byte) main::i#1!=rangelast(0,$ff)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) HEAP_START#0 = (byte*) 49152
|
||||
Constant (const word) malloc::size#0 = $100
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) malloc::return#0 = HEAP_START#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) malloc::return#2 = malloc::return#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) BYTES#0 = malloc::return#2
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [22] main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value [24] if(main::i#1!=rangelast(0,$ff)) goto main::@1 to (number) 0
|
||||
Eliminating unused variable (byte*) heap_head#1 and assignment [0] (byte*) heap_head#1 ← (const byte*) HEAP_START#0 + (const word) malloc::size#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Eliminating unused constant (const word) malloc::size#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding number conversion cast (unumber) 0 in if((byte) main::i#1!=(number) 0) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant integer cast 0
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Constant inlined main::i#0 = (byte) 0
|
||||
Constant inlined malloc::return#2 = (const byte*) HEAP_START#0
|
||||
Constant inlined BYTES#0 = (const byte*) HEAP_START#0
|
||||
Constant inlined malloc::return#0 = (const byte*) HEAP_START#0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Added new block during phi lifting main::@3(between main::@1 and main::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @4
|
||||
Adding NOP phi() at start of @3
|
||||
Adding NOP phi() at start of @5
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of malloc
|
||||
CALL GRAPH
|
||||
Calls in [] to malloc:2 main:5
|
||||
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced [14] main::i#3 ← main::i#1
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Culled Empty Block (label) @4
|
||||
Culled Empty Block (label) @5
|
||||
Culled Empty Block (label) main::@3
|
||||
Renumbering block @2 to @1
|
||||
Renumbering block @3 to @2
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of malloc
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call malloc
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[7] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[8] *((const byte*) HEAP_START#0 + (byte) main::i#2) ← (byte) main::i#2
|
||||
[9] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[10] if((byte) main::i#1!=(byte) 0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[11] return
|
||||
to:@return
|
||||
malloc: scope:[malloc] from @1
|
||||
[12] phi()
|
||||
to:malloc::@return
|
||||
malloc::@return: scope:[malloc] from malloc
|
||||
[13] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(byte*) BYTES
|
||||
(byte*) HEAP_START
|
||||
(byte*) heap_head
|
||||
(void()) main()
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 22.0
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::return
|
||||
(word) malloc::size
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Experiments with malloc() - a byte array
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call malloc
|
||||
//SEG7 [12] phi from @1 to malloc [phi:@1->malloc]
|
||||
malloc_from_b1:
|
||||
jsr malloc
|
||||
//SEG8 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG9 @2
|
||||
b2:
|
||||
//SEG10 [4] call main
|
||||
//SEG11 [6] phi from @2 to main [phi:@2->main]
|
||||
main_from_b2:
|
||||
jsr main
|
||||
//SEG12 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG13 @end
|
||||
bend:
|
||||
//SEG14 main
|
||||
main: {
|
||||
.label i = 2
|
||||
//SEG15 [7] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG16 [7] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
jmp b1
|
||||
//SEG17 [7] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG18 [7] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG19 main::@1
|
||||
b1:
|
||||
//SEG20 [8] *((const byte*) HEAP_START#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuz1=vbuz1
|
||||
ldy i
|
||||
tya
|
||||
sta HEAP_START,y
|
||||
//SEG21 [9] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc i
|
||||
//SEG22 [10] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuz1_neq_0_then_la1
|
||||
lda i
|
||||
cmp #0
|
||||
bne b1_from_b1
|
||||
jmp breturn
|
||||
//SEG23 main::@return
|
||||
breturn:
|
||||
//SEG24 [11] return
|
||||
rts
|
||||
}
|
||||
//SEG25 malloc
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
jmp breturn
|
||||
//SEG26 malloc::@return
|
||||
breturn:
|
||||
//SEG27 [13] return
|
||||
rts
|
||||
}
|
||||
//SEG28 File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 38.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Uplift Scope [malloc]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 308 combination reg byte x [ main::i#2 main::i#1 ]
|
||||
Uplifting [malloc] best 308 combination
|
||||
Uplifting [] best 308 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Experiments with malloc() - a byte array
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call malloc
|
||||
//SEG7 [12] phi from @1 to malloc [phi:@1->malloc]
|
||||
malloc_from_b1:
|
||||
jsr malloc
|
||||
//SEG8 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG9 @2
|
||||
b2:
|
||||
//SEG10 [4] call main
|
||||
//SEG11 [6] phi from @2 to main [phi:@2->main]
|
||||
main_from_b2:
|
||||
jsr main
|
||||
//SEG12 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG13 @end
|
||||
bend:
|
||||
//SEG14 main
|
||||
main: {
|
||||
//SEG15 [7] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG16 [7] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp b1
|
||||
//SEG17 [7] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG18 [7] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG19 main::@1
|
||||
b1:
|
||||
//SEG20 [8] *((const byte*) HEAP_START#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx
|
||||
txa
|
||||
sta HEAP_START,x
|
||||
//SEG21 [9] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG22 [10] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuxx_neq_0_then_la1
|
||||
cpx #0
|
||||
bne b1_from_b1
|
||||
jmp breturn
|
||||
//SEG23 main::@return
|
||||
breturn:
|
||||
//SEG24 [11] return
|
||||
rts
|
||||
}
|
||||
//SEG25 malloc
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
jmp breturn
|
||||
//SEG26 malloc::@return
|
||||
breturn:
|
||||
//SEG27 [13] return
|
||||
rts
|
||||
}
|
||||
//SEG28 File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label b1_from_b1 with b1
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction b1:
|
||||
Removing instruction malloc_from_b1:
|
||||
Removing instruction b2_from_b1:
|
||||
Removing instruction main_from_b2:
|
||||
Removing instruction bend_from_b2:
|
||||
Removing instruction b1_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction b2:
|
||||
Removing instruction bend:
|
||||
Removing instruction b1_from_main:
|
||||
Removing instruction breturn:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Adding RTS to root block
|
||||
Succesful ASM optimization Pass5AddMainRts
|
||||
Removing instruction jmp b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BYTES
|
||||
(byte*) HEAP_START
|
||||
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
|
||||
(byte*) heap_head
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 22.0
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(label) malloc::@return
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::return
|
||||
(word) malloc::size
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 185
|
||||
|
||||
//SEG0 File Comments
|
||||
// Experiments with malloc() - a byte array
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call malloc
|
||||
//SEG7 [12] phi from @1 to malloc [phi:@1->malloc]
|
||||
jsr malloc
|
||||
//SEG8 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
//SEG9 @2
|
||||
//SEG10 [4] call main
|
||||
//SEG11 [6] phi from @2 to main [phi:@2->main]
|
||||
jsr main
|
||||
rts
|
||||
//SEG12 [5] phi from @2 to @end [phi:@2->@end]
|
||||
//SEG13 @end
|
||||
//SEG14 main
|
||||
main: {
|
||||
//SEG15 [7] phi from main to main::@1 [phi:main->main::@1]
|
||||
//SEG16 [7] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
//SEG17 [7] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
//SEG18 [7] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
//SEG19 main::@1
|
||||
b1:
|
||||
//SEG20 [8] *((const byte*) HEAP_START#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx
|
||||
txa
|
||||
sta HEAP_START,x
|
||||
//SEG21 [9] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG22 [10] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuxx_neq_0_then_la1
|
||||
cpx #0
|
||||
bne b1
|
||||
//SEG23 main::@return
|
||||
//SEG24 [11] return
|
||||
rts
|
||||
}
|
||||
//SEG25 malloc
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
//SEG26 malloc::@return
|
||||
//SEG27 [13] return
|
||||
rts
|
||||
}
|
||||
//SEG28 File Data
|
||||
|
21
src/test/ref/malloc-0.sym
Normal file
21
src/test/ref/malloc-0.sym
Normal file
@ -0,0 +1,21 @@
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BYTES
|
||||
(byte*) HEAP_START
|
||||
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
|
||||
(byte*) heap_head
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 22.0
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(label) malloc::@return
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::return
|
||||
(word) malloc::size
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
42
src/test/ref/malloc-1.asm
Normal file
42
src/test/ref/malloc-1.asm
Normal file
@ -0,0 +1,42 @@
|
||||
// Experiments with malloc() - a word array
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_WORD = 2
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
bbegin:
|
||||
jsr malloc
|
||||
jsr main
|
||||
rts
|
||||
main: {
|
||||
.label w = 2
|
||||
lda #<HEAP_START
|
||||
sta w
|
||||
lda #>HEAP_START
|
||||
sta w+1
|
||||
ldx #0
|
||||
b1:
|
||||
txa
|
||||
ldy #0
|
||||
sta (w),y
|
||||
tya
|
||||
iny
|
||||
sta (w),y
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc w
|
||||
sta w
|
||||
bcc !+
|
||||
inc w+1
|
||||
!:
|
||||
inx
|
||||
cpx #0
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
rts
|
||||
}
|
33
src/test/ref/malloc-1.cfg
Normal file
33
src/test/ref/malloc-1.cfg
Normal file
@ -0,0 +1,33 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call malloc
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[7] (word*) main::w#2 ← phi( main/(const byte*) HEAP_START#0 main::@1/(word*) main::w#1 )
|
||||
[7] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[8] *((word*) main::w#2) ← (byte) main::i#2
|
||||
[9] (word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD
|
||||
[10] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[11] if((byte) main::i#1!=(byte) 0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[12] return
|
||||
to:@return
|
||||
malloc: scope:[malloc] from @1
|
||||
[13] phi()
|
||||
to:malloc::@return
|
||||
malloc::@return: scope:[malloc] from malloc
|
||||
[14] return
|
||||
to:@return
|
605
src/test/ref/malloc-1.log
Normal file
605
src/test/ref/malloc-1.log
Normal file
@ -0,0 +1,605 @@
|
||||
Adding pointer type conversion cast (byte*) HEAP_START in (byte*) HEAP_START ← (number) $c000
|
||||
Fixing pointer increment (word*) main::w ← ++ (word*) main::w
|
||||
Identified constant variable (byte*) HEAP_START
|
||||
Culled Empty Block (label) malloc::@1
|
||||
Culled Empty Block (label) @1
|
||||
Culled Empty Block (label) main::@2
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte*) HEAP_START#0 ← ((byte*)) (number) $c000
|
||||
(byte*) heap_head#0 ← (byte*) HEAP_START#0
|
||||
to:@2
|
||||
malloc: scope:[malloc] from @2
|
||||
(word) malloc::size#1 ← phi( @2/(word) malloc::size#0 )
|
||||
(byte*) heap_head#4 ← phi( @2/(byte*) heap_head#7 )
|
||||
(byte*) malloc::mem#0 ← (byte*) heap_head#4
|
||||
(byte*) heap_head#1 ← (byte*) heap_head#4 + (word) malloc::size#1
|
||||
(byte*) malloc::return#0 ← (byte*) malloc::mem#0
|
||||
to:malloc::@return
|
||||
malloc::@return: scope:[malloc] from malloc
|
||||
(byte*) heap_head#5 ← phi( malloc/(byte*) heap_head#1 )
|
||||
(byte*) malloc::return#3 ← phi( malloc/(byte*) malloc::return#0 )
|
||||
(byte*) malloc::return#1 ← (byte*) malloc::return#3
|
||||
(byte*) heap_head#2 ← (byte*) heap_head#5
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
(byte*) heap_head#7 ← phi( @begin/(byte*) heap_head#0 )
|
||||
(word) malloc::size#0 ← (number) $200
|
||||
call malloc
|
||||
(byte*) malloc::return#2 ← (byte*) malloc::return#1
|
||||
to:@4
|
||||
@4: scope:[] from @2
|
||||
(byte*) heap_head#6 ← phi( @2/(byte*) heap_head#2 )
|
||||
(byte*) malloc::return#4 ← phi( @2/(byte*) malloc::return#2 )
|
||||
(byte*~) $0 ← (byte*) malloc::return#4
|
||||
(byte*) heap_head#3 ← (byte*) heap_head#6
|
||||
(word*) WORDS#0 ← (byte*~) $0
|
||||
to:@3
|
||||
main: scope:[main] from @3
|
||||
(word*) WORDS#1 ← phi( @3/(word*) WORDS#2 )
|
||||
(word*) main::w#0 ← (word*) WORDS#1
|
||||
(byte) main::i#0 ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(word*) main::w#2 ← phi( main/(word*) main::w#0 main::@1/(word*) main::w#1 )
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
*((word*) main::w#2) ← (byte) main::i#2
|
||||
(word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,$ff)
|
||||
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,$ff)
|
||||
if((bool~) main::$0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@3: scope:[] from @4
|
||||
(word*) WORDS#2 ← phi( @4/(word*) WORDS#0 )
|
||||
call main
|
||||
to:@5
|
||||
@5: scope:[] from @3
|
||||
to:@end
|
||||
@end: scope:[] from @5
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(byte*~) $0
|
||||
(label) @2
|
||||
(label) @3
|
||||
(label) @4
|
||||
(label) @5
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) HEAP_START
|
||||
(byte*) HEAP_START#0
|
||||
(const byte) SIZEOF_WORD = (byte) 2
|
||||
(word*) WORDS
|
||||
(word*) WORDS#0
|
||||
(word*) WORDS#1
|
||||
(word*) WORDS#2
|
||||
(byte*) heap_head
|
||||
(byte*) heap_head#0
|
||||
(byte*) heap_head#1
|
||||
(byte*) heap_head#2
|
||||
(byte*) heap_head#3
|
||||
(byte*) heap_head#4
|
||||
(byte*) heap_head#5
|
||||
(byte*) heap_head#6
|
||||
(byte*) heap_head#7
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#0
|
||||
(byte) main::i#1
|
||||
(byte) main::i#2
|
||||
(word*) main::w
|
||||
(word*) main::w#0
|
||||
(word*) main::w#1
|
||||
(word*) main::w#2
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(label) malloc::@return
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::mem#0
|
||||
(byte*) malloc::return
|
||||
(byte*) malloc::return#0
|
||||
(byte*) malloc::return#1
|
||||
(byte*) malloc::return#2
|
||||
(byte*) malloc::return#3
|
||||
(byte*) malloc::return#4
|
||||
(word) malloc::size
|
||||
(word) malloc::size#0
|
||||
(word) malloc::size#1
|
||||
|
||||
Adding number conversion cast (unumber) $200 in (word) malloc::size#0 ← (number) $200
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Inlining cast (byte*) HEAP_START#0 ← (byte*)(number) $c000
|
||||
Inlining cast (word) malloc::size#0 ← (unumber)(number) $200
|
||||
Successful SSA optimization Pass2InlineCast
|
||||
Simplifying constant pointer cast (byte*) 49152
|
||||
Simplifying constant integer cast $200
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (word) $200
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias (byte*) HEAP_START#0 = (byte*) heap_head#0 (byte*) heap_head#7
|
||||
Alias (byte*) malloc::return#0 = (byte*) malloc::mem#0 (byte*) malloc::return#3 (byte*) malloc::return#1
|
||||
Alias (byte*) heap_head#1 = (byte*) heap_head#5 (byte*) heap_head#2
|
||||
Alias (byte*) malloc::return#2 = (byte*) malloc::return#4
|
||||
Alias (byte*) heap_head#3 = (byte*) heap_head#6
|
||||
Alias (word*) WORDS#0 = (byte*~) $0 (word*) WORDS#2
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Identical Phi Values (byte*) heap_head#4 (byte*) HEAP_START#0
|
||||
Identical Phi Values (word) malloc::size#1 (word) malloc::size#0
|
||||
Identical Phi Values (byte*) heap_head#3 (byte*) heap_head#1
|
||||
Identical Phi Values (word*) WORDS#1 (word*) WORDS#0
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition (bool~) main::$0 [26] if((byte) main::i#1!=rangelast(0,$ff)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) HEAP_START#0 = (byte*) 49152
|
||||
Constant (const word) malloc::size#0 = $200
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) malloc::return#0 = HEAP_START#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) malloc::return#2 = malloc::return#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const word*) WORDS#0 = malloc::return#2
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const word*) main::w#0 = WORDS#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [24] main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value [26] if(main::i#1!=rangelast(0,$ff)) goto main::@1 to (number) 0
|
||||
Eliminating unused variable (byte*) heap_head#1 and assignment [0] (byte*) heap_head#1 ← (const byte*) HEAP_START#0 + (const word) malloc::size#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Eliminating unused constant (const word) malloc::size#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding number conversion cast (unumber) 0 in if((byte) main::i#1!=(number) 0) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant integer cast 0
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Inlining constant with var siblings (const word*) main::w#0
|
||||
Constant inlined main::i#0 = (byte) 0
|
||||
Constant inlined malloc::return#2 = (const byte*) HEAP_START#0
|
||||
Constant inlined malloc::return#0 = (const byte*) HEAP_START#0
|
||||
Constant inlined main::w#0 = (const byte*) HEAP_START#0
|
||||
Constant inlined WORDS#0 = (const byte*) HEAP_START#0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Added new block during phi lifting main::@3(between main::@1 and main::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @4
|
||||
Adding NOP phi() at start of @3
|
||||
Adding NOP phi() at start of @5
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of malloc
|
||||
CALL GRAPH
|
||||
Calls in [] to malloc:2 main:5
|
||||
|
||||
Created 2 initial phi equivalence classes
|
||||
Coalesced [15] main::i#3 ← main::i#1
|
||||
Coalesced [16] main::w#3 ← main::w#1
|
||||
Coalesced down to 2 phi equivalence classes
|
||||
Culled Empty Block (label) @4
|
||||
Culled Empty Block (label) @5
|
||||
Culled Empty Block (label) main::@3
|
||||
Renumbering block @2 to @1
|
||||
Renumbering block @3 to @2
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of malloc
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call malloc
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[7] (word*) main::w#2 ← phi( main/(const byte*) HEAP_START#0 main::@1/(word*) main::w#1 )
|
||||
[7] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[8] *((word*) main::w#2) ← (byte) main::i#2
|
||||
[9] (word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD
|
||||
[10] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[11] if((byte) main::i#1!=(byte) 0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[12] return
|
||||
to:@return
|
||||
malloc: scope:[malloc] from @1
|
||||
[13] phi()
|
||||
to:malloc::@return
|
||||
malloc::@return: scope:[malloc] from malloc
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(byte*) HEAP_START
|
||||
(word*) WORDS
|
||||
(byte*) heap_head
|
||||
(void()) main()
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 11.0
|
||||
(word*) main::w
|
||||
(word*) main::w#1 7.333333333333333
|
||||
(word*) main::w#2 16.5
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::return
|
||||
(word) malloc::size
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::w#2 main::w#1 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ main::w#2 main::w#1 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Allocated zp ZP_WORD:3 [ main::w#2 main::w#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Experiments with malloc() - a word array
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call malloc
|
||||
//SEG7 [13] phi from @1 to malloc [phi:@1->malloc]
|
||||
malloc_from_b1:
|
||||
jsr malloc
|
||||
//SEG8 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG9 @2
|
||||
b2:
|
||||
//SEG10 [4] call main
|
||||
//SEG11 [6] phi from @2 to main [phi:@2->main]
|
||||
main_from_b2:
|
||||
jsr main
|
||||
//SEG12 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG13 @end
|
||||
bend:
|
||||
//SEG14 main
|
||||
main: {
|
||||
.label w = 3
|
||||
.label i = 2
|
||||
//SEG15 [7] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG16 [7] phi (word*) main::w#2 = (const byte*) HEAP_START#0 [phi:main->main::@1#0] -- pwuz1=pbuc1
|
||||
lda #<HEAP_START
|
||||
sta w
|
||||
lda #>HEAP_START
|
||||
sta w+1
|
||||
//SEG17 [7] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
jmp b1
|
||||
//SEG18 [7] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG19 [7] phi (word*) main::w#2 = (word*) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
//SEG20 [7] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp b1
|
||||
//SEG21 main::@1
|
||||
b1:
|
||||
//SEG22 [8] *((word*) main::w#2) ← (byte) main::i#2 -- _deref_pwuz1=vbuz2
|
||||
lda i
|
||||
ldy #0
|
||||
sta (w),y
|
||||
tya
|
||||
iny
|
||||
sta (w),y
|
||||
//SEG23 [9] (word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD -- pwuz1=pwuz1_plus_vbuc1
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc w
|
||||
sta w
|
||||
bcc !+
|
||||
inc w+1
|
||||
!:
|
||||
//SEG24 [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
inc i
|
||||
//SEG25 [11] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuz1_neq_0_then_la1
|
||||
lda i
|
||||
cmp #0
|
||||
bne b1_from_b1
|
||||
jmp breturn
|
||||
//SEG26 main::@return
|
||||
breturn:
|
||||
//SEG27 [12] return
|
||||
rts
|
||||
}
|
||||
//SEG28 malloc
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
jmp breturn
|
||||
//SEG29 malloc::@return
|
||||
breturn:
|
||||
//SEG30 [14] return
|
||||
rts
|
||||
}
|
||||
//SEG31 File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [8] *((word*) main::w#2) ← (byte) main::i#2 [ main::i#2 main::w#2 ] ( main:4 [ main::i#2 main::w#2 ] ) always clobbers reg byte a reg byte y
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Statement [9] (word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD [ main::i#2 main::w#1 ] ( main:4 [ main::i#2 main::w#1 ] ) always clobbers reg byte a
|
||||
Statement [8] *((word*) main::w#2) ← (byte) main::i#2 [ main::i#2 main::w#2 ] ( main:4 [ main::i#2 main::w#2 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [9] (word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD [ main::i#2 main::w#1 ] ( main:4 [ main::i#2 main::w#1 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x ,
|
||||
Potential registers zp ZP_WORD:3 [ main::w#2 main::w#1 ] : zp ZP_WORD:3 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 23.83: zp ZP_WORD:3 [ main::w#2 main::w#1 ]
|
||||
Uplift Scope [malloc]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 713 combination reg byte x [ main::i#2 main::i#1 ] zp ZP_WORD:3 [ main::w#2 main::w#1 ]
|
||||
Uplifting [malloc] best 713 combination
|
||||
Uplifting [] best 713 combination
|
||||
Allocated (was zp ZP_WORD:3) zp ZP_WORD:2 [ main::w#2 main::w#1 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Experiments with malloc() - a word array
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG5 @1
|
||||
b1:
|
||||
//SEG6 [2] call malloc
|
||||
//SEG7 [13] phi from @1 to malloc [phi:@1->malloc]
|
||||
malloc_from_b1:
|
||||
jsr malloc
|
||||
//SEG8 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG9 @2
|
||||
b2:
|
||||
//SEG10 [4] call main
|
||||
//SEG11 [6] phi from @2 to main [phi:@2->main]
|
||||
main_from_b2:
|
||||
jsr main
|
||||
//SEG12 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG13 @end
|
||||
bend:
|
||||
//SEG14 main
|
||||
main: {
|
||||
.label w = 2
|
||||
//SEG15 [7] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG16 [7] phi (word*) main::w#2 = (const byte*) HEAP_START#0 [phi:main->main::@1#0] -- pwuz1=pbuc1
|
||||
lda #<HEAP_START
|
||||
sta w
|
||||
lda #>HEAP_START
|
||||
sta w+1
|
||||
//SEG17 [7] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp b1
|
||||
//SEG18 [7] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG19 [7] phi (word*) main::w#2 = (word*) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
//SEG20 [7] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
jmp b1
|
||||
//SEG21 main::@1
|
||||
b1:
|
||||
//SEG22 [8] *((word*) main::w#2) ← (byte) main::i#2 -- _deref_pwuz1=vbuxx
|
||||
txa
|
||||
ldy #0
|
||||
sta (w),y
|
||||
tya
|
||||
iny
|
||||
sta (w),y
|
||||
//SEG23 [9] (word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD -- pwuz1=pwuz1_plus_vbuc1
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc w
|
||||
sta w
|
||||
bcc !+
|
||||
inc w+1
|
||||
!:
|
||||
//SEG24 [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG25 [11] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuxx_neq_0_then_la1
|
||||
cpx #0
|
||||
bne b1_from_b1
|
||||
jmp breturn
|
||||
//SEG26 main::@return
|
||||
breturn:
|
||||
//SEG27 [12] return
|
||||
rts
|
||||
}
|
||||
//SEG28 malloc
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
jmp breturn
|
||||
//SEG29 malloc::@return
|
||||
breturn:
|
||||
//SEG30 [14] return
|
||||
rts
|
||||
}
|
||||
//SEG31 File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label b1_from_b1 with b1
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction b1:
|
||||
Removing instruction malloc_from_b1:
|
||||
Removing instruction b2_from_b1:
|
||||
Removing instruction main_from_b2:
|
||||
Removing instruction bend_from_b2:
|
||||
Removing instruction b1_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction b2:
|
||||
Removing instruction bend:
|
||||
Removing instruction b1_from_main:
|
||||
Removing instruction breturn:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Adding RTS to root block
|
||||
Succesful ASM optimization Pass5AddMainRts
|
||||
Removing instruction jmp b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) HEAP_START
|
||||
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte) 2
|
||||
(word*) WORDS
|
||||
(byte*) heap_head
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 11.0
|
||||
(word*) main::w
|
||||
(word*) main::w#1 w zp ZP_WORD:2 7.333333333333333
|
||||
(word*) main::w#2 w zp ZP_WORD:2 16.5
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(label) malloc::@return
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::return
|
||||
(word) malloc::size
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp ZP_WORD:2 [ main::w#2 main::w#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 590
|
||||
|
||||
//SEG0 File Comments
|
||||
// Experiments with malloc() - a word array
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.const SIZEOF_WORD = 2
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG5 @1
|
||||
//SEG6 [2] call malloc
|
||||
//SEG7 [13] phi from @1 to malloc [phi:@1->malloc]
|
||||
jsr malloc
|
||||
//SEG8 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
//SEG9 @2
|
||||
//SEG10 [4] call main
|
||||
//SEG11 [6] phi from @2 to main [phi:@2->main]
|
||||
jsr main
|
||||
rts
|
||||
//SEG12 [5] phi from @2 to @end [phi:@2->@end]
|
||||
//SEG13 @end
|
||||
//SEG14 main
|
||||
main: {
|
||||
.label w = 2
|
||||
//SEG15 [7] phi from main to main::@1 [phi:main->main::@1]
|
||||
//SEG16 [7] phi (word*) main::w#2 = (const byte*) HEAP_START#0 [phi:main->main::@1#0] -- pwuz1=pbuc1
|
||||
lda #<HEAP_START
|
||||
sta w
|
||||
lda #>HEAP_START
|
||||
sta w+1
|
||||
//SEG17 [7] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#1] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
//SEG18 [7] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
//SEG19 [7] phi (word*) main::w#2 = (word*) main::w#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
//SEG20 [7] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy
|
||||
//SEG21 main::@1
|
||||
b1:
|
||||
//SEG22 [8] *((word*) main::w#2) ← (byte) main::i#2 -- _deref_pwuz1=vbuxx
|
||||
txa
|
||||
ldy #0
|
||||
sta (w),y
|
||||
tya
|
||||
iny
|
||||
sta (w),y
|
||||
//SEG23 [9] (word*) main::w#1 ← (word*) main::w#2 + (const byte) SIZEOF_WORD -- pwuz1=pwuz1_plus_vbuc1
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc w
|
||||
sta w
|
||||
bcc !+
|
||||
inc w+1
|
||||
!:
|
||||
//SEG24 [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG25 [11] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuxx_neq_0_then_la1
|
||||
cpx #0
|
||||
bne b1
|
||||
//SEG26 main::@return
|
||||
//SEG27 [12] return
|
||||
rts
|
||||
}
|
||||
//SEG28 malloc
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
//SEG29 malloc::@return
|
||||
//SEG30 [14] return
|
||||
rts
|
||||
}
|
||||
//SEG31 File Data
|
||||
|
26
src/test/ref/malloc-1.sym
Normal file
26
src/test/ref/malloc-1.sym
Normal file
@ -0,0 +1,26 @@
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) HEAP_START
|
||||
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte) 2
|
||||
(word*) WORDS
|
||||
(byte*) heap_head
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 11.0
|
||||
(word*) main::w
|
||||
(word*) main::w#1 w zp ZP_WORD:2 7.333333333333333
|
||||
(word*) main::w#2 w zp ZP_WORD:2 16.5
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(label) malloc::@return
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::return
|
||||
(word) malloc::size
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
zp ZP_WORD:2 [ main::w#2 main::w#1 ]
|
@ -23,8 +23,8 @@ main::@4: scope:[main] from main::@3
|
||||
main::@1: scope:[main] from main::@1 main::@4
|
||||
[11] (byte) main::i#2 ← phi( main::@1/(byte) main::i#1 main::@4/(byte) 0 )
|
||||
[12] *((byte*) main::buf1#0 + (byte) main::i#2) ← (byte) main::i#2
|
||||
[13] (byte~) main::$6 ← (byte) $ff - (byte) main::i#2
|
||||
[14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$6
|
||||
[13] (byte~) main::$4 ← (byte) $ff - (byte) main::i#2
|
||||
[14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$4
|
||||
[15] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[16] if((byte) main::i#1!=(byte) $64) goto main::@1
|
||||
to:main::@2
|
||||
|
@ -1,4 +1,6 @@
|
||||
Adding pointer type conversion cast (byte*) HEAP_START in (byte*) HEAP_START ← (number) $c000
|
||||
Adding void pointer type conversion cast (void*) main::buf1 in (void~) main::$2 ← call free (byte*) main::buf1
|
||||
Adding void pointer type conversion cast (void*) main::buf2 in (void~) main::$3 ← call free (byte*) main::buf2
|
||||
Adding pointer type conversion cast (byte*) main::screen in (byte*) main::screen ← (number) $400
|
||||
Identified constant variable (byte*) HEAP_START
|
||||
Identified constant variable (byte*) main::screen
|
||||
@ -41,8 +43,7 @@ main::@3: scope:[main] from main
|
||||
(byte*) malloc::return#5 ← phi( main/(byte*) malloc::return#2 )
|
||||
(byte*~) main::$0 ← (byte*) malloc::return#5
|
||||
(byte*) heap_head#3 ← (byte*) heap_head#9
|
||||
(byte*~) main::$1 ← ((byte*)) (byte*~) main::$0
|
||||
(byte*) main::buf1#0 ← (byte*~) main::$1
|
||||
(byte*) main::buf1#0 ← (byte*~) main::$0
|
||||
(word) malloc::size#1 ← (number) $64
|
||||
call malloc
|
||||
(byte*) malloc::return#3 ← (byte*) malloc::return#1
|
||||
@ -51,10 +52,9 @@ main::@4: scope:[main] from main::@3
|
||||
(byte*) main::buf1#4 ← phi( main::@3/(byte*) main::buf1#0 )
|
||||
(byte*) heap_head#10 ← phi( main::@3/(byte*) heap_head#2 )
|
||||
(byte*) malloc::return#6 ← phi( main::@3/(byte*) malloc::return#3 )
|
||||
(byte*~) main::$2 ← (byte*) malloc::return#6
|
||||
(byte*~) main::$1 ← (byte*) malloc::return#6
|
||||
(byte*) heap_head#4 ← (byte*) heap_head#10
|
||||
(byte*~) main::$3 ← ((byte*)) (byte*~) main::$2
|
||||
(byte*) main::buf2#0 ← (byte*~) main::$3
|
||||
(byte*) main::buf2#0 ← (byte*~) main::$1
|
||||
(byte) main::i#0 ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@1 main::@4
|
||||
@ -63,24 +63,24 @@ main::@1: scope:[main] from main::@1 main::@4
|
||||
(byte*) main::buf1#1 ← phi( main::@1/(byte*) main::buf1#1 main::@4/(byte*) main::buf1#4 )
|
||||
(byte) main::i#2 ← phi( main::@1/(byte) main::i#1 main::@4/(byte) main::i#0 )
|
||||
*((byte*) main::buf1#1 + (byte) main::i#2) ← (byte) main::i#2
|
||||
(number~) main::$6 ← (number) $ff - (byte) main::i#2
|
||||
*((byte*) main::buf2#1 + (byte) main::i#2) ← (number~) main::$6
|
||||
(number~) main::$4 ← (number) $ff - (byte) main::i#2
|
||||
*((byte*) main::buf2#1 + (byte) main::i#2) ← (number~) main::$4
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,$63)
|
||||
(bool~) main::$7 ← (byte) main::i#1 != rangelast(0,$63)
|
||||
if((bool~) main::$7) goto main::@1
|
||||
(bool~) main::$5 ← (byte) main::i#1 != rangelast(0,$63)
|
||||
if((bool~) main::$5) goto main::@1
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte*) heap_head#17 ← phi( main::@1/(byte*) heap_head#18 )
|
||||
(byte*) main::buf2#4 ← phi( main::@1/(byte*) main::buf2#1 )
|
||||
(byte*) main::buf1#2 ← phi( main::@1/(byte*) main::buf1#1 )
|
||||
(byte*) free::ptr#0 ← (byte*) main::buf1#2
|
||||
(void*) free::ptr#0 ← (void*)(byte*) main::buf1#2
|
||||
call free
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@2
|
||||
(byte*) heap_head#16 ← phi( main::@2/(byte*) heap_head#17 )
|
||||
(byte*) main::buf1#5 ← phi( main::@2/(byte*) main::buf1#2 )
|
||||
(byte*) main::buf2#2 ← phi( main::@2/(byte*) main::buf2#4 )
|
||||
(byte*) free::ptr#1 ← (byte*) main::buf2#2
|
||||
(void*) free::ptr#1 ← (void*)(byte*) main::buf2#2
|
||||
call free
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@5
|
||||
@ -113,11 +113,11 @@ SYMBOL TABLE SSA
|
||||
(label) @end
|
||||
(byte*) HEAP_START
|
||||
(byte*) HEAP_START#0
|
||||
(void()) free((byte*) free::ptr)
|
||||
(void()) free((void*) free::ptr)
|
||||
(label) free::@return
|
||||
(byte*) free::ptr
|
||||
(byte*) free::ptr#0
|
||||
(byte*) free::ptr#1
|
||||
(void*) free::ptr
|
||||
(void*) free::ptr#0
|
||||
(void*) free::ptr#1
|
||||
(byte*) heap_head
|
||||
(byte*) heap_head#0
|
||||
(byte*) heap_head#1
|
||||
@ -141,10 +141,8 @@ SYMBOL TABLE SSA
|
||||
(void()) main()
|
||||
(byte*~) main::$0
|
||||
(byte*~) main::$1
|
||||
(byte*~) main::$2
|
||||
(byte*~) main::$3
|
||||
(number~) main::$6
|
||||
(bool~) main::$7
|
||||
(number~) main::$4
|
||||
(bool~) main::$5
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
@ -190,23 +188,19 @@ SYMBOL TABLE SSA
|
||||
|
||||
Adding number conversion cast (unumber) $64 in (word) malloc::size#0 ← (number) $64
|
||||
Adding number conversion cast (unumber) $64 in (word) malloc::size#1 ← (number) $64
|
||||
Adding number conversion cast (unumber) $ff in (number~) main::$6 ← (number) $ff - (byte) main::i#2
|
||||
Adding number conversion cast (unumber) main::$6 in (number~) main::$6 ← (unumber)(number) $ff - (byte) main::i#2
|
||||
Adding number conversion cast (unumber) $ff in (number~) main::$4 ← (number) $ff - (byte) main::i#2
|
||||
Adding number conversion cast (unumber) main::$4 in (number~) main::$4 ← (unumber)(number) $ff - (byte) main::i#2
|
||||
Adding number conversion cast (unumber) 0 in *((byte*) main::screen#0 + (number) 0) ← *((byte*) main::buf1#3)
|
||||
Adding number conversion cast (unumber) 1 in *((byte*) main::screen#0 + (number) 1) ← *((byte*) main::buf2#3)
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Inlining cast (byte*) HEAP_START#0 ← (byte*)(number) $c000
|
||||
Inlining cast (word) malloc::size#0 ← (unumber)(number) $64
|
||||
Inlining cast (byte*~) main::$1 ← (byte*)(byte*~) main::$0
|
||||
Inlining cast (word) malloc::size#1 ← (unumber)(number) $64
|
||||
Inlining cast (byte*~) main::$3 ← (byte*)(byte*~) main::$2
|
||||
Inlining cast (byte*) main::screen#0 ← (byte*)(number) $400
|
||||
Successful SSA optimization Pass2InlineCast
|
||||
Simplifying constant pointer cast (byte*) 49152
|
||||
Simplifying constant integer cast $64
|
||||
Simplifying constant integer cast (byte*~) main::$0
|
||||
Simplifying constant integer cast $64
|
||||
Simplifying constant integer cast (byte*~) main::$2
|
||||
Simplifying constant integer cast $ff
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast 0
|
||||
@ -218,16 +212,16 @@ Finalized unsigned number type (byte) $ff
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) 1
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Inferred type updated to byte in (unumber~) main::$6 ← (byte) $ff - (byte) main::i#2
|
||||
Inferred type updated to byte in (unumber~) main::$4 ← (byte) $ff - (byte) main::i#2
|
||||
Alias (byte*) HEAP_START#0 = (byte*) heap_head#0 (byte*) heap_head#15
|
||||
Alias (byte*) malloc::return#0 = (byte*) malloc::mem#0 (byte*) malloc::return#4 (byte*) malloc::return#1
|
||||
Alias (byte*) heap_head#1 = (byte*) heap_head#8 (byte*) heap_head#2
|
||||
Alias (byte*) malloc::return#2 = (byte*) malloc::return#5
|
||||
Alias (byte*) heap_head#3 = (byte*) heap_head#9
|
||||
Alias (byte*) main::buf1#0 = (byte*~) main::$1 (byte*~) main::$0 (byte*) main::buf1#4
|
||||
Alias (byte*) main::buf1#0 = (byte*~) main::$0 (byte*) main::buf1#4
|
||||
Alias (byte*) malloc::return#3 = (byte*) malloc::return#6
|
||||
Alias (byte*) heap_head#10 = (byte*) heap_head#4
|
||||
Alias (byte*) main::buf2#0 = (byte*~) main::$3 (byte*~) main::$2
|
||||
Alias (byte*) main::buf2#0 = (byte*~) main::$1
|
||||
Alias (byte*) main::buf1#1 = (byte*) main::buf1#2 (byte*) main::buf1#5 (byte*) main::buf1#3
|
||||
Alias (byte*) main::buf2#1 = (byte*) main::buf2#4 (byte*) main::buf2#2 (byte*) main::buf2#3
|
||||
Alias (byte*) heap_head#11 = (byte*) heap_head#17 (byte*) heap_head#18 (byte*) heap_head#16 (byte*) heap_head#14 (byte*) heap_head#5
|
||||
@ -245,7 +239,7 @@ Identical Phi Values (byte*) main::buf2#1 (byte*) main::buf2#0
|
||||
Identical Phi Values (byte*) heap_head#11 (byte*) heap_head#10
|
||||
Identical Phi Values (byte*) heap_head#12 (byte*) heap_head#11
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition (bool~) main::$7 [35] if((byte) main::i#1!=rangelast(0,$63)) goto main::@1
|
||||
Simple Condition (bool~) main::$5 [33] if((byte) main::i#1!=rangelast(0,$63)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) HEAP_START#0 = (byte*) 49152
|
||||
Constant (const word) malloc::size#0 = $64
|
||||
@ -253,12 +247,12 @@ Constant (const word) malloc::size#1 = $64
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Constant (const byte*) main::screen#0 = (byte*) 1024
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [33] main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value [35] if(main::i#1!=rangelast(0,$63)) goto main::@1 to (number) $64
|
||||
Simplifying expression containing zero main::screen#0 in [44] *((const byte*) main::screen#0 + (byte) 0) ← *((byte*) main::buf1#0)
|
||||
Resolved ranged next value [31] main::i#1 ← ++ main::i#2 to ++
|
||||
Resolved ranged comparison value [33] if(main::i#1!=rangelast(0,$63)) goto main::@1 to (number) $64
|
||||
Simplifying expression containing zero main::screen#0 in [42] *((const byte*) main::screen#0 + (byte) 0) ← *((byte*) main::buf1#0)
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused variable (byte*) free::ptr#0 and assignment [17] (byte*) free::ptr#0 ← (byte*) main::buf1#0
|
||||
Eliminating unused variable (byte*) free::ptr#1 and assignment [19] (byte*) free::ptr#1 ← (byte*) main::buf2#0
|
||||
Eliminating unused variable (void*) free::ptr#0 and assignment [17] (void*) free::ptr#0 ← (void*)(byte*) main::buf1#0
|
||||
Eliminating unused variable (void*) free::ptr#1 and assignment [19] (void*) free::ptr#1 ← (void*)(byte*) main::buf2#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding number conversion cast (unumber) $64 in if((byte) main::i#1!=(number) $64) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
@ -331,8 +325,8 @@ main::@4: scope:[main] from main::@3
|
||||
main::@1: scope:[main] from main::@1 main::@4
|
||||
[11] (byte) main::i#2 ← phi( main::@1/(byte) main::i#1 main::@4/(byte) 0 )
|
||||
[12] *((byte*) main::buf1#0 + (byte) main::i#2) ← (byte) main::i#2
|
||||
[13] (byte~) main::$6 ← (byte) $ff - (byte) main::i#2
|
||||
[14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$6
|
||||
[13] (byte~) main::$4 ← (byte) $ff - (byte) main::i#2
|
||||
[14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$4
|
||||
[15] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[16] if((byte) main::i#1!=(byte) $64) goto main::@1
|
||||
to:main::@2
|
||||
@ -369,13 +363,13 @@ malloc::@return: scope:[malloc] from malloc
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(byte*) HEAP_START
|
||||
(void()) free((byte*) free::ptr)
|
||||
(byte*) free::ptr
|
||||
(void()) free((void*) free::ptr)
|
||||
(void*) free::ptr
|
||||
(byte*) heap_head
|
||||
(byte*) heap_head#1 0.8
|
||||
(byte*) heap_head#7 3.0
|
||||
(void()) main()
|
||||
(byte~) main::$6 22.0
|
||||
(byte~) main::$4 22.0
|
||||
(byte*) main::buf1
|
||||
(byte*) main::buf1#0 1.0714285714285714
|
||||
(byte*) main::buf2
|
||||
@ -399,7 +393,7 @@ Added variable malloc::return#2 to zero page equivalence class [ malloc::return#
|
||||
Added variable main::buf1#0 to zero page equivalence class [ main::buf1#0 ]
|
||||
Added variable malloc::return#3 to zero page equivalence class [ malloc::return#3 ]
|
||||
Added variable main::buf2#0 to zero page equivalence class [ main::buf2#0 ]
|
||||
Added variable main::$6 to zero page equivalence class [ main::$6 ]
|
||||
Added variable main::$4 to zero page equivalence class [ main::$4 ]
|
||||
Added variable malloc::return#0 to zero page equivalence class [ malloc::return#0 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
@ -408,7 +402,7 @@ Complete equivalence classes
|
||||
[ main::buf1#0 ]
|
||||
[ malloc::return#3 ]
|
||||
[ main::buf2#0 ]
|
||||
[ main::$6 ]
|
||||
[ main::$4 ]
|
||||
[ malloc::return#0 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Allocated zp ZP_WORD:3 [ heap_head#7 heap_head#1 ]
|
||||
@ -416,7 +410,7 @@ Allocated zp ZP_WORD:5 [ malloc::return#2 ]
|
||||
Allocated zp ZP_WORD:7 [ main::buf1#0 ]
|
||||
Allocated zp ZP_WORD:9 [ malloc::return#3 ]
|
||||
Allocated zp ZP_WORD:11 [ main::buf2#0 ]
|
||||
Allocated zp ZP_BYTE:13 [ main::$6 ]
|
||||
Allocated zp ZP_BYTE:13 [ main::$4 ]
|
||||
Allocated zp ZP_WORD:14 [ malloc::return#0 ]
|
||||
|
||||
INITIAL ASM
|
||||
@ -449,7 +443,7 @@ bend:
|
||||
//SEG10 main
|
||||
main: {
|
||||
.label screen = $400
|
||||
.label _6 = $d
|
||||
.label _4 = $d
|
||||
.label buf1 = 7
|
||||
.label buf2 = $b
|
||||
.label i = 2
|
||||
@ -509,13 +503,13 @@ main: {
|
||||
lda i
|
||||
tay
|
||||
sta (buf1),y
|
||||
//SEG29 [13] (byte~) main::$6 ← (byte) $ff - (byte) main::i#2 -- vbuz1=vbuc1_minus_vbuz2
|
||||
//SEG29 [13] (byte~) main::$4 ← (byte) $ff - (byte) main::i#2 -- vbuz1=vbuc1_minus_vbuz2
|
||||
lda #$ff
|
||||
sec
|
||||
sbc i
|
||||
sta _6
|
||||
//SEG30 [14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$6 -- pbuz1_derefidx_vbuz2=vbuz3
|
||||
lda _6
|
||||
sta _4
|
||||
//SEG30 [14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$4 -- pbuz1_derefidx_vbuz2=vbuz3
|
||||
lda _4
|
||||
ldy i
|
||||
sta (buf2),y
|
||||
//SEG31 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||
@ -602,7 +596,7 @@ Statement [6] (byte*) malloc::return#2 ← (byte*) malloc::return#0 [ malloc::re
|
||||
Statement [7] (byte*) main::buf1#0 ← (byte*) malloc::return#2 [ main::buf1#0 heap_head#1 ] ( main:2 [ main::buf1#0 heap_head#1 ] ) always clobbers reg byte a
|
||||
Statement [9] (byte*) malloc::return#3 ← (byte*) malloc::return#0 [ main::buf1#0 malloc::return#3 ] ( main:2 [ main::buf1#0 malloc::return#3 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte*) main::buf2#0 ← (byte*) malloc::return#3 [ main::buf1#0 main::buf2#0 ] ( main:2 [ main::buf1#0 main::buf2#0 ] ) always clobbers reg byte a
|
||||
Statement [13] (byte~) main::$6 ← (byte) $ff - (byte) main::i#2 [ main::buf1#0 main::buf2#0 main::i#2 main::$6 ] ( main:2 [ main::buf1#0 main::buf2#0 main::i#2 main::$6 ] ) always clobbers reg byte a
|
||||
Statement [13] (byte~) main::$4 ← (byte) $ff - (byte) main::i#2 [ main::buf1#0 main::buf2#0 main::i#2 main::$4 ] ( main:2 [ main::buf1#0 main::buf2#0 main::i#2 main::$4 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Statement [21] *((const byte*) main::screen#0) ← *((byte*) main::buf1#0) [ main::buf2#0 ] ( main:2 [ main::buf2#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [22] *((const byte*) main::screen#0+(byte) 1) ← *((byte*) main::buf2#0) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
|
||||
@ -613,7 +607,7 @@ Statement [7] (byte*) main::buf1#0 ← (byte*) malloc::return#2 [ main::buf1#0 h
|
||||
Statement [9] (byte*) malloc::return#3 ← (byte*) malloc::return#0 [ main::buf1#0 malloc::return#3 ] ( main:2 [ main::buf1#0 malloc::return#3 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte*) main::buf2#0 ← (byte*) malloc::return#3 [ main::buf1#0 main::buf2#0 ] ( main:2 [ main::buf1#0 main::buf2#0 ] ) always clobbers reg byte a
|
||||
Statement [12] *((byte*) main::buf1#0 + (byte) main::i#2) ← (byte) main::i#2 [ main::buf1#0 main::buf2#0 main::i#2 ] ( main:2 [ main::buf1#0 main::buf2#0 main::i#2 ] ) always clobbers reg byte a
|
||||
Statement [13] (byte~) main::$6 ← (byte) $ff - (byte) main::i#2 [ main::buf1#0 main::buf2#0 main::i#2 main::$6 ] ( main:2 [ main::buf1#0 main::buf2#0 main::i#2 main::$6 ] ) always clobbers reg byte a
|
||||
Statement [13] (byte~) main::$4 ← (byte) $ff - (byte) main::i#2 [ main::buf1#0 main::buf2#0 main::i#2 main::$4 ] ( main:2 [ main::buf1#0 main::buf2#0 main::i#2 main::$4 ] ) always clobbers reg byte a
|
||||
Statement [21] *((const byte*) main::screen#0) ← *((byte*) main::buf1#0) [ main::buf2#0 ] ( main:2 [ main::buf2#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [22] *((const byte*) main::screen#0+(byte) 1) ← *((byte*) main::buf2#0) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
|
||||
Statement [27] (byte*) malloc::return#0 ← (byte*) heap_head#7 [ malloc::return#0 heap_head#7 ] ( main:2::malloc:5 [ malloc::return#0 heap_head#7 ] main:2::malloc:8 [ main::buf1#0 malloc::return#0 heap_head#7 ] ) always clobbers reg byte a
|
||||
@ -624,16 +618,16 @@ Potential registers zp ZP_WORD:5 [ malloc::return#2 ] : zp ZP_WORD:5 ,
|
||||
Potential registers zp ZP_WORD:7 [ main::buf1#0 ] : zp ZP_WORD:7 ,
|
||||
Potential registers zp ZP_WORD:9 [ malloc::return#3 ] : zp ZP_WORD:9 ,
|
||||
Potential registers zp ZP_WORD:11 [ main::buf2#0 ] : zp ZP_WORD:11 ,
|
||||
Potential registers zp ZP_BYTE:13 [ main::$6 ] : zp ZP_BYTE:13 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_BYTE:13 [ main::$4 ] : zp ZP_BYTE:13 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp ZP_WORD:14 [ malloc::return#0 ] : zp ZP_WORD:14 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 33: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:13 [ main::$6 ] 1.25: zp ZP_WORD:11 [ main::buf2#0 ] 1.07: zp ZP_WORD:7 [ main::buf1#0 ]
|
||||
Uplift Scope [main] 33: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:13 [ main::$4 ] 1.25: zp ZP_WORD:11 [ main::buf2#0 ] 1.07: zp ZP_WORD:7 [ main::buf1#0 ]
|
||||
Uplift Scope [malloc] 4: zp ZP_WORD:5 [ malloc::return#2 ] 4: zp ZP_WORD:9 [ malloc::return#3 ] 1.2: zp ZP_WORD:14 [ malloc::return#0 ]
|
||||
Uplift Scope [] 3.8: zp ZP_WORD:3 [ heap_head#7 heap_head#1 ]
|
||||
Uplift Scope [free]
|
||||
|
||||
Uplifting [main] best 579 combination reg byte y [ main::i#2 main::i#1 ] reg byte a [ main::$6 ] zp ZP_WORD:11 [ main::buf2#0 ] zp ZP_WORD:7 [ main::buf1#0 ]
|
||||
Uplifting [main] best 579 combination reg byte y [ main::i#2 main::i#1 ] reg byte a [ main::$4 ] zp ZP_WORD:11 [ main::buf2#0 ] zp ZP_WORD:7 [ main::buf1#0 ]
|
||||
Uplifting [malloc] best 579 combination zp ZP_WORD:5 [ malloc::return#2 ] zp ZP_WORD:9 [ malloc::return#3 ] zp ZP_WORD:14 [ malloc::return#0 ]
|
||||
Uplifting [] best 579 combination zp ZP_WORD:3 [ heap_head#7 heap_head#1 ]
|
||||
Uplifting [free] best 579 combination
|
||||
@ -718,12 +712,12 @@ main: {
|
||||
//SEG28 [12] *((byte*) main::buf1#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuz1_derefidx_vbuyy=vbuyy
|
||||
tya
|
||||
sta (buf1),y
|
||||
//SEG29 [13] (byte~) main::$6 ← (byte) $ff - (byte) main::i#2 -- vbuaa=vbuc1_minus_vbuyy
|
||||
//SEG29 [13] (byte~) main::$4 ← (byte) $ff - (byte) main::i#2 -- vbuaa=vbuc1_minus_vbuyy
|
||||
tya
|
||||
eor #$ff
|
||||
clc
|
||||
adc #$ff+1
|
||||
//SEG30 [14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$6 -- pbuz1_derefidx_vbuyy=vbuaa
|
||||
//SEG30 [14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$4 -- pbuz1_derefidx_vbuyy=vbuaa
|
||||
sta (buf2),y
|
||||
//SEG31 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
@ -855,14 +849,14 @@ FINAL SYMBOL TABLE
|
||||
(label) @end
|
||||
(byte*) HEAP_START
|
||||
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
|
||||
(void()) free((byte*) free::ptr)
|
||||
(void()) free((void*) free::ptr)
|
||||
(label) free::@return
|
||||
(byte*) free::ptr
|
||||
(void*) free::ptr
|
||||
(byte*) heap_head
|
||||
(byte*) heap_head#1 heap_head zp ZP_WORD:2 0.8
|
||||
(byte*) heap_head#7 heap_head zp ZP_WORD:2 3.0
|
||||
(void()) main()
|
||||
(byte~) main::$6 reg byte a 22.0
|
||||
(byte~) main::$4 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
@ -892,7 +886,7 @@ reg byte y [ main::i#2 main::i#1 ]
|
||||
zp ZP_WORD:2 [ heap_head#7 heap_head#1 ]
|
||||
zp ZP_WORD:4 [ malloc::return#2 main::buf1#0 ]
|
||||
zp ZP_WORD:6 [ malloc::return#3 main::buf2#0 malloc::return#0 ]
|
||||
reg byte a [ main::$6 ]
|
||||
reg byte a [ main::$4 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
@ -952,12 +946,12 @@ main: {
|
||||
//SEG28 [12] *((byte*) main::buf1#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuz1_derefidx_vbuyy=vbuyy
|
||||
tya
|
||||
sta (buf1),y
|
||||
//SEG29 [13] (byte~) main::$6 ← (byte) $ff - (byte) main::i#2 -- vbuaa=vbuc1_minus_vbuyy
|
||||
//SEG29 [13] (byte~) main::$4 ← (byte) $ff - (byte) main::i#2 -- vbuaa=vbuc1_minus_vbuyy
|
||||
tya
|
||||
eor #$ff
|
||||
clc
|
||||
adc #$ff+1
|
||||
//SEG30 [14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$6 -- pbuz1_derefidx_vbuyy=vbuaa
|
||||
//SEG30 [14] *((byte*) main::buf2#0 + (byte) main::i#2) ← (byte~) main::$4 -- pbuz1_derefidx_vbuyy=vbuaa
|
||||
sta (buf2),y
|
||||
//SEG31 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
|
@ -3,14 +3,14 @@
|
||||
(label) @end
|
||||
(byte*) HEAP_START
|
||||
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
|
||||
(void()) free((byte*) free::ptr)
|
||||
(void()) free((void*) free::ptr)
|
||||
(label) free::@return
|
||||
(byte*) free::ptr
|
||||
(void*) free::ptr
|
||||
(byte*) heap_head
|
||||
(byte*) heap_head#1 heap_head zp ZP_WORD:2 0.8
|
||||
(byte*) heap_head#7 heap_head zp ZP_WORD:2 3.0
|
||||
(void()) main()
|
||||
(byte~) main::$6 reg byte a 22.0
|
||||
(byte~) main::$4 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
@ -40,4 +40,4 @@ reg byte y [ main::i#2 main::i#1 ]
|
||||
zp ZP_WORD:2 [ heap_head#7 heap_head#1 ]
|
||||
zp ZP_WORD:4 [ malloc::return#2 main::buf1#0 ]
|
||||
zp ZP_WORD:6 [ malloc::return#3 main::buf2#0 malloc::return#0 ]
|
||||
reg byte a [ main::$6 ]
|
||||
reg byte a [ main::$4 ]
|
||||
|
350
src/test/ref/screen-center-distance.asm
Normal file
350
src/test/ref/screen-center-distance.asm
Normal file
@ -0,0 +1,350 @@
|
||||
// Calculate the distance to the center of the screen - and show it using font-hex
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_WORD = 2
|
||||
// Start of the heap used by malloc()
|
||||
.label HEAP_START = $c000
|
||||
.label D018 = $d018
|
||||
.label CHARSET = $2000
|
||||
.label SCREEN = $2800
|
||||
.const NUM_SQUARES = $30
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CHARSET)/4&$f
|
||||
.label yds = $16
|
||||
.label xds = $18
|
||||
.label ds = $18
|
||||
.label screen = 4
|
||||
.label x = 3
|
||||
.label y = 2
|
||||
jsr init_font_hex
|
||||
lda #toD0181_return
|
||||
sta D018
|
||||
jsr init_squares
|
||||
lda #<SCREEN
|
||||
sta screen
|
||||
lda #>SCREEN
|
||||
sta screen+1
|
||||
lda #0
|
||||
sta y
|
||||
b1:
|
||||
lda y
|
||||
asl
|
||||
cmp #$18
|
||||
bcs b2
|
||||
eor #$ff
|
||||
clc
|
||||
adc #$18+1
|
||||
b4:
|
||||
jsr sqr
|
||||
lda sqr.return_2
|
||||
sta sqr.return
|
||||
lda sqr.return_2+1
|
||||
sta sqr.return+1
|
||||
lda #0
|
||||
sta x
|
||||
b5:
|
||||
lda x
|
||||
asl
|
||||
cmp #$27
|
||||
bcs b6
|
||||
eor #$ff
|
||||
clc
|
||||
adc #$27+1
|
||||
b8:
|
||||
jsr sqr
|
||||
lda ds
|
||||
clc
|
||||
adc yds
|
||||
sta ds
|
||||
lda ds+1
|
||||
adc yds+1
|
||||
sta ds+1
|
||||
jsr sqrt
|
||||
ldy #0
|
||||
sta (screen),y
|
||||
inc screen
|
||||
bne !+
|
||||
inc screen+1
|
||||
!:
|
||||
inc x
|
||||
lda #$28
|
||||
cmp x
|
||||
bne b5
|
||||
inc y
|
||||
lda #$19
|
||||
cmp y
|
||||
bne b1
|
||||
rts
|
||||
b6:
|
||||
sec
|
||||
sbc #$27
|
||||
jmp b8
|
||||
b2:
|
||||
sec
|
||||
sbc #$18
|
||||
jmp b4
|
||||
}
|
||||
// Find the (integer) square root of a word value
|
||||
// If the square is not an integer then it returns the largest integer N where N*N <= val
|
||||
// Uses a table of squares that must be initialized by calling init_squares()
|
||||
// sqrt(word zeropage($18) val)
|
||||
sqrt: {
|
||||
.label _3 = 6
|
||||
.label val = $18
|
||||
.label found = 6
|
||||
jsr bsearch16u
|
||||
lda _3
|
||||
sec
|
||||
sbc #<HEAP_START
|
||||
sta _3
|
||||
lda _3+1
|
||||
sbc #>HEAP_START
|
||||
sta _3+1
|
||||
lda _3
|
||||
lsr
|
||||
rts
|
||||
}
|
||||
// Searches an array of nitems unsigned words, the initial member of which is pointed to by base, for a member that matches the value key.
|
||||
// - key - The value to look for
|
||||
// - items - Pointer to the start of the array to search in
|
||||
// - num - The number of items in the array
|
||||
// Returns pointer to an entry in the array that matches the search key
|
||||
// bsearch16u(word zeropage($18) key, word* zeropage(6) items, byte register(X) num)
|
||||
bsearch16u: {
|
||||
.label _2 = 6
|
||||
.label key = $18
|
||||
.label return = 6
|
||||
.label pivot = $1a
|
||||
.label result = $1c
|
||||
.label items = 6
|
||||
lda #<HEAP_START
|
||||
sta items
|
||||
lda #>HEAP_START
|
||||
sta items+1
|
||||
ldx #NUM_SQUARES
|
||||
b3:
|
||||
cpx #0
|
||||
bne b4
|
||||
ldy #1
|
||||
lda (items),y
|
||||
cmp key+1
|
||||
bne !+
|
||||
dey
|
||||
lda (items),y
|
||||
cmp key
|
||||
beq b2
|
||||
!:
|
||||
bcc b2
|
||||
lda _2
|
||||
sec
|
||||
sbc #<1*SIZEOF_WORD
|
||||
sta _2
|
||||
lda _2+1
|
||||
sbc #>1*SIZEOF_WORD
|
||||
sta _2+1
|
||||
b2:
|
||||
rts
|
||||
b4:
|
||||
txa
|
||||
lsr
|
||||
asl
|
||||
clc
|
||||
adc items
|
||||
sta pivot
|
||||
lda #0
|
||||
adc items+1
|
||||
sta pivot+1
|
||||
sec
|
||||
lda key
|
||||
ldy #0
|
||||
sbc (pivot),y
|
||||
sta result
|
||||
lda key+1
|
||||
iny
|
||||
sbc (pivot),y
|
||||
sta result+1
|
||||
bne b6
|
||||
lda result
|
||||
bne b6
|
||||
lda pivot
|
||||
sta return
|
||||
lda pivot+1
|
||||
sta return+1
|
||||
rts
|
||||
b6:
|
||||
lda result+1
|
||||
bmi b7
|
||||
bne !+
|
||||
lda result
|
||||
beq b7
|
||||
!:
|
||||
lda #1*SIZEOF_WORD
|
||||
clc
|
||||
adc pivot
|
||||
sta items
|
||||
lda #0
|
||||
adc pivot+1
|
||||
sta items+1
|
||||
dex
|
||||
b7:
|
||||
txa
|
||||
lsr
|
||||
tax
|
||||
jmp b3
|
||||
}
|
||||
// Find the square of a byte value
|
||||
// Uses a table of squares that must be initialized by calling init_squares()
|
||||
// sqr(byte register(A) val)
|
||||
sqr: {
|
||||
.label return = $16
|
||||
.label return_1 = $18
|
||||
.label return_2 = $18
|
||||
asl
|
||||
tay
|
||||
lda HEAP_START,y
|
||||
sta return_2
|
||||
lda #0
|
||||
sta return_2+1
|
||||
rts
|
||||
}
|
||||
// Initialize squares table
|
||||
// Uses iterative formula (x+1)^2 = x^2 + 2*x + 1
|
||||
init_squares: {
|
||||
.label squares = $b
|
||||
.label sqr = 9
|
||||
jsr malloc
|
||||
ldx #0
|
||||
lda #<HEAP_START
|
||||
sta squares
|
||||
lda #>HEAP_START
|
||||
sta squares+1
|
||||
txa
|
||||
sta sqr
|
||||
sta sqr+1
|
||||
b1:
|
||||
ldy #0
|
||||
lda sqr
|
||||
sta (squares),y
|
||||
iny
|
||||
lda sqr+1
|
||||
sta (squares),y
|
||||
lda #SIZEOF_WORD
|
||||
clc
|
||||
adc squares
|
||||
sta squares
|
||||
bcc !+
|
||||
inc squares+1
|
||||
!:
|
||||
txa
|
||||
asl
|
||||
clc
|
||||
adc #1
|
||||
clc
|
||||
adc sqr
|
||||
sta sqr
|
||||
bcc !+
|
||||
inc sqr+1
|
||||
!:
|
||||
inx
|
||||
cpx #NUM_SQUARES-1+1
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
rts
|
||||
}
|
||||
// Make charset from proto chars
|
||||
// init_font_hex(byte* zeropage($10) charset)
|
||||
init_font_hex: {
|
||||
.label _0 = $1e
|
||||
.label idx = $15
|
||||
.label proto_lo = $12
|
||||
.label charset = $10
|
||||
.label c1 = $14
|
||||
.label proto_hi = $d
|
||||
.label c = $f
|
||||
lda #0
|
||||
sta c
|
||||
lda #<FONT_HEX_PROTO
|
||||
sta proto_hi
|
||||
lda #>FONT_HEX_PROTO
|
||||
sta proto_hi+1
|
||||
lda #<CHARSET
|
||||
sta charset
|
||||
lda #>CHARSET
|
||||
sta charset+1
|
||||
b1:
|
||||
lda #0
|
||||
sta c1
|
||||
lda #<FONT_HEX_PROTO
|
||||
sta proto_lo
|
||||
lda #>FONT_HEX_PROTO
|
||||
sta proto_lo+1
|
||||
b2:
|
||||
lda #0
|
||||
tay
|
||||
sta (charset),y
|
||||
lda #1
|
||||
sta idx
|
||||
ldx #0
|
||||
b3:
|
||||
txa
|
||||
tay
|
||||
lda (proto_hi),y
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta _0
|
||||
txa
|
||||
tay
|
||||
lda (proto_lo),y
|
||||
asl
|
||||
ora _0
|
||||
ldy idx
|
||||
sta (charset),y
|
||||
inc idx
|
||||
inx
|
||||
cpx #5
|
||||
bne b3
|
||||
lda #0
|
||||
ldy idx
|
||||
sta (charset),y
|
||||
iny
|
||||
sta (charset),y
|
||||
lda #5
|
||||
clc
|
||||
adc proto_lo
|
||||
sta proto_lo
|
||||
bcc !+
|
||||
inc proto_lo+1
|
||||
!:
|
||||
lda #8
|
||||
clc
|
||||
adc charset
|
||||
sta charset
|
||||
bcc !+
|
||||
inc charset+1
|
||||
!:
|
||||
inc c1
|
||||
lda #$10
|
||||
cmp c1
|
||||
bne b2
|
||||
lda #5
|
||||
clc
|
||||
adc proto_hi
|
||||
sta proto_hi
|
||||
bcc !+
|
||||
inc proto_hi+1
|
||||
!:
|
||||
inc c
|
||||
lda #$10
|
||||
cmp c
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
// Bit patterns for symbols 0-f (3x5 pixels) used in font hex
|
||||
FONT_HEX_PROTO: .byte 2, 5, 5, 5, 2, 6, 2, 2, 2, 7, 6, 1, 2, 4, 7, 6, 1, 2, 1, 6, 5, 5, 7, 1, 1, 7, 4, 6, 1, 6, 3, 4, 6, 5, 2, 7, 1, 1, 1, 1, 2, 5, 2, 5, 2, 2, 5, 3, 1, 1, 2, 5, 7, 5, 5, 6, 5, 6, 5, 6, 2, 5, 4, 5, 2, 6, 5, 5, 5, 6, 7, 4, 6, 4, 7, 7, 4, 6, 4, 4
|
212
src/test/ref/screen-center-distance.cfg
Normal file
212
src/test/ref/screen-center-distance.cfg
Normal file
@ -0,0 +1,212 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
[5] call init_font_hex
|
||||
to:main::toD0181
|
||||
main::toD0181: scope:[main] from main
|
||||
[6] phi()
|
||||
to:main::@10
|
||||
main::@10: scope:[main] from main::toD0181
|
||||
[7] *((const byte*) D018#0) ← (const byte) main::toD0181_return#0
|
||||
[8] call init_squares
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@10 main::@9
|
||||
[9] (byte*) main::screen#10 ← phi( main::@9/(byte*) main::screen#1 main::@10/(const byte*) SCREEN#0 )
|
||||
[9] (byte) main::y#10 ← phi( main::@9/(byte) main::y#1 main::@10/(byte) 0 )
|
||||
[10] (byte) main::y2#0 ← (byte) main::y#10 << (byte) 1
|
||||
[11] if((byte) main::y2#0>=(byte) $18) goto main::@2
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1
|
||||
[12] (byte~) main::$6 ← (byte) $18 - (byte) main::y2#0
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2 main::@3
|
||||
[13] (byte) main::yd#0 ← phi( main::@2/(byte~) main::$8 main::@3/(byte~) main::$6 )
|
||||
[14] (byte) sqr::val#0 ← (byte) main::yd#0
|
||||
[15] call sqr
|
||||
[16] (word) sqr::return#0 ← (word) sqr::return#2
|
||||
to:main::@11
|
||||
main::@11: scope:[main] from main::@4
|
||||
[17] (word) main::yds#0 ← (word) sqr::return#0
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@11 main::@13
|
||||
[18] (byte*) main::screen#2 ← phi( main::@11/(byte*) main::screen#10 main::@13/(byte*) main::screen#1 )
|
||||
[18] (byte) main::x#2 ← phi( main::@11/(byte) 0 main::@13/(byte) main::x#1 )
|
||||
[19] (byte) main::x2#0 ← (byte) main::x#2 << (byte) 1
|
||||
[20] if((byte) main::x2#0>=(byte) $27) goto main::@6
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@5
|
||||
[21] (byte~) main::$14 ← (byte) $27 - (byte) main::x2#0
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@6 main::@7
|
||||
[22] (byte) main::xd#0 ← phi( main::@6/(byte~) main::$16 main::@7/(byte~) main::$14 )
|
||||
[23] (byte) sqr::val#1 ← (byte) main::xd#0
|
||||
[24] call sqr
|
||||
[25] (word) sqr::return#1 ← (word) sqr::return#2
|
||||
to:main::@12
|
||||
main::@12: scope:[main] from main::@8
|
||||
[26] (word) main::xds#0 ← (word) sqr::return#1
|
||||
[27] (word) main::ds#0 ← (word) main::xds#0 + (word) main::yds#0
|
||||
[28] (word) sqrt::val#0 ← (word) main::ds#0
|
||||
[29] call sqrt
|
||||
[30] (byte) sqrt::return#0 ← (byte) sqrt::return#1
|
||||
to:main::@13
|
||||
main::@13: scope:[main] from main::@12
|
||||
[31] (byte) main::d#0 ← (byte) sqrt::return#0
|
||||
[32] *((byte*) main::screen#2) ← (byte) main::d#0
|
||||
[33] (byte*) main::screen#1 ← ++ (byte*) main::screen#2
|
||||
[34] (byte) main::x#1 ← ++ (byte) main::x#2
|
||||
[35] if((byte) main::x#1!=(byte) $28) goto main::@5
|
||||
to:main::@9
|
||||
main::@9: scope:[main] from main::@13
|
||||
[36] (byte) main::y#1 ← ++ (byte) main::y#10
|
||||
[37] if((byte) main::y#1!=(byte) $19) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@9
|
||||
[38] return
|
||||
to:@return
|
||||
main::@6: scope:[main] from main::@5
|
||||
[39] (byte~) main::$16 ← (byte) main::x2#0 - (byte) $27
|
||||
to:main::@8
|
||||
main::@2: scope:[main] from main::@1
|
||||
[40] (byte~) main::$8 ← (byte) main::y2#0 - (byte) $18
|
||||
to:main::@4
|
||||
sqrt: scope:[sqrt] from main::@12
|
||||
[41] (word) bsearch16u::key#0 ← (word) sqrt::val#0
|
||||
[42] call bsearch16u
|
||||
[43] (word*) bsearch16u::return#0 ← (word*) bsearch16u::return#2
|
||||
to:sqrt::@1
|
||||
sqrt::@1: scope:[sqrt] from sqrt
|
||||
[44] (word*) sqrt::found#0 ← (word*) bsearch16u::return#0
|
||||
[45] (word~) sqrt::$3 ← (byte*)(word*) sqrt::found#0 - (const byte*) HEAP_START#0
|
||||
[46] (byte~) sqrt::$4 ← (byte)(word~) sqrt::$3
|
||||
[47] (byte) sqrt::return#1 ← (byte~) sqrt::$4 >> (byte) 1
|
||||
to:sqrt::@return
|
||||
sqrt::@return: scope:[sqrt] from sqrt::@1
|
||||
[48] return
|
||||
to:@return
|
||||
bsearch16u: scope:[bsearch16u] from sqrt
|
||||
[49] phi()
|
||||
to:bsearch16u::@3
|
||||
bsearch16u::@3: scope:[bsearch16u] from bsearch16u bsearch16u::@7
|
||||
[50] (word*) bsearch16u::items#2 ← phi( bsearch16u/(const byte*) HEAP_START#0 bsearch16u::@7/(word*) bsearch16u::items#8 )
|
||||
[50] (byte) bsearch16u::num#3 ← phi( bsearch16u/(const byte) NUM_SQUARES#0 bsearch16u::@7/(byte) bsearch16u::num#1 )
|
||||
[51] if((byte) bsearch16u::num#3>(byte) 0) goto bsearch16u::@4
|
||||
to:bsearch16u::@5
|
||||
bsearch16u::@5: scope:[bsearch16u] from bsearch16u::@3
|
||||
[52] if(*((word*) bsearch16u::items#2)<=(word) bsearch16u::key#0) goto bsearch16u::@2
|
||||
to:bsearch16u::@1
|
||||
bsearch16u::@1: scope:[bsearch16u] from bsearch16u::@5
|
||||
[53] (word*~) bsearch16u::$2 ← (word*) bsearch16u::items#2 - (byte) 1*(const byte) SIZEOF_WORD
|
||||
to:bsearch16u::@2
|
||||
bsearch16u::@2: scope:[bsearch16u] from bsearch16u::@1 bsearch16u::@5
|
||||
[54] (word*) bsearch16u::return#3 ← phi( bsearch16u::@5/(word*) bsearch16u::items#2 bsearch16u::@1/(word*~) bsearch16u::$2 )
|
||||
to:bsearch16u::@return
|
||||
bsearch16u::@return: scope:[bsearch16u] from bsearch16u::@2 bsearch16u::@8
|
||||
[55] (word*) bsearch16u::return#2 ← phi( bsearch16u::@8/(word*~) bsearch16u::return#6 bsearch16u::@2/(word*) bsearch16u::return#3 )
|
||||
[56] return
|
||||
to:@return
|
||||
bsearch16u::@4: scope:[bsearch16u] from bsearch16u::@3
|
||||
[57] (byte~) bsearch16u::$6 ← (byte) bsearch16u::num#3 >> (byte) 1
|
||||
[58] (byte~) bsearch16u::$16 ← (byte~) bsearch16u::$6 << (byte) 1
|
||||
[59] (word*) bsearch16u::pivot#0 ← (word*) bsearch16u::items#2 + (byte~) bsearch16u::$16
|
||||
[60] (signed word) bsearch16u::result#0 ← (signed word)(word) bsearch16u::key#0 - (signed word)*((word*) bsearch16u::pivot#0)
|
||||
[61] if((signed word) bsearch16u::result#0!=(signed byte) 0) goto bsearch16u::@6
|
||||
to:bsearch16u::@8
|
||||
bsearch16u::@8: scope:[bsearch16u] from bsearch16u::@4
|
||||
[62] (word*~) bsearch16u::return#6 ← (word*) bsearch16u::pivot#0
|
||||
to:bsearch16u::@return
|
||||
bsearch16u::@6: scope:[bsearch16u] from bsearch16u::@4
|
||||
[63] if((signed word) bsearch16u::result#0<=(signed byte) 0) goto bsearch16u::@7
|
||||
to:bsearch16u::@9
|
||||
bsearch16u::@9: scope:[bsearch16u] from bsearch16u::@6
|
||||
[64] (word*) bsearch16u::items#1 ← (word*) bsearch16u::pivot#0 + (byte) 1*(const byte) SIZEOF_WORD
|
||||
[65] (byte) bsearch16u::num#2 ← -- (byte) bsearch16u::num#3
|
||||
to:bsearch16u::@7
|
||||
bsearch16u::@7: scope:[bsearch16u] from bsearch16u::@6 bsearch16u::@9
|
||||
[66] (word*) bsearch16u::items#8 ← phi( bsearch16u::@9/(word*) bsearch16u::items#1 bsearch16u::@6/(word*) bsearch16u::items#2 )
|
||||
[66] (byte) bsearch16u::num#5 ← phi( bsearch16u::@9/(byte) bsearch16u::num#2 bsearch16u::@6/(byte) bsearch16u::num#3 )
|
||||
[67] (byte) bsearch16u::num#1 ← (byte) bsearch16u::num#5 >> (byte) 1
|
||||
to:bsearch16u::@3
|
||||
sqr: scope:[sqr] from main::@4 main::@8
|
||||
[68] (byte) sqr::val#2 ← phi( main::@4/(byte) sqr::val#0 main::@8/(byte) sqr::val#1 )
|
||||
[69] (byte~) sqr::$0 ← (byte) sqr::val#2 << (byte) 1
|
||||
[70] (word) sqr::return#2 ← *((const byte*) HEAP_START#0 + (byte~) sqr::$0)
|
||||
to:sqr::@return
|
||||
sqr::@return: scope:[sqr] from sqr
|
||||
[71] return
|
||||
to:@return
|
||||
init_squares: scope:[init_squares] from main::@10
|
||||
[72] phi()
|
||||
[73] call malloc
|
||||
to:init_squares::@1
|
||||
init_squares::@1: scope:[init_squares] from init_squares init_squares::@1
|
||||
[74] (byte) init_squares::i#2 ← phi( init_squares::@1/(byte) init_squares::i#1 init_squares/(byte) 0 )
|
||||
[74] (word*) init_squares::squares#2 ← phi( init_squares::@1/(word*) init_squares::squares#1 init_squares/(const byte*) HEAP_START#0 )
|
||||
[74] (word) init_squares::sqr#2 ← phi( init_squares::@1/(word) init_squares::sqr#1 init_squares/(byte) 0 )
|
||||
[75] *((word*) init_squares::squares#2) ← (word) init_squares::sqr#2
|
||||
[76] (word*) init_squares::squares#1 ← (word*) init_squares::squares#2 + (const byte) SIZEOF_WORD
|
||||
[77] (byte~) init_squares::$3 ← (byte) init_squares::i#2 << (byte) 1
|
||||
[78] (byte~) init_squares::$4 ← (byte~) init_squares::$3 + (byte) 1
|
||||
[79] (word) init_squares::sqr#1 ← (word) init_squares::sqr#2 + (byte~) init_squares::$4
|
||||
[80] (byte) init_squares::i#1 ← ++ (byte) init_squares::i#2
|
||||
[81] if((byte) init_squares::i#1!=(const byte) NUM_SQUARES#0-(byte) 1+(byte) 1) goto init_squares::@1
|
||||
to:init_squares::@return
|
||||
init_squares::@return: scope:[init_squares] from init_squares::@1
|
||||
[82] return
|
||||
to:@return
|
||||
malloc: scope:[malloc] from init_squares
|
||||
[83] phi()
|
||||
to:malloc::@return
|
||||
malloc::@return: scope:[malloc] from malloc
|
||||
[84] return
|
||||
to:@return
|
||||
init_font_hex: scope:[init_font_hex] from main
|
||||
[85] phi()
|
||||
to:init_font_hex::@1
|
||||
init_font_hex::@1: scope:[init_font_hex] from init_font_hex init_font_hex::@5
|
||||
[86] (byte) init_font_hex::c#6 ← phi( init_font_hex/(byte) 0 init_font_hex::@5/(byte) init_font_hex::c#1 )
|
||||
[86] (byte*) init_font_hex::proto_hi#6 ← phi( init_font_hex/(const byte[]) FONT_HEX_PROTO#0 init_font_hex::@5/(byte*) init_font_hex::proto_hi#1 )
|
||||
[86] (byte*) init_font_hex::charset#5 ← phi( init_font_hex/(const byte*) CHARSET#0 init_font_hex::@5/(byte*) init_font_hex::charset#0 )
|
||||
to:init_font_hex::@2
|
||||
init_font_hex::@2: scope:[init_font_hex] from init_font_hex::@1 init_font_hex::@4
|
||||
[87] (byte) init_font_hex::c1#4 ← phi( init_font_hex::@1/(byte) 0 init_font_hex::@4/(byte) init_font_hex::c1#1 )
|
||||
[87] (byte*) init_font_hex::proto_lo#4 ← phi( init_font_hex::@1/(const byte[]) FONT_HEX_PROTO#0 init_font_hex::@4/(byte*) init_font_hex::proto_lo#1 )
|
||||
[87] (byte*) init_font_hex::charset#2 ← phi( init_font_hex::@1/(byte*) init_font_hex::charset#5 init_font_hex::@4/(byte*) init_font_hex::charset#0 )
|
||||
[88] *((byte*) init_font_hex::charset#2) ← (byte) 0
|
||||
to:init_font_hex::@3
|
||||
init_font_hex::@3: scope:[init_font_hex] from init_font_hex::@2 init_font_hex::@3
|
||||
[89] (byte) init_font_hex::idx#5 ← phi( init_font_hex::@2/(byte) 1 init_font_hex::@3/(byte) init_font_hex::idx#2 )
|
||||
[89] (byte) init_font_hex::i#2 ← phi( init_font_hex::@2/(byte) 0 init_font_hex::@3/(byte) init_font_hex::i#1 )
|
||||
[90] (byte~) init_font_hex::$0 ← *((byte*) init_font_hex::proto_hi#6 + (byte) init_font_hex::i#2) << (byte) 4
|
||||
[91] (byte~) init_font_hex::$1 ← *((byte*) init_font_hex::proto_lo#4 + (byte) init_font_hex::i#2) << (byte) 1
|
||||
[92] (byte~) init_font_hex::$2 ← (byte~) init_font_hex::$0 | (byte~) init_font_hex::$1
|
||||
[93] *((byte*) init_font_hex::charset#2 + (byte) init_font_hex::idx#5) ← (byte~) init_font_hex::$2
|
||||
[94] (byte) init_font_hex::idx#2 ← ++ (byte) init_font_hex::idx#5
|
||||
[95] (byte) init_font_hex::i#1 ← ++ (byte) init_font_hex::i#2
|
||||
[96] if((byte) init_font_hex::i#1!=(byte) 5) goto init_font_hex::@3
|
||||
to:init_font_hex::@4
|
||||
init_font_hex::@4: scope:[init_font_hex] from init_font_hex::@3
|
||||
[97] *((byte*) init_font_hex::charset#2 + (byte) init_font_hex::idx#2) ← (byte) 0
|
||||
[98] (byte) init_font_hex::idx#3 ← ++ (byte) init_font_hex::idx#2
|
||||
[99] *((byte*) init_font_hex::charset#2 + (byte) init_font_hex::idx#3) ← (byte) 0
|
||||
[100] (byte*) init_font_hex::proto_lo#1 ← (byte*) init_font_hex::proto_lo#4 + (byte) 5
|
||||
[101] (byte*) init_font_hex::charset#0 ← (byte*) init_font_hex::charset#2 + (byte) 8
|
||||
[102] (byte) init_font_hex::c1#1 ← ++ (byte) init_font_hex::c1#4
|
||||
[103] if((byte) init_font_hex::c1#1!=(byte) $10) goto init_font_hex::@2
|
||||
to:init_font_hex::@5
|
||||
init_font_hex::@5: scope:[init_font_hex] from init_font_hex::@4
|
||||
[104] (byte*) init_font_hex::proto_hi#1 ← (byte*) init_font_hex::proto_hi#6 + (byte) 5
|
||||
[105] (byte) init_font_hex::c#1 ← ++ (byte) init_font_hex::c#6
|
||||
[106] if((byte) init_font_hex::c#1!=(byte) $10) goto init_font_hex::@1
|
||||
to:init_font_hex::@return
|
||||
init_font_hex::@return: scope:[init_font_hex] from init_font_hex::@5
|
||||
[107] return
|
||||
to:@return
|
4830
src/test/ref/screen-center-distance.log
Normal file
4830
src/test/ref/screen-center-distance.log
Normal file
File diff suppressed because it is too large
Load Diff
225
src/test/ref/screen-center-distance.sym
Normal file
225
src/test/ref/screen-center-distance.sym
Normal file
@ -0,0 +1,225 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) CHARSET
|
||||
(const byte*) CHARSET#0 CHARSET = (byte*) 8192
|
||||
(byte*) D018
|
||||
(const byte*) D018#0 D018 = (byte*) 53272
|
||||
(byte[]) FONT_HEX_PROTO
|
||||
(const byte[]) FONT_HEX_PROTO#0 FONT_HEX_PROTO = { (byte) 2, (byte) 5, (byte) 5, (byte) 5, (byte) 2, (byte) 6, (byte) 2, (byte) 2, (byte) 2, (byte) 7, (byte) 6, (byte) 1, (byte) 2, (byte) 4, (byte) 7, (byte) 6, (byte) 1, (byte) 2, (byte) 1, (byte) 6, (byte) 5, (byte) 5, (byte) 7, (byte) 1, (byte) 1, (byte) 7, (byte) 4, (byte) 6, (byte) 1, (byte) 6, (byte) 3, (byte) 4, (byte) 6, (byte) 5, (byte) 2, (byte) 7, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 2, (byte) 5, (byte) 2, (byte) 5, (byte) 2, (byte) 2, (byte) 5, (byte) 3, (byte) 1, (byte) 1, (byte) 2, (byte) 5, (byte) 7, (byte) 5, (byte) 5, (byte) 6, (byte) 5, (byte) 6, (byte) 5, (byte) 6, (byte) 2, (byte) 5, (byte) 4, (byte) 5, (byte) 2, (byte) 6, (byte) 5, (byte) 5, (byte) 5, (byte) 6, (byte) 7, (byte) 4, (byte) 6, (byte) 4, (byte) 7, (byte) 7, (byte) 4, (byte) 6, (byte) 4, (byte) 4 }
|
||||
(byte*) HEAP_START
|
||||
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
|
||||
(byte) NUM_SQUARES
|
||||
(const byte) NUM_SQUARES#0 NUM_SQUARES = (byte) $30
|
||||
(byte*) SCREEN
|
||||
(const byte*) SCREEN#0 SCREEN = (byte*) 10240
|
||||
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte) 2
|
||||
(word*) SQUARES
|
||||
(word*()) bsearch16u((word) bsearch16u::key , (word*) bsearch16u::items , (byte) bsearch16u::num)
|
||||
(byte~) bsearch16u::$16 reg byte a 2002.0
|
||||
(word*~) bsearch16u::$2 $2 zp ZP_WORD:6 4.0
|
||||
(byte~) bsearch16u::$6 reg byte a 2002.0
|
||||
(label) bsearch16u::@1
|
||||
(label) bsearch16u::@2
|
||||
(label) bsearch16u::@3
|
||||
(label) bsearch16u::@4
|
||||
(label) bsearch16u::@5
|
||||
(label) bsearch16u::@6
|
||||
(label) bsearch16u::@7
|
||||
(label) bsearch16u::@8
|
||||
(label) bsearch16u::@9
|
||||
(label) bsearch16u::@return
|
||||
(word*) bsearch16u::items
|
||||
(word*) bsearch16u::items#1 items zp ZP_WORD:6 1001.0
|
||||
(word*) bsearch16u::items#2 items zp ZP_WORD:6 334.33333333333337
|
||||
(word*) bsearch16u::items#8 items zp ZP_WORD:6 1501.5
|
||||
(word) bsearch16u::key
|
||||
(word) bsearch16u::key#0 key zp ZP_WORD:24 0.2857142857142857
|
||||
(byte) bsearch16u::num
|
||||
(byte) bsearch16u::num#1 reg byte x 2002.0
|
||||
(byte) bsearch16u::num#2 reg byte x 2002.0
|
||||
(byte) bsearch16u::num#3 reg byte x 556.1111111111111
|
||||
(byte) bsearch16u::num#5 reg byte x 3003.0
|
||||
(word*) bsearch16u::pivot
|
||||
(word*) bsearch16u::pivot#0 pivot zp ZP_WORD:26 501.0
|
||||
(signed word) bsearch16u::result
|
||||
(signed word) bsearch16u::result#0 result zp ZP_WORD:28 1501.5
|
||||
(word*) bsearch16u::return
|
||||
(word*) bsearch16u::return#0 return zp ZP_WORD:6 4.0
|
||||
(word*) bsearch16u::return#2 return zp ZP_WORD:6 2.0
|
||||
(word*) bsearch16u::return#3 return zp ZP_WORD:6 6.0
|
||||
(word*~) bsearch16u::return#6 return zp ZP_WORD:6 4.0
|
||||
(byte*) heap_head
|
||||
(void()) init_font_hex((byte*) init_font_hex::charset)
|
||||
(byte~) init_font_hex::$0 $0 zp ZP_BYTE:30 1001.0
|
||||
(byte~) init_font_hex::$1 reg byte a 2002.0
|
||||
(byte~) init_font_hex::$2 reg byte a 2002.0
|
||||
(label) init_font_hex::@1
|
||||
(label) init_font_hex::@2
|
||||
(label) init_font_hex::@3
|
||||
(label) init_font_hex::@4
|
||||
(label) init_font_hex::@5
|
||||
(label) init_font_hex::@return
|
||||
(byte) init_font_hex::c
|
||||
(byte) init_font_hex::c#1 c zp ZP_BYTE:15 16.5
|
||||
(byte) init_font_hex::c#6 c zp ZP_BYTE:15 1.1578947368421053
|
||||
(byte) init_font_hex::c1
|
||||
(byte) init_font_hex::c1#1 c1 zp ZP_BYTE:20 151.5
|
||||
(byte) init_font_hex::c1#4 c1 zp ZP_BYTE:20 13.466666666666667
|
||||
(byte*) init_font_hex::charset
|
||||
(byte*) init_font_hex::charset#0 charset zp ZP_WORD:16 35.5
|
||||
(byte*) init_font_hex::charset#2 charset zp ZP_WORD:16 108.35714285714285
|
||||
(byte*) init_font_hex::charset#5 charset zp ZP_WORD:16 22.0
|
||||
(byte) init_font_hex::i
|
||||
(byte) init_font_hex::i#1 reg byte x 1501.5
|
||||
(byte) init_font_hex::i#2 reg byte x 667.3333333333334
|
||||
(byte) init_font_hex::idx
|
||||
(byte) init_font_hex::idx#2 idx zp ZP_BYTE:21 551.0
|
||||
(byte) init_font_hex::idx#3 reg byte y 202.0
|
||||
(byte) init_font_hex::idx#5 idx zp ZP_BYTE:21 600.5999999999999
|
||||
(byte*) init_font_hex::proto_hi
|
||||
(byte*) init_font_hex::proto_hi#1 proto_hi zp ZP_WORD:13 7.333333333333333
|
||||
(byte*) init_font_hex::proto_hi#6 proto_hi zp ZP_WORD:13 56.83333333333334
|
||||
(byte*) init_font_hex::proto_lo
|
||||
(byte*) init_font_hex::proto_lo#1 proto_lo zp ZP_WORD:18 50.5
|
||||
(byte*) init_font_hex::proto_lo#4 proto_lo zp ZP_WORD:18 92.53846153846155
|
||||
(void()) init_squares()
|
||||
(byte~) init_squares::$3 reg byte a 22.0
|
||||
(byte~) init_squares::$4 reg byte a 22.0
|
||||
(label) init_squares::@1
|
||||
(label) init_squares::@return
|
||||
(byte) init_squares::i
|
||||
(byte) init_squares::i#1 reg byte x 16.5
|
||||
(byte) init_squares::i#2 reg byte x 5.5
|
||||
(word) init_squares::sqr
|
||||
(word) init_squares::sqr#1 sqr zp ZP_WORD:9 7.333333333333333
|
||||
(word) init_squares::sqr#2 sqr zp ZP_WORD:9 6.6000000000000005
|
||||
(word*) init_squares::squares
|
||||
(word*) init_squares::squares#1 squares zp ZP_WORD:11 3.6666666666666665
|
||||
(word*) init_squares::squares#2 squares zp ZP_WORD:11 16.5
|
||||
(void()) main()
|
||||
(byte~) main::$14 reg byte a 202.0
|
||||
(byte~) main::$16 reg byte a 202.0
|
||||
(byte~) main::$6 reg byte a 22.0
|
||||
(byte~) main::$8 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@10
|
||||
(label) main::@11
|
||||
(label) main::@12
|
||||
(label) main::@13
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@7
|
||||
(label) main::@8
|
||||
(label) main::@9
|
||||
(label) main::@return
|
||||
(byte) main::d
|
||||
(byte) main::d#0 reg byte a 202.0
|
||||
(word) main::ds
|
||||
(word) main::ds#0 ds zp ZP_WORD:24 202.0
|
||||
(byte*) main::screen
|
||||
(byte*) main::screen#1 screen zp ZP_WORD:4 42.599999999999994
|
||||
(byte*) main::screen#10 screen zp ZP_WORD:4 2.2
|
||||
(byte*) main::screen#2 screen zp ZP_WORD:4 19.625
|
||||
(label) main::toD0181
|
||||
(word~) main::toD0181_$0
|
||||
(number~) main::toD0181_$1
|
||||
(number~) main::toD0181_$2
|
||||
(number~) main::toD0181_$3
|
||||
(word~) main::toD0181_$4
|
||||
(byte~) main::toD0181_$5
|
||||
(number~) main::toD0181_$6
|
||||
(number~) main::toD0181_$7
|
||||
(number~) main::toD0181_$8
|
||||
(byte*) main::toD0181_gfx
|
||||
(byte) main::toD0181_return
|
||||
(const byte) main::toD0181_return#0 toD0181_return = >(word)(const byte*) SCREEN#0&(word) $3fff*(byte) 4|>(word)(const byte*) CHARSET#0/(byte) 4&(byte) $f
|
||||
(byte*) main::toD0181_screen
|
||||
(byte) main::x
|
||||
(byte) main::x#1 x zp ZP_BYTE:3 151.5
|
||||
(byte) main::x#2 x zp ZP_BYTE:3 17.823529411764707
|
||||
(byte) main::x2
|
||||
(byte) main::x2#0 reg byte a 202.0
|
||||
(byte) main::xd
|
||||
(byte) main::xd#0 reg byte a 303.0
|
||||
(word) main::xds
|
||||
(word) main::xds#0 xds zp ZP_WORD:24 202.0
|
||||
(byte) main::y
|
||||
(byte) main::y#1 y zp ZP_BYTE:2 16.5
|
||||
(byte) main::y#10 y zp ZP_BYTE:2 1.1379310344827585
|
||||
(byte) main::y2
|
||||
(byte) main::y2#0 reg byte a 22.0
|
||||
(byte) main::yd
|
||||
(byte) main::yd#0 reg byte a 33.0
|
||||
(word) main::yds
|
||||
(word) main::yds#0 yds zp ZP_WORD:22 5.6
|
||||
(byte*()) malloc((word) malloc::size)
|
||||
(label) malloc::@return
|
||||
(byte*) malloc::mem
|
||||
(byte*) malloc::return
|
||||
(word) malloc::size
|
||||
(word()) sqr((byte) sqr::val)
|
||||
(byte~) sqr::$0 reg byte a 4.0
|
||||
(label) sqr::@return
|
||||
(word) sqr::return
|
||||
(word) sqr::return#0 return zp ZP_WORD:22 22.0
|
||||
(word) sqr::return#1 return#1 zp ZP_WORD:24 202.0
|
||||
(word) sqr::return#2 return#2 zp ZP_WORD:24 28.5
|
||||
(byte) sqr::val
|
||||
(byte) sqr::val#0 reg byte a 22.0
|
||||
(byte) sqr::val#1 reg byte a 202.0
|
||||
(byte) sqr::val#2 reg byte a 114.0
|
||||
(byte()) sqrt((word) sqrt::val)
|
||||
(word~) sqrt::$3 $3 zp ZP_WORD:6 2.0
|
||||
(byte~) sqrt::$4 reg byte a 4.0
|
||||
(label) sqrt::@1
|
||||
(label) sqrt::@return
|
||||
(word*) sqrt::found
|
||||
(word*) sqrt::found#0 found zp ZP_WORD:6 2.0
|
||||
(byte) sqrt::return
|
||||
(byte) sqrt::return#0 reg byte a 202.0
|
||||
(byte) sqrt::return#1 reg byte a 34.33333333333333
|
||||
(byte) sqrt::sqr1
|
||||
(word) sqrt::val
|
||||
(word) sqrt::val#0 val zp ZP_WORD:24 103.0
|
||||
|
||||
zp ZP_BYTE:2 [ main::y#10 main::y#1 ]
|
||||
reg byte a [ main::yd#0 main::$8 main::$6 ]
|
||||
zp ZP_BYTE:3 [ main::x#2 main::x#1 ]
|
||||
zp ZP_WORD:4 [ main::screen#2 main::screen#10 main::screen#1 ]
|
||||
reg byte a [ main::xd#0 main::$16 main::$14 ]
|
||||
zp ZP_WORD:6 [ bsearch16u::return#2 bsearch16u::return#6 bsearch16u::return#3 bsearch16u::items#2 bsearch16u::items#8 bsearch16u::$2 bsearch16u::items#1 bsearch16u::return#0 sqrt::found#0 sqrt::$3 ]
|
||||
reg byte x [ bsearch16u::num#5 bsearch16u::num#2 bsearch16u::num#3 bsearch16u::num#1 ]
|
||||
reg byte a [ sqr::val#2 sqr::val#0 sqr::val#1 ]
|
||||
zp ZP_WORD:9 [ init_squares::sqr#2 init_squares::sqr#1 ]
|
||||
zp ZP_WORD:11 [ init_squares::squares#2 init_squares::squares#1 ]
|
||||
reg byte x [ init_squares::i#2 init_squares::i#1 ]
|
||||
zp ZP_WORD:13 [ init_font_hex::proto_hi#6 init_font_hex::proto_hi#1 ]
|
||||
zp ZP_BYTE:15 [ init_font_hex::c#6 init_font_hex::c#1 ]
|
||||
zp ZP_WORD:16 [ init_font_hex::charset#2 init_font_hex::charset#5 init_font_hex::charset#0 ]
|
||||
zp ZP_WORD:18 [ init_font_hex::proto_lo#4 init_font_hex::proto_lo#1 ]
|
||||
zp ZP_BYTE:20 [ init_font_hex::c1#4 init_font_hex::c1#1 ]
|
||||
reg byte x [ init_font_hex::i#2 init_font_hex::i#1 ]
|
||||
zp ZP_BYTE:21 [ init_font_hex::idx#5 init_font_hex::idx#2 ]
|
||||
reg byte a [ main::y2#0 ]
|
||||
zp ZP_WORD:22 [ sqr::return#0 main::yds#0 ]
|
||||
reg byte a [ main::x2#0 ]
|
||||
zp ZP_WORD:24 [ sqr::return#1 main::xds#0 sqr::return#2 main::ds#0 sqrt::val#0 bsearch16u::key#0 ]
|
||||
reg byte a [ sqrt::return#0 ]
|
||||
reg byte a [ main::d#0 ]
|
||||
reg byte a [ sqrt::$4 ]
|
||||
reg byte a [ sqrt::return#1 ]
|
||||
reg byte a [ bsearch16u::$6 ]
|
||||
reg byte a [ bsearch16u::$16 ]
|
||||
zp ZP_WORD:26 [ bsearch16u::pivot#0 ]
|
||||
zp ZP_WORD:28 [ bsearch16u::result#0 ]
|
||||
reg byte a [ sqr::$0 ]
|
||||
reg byte a [ init_squares::$3 ]
|
||||
reg byte a [ init_squares::$4 ]
|
||||
zp ZP_BYTE:30 [ init_font_hex::$0 ]
|
||||
reg byte a [ init_font_hex::$1 ]
|
||||
reg byte a [ init_font_hex::$2 ]
|
||||
reg byte y [ init_font_hex::idx#3 ]
|
@ -5843,7 +5843,7 @@ printEntry: {
|
||||
jmp b1
|
||||
//SEG200 printEntry::@1
|
||||
b1:
|
||||
//SEG201 [97] (word~) print_word::w#7 ← (word)*((byte**)(byte*) printEntry::entry#10) -- vwuz1=_deref_pptz2
|
||||
//SEG201 [97] (word~) print_word::w#7 ← (word)*((byte**)(byte*) printEntry::entry#10) -- vwuz1=_deref_pwuz2
|
||||
ldy #0
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -5895,7 +5895,7 @@ printEntry: {
|
||||
jmp b2
|
||||
//SEG219 printEntry::@2
|
||||
b2:
|
||||
//SEG220 [104] (word~) print_word::w#8 ← (word)*((byte**)(byte*) printEntry::entry#10 + (byte) 2) -- vwuz1=pptz2_derefidx_vbuc1
|
||||
//SEG220 [104] (word~) print_word::w#8 ← (word)*((byte**)(byte*) printEntry::entry#10 + (byte) 2) -- vwuz1=pwuz2_derefidx_vbuc1
|
||||
ldy #2
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -5999,7 +5999,7 @@ printEntry: {
|
||||
jmp b4
|
||||
//SEG257 printEntry::@4
|
||||
b4:
|
||||
//SEG258 [118] (word~) print_word::w#10 ← (word)*((word**)(byte*) printEntry::entry#10 + (byte) 6) -- vwuz1=pptz2_derefidx_vbuc1
|
||||
//SEG258 [118] (word~) print_word::w#10 ← (word)*((word**)(byte*) printEntry::entry#10 + (byte) 6) -- vwuz1=pwuz2_derefidx_vbuc1
|
||||
ldy #6
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -7918,7 +7918,7 @@ printEntry: {
|
||||
jmp b1
|
||||
//SEG200 printEntry::@1
|
||||
b1:
|
||||
//SEG201 [97] (word~) print_word::w#7 ← (word)*((byte**)(byte*) printEntry::entry#10) -- vwuz1=_deref_pptz2
|
||||
//SEG201 [97] (word~) print_word::w#7 ← (word)*((byte**)(byte*) printEntry::entry#10) -- vwuz1=_deref_pwuz2
|
||||
ldy #0
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -7970,7 +7970,7 @@ printEntry: {
|
||||
jmp b2
|
||||
//SEG219 printEntry::@2
|
||||
b2:
|
||||
//SEG220 [104] (word~) print_word::w#8 ← (word)*((byte**)(byte*) printEntry::entry#10 + (byte) 2) -- vwuz1=pptz2_derefidx_vbuc1
|
||||
//SEG220 [104] (word~) print_word::w#8 ← (word)*((byte**)(byte*) printEntry::entry#10 + (byte) 2) -- vwuz1=pwuz2_derefidx_vbuc1
|
||||
ldy #2
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -8074,7 +8074,7 @@ printEntry: {
|
||||
jmp b4
|
||||
//SEG257 printEntry::@4
|
||||
b4:
|
||||
//SEG258 [118] (word~) print_word::w#10 ← (word)*((word**)(byte*) printEntry::entry#10 + (byte) 6) -- vwuz1=pptz2_derefidx_vbuc1
|
||||
//SEG258 [118] (word~) print_word::w#10 ← (word)*((word**)(byte*) printEntry::entry#10 + (byte) 6) -- vwuz1=pwuz2_derefidx_vbuc1
|
||||
ldy #6
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -10389,7 +10389,7 @@ printEntry: {
|
||||
//SEG198 [96] phi from printEntry to printEntry::entryBufDisk1 [phi:printEntry->printEntry::entryBufDisk1]
|
||||
//SEG199 printEntry::entryBufDisk1
|
||||
//SEG200 printEntry::@1
|
||||
//SEG201 [97] (word~) print_word::w#7 ← (word)*((byte**)(byte*) printEntry::entry#10) -- vwuz1=_deref_pptz2
|
||||
//SEG201 [97] (word~) print_word::w#7 ← (word)*((byte**)(byte*) printEntry::entry#10) -- vwuz1=_deref_pwuz2
|
||||
ldy #0
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -10429,7 +10429,7 @@ printEntry: {
|
||||
//SEG217 [103] phi from printEntry::@15 to printEntry::entryBufEdit1 [phi:printEntry::@15->printEntry::entryBufEdit1]
|
||||
//SEG218 printEntry::entryBufEdit1
|
||||
//SEG219 printEntry::@2
|
||||
//SEG220 [104] (word~) print_word::w#8 ← (word)*((byte**)(byte*) printEntry::entry#10 + (byte) 2) -- vwuz1=pptz2_derefidx_vbuc1
|
||||
//SEG220 [104] (word~) print_word::w#8 ← (word)*((byte**)(byte*) printEntry::entry#10 + (byte) 2) -- vwuz1=pwuz2_derefidx_vbuc1
|
||||
ldy #2
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
@ -10509,7 +10509,7 @@ printEntry: {
|
||||
//SEG255 [117] phi from printEntry::@19 to printEntry::entryTsOrder1 [phi:printEntry::@19->printEntry::entryTsOrder1]
|
||||
//SEG256 printEntry::entryTsOrder1
|
||||
//SEG257 printEntry::@4
|
||||
//SEG258 [118] (word~) print_word::w#10 ← (word)*((word**)(byte*) printEntry::entry#10 + (byte) 6) -- vwuz1=pptz2_derefidx_vbuc1
|
||||
//SEG258 [118] (word~) print_word::w#10 ← (word)*((word**)(byte*) printEntry::entry#10 + (byte) 6) -- vwuz1=pwuz2_derefidx_vbuc1
|
||||
ldy #6
|
||||
lda (entry),y
|
||||
sta print_word.w
|
||||
|
@ -9,7 +9,7 @@ main: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #$ff+1
|
||||
axs #-$ff-1
|
||||
lda #0
|
||||
sta table,x
|
||||
iny
|
||||
|
@ -257,7 +257,7 @@ main: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #$ff+1
|
||||
axs #-$ff-1
|
||||
//SEG17 [7] *((const byte[$100]) table#0 + (byte~) main::$0) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2
|
||||
lda #0
|
||||
sta table,x
|
||||
@ -349,7 +349,7 @@ main: {
|
||||
tya
|
||||
eor #$ff
|
||||
tax
|
||||
axs #$ff+1
|
||||
axs #-$ff-1
|
||||
//SEG17 [7] *((const byte[$100]) table#0 + (byte~) main::$0) ← (byte) 0 -- pbuc1_derefidx_vbuxx=vbuc2
|
||||
lda #0
|
||||
sta table,x
|
||||
|
Loading…
x
Reference in New Issue
Block a user