mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
more efficient code for inc/dec on arrays
This commit is contained in:
parent
8adbcb7a26
commit
c58b862b34
@ -22,27 +22,20 @@
|
||||
|
||||
sub start() {
|
||||
|
||||
c64scr.print(" X=")
|
||||
c64scr.print_ub(X)
|
||||
c64.CHROUT('\n')
|
||||
; c64scr.print(" X=")
|
||||
; c64scr.print_ub(X)
|
||||
; c64.CHROUT('\n')
|
||||
|
||||
c64scr.print(" X=")
|
||||
c64scr.print_ub(X)
|
||||
c64.CHROUT('\n')
|
||||
ubyte[256] screenarray
|
||||
ubyte index = 2
|
||||
screenarray[1]--
|
||||
screenarray[index]--
|
||||
|
||||
|
||||
; c64scr.print(" X=")
|
||||
; c64scr.print_ub(X)
|
||||
; c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
~ irq {
|
||||
|
||||
sub irq() {
|
||||
memory ubyte[256] screenarray = $0400
|
||||
memory ubyte firstscreenchar = $0400
|
||||
|
||||
screenarray[0]++ ; @todo incorrect code generated?
|
||||
firstscreenchar++ ; ... this is okay
|
||||
c64.EXTCOL++
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -342,6 +342,28 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeIncArrayindexedVar(dt: DataType): Opcode {
|
||||
return when(dt) {
|
||||
DataType.ARRAY_UB -> Opcode.INC_INDEXED_VAR_UB
|
||||
DataType.ARRAY_B -> Opcode.INC_INDEXED_VAR_B
|
||||
DataType.ARRAY_UW -> Opcode.INC_INDEXED_VAR_UW
|
||||
DataType.ARRAY_W -> Opcode.INC_INDEXED_VAR_W
|
||||
DataType.ARRAY_F -> Opcode.INC_INDEXED_VAR_FLOAT
|
||||
else -> throw CompilerException("can't inc type $dt")
|
||||
}
|
||||
}
|
||||
|
||||
private fun opcodeDecArrayindexedVar(dt: DataType): Opcode {
|
||||
return when(dt) {
|
||||
DataType.ARRAY_UB -> Opcode.DEC_INDEXED_VAR_UB
|
||||
DataType.ARRAY_B -> Opcode.DEC_INDEXED_VAR_B
|
||||
DataType.ARRAY_UW -> Opcode.DEC_INDEXED_VAR_UW
|
||||
DataType.ARRAY_W -> Opcode.DEC_INDEXED_VAR_W
|
||||
DataType.ARRAY_F -> Opcode.DEC_INDEXED_VAR_FLOAT
|
||||
else -> throw CompilerException("can't dec type $dt")
|
||||
}
|
||||
}
|
||||
|
||||
private fun translate(stmt: InlineAssembly) {
|
||||
prog.instr(Opcode.INLINE_ASSEMBLY, callLabel = stmt.assembly)
|
||||
}
|
||||
@ -573,7 +595,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
DataType.ARRAY_B, DataType.ARRAY_W -> {
|
||||
if(lv.heapId==null)
|
||||
throw CompilerException("array should have been moved into heap ${lv.position}")
|
||||
prog.instr(Opcode.PUSH_WORD, Value(lv.type, lv.heapId))
|
||||
prog.instr(Opcode.PUSH_WORD, Value(lv.type, lv.heapId)) // XXX push address of array
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -634,7 +656,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
DataType.UWORD -> prog.instr(Opcode.PUSH_MEM_UW, Value(DataType.UWORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
DataType.WORD -> prog.instr(Opcode.PUSH_MEM_W, Value(DataType.UWORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
DataType.FLOAT -> prog.instr(Opcode.PUSH_MEM_FLOAT, Value(DataType.UWORD, (target.value as LiteralValue).asNumericValue!!))
|
||||
else -> TODO("invalid datatype for memory variable expression: $target")
|
||||
else -> throw CompilerException("invalid datatype for memory variable expression: $target")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1213,16 +1235,12 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
}
|
||||
stmt.target.arrayindexed!=null -> {
|
||||
// todo: generate more efficient bytecode for this?
|
||||
translate(stmt.target.arrayindexed!!, false)
|
||||
val one = Value(stmt.target.arrayindexed!!.resultingDatatype(namespace, heap)!!, 1)
|
||||
val opcode = opcodePush(one.type)
|
||||
prog.instr(opcode, one)
|
||||
val variable = stmt.target.arrayindexed!!.identifier?.targetStatement(namespace) as VarDecl
|
||||
translate(stmt.target.arrayindexed!!.arrayspec.x)
|
||||
when(stmt.operator) {
|
||||
"++" -> prog.instr(opcodeAdd(one.type))
|
||||
"--" -> prog.instr(opcodeSub(one.type))
|
||||
"++" -> prog.instr(opcodeIncArrayindexedVar(variable.datatype), callLabel = variable.scopedname)
|
||||
"--" -> prog.instr(opcodeDecArrayindexedVar(variable.datatype), callLabel = variable.scopedname)
|
||||
}
|
||||
translate(stmt.target.arrayindexed!!, true)
|
||||
}
|
||||
else -> throw CompilerException("very strange postincrdecr")
|
||||
}
|
||||
|
@ -192,13 +192,23 @@ enum class Opcode {
|
||||
NOTEQUAL_WORD,
|
||||
NOTEQUAL_F,
|
||||
|
||||
// arrayspec access
|
||||
// array access and simple manipulations
|
||||
READ_INDEXED_VAR_BYTE,
|
||||
READ_INDEXED_VAR_WORD,
|
||||
READ_INDEXED_VAR_FLOAT,
|
||||
WRITE_INDEXED_VAR_BYTE,
|
||||
WRITE_INDEXED_VAR_WORD,
|
||||
WRITE_INDEXED_VAR_FLOAT,
|
||||
INC_INDEXED_VAR_B,
|
||||
INC_INDEXED_VAR_UB,
|
||||
INC_INDEXED_VAR_W,
|
||||
INC_INDEXED_VAR_UW,
|
||||
INC_INDEXED_VAR_FLOAT,
|
||||
DEC_INDEXED_VAR_B,
|
||||
DEC_INDEXED_VAR_UB,
|
||||
DEC_INDEXED_VAR_W,
|
||||
DEC_INDEXED_VAR_UW,
|
||||
DEC_INDEXED_VAR_FLOAT,
|
||||
|
||||
// branching, without consuming a value from the stack
|
||||
JUMP,
|
||||
@ -248,5 +258,9 @@ val opcodesWithVarArgument = setOf(
|
||||
Opcode.POP_VAR_BYTE, Opcode.POP_VAR_WORD, Opcode.POP_VAR_FLOAT,
|
||||
Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_FLOAT, Opcode.PUSH_ADDR_HEAPVAR,
|
||||
Opcode.READ_INDEXED_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.READ_INDEXED_VAR_FLOAT,
|
||||
Opcode.WRITE_INDEXED_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD, Opcode.WRITE_INDEXED_VAR_FLOAT
|
||||
Opcode.WRITE_INDEXED_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD, Opcode.WRITE_INDEXED_VAR_FLOAT,
|
||||
Opcode.INC_INDEXED_VAR_UB, Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UW,
|
||||
Opcode.INC_INDEXED_VAR_W, Opcode.INC_INDEXED_VAR_FLOAT,
|
||||
Opcode.DEC_INDEXED_VAR_UB, Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UW,
|
||||
Opcode.DEC_INDEXED_VAR_W, Opcode.DEC_INDEXED_VAR_FLOAT
|
||||
)
|
||||
|
@ -808,6 +808,26 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((opcodes[0]==Opcode.PUSH_BYTE && opcodes[1] in setOf(Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB,
|
||||
Opcode.INC_INDEXED_VAR_UW, Opcode.INC_INDEXED_VAR_W, Opcode.INC_INDEXED_VAR_FLOAT,
|
||||
Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB, Opcode.DEC_INDEXED_VAR_W,
|
||||
Opcode.DEC_INDEXED_VAR_UW, Opcode.DEC_INDEXED_VAR_FLOAT))) {
|
||||
val fragment = sameConstantIndexedVarOperation(segment[1].callLabel!!, segment[0].arg!!.integerValue(), segment[1])
|
||||
if(fragment!=null) {
|
||||
fragment.segmentSize=2
|
||||
result.add(fragment)
|
||||
}
|
||||
}
|
||||
else if((opcodes[0]==Opcode.PUSH_VAR_BYTE && opcodes[1] in setOf(Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB,
|
||||
Opcode.INC_INDEXED_VAR_UW, Opcode.INC_INDEXED_VAR_W, Opcode.INC_INDEXED_VAR_FLOAT,
|
||||
Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB, Opcode.DEC_INDEXED_VAR_W,
|
||||
Opcode.DEC_INDEXED_VAR_UW, Opcode.DEC_INDEXED_VAR_FLOAT))) {
|
||||
val fragment = sameIndexedVarOperation(segment[1].callLabel!!, segment[0].callLabel!!, segment[1])
|
||||
if(fragment!=null) {
|
||||
fragment.segmentSize=2
|
||||
result.add(fragment)
|
||||
}
|
||||
}
|
||||
else if((opcodes[0]==Opcode.PUSH_MEM_UB && opcodes[2]==Opcode.POP_MEM_BYTE) ||
|
||||
(opcodes[0]==Opcode.PUSH_MEM_B && opcodes[2]==Opcode.POP_MEM_BYTE) ||
|
||||
(opcodes[0]==Opcode.PUSH_MEM_UW && opcodes[2]==Opcode.POP_MEM_WORD) ||
|
||||
@ -877,6 +897,14 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
Opcode.ROR2_BYTE -> AsmFragment(" lda $variable+$index | lsr a | bcc + | ora #\$80 |+ | sta $variable+$index", 10)
|
||||
Opcode.ROL2_WORD -> AsmFragment(" asl $variable+$index | rol $variable+${index+1} | bcc + | inc $variable+$index |+",20)
|
||||
Opcode.ROR2_WORD -> AsmFragment(" lsr $variable+${index+1} | ror $variable+$index | bcc + | lda $variable+${index+1} | ora #\$80 | sta $variable+${index+1} |+", 30)
|
||||
Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB -> AsmFragment(" inc $variable+$index", 2)
|
||||
Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB -> AsmFragment(" dec $variable+$index", 5)
|
||||
Opcode.INC_INDEXED_VAR_W -> TODO("inc array_w")
|
||||
Opcode.INC_INDEXED_VAR_UW -> TODO("inc array_uw")
|
||||
Opcode.INC_INDEXED_VAR_FLOAT -> TODO("inc array_f")
|
||||
Opcode.DEC_INDEXED_VAR_W -> TODO("dec array_w")
|
||||
Opcode.DEC_INDEXED_VAR_UW -> TODO("dec array_uw")
|
||||
Opcode.DEC_INDEXED_VAR_FLOAT -> TODO("dec array_f")
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@ -921,6 +949,15 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
Opcode.ROR2_BYTE -> AsmFragment("$saveX $loadX lda $variable,x | lsr a | bcc + | ora #\$80 |+ | sta $variable,x $restoreX", 10)
|
||||
Opcode.ROL2_WORD -> AsmFragment(" txa | $loadXWord asl $variable,x | rol $variable+1,x | bcc + | inc $variable,x |+ | tax", 30)
|
||||
Opcode.ROR2_WORD -> AsmFragment("$saveX $loadXWord lsr $variable+1,x | ror $variable,x | bcc + | lda $variable+1,x | ora #\$80 | sta $variable+1,x |+ $restoreX", 30)
|
||||
Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB -> AsmFragment(" txa | $loadX inc $variable,x | tax", 10)
|
||||
Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB -> AsmFragment(" txa | $loadX dec $variable,x | tax", 10)
|
||||
Opcode.INC_INDEXED_VAR_W -> TODO("inc array_w")
|
||||
Opcode.INC_INDEXED_VAR_UW -> TODO("inc array_uw")
|
||||
Opcode.INC_INDEXED_VAR_FLOAT -> TODO("inc array_f")
|
||||
Opcode.DEC_INDEXED_VAR_W -> TODO("dec array_w")
|
||||
Opcode.DEC_INDEXED_VAR_UW -> TODO("dec array_uw")
|
||||
Opcode.DEC_INDEXED_VAR_FLOAT -> TODO("dec array_f")
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@ -2807,7 +2844,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE)) { segment ->
|
||||
" lda ${hexVal(segment[0])} | eor #${hexVal(segment[1])} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -944,6 +944,18 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
checkDt(variable, DataType.FLOAT)
|
||||
variables[ins.callLabel] =variable.dec()
|
||||
}
|
||||
Opcode.INC_INDEXED_VAR_B,Opcode.INC_INDEXED_VAR_UB,Opcode.INC_INDEXED_VAR_W,Opcode.INC_INDEXED_VAR_UW,Opcode.INC_INDEXED_VAR_FLOAT -> {
|
||||
val index = evalstack.pop().integerValue()
|
||||
val variable = getVar(ins.callLabel!!)
|
||||
val array = heap.get(variable.heapId)
|
||||
array.array!![index].inc()
|
||||
}
|
||||
Opcode.DEC_INDEXED_VAR_B,Opcode.DEC_INDEXED_VAR_UB,Opcode.DEC_INDEXED_VAR_W,Opcode.DEC_INDEXED_VAR_UW,Opcode.DEC_INDEXED_VAR_FLOAT -> {
|
||||
val index = evalstack.pop().integerValue()
|
||||
val variable = getVar(ins.callLabel!!)
|
||||
val array = heap.get(variable.heapId)
|
||||
array.array!![index].dec()
|
||||
}
|
||||
Opcode.MSB -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UWORD, DataType.WORD)
|
||||
|
Loading…
Reference in New Issue
Block a user