mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-26 12:49:21 +00:00
Now supports \xnn syntax for all values - even those without a proper encoding. Closes #383
This commit is contained in:
parent
e506732779
commit
f42a921d2b
@ -34,8 +34,12 @@ public class AsmFormat {
|
|||||||
return getAsmBool(((ConstantBool) value).getBool());
|
return getAsmBool(((ConstantBool) value).getBool());
|
||||||
} else if(value instanceof ConstantChar) {
|
} else if(value instanceof ConstantChar) {
|
||||||
ConstantChar constantChar = (ConstantChar) value;
|
ConstantChar constantChar = (ConstantChar) value;
|
||||||
|
if(!constantChar.getEncoding().hasEncoding(constantChar.getChar()))
|
||||||
|
return getAsmNumber(constantChar.getInteger());
|
||||||
|
else {
|
||||||
String escapedChar = constantChar.getCharEscaped();
|
String escapedChar = constantChar.getCharEscaped();
|
||||||
return "'" + escapedChar + "'";
|
return "'" + escapedChar + "'";
|
||||||
|
}
|
||||||
} else if(value instanceof ConstantString) {
|
} else if(value instanceof ConstantString) {
|
||||||
String stringValue = ((ConstantString) value).getValue();
|
String stringValue = ((ConstantString) value).getValue();
|
||||||
String escapedString = ((ConstantString) value).getStringEscaped();
|
String escapedString = ((ConstantString) value).getStringEscaped();
|
||||||
|
@ -14,6 +14,14 @@ public enum StringEncoding {
|
|||||||
SCREENCODE_MIXED("screencode_mixed", "sm", CharToPetsciiConverter.charToScreenCode_mixed),
|
SCREENCODE_MIXED("screencode_mixed", "sm", CharToPetsciiConverter.charToScreenCode_mixed),
|
||||||
SCREENCODE_UPPER("screencode_upper", "su", CharToPetsciiConverter.charToScreenCode_upper);
|
SCREENCODE_UPPER("screencode_upper", "su", CharToPetsciiConverter.charToScreenCode_upper);
|
||||||
|
|
||||||
|
|
||||||
|
/** Char value used to encode \xnn chars without a value within the chosen encoding. A char C is encoded as CHAR_SPECIAL_VAL+C */
|
||||||
|
public static final char CHAR_SPECIAL_VAL = 64000;
|
||||||
|
/** The minimal value of a specially encoded char. */
|
||||||
|
public static final char CHAR_SPECIAL_MIN = CHAR_SPECIAL_VAL + Byte.MIN_VALUE;
|
||||||
|
/** The maximal value of a specially encoded char. */
|
||||||
|
public static final char CHAR_SPECIAL_MAX = CHAR_SPECIAL_VAL + Byte.MAX_VALUE;
|
||||||
|
|
||||||
/** The encoding name. */
|
/** The encoding name. */
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
@ -72,9 +80,24 @@ public enum StringEncoding {
|
|||||||
*/
|
*/
|
||||||
public Long encodedFromChar(Character aChar) {
|
public Long encodedFromChar(Character aChar) {
|
||||||
Byte encodedValue = mapping.get(aChar);
|
Byte encodedValue = mapping.get(aChar);
|
||||||
|
if(encodedValue != null)
|
||||||
return encodedValue.longValue();
|
return encodedValue.longValue();
|
||||||
|
else
|
||||||
|
// Char is not in encoding - it must be made up!
|
||||||
|
return (long) aChar - CHAR_SPECIAL_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a character has en encoding within the specific encoding
|
||||||
|
* @param aChar The char to examine
|
||||||
|
* @return true if the char has a proper encoding. False if it does not.
|
||||||
|
*/
|
||||||
|
public boolean hasEncoding(Character aChar) {
|
||||||
|
Byte encodedValue = mapping.get(aChar);
|
||||||
|
return encodedValue != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get UNICODE/ASCII character for a specific encoded integer value using the specific encoding
|
* Get UNICODE/ASCII character for a specific encoded integer value using the specific encoding
|
||||||
*
|
*
|
||||||
@ -86,7 +109,8 @@ public enum StringEncoding {
|
|||||||
if(mapEntry.getValue() == encodedValue.byteValue())
|
if(mapEntry.getValue() == encodedValue.byteValue())
|
||||||
return mapEntry.getKey();
|
return mapEntry.getKey();
|
||||||
}
|
}
|
||||||
return null;
|
// If the mapping does not handle the Char - make one up
|
||||||
|
return (char) (CHAR_SPECIAL_VAL + encodedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,9 +195,12 @@ public enum StringEncoding {
|
|||||||
return Character.toString(aChar);
|
return Character.toString(aChar);
|
||||||
case '\\':
|
case '\\':
|
||||||
return "\\\\";
|
return "\\\\";
|
||||||
default:
|
|
||||||
return Character.toString(aChar);
|
|
||||||
}
|
}
|
||||||
|
if(aChar >= CHAR_SPECIAL_MIN && aChar <= CHAR_SPECIAL_MAX) {
|
||||||
|
final byte charValue = (byte) (aChar - CHAR_SPECIAL_VAL);
|
||||||
|
return String.format("\\$%x", charValue);
|
||||||
|
} else
|
||||||
|
return Character.toString(aChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,5 +215,4 @@ public enum StringEncoding {
|
|||||||
return escaped.toString();
|
return escaped.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -641,11 +641,6 @@ public class TestPrograms {
|
|||||||
compileAndCompare("code-after-return");
|
compileAndCompare("code-after-return");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStringEscapesErr2() throws IOException, URISyntaxException {
|
|
||||||
assertError("string-escapes-err-2", "No character 0xff in encoding petscii_mixed");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringEscapesErr1() throws IOException, URISyntaxException {
|
public void testStringEscapesErr1() throws IOException, URISyntaxException {
|
||||||
assertError("string-escapes-err-1", "Illegal string escape sequence");
|
assertError("string-escapes-err-1", "Illegal string escape sequence");
|
||||||
@ -656,6 +651,11 @@ public class TestPrograms {
|
|||||||
assertError("string-escapes-err-0", "Unfinished string escape sequence at end of string");
|
assertError("string-escapes-err-0", "Unfinished string escape sequence at end of string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringEscapes5() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("string-escapes-5");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringEscapes4() throws IOException, URISyntaxException {
|
public void testStringEscapes4() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("string-escapes-4");
|
compileAndCompare("string-escapes-4");
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#pragma encoding(petscii_mixed)
|
#pragma encoding(petscii_mixed)
|
||||||
|
|
||||||
char MESSAGE[] = "hello\nworld";
|
char MESSAGE[] = "hello\nworld";
|
||||||
|
char CH = '\n';
|
||||||
|
|
||||||
char* SCREEN = 0x0400;
|
char* SCREEN = 0x0400;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -23,4 +25,6 @@ void main() {
|
|||||||
msg++;
|
msg++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCREEN[0x50] = CH;
|
||||||
|
|
||||||
}
|
}
|
16
src/test/kc/string-escapes-5.kc
Normal file
16
src/test/kc/string-escapes-5.kc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Test using some simple supported string escape
|
||||||
|
// Uses \xnn to add chars by hex-code that do not exist with the encoding.
|
||||||
|
|
||||||
|
#pragma encoding(petscii_mixed)
|
||||||
|
char MESSAGE[] = "qwe\xffasd\xferty";
|
||||||
|
|
||||||
|
char CH = '\xff';
|
||||||
|
|
||||||
|
char * const SCREEN = 0x0400;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
char i=0;
|
||||||
|
while(MESSAGE[i])
|
||||||
|
SCREEN[i] = MESSAGE[i++];
|
||||||
|
SCREEN[0x28] = CH;
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
// Test errors using string escape sequences
|
|
||||||
// Unsupported hex character sequence
|
|
||||||
|
|
||||||
#pragma encoding(petscii_mixed)
|
|
||||||
char MESSAGE[] = "qwe\xff";
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
}
|
|
@ -3,6 +3,9 @@
|
|||||||
.pc = $801 "Basic"
|
.pc = $801 "Basic"
|
||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = '\n'
|
||||||
|
.label SCREEN = $400
|
||||||
main: {
|
main: {
|
||||||
.label cursor = 6
|
.label cursor = 6
|
||||||
.label msg = 2
|
.label msg = 2
|
||||||
@ -25,6 +28,9 @@ main: {
|
|||||||
lda (msg),y
|
lda (msg),y
|
||||||
cmp #0
|
cmp #0
|
||||||
bne __b2
|
bne __b2
|
||||||
|
// SCREEN[0x50] = CH
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$50
|
||||||
// }
|
// }
|
||||||
rts
|
rts
|
||||||
__b2:
|
__b2:
|
||||||
@ -32,11 +38,10 @@ main: {
|
|||||||
// line += 0x28;
|
// line += 0x28;
|
||||||
// cursor = line;
|
// cursor = line;
|
||||||
// break;
|
// break;
|
||||||
.encoding "petscii_mixed"
|
|
||||||
lda #'\n'
|
lda #'\n'
|
||||||
ldy #0
|
ldy #0
|
||||||
cmp (msg),y
|
cmp (msg),y
|
||||||
beq __b3
|
beq __b4
|
||||||
// *msg & 0x3f
|
// *msg & 0x3f
|
||||||
lda #$3f
|
lda #$3f
|
||||||
and (msg),y
|
and (msg),y
|
||||||
@ -47,14 +52,14 @@ main: {
|
|||||||
bne !+
|
bne !+
|
||||||
inc.z cursor+1
|
inc.z cursor+1
|
||||||
!:
|
!:
|
||||||
__b5:
|
__b6:
|
||||||
// msg++;
|
// msg++;
|
||||||
inc.z msg
|
inc.z msg
|
||||||
bne !+
|
bne !+
|
||||||
inc.z msg+1
|
inc.z msg+1
|
||||||
!:
|
!:
|
||||||
jmp __b1
|
jmp __b1
|
||||||
__b3:
|
__b4:
|
||||||
// line += 0x28
|
// line += 0x28
|
||||||
lda #$28
|
lda #$28
|
||||||
clc
|
clc
|
||||||
@ -67,7 +72,7 @@ main: {
|
|||||||
sta.z line
|
sta.z line
|
||||||
lda.z cursor+1
|
lda.z cursor+1
|
||||||
sta.z line+1
|
sta.z line+1
|
||||||
jmp __b5
|
jmp __b6
|
||||||
}
|
}
|
||||||
MESSAGE: .text @"hello\nworld"
|
MESSAGE: .text @"hello\nworld"
|
||||||
.byte 0
|
.byte 0
|
||||||
|
@ -12,30 +12,33 @@
|
|||||||
main: scope:[main] from @1
|
main: scope:[main] from @1
|
||||||
[4] phi()
|
[4] phi()
|
||||||
to:main::@1
|
to:main::@1
|
||||||
main::@1: scope:[main] from main main::@5
|
main::@1: scope:[main] from main main::@6
|
||||||
[5] (byte*) main::cursor#3 ← phi( main/(byte*) 1024 main::@5/(byte*) main::cursor#6 )
|
[5] (byte*) main::cursor#3 ← phi( main/(byte*) 1024 main::@6/(byte*) main::cursor#6 )
|
||||||
[5] (byte*) main::line#2 ← phi( main/(byte*) 1024 main::@5/(byte*) main::line#5 )
|
[5] (byte*) main::line#2 ← phi( main/(byte*) 1024 main::@6/(byte*) main::line#5 )
|
||||||
[5] (byte*) main::msg#2 ← phi( main/(const byte*) MESSAGE main::@5/(byte*) main::msg#1 )
|
[5] (byte*) main::msg#2 ← phi( main/(const byte*) MESSAGE main::@6/(byte*) main::msg#1 )
|
||||||
[6] if((byte) 0!=*((byte*) main::msg#2)) goto main::@2
|
[6] if((byte) 0!=*((byte*) main::msg#2)) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
[7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH
|
||||||
to:main::@return
|
to:main::@return
|
||||||
main::@return: scope:[main] from main::@1
|
main::@return: scope:[main] from main::@3
|
||||||
[7] return
|
[8] return
|
||||||
to:@return
|
to:@return
|
||||||
main::@2: scope:[main] from main::@1
|
main::@2: scope:[main] from main::@1
|
||||||
[8] if(*((byte*) main::msg#2)==(byte) '
|
[9] if(*((byte*) main::msg#2)==(byte) '
|
||||||
'pm) goto main::@3
|
'pm) goto main::@4
|
||||||
to:main::@4
|
|
||||||
main::@4: scope:[main] from main::@2
|
|
||||||
[9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f
|
|
||||||
[10] *((byte*) main::cursor#3) ← (byte~) main::$0
|
|
||||||
[11] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3
|
|
||||||
to:main::@5
|
to:main::@5
|
||||||
main::@5: scope:[main] from main::@3 main::@4
|
main::@5: scope:[main] from main::@2
|
||||||
[12] (byte*) main::cursor#6 ← phi( main::@3/(byte*) main::cursor#1 main::@4/(byte*) main::cursor#2 )
|
[10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f
|
||||||
[12] (byte*) main::line#5 ← phi( main::@3/(byte*) main::line#8 main::@4/(byte*) main::line#2 )
|
[11] *((byte*) main::cursor#3) ← (byte~) main::$0
|
||||||
[13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2
|
[12] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3
|
||||||
|
to:main::@6
|
||||||
|
main::@6: scope:[main] from main::@4 main::@5
|
||||||
|
[13] (byte*) main::cursor#6 ← phi( main::@4/(byte*) main::cursor#1 main::@5/(byte*) main::cursor#2 )
|
||||||
|
[13] (byte*) main::line#5 ← phi( main::@4/(byte*) main::line#8 main::@5/(byte*) main::line#2 )
|
||||||
|
[14] (byte*) main::msg#1 ← ++ (byte*) main::msg#2
|
||||||
to:main::@1
|
to:main::@1
|
||||||
main::@3: scope:[main] from main::@2
|
main::@4: scope:[main] from main::@2
|
||||||
[14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
[15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
||||||
[15] (byte*) main::line#8 ← (byte*) main::cursor#1
|
[16] (byte*) main::line#8 ← (byte*) main::cursor#1
|
||||||
to:main::@5
|
to:main::@6
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Warning! Adding boolean cast to non-boolean condition *((byte*) main::msg)
|
Warning! Adding boolean cast to non-boolean condition *((byte*) main::msg)
|
||||||
|
Identified constant variable (byte) CH
|
||||||
Identified constant variable (byte*) SCREEN
|
Identified constant variable (byte*) SCREEN
|
||||||
Culled Empty Block (label) main::@9
|
Culled Empty Block (label) main::@9
|
||||||
Culled Empty Block (label) main::@3
|
|
||||||
Culled Empty Block (label) main::@10
|
Culled Empty Block (label) main::@10
|
||||||
Culled Empty Block (label) main::@11
|
Culled Empty Block (label) main::@11
|
||||||
Culled Empty Block (label) main::@12
|
Culled Empty Block (label) main::@12
|
||||||
@ -24,7 +24,7 @@ main::@1: scope:[main] from main main::@6
|
|||||||
(byte*) main::msg#2 ← phi( main/(byte*) main::msg#0 main::@6/(byte*) main::msg#1 )
|
(byte*) main::msg#2 ← phi( main/(byte*) main::msg#0 main::@6/(byte*) main::msg#1 )
|
||||||
(bool~) main::$1 ← (number) 0 != *((byte*) main::msg#2)
|
(bool~) main::$1 ← (number) 0 != *((byte*) main::msg#2)
|
||||||
if((bool~) main::$1) goto main::@2
|
if((bool~) main::$1) goto main::@2
|
||||||
to:main::@return
|
to:main::@3
|
||||||
main::@2: scope:[main] from main::@1
|
main::@2: scope:[main] from main::@1
|
||||||
(byte*) main::cursor#4 ← phi( main::@1/(byte*) main::cursor#5 )
|
(byte*) main::cursor#4 ← phi( main::@1/(byte*) main::cursor#5 )
|
||||||
(byte*) main::line#3 ← phi( main::@1/(byte*) main::line#4 )
|
(byte*) main::line#3 ← phi( main::@1/(byte*) main::line#4 )
|
||||||
@ -32,6 +32,9 @@ main::@2: scope:[main] from main::@1
|
|||||||
if(*((byte*) main::msg#3)==(byte) '
|
if(*((byte*) main::msg#3)==(byte) '
|
||||||
'pm) goto main::@4
|
'pm) goto main::@4
|
||||||
to:main::@5
|
to:main::@5
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
*((const byte*) SCREEN + (number) $50) ← (const byte) CH
|
||||||
|
to:main::@return
|
||||||
main::@4: scope:[main] from main::@2
|
main::@4: scope:[main] from main::@2
|
||||||
(byte*) main::msg#6 ← phi( main::@2/(byte*) main::msg#3 )
|
(byte*) main::msg#6 ← phi( main::@2/(byte*) main::msg#3 )
|
||||||
(byte*) main::line#2 ← phi( main::@2/(byte*) main::line#3 )
|
(byte*) main::line#2 ← phi( main::@2/(byte*) main::line#3 )
|
||||||
@ -52,7 +55,7 @@ main::@6: scope:[main] from main::@4 main::@5
|
|||||||
(byte*) main::msg#5 ← phi( main::@4/(byte*) main::msg#6 main::@5/(byte*) main::msg#4 )
|
(byte*) main::msg#5 ← phi( main::@4/(byte*) main::msg#6 main::@5/(byte*) main::msg#4 )
|
||||||
(byte*) main::msg#1 ← ++ (byte*) main::msg#5
|
(byte*) main::msg#1 ← ++ (byte*) main::msg#5
|
||||||
to:main::@1
|
to:main::@1
|
||||||
main::@return: scope:[main] from main::@1
|
main::@return: scope:[main] from main::@3
|
||||||
return
|
return
|
||||||
to:@return
|
to:@return
|
||||||
@1: scope:[] from @begin
|
@1: scope:[] from @begin
|
||||||
@ -67,13 +70,17 @@ SYMBOL TABLE SSA
|
|||||||
(label) @2
|
(label) @2
|
||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
|
(const byte) CH = (byte) '
|
||||||
|
'pm
|
||||||
(const byte*) MESSAGE[] = (byte*) "hello
|
(const byte*) MESSAGE[] = (byte*) "hello
|
||||||
world"pm
|
world"pm
|
||||||
|
(const byte*) SCREEN = (byte*)(number) $400
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(number~) main::$0
|
(number~) main::$0
|
||||||
(bool~) main::$1
|
(bool~) main::$1
|
||||||
(label) main::@1
|
(label) main::@1
|
||||||
(label) main::@2
|
(label) main::@2
|
||||||
|
(label) main::@3
|
||||||
(label) main::@4
|
(label) main::@4
|
||||||
(label) main::@5
|
(label) main::@5
|
||||||
(label) main::@6
|
(label) main::@6
|
||||||
@ -104,16 +111,20 @@ world"pm
|
|||||||
(byte*) main::msg#6
|
(byte*) main::msg#6
|
||||||
|
|
||||||
Adding number conversion cast (unumber) 0 in (bool~) main::$1 ← (number) 0 != *((byte*) main::msg#2)
|
Adding number conversion cast (unumber) 0 in (bool~) main::$1 ← (number) 0 != *((byte*) main::msg#2)
|
||||||
|
Adding number conversion cast (unumber) $50 in *((const byte*) SCREEN + (number) $50) ← (const byte) CH
|
||||||
Adding number conversion cast (unumber) $28 in (byte*) main::line#1 ← (byte*) main::line#2 + (number) $28
|
Adding number conversion cast (unumber) $28 in (byte*) main::line#1 ← (byte*) main::line#2 + (number) $28
|
||||||
Adding number conversion cast (unumber) $3f in (number~) main::$0 ← *((byte*) main::msg#4) & (number) $3f
|
Adding number conversion cast (unumber) $3f in (number~) main::$0 ← *((byte*) main::msg#4) & (number) $3f
|
||||||
Adding number conversion cast (unumber) main::$0 in (number~) main::$0 ← *((byte*) main::msg#4) & (unumber)(number) $3f
|
Adding number conversion cast (unumber) main::$0 in (number~) main::$0 ← *((byte*) main::msg#4) & (unumber)(number) $3f
|
||||||
Successful SSA optimization PassNAddNumberTypeConversions
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
Simplifying constant pointer cast (byte*) 1024
|
Simplifying constant pointer cast (byte*) 1024
|
||||||
|
Simplifying constant pointer cast (byte*) 1024
|
||||||
Simplifying constant integer cast 0
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast $50
|
||||||
Simplifying constant integer cast $28
|
Simplifying constant integer cast $28
|
||||||
Simplifying constant integer cast $3f
|
Simplifying constant integer cast $3f
|
||||||
Successful SSA optimization PassNCastSimplification
|
Successful SSA optimization PassNCastSimplification
|
||||||
Finalized unsigned number type (byte) 0
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) $50
|
||||||
Finalized unsigned number type (byte) $28
|
Finalized unsigned number type (byte) $28
|
||||||
Finalized unsigned number type (byte) $3f
|
Finalized unsigned number type (byte) $3f
|
||||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
@ -136,6 +147,8 @@ Inlining constant with var siblings (const byte*) main::msg#0
|
|||||||
Constant inlined main::cursor#0 = (byte*) 1024
|
Constant inlined main::cursor#0 = (byte*) 1024
|
||||||
Constant inlined main::msg#0 = (const byte*) MESSAGE
|
Constant inlined main::msg#0 = (const byte*) MESSAGE
|
||||||
Successful SSA optimization Pass2ConstantInlining
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
Consolidated array index constant in *(SCREEN+$50)
|
||||||
|
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||||
Adding NOP phi() at start of @begin
|
Adding NOP phi() at start of @begin
|
||||||
Adding NOP phi() at start of @1
|
Adding NOP phi() at start of @1
|
||||||
Adding NOP phi() at start of @2
|
Adding NOP phi() at start of @2
|
||||||
@ -145,18 +158,15 @@ CALL GRAPH
|
|||||||
Calls in [] to main:2
|
Calls in [] to main:2
|
||||||
|
|
||||||
Created 5 initial phi equivalence classes
|
Created 5 initial phi equivalence classes
|
||||||
Coalesced [13] main::line#9 ← main::line#2
|
Coalesced [14] main::line#9 ← main::line#2
|
||||||
Coalesced [14] main::cursor#9 ← main::cursor#2
|
Coalesced [15] main::cursor#9 ← main::cursor#2
|
||||||
Coalesced [17] main::msg#7 ← main::msg#1
|
Coalesced [18] main::msg#7 ← main::msg#1
|
||||||
Coalesced (already) [18] main::line#7 ← main::line#5
|
Coalesced (already) [19] main::line#7 ← main::line#5
|
||||||
Coalesced [19] main::cursor#7 ← main::cursor#6
|
Coalesced [20] main::cursor#7 ← main::cursor#6
|
||||||
Not coalescing [21] main::line#8 ← main::cursor#1
|
Not coalescing [22] main::line#8 ← main::cursor#1
|
||||||
Coalesced [22] main::cursor#8 ← main::cursor#1
|
Coalesced [23] main::cursor#8 ← main::cursor#1
|
||||||
Coalesced down to 3 phi equivalence classes
|
Coalesced down to 3 phi equivalence classes
|
||||||
Culled Empty Block (label) @2
|
Culled Empty Block (label) @2
|
||||||
Renumbering block main::@4 to main::@3
|
|
||||||
Renumbering block main::@5 to main::@4
|
|
||||||
Renumbering block main::@6 to main::@5
|
|
||||||
Adding NOP phi() at start of @begin
|
Adding NOP phi() at start of @begin
|
||||||
Adding NOP phi() at start of @1
|
Adding NOP phi() at start of @1
|
||||||
Adding NOP phi() at start of @end
|
Adding NOP phi() at start of @end
|
||||||
@ -177,33 +187,36 @@ FINAL CONTROL FLOW GRAPH
|
|||||||
main: scope:[main] from @1
|
main: scope:[main] from @1
|
||||||
[4] phi()
|
[4] phi()
|
||||||
to:main::@1
|
to:main::@1
|
||||||
main::@1: scope:[main] from main main::@5
|
main::@1: scope:[main] from main main::@6
|
||||||
[5] (byte*) main::cursor#3 ← phi( main/(byte*) 1024 main::@5/(byte*) main::cursor#6 )
|
[5] (byte*) main::cursor#3 ← phi( main/(byte*) 1024 main::@6/(byte*) main::cursor#6 )
|
||||||
[5] (byte*) main::line#2 ← phi( main/(byte*) 1024 main::@5/(byte*) main::line#5 )
|
[5] (byte*) main::line#2 ← phi( main/(byte*) 1024 main::@6/(byte*) main::line#5 )
|
||||||
[5] (byte*) main::msg#2 ← phi( main/(const byte*) MESSAGE main::@5/(byte*) main::msg#1 )
|
[5] (byte*) main::msg#2 ← phi( main/(const byte*) MESSAGE main::@6/(byte*) main::msg#1 )
|
||||||
[6] if((byte) 0!=*((byte*) main::msg#2)) goto main::@2
|
[6] if((byte) 0!=*((byte*) main::msg#2)) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
[7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH
|
||||||
to:main::@return
|
to:main::@return
|
||||||
main::@return: scope:[main] from main::@1
|
main::@return: scope:[main] from main::@3
|
||||||
[7] return
|
[8] return
|
||||||
to:@return
|
to:@return
|
||||||
main::@2: scope:[main] from main::@1
|
main::@2: scope:[main] from main::@1
|
||||||
[8] if(*((byte*) main::msg#2)==(byte) '
|
[9] if(*((byte*) main::msg#2)==(byte) '
|
||||||
'pm) goto main::@3
|
'pm) goto main::@4
|
||||||
to:main::@4
|
|
||||||
main::@4: scope:[main] from main::@2
|
|
||||||
[9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f
|
|
||||||
[10] *((byte*) main::cursor#3) ← (byte~) main::$0
|
|
||||||
[11] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3
|
|
||||||
to:main::@5
|
to:main::@5
|
||||||
main::@5: scope:[main] from main::@3 main::@4
|
main::@5: scope:[main] from main::@2
|
||||||
[12] (byte*) main::cursor#6 ← phi( main::@3/(byte*) main::cursor#1 main::@4/(byte*) main::cursor#2 )
|
[10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f
|
||||||
[12] (byte*) main::line#5 ← phi( main::@3/(byte*) main::line#8 main::@4/(byte*) main::line#2 )
|
[11] *((byte*) main::cursor#3) ← (byte~) main::$0
|
||||||
[13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2
|
[12] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3
|
||||||
|
to:main::@6
|
||||||
|
main::@6: scope:[main] from main::@4 main::@5
|
||||||
|
[13] (byte*) main::cursor#6 ← phi( main::@4/(byte*) main::cursor#1 main::@5/(byte*) main::cursor#2 )
|
||||||
|
[13] (byte*) main::line#5 ← phi( main::@4/(byte*) main::line#8 main::@5/(byte*) main::line#2 )
|
||||||
|
[14] (byte*) main::msg#1 ← ++ (byte*) main::msg#2
|
||||||
to:main::@1
|
to:main::@1
|
||||||
main::@3: scope:[main] from main::@2
|
main::@4: scope:[main] from main::@2
|
||||||
[14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
[15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
||||||
[15] (byte*) main::line#8 ← (byte*) main::cursor#1
|
[16] (byte*) main::line#8 ← (byte*) main::cursor#1
|
||||||
to:main::@5
|
to:main::@6
|
||||||
|
|
||||||
|
|
||||||
VARIABLE REGISTER WEIGHTS
|
VARIABLE REGISTER WEIGHTS
|
||||||
@ -247,6 +260,9 @@ Target platform is c64basic / MOS6502X
|
|||||||
:BasicUpstart(__bbegin)
|
:BasicUpstart(__bbegin)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = '\n'
|
||||||
|
.label SCREEN = $400
|
||||||
// @begin
|
// @begin
|
||||||
__bbegin:
|
__bbegin:
|
||||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
@ -294,58 +310,63 @@ main: {
|
|||||||
lda (msg),y
|
lda (msg),y
|
||||||
cmp #0
|
cmp #0
|
||||||
bne __b2
|
bne __b2
|
||||||
|
jmp __b3
|
||||||
|
// main::@3
|
||||||
|
__b3:
|
||||||
|
// [7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH -- _deref_pbuc1=vbuc2
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$50
|
||||||
jmp __breturn
|
jmp __breturn
|
||||||
// main::@return
|
// main::@return
|
||||||
__breturn:
|
__breturn:
|
||||||
// [7] return
|
// [8] return
|
||||||
rts
|
rts
|
||||||
// main::@2
|
// main::@2
|
||||||
__b2:
|
__b2:
|
||||||
// [8] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@3 -- _deref_pbuz1_eq_vbuc1_then_la1
|
// [9] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@4 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||||
.encoding "petscii_mixed"
|
|
||||||
lda #'\n'
|
lda #'\n'
|
||||||
ldy #0
|
ldy #0
|
||||||
cmp (msg),y
|
cmp (msg),y
|
||||||
beq __b3
|
beq __b4
|
||||||
jmp __b4
|
jmp __b5
|
||||||
// main::@4
|
// main::@5
|
||||||
__b4:
|
__b5:
|
||||||
// [9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuz1=_deref_pbuz2_band_vbuc1
|
// [10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuz1=_deref_pbuz2_band_vbuc1
|
||||||
lda #$3f
|
lda #$3f
|
||||||
ldy #0
|
ldy #0
|
||||||
and (msg),y
|
and (msg),y
|
||||||
sta.z __0
|
sta.z __0
|
||||||
// [10] *((byte*) main::cursor#3) ← (byte~) main::$0 -- _deref_pbuz1=vbuz2
|
// [11] *((byte*) main::cursor#3) ← (byte~) main::$0 -- _deref_pbuz1=vbuz2
|
||||||
lda.z __0
|
lda.z __0
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (cursor),y
|
sta (cursor),y
|
||||||
// [11] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3 -- pbuz1=_inc_pbuz1
|
// [12] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3 -- pbuz1=_inc_pbuz1
|
||||||
inc.z cursor
|
inc.z cursor
|
||||||
bne !+
|
bne !+
|
||||||
inc.z cursor+1
|
inc.z cursor+1
|
||||||
!:
|
!:
|
||||||
// [12] phi from main::@3 main::@4 to main::@5 [phi:main::@3/main::@4->main::@5]
|
// [13] phi from main::@4 main::@5 to main::@6 [phi:main::@4/main::@5->main::@6]
|
||||||
__b5_from___b3:
|
__b6_from___b4:
|
||||||
__b5_from___b4:
|
__b6_from___b5:
|
||||||
// [12] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@3/main::@4->main::@5#0] -- register_copy
|
// [13] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@4/main::@5->main::@6#0] -- register_copy
|
||||||
// [12] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@3/main::@4->main::@5#1] -- register_copy
|
// [13] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@4/main::@5->main::@6#1] -- register_copy
|
||||||
jmp __b5
|
jmp __b6
|
||||||
// main::@5
|
// main::@6
|
||||||
__b5:
|
__b6:
|
||||||
// [13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
// [14] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
||||||
inc.z msg
|
inc.z msg
|
||||||
bne !+
|
bne !+
|
||||||
inc.z msg+1
|
inc.z msg+1
|
||||||
!:
|
!:
|
||||||
// [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
|
// [5] phi from main::@6 to main::@1 [phi:main::@6->main::@1]
|
||||||
__b1_from___b5:
|
__b1_from___b6:
|
||||||
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@5->main::@1#0] -- register_copy
|
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@6->main::@1#0] -- register_copy
|
||||||
// [5] phi (byte*) main::line#2 = (byte*) main::line#5 [phi:main::@5->main::@1#1] -- register_copy
|
// [5] phi (byte*) main::line#2 = (byte*) main::line#5 [phi:main::@6->main::@1#1] -- register_copy
|
||||||
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@5->main::@1#2] -- register_copy
|
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@6->main::@1#2] -- register_copy
|
||||||
jmp __b1
|
jmp __b1
|
||||||
// main::@3
|
// main::@4
|
||||||
__b3:
|
__b4:
|
||||||
// [14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
// [15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
||||||
lda #$28
|
lda #$28
|
||||||
clc
|
clc
|
||||||
adc.z line
|
adc.z line
|
||||||
@ -353,12 +374,12 @@ main: {
|
|||||||
lda #0
|
lda #0
|
||||||
adc.z line+1
|
adc.z line+1
|
||||||
sta.z cursor+1
|
sta.z cursor+1
|
||||||
// [15] (byte*) main::line#8 ← (byte*) main::cursor#1 -- pbuz1=pbuz2
|
// [16] (byte*) main::line#8 ← (byte*) main::cursor#1 -- pbuz1=pbuz2
|
||||||
lda.z cursor
|
lda.z cursor
|
||||||
sta.z line
|
sta.z line
|
||||||
lda.z cursor+1
|
lda.z cursor+1
|
||||||
sta.z line+1
|
sta.z line+1
|
||||||
jmp __b5_from___b3
|
jmp __b6_from___b4
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
MESSAGE: .text @"hello\nworld"
|
MESSAGE: .text @"hello\nworld"
|
||||||
@ -366,12 +387,13 @@ main: {
|
|||||||
|
|
||||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
Statement [6] if((byte) 0!=*((byte*) main::msg#2)) goto main::@2 [ main::msg#2 main::line#2 main::cursor#3 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 ] { } ) always clobbers reg byte a reg byte y
|
Statement [6] if((byte) 0!=*((byte*) main::msg#2)) goto main::@2 [ main::msg#2 main::line#2 main::cursor#3 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 ] { } ) always clobbers reg byte a reg byte y
|
||||||
Statement [8] if(*((byte*) main::msg#2)==(byte) '
|
Statement [7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH [ ] ( main:2 [ ] { } ) always clobbers reg byte a
|
||||||
'pm) goto main::@3 [ main::msg#2 main::line#2 main::cursor#3 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 ] { } ) always clobbers reg byte a reg byte y
|
Statement [9] if(*((byte*) main::msg#2)==(byte) '
|
||||||
Statement [9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f [ main::msg#2 main::line#2 main::cursor#3 main::$0 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 main::$0 ] { } ) always clobbers reg byte a reg byte y
|
'pm) goto main::@4 [ main::msg#2 main::line#2 main::cursor#3 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 ] { } ) always clobbers reg byte a reg byte y
|
||||||
Statement [10] *((byte*) main::cursor#3) ← (byte~) main::$0 [ main::msg#2 main::line#2 main::cursor#3 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 ] { } ) always clobbers reg byte y
|
Statement [10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f [ main::msg#2 main::line#2 main::cursor#3 main::$0 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 main::$0 ] { } ) always clobbers reg byte a reg byte y
|
||||||
Statement [14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 [ main::msg#2 main::cursor#1 ] ( main:2 [ main::msg#2 main::cursor#1 ] { } ) always clobbers reg byte a
|
Statement [11] *((byte*) main::cursor#3) ← (byte~) main::$0 [ main::msg#2 main::line#2 main::cursor#3 ] ( main:2 [ main::msg#2 main::line#2 main::cursor#3 ] { } ) always clobbers reg byte y
|
||||||
Statement [15] (byte*) main::line#8 ← (byte*) main::cursor#1 [ main::msg#2 main::line#8 main::cursor#1 ] ( main:2 [ main::msg#2 main::line#8 main::cursor#1 ] { } ) always clobbers reg byte a
|
Statement [15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 [ main::msg#2 main::cursor#1 ] ( main:2 [ main::msg#2 main::cursor#1 ] { } ) always clobbers reg byte a
|
||||||
|
Statement [16] (byte*) main::line#8 ← (byte*) main::cursor#1 [ main::msg#2 main::line#8 main::cursor#1 ] ( main:2 [ main::msg#2 main::line#8 main::cursor#1 ] { } ) always clobbers reg byte a
|
||||||
Potential registers zp[2]:2 [ main::msg#2 main::msg#1 ] : zp[2]:2 ,
|
Potential registers zp[2]:2 [ main::msg#2 main::msg#1 ] : zp[2]:2 ,
|
||||||
Potential registers zp[2]:4 [ main::line#2 main::line#5 main::line#8 ] : zp[2]:4 ,
|
Potential registers zp[2]:4 [ main::line#2 main::line#5 main::line#8 ] : zp[2]:4 ,
|
||||||
Potential registers zp[2]:6 [ main::cursor#3 main::cursor#6 main::cursor#1 main::cursor#2 ] : zp[2]:6 ,
|
Potential registers zp[2]:6 [ main::cursor#3 main::cursor#6 main::cursor#1 main::cursor#2 ] : zp[2]:6 ,
|
||||||
@ -381,8 +403,8 @@ REGISTER UPLIFT SCOPES
|
|||||||
Uplift Scope [main] 565.6: zp[2]:6 [ main::cursor#3 main::cursor#6 main::cursor#1 main::cursor#2 ] 404: zp[2]:4 [ main::line#2 main::line#5 main::line#8 ] 258.11: zp[2]:2 [ main::msg#2 main::msg#1 ] 202: zp[1]:8 [ main::$0 ]
|
Uplift Scope [main] 565.6: zp[2]:6 [ main::cursor#3 main::cursor#6 main::cursor#1 main::cursor#2 ] 404: zp[2]:4 [ main::line#2 main::line#5 main::line#8 ] 258.11: zp[2]:2 [ main::msg#2 main::msg#1 ] 202: zp[1]:8 [ main::$0 ]
|
||||||
Uplift Scope []
|
Uplift Scope []
|
||||||
|
|
||||||
Uplifting [main] best 1463 combination zp[2]:6 [ main::cursor#3 main::cursor#6 main::cursor#1 main::cursor#2 ] zp[2]:4 [ main::line#2 main::line#5 main::line#8 ] zp[2]:2 [ main::msg#2 main::msg#1 ] reg byte a [ main::$0 ]
|
Uplifting [main] best 1472 combination zp[2]:6 [ main::cursor#3 main::cursor#6 main::cursor#1 main::cursor#2 ] zp[2]:4 [ main::line#2 main::line#5 main::line#8 ] zp[2]:2 [ main::msg#2 main::msg#1 ] reg byte a [ main::$0 ]
|
||||||
Uplifting [] best 1463 combination
|
Uplifting [] best 1472 combination
|
||||||
|
|
||||||
ASSEMBLER BEFORE OPTIMIZATION
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
// File Comments
|
// File Comments
|
||||||
@ -393,6 +415,9 @@ ASSEMBLER BEFORE OPTIMIZATION
|
|||||||
:BasicUpstart(__bbegin)
|
:BasicUpstart(__bbegin)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = '\n'
|
||||||
|
.label SCREEN = $400
|
||||||
// @begin
|
// @begin
|
||||||
__bbegin:
|
__bbegin:
|
||||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
@ -439,56 +464,61 @@ main: {
|
|||||||
lda (msg),y
|
lda (msg),y
|
||||||
cmp #0
|
cmp #0
|
||||||
bne __b2
|
bne __b2
|
||||||
|
jmp __b3
|
||||||
|
// main::@3
|
||||||
|
__b3:
|
||||||
|
// [7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH -- _deref_pbuc1=vbuc2
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$50
|
||||||
jmp __breturn
|
jmp __breturn
|
||||||
// main::@return
|
// main::@return
|
||||||
__breturn:
|
__breturn:
|
||||||
// [7] return
|
// [8] return
|
||||||
rts
|
rts
|
||||||
// main::@2
|
// main::@2
|
||||||
__b2:
|
__b2:
|
||||||
// [8] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@3 -- _deref_pbuz1_eq_vbuc1_then_la1
|
// [9] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@4 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||||
.encoding "petscii_mixed"
|
|
||||||
lda #'\n'
|
lda #'\n'
|
||||||
ldy #0
|
ldy #0
|
||||||
cmp (msg),y
|
cmp (msg),y
|
||||||
beq __b3
|
beq __b4
|
||||||
jmp __b4
|
jmp __b5
|
||||||
// main::@4
|
// main::@5
|
||||||
__b4:
|
__b5:
|
||||||
// [9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuaa=_deref_pbuz1_band_vbuc1
|
// [10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuaa=_deref_pbuz1_band_vbuc1
|
||||||
lda #$3f
|
lda #$3f
|
||||||
ldy #0
|
ldy #0
|
||||||
and (msg),y
|
and (msg),y
|
||||||
// [10] *((byte*) main::cursor#3) ← (byte~) main::$0 -- _deref_pbuz1=vbuaa
|
// [11] *((byte*) main::cursor#3) ← (byte~) main::$0 -- _deref_pbuz1=vbuaa
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (cursor),y
|
sta (cursor),y
|
||||||
// [11] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3 -- pbuz1=_inc_pbuz1
|
// [12] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3 -- pbuz1=_inc_pbuz1
|
||||||
inc.z cursor
|
inc.z cursor
|
||||||
bne !+
|
bne !+
|
||||||
inc.z cursor+1
|
inc.z cursor+1
|
||||||
!:
|
!:
|
||||||
// [12] phi from main::@3 main::@4 to main::@5 [phi:main::@3/main::@4->main::@5]
|
// [13] phi from main::@4 main::@5 to main::@6 [phi:main::@4/main::@5->main::@6]
|
||||||
__b5_from___b3:
|
__b6_from___b4:
|
||||||
__b5_from___b4:
|
__b6_from___b5:
|
||||||
// [12] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@3/main::@4->main::@5#0] -- register_copy
|
// [13] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@4/main::@5->main::@6#0] -- register_copy
|
||||||
// [12] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@3/main::@4->main::@5#1] -- register_copy
|
// [13] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@4/main::@5->main::@6#1] -- register_copy
|
||||||
jmp __b5
|
jmp __b6
|
||||||
// main::@5
|
// main::@6
|
||||||
__b5:
|
__b6:
|
||||||
// [13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
// [14] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
||||||
inc.z msg
|
inc.z msg
|
||||||
bne !+
|
bne !+
|
||||||
inc.z msg+1
|
inc.z msg+1
|
||||||
!:
|
!:
|
||||||
// [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
|
// [5] phi from main::@6 to main::@1 [phi:main::@6->main::@1]
|
||||||
__b1_from___b5:
|
__b1_from___b6:
|
||||||
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@5->main::@1#0] -- register_copy
|
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@6->main::@1#0] -- register_copy
|
||||||
// [5] phi (byte*) main::line#2 = (byte*) main::line#5 [phi:main::@5->main::@1#1] -- register_copy
|
// [5] phi (byte*) main::line#2 = (byte*) main::line#5 [phi:main::@6->main::@1#1] -- register_copy
|
||||||
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@5->main::@1#2] -- register_copy
|
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@6->main::@1#2] -- register_copy
|
||||||
jmp __b1
|
jmp __b1
|
||||||
// main::@3
|
// main::@4
|
||||||
__b3:
|
__b4:
|
||||||
// [14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
// [15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
||||||
lda #$28
|
lda #$28
|
||||||
clc
|
clc
|
||||||
adc.z line
|
adc.z line
|
||||||
@ -496,12 +526,12 @@ main: {
|
|||||||
lda #0
|
lda #0
|
||||||
adc.z line+1
|
adc.z line+1
|
||||||
sta.z cursor+1
|
sta.z cursor+1
|
||||||
// [15] (byte*) main::line#8 ← (byte*) main::cursor#1 -- pbuz1=pbuz2
|
// [16] (byte*) main::line#8 ← (byte*) main::cursor#1 -- pbuz1=pbuz2
|
||||||
lda.z cursor
|
lda.z cursor
|
||||||
sta.z line
|
sta.z line
|
||||||
lda.z cursor+1
|
lda.z cursor+1
|
||||||
sta.z line+1
|
sta.z line+1
|
||||||
jmp __b5_from___b3
|
jmp __b6_from___b4
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
MESSAGE: .text @"hello\nworld"
|
MESSAGE: .text @"hello\nworld"
|
||||||
@ -511,25 +541,27 @@ ASSEMBLER OPTIMIZATIONS
|
|||||||
Removing instruction jmp __b1
|
Removing instruction jmp __b1
|
||||||
Removing instruction jmp __bend
|
Removing instruction jmp __bend
|
||||||
Removing instruction jmp __b1
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __b3
|
||||||
Removing instruction jmp __breturn
|
Removing instruction jmp __breturn
|
||||||
Removing instruction jmp __b4
|
|
||||||
Removing instruction jmp __b5
|
Removing instruction jmp __b5
|
||||||
|
Removing instruction jmp __b6
|
||||||
Succesful ASM optimization Pass5NextJumpElimination
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
Removing instruction ldy #0
|
Removing instruction ldy #0
|
||||||
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||||
Replacing label __b5_from___b3 with __b5
|
Replacing label __b6_from___b4 with __b6
|
||||||
Removing instruction __b1_from___bbegin:
|
Removing instruction __b1_from___bbegin:
|
||||||
Removing instruction __b1:
|
Removing instruction __b1:
|
||||||
Removing instruction main_from___b1:
|
Removing instruction main_from___b1:
|
||||||
Removing instruction __bend_from___b1:
|
Removing instruction __bend_from___b1:
|
||||||
Removing instruction __b5_from___b3:
|
Removing instruction __b6_from___b4:
|
||||||
Removing instruction __b5_from___b4:
|
Removing instruction __b6_from___b5:
|
||||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||||
Removing instruction __bend:
|
Removing instruction __bend:
|
||||||
Removing instruction __b1_from_main:
|
Removing instruction __b1_from_main:
|
||||||
|
Removing instruction __b3:
|
||||||
Removing instruction __breturn:
|
Removing instruction __breturn:
|
||||||
Removing instruction __b4:
|
Removing instruction __b5:
|
||||||
Removing instruction __b1_from___b5:
|
Removing instruction __b1_from___b6:
|
||||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
Updating BasicUpstart to call main directly
|
Updating BasicUpstart to call main directly
|
||||||
Removing instruction jsr main
|
Removing instruction jsr main
|
||||||
@ -543,8 +575,11 @@ FINAL SYMBOL TABLE
|
|||||||
(label) @1
|
(label) @1
|
||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
|
(const byte) CH = (byte) '
|
||||||
|
'pm
|
||||||
(const byte*) MESSAGE[] = (byte*) "hello
|
(const byte*) MESSAGE[] = (byte*) "hello
|
||||||
world"pm
|
world"pm
|
||||||
|
(const byte*) SCREEN = (byte*) 1024
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(byte~) main::$0 reg byte a 202.0
|
(byte~) main::$0 reg byte a 202.0
|
||||||
(label) main::@1
|
(label) main::@1
|
||||||
@ -552,6 +587,7 @@ world"pm
|
|||||||
(label) main::@3
|
(label) main::@3
|
||||||
(label) main::@4
|
(label) main::@4
|
||||||
(label) main::@5
|
(label) main::@5
|
||||||
|
(label) main::@6
|
||||||
(label) main::@return
|
(label) main::@return
|
||||||
(byte*) main::cursor
|
(byte*) main::cursor
|
||||||
(byte*) main::cursor#1 cursor zp[2]:6 151.5
|
(byte*) main::cursor#1 cursor zp[2]:6 151.5
|
||||||
@ -573,7 +609,7 @@ reg byte a [ main::$0 ]
|
|||||||
|
|
||||||
|
|
||||||
FINAL ASSEMBLER
|
FINAL ASSEMBLER
|
||||||
Score: 1291
|
Score: 1297
|
||||||
|
|
||||||
// File Comments
|
// File Comments
|
||||||
// Test using some simple supported string escape \n in both string and char
|
// Test using some simple supported string escape \n in both string and char
|
||||||
@ -583,6 +619,9 @@ Score: 1291
|
|||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = '\n'
|
||||||
|
.label SCREEN = $400
|
||||||
// @begin
|
// @begin
|
||||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
// @1
|
// @1
|
||||||
@ -619,9 +658,14 @@ main: {
|
|||||||
lda (msg),y
|
lda (msg),y
|
||||||
cmp #0
|
cmp #0
|
||||||
bne __b2
|
bne __b2
|
||||||
|
// main::@3
|
||||||
|
// SCREEN[0x50] = CH
|
||||||
|
// [7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH -- _deref_pbuc1=vbuc2
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$50
|
||||||
// main::@return
|
// main::@return
|
||||||
// }
|
// }
|
||||||
// [7] return
|
// [8] return
|
||||||
rts
|
rts
|
||||||
// main::@2
|
// main::@2
|
||||||
__b2:
|
__b2:
|
||||||
@ -629,46 +673,45 @@ main: {
|
|||||||
// line += 0x28;
|
// line += 0x28;
|
||||||
// cursor = line;
|
// cursor = line;
|
||||||
// break;
|
// break;
|
||||||
// [8] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@3 -- _deref_pbuz1_eq_vbuc1_then_la1
|
// [9] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@4 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||||
.encoding "petscii_mixed"
|
|
||||||
lda #'\n'
|
lda #'\n'
|
||||||
ldy #0
|
ldy #0
|
||||||
cmp (msg),y
|
cmp (msg),y
|
||||||
beq __b3
|
beq __b4
|
||||||
// main::@4
|
// main::@5
|
||||||
// *msg & 0x3f
|
// *msg & 0x3f
|
||||||
// [9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuaa=_deref_pbuz1_band_vbuc1
|
// [10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuaa=_deref_pbuz1_band_vbuc1
|
||||||
lda #$3f
|
lda #$3f
|
||||||
and (msg),y
|
and (msg),y
|
||||||
// *cursor++ = *msg & 0x3f
|
// *cursor++ = *msg & 0x3f
|
||||||
// [10] *((byte*) main::cursor#3) ← (byte~) main::$0 -- _deref_pbuz1=vbuaa
|
// [11] *((byte*) main::cursor#3) ← (byte~) main::$0 -- _deref_pbuz1=vbuaa
|
||||||
sta (cursor),y
|
sta (cursor),y
|
||||||
// *cursor++ = *msg & 0x3f;
|
// *cursor++ = *msg & 0x3f;
|
||||||
// [11] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3 -- pbuz1=_inc_pbuz1
|
// [12] (byte*) main::cursor#2 ← ++ (byte*) main::cursor#3 -- pbuz1=_inc_pbuz1
|
||||||
inc.z cursor
|
inc.z cursor
|
||||||
bne !+
|
bne !+
|
||||||
inc.z cursor+1
|
inc.z cursor+1
|
||||||
!:
|
!:
|
||||||
// [12] phi from main::@3 main::@4 to main::@5 [phi:main::@3/main::@4->main::@5]
|
// [13] phi from main::@4 main::@5 to main::@6 [phi:main::@4/main::@5->main::@6]
|
||||||
// [12] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@3/main::@4->main::@5#0] -- register_copy
|
// [13] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@4/main::@5->main::@6#0] -- register_copy
|
||||||
// [12] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@3/main::@4->main::@5#1] -- register_copy
|
// [13] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@4/main::@5->main::@6#1] -- register_copy
|
||||||
// main::@5
|
// main::@6
|
||||||
__b5:
|
__b6:
|
||||||
// msg++;
|
// msg++;
|
||||||
// [13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
// [14] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
||||||
inc.z msg
|
inc.z msg
|
||||||
bne !+
|
bne !+
|
||||||
inc.z msg+1
|
inc.z msg+1
|
||||||
!:
|
!:
|
||||||
// [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
|
// [5] phi from main::@6 to main::@1 [phi:main::@6->main::@1]
|
||||||
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@5->main::@1#0] -- register_copy
|
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@6->main::@1#0] -- register_copy
|
||||||
// [5] phi (byte*) main::line#2 = (byte*) main::line#5 [phi:main::@5->main::@1#1] -- register_copy
|
// [5] phi (byte*) main::line#2 = (byte*) main::line#5 [phi:main::@6->main::@1#1] -- register_copy
|
||||||
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@5->main::@1#2] -- register_copy
|
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@6->main::@1#2] -- register_copy
|
||||||
jmp __b1
|
jmp __b1
|
||||||
// main::@3
|
// main::@4
|
||||||
__b3:
|
__b4:
|
||||||
// line += 0x28
|
// line += 0x28
|
||||||
// [14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
// [15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
||||||
lda #$28
|
lda #$28
|
||||||
clc
|
clc
|
||||||
adc.z line
|
adc.z line
|
||||||
@ -676,12 +719,12 @@ main: {
|
|||||||
lda #0
|
lda #0
|
||||||
adc.z line+1
|
adc.z line+1
|
||||||
sta.z cursor+1
|
sta.z cursor+1
|
||||||
// [15] (byte*) main::line#8 ← (byte*) main::cursor#1 -- pbuz1=pbuz2
|
// [16] (byte*) main::line#8 ← (byte*) main::cursor#1 -- pbuz1=pbuz2
|
||||||
lda.z cursor
|
lda.z cursor
|
||||||
sta.z line
|
sta.z line
|
||||||
lda.z cursor+1
|
lda.z cursor+1
|
||||||
sta.z line+1
|
sta.z line+1
|
||||||
jmp __b5
|
jmp __b6
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
MESSAGE: .text @"hello\nworld"
|
MESSAGE: .text @"hello\nworld"
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
(label) @1
|
(label) @1
|
||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
|
(const byte) CH = (byte) '
|
||||||
|
'pm
|
||||||
(const byte*) MESSAGE[] = (byte*) "hello
|
(const byte*) MESSAGE[] = (byte*) "hello
|
||||||
world"pm
|
world"pm
|
||||||
|
(const byte*) SCREEN = (byte*) 1024
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(byte~) main::$0 reg byte a 202.0
|
(byte~) main::$0 reg byte a 202.0
|
||||||
(label) main::@1
|
(label) main::@1
|
||||||
@ -10,6 +13,7 @@ world"pm
|
|||||||
(label) main::@3
|
(label) main::@3
|
||||||
(label) main::@4
|
(label) main::@4
|
||||||
(label) main::@5
|
(label) main::@5
|
||||||
|
(label) main::@6
|
||||||
(label) main::@return
|
(label) main::@return
|
||||||
(byte*) main::cursor
|
(byte*) main::cursor
|
||||||
(byte*) main::cursor#1 cursor zp[2]:6 151.5
|
(byte*) main::cursor#1 cursor zp[2]:6 151.5
|
||||||
|
30
src/test/ref/string-escapes-5.asm
Normal file
30
src/test/ref/string-escapes-5.asm
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Test using some simple supported string escape
|
||||||
|
// Uses \xnn to add chars by hex-code that do not exist with the encoding.
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
.label SCREEN = $400
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = -1
|
||||||
|
main: {
|
||||||
|
ldx #0
|
||||||
|
__b1:
|
||||||
|
// while(MESSAGE[i])
|
||||||
|
lda MESSAGE,x
|
||||||
|
cmp #0
|
||||||
|
bne __b2
|
||||||
|
// SCREEN[0x28] = CH
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$28
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
__b2:
|
||||||
|
// SCREEN[i] = MESSAGE[i++]
|
||||||
|
lda MESSAGE,x
|
||||||
|
sta SCREEN,x
|
||||||
|
// SCREEN[i] = MESSAGE[i++];
|
||||||
|
inx
|
||||||
|
jmp __b1
|
||||||
|
}
|
||||||
|
MESSAGE: .text @"qwe\$ffasd\$ferty"
|
||||||
|
.byte 0
|
28
src/test/ref/string-escapes-5.cfg
Normal file
28
src/test/ref/string-escapes-5.cfg
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
@begin: scope:[] from
|
||||||
|
[0] phi()
|
||||||
|
to:@1
|
||||||
|
@1: scope:[] from @begin
|
||||||
|
[1] phi()
|
||||||
|
[2] call main
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @1
|
||||||
|
[3] phi()
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from @1
|
||||||
|
[4] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@2
|
||||||
|
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
|
||||||
|
[6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
[7] *((const nomodify byte*) SCREEN+(byte) $28) ← (const byte) CH
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@3
|
||||||
|
[8] return
|
||||||
|
to:@return
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
[9] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2)
|
||||||
|
[10] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||||
|
to:main::@1
|
398
src/test/ref/string-escapes-5.log
Normal file
398
src/test/ref/string-escapes-5.log
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
Warning! Adding boolean cast to non-boolean condition *((const byte*) MESSAGE + (byte) main::i)
|
||||||
|
Identified constant variable (byte) CH
|
||||||
|
Culled Empty Block (label) main::@4
|
||||||
|
Culled Empty Block (label) main::@5
|
||||||
|
Culled Empty Block (label) main::@6
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
@begin: scope:[] from
|
||||||
|
to:@1
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from @1
|
||||||
|
(byte) main::i#0 ← (byte) 0
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@2
|
||||||
|
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
|
||||||
|
(bool~) main::$0 ← (number) 0 != *((const byte*) MESSAGE + (byte) main::i#2)
|
||||||
|
if((bool~) main::$0) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
|
||||||
|
*((const nomodify byte*) SCREEN + (byte) main::i#3) ← *((const byte*) MESSAGE + (byte) main::i#3)
|
||||||
|
(byte) main::i#1 ← ++ (byte) main::i#3
|
||||||
|
to:main::@1
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
*((const nomodify byte*) SCREEN + (number) $28) ← (const byte) CH
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@3
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
@1: scope:[] from @begin
|
||||||
|
call main
|
||||||
|
to:@2
|
||||||
|
@2: scope:[] from @1
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @2
|
||||||
|
|
||||||
|
SYMBOL TABLE SSA
|
||||||
|
(label) @1
|
||||||
|
(label) @2
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(const byte) CH = (byte) '刺'pm
|
||||||
|
(const byte*) MESSAGE[] = (byte*) "qwe刺asd茶rty"pm
|
||||||
|
(const nomodify byte*) SCREEN = (byte*)(number) $400
|
||||||
|
(void()) main()
|
||||||
|
(bool~) main::$0
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@3
|
||||||
|
(label) main::@return
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#0
|
||||||
|
(byte) main::i#1
|
||||||
|
(byte) main::i#2
|
||||||
|
(byte) main::i#3
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) 0 in (bool~) main::$0 ← (number) 0 != *((const byte*) MESSAGE + (byte) main::i#2)
|
||||||
|
Adding number conversion cast (unumber) $28 in *((const nomodify byte*) SCREEN + (number) $28) ← (const byte) CH
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Simplifying constant pointer cast (byte*) 1024
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast $28
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) $28
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Alias main::i#2 = main::i#3
|
||||||
|
Successful SSA optimization Pass2AliasElimination
|
||||||
|
Simple Condition (bool~) main::$0 [3] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2
|
||||||
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||||
|
Constant (const byte) main::i#0 = 0
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Inlining constant with var siblings (const byte) main::i#0
|
||||||
|
Constant inlined main::i#0 = (byte) 0
|
||||||
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
Consolidated array index constant in *(SCREEN+$28)
|
||||||
|
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||||
|
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
|
||||||
|
CALL GRAPH
|
||||||
|
Calls in [] to main:2
|
||||||
|
|
||||||
|
Created 1 initial phi equivalence classes
|
||||||
|
Coalesced [12] main::i#4 ← main::i#1
|
||||||
|
Coalesced down to 1 phi equivalence classes
|
||||||
|
Culled Empty Block (label) @2
|
||||||
|
Adding NOP phi() at start of @begin
|
||||||
|
Adding NOP phi() at start of @1
|
||||||
|
Adding NOP phi() at start of @end
|
||||||
|
Adding NOP phi() at start of main
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
@begin: scope:[] from
|
||||||
|
[0] phi()
|
||||||
|
to:@1
|
||||||
|
@1: scope:[] from @begin
|
||||||
|
[1] phi()
|
||||||
|
[2] call main
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @1
|
||||||
|
[3] phi()
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from @1
|
||||||
|
[4] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@2
|
||||||
|
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
|
||||||
|
[6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
[7] *((const nomodify byte*) SCREEN+(byte) $28) ← (const byte) CH
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@3
|
||||||
|
[8] return
|
||||||
|
to:@return
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
[9] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2)
|
||||||
|
[10] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||||
|
to:main::@1
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
(void()) main()
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#1 202.0
|
||||||
|
(byte) main::i#2 168.33333333333331
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
[ main::i#2 main::i#1 ]
|
||||||
|
Complete equivalence classes
|
||||||
|
[ main::i#2 main::i#1 ]
|
||||||
|
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
|
||||||
|
INITIAL ASM
|
||||||
|
Target platform is c64basic / MOS6502X
|
||||||
|
// File Comments
|
||||||
|
// Test using some simple supported string escape
|
||||||
|
// Uses \xnn to add chars by hex-code that do not exist with the encoding.
|
||||||
|
// Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(__bbegin)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = -1
|
||||||
|
// @begin
|
||||||
|
__bbegin:
|
||||||
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
__b1_from___bbegin:
|
||||||
|
jmp __b1
|
||||||
|
// @1
|
||||||
|
__b1:
|
||||||
|
// [2] call main
|
||||||
|
// [4] phi from @1 to main [phi:@1->main]
|
||||||
|
main_from___b1:
|
||||||
|
jsr main
|
||||||
|
// [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
__bend_from___b1:
|
||||||
|
jmp __bend
|
||||||
|
// @end
|
||||||
|
__bend:
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
.label i = 2
|
||||||
|
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
__b1_from_main:
|
||||||
|
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||||
|
lda #0
|
||||||
|
sta.z i
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 -- vbuc1_neq_pbuc2_derefidx_vbuz1_then_la1
|
||||||
|
lda #0
|
||||||
|
ldy.z i
|
||||||
|
cmp MESSAGE,y
|
||||||
|
bne __b2
|
||||||
|
jmp __b3
|
||||||
|
// main::@3
|
||||||
|
__b3:
|
||||||
|
// [7] *((const nomodify byte*) SCREEN+(byte) $28) ← (const byte) CH -- _deref_pbuc1=vbuc2
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$28
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [8] return
|
||||||
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// [9] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz1
|
||||||
|
ldy.z i
|
||||||
|
lda MESSAGE,y
|
||||||
|
sta SCREEN,y
|
||||||
|
// [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||||
|
inc.z i
|
||||||
|
// [5] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
__b1_from___b2:
|
||||||
|
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
jmp __b1
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
MESSAGE: .text @"qwe\$ffasd\$ferty"
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||||
|
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Statement [7] *((const nomodify byte*) SCREEN+(byte) $28) ← (const byte) CH [ ] ( main:2 [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [9] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||||
|
Statement [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||||
|
Statement [7] *((const nomodify byte*) SCREEN+(byte) $28) ← (const byte) CH [ ] ( main:2 [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [9] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||||
|
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [main] 370.33: zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Uplift Scope []
|
||||||
|
|
||||||
|
Uplifting [main] best 342 combination reg byte x [ main::i#2 main::i#1 ]
|
||||||
|
Uplifting [] best 342 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
// File Comments
|
||||||
|
// Test using some simple supported string escape
|
||||||
|
// Uses \xnn to add chars by hex-code that do not exist with the encoding.
|
||||||
|
// Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(__bbegin)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = -1
|
||||||
|
// @begin
|
||||||
|
__bbegin:
|
||||||
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
__b1_from___bbegin:
|
||||||
|
jmp __b1
|
||||||
|
// @1
|
||||||
|
__b1:
|
||||||
|
// [2] call main
|
||||||
|
// [4] phi from @1 to main [phi:@1->main]
|
||||||
|
main_from___b1:
|
||||||
|
jsr main
|
||||||
|
// [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
__bend_from___b1:
|
||||||
|
jmp __bend
|
||||||
|
// @end
|
||||||
|
__bend:
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
__b1_from_main:
|
||||||
|
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||||
|
ldx #0
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 -- vbuc1_neq_pbuc2_derefidx_vbuxx_then_la1
|
||||||
|
lda MESSAGE,x
|
||||||
|
cmp #0
|
||||||
|
bne __b2
|
||||||
|
jmp __b3
|
||||||
|
// main::@3
|
||||||
|
__b3:
|
||||||
|
// [7] *((const nomodify byte*) SCREEN+(byte) $28) ← (const byte) CH -- _deref_pbuc1=vbuc2
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$28
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [8] return
|
||||||
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// [9] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
|
||||||
|
lda MESSAGE,x
|
||||||
|
sta SCREEN,x
|
||||||
|
// [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||||
|
inx
|
||||||
|
// [5] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
__b1_from___b2:
|
||||||
|
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
jmp __b1
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
MESSAGE: .text @"qwe\$ffasd\$ferty"
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __bend
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __b3
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction __b1_from___bbegin:
|
||||||
|
Removing instruction __b1:
|
||||||
|
Removing instruction main_from___b1:
|
||||||
|
Removing instruction __bend_from___b1:
|
||||||
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||||
|
Removing instruction __bend:
|
||||||
|
Removing instruction __b1_from_main:
|
||||||
|
Removing instruction __b3:
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Removing instruction __b1_from___b2:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
Updating BasicUpstart to call main directly
|
||||||
|
Removing instruction jsr main
|
||||||
|
Succesful ASM optimization Pass5SkipBegin
|
||||||
|
Removing instruction __bbegin:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
(label) @1
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(const byte) CH = (byte) '刺'pm
|
||||||
|
(const byte*) MESSAGE[] = (byte*) "qwe刺asd茶rty"pm
|
||||||
|
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@3
|
||||||
|
(label) main::@return
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#1 reg byte x 202.0
|
||||||
|
(byte) main::i#2 reg byte x 168.33333333333331
|
||||||
|
|
||||||
|
reg byte x [ main::i#2 main::i#1 ]
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 267
|
||||||
|
|
||||||
|
// File Comments
|
||||||
|
// Test using some simple supported string escape
|
||||||
|
// Uses \xnn to add chars by hex-code that do not exist with the encoding.
|
||||||
|
// Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
|
.encoding "petscii_mixed"
|
||||||
|
.const CH = -1
|
||||||
|
// @begin
|
||||||
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
// @1
|
||||||
|
// [2] call main
|
||||||
|
// [4] phi from @1 to main [phi:@1->main]
|
||||||
|
// [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
// @end
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||||
|
ldx #0
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// while(MESSAGE[i])
|
||||||
|
// [6] if((byte) 0!=*((const byte*) MESSAGE + (byte) main::i#2)) goto main::@2 -- vbuc1_neq_pbuc2_derefidx_vbuxx_then_la1
|
||||||
|
lda MESSAGE,x
|
||||||
|
cmp #0
|
||||||
|
bne __b2
|
||||||
|
// main::@3
|
||||||
|
// SCREEN[0x28] = CH
|
||||||
|
// [7] *((const nomodify byte*) SCREEN+(byte) $28) ← (const byte) CH -- _deref_pbuc1=vbuc2
|
||||||
|
lda #CH
|
||||||
|
sta SCREEN+$28
|
||||||
|
// main::@return
|
||||||
|
// }
|
||||||
|
// [8] return
|
||||||
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// SCREEN[i] = MESSAGE[i++]
|
||||||
|
// [9] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) MESSAGE + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
|
||||||
|
lda MESSAGE,x
|
||||||
|
sta SCREEN,x
|
||||||
|
// SCREEN[i] = MESSAGE[i++];
|
||||||
|
// [10] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||||
|
inx
|
||||||
|
// [5] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
jmp __b1
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
MESSAGE: .text @"qwe\$ffasd\$ferty"
|
||||||
|
.byte 0
|
||||||
|
|
16
src/test/ref/string-escapes-5.sym
Normal file
16
src/test/ref/string-escapes-5.sym
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
(label) @1
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(const byte) CH = (byte) '刺'pm
|
||||||
|
(const byte*) MESSAGE[] = (byte*) "qwe刺asd茶rty"pm
|
||||||
|
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@3
|
||||||
|
(label) main::@return
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#1 reg byte x 202.0
|
||||||
|
(byte) main::i#2 reg byte x 168.33333333333331
|
||||||
|
|
||||||
|
reg byte x [ main::i#2 main::i#1 ]
|
Loading…
Reference in New Issue
Block a user