mirror of
https://github.com/irmen/prog8.git
synced 2025-11-26 04:17:47 +00:00
Compare commits
7 Commits
v12.0-BETA
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b86f97aaa | ||
|
|
93135774e6 | ||
|
|
a64f27c6b0 | ||
|
|
69ef63c96d | ||
|
|
df1a2a1611 | ||
|
|
d19a3af9ed | ||
|
|
352c11ad9f |
@@ -544,7 +544,7 @@ private fun optimizeJsrRtsAndOtherCombinations(linesByFour: Sequence<List<Indexe
|
|||||||
val third = lines[2].value
|
val third = lines[2].value
|
||||||
|
|
||||||
if(!haslabel(second)) {
|
if(!haslabel(second)) {
|
||||||
if ((" jmp" in first || "\tjmp" in first ) && (" rts" in second || "\trts" in second)) {
|
if ((" jmp" in first || "\tjmp" in first || " bra" in first || "\tbra" in first ) && (" rts" in second || "\trts" in second)) {
|
||||||
mods += Modification(lines[1].index, true, null)
|
mods += Modification(lines[1].index, true, null)
|
||||||
}
|
}
|
||||||
else if ((" jsr" in first || "\tjsr" in first ) && (" rts" in second || "\trts" in second)) {
|
else if ((" jsr" in first || "\tjsr" in first ) && (" rts" in second || "\trts" in second)) {
|
||||||
|
|||||||
@@ -305,13 +305,13 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
|||||||
"<<" -> {
|
"<<" -> {
|
||||||
if(target.dt.isByte) inplaceByteShiftLeft(target, value)
|
if(target.dt.isByte) inplaceByteShiftLeft(target, value)
|
||||||
else if(target.dt.isWord) inplaceWordShiftLeft(target, value)
|
else if(target.dt.isWord) inplaceWordShiftLeft(target, value)
|
||||||
else if(target.dt.isLong) TODO("inplace long << ${target.position}")
|
else if(target.dt.isLong) inplaceLongShiftLeft(target, value)
|
||||||
else throw AssemblyError("weird dt ${target.position}")
|
else throw AssemblyError("weird dt ${target.position}")
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if(target.dt.isByte) inplaceByteShiftRight(target, value)
|
if(target.dt.isByte) inplaceByteShiftRight(target, value)
|
||||||
else if(target.dt.isWord) inplaceWordShiftRight(target, value)
|
else if(target.dt.isWord) inplaceWordShiftRight(target, value)
|
||||||
else if(target.dt.isLong) TODO("inplace long >> ${target.position}")
|
else if(target.dt.isLong) inplaceLongShiftRight(target, value)
|
||||||
else throw AssemblyError("weird dt ${target.position}")
|
else throw AssemblyError("weird dt ${target.position}")
|
||||||
}
|
}
|
||||||
"&", "and" -> {
|
"&", "and" -> {
|
||||||
@@ -756,11 +756,129 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
|||||||
asmgen.assignRegister(RegisterOrPair.AY, target)
|
asmgen.assignRegister(RegisterOrPair.AY, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun inplaceLongShiftRight(target: PtrTarget, value: AsmAssignSource) {
|
||||||
|
val (zpPtrVar, offset) = deref(target.pointer)
|
||||||
|
|
||||||
|
fun shift1signed() {
|
||||||
|
asmgen.out("""
|
||||||
|
ldy #${offset}+3
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
asl a ; save sign bit
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
ror a
|
||||||
|
sta ($zpPtrVar),y
|
||||||
|
dey
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
ror a
|
||||||
|
sta ($zpPtrVar),y
|
||||||
|
dey
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
ror a
|
||||||
|
sta ($zpPtrVar),y
|
||||||
|
dey
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
ror a
|
||||||
|
sta ($zpPtrVar),y""")
|
||||||
|
}
|
||||||
|
|
||||||
|
when(value.kind) {
|
||||||
|
SourceStorageKind.LITERALNUMBER -> {
|
||||||
|
val number = value.number!!.number.toInt()
|
||||||
|
if(number==1) {
|
||||||
|
shift1signed()
|
||||||
|
} else if(number>1) {
|
||||||
|
asmgen.out(" ldx #$number")
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceStorageKind.VARIABLE -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
val varname = value.asmVarname
|
||||||
|
asmgen.out(" ldx $varname")
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
SourceStorageKind.EXPRESSION -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.X)
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
SourceStorageKind.REGISTER -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
val register = value.register!!
|
||||||
|
asmgen.assignRegister(register, AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE, null, target.position, register = RegisterOrPair.X))
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird source value $value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun inplaceWordShiftRight(target: PtrTarget, value: AsmAssignSource) {
|
private fun inplaceWordShiftRight(target: PtrTarget, value: AsmAssignSource) {
|
||||||
val (zpPtrVar, offset) = deref(target.pointer)
|
val (zpPtrVar, offset) = deref(target.pointer)
|
||||||
|
|
||||||
if(target.dt.isSigned)
|
if(target.dt.isSigned) {
|
||||||
TODO("signed word shift right ${target.position} $value")
|
// signed word shift right
|
||||||
|
fun shift1signed() {
|
||||||
|
asmgen.out("""
|
||||||
|
ldy #${offset+1u}
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
asl a ; save sign bit
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
ror a
|
||||||
|
sta ($zpPtrVar),y
|
||||||
|
dey
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
ror a
|
||||||
|
sta ($zpPtrVar),y""")
|
||||||
|
}
|
||||||
|
|
||||||
|
when(value.kind) {
|
||||||
|
SourceStorageKind.LITERALNUMBER -> {
|
||||||
|
val number = value.number!!.number.toInt()
|
||||||
|
if(number==1) {
|
||||||
|
shift1signed()
|
||||||
|
} else if(number>1) {
|
||||||
|
asmgen.out(" ldx #$number")
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceStorageKind.VARIABLE -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
val varname = value.asmVarname
|
||||||
|
asmgen.out(" ldx $varname")
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
SourceStorageKind.EXPRESSION -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.X)
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
SourceStorageKind.REGISTER -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
val register = value.register!!
|
||||||
|
asmgen.assignRegister(register, AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE, null, target.position, register = RegisterOrPair.X))
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1signed()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird source value $value")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// unsigned word shift right
|
||||||
|
|
||||||
fun shift1unsigned() {
|
fun shift1unsigned() {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@@ -812,6 +930,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
|||||||
else -> throw AssemblyError("weird source value $value")
|
else -> throw AssemblyError("weird source value $value")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun inplaceByteShiftRight(target: PtrTarget, value: AsmAssignSource) {
|
private fun inplaceByteShiftRight(target: PtrTarget, value: AsmAssignSource) {
|
||||||
val (zpPtrVar, offset) = deref(target.pointer)
|
val (zpPtrVar, offset) = deref(target.pointer)
|
||||||
@@ -878,6 +997,68 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun inplaceLongShiftLeft(target: PtrTarget, value: AsmAssignSource) {
|
||||||
|
val (zpPtrVar, offset) = deref(target.pointer)
|
||||||
|
|
||||||
|
fun shift1() {
|
||||||
|
asmgen.out("""
|
||||||
|
ldy #$offset
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
asl a
|
||||||
|
sta ($zpPtrVar),y
|
||||||
|
iny
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
rol a
|
||||||
|
sta ($zpPtrVar),y
|
||||||
|
iny
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
rol a
|
||||||
|
sta ($zpPtrVar),y
|
||||||
|
iny
|
||||||
|
lda ($zpPtrVar),y
|
||||||
|
rol a
|
||||||
|
sta ($zpPtrVar),y""")
|
||||||
|
}
|
||||||
|
|
||||||
|
when(value.kind) {
|
||||||
|
SourceStorageKind.LITERALNUMBER -> {
|
||||||
|
val number = value.number!!.number.toInt()
|
||||||
|
if(number==1) {
|
||||||
|
shift1()
|
||||||
|
} else if(number>1) {
|
||||||
|
asmgen.out(" ldx #$number")
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceStorageKind.VARIABLE -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
val varname = value.asmVarname
|
||||||
|
asmgen.out(" ldx $varname")
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
SourceStorageKind.EXPRESSION -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.X)
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
SourceStorageKind.REGISTER -> {
|
||||||
|
require(value.datatype.isByte)
|
||||||
|
val register = value.register!!
|
||||||
|
asmgen.assignRegister(register, AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE, null, target.position, register = RegisterOrPair.X))
|
||||||
|
asmgen.out("-")
|
||||||
|
shift1()
|
||||||
|
asmgen.out(" dex | bne -")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird source value $value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun inplaceWordShiftLeft(target: PtrTarget, value: AsmAssignSource) {
|
private fun inplaceWordShiftLeft(target: PtrTarget, value: AsmAssignSource) {
|
||||||
val (zpPtrVar, offset) = deref(target.pointer)
|
val (zpPtrVar, offset) = deref(target.pointer)
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,10 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
"&=" -> addInstr(inplaceInstrs, IRInstruction(Opcode.ANDR, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
"&=" -> addInstr(inplaceInstrs, IRInstruction(Opcode.ANDR, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
||||||
"^=", "xor=" -> addInstr(inplaceInstrs, IRInstruction(Opcode.XORR, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
"^=", "xor=" -> addInstr(inplaceInstrs, IRInstruction(Opcode.XORR, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
||||||
"<<=" -> addInstr(inplaceInstrs, IRInstruction(Opcode.LSLN, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
"<<=" -> addInstr(inplaceInstrs, IRInstruction(Opcode.LSLN, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
||||||
">>=" -> addInstr(inplaceInstrs, IRInstruction(Opcode.LSRN, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
">>=" -> {
|
||||||
|
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
|
||||||
|
addInstr(inplaceInstrs, IRInstruction(opc, targetDt, reg1 = oldvalueReg, reg2 = operandTr.resultReg), null)
|
||||||
|
}
|
||||||
"or=" -> {
|
"or=" -> {
|
||||||
val shortcutLabel = codeGen.createLabelName()
|
val shortcutLabel = codeGen.createLabelName()
|
||||||
addInstr(inplaceInstrs, IRInstruction(Opcode.BSTNE, labelSymbol = shortcutLabel), null)
|
addInstr(inplaceInstrs, IRInstruction(Opcode.BSTNE, labelSymbol = shortcutLabel), null)
|
||||||
|
|||||||
@@ -1140,6 +1140,16 @@ cx16 {
|
|||||||
&word r14s = $1bfc
|
&word r14s = $1bfc
|
||||||
&word r15s = $1bfe
|
&word r15s = $1bfe
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $1be0
|
||||||
|
&long r2r3sl = $1be4
|
||||||
|
&long r4r5sl = $1be8
|
||||||
|
&long r6r7sl = $1bec
|
||||||
|
&long r8r0sl = $1bf0
|
||||||
|
&long r10r11sl = $1bf4
|
||||||
|
&long r12r13sl = $1bf8
|
||||||
|
&long r14r15sl = $1bfc
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $1be0
|
&ubyte r0L = $1be0
|
||||||
&ubyte r1L = $1be2
|
&ubyte r1L = $1be2
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
FL_ONE_const .byte 129 ; 1.0
|
FL_ONE_const .byte 129 ; 1.0
|
||||||
FL_ZERO_const .byte 0,0,0,0,0 ; 0.0
|
FL_ZERO_const .byte 0,0,0,0,0 ; 0.0
|
||||||
FL_LOG2_const .byte $80, $31, $72, $17, $f8 ; log(2)
|
; note: don't add too many constants here because they all end up in the resulting program
|
||||||
FL_65536_const .byte $91, $00, $00, $00, $00 ; 65536.0
|
|
||||||
|
|
||||||
|
|
||||||
.section BSS
|
.section BSS
|
||||||
@@ -159,6 +158,9 @@ cast_from_long .proc
|
|||||||
ldx cx16.r0L
|
ldx cx16.r0L
|
||||||
ldy cx16.r0H
|
ldy cx16.r0H
|
||||||
jmp MOVMF
|
jmp MOVMF
|
||||||
|
|
||||||
|
FL_65536_const .byte $91, $00, $00, $00, $00 ; 65536.0
|
||||||
|
; !notreached!
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
cast_as_long .proc
|
cast_as_long .proc
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
|
|
||||||
func_sign_f_into_A .proc
|
func_sign_f_into_A .proc
|
||||||
|
; sign in A, also sets status flags
|
||||||
jsr MOVFM
|
jsr MOVFM
|
||||||
jmp SIGN
|
jsr SIGN
|
||||||
|
cmp #0
|
||||||
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1150,6 +1150,16 @@ cx16 {
|
|||||||
&word r14s = $cffc
|
&word r14s = $cffc
|
||||||
&word r15s = $cffe
|
&word r15s = $cffe
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $cfe0
|
||||||
|
&long r2r3sl = $cfe4
|
||||||
|
&long r4r5sl = $cfe8
|
||||||
|
&long r6r7sl = $cfec
|
||||||
|
&long r8r0sl = $cff0
|
||||||
|
&long r10r11sl = $cff4
|
||||||
|
&long r12r13sl = $cff8
|
||||||
|
&long r14r15sl = $cffc
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $cfe0
|
&ubyte r0L = $cfe0
|
||||||
&ubyte r1L = $cfe2
|
&ubyte r1L = $cfe2
|
||||||
|
|||||||
@@ -217,6 +217,16 @@ cx16 {
|
|||||||
&word r14s = $001e
|
&word r14s = $001e
|
||||||
&word r15s = $0020
|
&word r15s = $0020
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $0002
|
||||||
|
&long r2r3sl = $0006
|
||||||
|
&long r4r5sl = $000a
|
||||||
|
&long r6r7sl = $000e
|
||||||
|
&long r8r0sl = $0012
|
||||||
|
&long r10r11sl = $0016
|
||||||
|
&long r12r13sl = $001a
|
||||||
|
&long r14r15sl = $001e
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $0002
|
&ubyte r0L = $0002
|
||||||
&ubyte r1L = $0004
|
&ubyte r1L = $0004
|
||||||
|
|||||||
@@ -605,6 +605,16 @@ cx16 {
|
|||||||
&word r14s = $7ffc
|
&word r14s = $7ffc
|
||||||
&word r15s = $7ffe
|
&word r15s = $7ffe
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $7fe0
|
||||||
|
&long r2r3sl = $7fe4
|
||||||
|
&long r4r5sl = $7fe8
|
||||||
|
&long r6r7sl = $7fec
|
||||||
|
&long r8r0sl = $7fe0
|
||||||
|
&long r10r11sl = $7fe4
|
||||||
|
&long r12r13sl = $7fe8
|
||||||
|
&long r14r15sl = $7fec
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $7fe0
|
&ubyte r0L = $7fe0
|
||||||
&ubyte r1L = $7fe2
|
&ubyte r1L = $7fe2
|
||||||
|
|||||||
@@ -160,6 +160,9 @@ sub log2(float value) -> float {
|
|||||||
ldy #>FL_LOG2_const
|
ldy #>FL_LOG2_const
|
||||||
jsr MOVFM
|
jsr MOVFM
|
||||||
jmp FDIVT
|
jmp FDIVT
|
||||||
|
|
||||||
|
FL_LOG2_const .byte $80, $31, $72, $17, $f8 ; log(2)
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -307,6 +307,16 @@ cx16 {
|
|||||||
&word r14s = $ff1e
|
&word r14s = $ff1e
|
||||||
&word r15s = $ff20
|
&word r15s = $ff20
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $ff02
|
||||||
|
&long r2r3sl = $ff06
|
||||||
|
&long r4r5sl = $ff0a
|
||||||
|
&long r6r7sl = $ff0e
|
||||||
|
&long r8r0sl = $ff12
|
||||||
|
&long r10r11sl = $ff16
|
||||||
|
&long r12r13sl = $ff1a
|
||||||
|
&long r14r15sl = $ff1e
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $ff02
|
&ubyte r0L = $ff02
|
||||||
&ubyte r1L = $ff04
|
&ubyte r1L = $ff04
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ class TestCompilerOnCharLit: FunSpec({
|
|||||||
|
|
||||||
test("testCharLitAsExtsubArg") {
|
test("testCharLitAsExtsubArg") {
|
||||||
val platform = Cx16Target()
|
val platform = Cx16Target()
|
||||||
val result = compileText(platform, false, """
|
val result = compileText(platform, false, $$"""
|
||||||
main {
|
main {
|
||||||
extsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
extsub $FFD2 = chrout(ubyte ch @ A)
|
||||||
sub start() {
|
sub start() {
|
||||||
chrout('\n')
|
chrout('\n')
|
||||||
}
|
}
|
||||||
@@ -61,9 +61,9 @@ class TestCompilerOnCharLit: FunSpec({
|
|||||||
|
|
||||||
test("testCharVarAsExtsubArg") {
|
test("testCharVarAsExtsubArg") {
|
||||||
val platform = Cx16Target()
|
val platform = Cx16Target()
|
||||||
val result = compileText(platform, false, """
|
val result = compileText(platform, false, $$"""
|
||||||
main {
|
main {
|
||||||
extsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
extsub $FFD2 = chrout(ubyte ch @ A)
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte ch = '\n'
|
ubyte ch = '\n'
|
||||||
chrout(ch)
|
chrout(ch)
|
||||||
@@ -96,9 +96,9 @@ class TestCompilerOnCharLit: FunSpec({
|
|||||||
|
|
||||||
test("testCharConstAsExtsubArg") {
|
test("testCharConstAsExtsubArg") {
|
||||||
val platform = Cx16Target()
|
val platform = Cx16Target()
|
||||||
val result = compileText(platform, false, """
|
val result = compileText(platform, false, $$"""
|
||||||
main {
|
main {
|
||||||
extsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
extsub $FFD2 = chrout(ubyte ch @ A)
|
||||||
sub start() {
|
sub start() {
|
||||||
const ubyte ch = '\n'
|
const ubyte ch = '\n'
|
||||||
chrout(ch)
|
chrout(ch)
|
||||||
|
|||||||
@@ -1030,9 +1030,9 @@ class Subroutine(override val name: String,
|
|||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
is NumericLiteral -> {
|
is NumericLiteral -> {
|
||||||
if(node===asmAddress?.address) {
|
if(node===asmAddress?.address || node==asmAddress?.address) {
|
||||||
asmAddress.address = replacement
|
asmAddress.address = replacement
|
||||||
} else if(node===asmAddress?.varbank) {
|
} else if(node==asmAddress?.varbank) {
|
||||||
asmAddress.constbank = replacement.number.toInt().toUByte()
|
asmAddress.constbank = replacement.number.toInt().toUByte()
|
||||||
asmAddress.varbank = null
|
asmAddress.varbank = null
|
||||||
} else throw FatalAstException("can't replace")
|
} else throw FatalAstException("can't replace")
|
||||||
|
|||||||
@@ -1155,6 +1155,7 @@ so pay attention to any jumps and rts instructions in the inlined code!
|
|||||||
|
|
||||||
- ``cx16.r0`` - ``cx16.r15`` (memory-mapped **uword** values, most often these are used)
|
- ``cx16.r0`` - ``cx16.r15`` (memory-mapped **uword** values, most often these are used)
|
||||||
- ``cx16.r0s`` - ``cx16.r15s`` (memory-mapped **word** values, used when you need a signed word)
|
- ``cx16.r0s`` - ``cx16.r15s`` (memory-mapped **word** values, used when you need a signed word)
|
||||||
|
- ``cx16.r0r1sl`` - ``cx16.r14r15sl`` (memory-mapped **long** values in 2 consecutive virtual registers, used when you need a signed long)
|
||||||
- ``cx16.r0H``, ``cx16.r0L`` (for each r0..r15; memory-mapped **ubyte** values, both bytes of the register)
|
- ``cx16.r0H``, ``cx16.r0L`` (for each r0..r15; memory-mapped **ubyte** values, both bytes of the register)
|
||||||
- ``cx16.r0sH``, ``cx16.r0sL`` (for each r0..r15; memory-mapped **byte** values, both bytes of the register)
|
- ``cx16.r0sH``, ``cx16.r0sL`` (for each r0..r15; memory-mapped **byte** values, both bytes of the register)
|
||||||
- ``cx16.r0bH``, ``cx16.r0bL`` (for each r0..r15; memory-mapped **bool** values, both bytes of the register)
|
- ``cx16.r0bH``, ``cx16.r0bL`` (for each r0..r15; memory-mapped **bool** values, both bytes of the register)
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- before final release: test all examples and programs again with final version of the compiler!
|
|
||||||
|
Weird Heisenbug
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
- examples/cube3d-float crashes with div by zero error on C64 (works on cx16. ALready broken in v11, v10 still worked)
|
||||||
|
caused by the RTS after JMP removal in optimizeJsrRtsAndOtherCombinations (replacing it with a NOP makes the problem disappear !??!?)
|
||||||
|
|
||||||
|
|
||||||
Future Things and Ideas
|
Future Things and Ideas
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- make $8000000 a valid long integer (-2147483648) this is more involved than you think. To make this work: long \|= $80000000
|
- make $8000000 a valid long integer (-2147483648) this is more involved than you think. To make this work: long \|= $80000000
|
||||||
- add cx16.r0r1sL, r2r3sL, ... etc to map signed longs on the virtual registers?
|
- implement rest of long comparisons in IfElseAsmGen compareLongValues(): expressions operands that might clobber the R14-R15 registers... (github issue 196?)
|
||||||
- implement rest of long comparisons in IfElseAsmGen compareLongValues(): expressions operands that might clobber the R14-R15 registers...
|
|
||||||
- struct/ptr: implement the remaining TODOs in PointerAssignmentsGen.
|
- struct/ptr: implement the remaining TODOs in PointerAssignmentsGen.
|
||||||
- struct/ptr: optimize deref in PointerAssignmentsGen: optimize 'forceTemporary' to only use a temporary when the offset is >0
|
- struct/ptr: optimize deref in PointerAssignmentsGen: optimize 'forceTemporary' to only use a temporary when the offset is >0
|
||||||
- struct/ptr: optimize the float copying in assignIndexedPointer() (also word and long?)
|
- struct/ptr: optimize the float copying in assignIndexedPointer() (also word and long?)
|
||||||
@@ -59,7 +62,6 @@ Future Things and Ideas
|
|||||||
|
|
||||||
IR/VM
|
IR/VM
|
||||||
-----
|
-----
|
||||||
- optimize bool b = sgn(value)<0: still does a compare with 0 even though SGN sets all status bits. What is the code when a BIT instruction is used?
|
|
||||||
- optimize float<0 float==0 float>0 to use SGN instruction? Check what code is generated for other data types.
|
- optimize float<0 float==0 float>0 to use SGN instruction? Check what code is generated for other data types.
|
||||||
- getting it in shape for code generation: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
- getting it in shape for code generation: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
||||||
- fix call() return value handling (... what's wrong with it again?)
|
- fix call() return value handling (... what's wrong with it again?)
|
||||||
@@ -115,20 +117,21 @@ Libraries
|
|||||||
Optimizations
|
Optimizations
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
- change float<0, float==0, float>0 to use sgn(float) instead? (also see IR)
|
- (6502) optimize if sgn(value)<0: still does a compare with 0 even though SGN sets all status bits.
|
||||||
|
- longvar = lptr^^ , lptr2^^=lptr^^ now go via temporary registers, optimize this to avoid using temps. (seems like it is dereferencing the pointer first and then assigning the intermediate value)
|
||||||
- optimize inplaceLongShiftRight() for byte aligned cases
|
- optimize inplaceLongShiftRight() for byte aligned cases
|
||||||
- more optimized operator handling of different types, for example uword a ^ byte b now does a type cast of b to word first
|
- more optimized operator handling of different types, for example uword a ^ byte b now does a type cast of b to word first
|
||||||
- optimize longEqualsValue() for const and variable operands to not assign needlessly to R0-R3.
|
- optimize longEqualsValue() for long const and variable operands to not assign needlessly to R0-R3.
|
||||||
- optimize optimizedBitwiseExpr() for const and variable operands to not assign needlessly to R0-R3.
|
- optimize optimizedBitwiseExpr() for long const and variable operands to not assign needlessly to R0-R3.
|
||||||
- optimize inplacemodificationLongWithLiteralval() for more shift values such as 8, 16, 24 etc but take sign bit into account!
|
- optimize inplacemodificationLongWithLiteralval() for more shift values such as 8, 16, 24 etc but take sign bit into account!
|
||||||
- optimize simple cases in funcPeekL and funcPokeL
|
- optimize simple cases in funcPeekL and funcPokeL
|
||||||
- bind types in the Ast much sooner than the simplifiedAst creation, so that we maybe could get rid of InferredType ?
|
- bind types in the Ast much sooner than the simplifiedAst creation, so that we maybe could get rid of InferredType ?
|
||||||
- longvar = lptr^^ now goes via temporary registers, optimize this to avoid using temps. Also check lptr^^ = lvar.
|
|
||||||
- Port more benchmarks from https://thred.github.io/c-bench-64/ to prog8 and see how it stacks up. (see benchmark-c/ directory)
|
- Port more benchmarks from https://thred.github.io/c-bench-64/ to prog8 and see how it stacks up. (see benchmark-c/ directory)
|
||||||
- Since fixing the missing zp-var initialization, programs grew in size again because STZ's reappeared. Can we add more intelligent (and correct!) optimizations to remove those STZs that might be redundant again?
|
- Since fixing the missing zp-var initialization, programs grew in size again because STZ's reappeared. Can we add more intelligent (and correct!) optimizations to remove those STZs that might be redundant again?
|
||||||
- in Identifier: use typedarray of strings instead of listOf? Other places?
|
- in Identifier: use typedarray of strings instead of listOf? Other places?
|
||||||
|
- Compilation speed regression: test/comparisons/test_word_lte.p8 compilation takes twice as long as with prog8 10.5
|
||||||
- Compilation speed: try to join multiple modifications in 1 result in the AST processors instead of returning it straight away every time
|
- Compilation speed: try to join multiple modifications in 1 result in the AST processors instead of returning it straight away every time
|
||||||
- Optimize the IfExpression code generation to be more like regular if-else code. (both 6502 and IR) search for "TODO don't store condition as expression"
|
- Optimize the IfExpression code generation to be more like regular if-else code. (both 6502 and IR) search for "TODO don't store condition as expression" ... but maybe postpone until codegen from IR, where it seems solved?
|
||||||
- optimize floats.cast_from_long and floats.cast_as_long by directly accessing FAC bits?
|
- optimize floats.cast_from_long and floats.cast_as_long by directly accessing FAC bits?
|
||||||
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served?
|
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served?
|
||||||
for instance, vars used inside loops first, then loopvars, then uwords used as pointers (or these first??), then the rest
|
for instance, vars used inside loops first, then loopvars, then uwords used as pointers (or these first??), then the rest
|
||||||
|
|||||||
@@ -482,6 +482,16 @@ cx16 {
|
|||||||
&word r14s = $1b1c
|
&word r14s = $1b1c
|
||||||
&word r15s = $1b1e
|
&word r15s = $1b1e
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $1b00
|
||||||
|
&long r2r3sl = $1b04
|
||||||
|
&long r4r5sl = $1b08
|
||||||
|
&long r6r7sl = $1b0c
|
||||||
|
&long r8r0sl = $1b00
|
||||||
|
&long r10r11sl = $1b04
|
||||||
|
&long r12r13sl = $1b08
|
||||||
|
&long r14r15sl = $1b0c
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $1b00
|
&ubyte r0L = $1b00
|
||||||
&ubyte r1L = $1b02
|
&ubyte r1L = $1b02
|
||||||
|
|||||||
@@ -741,6 +741,16 @@ cx16 {
|
|||||||
&word r14s = $002c
|
&word r14s = $002c
|
||||||
&word r15s = $002e
|
&word r15s = $002e
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $0010
|
||||||
|
&long r2r3sl = $0014
|
||||||
|
&long r4r5sl = $0018
|
||||||
|
&long r6r7sl = $001c
|
||||||
|
&long r8r0sl = $0020
|
||||||
|
&long r10r11sl = $0024
|
||||||
|
&long r12r13sl = $0028
|
||||||
|
&long r14r15sl = $002c
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $0010
|
&ubyte r0L = $0010
|
||||||
&ubyte r1L = $0012
|
&ubyte r1L = $0012
|
||||||
|
|||||||
@@ -414,6 +414,16 @@ cx16 {
|
|||||||
&word r14s = $001e
|
&word r14s = $001e
|
||||||
&word r15s = $0020
|
&word r15s = $0020
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $0002
|
||||||
|
&long r2r3sl = $0006
|
||||||
|
&long r4r5sl = $000a
|
||||||
|
&long r6r7sl = $000e
|
||||||
|
&long r8r0sl = $0012
|
||||||
|
&long r10r11sl = $0016
|
||||||
|
&long r12r13sl = $001a
|
||||||
|
&long r14r15sl = $001e
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $0002
|
&ubyte r0L = $0002
|
||||||
&ubyte r1L = $0004
|
&ubyte r1L = $0004
|
||||||
|
|||||||
@@ -203,6 +203,16 @@ cx16 {
|
|||||||
&word r14s = $cffc
|
&word r14s = $cffc
|
||||||
&word r15s = $cffe
|
&word r15s = $cffe
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $cfe0
|
||||||
|
&long r2r3sl = $cfe4
|
||||||
|
&long r4r5sl = $cfe8
|
||||||
|
&long r6r7sl = $cfec
|
||||||
|
&long r8r0sl = $cff0
|
||||||
|
&long r10r11sl = $cff4
|
||||||
|
&long r12r13sl = $cff8
|
||||||
|
&long r14r15sl = $cffc
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $cfe0
|
&ubyte r0L = $cfe0
|
||||||
&ubyte r1L = $cfe2
|
&ubyte r1L = $cfe2
|
||||||
|
|||||||
@@ -203,6 +203,16 @@ cx16 {
|
|||||||
&word r14s = $001e
|
&word r14s = $001e
|
||||||
&word r15s = $0020
|
&word r15s = $0020
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $0002
|
||||||
|
&long r2r3sl = $0006
|
||||||
|
&long r4r5sl = $000a
|
||||||
|
&long r6r7sl = $000e
|
||||||
|
&long r8r0sl = $0012
|
||||||
|
&long r10r11sl = $0016
|
||||||
|
&long r12r13sl = $001a
|
||||||
|
&long r14r15sl = $001e
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $0002
|
&ubyte r0L = $0002
|
||||||
&ubyte r1L = $0004
|
&ubyte r1L = $0004
|
||||||
|
|||||||
@@ -199,6 +199,16 @@ cx16 {
|
|||||||
&word r14s = $7ffc
|
&word r14s = $7ffc
|
||||||
&word r15s = $7ffe
|
&word r15s = $7ffe
|
||||||
|
|
||||||
|
; signed long versions
|
||||||
|
&long r0r1sl = $7fe0
|
||||||
|
&long r2r3sl = $7fe4
|
||||||
|
&long r4r5sl = $7fe8
|
||||||
|
&long r6r7sl = $7fec
|
||||||
|
&long r8r0sl = $7fe0
|
||||||
|
&long r10r11sl = $7fe4
|
||||||
|
&long r12r13sl = $7fe8
|
||||||
|
&long r14r15sl = $7fec
|
||||||
|
|
||||||
; ubyte versions (low and high bytes)
|
; ubyte versions (low and high bytes)
|
||||||
&ubyte r0L = $7fe0
|
&ubyte r0L = $7fe0
|
||||||
&ubyte r1L = $7fe2
|
&ubyte r1L = $7fe2
|
||||||
|
|||||||
@@ -8,4 +8,4 @@ Look in the Makefile to see how to build or run the various programs.
|
|||||||
and example program, you can find those efforts here on GitHub: https://github.com/adiee5/prog8-nes-target
|
and example program, you can find those efforts here on GitHub: https://github.com/adiee5/prog8-nes-target
|
||||||
|
|
||||||
*gillham* has been working on a few other compilation targets, such as VIC-20 (various editions), Foenix, and CX16OS.
|
*gillham* has been working on a few other compilation targets, such as VIC-20 (various editions), Foenix, and CX16OS.
|
||||||
you can find them here on GitHub: https://github.com/gillham/prog8targets
|
These will be much more complete than the examples here. You can find them on GitHub: https://github.com/gillham/prog8targets
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ adpcm {
|
|||||||
; $ ffmpeg -i source.mp3 -ss 00:01:27.50 -to 00:01:36.50 -ar 8000 -ac 1 -c:a adpcm_ima_wav -block_size 256 -map_metadata -1 -bitexact out.wav
|
; $ ffmpeg -i source.mp3 -ss 00:01:27.50 -to 00:01:36.50 -ar 8000 -ac 1 -c:a adpcm_ima_wav -block_size 256 -map_metadata -1 -bitexact out.wav
|
||||||
; And/or use a tool such as https://github.com/dbry/adpcm-xq (make sure to set the correct block size, -b8)
|
; And/or use a tool such as https://github.com/dbry/adpcm-xq (make sure to set the correct block size, -b8)
|
||||||
;
|
;
|
||||||
|
; NOTE: sox may generate IMA-ADPCM files with a block size different than 256 bytes, which is not supported by this decoder. Use ffmpeg instead.
|
||||||
|
;
|
||||||
; NOTE: for speed reasons this implementation doesn't guard against clipping errors.
|
; NOTE: for speed reasons this implementation doesn't guard against clipping errors.
|
||||||
; if the output sounds distorted, lower the volume of the source waveform to 80% and try again etc.
|
; if the output sounds distorted, lower the volume of the source waveform to 80% and try again etc.
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
; $ ffmpeg -i source.mp3 -ss 00:01:27.50 -to 00:01:36.50 -ar 8000 -ac 1 -c:a adpcm_ima_wav -block_size 256 -map_metadata -1 -bitexact out.wav
|
; $ ffmpeg -i source.mp3 -ss 00:01:27.50 -to 00:01:36.50 -ar 8000 -ac 1 -c:a adpcm_ima_wav -block_size 256 -map_metadata -1 -bitexact out.wav
|
||||||
; Or use a tool such as https://github.com/dbry/adpcm-xq (make sure to set correct block size)
|
; Or use a tool such as https://github.com/dbry/adpcm-xq (make sure to set correct block size)
|
||||||
;
|
;
|
||||||
|
; NOTE: sox may generate IMA-ADPCM files with a block size different than 256 bytes, which is not supported by this decoder. Use ffmpeg instead.
|
||||||
|
;
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ main {
|
|||||||
ubyte vera_rate
|
ubyte vera_rate
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
;; diskio.fastmode(1)
|
diskio.fastmode(1)
|
||||||
txt.print("name of .wav file to play on drive 8: ")
|
txt.print("name of .wav file to play on drive 8: ")
|
||||||
while 0==txt.input_chars(MUSIC_FILENAME) {
|
while 0==txt.input_chars(MUSIC_FILENAME) {
|
||||||
; until user types a name...
|
; until user types a name...
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
%import sprites
|
%import sprites
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
; play a raw pcm stereo 16 bit audio file at 16021 hz,
|
; play a raw pcm stereo 16 bit audio file at 14877 hz,
|
||||||
; with real-time VU meters and sample waveform displays.
|
; with real-time VU meters and sample waveform displays.
|
||||||
|
|
||||||
; you can make an appropriate pcm file with one of the following commands:
|
; you can make an appropriate pcm file with one of the following commands:
|
||||||
; ffmpeg -i input_audio_file -ac 2 -ar 16021 -f s16le -acodec pcm_s16le music.pcm
|
; ffmpeg -i input_audio_file -ac 2 -ar 14877 -f s16le -acodec pcm_s16le music.pcm
|
||||||
; sox input_audio_file -e signed-integer -L -b 16 -c 2 -r 16021 -t raw music.pcm
|
; sox input_audio_file -e signed-integer -L -b 16 -c 2 -r 14877 -t raw music.pcm
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
const ubyte vera_rate = 42 ; 16021 hz
|
const ubyte vera_rate = 39 ; 14877 hz
|
||||||
str pcmfile = "music.pcm" ; see format specs mentioned above
|
str pcmfile = "music.pcm" ; see format specs mentioned above
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
@@ -34,7 +34,7 @@ main {
|
|||||||
cx16.GRAPH_put_next_char(cx16.r9L)
|
cx16.GRAPH_put_next_char(cx16.r9L)
|
||||||
cx16.r0 = 250
|
cx16.r0 = 250
|
||||||
cx16.r1 = 20
|
cx16.r1 = 20
|
||||||
for cx16.r9L in iso:"16kHz stereo"
|
for cx16.r9L in iso:"15kHz stereo"
|
||||||
cx16.GRAPH_put_next_char(cx16.r9L)
|
cx16.GRAPH_put_next_char(cx16.r9L)
|
||||||
|
|
||||||
cx16.rombank(0) ; activate kernal bank for faster calls
|
cx16.rombank(0) ; activate kernal bank for faster calls
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
; PRG size by a lot because they embed a large multiplication lookup table.
|
; PRG size by a lot because they embed a large multiplication lookup table.
|
||||||
|
|
||||||
|
|
||||||
|
%import textio
|
||||||
%import math
|
%import math
|
||||||
%import syslib
|
%import syslib
|
||||||
|
|
||||||
@@ -38,6 +39,8 @@ main {
|
|||||||
repeat {
|
repeat {
|
||||||
clear_particles()
|
clear_particles()
|
||||||
update_particles()
|
update_particles()
|
||||||
|
txt.home()
|
||||||
|
txt.print_uw(active_particles)
|
||||||
sys.waitvsync()
|
sys.waitvsync()
|
||||||
sys.waitvsync()
|
sys.waitvsync()
|
||||||
}
|
}
|
||||||
|
|||||||
117
examples/test.p8
117
examples/test.p8
@@ -1,87 +1,54 @@
|
|||||||
%import floats
|
%option no_sysinit ; leave the CX16 defaults in place
|
||||||
|
%zeropage basicsafe ; don't step on BASIC zero page locations
|
||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
struct element {
|
||||||
|
ubyte type
|
||||||
|
long x
|
||||||
|
word w
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
long @shared lv = -1
|
word w = -1111
|
||||||
word @shared wv = -1
|
long l = -11111111
|
||||||
byte @shared bv = -1
|
^^element myElement = [1, -11111111, -1111]
|
||||||
float @shared fv = -1.1
|
|
||||||
bool b1, b2, b3, b4 = false
|
|
||||||
|
|
||||||
b1 = bv<0
|
txt.print_w(w)
|
||||||
b2 = wv<0
|
txt.spc()
|
||||||
b3 = lv<0
|
w >>= 4
|
||||||
b4 = fv<0
|
txt.print_w(w)
|
||||||
txt.print_bool(b1)
|
txt.spc()
|
||||||
txt.print_bool(b2)
|
w <<= 4
|
||||||
txt.print_bool(b3)
|
txt.print_w(w)
|
||||||
txt.print_bool(b4)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
b1=b2=b3=b4=false
|
txt.print_w(myElement.w)
|
||||||
b1 = sgn(bv)<0
|
txt.spc()
|
||||||
b2 = sgn(wv)<0
|
myElement.w >>= 4
|
||||||
b3 = sgn(lv)<0
|
txt.print_w(myElement.w)
|
||||||
b4 = sgn(fv)<0
|
txt.spc()
|
||||||
txt.print_bool(b1)
|
myElement.w <<= 4
|
||||||
txt.print_bool(b2)
|
txt.print_w(myElement.w)
|
||||||
txt.print_bool(b3)
|
|
||||||
txt.print_bool(b4)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
bv = 1
|
txt.nl()
|
||||||
wv = 1
|
txt.print_l(l)
|
||||||
lv = 1
|
txt.spc()
|
||||||
fv = 1.1
|
l >>= 4
|
||||||
b1 = sgn(bv)<0
|
txt.print_l(l)
|
||||||
b2 = sgn(wv)<0
|
txt.spc()
|
||||||
b3 = sgn(lv)<0
|
l <<= 4
|
||||||
b4 = sgn(fv)<0
|
txt.print_l(l)
|
||||||
txt.print_bool(b1)
|
txt.nl()
|
||||||
txt.print_bool(b2)
|
txt.print_l(myElement.x)
|
||||||
txt.print_bool(b3)
|
txt.spc()
|
||||||
txt.print_bool(b4)
|
myElement.x >>= 4
|
||||||
|
txt.print_l(myElement.x)
|
||||||
|
txt.spc()
|
||||||
|
myElement.x <<= 4
|
||||||
|
txt.print_l(myElement.x)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
sub start2() {
|
|
||||||
uword uw
|
|
||||||
word sw
|
|
||||||
long lv
|
|
||||||
float fl
|
|
||||||
|
|
||||||
|
|
||||||
uw = 44555
|
|
||||||
fl = uw as float
|
|
||||||
txt.print_f(fl)
|
|
||||||
txt.nl()
|
|
||||||
fl /= 2
|
|
||||||
uw = fl as uword
|
|
||||||
txt.print_uw(uw)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
sw = -8888
|
|
||||||
fl = sw as float
|
|
||||||
txt.print_f(fl)
|
|
||||||
txt.nl()
|
|
||||||
fl /= 2
|
|
||||||
sw = fl as word
|
|
||||||
txt.print_w(sw)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
lv = -99886666
|
|
||||||
fl = lv as float
|
|
||||||
txt.print_f(fl)
|
|
||||||
txt.nl()
|
|
||||||
fl /= 2
|
|
||||||
lv = fl as long
|
|
||||||
txt.print_l(lv)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ org.gradle.parallel=true
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.configuration-cache=false
|
org.gradle.configuration-cache=false
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
version=12.0-BETA7
|
version=12.0.1-SNAPSHOT
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ fun optimizeSimplifiedAst(program: PtProgram, options: CompilationOptions, st: S
|
|||||||
return
|
return
|
||||||
while (errors.noErrors() &&
|
while (errors.noErrors() &&
|
||||||
optimizeAssignTargets(program, st)
|
optimizeAssignTargets(program, st)
|
||||||
|
+ optimizeFloatComparesToZero(program)
|
||||||
+ optimizeBinaryExpressions(program, options) > 0) {
|
+ optimizeBinaryExpressions(program, options) > 0) {
|
||||||
// keep rolling
|
// keep rolling
|
||||||
}
|
}
|
||||||
@@ -152,3 +153,27 @@ private fun optimizeBinaryExpressions(program: PtProgram, options: CompilationOp
|
|||||||
}
|
}
|
||||||
return changes
|
return changes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun optimizeFloatComparesToZero(program: PtProgram): Int {
|
||||||
|
var changes = 0
|
||||||
|
walkAst(program) { node: PtNode, depth: Int ->
|
||||||
|
if (node is PtBinaryExpression) {
|
||||||
|
val constvalue = node.right.asConstValue()
|
||||||
|
if(node.type.isBool && constvalue==0.0 && node.left.type.isFloat && node.operator in ComparisonOperators) {
|
||||||
|
// float == 0 --> sgn(float) == 0
|
||||||
|
val sign = PtBuiltinFunctionCall("sgn", false, true, DataType.BYTE, node.position)
|
||||||
|
sign.add(node.left)
|
||||||
|
val replacement = PtBinaryExpression(node.operator, DataType.BOOL, node.position)
|
||||||
|
replacement.add(sign)
|
||||||
|
replacement.add(PtNumber(BaseDataType.BYTE, 0.0, node.position))
|
||||||
|
replacement.parent = node.parent
|
||||||
|
val index = node.parent.children.indexOf(node)
|
||||||
|
node.parent.children[index] = replacement
|
||||||
|
changes++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
return changes
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user