mirror of
https://github.com/irmen/prog8.git
synced 2025-02-24 13:29:10 +00:00
fixed rol(),rol2(),ror(),ror2()
This commit is contained in:
parent
9e33b8b8da
commit
504d1440cc
@ -471,7 +471,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
DataType.UBYTE -> {
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(!what.index.isSimple()) asmgen.out(" php") // save Carry
|
||||
asmgen.loadScaledArrayIndexIntoRegister(what, CpuRegister.X)
|
||||
if(!what.index.isSimple()) asmgen.out(" plp")
|
||||
val varname = asmgen.asmVariableName(what.variable)
|
||||
asmgen.out(" ror ${varname},x")
|
||||
}
|
||||
@ -482,15 +484,19 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
} else {
|
||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.address)
|
||||
if(ptrAndIndex!=null) {
|
||||
asmgen.out(" php")
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.A)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.first, RegisterOrPair.AY)
|
||||
asmgen.out(" sta (+) + 1 | sty (+) + 2")
|
||||
asmgen.restoreRegisterStack(CpuRegister.X, false)
|
||||
asmgen.out("""
|
||||
plp
|
||||
+ ror ${'$'}ffff,x ; modified""")
|
||||
} else {
|
||||
if(!what.address.isSimple()) asmgen.out(" php") // save Carry
|
||||
asmgen.assignExpressionToRegister(what.address, RegisterOrPair.AY)
|
||||
if(!what.address.isSimple()) asmgen.out(" plp")
|
||||
asmgen.out("""
|
||||
sta (+) + 1
|
||||
sty (+) + 2
|
||||
@ -508,7 +514,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
DataType.UWORD -> {
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(!what.index.isSimple()) asmgen.out(" php") // save Carry
|
||||
asmgen.loadScaledArrayIndexIntoRegister(what, CpuRegister.X)
|
||||
if(!what.index.isSimple()) asmgen.out(" plp")
|
||||
val varname = asmgen.asmVariableName(what.variable)
|
||||
if(what.splitWords)
|
||||
asmgen.out(" ror ${varname}_msb,x | ror ${varname}_lsb,x")
|
||||
@ -579,7 +587,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
DataType.UBYTE -> {
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(!what.index.isSimple()) asmgen.out(" php") // save Carry
|
||||
asmgen.loadScaledArrayIndexIntoRegister(what, CpuRegister.X)
|
||||
if(!what.index.isSimple()) asmgen.out(" plp")
|
||||
val varname = asmgen.asmVariableName(what.variable)
|
||||
asmgen.out(" rol ${varname},x")
|
||||
}
|
||||
@ -590,15 +600,19 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
} else {
|
||||
val ptrAndIndex = asmgen.pointerViaIndexRegisterPossible(what.address)
|
||||
if(ptrAndIndex!=null) {
|
||||
asmgen.out(" php")
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.A)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||
asmgen.assignExpressionToRegister(ptrAndIndex.first, RegisterOrPair.AY)
|
||||
asmgen.out(" sta (+) + 1 | sty (+) + 2")
|
||||
asmgen.restoreRegisterStack(CpuRegister.X, false)
|
||||
asmgen.out("""
|
||||
plp
|
||||
+ rol ${'$'}ffff,x ; modified""")
|
||||
} else {
|
||||
if(!what.address.isSimple()) asmgen.out(" php") // save Carry
|
||||
asmgen.assignExpressionToRegister(what.address, RegisterOrPair.AY)
|
||||
if(!what.address.isSimple()) asmgen.out(" plp")
|
||||
asmgen.out("""
|
||||
sta (+) + 1
|
||||
sty (+) + 2
|
||||
@ -616,7 +630,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
DataType.UWORD -> {
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(!what.index.isSimple()) asmgen.out(" php") // save Carry
|
||||
asmgen.loadScaledArrayIndexIntoRegister(what, CpuRegister.X)
|
||||
if(!what.index.isSimple()) asmgen.out(" plp")
|
||||
val varname = asmgen.asmVariableName(what.variable)
|
||||
if(what.splitWords)
|
||||
asmgen.out(" rol ${varname}_lsb,x | rol ${varname}_msb,x")
|
||||
|
@ -50,25 +50,26 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
assignment: PtAugmentedAssign
|
||||
): IRCodeChunks {
|
||||
val value = assignment.value
|
||||
val vmDt = irType(value.type)
|
||||
val targetDt = irType(assignment.target.type)
|
||||
val signed = assignment.target.type in SignedDatatypes
|
||||
return when(assignment.operator) {
|
||||
"+=" -> expressionEval.operatorPlusInplace(address, null, vmDt, value)
|
||||
"-=" -> expressionEval.operatorMinusInplace(address, null, vmDt, value)
|
||||
"*=" -> expressionEval.operatorMultiplyInplace(address, null, vmDt, value)
|
||||
"/=" -> expressionEval.operatorDivideInplace(address, null, vmDt, value.type in SignedDatatypes, value)
|
||||
"|=" -> expressionEval.operatorOrInplace(address, null, vmDt, value)
|
||||
"&=" -> expressionEval.operatorAndInplace(address, null, vmDt, value)
|
||||
"^=" -> expressionEval.operatorXorInplace(address, null, vmDt, value)
|
||||
"<<=" -> expressionEval.operatorShiftLeftInplace(address, null, vmDt, value)
|
||||
">>=" -> expressionEval.operatorShiftRightInplace(address, null, vmDt, value.type in SignedDatatypes, value)
|
||||
"%=" -> expressionEval.operatorModuloInplace(address, null, vmDt, value)
|
||||
"==" -> expressionEval.operatorEqualsInplace(address, null, vmDt, value)
|
||||
"!=" -> expressionEval.operatorNotEqualsInplace(address, null, vmDt, value)
|
||||
"<" -> expressionEval.operatorLessInplace(address, null, vmDt, value.type in SignedDatatypes, value)
|
||||
">" -> expressionEval.operatorGreaterInplace(address, null, vmDt, value.type in SignedDatatypes, value)
|
||||
"<=" -> expressionEval.operatorLessEqualInplace(address, null, vmDt, value.type in SignedDatatypes, value)
|
||||
">=" -> expressionEval.operatorGreaterEqualInplace(address, null, vmDt, value.type in SignedDatatypes, value)
|
||||
in PrefixOperators -> inplacePrefix(assignment.operator, vmDt, address, null)
|
||||
"+=" -> expressionEval.operatorPlusInplace(address, null, targetDt, value)
|
||||
"-=" -> expressionEval.operatorMinusInplace(address, null, targetDt, value)
|
||||
"*=" -> expressionEval.operatorMultiplyInplace(address, null, targetDt, value)
|
||||
"/=" -> expressionEval.operatorDivideInplace(address, null, targetDt, signed, value)
|
||||
"|=" -> expressionEval.operatorOrInplace(address, null, targetDt, value)
|
||||
"&=" -> expressionEval.operatorAndInplace(address, null, targetDt, value)
|
||||
"^=" -> expressionEval.operatorXorInplace(address, null, targetDt, value)
|
||||
"<<=" -> expressionEval.operatorShiftLeftInplace(address, null, targetDt, value)
|
||||
">>=" -> expressionEval.operatorShiftRightInplace(address, null, targetDt, signed, value)
|
||||
"%=" -> expressionEval.operatorModuloInplace(address, null, targetDt, value)
|
||||
"==" -> expressionEval.operatorEqualsInplace(address, null, targetDt, value)
|
||||
"!=" -> expressionEval.operatorNotEqualsInplace(address, null, targetDt, value)
|
||||
"<" -> expressionEval.operatorLessInplace(address, null, targetDt, signed, value)
|
||||
">" -> expressionEval.operatorGreaterInplace(address, null, targetDt, signed, value)
|
||||
"<=" -> expressionEval.operatorLessEqualInplace(address, null, targetDt, signed, value)
|
||||
">=" -> expressionEval.operatorGreaterEqualInplace(address, null, targetDt, signed, value)
|
||||
in PrefixOperators -> inplacePrefix(assignment.operator, targetDt, address, null)
|
||||
|
||||
else -> throw AssemblyError("invalid augmented assign operator ${assignment.operator}")
|
||||
}
|
||||
@ -76,26 +77,27 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
|
||||
private fun assignVarAugmented(symbol: String, assignment: PtAugmentedAssign): IRCodeChunks {
|
||||
val value = assignment.value
|
||||
val signed = assignment.target.type in SignedDatatypes
|
||||
val targetDt = irType(assignment.target.type)
|
||||
return when (assignment.operator) {
|
||||
return when(assignment.operator) {
|
||||
"+=" -> expressionEval.operatorPlusInplace(null, symbol, targetDt, value)
|
||||
"-=" -> expressionEval.operatorMinusInplace(null, symbol, targetDt, value)
|
||||
"*=" -> expressionEval.operatorMultiplyInplace(null, symbol, targetDt, value)
|
||||
"/=" -> expressionEval.operatorDivideInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||
"/=" -> expressionEval.operatorDivideInplace(null, symbol, targetDt, signed, value)
|
||||
"|=" -> expressionEval.operatorOrInplace(null, symbol, targetDt, value)
|
||||
"or=" -> expressionEval.operatorLogicalOrInplace(null, symbol, targetDt, value)
|
||||
"&=" -> expressionEval.operatorAndInplace(null, symbol, targetDt, value)
|
||||
"and=" -> expressionEval.operatorLogicalAndInplace(null, symbol, targetDt, value)
|
||||
"^=", "xor=" -> expressionEval.operatorXorInplace(null, symbol, targetDt, value)
|
||||
"<<=" -> expressionEval.operatorShiftLeftInplace(null, symbol, targetDt, value)
|
||||
">>=" -> expressionEval.operatorShiftRightInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||
">>=" -> expressionEval.operatorShiftRightInplace(null, symbol, targetDt, signed, value)
|
||||
"%=" -> expressionEval.operatorModuloInplace(null, symbol, targetDt, value)
|
||||
"==" -> expressionEval.operatorEqualsInplace(null, symbol, targetDt, value)
|
||||
"!=" -> expressionEval.operatorNotEqualsInplace(null, symbol, targetDt, value)
|
||||
"<" -> expressionEval.operatorLessInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||
">" -> expressionEval.operatorGreaterInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||
"<=" -> expressionEval.operatorLessEqualInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||
">=" -> expressionEval.operatorGreaterEqualInplace(null, symbol, targetDt, value.type in SignedDatatypes, value)
|
||||
"<" -> expressionEval.operatorLessInplace(null, symbol, targetDt, signed, value)
|
||||
">" -> expressionEval.operatorGreaterInplace(null, symbol, targetDt, signed, value)
|
||||
"<=" -> expressionEval.operatorLessEqualInplace(null, symbol, targetDt, signed, value)
|
||||
">=" -> expressionEval.operatorGreaterEqualInplace(null, symbol, targetDt, signed, value)
|
||||
in PrefixOperators -> inplacePrefix(assignment.operator, targetDt, null, symbol)
|
||||
else -> throw AssemblyError("invalid augmented assign operator ${assignment.operator}")
|
||||
}
|
||||
@ -104,11 +106,11 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
private fun fallbackAssign(origAssign: PtAugmentedAssign): IRCodeChunks {
|
||||
val value: PtExpression
|
||||
if(origAssign.operator in PrefixOperators) {
|
||||
value = PtPrefix(origAssign.operator, origAssign.value.type, origAssign.value.position)
|
||||
value = PtPrefix(origAssign.operator, origAssign.target.type, origAssign.value.position)
|
||||
value.add(origAssign.value)
|
||||
} else {
|
||||
require(origAssign.operator.endsWith('='))
|
||||
value = PtBinaryExpression(origAssign.operator.dropLast(1), origAssign.value.type, origAssign.value.position)
|
||||
value = PtBinaryExpression(origAssign.operator.dropLast(1), origAssign.target.type, origAssign.value.position)
|
||||
val left: PtExpression = origAssign.target.children.single() as PtExpression
|
||||
value.add(left)
|
||||
value.add(origAssign.value)
|
||||
|
@ -623,22 +623,28 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultReg, reg2 = tr.resultReg)
|
||||
}
|
||||
addInstr(result, IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
// TODO optimize this to use the other ROL/ROR instructions too to always load into a temp reg
|
||||
val vmDt = irType(call.args[0].type)
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val saveCarry = opcode in OpcodesThatDependOnCarry && !call.args[0].isSimple()
|
||||
if(saveCarry)
|
||||
addInstr(result, IRInstruction(Opcode.PUSHST), null) // save Carry
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(opcode, vmDt, reg1 = tr.resultReg)
|
||||
}
|
||||
if(saveCarry)
|
||||
addInstr(result, IRInstruction(Opcode.POPST), null)
|
||||
addInstr(result, IRInstruction(opcode, vmDt, reg1 = tr.resultReg), null)
|
||||
if(saveCarry)
|
||||
addInstr(result, IRInstruction(Opcode.PUSHST), null) // save Carry
|
||||
result += assignRegisterTo(call.args[0], tr.resultReg)
|
||||
if(saveCarry)
|
||||
addInstr(result, IRInstruction(Opcode.POPST), null)
|
||||
return ExpressionCodeResult(result, vmDt, -1, -1)
|
||||
}
|
||||
|
||||
|
865
compiler/test/arithmetic/bitshift2.p8
Normal file
865
compiler/test/arithmetic/bitshift2.p8
Normal file
@ -0,0 +1,865 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
unsigned()
|
||||
signed()
|
||||
}
|
||||
|
||||
ubyte[2] ubarray
|
||||
uword[2] uwarray
|
||||
byte[2] barray
|
||||
word[2] warray
|
||||
|
||||
sub value_and_carry(ubyte value) -> ubyte {
|
||||
sys.set_carry()
|
||||
return value
|
||||
}
|
||||
|
||||
sub unsigned() {
|
||||
txt.print("rol_ub\n")
|
||||
test_rol_ub(%00000000, false, %00000000, false)
|
||||
test_rol_ub(%00000000, true, %00000001, false)
|
||||
test_rol_ub(%01000000, false, %10000000, false)
|
||||
test_rol_ub(%01000000, true, %10000001, false)
|
||||
test_rol_ub(%10000000, false, %00000000, true)
|
||||
test_rol_ub(%10000000, true, %00000001, true)
|
||||
|
||||
txt.print("ror_ub\n")
|
||||
test_ror_ub(%00000000, false, %00000000, false)
|
||||
test_ror_ub(%00000000, true, %10000000, false)
|
||||
test_ror_ub(%01000000, false, %00100000, false)
|
||||
test_ror_ub(%01000000, true, %10100000, false)
|
||||
test_ror_ub(%00000001, false, %00000000, true)
|
||||
test_ror_ub(%00000001, true, %10000000, true)
|
||||
|
||||
txt.print("rol2_ub\n")
|
||||
test_rol2_ub(%00000000, %00000000)
|
||||
test_rol2_ub(%01000001, %10000010)
|
||||
test_rol2_ub(%10000010, %00000101)
|
||||
test_rol2_ub(%11111110, %11111101)
|
||||
|
||||
txt.print("ror2_ub\n")
|
||||
test_ror2_ub(%00000000, %00000000)
|
||||
test_ror2_ub(%01000001, %10100000)
|
||||
test_ror2_ub(%10000010, %01000001)
|
||||
test_ror2_ub(%11111110, %01111111)
|
||||
|
||||
txt.print("rol_uw\n")
|
||||
test_rol_uw(%0000000010000000, false, %0000000100000000, false)
|
||||
test_rol_uw(%0000000010000000, true, %0000000100000001, false)
|
||||
test_rol_uw(%0100000010000000, false, %1000000100000000, false)
|
||||
test_rol_uw(%0100000010000000, true, %1000000100000001, false)
|
||||
test_rol_uw(%1000000010000000, false, %0000000100000000, true)
|
||||
test_rol_uw(%1000000010000000, true, %0000000100000001, true)
|
||||
|
||||
txt.print("ror_uw\n")
|
||||
test_ror_uw(%0000000100000000, false, %0000000010000000, false)
|
||||
test_ror_uw(%0000000100000000, true, %1000000010000000, false)
|
||||
test_ror_uw(%0100000100000000, false, %0010000010000000, false)
|
||||
test_ror_uw(%0100000100000000, true, %1010000010000000, false)
|
||||
test_ror_uw(%0000000100000001, false, %0000000010000000, true)
|
||||
test_ror_uw(%0000000100000001, true, %1000000010000000, true)
|
||||
|
||||
txt.print("rol2_uw\n")
|
||||
test_rol2_uw(%0000000010000000, %0000000100000000)
|
||||
test_rol2_uw(%0100000110000000, %1000001100000000)
|
||||
test_rol2_uw(%1000001010000000, %0000010100000001)
|
||||
test_rol2_uw(%1111111010000000, %1111110100000001)
|
||||
|
||||
txt.print("ror2_uw\n")
|
||||
test_ror2_uw(%0000000100000000, %0000000010000000)
|
||||
test_ror2_uw(%0100000100000000, %0010000010000000)
|
||||
test_ror2_uw(%1000001100000001, %1100000110000000)
|
||||
test_ror2_uw(%1111111100000011, %1111111110000001)
|
||||
|
||||
txt.print("<< ub\n")
|
||||
test_shiftl_ub(%00000000, %00000000, false)
|
||||
test_shiftl_ub(%00000001, %00000010, false)
|
||||
test_shiftl_ub(%01000000, %10000000, false)
|
||||
test_shiftl_ub(%10000000, %00000000, true)
|
||||
|
||||
txt.print(">> ub\n")
|
||||
test_shiftr_ub(%00000000, %00000000, false)
|
||||
test_shiftr_ub(%00000001, %00000000, true)
|
||||
test_shiftr_ub(%10000000, %01000000, false)
|
||||
test_shiftr_ub(%10000001, %01000000, true)
|
||||
|
||||
txt.print("<< uw\n")
|
||||
test_shiftl_uw(%0000000000000000, %0000000000000000, false)
|
||||
test_shiftl_uw(%0000000000000001, %0000000000000010, false)
|
||||
test_shiftl_uw(%0000000010000001, %0000000100000010, false)
|
||||
test_shiftl_uw(%0100000010000000, %1000000100000000, false)
|
||||
test_shiftl_uw(%1100000010000000, %1000000100000000, true)
|
||||
test_shiftl_uw(%1000000000000000, %0000000000000000, true)
|
||||
|
||||
txt.print(">> uw\n")
|
||||
test_shiftr_uw(%0000000000000000, %0000000000000000, false)
|
||||
test_shiftr_uw(%0000000000000001, %0000000000000000, true)
|
||||
test_shiftr_uw(%0000001100000010, %0000000110000001, false)
|
||||
test_shiftr_uw(%0000001100000011, %0000000110000001, true)
|
||||
test_shiftr_uw(%1000000000000010, %0100000000000001, false)
|
||||
}
|
||||
|
||||
sub signed() {
|
||||
txt.print("<< b\n")
|
||||
test_shiftl_b(%00000000 as byte, %00000000 as byte, false)
|
||||
test_shiftl_b(%00000001 as byte, %00000010 as byte, false)
|
||||
test_shiftl_b(%01000000 as byte, %10000000 as byte, false)
|
||||
test_shiftl_b(%10000000 as byte, %00000000 as byte, true)
|
||||
|
||||
txt.print(">> b\n")
|
||||
test_shiftr_b(%00000000 as byte, %00000000 as byte, false)
|
||||
test_shiftr_b(%00000001 as byte, %00000000 as byte, true)
|
||||
test_shiftr_b(%10000000 as byte, %11000000 as byte, false)
|
||||
test_shiftr_b(%10000010 as byte, %11000001 as byte, false)
|
||||
test_shiftr_b(%10000001 as byte, %11000000 as byte, true)
|
||||
|
||||
txt.print("<< w\n")
|
||||
test_shiftl_w(%0000000000000000 as word, %0000000000000000 as word, false)
|
||||
test_shiftl_w(%0000000000000001 as word, %0000000000000010 as word, false)
|
||||
test_shiftl_w(%0000000010000001 as word, %0000000100000010 as word, false)
|
||||
test_shiftl_w(%0100000010000000 as word, %1000000100000000 as word, false)
|
||||
test_shiftl_w(%1100000010000000 as word, %1000000100000000 as word, true)
|
||||
test_shiftl_w(%1000000000000000 as word, %0000000000000000 as word, true)
|
||||
|
||||
txt.print(">> w\n")
|
||||
test_shiftr_w(%0000000000000000 as word, %0000000000000000 as word, false)
|
||||
test_shiftr_w(%0000000000000001 as word, %0000000000000000 as word, true)
|
||||
test_shiftr_w(%0000001100000010 as word, %0000000110000001 as word, false)
|
||||
test_shiftr_w(%0000001100000011 as word, %0000000110000001 as word, true)
|
||||
test_shiftr_w(%1000000000000010 as word, %1100000000000001 as word, false)
|
||||
test_shiftr_w(%1000000000000001 as word, %1100000000000000 as word, true)
|
||||
}
|
||||
|
||||
|
||||
sub test_rol2_ub(ubyte value, ubyte test) {
|
||||
ubyte original = value
|
||||
sys.set_carry()
|
||||
rol2(value)
|
||||
if value!=test {
|
||||
txt.print("rol2_ub error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(value)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.nl()
|
||||
}
|
||||
ubarray[1]=original
|
||||
sys.set_carry()
|
||||
rol2(ubarray[1])
|
||||
if ubarray[1]!=test {
|
||||
txt.print("rol2_ub array error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(ubarray[1])
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.nl()
|
||||
}
|
||||
@($8000)=original
|
||||
sys.set_carry()
|
||||
rol2(@($8000))
|
||||
if @($8000)!=test {
|
||||
txt.print("rol2_ub mem error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(@($8000))
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_ror2_ub(ubyte value, ubyte test) {
|
||||
ubyte original = value
|
||||
sys.set_carry()
|
||||
ror2(value)
|
||||
if value!=test {
|
||||
txt.print("ror2_ub error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(value)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.nl()
|
||||
}
|
||||
ubarray[1] = original
|
||||
sys.set_carry()
|
||||
ror2(ubarray[1])
|
||||
if ubarray[1]!=test {
|
||||
txt.print("ror2_ub array error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(ubarray[1])
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.nl()
|
||||
}
|
||||
@($8000) = original
|
||||
sys.set_carry()
|
||||
ror2(@($8000))
|
||||
if @($8000)!=test {
|
||||
txt.print("ror2_ub mem error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(@($8000))
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_rol_ub(ubyte value, bool carry, ubyte test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
ubyte original = value
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
rol(value)
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry{
|
||||
txt.print("rol_ub error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(carry)
|
||||
txt.spc()
|
||||
txt.print_ub(value)
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
ubarray[1] = original
|
||||
carrycheck = false
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
rol(ubarray[value_and_carry(1)])
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if ubarray[1]!=test or carrycheck!=newcarry{
|
||||
txt.print("rol_ub array error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(carry)
|
||||
txt.spc()
|
||||
txt.print_ub(ubarray[1])
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
@($8001)=original
|
||||
carrycheck = false
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
rol(@($8000+value_and_carry(1)))
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if @($8001)!=test or carrycheck!=newcarry {
|
||||
txt.print("rol_ub mem error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(carry)
|
||||
txt.spc()
|
||||
txt.print_ub(@($8001))
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_ror_ub(ubyte value, bool carry, ubyte test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
ubyte original = value
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
ror(value)
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry{
|
||||
txt.print("ror_ub error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(carry)
|
||||
txt.spc()
|
||||
txt.print_ub(value)
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
ubarray[1] = original
|
||||
carrycheck = false
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
ror(ubarray[value_and_carry(1)])
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if ubarray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print("ror_ub array error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(carry)
|
||||
txt.spc()
|
||||
txt.print_ub(ubarray[1])
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
@($8001) = original
|
||||
carrycheck = false
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
ror(@($8000+value_and_carry(1)))
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if @($8001)!=test or carrycheck!=newcarry {
|
||||
txt.print("ror_ub mem error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(carry)
|
||||
txt.spc()
|
||||
txt.print_ub(@($8001))
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_rol2_uw(uword value, uword test) {
|
||||
uword original = value
|
||||
sys.set_carry()
|
||||
rol2(value)
|
||||
if value!=test {
|
||||
txt.print("rol2_uw error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(value)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
uwarray[1] = original
|
||||
sys.set_carry()
|
||||
rol2(uwarray[1])
|
||||
if uwarray[1]!=test {
|
||||
txt.print("rol2_uw array error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(uwarray[1])
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_ror2_uw(uword value, uword test) {
|
||||
uword original = value
|
||||
sys.set_carry()
|
||||
ror2(value)
|
||||
if value!=test {
|
||||
txt.print("ror2_uw error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(value)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
uwarray[1] = original
|
||||
sys.set_carry()
|
||||
ror2(uwarray[1])
|
||||
if uwarray[1]!=test {
|
||||
txt.print("ror2_uw array error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(uwarray[1])
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_rol_uw(uword value, bool carry, uword test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
uword original = value
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
rol(value)
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry{
|
||||
txt.print("rol_uw error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(carry)
|
||||
txt.spc()
|
||||
txt.print_uw(value)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
uwarray[1] = original
|
||||
carrycheck = false
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
rol(uwarray[value_and_carry(1)])
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if uwarray[1]!=test or carrycheck!=newcarry{
|
||||
txt.print("rol_uw array error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(carry)
|
||||
txt.spc()
|
||||
txt.print_uw(uwarray[1])
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_ror_uw(uword value, bool carry, uword test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
uword original = value
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
ror(value)
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry{
|
||||
txt.print("ror_uw error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(carry)
|
||||
txt.spc()
|
||||
txt.print_uw(value)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
uwarray[1] = original
|
||||
carrycheck = false
|
||||
if carry
|
||||
sys.set_carry()
|
||||
else
|
||||
sys.clear_carry()
|
||||
ror(uwarray[value_and_carry(1)])
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if uwarray[1]!=test or carrycheck!=newcarry{
|
||||
txt.print("ror_uw array error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(carry)
|
||||
txt.spc()
|
||||
txt.print_uw(uwarray[1])
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftl_ub(ubyte value, ubyte test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
ubyte original = value
|
||||
sys.set_carry()
|
||||
value <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print("<< ub error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(value)
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
ubarray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
ubarray[1] <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if ubarray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print("<< ub array error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(ubarray[1])
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftr_ub(ubyte value, ubyte test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
ubyte original = value
|
||||
sys.set_carry()
|
||||
value >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print(">> ub error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(value)
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
ubarray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
ubarray[1] >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if ubarray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print(">> ub array error ")
|
||||
txt.print_ub(original)
|
||||
txt.spc()
|
||||
txt.print_ub(ubarray[1])
|
||||
txt.spc()
|
||||
txt.print_ub(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_ub(test)
|
||||
txt.spc()
|
||||
txt.print_ub(newcarry)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftl_uw(uword value, uword test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
uword original = value
|
||||
sys.set_carry()
|
||||
value <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print("<< uw error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(value)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
uwarray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
uwarray[1] <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if uwarray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print("<< uw array error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(uwarray[1])
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftr_uw(uword value, uword test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
uword original = value
|
||||
sys.set_carry()
|
||||
value >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print(">> uw error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(value)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
uwarray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
uwarray[1] >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if uwarray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print(">> uw array error ")
|
||||
txt.print_uw(original)
|
||||
txt.spc()
|
||||
txt.print_uw(uwarray[1])
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_uw(test)
|
||||
txt.spc()
|
||||
txt.print_uw(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftl_b(byte value, byte test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
byte original = value
|
||||
sys.set_carry()
|
||||
value <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print("<< b error ")
|
||||
txt.print_b(original)
|
||||
txt.spc()
|
||||
txt.print_b(value)
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_b(test)
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
barray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
barray[1] <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if barray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print("<< b array error ")
|
||||
txt.print_b(original)
|
||||
txt.spc()
|
||||
txt.print_b(barray[1])
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_b(test)
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftr_b(byte value, byte test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
byte original = value
|
||||
sys.set_carry()
|
||||
value >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print(">> b error ")
|
||||
txt.print_b(original)
|
||||
txt.spc()
|
||||
txt.print_b(value)
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_b(test)
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
barray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
barray[1] >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if barray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print(">> b array error ")
|
||||
txt.print_b(original)
|
||||
txt.spc()
|
||||
txt.print_b(barray[1])
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_b(test)
|
||||
txt.spc()
|
||||
txt.print_b(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftl_w(word value, word test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
word original = value
|
||||
sys.set_carry()
|
||||
value <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print("<< w error ")
|
||||
txt.print_w(original)
|
||||
txt.spc()
|
||||
txt.print_w(value)
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_w(test)
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
warray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
warray[1] <<= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if warray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print("<< w array error ")
|
||||
txt.print_w(original)
|
||||
txt.spc()
|
||||
txt.print_w(warray[1])
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_w(test)
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
sub test_shiftr_w(word value, word test, bool newcarry) {
|
||||
bool carrycheck = false
|
||||
word original = value
|
||||
sys.set_carry()
|
||||
value >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if value!=test or carrycheck!=newcarry {
|
||||
txt.print(">> w error ")
|
||||
txt.print_w(original)
|
||||
txt.spc()
|
||||
txt.print_w(value)
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_w(test)
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
warray[1] = original
|
||||
sys.set_carry()
|
||||
carrycheck = false
|
||||
warray[1] >>= 1
|
||||
if_cs
|
||||
carrycheck=true
|
||||
if warray[1]!=test or carrycheck!=newcarry {
|
||||
txt.print(">> w array error ")
|
||||
txt.print_w(original)
|
||||
txt.spc()
|
||||
txt.print_w(warray[1])
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.print(" exp: ")
|
||||
txt.print_w(test)
|
||||
txt.spc()
|
||||
txt.print_w(carrycheck)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
}
|
@ -294,4 +294,22 @@ main {
|
||||
((st[4] as Assignment).value as NumericLiteral).number shouldBe 0x9e00+2*30
|
||||
((st[5] as Assignment).value as NumericLiteral).number shouldBe 0x9e00+2*30
|
||||
}
|
||||
|
||||
test("address of a const uword pointer array expression") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
const uword buffer = ${'$'}2000
|
||||
uword addr = &buffer[2]
|
||||
|
||||
const ubyte width = 100
|
||||
ubyte @shared i
|
||||
ubyte @shared j
|
||||
uword addr2 = &buffer[i * width + j]
|
||||
}
|
||||
}"""
|
||||
val result = compileText(Cx16Target(), true, src, writeAssembly = false)!!
|
||||
val st = result.compilerAst.entrypoint.statements
|
||||
st.size shouldBe 9999
|
||||
}
|
||||
})
|
||||
|
@ -203,5 +203,19 @@ main {
|
||||
}"""
|
||||
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
||||
}
|
||||
|
||||
test("address of a uword pointer array expression") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
set_state(12345, 1)
|
||||
}
|
||||
sub set_state(uword buffer, ubyte i) {
|
||||
uword addr = &buffer[i]
|
||||
addr++
|
||||
}
|
||||
}"""
|
||||
compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
funcRor()/funcRol(): save carry flag before calculating array index otherwise it gets clobbered
|
||||
2 unit tests that are failing.
|
||||
Mark had a compiler crash FatalAstException: invalid dt.
|
||||
|
||||
Mark had a compiler crash FatalAstException: invalid dt
|
||||
IR: optimize funcRolRor()
|
||||
|
||||
...
|
||||
|
||||
|
@ -4,93 +4,5 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
word @shared q = -12345
|
||||
txt.print_w(q)
|
||||
txt.nl()
|
||||
txt.print_uwbin(q as uword, true)
|
||||
txt.nl()
|
||||
q >>=9
|
||||
txt.print_w(q)
|
||||
txt.nl()
|
||||
txt.print_uwbin(q as uword, true)
|
||||
txt.nl()
|
||||
|
||||
; mem()
|
||||
; bytes()
|
||||
; words()
|
||||
}
|
||||
|
||||
sub mem() {
|
||||
@($2000) = $7a
|
||||
rol(@($2000))
|
||||
txt.print_ubbin(@($2000), true)
|
||||
txt.nl()
|
||||
rol2(@($2000))
|
||||
txt.print_ubbin(@($2000), true)
|
||||
txt.nl()
|
||||
ror(@($2000))
|
||||
txt.print_ubbin(@($2000), true)
|
||||
txt.nl()
|
||||
ror2(@($2000))
|
||||
txt.print_ubbin(@($2000), true)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub bytes() {
|
||||
ubyte[] wa = [$1a, $2b, $3c]
|
||||
|
||||
txt.print_ubbin(wa[2], true)
|
||||
txt.nl()
|
||||
rol(wa[2])
|
||||
txt.print_ubbin(wa[2], true)
|
||||
txt.nl()
|
||||
rol2(wa[2])
|
||||
txt.print_ubbin(wa[2], true)
|
||||
txt.nl()
|
||||
ror(wa[2])
|
||||
txt.print_ubbin(wa[2], true)
|
||||
txt.nl()
|
||||
ror2(wa[2])
|
||||
txt.print_ubbin(wa[2], true)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub words() {
|
||||
uword[] wa = [$11aa, $22bb, $33cc]
|
||||
uword[] @split swa = [$11aa, $22bb, $33cc]
|
||||
|
||||
txt.print_uwbin(wa[2], true)
|
||||
txt.nl()
|
||||
rol(wa[2])
|
||||
txt.print_uwbin(wa[2], true)
|
||||
txt.nl()
|
||||
rol2(wa[2])
|
||||
txt.print_uwbin(wa[2], true)
|
||||
txt.nl()
|
||||
ror(wa[2])
|
||||
txt.print_uwbin(wa[2], true)
|
||||
txt.nl()
|
||||
ror2(wa[2])
|
||||
txt.print_uwbin(wa[2], true)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
txt.print_uwbin(swa[2], true)
|
||||
txt.nl()
|
||||
rol(swa[2])
|
||||
txt.print_uwbin(swa[2], true)
|
||||
txt.nl()
|
||||
rol2(swa[2])
|
||||
txt.print_uwbin(swa[2], true)
|
||||
txt.nl()
|
||||
ror(swa[2])
|
||||
txt.print_uwbin(swa[2], true)
|
||||
txt.nl()
|
||||
ror2(swa[2])
|
||||
txt.print_uwbin(swa[2], true)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
@ -5,4 +5,4 @@ org.gradle.daemon=true
|
||||
kotlin.code.style=official
|
||||
javaVersion=11
|
||||
kotlinVersion=1.9.22
|
||||
version=9.8-SNAPSHOT
|
||||
version=10.0-SNAPSHOT
|
||||
|
@ -235,6 +235,8 @@ msig [b, w] reg1, reg2 - reg1 becomes the most significant by
|
||||
concat [b, w] reg1, reg2, reg3 - reg1.w = 'concatenate' two registers: lsb/lsw of reg2 (as msb) and lsb/lsw of reg3 (as lsb) into word or int (int not yet implemented; requires 32bits regs)
|
||||
push [b, w, f] reg1 - push value in reg1 on the stack
|
||||
pop [b, w, f] reg1 - pop value from stack into reg1
|
||||
pushst - push status register bits to stack
|
||||
popst - pop status register bits from stack
|
||||
*/
|
||||
|
||||
enum class Opcode {
|
||||
@ -387,6 +389,8 @@ enum class Opcode {
|
||||
SEC,
|
||||
PUSH,
|
||||
POP,
|
||||
PUSHST,
|
||||
POPST,
|
||||
MSIG,
|
||||
CONCAT,
|
||||
BREAKPOINT
|
||||
@ -699,6 +703,8 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.MSIG to InstructionFormat.from("BW,>r1,<r2"),
|
||||
Opcode.PUSH to InstructionFormat.from("BW,<r1 | F,<fr1"),
|
||||
Opcode.POP to InstructionFormat.from("BW,>r1 | F,>fr1"),
|
||||
Opcode.PUSHST to InstructionFormat.from("N"),
|
||||
Opcode.POPST to InstructionFormat.from("N"),
|
||||
Opcode.CONCAT to InstructionFormat.from("BW,<>r1,<r2,<r3"),
|
||||
Opcode.CLC to InstructionFormat.from("N"),
|
||||
Opcode.SEC to InstructionFormat.from("N"),
|
||||
|
@ -286,6 +286,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
Opcode.CONCAT -> InsCONCAT(ins)
|
||||
Opcode.PUSH -> InsPUSH(ins)
|
||||
Opcode.POP -> InsPOP(ins)
|
||||
Opcode.PUSHST -> InsPUSHST()
|
||||
Opcode.POPST -> InsPOPST()
|
||||
Opcode.BREAKPOINT -> InsBREAKPOINT()
|
||||
Opcode.CLC -> { statusCarry = false; nextPc() }
|
||||
Opcode.SEC -> { statusCarry = true; nextPc() }
|
||||
@ -360,6 +362,28 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsPUSHST() {
|
||||
var status: UByte = 0u
|
||||
if(statusNegative)
|
||||
status = status or 0b10000000u
|
||||
if(statusZero)
|
||||
status = status or 0b00000010u
|
||||
if(statusCarry)
|
||||
status = status or 0b00000001u
|
||||
// TODO overflow not yet supported
|
||||
valueStack.push(status)
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsPOPST() {
|
||||
val status = valueStack.pop().toInt()
|
||||
statusNegative = status and 0b10000000 != 0
|
||||
statusZero = status and 0b00000010 != 0
|
||||
statusCarry = status and 0b00000001 != 0
|
||||
// TODO overflow not yet supported
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsSYSCALL(i: IRInstruction) {
|
||||
// put the syscall's arguments that were prepared onto the stack
|
||||
for(value in syscallParams) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user