mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 05:29:38 +00:00
tweaked repeat
This commit is contained in:
parent
9f047ba752
commit
dd2c436dc6
@ -966,12 +966,10 @@ internal class AsmGen(private val program: Program,
|
||||
val name = asmVariableName(stmt.iterations as IdentifierReference)
|
||||
when(vardecl.datatype) {
|
||||
DataType.UBYTE, DataType.BYTE -> {
|
||||
out(" lda $name")
|
||||
repeatByteCountInA(null, repeatLabel, endLabel, stmt.body)
|
||||
repeatByteCountVar(name, repeatLabel, endLabel, stmt.body)
|
||||
}
|
||||
DataType.UWORD, DataType.WORD -> {
|
||||
out(" lda $name | ldy $name+1")
|
||||
repeatWordCountInAY(null, repeatLabel, endLabel, stmt.body)
|
||||
repeatWordCountVar(name, repeatLabel, endLabel, stmt.body)
|
||||
}
|
||||
else -> throw AssemblyError("invalid loop variable datatype $vardecl")
|
||||
}
|
||||
@ -1001,6 +999,7 @@ internal class AsmGen(private val program: Program,
|
||||
if(constIterations==0)
|
||||
return
|
||||
// note: A/Y must have been loaded with the number of iterations already!
|
||||
// TODO can be even more optimized by iterating over pages
|
||||
val counterVar = makeLabel("repeatcounter")
|
||||
out("""
|
||||
sta $counterVar
|
||||
@ -1035,22 +1034,54 @@ $counterVar .word 0""")
|
||||
val counterVar = makeLabel("repeatcounter")
|
||||
if(constIterations==null)
|
||||
out(" beq $endLabel")
|
||||
out("""
|
||||
sta $counterVar
|
||||
$repeatLabel""")
|
||||
out(" sta $counterVar")
|
||||
out(repeatLabel)
|
||||
translate(body)
|
||||
out("""
|
||||
dec $counterVar
|
||||
bne $repeatLabel
|
||||
beq $endLabel""")
|
||||
if(constIterations!=null && constIterations>=16 && zeropage.available() > 0) {
|
||||
// allocate count var on ZP
|
||||
val zpAddr = zeropage.allocate(counterVar, DataType.UBYTE, body.position, errors)
|
||||
out("""$counterVar = $zpAddr ; auto zp UBYTE""")
|
||||
} else {
|
||||
out("""
|
||||
beq $endLabel
|
||||
$counterVar .byte 0""")
|
||||
}
|
||||
out(endLabel)
|
||||
}
|
||||
|
||||
private fun repeatByteCountVar(repeatCountVar: String, repeatLabel: String, endLabel: String, body: AnonymousScope) {
|
||||
// note: cannot use original counter variable because it should retain its original value
|
||||
val counterVar = makeLabel("repeatcounter")
|
||||
out(" lda $repeatCountVar | beq $endLabel | sta $counterVar")
|
||||
out(repeatLabel)
|
||||
translate(body)
|
||||
out(" dec $counterVar | bne $repeatLabel")
|
||||
// inline countervar:
|
||||
out("""
|
||||
beq $endLabel
|
||||
$counterVar .byte 0""")
|
||||
out(endLabel)
|
||||
}
|
||||
|
||||
private fun repeatWordCountVar(repeatCountVar: String, repeatLabel: String, endLabel: String, body: AnonymousScope) {
|
||||
// TODO can be even more optimized by iterating over pages
|
||||
// note: cannot use original counter variable because it should retain its original value
|
||||
val counterVar = makeLabel("repeatcounter")
|
||||
out("""
|
||||
lda $repeatCountVar
|
||||
sta $counterVar
|
||||
ora $repeatCountVar+1
|
||||
beq $endLabel
|
||||
lda $repeatCountVar+1
|
||||
sta $counterVar+1""")
|
||||
out(repeatLabel)
|
||||
translate(body)
|
||||
out("""
|
||||
lda $counterVar
|
||||
bne +
|
||||
dec $counterVar+1
|
||||
+ dec $counterVar
|
||||
lda $counterVar
|
||||
ora $counterVar+1
|
||||
bne $repeatLabel
|
||||
beq $endLabel
|
||||
$counterVar .word 0""")
|
||||
out(endLabel)
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,13 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- add any2(), all2(), max2(), min2(), reverse2(), sum2(), sort2() that take (array, startindex, length) arguments
|
||||
- optimize for loop iterations better to allow proper inx, cpx #value, bne loop instructions (like repeat loop)
|
||||
- why is there a beq _prog8_label_2_repeatend at the end of repeat loops? seems unused
|
||||
- optimize swap of two memread values with index, using the same pointer expression/variable, like swap(@(ptr+1), @(ptr+2))
|
||||
- implement the linked_list millfork benchmark
|
||||
- use the 65c02 bit clear/set/test instructions for single-bit operations
|
||||
|
||||
- implement highres 4 color mode in gfx2
|
||||
- make a retro Amiga Workbench "simulator" using that new gfx mode
|
||||
- use the 65c02 bit clear/set/test instructions for single-bit operations
|
||||
- add a flood fill routine to gfx2
|
||||
- can we get rid of the --longOptionName command line options and only keep the short versions? https://github.com/Kotlin/kotlinx-cli/issues/50
|
||||
- add a f_seek() routine for the Cx16 that uses its seek dos api?
|
||||
|
@ -5,6 +5,12 @@ main {
|
||||
|
||||
|
||||
sub start() {
|
||||
txt.print("hello\n")
|
||||
uword xx
|
||||
uword iter = 256
|
||||
repeat iter {
|
||||
xx++
|
||||
}
|
||||
|
||||
txt.print_uw(xx)
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<option name="HAS_PARENS" value="true" />
|
||||
<option name="HAS_STRING_ESCAPES" value="true" />
|
||||
</options>
|
||||
<keywords keywords="&;->;@;\$;and;as;asmsub;break;clobbers;continue;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;until;when;while;xor;~" ignore_case="false" />
|
||||
<keywords keywords="&;->;@;\$;and;as;asmsub;break;clobbers;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;until;when;while;xor;~" ignore_case="false" />
|
||||
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%launcher;%option;%output;%target;%zeropage;%zpreserved" />
|
||||
<keywords3 keywords="byte;const;float;str;struct;ubyte;uword;void;word;zp" />
|
||||
<keywords4 keywords="abs;acos;all;any;asin;atan;avg;ceil;cos;cos16;cos16u;cos8;cos8u;deg;floor;len;ln;log2;lsb;lsl;lsr;max;memory;min;mkword;msb;offsetof;rad;reverse;rnd;rndf;rndw;rol;rol2;ror;ror2;round;sgn;sin;sin16;sin16u;sin8;sin8u;sizeof;sort;sqrt;sqrt16;sum;swap;tan" />
|
||||
|
Loading…
Reference in New Issue
Block a user