From 800b5b2a43d78203f04a31948de9db70ba1f82e4 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 5 Nov 2020 01:26:45 +0100 Subject: [PATCH] cleaning up and correcting cc for builtin functions --- compiler/res/prog8lib/c64/floats.asm | 328 +------------ compiler/res/prog8lib/c64/floats.p8 | 1 + compiler/res/prog8lib/c64/floats_funcs.asm | 437 ++++++++++++++++++ compiler/res/prog8lib/prog8_funcs.asm | 44 ++ compiler/res/prog8lib/prog8_lib.asm | 215 ++------- compiler/res/prog8lib/prog8_lib.p8 | 1 + .../compiler/target/c64/codegen/AsmGen.kt | 1 + .../c64/codegen/BuiltinFunctionsAsmGen.kt | 121 +++-- .../src/prog8/functions/BuiltinFunctions.kt | 6 +- examples/test.p8 | 402 +++++++++++----- 10 files changed, 888 insertions(+), 668 deletions(-) create mode 100644 compiler/res/prog8lib/c64/floats_funcs.asm create mode 100644 compiler/res/prog8lib/prog8_funcs.asm diff --git a/compiler/res/prog8lib/c64/floats.asm b/compiler/res/prog8lib/c64/floats.asm index 83414cdb8..4bc585875 100644 --- a/compiler/res/prog8lib/c64/floats.asm +++ b/compiler/res/prog8lib/c64/floats.asm @@ -61,7 +61,7 @@ stack_b2float .proc lda P8ESTACK_LO,x stx P8ZP_SCRATCH_REG jsr FREADSA - jmp push_fac1_as_result + jmp push_fac1._internal .pend stack_w2float .proc @@ -71,7 +71,7 @@ stack_w2float .proc lda P8ESTACK_HI,x stx P8ZP_SCRATCH_REG jsr GIVAYF - jmp push_fac1_as_result + jmp push_fac1._internal .pend stack_ub2float .proc @@ -82,7 +82,7 @@ stack_ub2float .proc tay lda #0 jsr GIVAYF - jmp push_fac1_as_result + jmp push_fac1._internal .pend stack_uw2float .proc @@ -92,7 +92,7 @@ stack_uw2float .proc ldy P8ESTACK_HI,x stx P8ZP_SCRATCH_REG jsr GIVUAYFAY - jmp push_fac1_as_result + jmp push_fac1._internal .pend stack_float2w .proc ; also used for float2b @@ -173,7 +173,6 @@ 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 @@ -183,16 +182,6 @@ pop_float_fac1 .proc jmp MOVFM .pend -pop_float_fac2 .proc - ; -- pops float from stack into FAC2 - lda #fmath_float1 - jsr pop_float - lda #fmath_float1 - jmp CONUPK - .pend - copy_float .proc ; -- 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. @@ -260,15 +249,9 @@ fmath_float2 .byte 0,0,0,0,0 ; storage for a mflpt5 value push_fac1 .proc - ; -- push the float in FAC1 onto the stack, usable as standalone + ; -- push the float in FAC1 onto the stack stx P8ZP_SCRATCH_REG - jmp push_fac1_as_result - .pend - - -push_fac1_as_result .proc - ; -- push the float in FAC1 onto the stack, and return from calculation - ldx #fmath_float1 jsr MOVMF lda #fmath_float2 jsr FPWR - ldx P8ZP_SCRATCH_REG - jmp push_fac1_as_result + jmp push_fac1._internal .pend div_f .proc @@ -303,7 +286,7 @@ div_f .proc lda #fmath_float1 jsr FDIV - jmp push_fac1_as_result + jmp push_fac1._internal .pend add_f .proc @@ -313,7 +296,7 @@ add_f .proc lda #fmath_float1 jsr FADD - jmp push_fac1_as_result + jmp push_fac1._internal .pend sub_f .proc @@ -323,7 +306,7 @@ sub_f .proc lda #fmath_float1 jsr FSUB - jmp push_fac1_as_result + jmp push_fac1._internal .pend mul_f .proc @@ -333,7 +316,7 @@ mul_f .proc lda #fmath_float1 jsr FMULT - jmp push_fac1_as_result + jmp push_fac1._internal .pend neg_f .proc @@ -344,18 +327,6 @@ neg_f .proc rts .pend -abs_f_cc .proc - ; -- push abs(AY) on stack - jsr abs_f_into_fac1_cc - jmp push_fac1 - .pend - -abs_f_into_fac1_cc .proc - ; -- FAC1 = abs(AY) - jsr floats.MOVFM - jmp floats.ABS - .pend - equal_f .proc ; -- are the two mflpt5 numbers on the stack identical? inx @@ -454,268 +425,6 @@ _return_true lda #1 bne _return_result .pend -func_rndf_into_fac1 .proc - stx P8ZP_SCRATCH_REG - lda #1 - jsr FREADSA - jsr RND ; rng into fac1 - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_sin_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr SIN - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_cos_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr COS - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_tan_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr TAN - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_atan_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr ATN - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_ln_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr LOG - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_log2_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr LOG - jsr MOVEF - lda #FL_LOG2 - jsr MOVFM - jsr FDIVT - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_sqrt_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr SQR - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_rad_into_fac1 .proc - ; -- convert degrees to radians (d * pi / 180) - jsr MOVFM - stx P8ZP_SCRATCH_REG - lda #<_pi_div_180 - ldy #>_pi_div_180 - jsr FMULT - ldx P8ZP_SCRATCH_REG - rts -_pi_div_180 .byte 123, 14, 250, 53, 18 ; pi / 180 - .pend - -func_deg_into_fac1 .proc - ; -- convert radians to degrees (d * (1/ pi * 180)) - jsr MOVFM - stx P8ZP_SCRATCH_REG - lda #<_one_over_pi_div_180 - ldy #>_one_over_pi_div_180 - jsr FMULT - ldx P8ZP_SCRATCH_REG - rts -_one_over_pi_div_180 .byte 134, 101, 46, 224, 211 ; 1 / (pi * 180) - .pend - -func_round_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr FADDH - jsr INT - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_floor_into_fac1 .proc - jsr MOVFM - stx P8ZP_SCRATCH_REG - jsr INT - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_ceil_into_fac1 .proc - ; -- ceil: tr = int(f); if tr==f -> return else return tr+1 - jsr MOVFM - stx P8ZP_SCRATCH_REG - ldx #fmath_float1 - jsr MOVMF - jsr INT - lda #fmath_float1 - jsr FCOMP - cmp #0 - beq + - lda #FL_ONE_const - jsr FADD -+ ldx P8ZP_SCRATCH_REG - rts - .pend - -func_any_f_into_A .proc - jsr func_any_f -_popA inx - lda P8ESTACK_LO,x - rts - .pend - -func_all_f_into_A .proc - jsr func_all_f - jmp func_any_f_into_A._popA - .pend - -func_any_f .proc - inx - lda P8ESTACK_LO,x ; array size - sta P8ZP_SCRATCH_B1 - asl a - asl a - clc - adc P8ZP_SCRATCH_B1 ; times 5 because of float - jmp prog8_lib.func_any_b._entry - .pend - -func_all_f .proc - inx - jsr prog8_lib.peek_address - lda P8ESTACK_LO,x ; array size - sta P8ZP_SCRATCH_B1 - asl a - asl a - clc - adc P8ZP_SCRATCH_B1 ; times 5 because of float - tay - dey -- lda (P8ZP_SCRATCH_W1),y - clc - dey - adc (P8ZP_SCRATCH_W1),y - dey - adc (P8ZP_SCRATCH_W1),y - dey - adc (P8ZP_SCRATCH_W1),y - dey - adc (P8ZP_SCRATCH_W1),y - dey - cmp #0 - beq + - cpy #255 - bne - - lda #1 - sta P8ESTACK_LO+1,x - rts -+ sta P8ESTACK_LO+1,x - rts - .pend - -func_max_f_into_fac1 .proc - lda #255 - sta _minmax_cmp+1 - lda #<_largest_neg_float - ldy #>_largest_neg_float -_minmax_entry jsr MOVFM - jsr prog8_lib.pop_array_and_lengthmin1Y - stx floats_store_reg -- sty P8ZP_SCRATCH_REG - lda P8ZP_SCRATCH_W1 - ldy P8ZP_SCRATCH_W1+1 - jsr FCOMP -_minmax_cmp cmp #255 ; modified - bne + - lda P8ZP_SCRATCH_W1 - ldy P8ZP_SCRATCH_W1+1 - jsr MOVFM -+ lda P8ZP_SCRATCH_W1 - clc - adc #5 - sta P8ZP_SCRATCH_W1 - bcc + - inc P8ZP_SCRATCH_W1+1 -+ ldy P8ZP_SCRATCH_REG - dey - cpy #255 - bne - - ldx floats_store_reg - rts -_largest_neg_float .byte 255,255,255,255,255 ; largest negative float -1.7014118345e+38 - .pend - -func_min_f_into_fac1 .proc - lda #1 - sta func_max_f_into_fac1._minmax_cmp+1 - lda #<_largest_pos_float - ldy #>_largest_pos_float - jmp func_max_f_into_fac1._minmax_entry -_largest_pos_float .byte 255,127,255,255,255 ; largest positive float - rts - .pend - -func_sum_f_into_fac1 .proc - lda #FL_ZERO_const - jsr MOVFM - jsr prog8_lib.pop_array_and_lengthmin1Y - stx floats_store_reg -- sty P8ZP_SCRATCH_REG - lda P8ZP_SCRATCH_W1 - ldy P8ZP_SCRATCH_W1+1 - jsr FADD - ldy P8ZP_SCRATCH_REG - dey - cpy #255 - beq + - lda P8ZP_SCRATCH_W1 - clc - adc #5 - sta P8ZP_SCRATCH_W1 - bcc - - inc P8ZP_SCRATCH_W1+1 - bne - -+ ldx floats_store_reg - rts - .pend - -sign_f_cc .proc - jsr MOVFM - jsr SIGN - sta P8ESTACK_LO,x - dex - rts - .pend - set_array_float_from_fac1 .proc ; -- set the float in FAC1 in the array (index in A, array in P8ZP_SCRATCH_W1) sta P8ZP_SCRATCH_B1 @@ -775,16 +484,3 @@ set_array_float .proc .pend -swap_floats .proc - ; -- swap floats pointed to by SCRATCH_ZPWORD1, SCRATCH_ZPWORD2 - ldy #4 -- lda (P8ZP_SCRATCH_W1),y - pha - lda (P8ZP_SCRATCH_W2),y - sta (P8ZP_SCRATCH_W1),y - pla - sta (P8ZP_SCRATCH_W2),y - dey - bpl - - rts - .pend diff --git a/compiler/res/prog8lib/c64/floats.p8 b/compiler/res/prog8lib/c64/floats.p8 index 3e1de1fed..fdc56960d 100644 --- a/compiler/res/prog8lib/c64/floats.p8 +++ b/compiler/res/prog8lib/c64/floats.p8 @@ -213,5 +213,6 @@ sub print_f (float value) { } %asminclude "library:c64/floats.asm", "" +%asminclude "library:c64/floats_funcs.asm", "" } diff --git a/compiler/res/prog8lib/c64/floats_funcs.asm b/compiler/res/prog8lib/c64/floats_funcs.asm new file mode 100644 index 000000000..91002b27a --- /dev/null +++ b/compiler/res/prog8lib/c64/floats_funcs.asm @@ -0,0 +1,437 @@ +; --- floating point builtin functions + + +abs_f_stack .proc + ; -- push abs(AY) on stack + jsr floats.MOVFM + jsr floats.ABS + jmp push_fac1 + .pend + +abs_f_fac1 .proc + ; -- FAC1 = abs(AY) + jsr floats.MOVFM + jmp floats.ABS + .pend + +func_atan_stack .proc + jsr func_atan_fac1 + jmp push_fac1 + .pend + +func_atan_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr ATN + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_ceil_stack .proc + jsr func_ceil_fac1 + jmp push_fac1 + .pend + +func_ceil_fac1 .proc + ; -- ceil: tr = int(f); if tr==f -> return else return tr+1 + jsr MOVFM + stx P8ZP_SCRATCH_REG + ldx #fmath_float1 + jsr MOVMF + jsr INT + lda #fmath_float1 + jsr FCOMP + cmp #0 + beq + + lda #FL_ONE_const + jsr FADD ++ ldx P8ZP_SCRATCH_REG + rts + .pend + +func_floor_stack .proc + jsr func_floor_fac1 + jmp push_fac1 + .pend + +func_floor_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr INT + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_round_stack .proc + jsr func_round_fac1 + jmp push_fac1 + .pend + +func_round_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr FADDH + jsr INT + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_sin_stack .proc + jsr func_sin_fac1 + jmp push_fac1 + .pend + +func_sin_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr SIN + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_cos_stack .proc + jsr func_cos_fac1 + jmp push_fac1 + .pend + +func_cos_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr COS + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_tan_stack .proc + jsr func_tan_fac1 + jmp push_fac1 + .pend + +func_tan_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr TAN + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_rad_stack .proc + jsr func_rad_fac1 + jmp push_fac1 + .pend + +func_rad_fac1 .proc + ; -- convert degrees to radians (d * pi / 180) + jsr MOVFM + stx P8ZP_SCRATCH_REG + lda #<_pi_div_180 + ldy #>_pi_div_180 + jsr FMULT + ldx P8ZP_SCRATCH_REG + rts +_pi_div_180 .byte 123, 14, 250, 53, 18 ; pi / 180 + .pend + +func_deg_stack .proc + jsr func_deg_fac1 + jmp push_fac1 + .pend + +func_deg_fac1 .proc + ; -- convert radians to degrees (d * (1/ pi * 180)) + jsr MOVFM + stx P8ZP_SCRATCH_REG + lda #<_one_over_pi_div_180 + ldy #>_one_over_pi_div_180 + jsr FMULT + ldx P8ZP_SCRATCH_REG + rts +_one_over_pi_div_180 .byte 134, 101, 46, 224, 211 ; 1 / (pi * 180) + .pend + +func_ln_stack .proc + jsr func_ln_fac1 + jmp push_fac1 + .pend + +func_ln_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr LOG + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_log2_stack .proc + jsr func_log2_fac1 + jmp push_fac1 + .pend + +func_log2_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr LOG + jsr MOVEF + lda #FL_LOG2 + jsr MOVFM + jsr FDIVT + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_sign_f_stack .proc + jsr func_sign_f_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sign_f_into_A .proc + jsr MOVFM + jmp SIGN + .pend + +func_sqrt_stack .proc + jsr func_sqrt_fac1 + jmp push_fac1 + .pend + +func_sqrt_fac1 .proc + jsr MOVFM + stx P8ZP_SCRATCH_REG + jsr SQR + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_rndf_stack .proc + jsr func_rndf_fac1 + jmp push_fac1 + .pend + +func_rndf_fac1 .proc + stx P8ZP_SCRATCH_REG + lda #1 + jsr FREADSA + jsr RND ; rng into fac1 + ldx P8ZP_SCRATCH_REG + rts + .pend + +func_swap_f .proc + ; -- swap floats pointed to by SCRATCH_ZPWORD1, SCRATCH_ZPWORD2 + ldy #4 +- lda (P8ZP_SCRATCH_W1),y + pha + lda (P8ZP_SCRATCH_W2),y + sta (P8ZP_SCRATCH_W1),y + pla + sta (P8ZP_SCRATCH_W2),y + dey + bpl - + rts + .pend + +func_reverse_f .proc + ; --- reverse an array of floats (array in P8ZP_SCRATCH_W1, num elements in A) +_left_index = P8ZP_SCRATCH_W2 +_right_index = P8ZP_SCRATCH_W2+1 +_loop_count = P8ZP_SCRATCH_REG + pha + jsr a_times_5 + sec + sbc #5 + sta _right_index + lda #0 + sta _left_index + pla + lsr a + sta _loop_count +_loop ; push the left indexed float on the stack + ldy _left_index + lda (P8ZP_SCRATCH_W1),y + pha + iny + lda (P8ZP_SCRATCH_W1),y + pha + iny + lda (P8ZP_SCRATCH_W1),y + pha + iny + lda (P8ZP_SCRATCH_W1),y + pha + iny + lda (P8ZP_SCRATCH_W1),y + pha + ; copy right index float to left index float + ldy _right_index + lda (P8ZP_SCRATCH_W1),y + ldy _left_index + sta (P8ZP_SCRATCH_W1),y + inc _left_index + inc _right_index + ldy _right_index + lda (P8ZP_SCRATCH_W1),y + ldy _left_index + sta (P8ZP_SCRATCH_W1),y + inc _left_index + inc _right_index + ldy _right_index + lda (P8ZP_SCRATCH_W1),y + ldy _left_index + sta (P8ZP_SCRATCH_W1),y + inc _left_index + inc _right_index + ldy _right_index + lda (P8ZP_SCRATCH_W1),y + ldy _left_index + sta (P8ZP_SCRATCH_W1),y + inc _left_index + inc _right_index + ldy _right_index + lda (P8ZP_SCRATCH_W1),y + ldy _left_index + sta (P8ZP_SCRATCH_W1),y + ; pop the float off the stack into the right index float + ldy _right_index + pla + sta (P8ZP_SCRATCH_W1),y + dey + pla + sta (P8ZP_SCRATCH_W1),y + dey + pla + sta (P8ZP_SCRATCH_W1),y + dey + pla + sta (P8ZP_SCRATCH_W1),y + dey + pla + sta (P8ZP_SCRATCH_W1),y + inc _left_index + lda _right_index + sec + sbc #9 + sta _right_index + dec _loop_count + bne _loop + rts + + .pend + + + +a_times_5 .proc + sta P8ZP_SCRATCH_B1 + asl a + asl a + clc + adc P8ZP_SCRATCH_B1 + rts + .pend + +func_any_f_into_A .proc + jsr a_times_5 + jmp prog8_lib.func_any_b_into_A + .pend + +func_all_f_into_A .proc + jsr a_times_5 + jmp prog8_lib.func_all_b_into_A + .pend + +func_any_f_stack .proc + jsr a_times_5 + jmp prog8_lib.func_any_b_stack + .pend + +func_all_f_stack .proc + jsr a_times_5 + jmp prog8_lib.func_all_b_stack + .pend + +func_max_f_stack .proc + jsr func_max_f_fac1 + jmp push_fac1 + .pend + +func_max_f_fac1 .proc + ; -- max(array) -> fac1, array in P8ZP_SCRATCH_W1, num elts in A +_loop_count = P8ZP_SCRATCH_REG + stx floats_store_reg + sta _loop_count + lda #255 + sta _minmax_cmp+1 ; modifying + lda #<_largest_neg_float + ldy #>_largest_neg_float +_minmax_entry jsr MOVFM +- lda P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + jsr FCOMP +_minmax_cmp cmp #255 ; modified + bne + + lda P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + jsr MOVFM ++ lda P8ZP_SCRATCH_W1 + clc + adc #5 + sta P8ZP_SCRATCH_W1 + bcc + + inc P8ZP_SCRATCH_W1+1 ++ dec _loop_count + bne - + ldx floats_store_reg + rts +_largest_neg_float .byte 255,255,255,255,255 ; largest negative float -1.7014118345e+38 + .pend + +func_min_f_stack .proc + jsr func_min_f_fac1 + jmp push_fac1 + .pend + +func_min_f_fac1 .proc + ; -- min(array) -> fac1, array in P8ZP_SCRATCH_W1, num elts in A + sta func_max_f_fac1._loop_count + lda #1 + sta func_max_f_fac1._minmax_cmp+1 + lda #<_largest_pos_float + ldy #>_largest_pos_float + jmp func_max_f_fac1._minmax_entry +_largest_pos_float .byte 255,127,255,255,255 ; largest positive float + rts + .pend + + +func_sum_f_stack .proc + jsr func_sum_f_fac1 + jmp push_fac1 + .pend + +func_sum_f_fac1 .proc + ; -- sum(array) -> fac1, array in P8ZP_SCRATCH_W1, num elts in A +_loop_count = P8ZP_SCRATCH_REG + stx floats_store_reg + sta _loop_count + lda #FL_ZERO_const + jsr MOVFM +- lda P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + jsr FADD + lda P8ZP_SCRATCH_W1 + clc + adc #5 + sta P8ZP_SCRATCH_W1 + bcc + + inc P8ZP_SCRATCH_W1+1 ++ dec _loop_count + bne - + ldx floats_store_reg + rts + .pend diff --git a/compiler/res/prog8lib/prog8_funcs.asm b/compiler/res/prog8lib/prog8_funcs.asm new file mode 100644 index 000000000..ccd728384 --- /dev/null +++ b/compiler/res/prog8lib/prog8_funcs.asm @@ -0,0 +1,44 @@ +; ---- builtin functions + + +func_any_b_stack .proc + jsr func_any_b_into_A +_pushA sta P8ESTACK_LO,x + dex + rts + .pend + +func_all_b_stack .proc + jsr func_all_b_into_A + jmp func_any_b_stack._pushA + .pend + +func_any_b_into_A .proc + ; -- any(array), array in P8ZP_SCRATCH_W1, num bytes in A + sta _cmp_mod+1 ; self-modifying code + ldy #0 +- lda (P8ZP_SCRATCH_W1),y + bne _got_any + iny +_cmp_mod cpy #255 ; modified + bne - + lda #0 + rts +_got_any lda #1 + rts + .pend + + +func_all_b_into_A .proc + ; -- all(array), array in P8ZP_SCRATCH_W1, num bytes in A + sta _cmp_mod+1 ; self-modifying code + ldy #0 +- lda (P8ZP_SCRATCH_W1),y + beq _got_not_all + iny +_cmp_mod cpy #255 ; modified + bne - + lda #1 +_got_not_all rts + .pend + diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 1e3572d07..8032d32cd 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -893,75 +893,27 @@ peek_address .proc rts .pend -func_any_b_into_A .proc - jsr func_any_b -_popA inx - lda P8ESTACK_LO,x - rts - .pend - -func_all_b_into_A .proc - jsr func_all_b - jmp func_any_b_into_A._popA - .pend - func_any_w_into_A .proc - jsr func_any_w + jsr func_any_w_cc jmp func_any_b_into_A._popA .pend func_all_w_into_A .proc - jsr func_all_w + jsr func_all_w_cc jmp func_any_b_into_A._popA .pend -func_any_b .proc - inx - lda P8ESTACK_LO,x ; array size -_entry sta _cmp_mod+1 ; self-modifying code - jsr peek_address - ldy #0 -- lda (P8ZP_SCRATCH_W1),y - bne _got_any - iny -_cmp_mod cpy #255 ; modified - bne - - lda #0 - sta P8ESTACK_LO+1,x - rts -_got_any lda #1 - sta P8ESTACK_LO+1,x - rts - .pend - -func_any_w .proc +func_any_w_cc .proc + ; TODO args not via stack inx lda P8ESTACK_LO,x ; array size asl a ; times 2 because of word - jmp func_any_b._entry + jmp func_any_b_cc._entry .pend -func_all_b .proc - inx - lda P8ESTACK_LO,x ; array size - sta _cmp_mod+1 ; self-modifying code - jsr peek_address - ldy #0 -- lda (P8ZP_SCRATCH_W1),y - beq _got_not_all - iny -_cmp_mod cpy #255 ; modified - bne - - lda #1 - sta P8ESTACK_LO+1,x - rts -_got_not_all lda #0 - sta P8ESTACK_LO+1,x - rts - .pend - -func_all_w .proc +func_all_w_cc .proc + ; TODO arg not via stack inx lda P8ESTACK_LO,x ; array size asl a ; times 2 because of word @@ -985,7 +937,8 @@ _cmp_mod cpy #255 ; modified rts .pend -func_max_ub .proc +func_max_ub_cc .proc + ; TODO args not via stack jsr pop_array_and_lengthmin1Y lda #0 sta P8ZP_SCRATCH_B1 @@ -1002,7 +955,8 @@ func_max_ub .proc rts .pend -func_max_b .proc +func_max_b_cc .proc + ; TODO args not via stack jsr pop_array_and_lengthmin1Y lda #-128 sta P8ZP_SCRATCH_B1 @@ -1023,7 +977,8 @@ func_max_b .proc rts .pend -func_max_uw .proc +func_max_uw_bb .proc + ; TODO args not via stack lda #0 sta _result_maxuw sta _result_maxuw+1 @@ -1060,7 +1015,8 @@ _lesseq dey _result_maxuw .word 0 .pend -func_max_w .proc +func_max_w_cc .proc + ; TODO args not via stack lda #0 sta _result_maxw lda #$80 @@ -1099,7 +1055,8 @@ _result_maxw .word 0 .pend -func_sum_b .proc +func_sum_b_cc .proc + ; TODO args not via stack jsr pop_array_and_lengthmin1Y lda #0 sta P8ESTACK_LO,x @@ -1123,7 +1080,8 @@ _loop lda (P8ZP_SCRATCH_W1),y rts .pend -func_sum_ub .proc +func_sum_ub_cc .proc + ; TODO args not via stack jsr pop_array_and_lengthmin1Y lda #0 sta P8ESTACK_HI,x @@ -1139,7 +1097,8 @@ func_sum_ub .proc rts .pend -func_sum_uw .proc +func_sum_uw_cc .proc + ; TODO args not via stack jsr pop_array_and_lengthmin1Y tya asl a @@ -1164,8 +1123,8 @@ func_sum_uw .proc rts .pend -func_sum_w .proc - jmp func_sum_uw +func_sum_w_cc .proc + jmp func_sum_uw_cc .pend @@ -1182,29 +1141,29 @@ pop_array_and_lengthmin1Y .proc .pend func_min_ub_into_A .proc - jsr func_min_ub + jsr func_min_ub_cc _popA inx lda P8ESTACK_LO,x rts .pend func_min_b_into_A .proc - jsr func_min_b + jsr func_min_b_cc jmp func_min_ub_into_A._popA .pend func_max_ub_into_A .proc - jsr func_max_ub + jsr func_max_ub_cc jmp func_min_ub_into_A._popA .pend func_max_b_into_A .proc - jsr func_max_b + jsr func_max_b_cc jmp func_min_ub_into_A._popA .pend func_sum_ub_into_AY .proc - jsr func_sum_ub + jsr func_sum_ub_cc _popAY inx lda P8ESTACK_LO,x ldy P8ESTACK_HI,x @@ -1212,42 +1171,43 @@ _popAY inx .pend func_sum_b_into_AY .proc - jsr func_sum_b + jsr func_sum_b_cc jmp func_sum_ub_into_AY._popAY .pend func_min_uw_into_AY .proc - jsr func_min_uw + jsr func_min_uw_cc jmp func_sum_ub_into_AY._popAY .pend func_min_w_into_AY .proc - jsr func_min_w + jsr func_min_w_cc jmp func_sum_ub_into_AY._popAY .pend func_max_uw_into_AY .proc - jsr func_max_uw + jsr func_max_uw_cc jmp func_sum_ub_into_AY._popAY .pend func_max_w_into_AY .proc - jsr func_max_w + jsr func_max_w_cc jmp func_sum_ub_into_AY._popAY .pend func_sum_uw_into_AY .proc - jsr func_sum_uw + jsr func_sum_uw_cc jmp func_sum_ub_into_AY._popAY .pend func_sum_w_into_AY .proc - jsr func_sum_w + jsr func_sum_w_cc jmp func_sum_ub_into_AY._popAY .pend -func_min_ub .proc +func_min_ub_cc .proc + ; TODO args not via stack jsr pop_array_and_lengthmin1Y lda #255 sta P8ZP_SCRATCH_B1 @@ -1265,7 +1225,8 @@ func_min_ub .proc .pend -func_min_b .proc +func_min_b_cc .proc + ; TODO args not via stack jsr pop_array_and_lengthmin1Y lda #127 sta P8ZP_SCRATCH_B1 @@ -1286,7 +1247,8 @@ func_min_b .proc rts .pend -func_min_uw .proc +func_min_uw_cc .proc + ; TODO args not via stack lda #$ff sta _result_minuw sta _result_minuw+1 @@ -1323,7 +1285,8 @@ _gtequ dey _result_minuw .word 0 .pend -func_min_w .proc +func_min_w_cc .proc + ; TODO not via stack lda #$ff sta _result_minw lda #$7f @@ -1827,98 +1790,6 @@ _loop ldy _index_right .pend -reverse_f .proc - ; --- reverse an array of floats -_left_index = P8ZP_SCRATCH_W2 -_right_index = P8ZP_SCRATCH_W2+1 -_loop_count = P8ZP_SCRATCH_REG - pha - sta P8ZP_SCRATCH_REG - asl a - asl a - clc - adc P8ZP_SCRATCH_REG ; *5 because float - sec - sbc #5 - sta _right_index - lda #0 - sta _left_index - pla - lsr a - sta _loop_count -_loop ; push the left indexed float on the stack - ldy _left_index - lda (P8ZP_SCRATCH_W1),y - pha - iny - lda (P8ZP_SCRATCH_W1),y - pha - iny - lda (P8ZP_SCRATCH_W1),y - pha - iny - lda (P8ZP_SCRATCH_W1),y - pha - iny - lda (P8ZP_SCRATCH_W1),y - pha - ; copy right index float to left index float - ldy _right_index - lda (P8ZP_SCRATCH_W1),y - ldy _left_index - sta (P8ZP_SCRATCH_W1),y - inc _left_index - inc _right_index - ldy _right_index - lda (P8ZP_SCRATCH_W1),y - ldy _left_index - sta (P8ZP_SCRATCH_W1),y - inc _left_index - inc _right_index - ldy _right_index - lda (P8ZP_SCRATCH_W1),y - ldy _left_index - sta (P8ZP_SCRATCH_W1),y - inc _left_index - inc _right_index - ldy _right_index - lda (P8ZP_SCRATCH_W1),y - ldy _left_index - sta (P8ZP_SCRATCH_W1),y - inc _left_index - inc _right_index - ldy _right_index - lda (P8ZP_SCRATCH_W1),y - ldy _left_index - sta (P8ZP_SCRATCH_W1),y - ; pop the float off the stack into the right index float - ldy _right_index - pla - sta (P8ZP_SCRATCH_W1),y - dey - pla - sta (P8ZP_SCRATCH_W1),y - dey - pla - sta (P8ZP_SCRATCH_W1),y - dey - pla - sta (P8ZP_SCRATCH_W1),y - dey - pla - sta (P8ZP_SCRATCH_W1),y - inc _left_index - lda _right_index - sec - sbc #9 - sta _right_index - dec _loop_count - bne _loop - rts - - .pend - - reverse_w .proc ; --- reverse an array of words (in-place) ; inputs: pointer to array in P8ZP_SCRATCH_W1, length in A diff --git a/compiler/res/prog8lib/prog8_lib.p8 b/compiler/res/prog8lib/prog8_lib.p8 index 4424c1d3e..18a9f7436 100644 --- a/compiler/res/prog8lib/prog8_lib.p8 +++ b/compiler/res/prog8lib/prog8_lib.p8 @@ -6,4 +6,5 @@ prog8_lib { %asminclude "library:prog8_lib.asm", "" + %asminclude "library:prog8_funcs.asm", "" } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 9d162d751..62f637853 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -1179,6 +1179,7 @@ $counterVar .byte 0""") out(" lda #<${asmVar} | ldy #>${asmVar} | jsr floats.MOVFM") } else -> { + // todo evaluate into fac1 instead of stack translateExpression(returnvalue) out(" jsr floats.pop_float_fac1") } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 06ac5c1ac..40665c880 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -1,6 +1,7 @@ package prog8.compiler.target.c64.codegen import prog8.ast.IFunctionCall +import prog8.ast.Node import prog8.ast.Program import prog8.ast.base.* import prog8.ast.expressions.* @@ -216,14 +217,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val """) } DataType.ARRAY_F -> { - // TODO cc asmgen.out(""" lda #<$varName ldy #>$varName sta P8ZP_SCRATCH_W1 sty P8ZP_SCRATCH_W1+1 lda #$numElements - jsr prog8_lib.reverse_f_cc + jsr floats.func_reverse_f """) } else -> throw AssemblyError("weird type") @@ -465,9 +465,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) { translateArguments(fcall.args, func) - asmgen.out(" jsr floats.func_${func.name}_into_fac1") if(resultToStack) - asmgen.out(" jsr floats.push_fac1") + asmgen.out(" jsr floats.func_${func.name}_stack") + else + asmgen.out(" jsr floats.func_${func.name}_fac1") } private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) { @@ -479,7 +480,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val 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") + DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_stack") else -> throw AssemblyError("weird type $dt") } } else { @@ -488,20 +489,20 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.BYTE -> asmgen.out(" jsr math.sign_b_into_A") DataType.UWORD -> asmgen.out(" jsr math.sign_uw_into_A") DataType.WORD -> asmgen.out(" jsr math.sign_w_into_A") - DataType.FLOAT -> asmgen.out(" jsr floats.pop_float_fac1 | jsr floats.SIGN") + DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_into_A") else -> throw AssemblyError("weird type $dt") } } } private fun funcAnyAll(fcall: IFunctionCall, function: FSignature, resultToStack: Boolean) { - outputPushAddressAndLenghtOfArray(fcall.args[0]) + outputAddressAndLenghtOfArray(fcall.args[0]) val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_b") - DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w") - DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f") + DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_cc") + DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_cc") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_stack") else -> throw AssemblyError("weird type $dt") } } else { @@ -515,15 +516,15 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } private fun funcMinMax(fcall: IFunctionCall, function: FSignature, resultToStack: Boolean) { - outputPushAddressAndLenghtOfArray(fcall.args[0]) + outputAddressAndLenghtOfArray(fcall.args[0]) val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_ub") - DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${function.name}_b") - DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${function.name}_uw") - DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w") - DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_into_fac1 | jsr floats.push_fac1") + DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_ub_cc") + DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_cc") + DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${function.name}_uw_cc") + DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_cc") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_stack") else -> throw AssemblyError("weird type $dt") } } else { @@ -532,22 +533,22 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_into_A") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${function.name}_uw_into_AY") DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_into_AY") - DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_into_fac1") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_fac1") else -> throw AssemblyError("weird type $dt") } } } private fun funcSum(fcall: IFunctionCall, resultToStack: Boolean) { - outputPushAddressAndLenghtOfArray(fcall.args[0]) + outputAddressAndLenghtOfArray(fcall.args[0]) val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_sum_ub") - DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b") - DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw") - DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w") - DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f_into_fac1 | jsr floats.push_fac1") + DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_sum_ub_cc") + DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b_cc") + DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw_cc") + DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w_cc") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f_stack") else -> throw AssemblyError("weird type $dt") } } else { @@ -556,7 +557,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b_into_AY") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw_into_AY") DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w_into_AY") - DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f_into_fac1") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f_fac1") else -> throw AssemblyError("weird type $dt") } } @@ -616,7 +617,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val sta P8ZP_SCRATCH_W2 lda #>$secondName sta P8ZP_SCRATCH_W2+1 - jsr floats.swap_floats + jsr floats.func_swap_f """) return } @@ -944,14 +945,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when (dt) { in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_cc") in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_cc") - DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_cc") + DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_stack") else -> throw AssemblyError("weird type") } } else { when (dt) { in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_into_A_cc") in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_into_AY_cc") - DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_into_fac1_cc") + DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_fac1") else -> throw AssemblyError("weird type") } } @@ -976,23 +977,19 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } private fun funcMkword(fcall: IFunctionCall, resultToStack: Boolean) { - // TODO cc - if(resultToStack) { - // trick: push the args in reverse order (lsb first, msb second) this saves some instructions - asmgen.translateExpression(fcall.args[1]) - asmgen.translateExpression(fcall.args[0]) - asmgen.out(" inx | lda P8ESTACK_LO,x | sta P8ESTACK_HI+1,x") - } else { - // TODO some args without stack usage... - // trick: push the args in reverse order (lsb first, msb second) this saves some instructions - asmgen.translateExpression(fcall.args[1]) - asmgen.translateExpression(fcall.args[0]) - asmgen.out(" inx | ldy P8ESTACK_LO,x | inx | lda P8ESTACK_LO,x") - } + var src = AsmAssignSource.fromAstSource(fcall.args[0], program, asmgen) // msb + var tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.Y, null, program, asmgen) + var assign = AsmAssignment(src, tgt, false, (fcall as Node).position) + asmgen.translateNormalAssignment(assign) + src = AsmAssignSource.fromAstSource(fcall.args[1], program, asmgen) // lsb + tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.A, null, program, asmgen) + assign = AsmAssignment(src, tgt, false, (fcall as Node).position) + asmgen.translateNormalAssignment(assign) + if(resultToStack) + asmgen.out(" sta P8ESTACK_LO,x | tya | sta P8ESTACK_HI,x | dex") } private fun funcMsb(fcall: IFunctionCall, resultToStack: Boolean) { - // TODO cc val arg = fcall.args.single() if (arg.inferType(program).typeOrElse(DataType.STRUCT) !in WordDatatypes) throw AssemblyError("msb required word argument") @@ -1001,53 +998,53 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val if (arg is IdentifierReference) { val sourceName = asmgen.asmVariableName(arg) asmgen.out(" lda $sourceName+1") - if(resultToStack) + if (resultToStack) asmgen.out(" sta P8ESTACK_LO,x | dex") } else { - asmgen.translateExpression(arg) // TODO this evalutes onto stack, use registers instead - if(resultToStack) - asmgen.out(" lda P8ESTACK_HI+1,x | sta P8ESTACK_LO+1,x") + val src = AsmAssignSource.fromAstSource(fcall.args.single(), program, asmgen) + val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen) + val assign = AsmAssignment(src, tgt, false, (fcall as Node).position) + asmgen.translateNormalAssignment(assign) + if (resultToStack) + asmgen.out(" tya | sta P8ESTACK_LO,x | dex") else - asmgen.out(" inx | lda P8ESTACK_HI,x") + asmgen.out(" tya") } } private fun funcLsb(fcall: IFunctionCall, resultToStack: Boolean) { - // TODO cc val arg = fcall.args.single() if (arg.inferType(program).typeOrElse(DataType.STRUCT) !in WordDatatypes) throw AssemblyError("lsb required word argument") if (arg is NumericLiteralValue) throw AssemblyError("lsb(const) should have been const-folded away") + if (arg is IdentifierReference) { val sourceName = asmgen.asmVariableName(arg) asmgen.out(" lda $sourceName") - if(resultToStack) + if (resultToStack) asmgen.out(" sta P8ESTACK_LO,x | dex") } else { - // TODO this evalutes onto stack, use registers instead - asmgen.translateExpression(arg) - if(resultToStack) { - // simply ignore the high-byte of what's on the stack now - } else { - asmgen.out(" inx | lda P8ESTACK_LO,x") - } + val src = AsmAssignSource.fromAstSource(fcall.args.single(), program, asmgen) + val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen) + val assign = AsmAssignment(src, tgt, false, (fcall as Node).position) + asmgen.translateNormalAssignment(assign) + if (resultToStack) + asmgen.out(" sta P8ESTACK_LO,x | dex") } } - private fun outputPushAddressAndLenghtOfArray(arg: Expression) { + private fun outputAddressAndLenghtOfArray(arg: Expression) { + // address in P8ZP_SCRATCH_W1, number of elements in A arg as IdentifierReference val identifierName = asmgen.asmVariableName(arg) val size = arg.targetVarDecl(program.namespace)!!.arraysize!!.constIndex()!! asmgen.out(""" lda #<$identifierName - sta P8ESTACK_LO,x - lda #>$identifierName - sta P8ESTACK_HI,x - dex + ldy #>$identifierName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 lda #$size - sta P8ESTACK_LO,x - dex """) } diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index 65cfce235..985f576b6 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -221,10 +221,10 @@ fun builtinFunctionReturnType(function: String, args: List, program: return when (function) { "abs" -> { val dt = args.single().inferType(program) - if(dt.typeOrElse(DataType.STRUCT) in NumericDatatypes) - return dt + return if(dt.typeOrElse(DataType.STRUCT) in NumericDatatypes) + dt else - throw FatalAstException("weird datatype passed to abs $dt") + InferredTypes.InferredType.unknown() } "max", "min" -> { when(val dt = datatypeFromIterableArg(args.single())) { diff --git a/examples/test.p8 b/examples/test.p8 index 5e94842d4..d0f6bab57 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,151 +4,323 @@ %zeropage basicsafe ; builtin functions converted to new call convention: -; 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 +; all functions operating on floating-point and fp arrays. +; +; mkword +; lsb +; msb main { sub start() { - const uword ADDR = $0400 + ubyte[] barr = [1,2,3,4,5,0,4,3,2,1] - ubyte ubb - ubyte zerobb - uword zeroww - uword uww - word ww + ubyte zero=0 + ubyte ub + ubyte ub2 + byte bb + uword uw + + ub = $fe + ub2 = $34 + uw = mkword(ub, ub2) + txt.print_uwhex(uw, true) + txt.chrout('\n') + uw = zero+mkword(ub, ub2)*1+zero + txt.print_uwhex(uw, true) + txt.chrout('\n') + + uw = $fe34 + ub = msb(uw) + txt.print_ubhex(ub, true) + txt.chrout('\n') + ub = zero+msb(uw)*1+zero + txt.print_ubhex(ub, true) + txt.chrout('\n') + + uw = $fe34 + ub = lsb(uw) + txt.print_ubhex(ub, true) + txt.chrout('\n') + ub = zero+lsb(uw)*1+zero + txt.print_ubhex(ub, true) + txt.chrout('\n') + + + + +; ub = min(barr) +; +; ub = zero+min(barr)*1+zero +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = max(barr) +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = zero+max(barr)*1+zero +; txt.print_ub(ub) +; txt.chrout('\n') +; +; uw = sum(barr) +; txt.print_uw(uw) +; txt.chrout('\n') +; +; uw = zero+sum(barr)*1+zero +; txt.print_uw(uw) +; txt.chrout('\n') +; +; ub = any(barr) +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = zero+any(barr)*1 +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = all(barr) +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = zero+all(barr)*1 +; txt.print_ub(ub) +; txt.chrout('\n') + + + + + testX() + } + + sub floatingpoint() { + ubyte[] barr = [1,2,3,4,5,0,4,3,2,1] + float[] flarr = [1.1, 2.2, 3.3, 0.0, -9.9, 5.5, 4.4] + + ubyte zero=0 + ubyte ub + byte bb + uword uw float fl float fzero=0.0 - float rr=0.0 - ; TODO byte -> word conversion is wrong + fl = -9.9 + fl = abs(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = fzero+abs(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') - 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') + fl = 9.9 + fl = atan(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = 9.9 + fl = fzero+atan(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') - 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') + fl = -9.9 + fl = ceil(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = fzero+ceil(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') -; for uww in 0 to 50000 step 10000 { -; txt.print_ub(sqrt16(uww)) -; txt.chrout('\n') -; } -; txt.chrout('\n') -; txt.chrout('\n') + fl = -9.9 + fl = cos(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = fzero+cos(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') -; for ww in -5 to 5 { -; txt.print_b(sgn(ww)+zerobb) -; txt.chrout('\n') -; } -; txt.chrout('\n') -; txt.chrout('\n') + fl = -9.9 + fl = sin(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = fzero+sin(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') -; for ww in -2 to 2 { -; txt.print_b(sgn(ww)) -; txt.chrout('\n') -; } -; txt.chrout('\n') -; txt.chrout('\n') -; -; for ww in -2 to 2 { -; txt.print_b(sgn(ww)+zerobb) -; txt.chrout('\n') -; } -; 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') + fl = 9.9 + fl = tan(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = 9.9 + fl = fzero+tan(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + fl = 3.1415927 + fl = deg(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = 3.1415927 + fl = fzero+deg(fl)*1.0+fzero + floats.print_f(fl) + 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') -; + fl = 90 + fl = rad(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = 90 + fl = fzero+rad(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = floor(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = fzero+floor(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') - testX() + fl = 3.1415927 + fl = ln(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = 3.1415927 + fl = fzero+ln(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') - return + fl = 3.1415927 + fl = log2(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = 3.1415927 + fl = fzero+log2(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = round(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = -9.9 + fl = fzero+round(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') - byte zerob=0 -; word zerow=0 -; float zerof=0 - byte bb -; word ww -; float fl - - testX() - - bb = -100 - bb = zerob+abs(bb) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?) + fl = -9.9 + bb = sgn(fl) + txt.print_b(bb) + txt.chrout('\n') + fl = -9.9 + bb = zero+sgn(fl)*1+zero txt.print_b(bb) txt.chrout('\n') -; ww = -12345 -; ww = zerow+abs(ww) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?) -; txt.print_w(ww) + fl = 3.1415927 + fl = sqrt(fl) + floats.print_f(fl) + txt.chrout('\n') + fl = 3.1415927 + fl = fzero+sqrt(fl)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + + fl = rndf() + floats.print_f(fl) + txt.chrout('\n') + fl = fzero+rndf()*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + + swap(fl, fzero) + swap(fzero, fl) + + ub = any(flarr) + txt.print_ub(ub) + txt.chrout('\n') + ub = zero+any(flarr)*1+zero + txt.print_ub(ub) + txt.chrout('\n') + ub = all(flarr) + txt.print_ub(ub) + txt.chrout('\n') + ub = zero+all(flarr)*1+zero + txt.print_ub(ub) + txt.chrout('\n') + + reverse(flarr) + for ub in 0 to len(flarr)-1 { + floats.print_f(flarr[ub]) + txt.chrout(',') + } + txt.chrout('\n') + fl = max(flarr) + floats.print_f(fl) + txt.chrout('\n') + fl = fzero+max(flarr)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + fl = min(flarr) + floats.print_f(fl) + txt.chrout('\n') + fl = fzero+min(flarr)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + fl = sum(flarr) + floats.print_f(fl) + txt.chrout('\n') + fl = fzero+sum(flarr)*1.0+fzero + floats.print_f(fl) + txt.chrout('\n') + +; ub = min(barr) +; +; ub = zero+min(barr)*1+zero +; txt.print_ub(ub) ; txt.chrout('\n') ; -; fl = -9.876 -; fl = zerof+abs(fl) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?) -; floats.print_f(fl) +; ub = max(barr) +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = zero+max(barr)*1+zero +; txt.print_ub(ub) +; txt.chrout('\n') +; +; uw = sum(barr) +; txt.print_uw(uw) +; txt.chrout('\n') +; +; uw = zero+sum(barr)*1+zero +; txt.print_uw(uw) +; txt.chrout('\n') +; +; ub = any(barr) +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = zero+any(barr)*1 +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = all(barr) +; txt.print_ub(ub) +; txt.chrout('\n') +; +; ub = zero+all(barr)*1 +; txt.print_ub(ub) ; txt.chrout('\n') -; memset(ADDR, 40*25, 100) -; memsetw(ADDR, 20*10, $3031) -; memcopy(ADDR, ADDR+40*12, 20*10*2) + + testX() - - bb++ } asmsub testX() {