mirror of
https://github.com/irmen/prog8.git
synced 2024-11-04 19:05:57 +00:00
implemented missing bitshift codegen (non-stack)
This commit is contained in:
parent
b717f1c7eb
commit
3841cef497
@ -515,51 +515,84 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
val shifts = expr.right.asConstInteger()
|
||||
if(shifts!=null) {
|
||||
val dt = expr.left.type
|
||||
if(dt in ByteDatatypes && shifts in 0..7) {
|
||||
if(dt in ByteDatatypes) {
|
||||
val signed = dt == DataType.BYTE
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.A, signed)
|
||||
if(expr.operator=="<<") {
|
||||
repeat(shifts) {
|
||||
asmgen.out(" asl a")
|
||||
}
|
||||
} else {
|
||||
if(signed && shifts>0) {
|
||||
asmgen.out(" ldy #$shifts | jsr math.lsr_byte_A")
|
||||
} else {
|
||||
if(shifts in 0..7) {
|
||||
require(dt==DataType.UBYTE)
|
||||
if (expr.operator == "<<") {
|
||||
repeat(shifts) {
|
||||
asmgen.out(" lsr a")
|
||||
asmgen.out(" asl a")
|
||||
}
|
||||
} else {
|
||||
if (signed && shifts > 0) {
|
||||
asmgen.out(" ldy #$shifts | jsr math.lsr_byte_A")
|
||||
} else {
|
||||
repeat(shifts) {
|
||||
asmgen.out(" lsr a")
|
||||
}
|
||||
}
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, signed)
|
||||
return true
|
||||
} else {
|
||||
if(signed && expr.operator==">>") {
|
||||
TODO("signed byte >> overshift should have been compiled away?")
|
||||
} else {
|
||||
asmgen.out(" lda #0")
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, signed)
|
||||
return true
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, signed)
|
||||
return true
|
||||
} else if(dt in WordDatatypes && shifts in 0..7) {
|
||||
} else if(dt in WordDatatypes) {
|
||||
val signed = dt == DataType.WORD
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed)
|
||||
if(expr.operator=="<<") {
|
||||
if(shifts>0) {
|
||||
asmgen.out(" sty P8ZP_SCRATCH_B1")
|
||||
repeat(shifts) {
|
||||
asmgen.out(" asl a | rol P8ZP_SCRATCH_B1")
|
||||
}
|
||||
asmgen.out(" ldy P8ZP_SCRATCH_B1")
|
||||
}
|
||||
} else {
|
||||
if(signed) {
|
||||
// TODO("shift AY >> $shifts signed")
|
||||
return false
|
||||
} else {
|
||||
if(shifts in 0..7) {
|
||||
if(expr.operator=="<<") {
|
||||
if(shifts>0) {
|
||||
asmgen.out(" sty P8ZP_SCRATCH_B1")
|
||||
repeat(shifts) {
|
||||
asmgen.out(" lsr P8ZP_SCRATCH_B1 | ror a")
|
||||
asmgen.out(" asl a | rol P8ZP_SCRATCH_B1")
|
||||
}
|
||||
asmgen.out(" ldy P8ZP_SCRATCH_B1")
|
||||
}
|
||||
} else {
|
||||
if(signed && shifts>0) {
|
||||
asmgen.out(" ldx #$shifts | jsr math.lsr_word_AY")
|
||||
} else {
|
||||
if(shifts>0) {
|
||||
asmgen.out(" sty P8ZP_SCRATCH_B1")
|
||||
repeat(shifts) {
|
||||
asmgen.out(" lsr P8ZP_SCRATCH_B1 | ror a")
|
||||
}
|
||||
asmgen.out(" ldy P8ZP_SCRATCH_B1")
|
||||
}
|
||||
}
|
||||
}
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
return true
|
||||
} else if (shifts in 8..15) {
|
||||
if(expr.operator == "<<") {
|
||||
// msb = lsb << (shifts-8), lsb = 0
|
||||
repeat(shifts-8) {
|
||||
asmgen.out(" asl a")
|
||||
}
|
||||
asmgen.out(" tay | lda #0")
|
||||
} else {
|
||||
asmgen.out(" ldx #$shifts | jsr math.lsr_word_AY")
|
||||
}
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
return true
|
||||
}
|
||||
else {
|
||||
if(signed && expr.operator==">>") {
|
||||
TODO("signed word >> overshift should have been compiled away?")
|
||||
} else {
|
||||
asmgen.out(" lda #0 | ldy #0")
|
||||
}
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
return true
|
||||
}
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
@ -749,20 +749,42 @@ mul_word_640 .proc
|
||||
; 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)
|
||||
; -- lsr signed byte in A times the value in Y (>1)
|
||||
cmp #0
|
||||
bmi _negative
|
||||
- lsr a
|
||||
dey
|
||||
bne -
|
||||
rts
|
||||
_negative lsr a
|
||||
ora #$80
|
||||
_negative sec
|
||||
ror a
|
||||
dey
|
||||
bne _negative
|
||||
rts
|
||||
.pend
|
||||
|
||||
lsr_word_AY .proc
|
||||
; -- lsr signed word in AY times the value in X (>1)
|
||||
sta P8ZP_SCRATCH_B1
|
||||
tya
|
||||
bmi _negative
|
||||
- lsr a
|
||||
ror P8ZP_SCRATCH_B1
|
||||
dex
|
||||
bne -
|
||||
tay
|
||||
lda P8ZP_SCRATCH_B1
|
||||
rts
|
||||
_negative sec
|
||||
ror a
|
||||
ror P8ZP_SCRATCH_B1
|
||||
dex
|
||||
bne _negative
|
||||
tay
|
||||
lda P8ZP_SCRATCH_B1
|
||||
rts
|
||||
.pend
|
||||
|
||||
|
||||
square .proc
|
||||
; -- calculate square root of signed word in AY, result in AY
|
||||
|
@ -5,9 +5,27 @@ main
|
||||
{
|
||||
sub start()
|
||||
{
|
||||
; uword zc = $ea31
|
||||
word zc = -5583
|
||||
txt.print_w(zc)
|
||||
txt.spc()
|
||||
txt.print_w(zc>>10) ; -6
|
||||
txt.nl()
|
||||
|
||||
txt.print_w(zc)
|
||||
txt.spc()
|
||||
txt.print_w(zc>>4) ; -349
|
||||
txt.nl()
|
||||
|
||||
txt.print_w(zc)
|
||||
txt.spc()
|
||||
txt.print_w(zc>>10) ; -6
|
||||
txt.nl()
|
||||
|
||||
cx16.r1L = (zc>>10) as ubyte
|
||||
txt.print_ub(cx16.r1L) ; 250
|
||||
txt.nl()
|
||||
cx16.r1L = (zc>>4) as ubyte
|
||||
txt.print_ub(cx16.r1L) ; 163
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user