added more asmgen for bitshift operations

This commit is contained in:
Irmen de Jong 2019-08-22 00:34:17 +02:00
parent 38208a7c9e
commit b79af624ae
6 changed files with 151 additions and 34 deletions

View File

@ -160,6 +160,8 @@ interface INameScope {
}
}
interface IAssignable {}
/*********** Everything starts from here, the Program; zero or more modules *************/

View File

@ -1,9 +1,6 @@
package prog8.ast.expressions
import prog8.ast.IFunctionCall
import prog8.ast.INameScope
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.*
import prog8.ast.antlr.escape
import prog8.ast.base.*
import prog8.ast.processing.IAstModifyingVisitor
@ -183,7 +180,7 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex
class ArrayIndexedExpression(var identifier: IdentifierReference,
val arrayspec: ArrayIndex,
override val position: Position) : Expression() {
override val position: Position) : Expression(), IAssignable {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
this.parent = parent
@ -252,7 +249,7 @@ data class AddressOf(var identifier: IdentifierReference, override val position:
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
}
class DirectMemoryRead(var addressExpression: Expression, override val position: Position) : Expression() {
class DirectMemoryRead(var addressExpression: Expression, override val position: Position) : Expression(), IAssignable {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -583,7 +580,7 @@ internal fun makeRange(fromVal: Int, toVal: Int, stepVal: Int): IntProgression {
}
}
class RegisterExpr(val register: Register, override val position: Position) : Expression() {
class RegisterExpr(val register: Register, override val position: Position) : Expression(), IAssignable {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -601,7 +598,7 @@ class RegisterExpr(val register: Register, override val position: Position) : Ex
override fun inferType(program: Program): InferredTypes.InferredType = InferredTypes.knownFor(DataType.UBYTE)
}
data class IdentifierReference(val nameInSource: List<String>, override val position: Position) : Expression() {
data class IdentifierReference(val nameInSource: List<String>, override val position: Position) : Expression(), IAssignable {
override lateinit var parent: Node
fun targetStatement(namespace: INameScope) =

View File

@ -37,7 +37,6 @@ sealed class Statement : Node {
}
}
class BuiltinFunctionStatementPlaceholder(val name: String, override val position: Position) : Statement() {
override var parent: Node = ParentSentinel
override fun linkParents(parent: Node) {}
@ -47,10 +46,8 @@ class BuiltinFunctionStatementPlaceholder(val name: String, override val positio
override val expensiveToInline = false
}
data class RegisterOrStatusflag(val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?, val stack: Boolean)
class Block(override val name: String,
val address: Int?,
override var statements: MutableList<Statement>,
@ -792,4 +789,3 @@ class DirectMemoryWrite(var addressExpression: Expression, override val position
fun accept(visitor: IAstVisitor) = visitor.visit(this)
fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
}

View File

@ -156,7 +156,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
is IdentifierReference -> asmgen.out(" asl ${asmgen.asmIdentifierName(what)}")
is DirectMemoryRead -> {
if (what.addressExpression is NumericLiteralValue) {
asmgen.out(" asl ${(what.addressExpression as NumericLiteralValue).number.toHex()}")
val number = (what.addressExpression as NumericLiteralValue).number
asmgen.out(" asl ${number.toHex()}")
} else {
TODO("lsl memory byte $what")
}
@ -197,7 +198,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
is IdentifierReference -> asmgen.out(" lsr ${asmgen.asmIdentifierName(what)}")
is DirectMemoryRead -> {
if (what.addressExpression is NumericLiteralValue) {
asmgen.out(" lsr ${(what.addressExpression as NumericLiteralValue).number.toHex()}")
val number = (what.addressExpression as NumericLiteralValue).number
asmgen.out(" lsr ${number.toHex()}")
} else {
TODO("lsr memory byte $what")
}
@ -211,8 +213,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
DataType.BYTE -> {
when (what) {
is ArrayIndexedExpression -> TODO("lsr sbyte $what")
is DirectMemoryRead -> TODO("lsr sbyte $what")
is RegisterExpr -> TODO("lsr sbyte $what")
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" lda $variable | asl a | ror $variable")
@ -249,10 +249,39 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val dt = what.inferType(program)
when (dt.typeOrElse(DataType.STRUCT)) {
DataType.UBYTE -> {
TODO("rol ubyte")
when(what) {
is ArrayIndexedExpression -> TODO("rol ubyte array")
is DirectMemoryRead -> {
if (what.addressExpression is NumericLiteralValue) {
val number = (what.addressExpression as NumericLiteralValue).number
asmgen.out(" rol ${number.toHex()}")
} else {
TODO("rol memory byte $what")
}
}
is RegisterExpr -> {
when(what.register) {
Register.A -> asmgen.out(" rol a")
Register.X -> asmgen.out(" txa | rol a | tax")
Register.Y -> asmgen.out(" tya | rol a | tay")
}
}
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" rol $variable")
}
else -> throw AssemblyError("weird type")
}
}
DataType.UWORD -> {
TODO("rol uword")
when(what) {
is ArrayIndexedExpression -> TODO("rol uword array")
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" rol $variable | rol $variable+1")
}
else -> throw AssemblyError("weird type")
}
}
else -> throw AssemblyError("weird type")
}
@ -263,10 +292,39 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val dt = what.inferType(program)
when (dt.typeOrElse(DataType.STRUCT)) {
DataType.UBYTE -> {
TODO("rol2 ubyte")
when(what) {
is ArrayIndexedExpression -> TODO("rol2 ubyte array")
is DirectMemoryRead -> {
if (what.addressExpression is NumericLiteralValue) {
val number = (what.addressExpression as NumericLiteralValue).number
asmgen.out(" lda ${number.toHex()} | cmp #\$80 | rol a | sta ${number.toHex()}")
} else {
TODO("rol2 memory byte $what")
}
}
is RegisterExpr -> {
when(what.register) {
Register.A -> asmgen.out(" cmp #\$80 | rol a ")
Register.X -> asmgen.out(" txa | cmp #\$80 | rol a | tax")
Register.Y -> asmgen.out(" tya | cmp #\$80 | rol a | tay")
}
}
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" lda $variable | cmp #\$80 | rol a | sta $variable")
}
else -> throw AssemblyError("weird type")
}
}
DataType.UWORD -> {
TODO("rol2 uword")
when(what) {
is ArrayIndexedExpression -> TODO("rol2 uword array")
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" asl $variable | rol $variable+1 | bcc + | inc $variable |+ ")
}
else -> throw AssemblyError("weird type")
}
}
else -> throw AssemblyError("weird type")
}
@ -277,10 +335,39 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val dt = what.inferType(program)
when (dt.typeOrElse(DataType.STRUCT)) {
DataType.UBYTE -> {
TODO("ror ubyte")
when(what) {
is ArrayIndexedExpression -> TODO("ror ubyte array")
is DirectMemoryRead -> {
if (what.addressExpression is NumericLiteralValue) {
val number = (what.addressExpression as NumericLiteralValue).number
asmgen.out(" ror ${number.toHex()}")
} else {
TODO("ror memory byte $what")
}
}
is RegisterExpr -> {
when(what.register) {
Register.A -> asmgen.out(" ror a")
Register.X -> asmgen.out(" txa | ror a | tax")
Register.Y -> asmgen.out(" tya | ror a | tay")
}
}
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" ror $variable")
}
else -> throw AssemblyError("weird type")
}
}
DataType.UWORD -> {
TODO("ror uword")
when(what) {
is ArrayIndexedExpression -> TODO("ror uword array")
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" ror $variable+1 | ror $variable")
}
else -> throw AssemblyError("weird type")
}
}
else -> throw AssemblyError("weird type")
}
@ -291,10 +378,38 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val dt = what.inferType(program)
when (dt.typeOrElse(DataType.STRUCT)) {
DataType.UBYTE -> {
TODO("ror2 ubyte")
}
when(what) {
is ArrayIndexedExpression -> TODO("ror2 ubyte array")
is DirectMemoryRead -> {
if (what.addressExpression is NumericLiteralValue) {
val number = (what.addressExpression as NumericLiteralValue).number
asmgen.out(" lda ${number.toHex()} | lsr a | bcc + | ora #\$80 |+ | sta ${number.toHex()}")
} else {
TODO("ror2 memory byte $what")
}
}
is RegisterExpr -> {
when(what.register) {
Register.A -> asmgen.out(" lsr a | bcc + | ora #\$80 |+ ")
Register.X -> asmgen.out(" txa | lsr a | bcc + | ora #\$80 |+ tax ")
Register.Y -> asmgen.out(" tya | lsr a | bcc + | ora #\$80 |+ tay ")
}
}
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" lda $variable | lsr a | bcc + | ora #\$80 |+ | sta $variable")
}
else -> throw AssemblyError("weird type")
} }
DataType.UWORD -> {
TODO("ror2 uword")
when(what) {
is ArrayIndexedExpression -> TODO("ror2 uword array")
is IdentifierReference -> {
val variable = asmgen.asmIdentifierName(what)
asmgen.out(" lsr $variable+1 | ror $variable | bcc + | lda $variable+1 | ora #\$80 | sta $variable+1 |+ ")
}
else -> throw AssemblyError("weird type")
}
}
else -> throw AssemblyError("weird type")
}

View File

@ -768,7 +768,7 @@ rol(x)
Modifies in-place, doesn't return a value (so can't be used in an expression).
rol2(x)
Like _rol but now as 8-bit or 16-bit rotation.
Like ``rol`` but now as 8-bit or 16-bit rotation.
It uses some extra logic to not consider the carry flag as extra rotation bit.
Modifies in-place, doesn't return a value (so can't be used in an expression).
@ -780,7 +780,7 @@ ror(x)
Modifies in-place, doesn't return a value (so can't be used in an expression).
ror2(x)
Like _ror but now as 8-bit or 16-bit rotation.
Like ``ror`` but now as 8-bit or 16-bit rotation.
It uses some extra logic to not consider the carry flag as extra rotation bit.
Modifies in-place, doesn't return a value (so can't be used in an expression).

View File

@ -11,7 +11,8 @@ main {
uword uw
&ubyte membyte=9999
&uword memword=9999
ubyte[10] barray
ubyte[10] ubarray
byte[10] bbarray
sub start() {
lsr(A)
@ -20,6 +21,10 @@ main {
rol(A)
ror2(A)
rol2(A)
lsr(bb)
lsl(bb)
lsr(membyte)
lsl(membyte)
ror(membyte)
@ -38,12 +43,14 @@ main {
rol(@(9999))
ror2(@(9999))
rol2(@(9999))
lsr(barray[1])
lsl(barray[1])
ror(barray[1])
rol(barray[1])
ror2(barray[1])
rol2(barray[1])
lsr(ubarray[1])
lsl(ubarray[1])
ror(ubarray[1])
rol(ubarray[1])
ror2(ubarray[1])
rol2(ubarray[1])
lsr(bbarray[1])
lsl(bbarray[1])
bb /= 2