mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
fixed bitshifting by more than the number of bits in the value
This commit is contained in:
parent
e83796b5b9
commit
aec3b82476
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 -> {
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user