diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 18d2385f3..32cfe267b 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,7 +1,7 @@ TODO ==== -- IR/VM: fix the vm/textelite game, it now prints garbage! (caused by the SGE opcode implementation change to set -1 instead of 1) +- VM: fix endless loop n=0 :: for i in 5 downto n (fine for n=1) (wrong for bytes and words) - IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register. diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 7e7f98ec6..843e93ab4 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -97,18 +97,19 @@ bgesr reg1, reg2, address - jump to location in program given by l ble reg1, value, address - jump to location in program given by location, if reg1 <= immediate value (unsigned) bles reg1, value, address - jump to location in program given by location, if reg1 <= immediate value (signed) ( NOTE: there are no bltr/bler instructions because these are equivalent to bgtr/bger with the register operands swapped around.) -sz reg1, reg2 - set reg1=-1 (all bits one) if reg2==0, else 0 -snz reg1, reg2 - set reg1=-1 (all bits one) if reg2!=0, else 0 -seq reg1, reg2 - set reg1=-1 (all bits one) if reg1 == reg2, else 0 -sne reg1, reg2 - set reg1=-1 (all bits one) if reg1 != reg2, else 0 -slt reg1, reg2 - set reg1=-1 (all bits one) if reg1 < reg2 (unsigned), else 0 -slts reg1, reg2 - set reg1=-1 (all bits one) if reg1 < reg2 (signed), else 0 -sle reg1, reg2 - set reg1=-1 (all bits one) if reg1 <= reg2 (unsigned), else 0 -sles reg1, reg2 - set reg1=-1 (all bits one) if reg1 <= reg2 (signed), else 0 -sgt reg1, reg2 - set reg1=-1 (all bits one) if reg1 > reg2 (unsigned), else 0 -sgts reg1, reg2 - set reg1=-1 (all bits one) if reg1 > reg2 (signed), else 0 -sge reg1, reg2 - set reg1=-1 (all bits one) if reg1 >= reg2 (unsigned), else 0 -sges reg1, reg2 - set reg1=-1 (all bits one) if reg1 >= reg2 (signed), else 0 +sz reg1, reg2 - set reg1=1 if reg2==0, else 0 +snz reg1, reg2 - set reg1=1 if reg2!=0, else 0 +seq reg1, reg2 - set reg1=1 if reg1 == reg2, else 0 +sne reg1, reg2 - set reg1=1 if reg1 != reg2, else 0 +slt reg1, reg2 - set reg1=1 if reg1 < reg2 (unsigned), else 0 +slts reg1, reg2 - set reg1=1 if reg1 < reg2 (signed), else 0 +sle reg1, reg2 - set reg1=1 if reg1 <= reg2 (unsigned), else 0 +sles reg1, reg2 - set reg1=1 if reg1 <= reg2 (signed), else 0 +sgt reg1, reg2 - set reg1=1 if reg1 > reg2 (unsigned), else 0 +sgts reg1, reg2 - set reg1=1 if reg1 > reg2 (signed), else 0 +sge reg1, reg2 - set reg1=1 if reg1 >= reg2 (unsigned), else 0 +sges reg1, reg2 - set reg1=1 if reg1 >= reg2 (signed), else 0 +(note: on the M68k these instructions will set all bits to 1 (so value=-1 instead of 1), but the boolean logic here requires it to be 0 or 1 in this IR) ARITHMETIC diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index d9595fa01..0f5b82f2e 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -808,84 +808,84 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsSZ(i: IRInstruction) { val (_: Int, right: Int) = getSetOnConditionOperands(i) - val value = if(right==0) -1 else 0 + val value = if(right==0) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSNZ(i: IRInstruction) { val (_: Int, right: Int) = getSetOnConditionOperands(i) - val value = if(right!=0) -1 else 0 + val value = if(right!=0) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSEQ(i: IRInstruction) { val (left: Int, right: Int) = getSetOnConditionOperands(i) - val value = if(left==right) -1 else 0 + val value = if(left==right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSNE(i: IRInstruction) { val (left: Int, right: Int) = getSetOnConditionOperands(i) - val value = if(left!=right) -1 else 0 + val value = if(left!=right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSLT(i: IRInstruction) { val (left, right) = getSetOnConditionOperandsU(i) - val value = if(leftright) -1 else 0 + val value = if(left>right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSGTS(i: IRInstruction) { val (left, right) = getSetOnConditionOperands(i) - val value = if(left>right) -1 else 0 + val value = if(left>right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSLE(i: IRInstruction) { val (left, right) = getSetOnConditionOperandsU(i) - val value = if(left<=right) -1 else 0 + val value = if(left<=right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSLES(i: IRInstruction) { val (left, right) = getSetOnConditionOperands(i) - val value = if(left<=right) -1 else 0 + val value = if(left<=right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSGE(i: IRInstruction) { val (left, right) = getSetOnConditionOperandsU(i) - val value = if(left>=right) -1 else 0 + val value = if(left>=right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc() } private fun InsSGES(i: IRInstruction) { val (left, right) = getSetOnConditionOperands(i) - val value = if(left>=right) -1 else 0 + val value = if(left>=right) 1 else 0 setResultReg(i.reg1!!, value, i.type!!) nextPc()