optimized lsb(msb(longvar)) which grabs the bank byte from a long

This commit is contained in:
Irmen de Jong
2026-01-01 21:39:34 +01:00
parent 50b8cae519
commit 82693cc3ee
3 changed files with 23 additions and 8 deletions
@@ -615,6 +615,15 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
val cast = TypecastExpression(arg.expression, DataType.UBYTE, true, arg.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, cast, parent))
}
} else if(arg is FunctionCallExpression && arg.target.nameInSource == listOf("msw")) {
// lsb(msb(longvar)) --> @(&longvar+2) ; get the bank byte from a long variable
val longvar = arg.args[0] as? IdentifierReference
if(longvar!=null && longvar.inferType(program).isLong) {
val address = AddressOf(longvar, null, null, false, false, functionCallExpr.position)
val plus2 = BinaryExpression(address, "+", NumericLiteral(BaseDataType.UWORD, 2.0, functionCallExpr.position), functionCallExpr.position)
val memread = DirectMemoryRead(plus2, functionCallExpr.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, memread, parent))
}
} else {
if(arg is IdentifierReference && arg.nameInSource.size==2
&& arg.nameInSource[0]=="cx16" && arg.nameInSource[1].uppercase() in RegisterOrPair.names) {
+3 -1
View File
@@ -101,9 +101,11 @@ msb (x)
msw (x)
Get the most significant (higher) word of the value x. For all word and byte numbers this will always result in 0.
For a long integer though, it returns the upper 16 bits of x as an uword.
If x is not greater than a 24 bit number ($ffffff), ``msw(x)`` will actually give you the bank byte of x (bits 16 to 23).
If x is a constant integer not greater than a 24 bit number ($ffffff), ``msw(x)`` will actually give you the bank byte of x (bits 16 to 23).
You can treat this as an ubyte value, even if the function is normally returning a uword:
``msw($123456)`` is $0012, which you can treat as an ubyte. ``msw($12345678)`` is $1234, an uword.
``msw`` of a *variable* will always be considered to be an uword, so to grab the bank byte of a long variable, you need to do this:
``lsb(msw(longvariable))`` (or the equivalent, ``@(&longvariable+2)``).
mkword (msb, lsb)
Efficiently create a word value from two bytes (the msb and the lsb). Avoids multiplication and shifting.
+11 -7
View File
@@ -1,18 +1,22 @@
%import textio
%import test_stack
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
sys.save_prog8_internals()
sys.restore_prog8_internals()
const long longconst = $12345678
long @shared longvar = $abcdef99
txt.print_uwhex(sys.progstart(), true)
txt.nl()
txt.print_uwhex(sys.progend(), true)
txt.print_uwhex(msw(longconst), true)
txt.spc()
txt.print_ubhex(lsb(msw(longconst)), true)
txt.nl()
txt.print_uwhex(msw(longvar), true)
txt.spc()
txt.print_ubhex(lsb(msw(longvar)), true)
txt.spc()
txt.print_ubhex(@(&longvar+2), true)
txt.nl()
}
}