From 81dd8a38135a017446db295e67000d2389a3e55d Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 31 Dec 2024 00:09:16 +0100 Subject: [PATCH] fix: crash on SHL with bool expressions --- .../z80/visitor/translator_inst_visitor.py | 2 +- tests/functional/arch/zx48k/shri16.asm | 44 +++++++++++ tests/functional/arch/zx48k/shri16.bas | 3 + tests/functional/arch/zx48k/shri32.asm | 75 ++++++++++++++++++- tests/functional/arch/zx48k/shri32.bas | 3 + tests/functional/arch/zx48k/shri8.asm | 33 ++++++++ tests/functional/arch/zx48k/shri8.bas | 3 + tests/functional/arch/zx48k/shru16.asm | 44 +++++++++++ tests/functional/arch/zx48k/shru16.bas | 3 + tests/functional/arch/zx48k/shru32.asm | 75 ++++++++++++++++++- tests/functional/arch/zx48k/shru32.bas | 3 + tests/functional/arch/zx48k/shru8.asm | 33 ++++++++ tests/functional/arch/zx48k/shru8.bas | 3 + 13 files changed, 319 insertions(+), 5 deletions(-) diff --git a/src/arch/z80/visitor/translator_inst_visitor.py b/src/arch/z80/visitor/translator_inst_visitor.py index 1e023ec0e..f43056038 100644 --- a/src/arch/z80/visitor/translator_inst_visitor.py +++ b/src/arch/z80/visitor/translator_inst_visitor.py @@ -226,7 +226,7 @@ def ic_shl(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: self.emit(f"shl{self._no_bool(type_)}", t, t1, t2) def ic_shr(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("shr" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"shr{self._no_bool(type_)}", t, t1, t2) def ic_store(self, type_: TYPE | sym.BASICTYPE, t1, t2) -> None: self.emit("store" + self.TSUFFIX(type_), t1, t2) diff --git a/tests/functional/arch/zx48k/shri16.asm b/tests/functional/arch/zx48k/shri16.asm index 7845767b4..cc39a1cf6 100644 --- a/tests/functional/arch/zx48k/shri16.asm +++ b/tests/functional/arch/zx48k/shri16.asm @@ -44,6 +44,39 @@ _b: xor a ld l, a ld h, 0 + ld (_a), hl + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + push af + ld a, (_b) + pop hl + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL7 +.LABEL.__LABEL6: + srl a + djnz .LABEL.__LABEL6 +.LABEL.__LABEL7: + ld l, a + ld h, 0 + ld (_a), hl + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + sub 1 + sbc a, a + inc a + ld b, a + ld hl, (_a) + or a + jr z, .LABEL.__LABEL9 +.LABEL.__LABEL8: + sra h + rr l + djnz .LABEL.__LABEL8 +.LABEL.__LABEL9: ld (_a), hl ld hl, 0 ld b, h @@ -60,4 +93,15 @@ _b: ei ret ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq16.asm" + push namespace core +__EQ16: ; Test if 16bit values HL == DE + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace +#line 71 "arch/zx48k/shri16.bas" END diff --git a/tests/functional/arch/zx48k/shri16.bas b/tests/functional/arch/zx48k/shri16.bas index 0178617ba..43a3ffcde 100644 --- a/tests/functional/arch/zx48k/shri16.bas +++ b/tests/functional/arch/zx48k/shri16.bas @@ -5,3 +5,6 @@ a = a >> b a = a >> 1 a = a >> 0 a = 0 >> b +a = (a = a) >> b +a = a >> (a = a) + diff --git a/tests/functional/arch/zx48k/shri32.asm b/tests/functional/arch/zx48k/shri32.asm index e691a61ba..30283b7dd 100644 --- a/tests/functional/arch/zx48k/shri32.asm +++ b/tests/functional/arch/zx48k/shri32.asm @@ -51,6 +51,51 @@ _b: ld h, 0 ld e, h ld d, h + ld (_a), hl + ld (_a + 2), de + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + push af + ld a, (_b) + pop hl + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL3 +.LABEL.__LABEL2: + srl a + djnz .LABEL.__LABEL2 +.LABEL.__LABEL3: + ld l, a + ld h, 0 + ld e, h + ld d, h + ld (_a), hl + ld (_a + 2), de + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + sub 1 + sbc a, a + inc a + ld b, a + ld hl, (_a) + ld de, (_a + 2) + or a + jr z, .LABEL.__LABEL5 +.LABEL.__LABEL4: + call .core.__SHRA32 + djnz .LABEL.__LABEL4 +.LABEL.__LABEL5: ld (_a), hl ld (_a + 2), de ld hl, 0 @@ -68,7 +113,7 @@ _b: ei ret ;; --- end of user code --- -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/shra32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bitwise/shra32.asm" push namespace core __SHRA32: ; Right Arithmetical Shift 32 bits sra d @@ -77,5 +122,31 @@ __SHRA32: ; Right Arithmetical Shift 32 bits rr l ret pop namespace -#line 46 "arch/zx48k/shri32.bas" +#line 91 "arch/zx48k/shri32.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq32.asm" + push namespace core +__EQ32: ; Test if 32bit value HLDE equals top of the stack + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part + exx + push bc ; CALLEE + exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret + pop namespace +#line 92 "arch/zx48k/shri32.bas" END diff --git a/tests/functional/arch/zx48k/shri32.bas b/tests/functional/arch/zx48k/shri32.bas index 758477186..98318953b 100644 --- a/tests/functional/arch/zx48k/shri32.bas +++ b/tests/functional/arch/zx48k/shri32.bas @@ -5,3 +5,6 @@ a = a >> b a = a >> 1 a = a >> 0 a = 0 >> b +a = (a = a) >> b +a = a >> (a = a) + diff --git a/tests/functional/arch/zx48k/shri8.asm b/tests/functional/arch/zx48k/shri8.asm index 074e13f54..c1321ca6c 100644 --- a/tests/functional/arch/zx48k/shri8.asm +++ b/tests/functional/arch/zx48k/shri8.asm @@ -40,6 +40,39 @@ _b: ld (_a), a ld a, (_b) xor a + ld (_a), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + push af + ld a, (_b) + pop hl + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL3 +.LABEL.__LABEL2: + srl a + djnz .LABEL.__LABEL2 +.LABEL.__LABEL3: + ld (_a), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + ld hl, (_a - 1) + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL5 +.LABEL.__LABEL4: + sra a + djnz .LABEL.__LABEL4 +.LABEL.__LABEL5: ld (_a), a ld hl, 0 ld b, h diff --git a/tests/functional/arch/zx48k/shri8.bas b/tests/functional/arch/zx48k/shri8.bas index 7684feef5..156b7d050 100644 --- a/tests/functional/arch/zx48k/shri8.bas +++ b/tests/functional/arch/zx48k/shri8.bas @@ -5,3 +5,6 @@ a = a >> b a = a >> 1 a = a >> 0 a = 0 >> b +a = (a = a) >> b +a = a >> (a = a) + diff --git a/tests/functional/arch/zx48k/shru16.asm b/tests/functional/arch/zx48k/shru16.asm index e4dc9f3c5..42a9aa231 100644 --- a/tests/functional/arch/zx48k/shru16.asm +++ b/tests/functional/arch/zx48k/shru16.asm @@ -44,6 +44,39 @@ _b: xor a ld l, a ld h, 0 + ld (_a), hl + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + push af + ld a, (_b) + pop hl + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL7 +.LABEL.__LABEL6: + srl a + djnz .LABEL.__LABEL6 +.LABEL.__LABEL7: + ld l, a + ld h, 0 + ld (_a), hl + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + sub 1 + sbc a, a + inc a + ld b, a + ld hl, (_a) + or a + jr z, .LABEL.__LABEL9 +.LABEL.__LABEL8: + srl h + rr l + djnz .LABEL.__LABEL8 +.LABEL.__LABEL9: ld (_a), hl ld hl, 0 ld b, h @@ -60,4 +93,15 @@ _b: ei ret ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq16.asm" + push namespace core +__EQ16: ; Test if 16bit values HL == DE + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace +#line 71 "arch/zx48k/shru16.bas" END diff --git a/tests/functional/arch/zx48k/shru16.bas b/tests/functional/arch/zx48k/shru16.bas index 1915574dd..285ef518b 100644 --- a/tests/functional/arch/zx48k/shru16.bas +++ b/tests/functional/arch/zx48k/shru16.bas @@ -5,3 +5,6 @@ a = a >> b a = a >> 1 a = a >> 0 a = 0 >> b +a = (a = a) >> b +a = a >> (a = a) + diff --git a/tests/functional/arch/zx48k/shru32.asm b/tests/functional/arch/zx48k/shru32.asm index 20b9f0a5f..97526a94d 100644 --- a/tests/functional/arch/zx48k/shru32.asm +++ b/tests/functional/arch/zx48k/shru32.asm @@ -51,6 +51,51 @@ _b: ld h, 0 ld e, h ld d, h + ld (_a), hl + ld (_a + 2), de + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + push af + ld a, (_b) + pop hl + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL3 +.LABEL.__LABEL2: + srl a + djnz .LABEL.__LABEL2 +.LABEL.__LABEL3: + ld l, a + ld h, 0 + ld e, h + ld d, h + ld (_a), hl + ld (_a + 2), de + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + sub 1 + sbc a, a + inc a + ld b, a + ld hl, (_a) + ld de, (_a + 2) + or a + jr z, .LABEL.__LABEL5 +.LABEL.__LABEL4: + call .core.__SHRL32 + djnz .LABEL.__LABEL4 +.LABEL.__LABEL5: ld (_a), hl ld (_a + 2), de ld hl, 0 @@ -68,7 +113,7 @@ _b: ei ret ;; --- end of user code --- -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/shrl32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bitwise/shrl32.asm" push namespace core __SHRL32: ; Right Logical Shift 32 bits srl d @@ -77,5 +122,31 @@ __SHRL32: ; Right Logical Shift 32 bits rr l ret pop namespace -#line 46 "arch/zx48k/shru32.bas" +#line 91 "arch/zx48k/shru32.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq32.asm" + push namespace core +__EQ32: ; Test if 32bit value HLDE equals top of the stack + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part + exx + push bc ; CALLEE + exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret + pop namespace +#line 92 "arch/zx48k/shru32.bas" END diff --git a/tests/functional/arch/zx48k/shru32.bas b/tests/functional/arch/zx48k/shru32.bas index 34191e0ca..0cb760816 100644 --- a/tests/functional/arch/zx48k/shru32.bas +++ b/tests/functional/arch/zx48k/shru32.bas @@ -5,3 +5,6 @@ a = a >> b a = a >> 1 a = a >> 0 a = 0 >> b +a = (a = a) >> b +a = a >> (a = a) + diff --git a/tests/functional/arch/zx48k/shru8.asm b/tests/functional/arch/zx48k/shru8.asm index 1808b7c38..0b8cf6320 100644 --- a/tests/functional/arch/zx48k/shru8.asm +++ b/tests/functional/arch/zx48k/shru8.asm @@ -40,6 +40,39 @@ _b: ld (_a), a ld a, (_b) xor a + ld (_a), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + push af + ld a, (_b) + pop hl + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL3 +.LABEL.__LABEL2: + srl a + djnz .LABEL.__LABEL2 +.LABEL.__LABEL3: + ld (_a), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + ld hl, (_a - 1) + or a + ld b, a + ld a, h + jr z, .LABEL.__LABEL5 +.LABEL.__LABEL4: + srl a + djnz .LABEL.__LABEL4 +.LABEL.__LABEL5: ld (_a), a ld hl, 0 ld b, h diff --git a/tests/functional/arch/zx48k/shru8.bas b/tests/functional/arch/zx48k/shru8.bas index c3a981afe..8a73243e6 100644 --- a/tests/functional/arch/zx48k/shru8.bas +++ b/tests/functional/arch/zx48k/shru8.bas @@ -5,3 +5,6 @@ a = a >> b a = a >> 1 a = a >> 0 a = 0 >> b +a = (a = a) >> b +a = a >> (a = a) +