fixed bitshifting by more than the number of bits in the value

This commit is contained in:
Irmen de Jong 2020-10-18 18:00:24 +02:00
parent e83796b5b9
commit aec3b82476
7 changed files with 127 additions and 128 deletions

View File

@ -1469,3 +1469,22 @@ shift_right_w_3 .proc
jmp shift_right_w_7._shift3
.pend
; support for bit shifting that is too large to be unrolled:
lsr_byte_A .proc
; -- lsr signed byte in A times the value in Y (assume >0)
cmp #0
bmi _negative
- lsr a
dey
bne -
rts
_negative lsr a
ora #$80
dey
bne _negative
rts
.pend

View File

@ -2145,34 +2145,3 @@ func_strcmp .proc
sta P8ESTACK_LO+1,x
rts
.pend
; support for bit shifting that is too large to be unrolled:
lsr_byte_A .proc
; -- lsr signed byte in A times the value in Y (assume >0)
cmp #0
bmi _negative
- lsr a
dey
bne -
rts
_negative lsr a
ora #$80
dey
bne _negative
rts
.pend
lsr_word_AY .proc
.error "make"
.pend
lsr_uword_AY .proc
.error "make"
.pend
asl_word_AY .proc
.error "make"
.pend

View File

@ -415,6 +415,10 @@ open class Assignment(var target: AssignTarget, var value: Expression, override
return if(subCast!=null) subCast.expression isSameAs target else castExpr.expression isSameAs target
}
if(target.identifier!=null) {
return value.referencesIdentifier(*(target.identifier!!.nameInSource.toTypedArray()))
}
return false
}
}

View File

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

View File

@ -575,21 +575,30 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta $name""")
}
"<<" -> {
repeat(value) { asmgen.out(" asl $name") }
if(value>=8) asmgen.out(" lda #0 | sta $name")
else repeat(value) { asmgen.out(" asl $name") }
}
">>" -> {
if(value>0) {
if (dt == DataType.UBYTE) {
repeat(value) { asmgen.out(" lsr $name") }
if(value>=8) asmgen.out(" lda #0 | sta $name")
else repeat(value) { asmgen.out(" lsr $name") }
} else {
if(value>3)
asmgen.out("""
when {
value>=8 -> asmgen.out("""
lda $name
bmi +
lda #0
beq ++
+ lda #-1
+ sta $name""")
value>3 -> asmgen.out("""
lda $name
ldy #$value
jsr prog8_lib.lsr_byte_A
sta $name""") // TODO make prog8_lib.lsr_byte_A
else
repeat(value) { asmgen.out(" lda $name | asl a | ror $name") }
jsr math.lsr_byte_A
sta $name""")
else -> repeat(value) { asmgen.out(" lda $name | asl a | ror $name") }
}
}
}
}
@ -798,38 +807,63 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
""")
}
"<<" -> {
if(value>4)
asmgen.out("""
lda #$value
sta P8ZP_SCRATCH_B1
lda #<$name
ldy #>$name
jsr prog8_lib.asl_word_AY""") // TODO make prog8_lib.asl_word_AY
else
repeat(value) { asmgen.out(" asl $name | rol $name+1") }
when {
value>=16 -> asmgen.out(" lda #0 | sta $name | sta $name+1")
value==8 -> asmgen.out(" lda $name | sta $name+1 | lda #0 | sta $name")
value>2 -> asmgen.out("""
ldy #$value
- asl $name
rol $name+1
dey
bne -
""")
else -> repeat(value) { asmgen.out(" asl $name | rol $name+1") }
}
}
">>" -> {
if (value > 0) {
if(dt==DataType.UWORD) {
if(value>4)
asmgen.out("""
lda #$value
sta P8ZP_SCRATCH_B1
lda #<$name
ldy #>$name
jsr prog8_lib.lsr_uword_AY""") // TODO make prog8_lib.lsr_uword_AY
else
repeat(value) { asmgen.out(" lsr $name+1 | ror $name")}
when {
value>=16 -> asmgen.out(" lda #0 | sta $name | sta $name+1")
value==8 -> asmgen.out(" lda $name+1 | sta $name | lda #0 | sta $name+1")
value>2 -> asmgen.out("""
ldy #$value
- lsr $name+1
ror $name
dey
bne -""")
else -> repeat(value) { asmgen.out(" lsr $name+1 | ror $name")}
}
} else {
if(value>2)
asmgen.out("""
lda #$value
sta P8ZP_SCRATCH_B1
lda #<$name
ldy #>$name
jsr prog8_lib.lsr_word_AY""") // TODO make prog8_lib.lsr_word_AY
else
repeat(value) { asmgen.out(" lda $name+1 | asl a | ror $name+1 | ror $name") }
when {
value>=16 -> asmgen.out("""
lda $name+1
bmi +
lda #0
beq ++
+ lda #-1
+ sta $name
sta $name+1""")
value==8 -> asmgen.out("""
lda $name+1
sta $name
bmi +
lda #0
- sta $name+1
beq ++
+ lda #-1
sta $name+1
+""")
value>2 -> asmgen.out("""
ldy #$value
- lda $name+1
asl a
ror $name+1
ror $name
dey
bne -""")
else -> repeat(value) { asmgen.out(" lda $name+1 | asl a | ror $name+1 | ror $name") }
}
}
}
}

View File

@ -605,6 +605,7 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker()
if (amount >= 16) {
return NumericLiteralValue(targetDt, 0, expr.position)
} else if (amount >= 8) {
// TODO is this correct???
val lsb = TypecastExpression(expr.left, DataType.UBYTE, true, expr.position)
if (amount == 8) {
return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position)
@ -644,8 +645,9 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker()
return NumericLiteralValue.optimalInteger(0, expr.position)
} else if (amount >= 8) {
val msb = FunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
if (amount == 8)
return msb
if (amount == 8) {
return TypecastExpression(msb, DataType.UWORD, true, expr.position)
}
return BinaryExpression(msb, ">>", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position)
}
}
@ -653,14 +655,6 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker()
if (amount > 16) {
expr.right = NumericLiteralValue.optimalInteger(16, expr.right.position)
return null
} else if (amount >= 8) {
val msbAsByte = TypecastExpression(
FunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position),
DataType.BYTE,
true, expr.position)
if (amount == 8)
return msbAsByte
return BinaryExpression(msbAsByte, ">>", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position)
}
}
else -> {

View File

@ -7,68 +7,47 @@ main {
sub start() {
word zz
uword uu
word ww
uword uw
ubyte ub
byte bb
bb = -111
bb >>= 0
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 9 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 1
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 10 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 2
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 11 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 3
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 12 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 4
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 13 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 5
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 14 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 6
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 15 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 7
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 16 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 8
txt.print_ubbin(bb as ubyte, true)
uw = 21111
uw >>= 17 ; TODO fix this shift!
txt.print_uwbin(uw as uword, true)
txt.chrout('\n')
bb = -111
bb >>= 9
txt.print_ubbin(bb as ubyte, true)
txt.chrout('\n')
; for ub in 0 to 8 {
; bb = 111
; bb >>= ub
; txt.print_ubbin(bb as ubyte, true)
; txt.chrout('\n')
; }
; txt.chrout('\n')
;
; for ub in 0 to 8 {
; bb = -111
; bb >>= ub
; txt.print_ubbin(bb as ubyte, true)
; txt.chrout('\n')
; }
; txt.chrout('\n')
; ub >>= 7
; ub <<= 7
;
@ -81,7 +60,7 @@ main {
; bb >>=7
; bb <<=7
; testX()
testX()
}
asmsub testX() {