more efficient branch asm, and fixed jump/call asm

This commit is contained in:
Irmen de Jong 2019-01-06 03:09:29 +01:00
parent 775cdd451c
commit a43f81cad4
5 changed files with 100 additions and 43 deletions

View File

@ -17,6 +17,14 @@
word[len(zcoor)] rotatedz=-1
sub start() {
label1:
label2:
Y--
if_mi goto label1
if_mi goto label1 else goto label2
uword anglex
uword angley
uword anglez

View File

@ -61,15 +61,18 @@ sub irq() {
angle++
c64.MSIGX=0
for ubyte i in 0 to 14 step 2 {
word x = (sin8(angle*2-i*8) as word)+190 ; @todo will/should be using shifts for faster multiplication
byte y = cos8(angle*3-i*8) // 2 ; @todo will/should be using shifts for faster multiplication
@(SP0X+i) = lsb(x)
@(SP0Y+i) = y+150 as ubyte
ubyte i=14
lsr(c64.MSIGX)
if msb(x) c64.MSIGX |= %10000000
}
nextsprite: ; @todo should be a for loop from 14 to 0 step -2 but this causes a value out of range error at the moment
word x = (sin8(angle*2-i*8) as word)+190 ; @todo will/should be using shifts for faster multiplication
byte y = cos8(angle*3-i*8) // 2 ; @todo will/should be using shifts for faster multiplication
@(SP0X+i) = lsb(x)
@(SP0Y+i) = y+150 as ubyte
lsl(c64.MSIGX)
if msb(x) c64.MSIGX++
i-=2
if_pl goto nextsprite
c64.EXTCOL++
}

View File

@ -270,9 +270,9 @@ interface IAstProcessor {
return scope
}
fun process(typecastExpression: TypecastExpression): IExpression {
typecastExpression.expression = typecastExpression.expression.process(this)
return typecastExpression
fun process(typecast: TypecastExpression): IExpression {
typecast.expression = typecast.expression.process(this)
return typecast
}
fun process(memread: DirectMemoryRead): IExpression {
@ -1934,7 +1934,7 @@ private fun prog8Parser.ReturnstmtContext.toAst() : Return {
private fun prog8Parser.UnconditionaljumpContext.toAst(): Jump {
val address = integerliteral()?.toAst()?.number?.toInt()
val identifier = scoped_identifier().toAst()
val identifier = scoped_identifier()?.toAst()
return Jump(address, identifier, null, toPosition())
}

View File

@ -195,7 +195,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
is VariableInitializationAssignment -> translate(stmt) // for initializing vars in a scope
is Assignment -> translate(stmt) // normal and augmented assignments
is PostIncrDecr -> translate(stmt)
is Jump -> translate(stmt)
is Jump -> translate(stmt, null)
is FunctionCallStatement -> translate(stmt)
is IfStatement -> translate(stmt)
is BranchStatement -> translate(stmt)
@ -399,35 +399,67 @@ private class StatementTranslator(private val prog: IntermediateProgram,
* _stmt_999_end:
* nop
*
* @todo generate more efficient bytecode for the form with just jumps: if_xx goto .. [else goto ..] ?
* -> this should translate into just a single branch opcode per goto
* if the branch statement just contains jumps, more efficient code is generated.
* (just the appropriate branching instruction is outputted!)
*/
if(branch.elsepart.isEmpty() && branch.truepart.isEmpty())
return
fun branchOpcode(branch: BranchStatement, complement: Boolean) =
if(complement) {
when (branch.condition) {
BranchCondition.CS -> Opcode.BCC
BranchCondition.CC -> Opcode.BCS
BranchCondition.EQ, BranchCondition.Z -> Opcode.BNZ
BranchCondition.NE, BranchCondition.NZ -> Opcode.BZ
BranchCondition.VS -> Opcode.BVC
BranchCondition.VC -> Opcode.BVS
BranchCondition.MI, BranchCondition.NEG -> Opcode.BPOS
BranchCondition.PL, BranchCondition.POS -> Opcode.BNEG
}
} else {
when (branch.condition) {
BranchCondition.CS -> Opcode.BCS
BranchCondition.CC -> Opcode.BCC
BranchCondition.EQ, BranchCondition.Z -> Opcode.BZ
BranchCondition.NE, BranchCondition.NZ -> Opcode.BNZ
BranchCondition.VS -> Opcode.BVS
BranchCondition.VC -> Opcode.BVC
BranchCondition.MI, BranchCondition.NEG -> Opcode.BNEG
BranchCondition.PL, BranchCondition.POS -> Opcode.BPOS
}
}
prog.line(branch.position)
val labelElse = makeLabel("else")
val labelEnd = makeLabel("end")
val opcode = when(branch.condition) {
BranchCondition.CS -> Opcode.BCC
BranchCondition.CC -> Opcode.BCS
BranchCondition.EQ, BranchCondition.Z -> Opcode.BNZ
BranchCondition.NE, BranchCondition.NZ -> Opcode.BZ
BranchCondition.VS -> Opcode.BVC
BranchCondition.VC -> Opcode.BVS
BranchCondition.MI, BranchCondition.NEG -> Opcode.BPOS
BranchCondition.PL, BranchCondition.POS -> Opcode.BNEG
}
if(branch.elsepart.isEmpty()) {
prog.instr(opcode, callLabel = labelEnd)
translate(branch.truepart)
prog.label(labelEnd)
val truejump = branch.truepart.statements.first()
val elsejump = branch.elsepart.statements.firstOrNull()
if(truejump is Jump && truejump.address==null && (elsejump ==null || (elsejump is Jump && elsejump.address==null))) {
// optimized code for just conditional jumping
val opcodeTrue = branchOpcode(branch, false)
translate(truejump, opcodeTrue)
if(elsejump is Jump) {
val opcodeFalse = branchOpcode(branch, true)
translate(elsejump, opcodeFalse)
}
} else {
prog.instr(opcode, callLabel = labelElse)
translate(branch.truepart)
prog.instr(Opcode.JUMP, callLabel = labelEnd)
prog.label(labelElse)
translate(branch.elsepart)
prog.label(labelEnd)
// regular if..else branching
val labelElse = makeLabel("else")
val labelEnd = makeLabel("end")
val opcode = branchOpcode(branch, true)
if (branch.elsepart.isEmpty()) {
prog.instr(opcode, callLabel = labelEnd)
translate(branch.truepart)
prog.label(labelEnd)
} else {
prog.instr(opcode, callLabel = labelElse)
translate(branch.truepart)
prog.instr(Opcode.JUMP, callLabel = labelEnd)
prog.label(labelElse)
translate(branch.elsepart)
prog.label(labelEnd)
}
prog.instr(Opcode.NOP)
}
prog.instr(Opcode.NOP)
}
private fun makeLabel(postfix: String): String {
@ -1235,13 +1267,17 @@ private class StatementTranslator(private val prog: IntermediateProgram,
prog.instr(Opcode.SYSCALL, Value(DataType.UBYTE, callNr))
}
private fun translate(stmt: Jump) {
private fun translate(stmt: Jump, branchOpcode: Opcode?) {
var jumpAddress: Value? = null
var jumpLabel: String? = null
when {
stmt.generatedLabel!=null -> jumpLabel = stmt.generatedLabel
stmt.address!=null -> jumpAddress = Value(DataType.UWORD, stmt.address)
stmt.address!=null -> {
if(branchOpcode!=null)
throw CompilerException("cannot branch to address, should use absolute jump instead")
jumpAddress = Value(DataType.UWORD, stmt.address)
}
else -> {
val target = stmt.identifier!!.targetStatement(namespace)!!
jumpLabel = when(target) {
@ -1252,7 +1288,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
}
}
prog.line(stmt.position)
prog.instr(Opcode.JUMP, jumpAddress, jumpLabel)
prog.instr(branchOpcode ?: Opcode.JUMP, jumpAddress, jumpLabel)
}
private fun translate(stmt: PostIncrDecr) {

View File

@ -414,8 +414,18 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.CLC -> " clc"
Opcode.SEI -> " sei"
Opcode.CLI -> " cli"
Opcode.JUMP -> " jmp ${ins.callLabel}"
Opcode.CALL -> " jsr ${ins.callLabel}"
Opcode.JUMP -> {
if(ins.callLabel!=null)
" jmp ${ins.callLabel}"
else
" jmp ${hexVal(ins)}"
}
Opcode.CALL -> {
if(ins.callLabel!=null)
" jsr ${ins.callLabel}"
else
" jsr ${hexVal(ins)}"
}
Opcode.RETURN -> " rts"
Opcode.RSAVE -> {
// save cpu status flag and all registers A, X, Y.