diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index c9b97f5ad..51a144eb1 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -167,15 +167,18 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express } else false if (assignment.value is PtMachineRegister) { valueRegister = (assignment.value as PtMachineRegister).register - if(extendByteToWord) - addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister), null) + if(extendByteToWord) { + valueRegister = codeGen.registers.nextFree() + addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister, reg2=(assignment.value as PtMachineRegister).register), null) + } } else { val tr = expressionEval.translateExpression(assignment.value) valueRegister = tr.resultReg addToResult(result, tr, valueRegister, -1) if(extendByteToWord) { + valueRegister = codeGen.registers.nextFree() val opcode = if(assignment.value.type in SignedDatatypes) Opcode.EXTS else Opcode.EXT - addInstr(result, IRInstruction(opcode, IRDataType.BYTE, reg1 = valueRegister), null) + addInstr(result, IRInstruction(opcode, IRDataType.BYTE, reg1=valueRegister, reg2=tr.resultReg), null) } } } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index 486de7abd..cd4f60d84 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -172,10 +172,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe val compareReg = codeGen.registers.nextFree() result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=tr.resultReg) - it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, immediate = 0x80) - it += IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1=compareReg, immediate = 0, labelSymbol = notNegativeLabel) + it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel) it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=tr.resultReg) - it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=tr.resultReg) } result += IRCodeChunk(notNegativeLabel, null) return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1) @@ -185,8 +183,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe val compareReg = codeGen.registers.nextFree() result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=tr.resultReg) - it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, immediate = 0x8000) - it += IRInstruction(Opcode.BEQ, IRDataType.WORD, reg1=compareReg, immediate = 0, labelSymbol = notNegativeLabel) + it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel) it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=tr.resultReg) } result += IRCodeChunk(notNegativeLabel, null) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index 3b4539b9e..1dbe1173f 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -274,13 +274,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { when(cast.value.type) { DataType.BYTE -> { // byte -> uword: sign extend - actualResultReg2 = tr.resultReg - addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2), null) + actualResultReg2 = codeGen.registers.nextFree() + addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null) } DataType.UBYTE -> { // ubyte -> uword: sign extend - actualResultReg2 = tr.resultReg - addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2), null) + actualResultReg2 = codeGen.registers.nextFree() + addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null) } DataType.WORD -> { actualResultReg2 = tr.resultReg @@ -296,13 +296,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { when(cast.value.type) { DataType.BYTE -> { // byte -> word: sign extend - actualResultReg2 = tr.resultReg - addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2), null) + actualResultReg2 = codeGen.registers.nextFree() + addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null) } DataType.UBYTE -> { // byte -> word: sign extend - actualResultReg2 = tr.resultReg - addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2), null) + actualResultReg2 = codeGen.registers.nextFree() + addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null) } DataType.UWORD -> { actualResultReg2 = tr.resultReg diff --git a/docs/source/todo.rst b/docs/source/todo.rst index cfd78d2a5..a295a1981 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,7 +2,7 @@ TODO ==== - fix VM print_w -- fix VM abs(byte) it always returns 0 +- fix VM abs(byte) it always returns 0 also check abs(word) - IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register. ... diff --git a/examples/test.p8 b/examples/test.p8 index 67f51d3f6..9ba8aef3d 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,28 +3,13 @@ %option no_sysinit main { + sub set_color(ubyte dummy, uword arg) { + arg++ + } + sub start() { - ubyte @shared current = cx16.screen_mode(0, true) - ubyte @shared width - ubyte @shared height - txt.print_ub(current) - txt.nl() - cx16.set_screen_mode(128) - %asm {{ - phx - jsr cx16.get_screen_mode - sta p8_current - stx p8_width - sty p8_height - plx - }} - txt.print_ub(current) - txt.spc() - txt.print_ub(width) - txt.spc() - txt.print_ub(height) - txt.nl() - txt.nl() + ubyte intens + set_color(0, (intens >> 1) * $111) byte intensity = -25 txt.print_b(intensity) diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 2e615ab4e..a706f0d7e 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -115,8 +115,8 @@ ARITHMETIC ---------- All have type b or w or f. Note: result types are the same as operand types! E.g. byte*byte->byte. -exts reg1 - reg1 = signed extension of reg1 (byte to word, or word to long) (note: unlike M68k, exts.b -> word and exts.w -> long. The latter is not yet implemented yet as we don't have longs yet) -ext reg1 - reg1 = unsigned extension of reg1 (which in practice just means clearing the MSB / MSW) (note: unlike M68k, ext.b -> word and ext.w -> long. The latter is not yet implemented yet as we don't have longs yet) +exts reg1, reg2 - reg1 = signed extension of reg2 (byte to word, or word to long) (note: unlike M68k, exts.b -> word and exts.w -> long. The latter is not yet implemented yet as we don't have longs yet) +ext reg1, reg2 - reg1 = unsigned extension of reg2 (which in practice just means clearing the MSB / MSW) (note: unlike M68k, ext.b -> word and ext.w -> long. The latter is not yet implemented yet as we don't have longs yet) inc reg1 - reg1 = reg1+1 incm address - memory at address += 1 dec reg1 - reg1 = reg1-1 @@ -583,8 +583,8 @@ val instructionFormats = mutableMapOf( Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,r1,r1"), - Opcode.EXTS to InstructionFormat.from("BW,<>r1"), + Opcode.EXT to InstructionFormat.from("BW,>r1,r1,r1,r1,a"),