fixed compiler crash: unsigned = (-(unsigned as word) as uword)

This commit is contained in:
Irmen de Jong 2022-11-27 16:50:44 +01:00
parent db55562f6a
commit ec64a68a71
5 changed files with 46 additions and 6 deletions

View File

@ -299,7 +299,7 @@ internal class AssignmentAsmGen(private val program: Program,
)
when (value.operator) {
"+" -> {}
"-" -> augmentableAsmGen.inplaceNegate(assign)
"-" -> augmentableAsmGen.inplaceNegate(assign, true)
"~" -> augmentableAsmGen.inplaceInvert(assign)
else -> throw AssemblyError("invalid prefix operator")
}

View File

@ -23,7 +23,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
// A = -A , A = +A, A = ~A, A = not A
when (value.operator) {
"+" -> {}
"-" -> inplaceNegate(assign)
"-" -> inplaceNegate(assign, false)
"~" -> inplaceInvert(assign)
else -> throw AssemblyError("invalid prefix operator")
}
@ -1871,9 +1871,16 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
internal fun inplaceNegate(assign: AsmAssignment) {
internal fun inplaceNegate(assign: AsmAssignment, ignoreDatatype: Boolean) {
val target = assign.target
when (target.datatype) {
val datatype = if(ignoreDatatype) {
when(target.datatype) {
DataType.UBYTE, DataType.BYTE -> DataType.BYTE
DataType.UWORD, DataType.WORD -> DataType.WORD
else -> target.datatype
}
} else target.datatype
when (datatype) {
DataType.BYTE -> {
when (target.kind) {
TargetStorageKind.VARIABLE -> {

View File

@ -63,5 +63,21 @@ class TestVariables: FunSpec({
"""
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
}
test("negation of unsigned via casts") {
val text = """
main {
sub start() {
cx16.r0L = -(cx16.r0L as byte) as ubyte
cx16.r0 = -(cx16.r0 as word) as uword
ubyte ub
uword uw
ub = -(ub as byte) as ubyte
uw = -(uw as word) as uword
}
}
"""
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
}
})

View File

@ -3,7 +3,7 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- fix compiler crash cx16.r0 = (-(cx16.r0 as word) as uword)
- make the adpcm example read wav files directly (so no need anymore to extract the binary frame data from them)
- duplicate diskio for cx16 (get rid of cx16diskio, just copy diskio and tweak everything) + documentation
- get f_seek_w working like in the BASIC program - this needs the changes to diskio.f_open to use suffixes ,p,m
- attempt to fix the expression codegen bug with reused temp vars (github #89)

View File

@ -3,6 +3,23 @@
%option no_sysinit
%zeropage basicsafe
;
; IMA ADPCM decoding and playback example.
; https://wiki.multimedia.cx/index.php/IMA_ADPCM
; https://wiki.multimedia.cx/index.php/Microsoft_IMA_ADPCM
;
; IMA ADPCM encodes two 16-bit PCM audio samples in 1 byte (1 word per nibble)
; thus compressing the audio data by a factor of 4.
; The encoding precision is about 13 bits per sample so it's a lossy compression scheme.
;
; NOTE: this program requires 16 bits MONO audio, and 256 byte encoded block size!
; HOW TO CREATE SUCH IMA-ADPCM ENCODED AUDIO? Use sox or ffmpeg:
; $ sox --guard source.mp3 -r 8000 -c 1 -e ima-adpcm out.wav trim 01:27.50 00:09
; $ ffmpeg -i source.mp3 -ss 00:01:27.50 -to 00:01:36.50 -ar 8000 -ac 1 -c:a adpcm_ima_wav -block_size 256 -map_metadata -1 -bitexact out.wav
;
; THEN use a tool to read the raw audio frame data from that resulting out.wav and save it as 'adpcm-mono.bin'.
;
main {
ubyte num_adpcm_blocks
@ -179,7 +196,7 @@ adpcm {
audiodata {
;; %option align_page
%option align_page
adpcm_data:
%asmbinary "adpcm-mono.bin"
adpcm_data_end: