mirror of
https://github.com/irmen/prog8.git
synced 2024-07-05 06:29:02 +00:00
rebuilding floating point stack evaluation (using cpu stack)
This commit is contained in:
parent
9f247901d4
commit
d5707b7bf3
@ -207,7 +207,8 @@ class AsmGen6502Internal (
|
|||||||
private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this)
|
private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this)
|
||||||
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
||||||
private val programGen = ProgramAndVarsGen(program, options, errors, symbolTable, functioncallAsmGen, this, allocator, zeropage)
|
private val programGen = ProgramAndVarsGen(program, options, errors, symbolTable, functioncallAsmGen, this, allocator, zeropage)
|
||||||
private val assignmentAsmGen = AssignmentAsmGen(program, this, allocator)
|
private val anyExprGen = AnyExprAsmGen(this)
|
||||||
|
private val assignmentAsmGen = AssignmentAsmGen(program, this, anyExprGen, allocator)
|
||||||
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
|
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
|
||||||
|
|
||||||
fun compileToAssembly(): IAssemblyProgram? {
|
fun compileToAssembly(): IAssemblyProgram? {
|
||||||
@ -3013,6 +3014,14 @@ $repeatLabel""")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun pushFAC1() {
|
||||||
|
out(" jsr floats.pushFAC1")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun popFAC1() {
|
||||||
|
out(" jsr floats.popFAC1")
|
||||||
|
}
|
||||||
|
|
||||||
internal fun needAsaveForExpr(arg: PtExpression): Boolean =
|
internal fun needAsaveForExpr(arg: PtExpression): Boolean =
|
||||||
arg !is PtNumber && arg !is PtIdentifier && (arg !is PtMemoryByte || !arg.isSimple())
|
arg !is PtNumber && arg !is PtIdentifier && (arg !is PtMemoryByte || !arg.isSimple())
|
||||||
|
|
||||||
|
@ -0,0 +1,266 @@
|
|||||||
|
package prog8.codegen.cpu6502.assignment
|
||||||
|
|
||||||
|
import prog8.code.ast.PtBinaryExpression
|
||||||
|
import prog8.code.core.*
|
||||||
|
import prog8.codegen.cpu6502.AsmGen6502Internal
|
||||||
|
|
||||||
|
//
|
||||||
|
// This contains codegen for stack-based evaluation of binary expressions.
|
||||||
|
// It uses the CPU stack so depth is limited.
|
||||||
|
// It is called "as a last resort" if the optimized codegen path is unable
|
||||||
|
// to come up with a special case of the expression.
|
||||||
|
//
|
||||||
|
internal class AnyExprAsmGen(
|
||||||
|
private val asmgen: AsmGen6502Internal
|
||||||
|
) {
|
||||||
|
fun assignAnyExpressionUsingStack(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
|
when(expr.type) {
|
||||||
|
in ByteDatatypes -> {
|
||||||
|
if(expr.left.type in ByteDatatypes && expr.right.type in ByteDatatypes)
|
||||||
|
return assignByteBinExpr(expr, assign)
|
||||||
|
if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
||||||
|
require(expr.operator in ComparisonOperators)
|
||||||
|
TODO("words operands comparison -> byte")
|
||||||
|
}
|
||||||
|
if (expr.left.type==DataType.FLOAT && expr.right.type==DataType.FLOAT) {
|
||||||
|
require(expr.operator in ComparisonOperators)
|
||||||
|
return assignFloatBinExpr(expr, assign)
|
||||||
|
}
|
||||||
|
TODO("weird expr operand types")
|
||||||
|
}
|
||||||
|
in WordDatatypes -> {
|
||||||
|
require(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
||||||
|
"both operands must be words"
|
||||||
|
}
|
||||||
|
return assignWordBinExpr(expr, assign)
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
require(expr.left.type==DataType.FLOAT && expr.right.type==DataType.FLOAT) {
|
||||||
|
"both operands must be floats"
|
||||||
|
}
|
||||||
|
return assignFloatBinExpr(expr, assign)
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird expression type in assignment")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assignWordBinExpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
|
when(expr.operator) {
|
||||||
|
"+" -> {
|
||||||
|
TODO("word + at ${expr.position}")
|
||||||
|
}
|
||||||
|
"-" -> {
|
||||||
|
TODO("word - at ${expr.position}")
|
||||||
|
}
|
||||||
|
"*" -> {
|
||||||
|
TODO("word * at ${expr.position}")
|
||||||
|
}
|
||||||
|
"/" -> {
|
||||||
|
TODO("word / at ${expr.position}")
|
||||||
|
}
|
||||||
|
"<<" -> {
|
||||||
|
TODO("word << at ${expr.position}")
|
||||||
|
}
|
||||||
|
">>" -> {
|
||||||
|
TODO("word >> at ${expr.position}")
|
||||||
|
}
|
||||||
|
"%" -> {
|
||||||
|
TODO("word % at ${expr.position}")
|
||||||
|
}
|
||||||
|
"&", "and" -> {
|
||||||
|
TODO("word and at ${expr.position}")
|
||||||
|
}
|
||||||
|
"|", "or" -> {
|
||||||
|
TODO("word or at ${expr.position}")
|
||||||
|
}
|
||||||
|
"^", "xor" -> {
|
||||||
|
TODO("word xor at ${expr.position}")
|
||||||
|
}
|
||||||
|
"==" -> {
|
||||||
|
TODO("word == at ${expr.position}")
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
TODO("word != at ${expr.position}")
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
TODO("word < at ${expr.position}")
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
TODO("word <= at ${expr.position}")
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
TODO("word > at ${expr.position}")
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
TODO("word >= at ${expr.position}")
|
||||||
|
}
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assignByteBinExpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
|
when(expr.operator) {
|
||||||
|
"+" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
|
||||||
|
asmgen.out(" pha")
|
||||||
|
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
||||||
|
asmgen.out(" pla | clc | adc P8ZP_SCRATCH_B1")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"-" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
|
||||||
|
asmgen.out(" pha")
|
||||||
|
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
||||||
|
asmgen.out(" pla | sec | sbc P8ZP_SCRATCH_B1")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"*" -> {
|
||||||
|
TODO("byte * at ${expr.position}")
|
||||||
|
}
|
||||||
|
"/" -> {
|
||||||
|
TODO("byte / at ${expr.position}")
|
||||||
|
}
|
||||||
|
"<<" -> {
|
||||||
|
TODO("byte << at ${expr.position}")
|
||||||
|
}
|
||||||
|
">>" -> {
|
||||||
|
TODO("byte >> at ${expr.position}")
|
||||||
|
}
|
||||||
|
"%" -> {
|
||||||
|
TODO("byte % at ${expr.position}")
|
||||||
|
}
|
||||||
|
"&", "and" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
|
||||||
|
asmgen.out(" pha")
|
||||||
|
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
||||||
|
asmgen.out(" pla | and P8ZP_SCRATCH_B1")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"|", "or" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
|
||||||
|
asmgen.out(" pha")
|
||||||
|
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
||||||
|
asmgen.out(" pla | ora P8ZP_SCRATCH_B1")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"^", "xor" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
|
||||||
|
asmgen.out(" pha")
|
||||||
|
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
||||||
|
asmgen.out(" pla | eor P8ZP_SCRATCH_B1")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"==" -> {
|
||||||
|
TODO("byte == at ${expr.position}")
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
TODO("byte != at ${expr.position}")
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
TODO("byte < at ${expr.position}")
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
TODO("byte <= at ${expr.position}")
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
TODO("byte > at ${expr.position}")
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
TODO("byte >= at ${expr.position}")
|
||||||
|
}
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assignFloatBinExpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
|
when(expr.operator) {
|
||||||
|
"+" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
||||||
|
if(!expr.right.isSimple()) asmgen.pushFAC1()
|
||||||
|
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.FAC2, true)
|
||||||
|
if(!expr.right.isSimple()) asmgen.popFAC1()
|
||||||
|
asmgen.out(" jsr floats.FADDT")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.FAC1, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"-" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.FAC1, true)
|
||||||
|
if(!expr.left.isSimple()) asmgen.pushFAC1()
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.FAC2, true)
|
||||||
|
if(!expr.left.isSimple()) asmgen.popFAC1()
|
||||||
|
asmgen.out(" jsr floats.FSUBT")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.FAC1, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"*" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
||||||
|
if(!expr.right.isSimple()) asmgen.pushFAC1()
|
||||||
|
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.FAC2, true)
|
||||||
|
if(!expr.right.isSimple()) asmgen.popFAC1()
|
||||||
|
asmgen.out(" jsr floats.FMULTT")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.FAC1, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"/" -> {
|
||||||
|
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.FAC1, true)
|
||||||
|
if(!expr.left.isSimple()) asmgen.pushFAC1()
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.FAC2, true)
|
||||||
|
if(!expr.left.isSimple()) asmgen.popFAC1()
|
||||||
|
asmgen.out(" jsr floats.FDIVT")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.FAC1, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"==" -> {
|
||||||
|
setupFloatComparisonFAC1vsVarAY(expr)
|
||||||
|
asmgen.out(" jsr floats.var_fac1_equal_f")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
setupFloatComparisonFAC1vsVarAY(expr)
|
||||||
|
asmgen.out(" jsr floats.var_fac1_notequal_f")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
setupFloatComparisonFAC1vsVarAY(expr)
|
||||||
|
asmgen.out(" jsr floats.var_fac1_less_f")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
setupFloatComparisonFAC1vsVarAY(expr)
|
||||||
|
asmgen.out(" jsr floats.var_fac1_greater_f")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
setupFloatComparisonFAC1vsVarAY(expr)
|
||||||
|
asmgen.out(" jsr floats.var_fac1_lesseq_f")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
setupFloatComparisonFAC1vsVarAY(expr)
|
||||||
|
asmgen.out(" jsr floats.var_fac1_greatereq_f")
|
||||||
|
asmgen.assignRegister(RegisterOrPair.A, assign.target)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else -> TODO("float expression operator ${expr.operator}")
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupFloatComparisonFAC1vsVarAY(expr: PtBinaryExpression) {
|
||||||
|
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
||||||
|
if(!expr.right.isSimple()) asmgen.pushFAC1()
|
||||||
|
asmgen.assignExpressionToVariable(expr.right, "floats.floats_temp_var", DataType.FLOAT)
|
||||||
|
if(!expr.right.isSimple()) asmgen.popFAC1()
|
||||||
|
asmgen.out(" lda #<floats.floats_temp_var | ldy #>floats.floats_temp_var")
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import prog8.codegen.cpu6502.returnsWhatWhere
|
|||||||
|
|
||||||
internal class AssignmentAsmGen(private val program: PtProgram,
|
internal class AssignmentAsmGen(private val program: PtProgram,
|
||||||
private val asmgen: AsmGen6502Internal,
|
private val asmgen: AsmGen6502Internal,
|
||||||
|
private val anyExprGen: AnyExprAsmGen,
|
||||||
private val allocator: VariableAllocator) {
|
private val allocator: VariableAllocator) {
|
||||||
private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
|
private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
|
||||||
|
|
||||||
@ -411,7 +412,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(expr.type !in IntegerDatatypes)
|
if(expr.type !in IntegerDatatypes)
|
||||||
return false
|
return anyExprGen.assignAnyExpressionUsingStack(expr, assign)
|
||||||
|
|
||||||
if(expr.operator in setOf("&", "|", "^", "and", "or", "xor"))
|
if(expr.operator in setOf("&", "|", "^", "and", "or", "xor"))
|
||||||
return optimizedLogicalOrBitwiseExpr(expr, assign.target)
|
return optimizedLogicalOrBitwiseExpr(expr, assign.target)
|
||||||
@ -428,7 +429,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
if(expr.operator=="%")
|
if(expr.operator=="%")
|
||||||
return optimizedRemainderExpr(expr, assign.target)
|
return optimizedRemainderExpr(expr, assign.target)
|
||||||
|
|
||||||
return false
|
return anyExprGen.assignAnyExpressionUsingStack(expr, assign)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun optimizedRemainderExpr(expr: PtBinaryExpression, target: AsmAssignTarget): Boolean {
|
private fun optimizedRemainderExpr(expr: PtBinaryExpression, target: AsmAssignTarget): Boolean {
|
||||||
@ -1579,6 +1580,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(targetDt==DataType.FLOAT && (target.register==RegisterOrPair.FAC1 || target.register==RegisterOrPair.FAC2)) {
|
if(targetDt==DataType.FLOAT && (target.register==RegisterOrPair.FAC1 || target.register==RegisterOrPair.FAC2)) {
|
||||||
|
if(target.register==RegisterOrPair.FAC2)
|
||||||
|
asmgen.pushFAC1()
|
||||||
when(valueDt) {
|
when(valueDt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
assignExpressionToRegister(value, RegisterOrPair.Y, false)
|
assignExpressionToRegister(value, RegisterOrPair.Y, false)
|
||||||
@ -1600,6 +1603,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
if(target.register==RegisterOrPair.FAC2) {
|
if(target.register==RegisterOrPair.FAC2) {
|
||||||
asmgen.out(" jsr floats.MOVEF")
|
asmgen.out(" jsr floats.MOVEF")
|
||||||
|
asmgen.popFAC1()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -2091,7 +2095,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun assignFAC2float(target: AsmAssignTarget) {
|
internal fun assignFAC2float(target: AsmAssignTarget) {
|
||||||
asmgen.out(" jsr floats.MOVFA") // fac2 -> fac1
|
asmgen.out(" jsr floats.MOVFA")
|
||||||
|
if(target.register != RegisterOrPair.FAC1)
|
||||||
assignFAC1float(target)
|
assignFAC1float(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2121,7 +2126,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte")
|
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte")
|
||||||
TargetStorageKind.REGISTER -> {
|
TargetStorageKind.REGISTER -> {
|
||||||
if (target.register!! != RegisterOrPair.FAC1)
|
if(target.register==RegisterOrPair.FAC2)
|
||||||
|
asmgen.out(" jsr floats.MOVAF")
|
||||||
|
else if (target.register!! != RegisterOrPair.FAC1)
|
||||||
throw AssemblyError("can't assign Fac1 float to another register")
|
throw AssemblyError("can't assign Fac1 float to another register")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import prog8.ast.walk.AstWalker
|
|||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.code.core.AugmentAssignmentOperators
|
import prog8.code.core.AugmentAssignmentOperators
|
||||||
import prog8.code.core.CompilationOptions
|
import prog8.code.core.CompilationOptions
|
||||||
|
import prog8.code.core.DataType
|
||||||
import prog8.code.target.VMTarget
|
import prog8.code.target.VMTarget
|
||||||
|
|
||||||
|
|
||||||
@ -21,6 +22,9 @@ class BinExprSplitter(private val program: Program, private val options: Compila
|
|||||||
if(options.compTarget.name == VMTarget.NAME)
|
if(options.compTarget.name == VMTarget.NAME)
|
||||||
return noModifications // don't split expressions when targeting the vm codegen, it handles nested expressions well
|
return noModifications // don't split expressions when targeting the vm codegen, it handles nested expressions well
|
||||||
|
|
||||||
|
if(assignment.value.inferType(program) istype DataType.FLOAT)
|
||||||
|
return noModifications
|
||||||
|
|
||||||
val binExpr = assignment.value as? BinaryExpression
|
val binExpr = assignment.value as? BinaryExpression
|
||||||
if (binExpr != null) {
|
if (binExpr != null) {
|
||||||
|
|
||||||
|
@ -208,7 +208,6 @@ var_fac1_greater_f .proc
|
|||||||
.pend
|
.pend
|
||||||
|
|
||||||
var_fac1_greatereq_f .proc
|
var_fac1_greatereq_f .proc
|
||||||
ldx P8ZP_SCRATCH_REG
|
|
||||||
; -- is the float in FAC1 >= the variable AY? Result in A. Clobbers X.
|
; -- is the float in FAC1 >= the variable AY? Result in A. Clobbers X.
|
||||||
jsr FCOMP
|
jsr FCOMP
|
||||||
cmp #0
|
cmp #0
|
||||||
@ -221,6 +220,14 @@ var_fac1_greatereq_f .proc
|
|||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
var_fac1_equal_f .proc
|
||||||
|
; -- are the floats numbers in FAC1 and the variable AY *not* identical? Result in A. Clobbers X.
|
||||||
|
jsr FCOMP
|
||||||
|
and #1
|
||||||
|
eor #1
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
var_fac1_notequal_f .proc
|
var_fac1_notequal_f .proc
|
||||||
; -- are the floats numbers in FAC1 and the variable AY *not* identical? Result in A. Clobbers X.
|
; -- are the floats numbers in FAC1 and the variable AY *not* identical? Result in A. Clobbers X.
|
||||||
jsr FCOMP
|
jsr FCOMP
|
||||||
@ -381,3 +388,61 @@ set_array_float .proc
|
|||||||
; -- copies the 5 bytes of the mflt value pointed to by SCRATCH_ZPWORD1,
|
; -- copies the 5 bytes of the mflt value pointed to by SCRATCH_ZPWORD1,
|
||||||
; into the 5 bytes pointed to by A/Y. Clobbers A,Y.
|
; into the 5 bytes pointed to by A/Y. Clobbers A,Y.
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
pushFAC1 .proc
|
||||||
|
;-- push floating point in FAC onto the cpu stack
|
||||||
|
; save return address
|
||||||
|
pla
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
pla
|
||||||
|
sta P8ZP_SCRATCH_W2+1
|
||||||
|
ldx #<floats.floats_temp_var
|
||||||
|
ldy #>floats.floats_temp_var
|
||||||
|
jsr floats.MOVMF
|
||||||
|
lda floats.floats_temp_var
|
||||||
|
pha
|
||||||
|
lda floats.floats_temp_var+1
|
||||||
|
pha
|
||||||
|
lda floats.floats_temp_var+2
|
||||||
|
pha
|
||||||
|
lda floats.floats_temp_var+3
|
||||||
|
pha
|
||||||
|
lda floats.floats_temp_var+4
|
||||||
|
pha
|
||||||
|
; re-push return address
|
||||||
|
lda P8ZP_SCRATCH_W2+1
|
||||||
|
pha
|
||||||
|
lda P8ZP_SCRATCH_W2
|
||||||
|
pha
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
popFAC1 .proc
|
||||||
|
; -- pop floating point value from cpu stack into FAC1
|
||||||
|
; save return address
|
||||||
|
pla
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
pla
|
||||||
|
sta P8ZP_SCRATCH_W2+1
|
||||||
|
pla
|
||||||
|
sta floats.floats_temp_var+4
|
||||||
|
pla
|
||||||
|
sta floats.floats_temp_var+3
|
||||||
|
pla
|
||||||
|
sta floats.floats_temp_var+2
|
||||||
|
pla
|
||||||
|
sta floats.floats_temp_var+1
|
||||||
|
pla
|
||||||
|
sta floats.floats_temp_var
|
||||||
|
lda #<floats.floats_temp_var
|
||||||
|
ldy #>floats.floats_temp_var
|
||||||
|
jsr floats.MOVFM
|
||||||
|
; re-push return address
|
||||||
|
lda P8ZP_SCRATCH_W2+1
|
||||||
|
pha
|
||||||
|
lda P8ZP_SCRATCH_W2
|
||||||
|
pha
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@ package prog8.buildversion
|
|||||||
const val MAVEN_GROUP = "prog8"
|
const val MAVEN_GROUP = "prog8"
|
||||||
const val MAVEN_NAME = "compiler"
|
const val MAVEN_NAME = "compiler"
|
||||||
const val VERSION = "9.2-SNAPSHOT"
|
const val VERSION = "9.2-SNAPSHOT"
|
||||||
const val GIT_REVISION = 3974
|
const val GIT_REVISION = 3980
|
||||||
const val GIT_SHA = "ab8173637a9939352ddb027ecd67f1c42b63b1fc"
|
const val GIT_SHA = "9f247901d484ca36d047cdcf77f5b905ba772f82"
|
||||||
const val GIT_DATE = "2023-07-16T09:15:28Z"
|
const val GIT_DATE = "2023-07-16T21:45:04Z"
|
||||||
const val GIT_BRANCH = "remove_evalstack"
|
const val GIT_BRANCH = "remove_evalstack"
|
||||||
const val BUILD_DATE = "2023-07-16T11:04:18Z"
|
const val BUILD_DATE = "2023-07-17T23:11:43Z"
|
||||||
const val BUILD_UNIX_TIME = 1689505458888L
|
const val BUILD_UNIX_TIME = 1689635503506L
|
||||||
const val DIRTY = 1
|
const val DIRTY = 1
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- (branch): fix float expressions codegen, it relied heavily on the evalstack
|
- (branch): fix float expressions codegen, it relied heavily on the evalstack (mandelbrot example zero division error)
|
||||||
- (branch): improve integer expression codegen even more to support even more cases?
|
- (branch): improve integer expression codegen even more to support even more cases?
|
||||||
|
- (branch): fully remove BinExprSplitter???
|
||||||
|
|
||||||
- IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register.
|
- IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register.
|
||||||
- IR: reduce the number of branch instructions (gradually), replace with CMP(I) + status branch instruction
|
- IR: reduce the number of branch instructions (gradually), replace with CMP(I) + status branch instruction
|
||||||
|
@ -9,6 +9,7 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
txt.print("calculating mandelbrot fractal...\n\n")
|
txt.print("calculating mandelbrot fractal...\n\n")
|
||||||
|
cbm.SETTIM(0,0,0)
|
||||||
|
|
||||||
ubyte pixelx
|
ubyte pixelx
|
||||||
ubyte pixely
|
ubyte pixely
|
||||||
@ -37,5 +38,10 @@ main {
|
|||||||
}
|
}
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float duration = (cbm.RDTIM16() as float) / 60
|
||||||
|
txt.print("\nfinished in ")
|
||||||
|
floats.print_f(duration)
|
||||||
|
txt.print(" seconds!\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,47 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
%import floats
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main
|
main {
|
||||||
{
|
const uword width = 60
|
||||||
sub start()
|
const uword height = 50
|
||||||
{
|
const ubyte max_iter = 16
|
||||||
uword uw = 54321
|
|
||||||
ubyte ub = 123
|
|
||||||
word sw = -12345
|
|
||||||
byte sb = -123
|
|
||||||
|
|
||||||
txt.print_uw(~ub as uword) ;132
|
sub start() {
|
||||||
txt.nl()
|
txt.print("calculating mandelbrot fractal...\n\n")
|
||||||
txt.print_ub(~uw as ubyte) ;206
|
cbm.SETTIM(0,0,0)
|
||||||
txt.nl()
|
|
||||||
txt.print_uw(~sb as uword) ;122
|
ubyte pixelx
|
||||||
txt.nl()
|
ubyte pixely
|
||||||
txt.print_ub(~sw as ubyte) ;56
|
|
||||||
txt.nl()
|
for pixely in 0 to height-1 {
|
||||||
txt.print_w(-sb as word) ;123
|
float yy = (pixely as float)/0.40/height - 1.3
|
||||||
txt.nl()
|
|
||||||
txt.print_b(-sw as byte) ;57
|
for pixelx in 0 to width-1 {
|
||||||
|
float xx = (pixelx as float)/0.32/width - 2.2
|
||||||
|
|
||||||
|
float xsquared = 0.0
|
||||||
|
float ysquared = 0.0
|
||||||
|
float x = 0.0
|
||||||
|
float y = 0.0
|
||||||
|
ubyte iter = 0
|
||||||
|
|
||||||
|
while iter<max_iter and xsquared+ysquared<4.0 {
|
||||||
|
y = x*y*2.0 + yy
|
||||||
|
x = xsquared - ysquared + xx
|
||||||
|
xsquared = x*x
|
||||||
|
ysquared = y*y
|
||||||
|
iter++
|
||||||
|
}
|
||||||
|
txt.color2(1, max_iter-iter)
|
||||||
|
txt.spc()
|
||||||
|
}
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float duration = (cbm.RDTIM16() as float) / 60
|
||||||
|
txt.print("\nfinished in ")
|
||||||
|
floats.print_f(duration)
|
||||||
|
txt.print(" seconds!\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user