bit shift expressions are "expanded" to the target value's datatype, now also for subroutine arguments.

implemented word bit shifts by variable number of bits.
This commit is contained in:
Irmen de Jong 2020-12-14 20:17:49 +01:00
parent 3b7a92f1b4
commit 4977d1fbd5
6 changed files with 72 additions and 35 deletions

View File

@ -1352,6 +1352,33 @@ shift_left_w_3 .proc
jmp shift_left_w_7._shift3
.pend
shift_left_w .proc
; -- variable number of shifts left
inx
ldy P8ESTACK_LO,x
bne _shift
rts
_shift asl P8ESTACK_LO+1,x
rol P8ESTACK_HI+1,x
dey
bne _shift
rts
.pend
shift_right_uw .proc
; -- uword variable number of shifts right
inx
ldy P8ESTACK_LO,x
bne _shift
rts
_shift lsr P8ESTACK_HI+1,x
ror P8ESTACK_LO+1,x
dey
bne _shift
rts
.pend
shift_right_uw_7 .proc
lda P8ESTACK_LO+1,x
sta P8ZP_SCRATCH_B1
@ -1482,6 +1509,21 @@ shift_right_w_3 .proc
.pend
shift_right_w .proc
; -- signed word variable number of shifts right
inx
ldy P8ESTACK_LO,x
bne _shift
rts
_shift lda P8ESTACK_HI+1,x
asl a
ror P8ESTACK_HI+1,x
ror P8ESTACK_LO+1,x
dey
bne _shift
rts
.pend
; support for bit shifting that is too large to be unrolled:

View File

@ -4,6 +4,7 @@ import prog8.ast.*
import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.functions.BuiltinFunctions
internal class StatementReorderer(val program: Program, val errors: ErrorReporter) : AstWalker() {
@ -111,6 +112,29 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr))
}
}
is IFunctionCall -> {
val argnum = parent.args.indexOf(expr)
when (val callee = parent.target.targetStatement(program.namespace)) {
is Subroutine -> {
val paramType = callee.parameters[argnum].type
if(leftDt isAssignableTo paramType) {
val cast = TypecastExpression(expr.left, paramType, true, parent.position)
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr))
}
}
is BuiltinFunctionStatementPlaceholder -> {
val func = BuiltinFunctions.getValue(callee.name)
val paramTypes = func.parameters[argnum].possibleDatatypes
for(type in paramTypes) {
if(leftDt isAssignableTo type) {
val cast = TypecastExpression(expr.left, type, true, parent.position)
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr))
}
}
}
else -> throw FatalAstException("weird callee")
}
}
else -> return noModifications
}
}

View File

@ -223,7 +223,7 @@ private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir:
programAst.processAstBeforeAsmGeneration(errors)
errors.handle()
// printAst(programAst)
printAst(programAst)
CompilationTarget.instance.machine.initializeZeropage(compilerOptions)
val assembly = CompilationTarget.instance.asmGenerator(

View File

@ -2,7 +2,7 @@
TODO
====
- reverse mkword() again because of consistency with the platform and AY register pairs...
- (thinking about) reverse mkword() again because of consistency with the platform and AY register pairs...??
- see if we can group some errors together for instance the (now single) errors about unidentified symbols
- Cx16 target: support full-screen 640x480 and 320x240 graphics? That requires our own custom graphics routines though to draw lines.
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)

View File

@ -21,7 +21,7 @@
; 01 = RLE [TODO not yet implemented]
; 10 = LZSA [TODO not yet implemented]
; 11 = Exomizer [TODO not yet implemented]
; bit 2 = palette format. 0 = 4 bits/channel (2 bytes per color, $0R $GB) [TODO not yet implemented]
; bit 2 = palette format. 0 = 4 bits/channel (2 bytes per color, $0R $GB)
; 1 = 8 bits/channel (3 bytes per color, $RR $GG $BB)
; 4 bits per channel is what the Vera in the Cx16 supports.
; bit 3 = bitmap format. 0 = raw bitmap pixels

View File

@ -9,39 +9,10 @@
main {
sub start () {
str s1 = "1234567890"
str s2 = "aapje"
txt.print_ub(strcopy(s2, s1))
txt.chrout('\n')
txt.print_ub(strcopy(s2, s1)+1)
txt.chrout('\n')
txt.print_ub(strlen(s2))
txt.chrout('\n')
txt.print_ub(strlen(s1))
txt.chrout('\n')
; uword xx
;
; foo(2**xx) ; TODO arg is zero if x=8, in the function. Param type uword. fix that . also check bit shift
; foo(1<<xx) ; TODO fix crash
; foo($0001<<xx) ; TODO fix crash
; foo($0001>>xx) ; TODO fix crash
;
;
; xx = $0001<<xx ; TODO make math.shift_left_w
; xx = $0001>>xx ; TODO make math.shift_right_(u)w
; uword scanline_data_ptr= $6000
; uword pixptr = xx/8 + scanline_data_ptr ; TODO why is this code so much larger than the following line:
; uword pixptr2 = scanline_data_ptr + xx/8
uword scanline_data_ptr= $6000
uword pixptr = xx/8 + scanline_data_ptr ; TODO why is this code so much larger than the following line:
uword pixptr2 = scanline_data_ptr + xx/8
test_stack.test()
}
sub foo(uword argje) {
txt.print_uwhex(argje, 1)
txt.chrout('\n')
}
}