diff --git a/compiler/res/prog8lib/c64/floats.asm b/compiler/res/prog8lib/c64/floats.asm index a587413f7..83414cdb8 100644 --- a/compiler/res/prog8lib/c64/floats.asm +++ b/compiler/res/prog8lib/c64/floats.asm @@ -96,7 +96,7 @@ stack_uw2float .proc .pend stack_float2w .proc ; also used for float2b - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr AYINT ldx P8ZP_SCRATCH_REG @@ -109,7 +109,7 @@ stack_float2w .proc ; also used for float2b .pend stack_float2uw .proc ; also used for float2ub - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr GETADR ldx P8ZP_SCRATCH_REG @@ -173,6 +173,7 @@ pop_float .proc .pend pop_float_fac1 .proc + ; TODO REMOVE THIS?? But is used in code generation at various places still ; -- pops float from stack into FAC1 lda #fmath_float1 @@ -471,7 +472,7 @@ func_sin_into_fac1 .proc .pend func_cos_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr COS ldx P8ZP_SCRATCH_REG @@ -479,7 +480,7 @@ func_cos_into_fac1 .proc .pend func_tan_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr TAN ldx P8ZP_SCRATCH_REG @@ -487,7 +488,7 @@ func_tan_into_fac1 .proc .pend func_atan_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr ATN ldx P8ZP_SCRATCH_REG @@ -495,7 +496,7 @@ func_atan_into_fac1 .proc .pend func_ln_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr LOG ldx P8ZP_SCRATCH_REG @@ -503,12 +504,12 @@ func_ln_into_fac1 .proc .pend func_log2_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr LOG jsr MOVEF - lda #c64.FL_LOG2 + lda #FL_LOG2 jsr MOVFM jsr FDIVT ldx P8ZP_SCRATCH_REG @@ -516,7 +517,7 @@ func_log2_into_fac1 .proc .pend func_sqrt_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr SQR ldx P8ZP_SCRATCH_REG @@ -525,7 +526,7 @@ func_sqrt_into_fac1 .proc func_rad_into_fac1 .proc ; -- convert degrees to radians (d * pi / 180) - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG lda #<_pi_div_180 ldy #>_pi_div_180 @@ -537,7 +538,7 @@ _pi_div_180 .byte 123, 14, 250, 53, 18 ; pi / 180 func_deg_into_fac1 .proc ; -- convert radians to degrees (d * (1/ pi * 180)) - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG lda #<_one_over_pi_div_180 ldy #>_one_over_pi_div_180 @@ -548,7 +549,7 @@ _one_over_pi_div_180 .byte 134, 101, 46, 224, 211 ; 1 / (pi * 180) .pend func_round_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr FADDH jsr INT @@ -557,7 +558,7 @@ func_round_into_fac1 .proc .pend func_floor_into_fac1 .proc - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG jsr INT ldx P8ZP_SCRATCH_REG @@ -566,7 +567,7 @@ func_floor_into_fac1 .proc func_ceil_into_fac1 .proc ; -- ceil: tr = int(f); if tr==f -> return else return tr+1 - jsr pop_float_fac1 + jsr MOVFM stx P8ZP_SCRATCH_REG ldx #fmath_float1 @@ -707,8 +708,8 @@ func_sum_f_into_fac1 .proc rts .pend -sign_f .proc - jsr pop_float_fac1 +sign_f_cc .proc + jsr MOVFM jsr SIGN sta P8ESTACK_LO,x dex diff --git a/compiler/res/prog8lib/math.asm b/compiler/res/prog8lib/math.asm index 2f719e1ae..392fb0156 100644 --- a/compiler/res/prog8lib/math.asm +++ b/compiler/res/prog8lib/math.asm @@ -1243,83 +1243,75 @@ mul_word_100 .proc ; ----------- end optimized multiplications ----------- - -sign_b .proc - lda P8ESTACK_LO+1,x - beq _sign_zero - bmi _sign_neg -_sign_pos lda #1 - sta P8ESTACK_LO+1,x - rts -_sign_neg lda #-1 -_sign_zero sta P8ESTACK_LO+1,x - rts - .pend - -sign_ub .proc - lda P8ESTACK_LO+1,x - beq sign_b._sign_zero - bne sign_b._sign_pos - .pend - -sign_w .proc - lda P8ESTACK_HI+1,x - bmi sign_b._sign_neg - beq sign_ub - bne sign_b._sign_pos - .pend - -sign_uw .proc - lda P8ESTACK_HI+1,x - beq _sign_possibly_zero -_sign_pos lda #1 - sta P8ESTACK_LO+1,x - rts -_sign_possibly_zero lda P8ESTACK_LO+1,x - bne _sign_pos - sta P8ESTACK_LO+1,x - rts - .pend - - -sign_b_into_A .proc - ; -- A = sgn(pop stack byte) - inx - lda P8ESTACK_LO,x - beq _sign_zero - bmi _sign_neg -_sign_pos lda #1 - rts -_sign_neg lda #-1 -_sign_zero rts - .pend - sign_ub_into_A .proc - ; -- A = sgn(pop stack ubyte) - lda P8ESTACK_LO+1,x - bne sign_b._sign_pos + cmp #0 + bne _pos + rts +_pos lda #1 rts .pend -sign_w_into_A .proc - ; -- A = sgn(pop stack word) - lda P8ESTACK_HI+1,x - bmi sign_b._sign_neg - bne sign_b._sign_pos +sign_ub_cc .proc + jsr sign_ub_into_A + sta P8ESTACK_LO,x + dex rts .pend sign_uw_into_A .proc - ; -- A = sgn(pop stack uword) - lda P8ESTACK_HI+1,x - beq _sign_possibly_zero -_sign_pos lda #1 + cpy #0 + beq _possibly_zero +_pos lda #1 rts -_sign_possibly_zero lda P8ESTACK_LO+1,x - bne _sign_pos +_possibly_zero cmp #0 + bne _pos rts .pend +sign_uw_cc .proc + jsr sign_uw_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +sign_b_into_A .proc + cmp #0 + beq _zero + bmi _neg + lda #1 +_zero rts +_neg lda #-1 + rts + .pend + +sign_b_cc .proc + jsr sign_b_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +sign_w_into_A .proc + cpy #0 + beq _possibly_zero + bmi _neg +_pos lda #1 + rts +_neg lda #-1 + rts +_possibly_zero cmp #0 + bne _pos + rts + .pend + + +sign_w_cc .proc + jsr sign_w_into_A + sta P8ESTACK_LO,x + dex + rts + .pend ; bit shifts. ; anything below 3 is done inline. anything above 7 is done via other optimizations. diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index be75cfb9f..1e3572d07 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -704,18 +704,11 @@ func_read_flags .proc .pend func_sqrt16_into_A .proc - jsr func_sqrt16 - jmp func_any_b_into_A._popA - .pend - -func_sqrt16 .proc ; integer square root from http://6502org.wikidot.com/software-math-sqrt - txa - pha - lda P8ESTACK_LO+1,x - ldy P8ESTACK_HI+1,x sta P8ZP_SCRATCH_W1 sty P8ZP_SCRATCH_W1+1 + txa + pha lda #0 sta P8ZP_SCRATCH_B1 sta P8ZP_SCRATCH_REG @@ -741,7 +734,6 @@ func_sqrt16 .proc pla tax lda P8ZP_SCRATCH_B1 - sta P8ESTACK_LO+1,x rts .pend @@ -828,7 +820,7 @@ func_sin8_cc .proc func_sin8u_cc .proc tay - lda _sinecos8u,y + lda func_sin8u_into_A._sinecos8u,y sta P8ESTACK_LO,x dex rts @@ -837,9 +829,10 @@ func_sin8u_cc .proc func_sin16_cc .proc tay lda func_sin16_into_AY._sinecos8lo,y - sta P8ESTACK_LO+1,x + sta P8ESTACK_LO,x lda func_sin16_into_AY._sinecos8hi,y - sta P8ESTACK_HI+1,x + sta P8ESTACK_HI,x + dex rts .pend @@ -847,9 +840,10 @@ func_sin16_cc .proc func_sin16u_cc .proc tay lda func_sin16u_into_AY._sinecos8ulo,y - sta P8ESTACK_LO+1,x + sta P8ESTACK_LO,x lda func_sin16u_into_AY._sinecos8uhi,y - sta P8ESTACK_HI+1,x + sta P8ESTACK_HI,x + dex rts .pend @@ -872,18 +866,20 @@ func_cos8u_cc .proc func_cos16_cc .proc tay lda func_sin16_into_AY._sinecos8lo+64,y - sta P8ESTACK_LO+1,x + sta P8ESTACK_LO,x lda func_sin16_into_AY._sinecos8hi+64,y - sta P8ESTACK_HI+1,x + sta P8ESTACK_HI,x + dex rts .pend func_cos16u_cc .proc tay lda func_sin16u_into_AY._sinecos8ulo+64,y - sta P8ESTACK_LO+1,x + sta P8ESTACK_LO,x lda func_sin16u_into_AY._sinecos8uhi+64,y - sta P8ESTACK_HI+1,x + sta P8ESTACK_HI,x + dex rts .pend diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 387083ed8..06ac5c1ac 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -475,11 +475,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.UBYTE -> asmgen.out(" jsr math.sign_ub") - DataType.BYTE -> asmgen.out(" jsr math.sign_b") - DataType.UWORD -> asmgen.out(" jsr math.sign_uw") - DataType.WORD -> asmgen.out(" jsr math.sign_w") - DataType.FLOAT -> asmgen.out(" jsr floats.sign_f") + DataType.UBYTE -> asmgen.out(" jsr math.sign_ub_cc") + DataType.BYTE -> asmgen.out(" jsr math.sign_b_cc") + DataType.UWORD -> asmgen.out(" jsr math.sign_uw_cc") + DataType.WORD -> asmgen.out(" jsr math.sign_w_cc") + DataType.FLOAT -> asmgen.out(" jsr floats.sign_f_cc") else -> throw AssemblyError("weird type $dt") } } else { @@ -1054,6 +1054,29 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun translateArguments(args: MutableList, signature: FSignature) { val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.STRUCT) }) + fun getSourceForFloat(value: Expression): AsmAssignSource { + return when (value) { + is IdentifierReference -> { + val addr = AddressOf(value, value.position) + AsmAssignSource.fromAstSource(addr, program, asmgen) + } + is NumericLiteralValue -> { + throw AssemblyError("float literals should have been converted into autovar") + } + else -> { + TODO("evaluate float expression, store float in (to be defined) result variable, get address of that variable.") +// val variable = IdentifierReference(listOf("p8_float_eval_result"), value.position) +// variable.linkParents(value) +// val assign = AsmAssignment(AsmAssignSource.fromAstSource(value, program, asmgen), +// AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.FLOAT, null, variableAsmName = asmgen.asmVariableName(variable)), +// false, Position.DUMMY) +// asmgen.translateNormalAssignment(assign) +// val addr = AddressOf(variable, value.position) +// AsmAssignSource.fromAstSource(addr, program, asmgen) + } + } + } + args.zip(callConv.params).zip(signature.parameters).forEach { val paramName = it.second.name val conv = it.first.second @@ -1061,24 +1084,32 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when { conv.variable -> { val varname = "prog8_lib.func_${signature.name}_cc._arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again - val src = if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) { - // put the address of the argument in AY - val addr = AddressOf(value as IdentifierReference, value.position) - AsmAssignSource.fromAstSource(addr, program, asmgen) - } else { - AsmAssignSource.fromAstSource(value, program, asmgen) + val src = when (conv.dt) { + DataType.FLOAT -> getSourceForFloat(value) + in PassByReferenceDatatypes -> { + // put the address of the argument in AY + val addr = AddressOf(value as IdentifierReference, value.position) + AsmAssignSource.fromAstSource(addr, program, asmgen) + } + else -> { + AsmAssignSource.fromAstSource(value, program, asmgen) + } } val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname) val assign = AsmAssignment(src, tgt, false, value.position) asmgen.translateNormalAssignment(assign) } conv.reg != null -> { - val src = if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) { - // put the address of the argument in AY - val addr = AddressOf(value as IdentifierReference, value.position) - AsmAssignSource.fromAstSource(addr, program, asmgen) - } else { - AsmAssignSource.fromAstSource(value, program, asmgen) + val src = when (conv.dt) { + DataType.FLOAT -> getSourceForFloat(value) + in PassByReferenceDatatypes -> { + // put the address of the argument in AY + val addr = AddressOf(value as IdentifierReference, value.position) + AsmAssignSource.fromAstSource(addr, program, asmgen) + } + else -> { + AsmAssignSource.fromAstSource(value, program, asmgen) + } } val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen) val assign = AsmAssignment(src, tgt, false, value.position) diff --git a/compiler/src/prog8/optimizer/BinExprSplitter.kt b/compiler/src/prog8/optimizer/BinExprSplitter.kt index 787419b52..eef2cedcc 100644 --- a/compiler/src/prog8/optimizer/BinExprSplitter.kt +++ b/compiler/src/prog8/optimizer/BinExprSplitter.kt @@ -53,6 +53,7 @@ X = BinExpr X = LeftExpr */ + // TODO can be generelized a bit by allowing LEFT EXPR to be more complex if(binExpr.operator in augmentAssignmentOperators && isSimpleTarget(assignment.target, program.namespace)) { if(assignment.target isSameAs binExpr.left || assignment.target isSameAs binExpr.right) return noModifications diff --git a/examples/plasma.p8 b/examples/plasma.p8 index e18205f79..81d9dc0ed 100644 --- a/examples/plasma.p8 +++ b/examples/plasma.p8 @@ -8,9 +8,6 @@ ; Cleanup and porting to C by Ullrich von Bassewitz. ; Converted to prog8 by Irmen de Jong. -; TODO the random charset is all wrong -; TODO why has the prg become bigger since register args? - main { const uword SCREEN1 = $E000 diff --git a/examples/test.p8 b/examples/test.p8 index a07378213..5e94842d4 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,8 +4,20 @@ %zeropage basicsafe ; builtin functions converted to new call convention: -; abs (int + float) - +; abs +; atan +; ceil +; cos (float), cos8, cos8u, cos16, cos16u +; deg +; floor +; ln +; log2 +; rad +; round +; sgn (float), sgn (integers) +; sin (float), sin8, sin8u, sin16, sin16u +; sqrt (float), sqrt16 +; tan main { @@ -22,107 +34,84 @@ main { float fzero=0.0 float rr=0.0 - rr = -4.0 - for ubb in 0 to 20 { - floats.print_f(abs(rr)) + ; TODO byte -> word conversion is wrong + + rr = 2.0 + for ubb in 0 to 10 { + floats.print_f(tan(rr)) txt.chrout('\n') rr += 0.5 } txt.chrout('\n') txt.chrout('\n') - rr = -2.0 - for ubb in 0 to 20 { - floats.print_f(abs(rr)+fzero) + rr = 2.0 + for ubb in 0 to 10 { + floats.print_f(tan(rr)+fzero) txt.chrout('\n') rr += 0.5 } txt.chrout('\n') txt.chrout('\n') - for ubb in 0 to 20 { - txt.print_ub(abs(ubb)) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - for ubb in 0 to 20 { - txt.print_ub(abs(ubb)+zerobb) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - for bb in -10 to 10 { - txt.print_b(abs(bb)) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - for bb in -10 to 10 { - txt.print_b(abs(bb)+zerobb) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - for uww in 0 to 20 { - txt.print_uw(abs(uww)) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - for uww in 0 to 20 { - txt.print_uw(abs(uww)+zeroww) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - for ww in -10 to 10 { - txt.print_w(abs(ww)) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - for ww in -10 to 10 { - txt.print_w(abs(ww)+zeroww) - txt.chrout('\n') - } - txt.chrout('\n') - txt.chrout('\n') - - -; for ubb in 0 to 20 { -; floats.print_f(sin(rr)) +; for uww in 0 to 50000 step 10000 { +; txt.print_ub(sqrt16(uww)) ; txt.chrout('\n') -; rr += 0.01 ; } ; txt.chrout('\n') ; txt.chrout('\n') -; for ubb in 0 to 20 { -; floats.print_f(cos(rr)) + +; for ww in -5 to 5 { +; txt.print_b(sgn(ww)+zerobb) ; txt.chrout('\n') -; rr += 0.01 ; } ; txt.chrout('\n') ; txt.chrout('\n') -; for ubb in 0 to 20 { -; floats.print_f(tan(rr)) + +; for ww in -2 to 2 { +; txt.print_b(sgn(ww)) ; txt.chrout('\n') -; rr += 0.01 ; } ; txt.chrout('\n') ; txt.chrout('\n') -; for ubb in 0 to 20 { -; floats.print_f(atan(rr)) +; +; for ww in -2 to 2 { +; txt.print_b(sgn(ww)+zerobb) ; txt.chrout('\n') -; rr += 0.01 ; } +; txt.chrout('\n') +; txt.chrout('\n') +; +; for bb in -2 to 2 { +; txt.print_b(sgn(bb)) +; txt.chrout('\n') +; } +; txt.chrout('\n') +; txt.chrout('\n') +; +; for bb in -2 to 2 { +; txt.print_b(sgn(bb)+zerobb) +; txt.chrout('\n') +; } +; txt.chrout('\n') +; txt.chrout('\n') + + +; for bb in -5 to 5 { +; txt.print_b(sgn(bb)) +; txt.chrout('\n') +; } +; txt.chrout('\n') +; txt.chrout('\n') +; +; for bb in -5 to 5 { +; txt.print_b(sgn(bb)+zerobb) +; txt.chrout('\n') +; } +; txt.chrout('\n') +; txt.chrout('\n') +; + testX()