From c0c14c6abf1dd83c1ee2667db1a6e20894fe355a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 31 Dec 2024 11:32:56 +0100 Subject: [PATCH 1/3] fix: using SHL or SHR with boolean expressions Reverted last changes and uses a different approach, since doing something like (a = b) SHL 1 sometimes rendered wrong results (boolean not normalized). --- .../z80/visitor/translator_inst_visitor.py | 4 +- src/symbols/binary.py | 47 +++++++++++-------- tests/functional/arch/zx48k/add8.asm | 17 +++++++ tests/functional/arch/zx48k/add8.bas | 2 + tests/functional/arch/zx48k/shlu16.asm | 5 +- tests/functional/arch/zx48k/shlu32.asm | 7 ++- tests/functional/arch/zx48k/shlu8.asm | 1 + tests/functional/arch/zx48k/shri16.asm | 5 +- tests/functional/arch/zx48k/shri32.asm | 7 ++- tests/functional/arch/zx48k/shri8.asm | 1 + tests/functional/arch/zx48k/shru16.asm | 5 +- tests/functional/arch/zx48k/shru32.asm | 7 ++- tests/functional/arch/zx48k/shru8.asm | 1 + 13 files changed, 78 insertions(+), 31 deletions(-) diff --git a/src/arch/z80/visitor/translator_inst_visitor.py b/src/arch/z80/visitor/translator_inst_visitor.py index f43056038..36f394fb3 100644 --- a/src/arch/z80/visitor/translator_inst_visitor.py +++ b/src/arch/z80/visitor/translator_inst_visitor.py @@ -223,10 +223,10 @@ def ic_return(self, addr) -> None: self.emit("ret", addr) def ic_shl(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit(f"shl{self._no_bool(type_)}", t, t1, t2) + self.emit(f"shl{self.TSUFFIX(type_)}", t, t1, t2) def ic_shr(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit(f"shr{self._no_bool(type_)}", t, t1, t2) + self.emit(f"shr{self.TSUFFIX(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/src/symbols/binary.py b/src/symbols/binary.py index 34f1c1b44..3d6191e6f 100644 --- a/src/symbols/binary.py +++ b/src/symbols/binary.py @@ -72,6 +72,31 @@ def make_node(cls, operator, left, right, lineno, func=None, type_=None): return None a, b = left, right # short form names + if operator in { + "BAND", + "BOR", + "BXOR", + "AND", + "OR", + "XOR", + "MINUS", + "MULT", + "DIV", + "SHL", + "SHR", + } and not check.is_numeric(a, b): + errmsg.error(lineno, f"Operator {operator} cannot be used with strings") + return None + + if operator not in {"AND", "OR", "XOR"}: + # Non-boolean operators use always numeric operands. + # We ensure operands are correctly converted to 0|1 values if they're boolean + if a.type_ == TYPE.boolean: + a = SymbolTYPECAST.make_node(TYPE.ubyte, a, lineno) + + if b.type_ == TYPE.boolean: + b = SymbolTYPECAST.make_node(TYPE.ubyte, b, lineno) + # Check for constant non-numeric operations c_type = check.common_type(a, b) # Resulting operation type or None if TYPE.is_numeric(c_type): # there must be a common type for a and b @@ -90,31 +115,13 @@ def make_node(cls, operator, left, right, lineno, func=None, type_=None): b = SymbolTYPECAST.make_node(c_type, b, lineno) # ensure type return SymbolCONSTEXPR(cls(operator, a, b, lineno, type_=type_, func=func), lineno=lineno) - if operator in { - "BNOT", - "BAND", - "BOR", - "BXOR", - "NOT", - "AND", - "OR", - "XOR", - "MINUS", - "MULT", - "DIV", - "SHL", - "SHR", - } and not check.is_numeric(a, b): - errmsg.error(lineno, "Operator %s cannot be used with STRINGS" % operator) - return None - if check.is_string(a, b) and func is not None: # Are they STRING Constants? if operator == "PLUS": return SymbolSTRING(func(a.value, b.value), lineno) return SymbolNUMBER(int(func(a.text, b.text)), type_=TYPE.ubyte, lineno=lineno) # Convert to u8 (boolean) - if operator in ("BNOT", "BAND", "BOR", "BXOR"): + if operator in {"BNOT", "BAND", "BOR", "BXOR"}: if TYPE.is_decimal(c_type): c_type = TYPE.long_ @@ -129,7 +136,7 @@ def make_node(cls, operator, left, right, lineno, func=None, type_=None): return None if type_ is None: - if operator in ("LT", "GT", "EQ", "LE", "GE", "NE", "AND", "OR", "XOR", "NOT"): + if operator in {"LT", "GT", "EQ", "LE", "GE", "NE", "AND", "OR", "XOR"}: type_ = TYPE.boolean else: type_ = c_type diff --git a/tests/functional/arch/zx48k/add8.asm b/tests/functional/arch/zx48k/add8.asm index 4b2221edd..8790b8201 100644 --- a/tests/functional/arch/zx48k/add8.asm +++ b/tests/functional/arch/zx48k/add8.asm @@ -38,6 +38,23 @@ _b: ld a, (_a) add a, h ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + push af + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + ld h, a + pop af + add a, h + ld (_b), a ld hl, 0 ld b, h ld c, l diff --git a/tests/functional/arch/zx48k/add8.bas b/tests/functional/arch/zx48k/add8.bas index 66403c245..a5f7fe078 100644 --- a/tests/functional/arch/zx48k/add8.bas +++ b/tests/functional/arch/zx48k/add8.bas @@ -8,3 +8,5 @@ b = a + 1 b = 0 + a b = 1 + a b = a + a +b = (a = a) + (a = a) + diff --git a/tests/functional/arch/zx48k/shlu16.asm b/tests/functional/arch/zx48k/shlu16.asm index e3f010b6a..a0b24dfe3 100644 --- a/tests/functional/arch/zx48k/shlu16.asm +++ b/tests/functional/arch/zx48k/shlu16.asm @@ -46,6 +46,9 @@ _b: ld de, (_a) ld hl, (_a) call .core.__EQ16 + sub 1 + sbc a, a + inc a push af ld a, (_b) pop hl @@ -100,5 +103,5 @@ __EQ16: ; Test if 16bit values HL == DE inc a ret pop namespace -#line 68 "arch/zx48k/shlu16.bas" +#line 71 "arch/zx48k/shlu16.bas" END diff --git a/tests/functional/arch/zx48k/shlu32.asm b/tests/functional/arch/zx48k/shlu32.asm index b8c321254..8953a9dde 100644 --- a/tests/functional/arch/zx48k/shlu32.asm +++ b/tests/functional/arch/zx48k/shlu32.asm @@ -60,6 +60,9 @@ _b: ld hl, (_a) ld de, (_a + 2) call .core.__EQ32 + sub 1 + sbc a, a + inc a push af ld a, (_b) pop hl @@ -118,7 +121,7 @@ __SHL32: ; Left Logical Shift 32 bits rl d ret pop namespace -#line 87 "arch/zx48k/shlu32.bas" +#line 90 "arch/zx48k/shlu32.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 @@ -144,5 +147,5 @@ __EQ32: ; Test if 32bit value HLDE equals top of the stack xor a ret pop namespace -#line 88 "arch/zx48k/shlu32.bas" +#line 91 "arch/zx48k/shlu32.bas" END diff --git a/tests/functional/arch/zx48k/shlu8.asm b/tests/functional/arch/zx48k/shlu8.asm index eee1cb31d..889d1a3db 100644 --- a/tests/functional/arch/zx48k/shlu8.asm +++ b/tests/functional/arch/zx48k/shlu8.asm @@ -46,6 +46,7 @@ _b: sub h sub 1 sbc a, a + neg push af ld a, (_b) pop hl diff --git a/tests/functional/arch/zx48k/shri16.asm b/tests/functional/arch/zx48k/shri16.asm index cc39a1cf6..60cf162c9 100644 --- a/tests/functional/arch/zx48k/shri16.asm +++ b/tests/functional/arch/zx48k/shri16.asm @@ -48,6 +48,9 @@ _b: ld de, (_a) ld hl, (_a) call .core.__EQ16 + sub 1 + sbc a, a + inc a push af ld a, (_b) pop hl @@ -103,5 +106,5 @@ __EQ16: ; Test if 16bit values HL == DE inc a ret pop namespace -#line 71 "arch/zx48k/shri16.bas" +#line 74 "arch/zx48k/shri16.bas" END diff --git a/tests/functional/arch/zx48k/shri32.asm b/tests/functional/arch/zx48k/shri32.asm index 30283b7dd..a650ae561 100644 --- a/tests/functional/arch/zx48k/shri32.asm +++ b/tests/functional/arch/zx48k/shri32.asm @@ -60,6 +60,9 @@ _b: ld hl, (_a) ld de, (_a + 2) call .core.__EQ32 + sub 1 + sbc a, a + inc a push af ld a, (_b) pop hl @@ -122,7 +125,7 @@ __SHRA32: ; Right Arithmetical Shift 32 bits rr l ret pop namespace -#line 91 "arch/zx48k/shri32.bas" +#line 94 "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 @@ -148,5 +151,5 @@ __EQ32: ; Test if 32bit value HLDE equals top of the stack xor a ret pop namespace -#line 92 "arch/zx48k/shri32.bas" +#line 95 "arch/zx48k/shri32.bas" END diff --git a/tests/functional/arch/zx48k/shri8.asm b/tests/functional/arch/zx48k/shri8.asm index c1321ca6c..6e0e12a02 100644 --- a/tests/functional/arch/zx48k/shri8.asm +++ b/tests/functional/arch/zx48k/shri8.asm @@ -46,6 +46,7 @@ _b: sub h sub 1 sbc a, a + neg push af ld a, (_b) pop hl diff --git a/tests/functional/arch/zx48k/shru16.asm b/tests/functional/arch/zx48k/shru16.asm index 42a9aa231..d60b0bc80 100644 --- a/tests/functional/arch/zx48k/shru16.asm +++ b/tests/functional/arch/zx48k/shru16.asm @@ -48,6 +48,9 @@ _b: ld de, (_a) ld hl, (_a) call .core.__EQ16 + sub 1 + sbc a, a + inc a push af ld a, (_b) pop hl @@ -103,5 +106,5 @@ __EQ16: ; Test if 16bit values HL == DE inc a ret pop namespace -#line 71 "arch/zx48k/shru16.bas" +#line 74 "arch/zx48k/shru16.bas" END diff --git a/tests/functional/arch/zx48k/shru32.asm b/tests/functional/arch/zx48k/shru32.asm index 97526a94d..22a7a6f04 100644 --- a/tests/functional/arch/zx48k/shru32.asm +++ b/tests/functional/arch/zx48k/shru32.asm @@ -60,6 +60,9 @@ _b: ld hl, (_a) ld de, (_a + 2) call .core.__EQ32 + sub 1 + sbc a, a + inc a push af ld a, (_b) pop hl @@ -122,7 +125,7 @@ __SHRL32: ; Right Logical Shift 32 bits rr l ret pop namespace -#line 91 "arch/zx48k/shru32.bas" +#line 94 "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 @@ -148,5 +151,5 @@ __EQ32: ; Test if 32bit value HLDE equals top of the stack xor a ret pop namespace -#line 92 "arch/zx48k/shru32.bas" +#line 95 "arch/zx48k/shru32.bas" END diff --git a/tests/functional/arch/zx48k/shru8.asm b/tests/functional/arch/zx48k/shru8.asm index 0b8cf6320..62c886c78 100644 --- a/tests/functional/arch/zx48k/shru8.asm +++ b/tests/functional/arch/zx48k/shru8.asm @@ -46,6 +46,7 @@ _b: sub h sub 1 sbc a, a + neg push af ld a, (_b) pop hl From 7adbea17c92113efa352e2890062c913342a49d7 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 31 Dec 2024 12:19:32 +0100 Subject: [PATCH 2/3] refact: use f-strings --- .../z80/visitor/translator_inst_visitor.py | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/src/arch/z80/visitor/translator_inst_visitor.py b/src/arch/z80/visitor/translator_inst_visitor.py index 36f394fb3..538c9340e 100644 --- a/src/arch/z80/visitor/translator_inst_visitor.py +++ b/src/arch/z80/visitor/translator_inst_visitor.py @@ -52,31 +52,31 @@ def ic_aaddr(self, t1, t2) -> None: self.emit("aaddr", t1, t2) def ic_abs(self, type_: TYPE | sym.BASICTYPE, t1, t2) -> None: - self.emit("abs" + self.TSUFFIX(type_), t1, t2) + self.emit(f"abs{self.TSUFFIX(type_)}", t1, t2) def ic_add(self, type_: TYPE | sym.BASICTYPE, t1, t2, t3) -> None: - self.emit("add" + self.TSUFFIX(type_), t1, t2, t3) + self.emit(f"add{self.TSUFFIX(type_)}", t1, t2, t3) def ic_aload(self, type_: TYPE | sym.BASICTYPE, t1, mangle: str) -> None: - self.emit("aload" + self.TSUFFIX(type_), t1, mangle) + self.emit(f"aload{self.TSUFFIX(type_)}", t1, mangle) def ic_and(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: self.emit(f"and{self._no_bool(type_)}", t, t1, t2) def ic_astore(self, type_: TYPE | sym.BASICTYPE, addr: str, t) -> None: - self.emit("astore" + self.TSUFFIX(type_), addr, t) + self.emit(f"astore{self.TSUFFIX(type_)}", addr, t) def ic_band(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("band" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"band{self.TSUFFIX(type_)}", t, t1, t2) def ic_bnot(self, type_: TYPE | sym.BASICTYPE, t1, t2) -> None: - self.emit("bnot" + self.TSUFFIX(type_), t1, t2) + self.emit(f"bnot{self.TSUFFIX(type_)}", t1, t2) def ic_bor(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("bor" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"bor{self.TSUFFIX(type_)}", t, t1, t2) def ic_bxor(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("bxor" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"bxor{self.TSUFFIX(type_)}", t, t1, t2) def ic_call(self, label: str, num: int) -> None: self.emit("call", label, num) @@ -91,7 +91,7 @@ def ic_deflabel(self, label: str, t) -> None: self.emit("deflabel", label, t) def ic_div(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("div" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"div{self.TSUFFIX(type_)}", t, t1, t2) def ic_end(self, t) -> None: self.emit("end", t) @@ -100,7 +100,7 @@ def ic_enter(self, arg) -> None: self.emit("enter", arg) def ic_eq(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("eq" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"eq{self.TSUFFIX(type_)}", t, t1, t2) def ic_exchg(self) -> None: self.emit("exchg") @@ -109,13 +109,13 @@ def ic_fparam(self, type_: TYPE | sym.BASICTYPE, t) -> None: self.emit(f"fparam{self._no_bool(type_)}", t) def ic_fpload(self, type_: TYPE | sym.BASICTYPE, t, offset) -> None: - self.emit("fpload" + self.TSUFFIX(type_), t, offset) + self.emit(f"fpload{self.TSUFFIX(type_)}", t, offset) def ic_ge(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("ge" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"ge{self.TSUFFIX(type_)}", t, t1, t2) def ic_gt(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("gt" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"gt{self.TSUFFIX(type_)}", t, t1, t2) def ic_in(self, t) -> None: self.emit("in", t) @@ -142,7 +142,7 @@ def ic_larrd(self, offset, arg1, size, arg2, bound_ptrs) -> None: self.emit("larrd", offset, arg1, size, arg2, bound_ptrs) def ic_le(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("le" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"le{self.TSUFFIX(type_)}", t, t1, t2) def ic_leave(self, convention: str) -> None: self.emit("leave", convention) @@ -151,10 +151,10 @@ def ic_lenstr(self, t1, t2) -> None: self.emit("lenstr", t1, t2) def ic_load(self, type_: TYPE | sym.BASICTYPE, t1, t2) -> None: - self.emit("load" + self.TSUFFIX(type_), t1, t2) + self.emit(f"load{self.TSUFFIX(type_)}", t1, t2) def ic_lt(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("lt" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"lt{self.TSUFFIX(type_)}", t, t1, t2) def ic_lvard(self, offset, default_value: list) -> None: self.emit("lvard", offset, default_value) @@ -166,16 +166,16 @@ def ic_memcopy(self, t1, t2, t3) -> None: self.emit("memcopy", t1, t2, t3) def ic_mod(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("mod" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"mod{self.TSUFFIX(type_)}", t, t1, t2) def ic_mul(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("mul" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"mul{self.TSUFFIX(type_)}", t, t1, t2) def ic_ne(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("ne" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"ne{self.TSUFFIX(type_)}", t, t1, t2) def ic_neg(self, type_: TYPE | sym.BASICTYPE, t1, t2) -> None: - self.emit("neg" + self.TSUFFIX(type_), t1, t2) + self.emit(f"neg{self.TSUFFIX(type_)}", t1, t2) def ic_nop(self) -> None: self.emit("nop") @@ -186,9 +186,6 @@ def ic_not(self, type_: TYPE | sym.BASICTYPE, t1, t2) -> None: def ic_or(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: self.emit(f"or{self._no_bool(type_)}", t, t1, t2) - def ic_org(self, type_: TYPE | sym.BASICTYPE) -> None: - self.emit("org" + self.TSUFFIX(type_)) - def ic_out(self, t1, t2) -> None: self.emit("out", t1, t2) @@ -199,25 +196,25 @@ def ic_paddr(self, t1, t2) -> None: self.emit("paddr", t1, t2) def ic_paload(self, type_: TYPE | sym.BASICTYPE, t, offset: int) -> None: - self.emit("paload" + self.TSUFFIX(type_), t, offset) + self.emit(f"paload{self.TSUFFIX(type_)}", t, offset) def ic_param(self, type_: TYPE | sym.BASICTYPE, t) -> None: - self.emit("param" + self.TSUFFIX(type_), t) + self.emit(f"param{self.TSUFFIX(type_)}", t) def ic_pastore(self, type_: TYPE | sym.BASICTYPE, offset, t) -> None: - self.emit("pastore" + self.TSUFFIX(type_), offset, t) + self.emit(f"pastore{self.TSUFFIX(type_)}", offset, t) def ic_pload(self, type_: TYPE | sym.BASICTYPE, t1, offset) -> None: - self.emit("pload" + self.TSUFFIX(type_), t1, offset) + self.emit(f"pload{self.TSUFFIX(type_)}", t1, offset) def ic_pow(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("pow" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"pow{self.TSUFFIX(type_)}", t, t1, t2) def ic_pstore(self, type_: TYPE | sym.BASICTYPE, offset, t) -> None: - self.emit("pstore" + self.TSUFFIX(type_), offset, t) + self.emit(f"pstore{self.TSUFFIX(type_)}", offset, t) def ic_ret(self, type_: TYPE | sym.BASICTYPE, t, addr) -> None: - self.emit("ret" + self.TSUFFIX(type_), t, addr) + self.emit(f"ret{self.TSUFFIX(type_)}", t, addr) def ic_return(self, addr) -> None: self.emit("ret", addr) @@ -229,10 +226,10 @@ def ic_shr(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: self.emit(f"shr{self.TSUFFIX(type_)}", t, t1, t2) def ic_store(self, type_: TYPE | sym.BASICTYPE, t1, t2) -> None: - self.emit("store" + self.TSUFFIX(type_), t1, t2) + self.emit(f"store{self.TSUFFIX(type_)}", t1, t2) def ic_sub(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("sub" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"sub{self.TSUFFIX(type_)}", t, t1, t2) def ic_var(self, name: str, size_) -> None: self.emit("var", name, size_) From 0b8dc9ffa7815ab416d8ff60e2c9b6aabccb04fe Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 31 Dec 2024 12:25:10 +0100 Subject: [PATCH 3/3] test: update tests for arith operators --- tests/functional/arch/zx48k/divu8.asm | 21 +++++++++++++++++++-- tests/functional/arch/zx48k/divu8.bas | 2 ++ tests/functional/arch/zx48k/mul8.asm | 21 +++++++++++++++++++-- tests/functional/arch/zx48k/mul8.bas | 2 ++ tests/functional/arch/zx48k/sub8.asm | 17 +++++++++++++++++ tests/functional/arch/zx48k/sub8.bas | 2 ++ 6 files changed, 61 insertions(+), 4 deletions(-) diff --git a/tests/functional/arch/zx48k/divu8.asm b/tests/functional/arch/zx48k/divu8.asm index 2c278cf18..9990faf23 100644 --- a/tests/functional/arch/zx48k/divu8.asm +++ b/tests/functional/arch/zx48k/divu8.asm @@ -51,6 +51,23 @@ _b: ld hl, (_a - 1) call .core.__DIVU8_FAST ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + push af + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + ld h, a + pop af + call .core.__DIVU8_FAST + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -66,7 +83,7 @@ _b: ei ret ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div8.asm" ; -------------------------------- push namespace core __DIVU8: ; 8 bit unsigned integer division @@ -131,5 +148,5 @@ __MODI8_FAST: ; __FASTCALL__ entry ld a, l ; remainder ret ; a = Modulus pop namespace -#line 44 "divu8.bas" +#line 61 "arch/zx48k/divu8.bas" END diff --git a/tests/functional/arch/zx48k/divu8.bas b/tests/functional/arch/zx48k/divu8.bas index a8526bc53..a66a1e268 100644 --- a/tests/functional/arch/zx48k/divu8.bas +++ b/tests/functional/arch/zx48k/divu8.bas @@ -11,3 +11,5 @@ b = 1 / a b = 2 / a b = 4 / a b = a / a +b = (a = a) / (a = a) + diff --git a/tests/functional/arch/zx48k/mul8.asm b/tests/functional/arch/zx48k/mul8.asm index 946f72f8a..ed768ffe3 100644 --- a/tests/functional/arch/zx48k/mul8.asm +++ b/tests/functional/arch/zx48k/mul8.asm @@ -52,6 +52,23 @@ _b: ld a, (_a) call .core.__MUL8_FAST ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + push af + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + ld h, a + pop af + call .core.__MUL8_FAST + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -67,7 +84,7 @@ _b: ei ret ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul8.asm" push namespace core __MUL8: ; Performs 8bit x 8bit multiplication PROC @@ -113,5 +130,5 @@ __MUL8B: ret ; result = HL ENDP pop namespace -#line 45 "mul8.bas" +#line 62 "arch/zx48k/mul8.bas" END diff --git a/tests/functional/arch/zx48k/mul8.bas b/tests/functional/arch/zx48k/mul8.bas index 90671ea95..5e53e7a63 100644 --- a/tests/functional/arch/zx48k/mul8.bas +++ b/tests/functional/arch/zx48k/mul8.bas @@ -12,3 +12,5 @@ b = 1 * a b = 2 * a b = 4 * a b = a * a +b = (a = a) * (a = a) + diff --git a/tests/functional/arch/zx48k/sub8.asm b/tests/functional/arch/zx48k/sub8.asm index 995f94109..d9660b907 100644 --- a/tests/functional/arch/zx48k/sub8.asm +++ b/tests/functional/arch/zx48k/sub8.asm @@ -40,6 +40,23 @@ _b: ld hl, (_a - 1) sub h ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + push af + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + neg + ld h, a + pop af + sub h + ld (_b), a ld hl, 0 ld b, h ld c, l diff --git a/tests/functional/arch/zx48k/sub8.bas b/tests/functional/arch/zx48k/sub8.bas index 3a1c98f00..1e798eb6d 100644 --- a/tests/functional/arch/zx48k/sub8.bas +++ b/tests/functional/arch/zx48k/sub8.bas @@ -8,3 +8,5 @@ b = a - 1 b = 0 - a b = 1 - a b = a - a +b = (a = a) - (a = a) +