mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-29 18:49:42 +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());
|
||||
} else if(value instanceof ConstantChar) {
|
||||
ConstantChar constantChar = (ConstantChar) value;
|
||||
if(!constantChar.getEncoding().hasEncoding(constantChar.getChar()))
|
||||
return getAsmNumber(constantChar.getInteger());
|
||||
else {
|
||||
String escapedChar = constantChar.getCharEscaped();
|
||||
return "'" + escapedChar + "'";
|
||||
}
|
||||
} else if(value instanceof ConstantString) {
|
||||
String stringValue = ((ConstantString) value).getValue();
|
||||
String escapedString = ((ConstantString) value).getStringEscaped();
|
||||
|
@ -14,6 +14,14 @@ public enum StringEncoding {
|
||||
SCREENCODE_MIXED("screencode_mixed", "sm", CharToPetsciiConverter.charToScreenCode_mixed),
|
||||
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. */
|
||||
public final String name;
|
||||
|
||||
@ -72,9 +80,24 @@ public enum StringEncoding {
|
||||
*/
|
||||
public Long encodedFromChar(Character aChar) {
|
||||
Byte encodedValue = mapping.get(aChar);
|
||||
if(encodedValue != null)
|
||||
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
|
||||
*
|
||||
@ -86,7 +109,8 @@ public enum StringEncoding {
|
||||
if(mapEntry.getValue() == encodedValue.byteValue())
|
||||
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);
|
||||
case '\\':
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -641,11 +641,6 @@ public class TestPrograms {
|
||||
compileAndCompare("code-after-return");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringEscapesErr2() throws IOException, URISyntaxException {
|
||||
assertError("string-escapes-err-2", "No character 0xff in encoding petscii_mixed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringEscapesErr1() throws IOException, URISyntaxException {
|
||||
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");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringEscapes5() throws IOException, URISyntaxException {
|
||||
compileAndCompare("string-escapes-5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringEscapes4() throws IOException, URISyntaxException {
|
||||
compileAndCompare("string-escapes-4");
|
||||
|
@ -4,6 +4,8 @@
|
||||
#pragma encoding(petscii_mixed)
|
||||
|
||||
char MESSAGE[] = "hello\nworld";
|
||||
char CH = '\n';
|
||||
|
||||
char* SCREEN = 0x0400;
|
||||
|
||||
void main() {
|
||||
@ -23,4 +25,6 @@ void main() {
|
||||
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"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.encoding "petscii_mixed"
|
||||
.const CH = '\n'
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
.label cursor = 6
|
||||
.label msg = 2
|
||||
@ -25,6 +28,9 @@ main: {
|
||||
lda (msg),y
|
||||
cmp #0
|
||||
bne __b2
|
||||
// SCREEN[0x50] = CH
|
||||
lda #CH
|
||||
sta SCREEN+$50
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
@ -32,11 +38,10 @@ main: {
|
||||
// line += 0x28;
|
||||
// cursor = line;
|
||||
// break;
|
||||
.encoding "petscii_mixed"
|
||||
lda #'\n'
|
||||
ldy #0
|
||||
cmp (msg),y
|
||||
beq __b3
|
||||
beq __b4
|
||||
// *msg & 0x3f
|
||||
lda #$3f
|
||||
and (msg),y
|
||||
@ -47,14 +52,14 @@ main: {
|
||||
bne !+
|
||||
inc.z cursor+1
|
||||
!:
|
||||
__b5:
|
||||
__b6:
|
||||
// msg++;
|
||||
inc.z msg
|
||||
bne !+
|
||||
inc.z msg+1
|
||||
!:
|
||||
jmp __b1
|
||||
__b3:
|
||||
__b4:
|
||||
// line += 0x28
|
||||
lda #$28
|
||||
clc
|
||||
@ -67,7 +72,7 @@ main: {
|
||||
sta.z line
|
||||
lda.z cursor+1
|
||||
sta.z line+1
|
||||
jmp __b5
|
||||
jmp __b6
|
||||
}
|
||||
MESSAGE: .text @"hello\nworld"
|
||||
.byte 0
|
||||
|
@ -12,30 +12,33 @@
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@5
|
||||
[5] (byte*) main::cursor#3 ← phi( main/(byte*) 1024 main::@5/(byte*) main::cursor#6 )
|
||||
[5] (byte*) main::line#2 ← phi( main/(byte*) 1024 main::@5/(byte*) main::line#5 )
|
||||
[5] (byte*) main::msg#2 ← phi( main/(const byte*) MESSAGE main::@5/(byte*) main::msg#1 )
|
||||
main::@1: scope:[main] from main main::@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::@6/(byte*) main::line#5 )
|
||||
[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
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1
|
||||
[7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[7] return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[8] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
[8] if(*((byte*) main::msg#2)==(byte) '
|
||||
'pm) goto main::@3
|
||||
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
|
||||
[9] if(*((byte*) main::msg#2)==(byte) '
|
||||
'pm) goto main::@4
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@3 main::@4
|
||||
[12] (byte*) main::cursor#6 ← phi( main::@3/(byte*) main::cursor#1 main::@4/(byte*) main::cursor#2 )
|
||||
[12] (byte*) main::line#5 ← phi( main::@3/(byte*) main::line#8 main::@4/(byte*) main::line#2 )
|
||||
[13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2
|
||||
main::@5: scope:[main] from main::@2
|
||||
[10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f
|
||||
[11] *((byte*) main::cursor#3) ← (byte~) main::$0
|
||||
[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
|
||||
main::@3: scope:[main] from main::@2
|
||||
[14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
||||
[15] (byte*) main::line#8 ← (byte*) main::cursor#1
|
||||
to:main::@5
|
||||
main::@4: scope:[main] from main::@2
|
||||
[15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
||||
[16] (byte*) main::line#8 ← (byte*) main::cursor#1
|
||||
to:main::@6
|
||||
|
@ -1,7 +1,7 @@
|
||||
Warning! Adding boolean cast to non-boolean condition *((byte*) main::msg)
|
||||
Identified constant variable (byte) CH
|
||||
Identified constant variable (byte*) SCREEN
|
||||
Culled Empty Block (label) main::@9
|
||||
Culled Empty Block (label) main::@3
|
||||
Culled Empty Block (label) main::@10
|
||||
Culled Empty Block (label) main::@11
|
||||
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 )
|
||||
(bool~) main::$1 ← (number) 0 != *((byte*) main::msg#2)
|
||||
if((bool~) main::$1) goto main::@2
|
||||
to:main::@return
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte*) main::cursor#4 ← phi( main::@1/(byte*) main::cursor#5 )
|
||||
(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) '
|
||||
'pm) goto main::@4
|
||||
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
|
||||
(byte*) main::msg#6 ← phi( main::@2/(byte*) main::msg#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#1 ← ++ (byte*) main::msg#5
|
||||
to:main::@1
|
||||
main::@return: scope:[main] from main::@1
|
||||
main::@return: scope:[main] from main::@3
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
@ -67,13 +70,17 @@ SYMBOL TABLE SSA
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) CH = (byte) '
|
||||
'pm
|
||||
(const byte*) MESSAGE[] = (byte*) "hello
|
||||
world"pm
|
||||
(const byte*) SCREEN = (byte*)(number) $400
|
||||
(void()) main()
|
||||
(number~) main::$0
|
||||
(bool~) main::$1
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
@ -104,16 +111,20 @@ world"pm
|
||||
(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) $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) $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
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast 0
|
||||
Simplifying constant integer cast $50
|
||||
Simplifying constant integer cast $28
|
||||
Simplifying constant integer cast $3f
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) $50
|
||||
Finalized unsigned number type (byte) $28
|
||||
Finalized unsigned number type (byte) $3f
|
||||
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::msg#0 = (const byte*) MESSAGE
|
||||
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 @1
|
||||
Adding NOP phi() at start of @2
|
||||
@ -145,18 +158,15 @@ CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 5 initial phi equivalence classes
|
||||
Coalesced [13] main::line#9 ← main::line#2
|
||||
Coalesced [14] main::cursor#9 ← main::cursor#2
|
||||
Coalesced [17] main::msg#7 ← main::msg#1
|
||||
Coalesced (already) [18] main::line#7 ← main::line#5
|
||||
Coalesced [19] main::cursor#7 ← main::cursor#6
|
||||
Not coalescing [21] main::line#8 ← main::cursor#1
|
||||
Coalesced [22] main::cursor#8 ← main::cursor#1
|
||||
Coalesced [14] main::line#9 ← main::line#2
|
||||
Coalesced [15] main::cursor#9 ← main::cursor#2
|
||||
Coalesced [18] main::msg#7 ← main::msg#1
|
||||
Coalesced (already) [19] main::line#7 ← main::line#5
|
||||
Coalesced [20] main::cursor#7 ← main::cursor#6
|
||||
Not coalescing [22] main::line#8 ← main::cursor#1
|
||||
Coalesced [23] main::cursor#8 ← main::cursor#1
|
||||
Coalesced down to 3 phi equivalence classes
|
||||
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 @1
|
||||
Adding NOP phi() at start of @end
|
||||
@ -177,33 +187,36 @@ FINAL CONTROL FLOW GRAPH
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@5
|
||||
[5] (byte*) main::cursor#3 ← phi( main/(byte*) 1024 main::@5/(byte*) main::cursor#6 )
|
||||
[5] (byte*) main::line#2 ← phi( main/(byte*) 1024 main::@5/(byte*) main::line#5 )
|
||||
[5] (byte*) main::msg#2 ← phi( main/(const byte*) MESSAGE main::@5/(byte*) main::msg#1 )
|
||||
main::@1: scope:[main] from main main::@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::@6/(byte*) main::line#5 )
|
||||
[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
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1
|
||||
[7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[7] return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[8] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
[8] if(*((byte*) main::msg#2)==(byte) '
|
||||
'pm) goto main::@3
|
||||
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
|
||||
[9] if(*((byte*) main::msg#2)==(byte) '
|
||||
'pm) goto main::@4
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@3 main::@4
|
||||
[12] (byte*) main::cursor#6 ← phi( main::@3/(byte*) main::cursor#1 main::@4/(byte*) main::cursor#2 )
|
||||
[12] (byte*) main::line#5 ← phi( main::@3/(byte*) main::line#8 main::@4/(byte*) main::line#2 )
|
||||
[13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2
|
||||
main::@5: scope:[main] from main::@2
|
||||
[10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f
|
||||
[11] *((byte*) main::cursor#3) ← (byte~) main::$0
|
||||
[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
|
||||
main::@3: scope:[main] from main::@2
|
||||
[14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
||||
[15] (byte*) main::line#8 ← (byte*) main::cursor#1
|
||||
to:main::@5
|
||||
main::@4: scope:[main] from main::@2
|
||||
[15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28
|
||||
[16] (byte*) main::line#8 ← (byte*) main::cursor#1
|
||||
to:main::@6
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
@ -247,6 +260,9 @@ Target platform is c64basic / MOS6502X
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.encoding "petscii_mixed"
|
||||
.const CH = '\n'
|
||||
.label SCREEN = $400
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
@ -294,58 +310,63 @@ main: {
|
||||
lda (msg),y
|
||||
cmp #0
|
||||
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
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [7] return
|
||||
// [8] return
|
||||
rts
|
||||
// main::@2
|
||||
__b2:
|
||||
// [8] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@3 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||
.encoding "petscii_mixed"
|
||||
// [9] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@4 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||
lda #'\n'
|
||||
ldy #0
|
||||
cmp (msg),y
|
||||
beq __b3
|
||||
jmp __b4
|
||||
// main::@4
|
||||
__b4:
|
||||
// [9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuz1=_deref_pbuz2_band_vbuc1
|
||||
beq __b4
|
||||
jmp __b5
|
||||
// main::@5
|
||||
__b5:
|
||||
// [10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuz1=_deref_pbuz2_band_vbuc1
|
||||
lda #$3f
|
||||
ldy #0
|
||||
and (msg),y
|
||||
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
|
||||
ldy #0
|
||||
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
|
||||
bne !+
|
||||
inc.z cursor+1
|
||||
!:
|
||||
// [12] phi from main::@3 main::@4 to main::@5 [phi:main::@3/main::@4->main::@5]
|
||||
__b5_from___b3:
|
||||
__b5_from___b4:
|
||||
// [12] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@3/main::@4->main::@5#0] -- register_copy
|
||||
// [12] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@3/main::@4->main::@5#1] -- register_copy
|
||||
jmp __b5
|
||||
// main::@5
|
||||
__b5:
|
||||
// [13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
||||
// [13] phi from main::@4 main::@5 to main::@6 [phi:main::@4/main::@5->main::@6]
|
||||
__b6_from___b4:
|
||||
__b6_from___b5:
|
||||
// [13] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@4/main::@5->main::@6#0] -- register_copy
|
||||
// [13] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@4/main::@5->main::@6#1] -- register_copy
|
||||
jmp __b6
|
||||
// main::@6
|
||||
__b6:
|
||||
// [14] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
||||
inc.z msg
|
||||
bne !+
|
||||
inc.z msg+1
|
||||
!:
|
||||
// [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
|
||||
__b1_from___b5:
|
||||
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@5->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::msg#2 = (byte*) main::msg#1 [phi:main::@5->main::@1#2] -- register_copy
|
||||
// [5] phi from main::@6 to main::@1 [phi:main::@6->main::@1]
|
||||
__b1_from___b6:
|
||||
// [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::@6->main::@1#1] -- register_copy
|
||||
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@6->main::@1#2] -- register_copy
|
||||
jmp __b1
|
||||
// main::@3
|
||||
__b3:
|
||||
// [14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
||||
// main::@4
|
||||
__b4:
|
||||
// [15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
||||
lda #$28
|
||||
clc
|
||||
adc.z line
|
||||
@ -353,12 +374,12 @@ main: {
|
||||
lda #0
|
||||
adc.z line+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
|
||||
sta.z line
|
||||
lda.z cursor+1
|
||||
sta.z line+1
|
||||
jmp __b5_from___b3
|
||||
jmp __b6_from___b4
|
||||
}
|
||||
// File Data
|
||||
MESSAGE: .text @"hello\nworld"
|
||||
@ -366,12 +387,13 @@ main: {
|
||||
|
||||
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 [8] if(*((byte*) main::msg#2)==(byte) '
|
||||
'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] (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 [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 [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 [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 [7] *((const byte*) SCREEN+(byte) $50) ← (const byte) CH [ ] ( main:2 [ ] { } ) always clobbers reg byte a
|
||||
Statement [9] if(*((byte*) main::msg#2)==(byte) '
|
||||
'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::$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 [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::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]: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 ,
|
||||
@ -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 []
|
||||
|
||||
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 [] best 1463 combination
|
||||
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 1472 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -393,6 +415,9 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.encoding "petscii_mixed"
|
||||
.const CH = '\n'
|
||||
.label SCREEN = $400
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
@ -439,56 +464,61 @@ main: {
|
||||
lda (msg),y
|
||||
cmp #0
|
||||
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
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [7] return
|
||||
// [8] return
|
||||
rts
|
||||
// main::@2
|
||||
__b2:
|
||||
// [8] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@3 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||
.encoding "petscii_mixed"
|
||||
// [9] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@4 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||
lda #'\n'
|
||||
ldy #0
|
||||
cmp (msg),y
|
||||
beq __b3
|
||||
jmp __b4
|
||||
// main::@4
|
||||
__b4:
|
||||
// [9] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuaa=_deref_pbuz1_band_vbuc1
|
||||
beq __b4
|
||||
jmp __b5
|
||||
// main::@5
|
||||
__b5:
|
||||
// [10] (byte~) main::$0 ← *((byte*) main::msg#2) & (byte) $3f -- vbuaa=_deref_pbuz1_band_vbuc1
|
||||
lda #$3f
|
||||
ldy #0
|
||||
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
|
||||
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
|
||||
bne !+
|
||||
inc.z cursor+1
|
||||
!:
|
||||
// [12] phi from main::@3 main::@4 to main::@5 [phi:main::@3/main::@4->main::@5]
|
||||
__b5_from___b3:
|
||||
__b5_from___b4:
|
||||
// [12] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@3/main::@4->main::@5#0] -- register_copy
|
||||
// [12] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@3/main::@4->main::@5#1] -- register_copy
|
||||
jmp __b5
|
||||
// main::@5
|
||||
__b5:
|
||||
// [13] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
||||
// [13] phi from main::@4 main::@5 to main::@6 [phi:main::@4/main::@5->main::@6]
|
||||
__b6_from___b4:
|
||||
__b6_from___b5:
|
||||
// [13] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@4/main::@5->main::@6#0] -- register_copy
|
||||
// [13] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@4/main::@5->main::@6#1] -- register_copy
|
||||
jmp __b6
|
||||
// main::@6
|
||||
__b6:
|
||||
// [14] (byte*) main::msg#1 ← ++ (byte*) main::msg#2 -- pbuz1=_inc_pbuz1
|
||||
inc.z msg
|
||||
bne !+
|
||||
inc.z msg+1
|
||||
!:
|
||||
// [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
|
||||
__b1_from___b5:
|
||||
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@5->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::msg#2 = (byte*) main::msg#1 [phi:main::@5->main::@1#2] -- register_copy
|
||||
// [5] phi from main::@6 to main::@1 [phi:main::@6->main::@1]
|
||||
__b1_from___b6:
|
||||
// [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::@6->main::@1#1] -- register_copy
|
||||
// [5] phi (byte*) main::msg#2 = (byte*) main::msg#1 [phi:main::@6->main::@1#2] -- register_copy
|
||||
jmp __b1
|
||||
// main::@3
|
||||
__b3:
|
||||
// [14] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
||||
// main::@4
|
||||
__b4:
|
||||
// [15] (byte*) main::cursor#1 ← (byte*) main::line#2 + (byte) $28 -- pbuz1=pbuz2_plus_vbuc1
|
||||
lda #$28
|
||||
clc
|
||||
adc.z line
|
||||
@ -496,12 +526,12 @@ main: {
|
||||
lda #0
|
||||
adc.z line+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
|
||||
sta.z line
|
||||
lda.z cursor+1
|
||||
sta.z line+1
|
||||
jmp __b5_from___b3
|
||||
jmp __b6_from___b4
|
||||
}
|
||||
// File Data
|
||||
MESSAGE: .text @"hello\nworld"
|
||||
@ -511,25 +541,27 @@ ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __bend
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __b3
|
||||
Removing instruction jmp __breturn
|
||||
Removing instruction jmp __b4
|
||||
Removing instruction jmp __b5
|
||||
Removing instruction jmp __b6
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction ldy #0
|
||||
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:
|
||||
Removing instruction main_from___b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Removing instruction __b5_from___b3:
|
||||
Removing instruction __b5_from___b4:
|
||||
Removing instruction __b6_from___b4:
|
||||
Removing instruction __b6_from___b5:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __bend:
|
||||
Removing instruction __b1_from_main:
|
||||
Removing instruction __b3:
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __b4:
|
||||
Removing instruction __b1_from___b5:
|
||||
Removing instruction __b5:
|
||||
Removing instruction __b1_from___b6:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
@ -543,8 +575,11 @@ FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) CH = (byte) '
|
||||
'pm
|
||||
(const byte*) MESSAGE[] = (byte*) "hello
|
||||
world"pm
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 202.0
|
||||
(label) main::@1
|
||||
@ -552,6 +587,7 @@ world"pm
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@return
|
||||
(byte*) main::cursor
|
||||
(byte*) main::cursor#1 cursor zp[2]:6 151.5
|
||||
@ -573,7 +609,7 @@ reg byte a [ main::$0 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 1291
|
||||
Score: 1297
|
||||
|
||||
// File Comments
|
||||
// Test using some simple supported string escape \n in both string and char
|
||||
@ -583,6 +619,9 @@ Score: 1291
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.encoding "petscii_mixed"
|
||||
.const CH = '\n'
|
||||
.label SCREEN = $400
|
||||
// @begin
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
// @1
|
||||
@ -619,9 +658,14 @@ main: {
|
||||
lda (msg),y
|
||||
cmp #0
|
||||
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
|
||||
// }
|
||||
// [7] return
|
||||
// [8] return
|
||||
rts
|
||||
// main::@2
|
||||
__b2:
|
||||
@ -629,46 +673,45 @@ main: {
|
||||
// line += 0x28;
|
||||
// cursor = line;
|
||||
// break;
|
||||
// [8] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@3 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||
.encoding "petscii_mixed"
|
||||
// [9] if(*((byte*) main::msg#2)==(byte) ' 'pm) goto main::@4 -- _deref_pbuz1_eq_vbuc1_then_la1
|
||||
lda #'\n'
|
||||
ldy #0
|
||||
cmp (msg),y
|
||||
beq __b3
|
||||
// main::@4
|
||||
beq __b4
|
||||
// main::@5
|
||||
// *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
|
||||
and (msg),y
|
||||
// *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
|
||||
// *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
|
||||
bne !+
|
||||
inc.z cursor+1
|
||||
!:
|
||||
// [12] phi from main::@3 main::@4 to main::@5 [phi:main::@3/main::@4->main::@5]
|
||||
// [12] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@3/main::@4->main::@5#0] -- register_copy
|
||||
// [12] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@3/main::@4->main::@5#1] -- register_copy
|
||||
// main::@5
|
||||
__b5:
|
||||
// [13] phi from main::@4 main::@5 to main::@6 [phi:main::@4/main::@5->main::@6]
|
||||
// [13] phi (byte*) main::cursor#6 = (byte*) main::cursor#1 [phi:main::@4/main::@5->main::@6#0] -- register_copy
|
||||
// [13] phi (byte*) main::line#5 = (byte*) main::line#8 [phi:main::@4/main::@5->main::@6#1] -- register_copy
|
||||
// main::@6
|
||||
__b6:
|
||||
// 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
|
||||
bne !+
|
||||
inc.z msg+1
|
||||
!:
|
||||
// [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
|
||||
// [5] phi (byte*) main::cursor#3 = (byte*) main::cursor#6 [phi:main::@5->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::msg#2 = (byte*) main::msg#1 [phi:main::@5->main::@1#2] -- register_copy
|
||||
// [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::@6->main::@1#0] -- 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::@6->main::@1#2] -- register_copy
|
||||
jmp __b1
|
||||
// main::@3
|
||||
__b3:
|
||||
// main::@4
|
||||
__b4:
|
||||
// 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
|
||||
clc
|
||||
adc.z line
|
||||
@ -676,12 +719,12 @@ main: {
|
||||
lda #0
|
||||
adc.z line+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
|
||||
sta.z line
|
||||
lda.z cursor+1
|
||||
sta.z line+1
|
||||
jmp __b5
|
||||
jmp __b6
|
||||
}
|
||||
// File Data
|
||||
MESSAGE: .text @"hello\nworld"
|
||||
|
@ -1,8 +1,11 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) CH = (byte) '
|
||||
'pm
|
||||
(const byte*) MESSAGE[] = (byte*) "hello
|
||||
world"pm
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 202.0
|
||||
(label) main::@1
|
||||
@ -10,6 +13,7 @@ world"pm
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@return
|
||||
(byte*) main::cursor
|
||||
(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