mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimized codegen for logical expressions with simple right operand (such as c64.READST() & $40 )
This commit is contained in:
parent
a1d04f2aad
commit
ca1089b881
@ -378,48 +378,60 @@ internal class AssignmentAsmGen(private val program: Program,
|
||||
if(!expr.inferType(program).isInteger)
|
||||
return false
|
||||
|
||||
if(expr.operator in setOf("&", "|", "^", "and", "or", "xor")) {
|
||||
if(expr.left.inferType(program).isBytes && expr.right.inferType(program).isBytes &&
|
||||
expr.left.isSimple && expr.right.isSimple) {
|
||||
if(expr.right is NumericLiteral || expr.right is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandByte(assign.target, expr.left, expr.operator, expr.right)
|
||||
else if(expr.left is NumericLiteral || expr.left is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandByte(assign.target, expr.right, expr.operator, expr.left)
|
||||
else {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
||||
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE, expr.definingSubroutine)
|
||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
||||
when (expr.operator) {
|
||||
"&", "and" -> asmgen.out(" and P8ZP_SCRATCH_B1")
|
||||
"|", "or" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
|
||||
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
||||
else -> throw AssemblyError("invalid operator")
|
||||
}
|
||||
assignRegisterByte(assign.target, CpuRegister.A)
|
||||
fun simpleLogicalBytesExpr() {
|
||||
// both left and right expression operands are simple.
|
||||
if (expr.right is NumericLiteral || expr.right is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandByte(assign.target, expr.left, expr.operator, expr.right)
|
||||
else if (expr.left is NumericLiteral || expr.left is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandByte(assign.target, expr.right, expr.operator, expr.left)
|
||||
else {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
||||
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE, expr.definingSubroutine)
|
||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
||||
when (expr.operator) {
|
||||
"&", "and" -> asmgen.out(" and P8ZP_SCRATCH_B1")
|
||||
"|", "or" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
|
||||
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
||||
else -> throw AssemblyError("invalid operator")
|
||||
}
|
||||
return true
|
||||
assignRegisterByte(assign.target, CpuRegister.A)
|
||||
}
|
||||
if(expr.left.inferType(program).isWords && expr.right.inferType(program).isWords &&
|
||||
expr.left.isSimple && expr.right.isSimple) {
|
||||
if(expr.right is NumericLiteral || expr.right is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandWord(assign.target, expr.left, expr.operator, expr.right)
|
||||
else if(expr.left is NumericLiteral || expr.left is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandWord(assign.target, expr.right, expr.operator, expr.left)
|
||||
else {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
||||
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_W1", DataType.UWORD, expr.definingSubroutine)
|
||||
when (expr.operator) {
|
||||
"&", "and" -> asmgen.out(" pla | and P8ZP_SCRATCH_W1+1 | tay | pla | and P8ZP_SCRATCH_W1")
|
||||
"|", "or" -> asmgen.out(" pla | ora P8ZP_SCRATCH_W1+1 | tay | pla | ora P8ZP_SCRATCH_W1")
|
||||
"^", "xor" -> asmgen.out(" pla | eor P8ZP_SCRATCH_W1+1 | tay | pla | eor P8ZP_SCRATCH_W1")
|
||||
else -> throw AssemblyError("invalid operator")
|
||||
}
|
||||
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||
}
|
||||
|
||||
fun simpleLogicalWordsExpr() {
|
||||
// both left and right expression operands are simple.
|
||||
if (expr.right is NumericLiteral || expr.right is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandWord(assign.target, expr.left, expr.operator, expr.right)
|
||||
else if (expr.left is NumericLiteral || expr.left is IdentifierReference)
|
||||
assignLogicalWithSimpleRightOperandWord(assign.target, expr.right, expr.operator, expr.left)
|
||||
else {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
||||
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_W1", DataType.UWORD, expr.definingSubroutine)
|
||||
when (expr.operator) {
|
||||
"&", "and" -> asmgen.out(" pla | and P8ZP_SCRATCH_W1+1 | tay | pla | and P8ZP_SCRATCH_W1")
|
||||
"|", "or" -> asmgen.out(" pla | ora P8ZP_SCRATCH_W1+1 | tay | pla | ora P8ZP_SCRATCH_W1")
|
||||
"^", "xor" -> asmgen.out(" pla | eor P8ZP_SCRATCH_W1+1 | tay | pla | eor P8ZP_SCRATCH_W1")
|
||||
else -> throw AssemblyError("invalid operator")
|
||||
}
|
||||
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||
}
|
||||
}
|
||||
|
||||
if(expr.operator in setOf("&", "|", "^", "and", "or", "xor")) {
|
||||
if (expr.left.inferType(program).isBytes && expr.right.inferType(program).isBytes) {
|
||||
if (expr.right.isSimple) {
|
||||
simpleLogicalBytesExpr()
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (expr.left.inferType(program).isWords && expr.right.inferType(program).isWords) {
|
||||
if (expr.right.isSimple) {
|
||||
simpleLogicalWordsExpr()
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- why slow stack eval for "if c64.READST() & $40" ?
|
||||
- regression test the various projects before release
|
||||
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user