fixed assigning byte to word not clearing msb sometimes

This commit is contained in:
Irmen de Jong
2023-07-16 21:52:28 +02:00
parent 450eaf7c4a
commit 5659742d97
4 changed files with 156 additions and 79 deletions

View File

@@ -45,12 +45,12 @@ internal class AssignmentAsmGen(private val program: PtProgram,
val variable = assign.source.asmVarname val variable = assign.source.asmVarname
when (assign.target.datatype) { when (assign.target.datatype) {
DataType.UBYTE, DataType.BYTE -> assignVariableByte(assign.target, variable) DataType.UBYTE, DataType.BYTE -> assignVariableByte(assign.target, variable)
DataType.WORD -> assignVariableWord(assign.target, variable) DataType.WORD -> assignVariableWord(assign.target, variable, assign.source.datatype)
DataType.UWORD -> { DataType.UWORD -> {
if(assign.source.datatype in PassByReferenceDatatypes) if(assign.source.datatype in PassByReferenceDatatypes)
assignAddressOf(assign.target, variable) assignAddressOf(assign.target, variable)
else else
assignVariableWord(assign.target, variable) assignVariableWord(assign.target, variable, assign.source.datatype)
} }
DataType.FLOAT -> assignVariableFloat(assign.target, variable) DataType.FLOAT -> assignVariableFloat(assign.target, variable)
DataType.STR -> assignVariableString(assign.target, variable) DataType.STR -> assignVariableString(assign.target, variable)
@@ -288,6 +288,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
is PtPrefix -> { is PtPrefix -> {
if(assign.target.array==null) { if(assign.target.array==null) {
if(assign.source.datatype==assign.target.datatype) {
// First assign the value to the target then apply the operator in place on the target. // First assign the value to the target then apply the operator in place on the target.
// This saves a temporary variable // This saves a temporary variable
translateNormalAssignment( translateNormalAssignment(
@@ -303,6 +304,30 @@ internal class AssignmentAsmGen(private val program: PtProgram,
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0") "not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
else -> throw AssemblyError("invalid prefix operator") else -> throw AssemblyError("invalid prefix operator")
} }
} else {
// use a temporary variable
val tempvar = if(value.type in ByteDatatypes) "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_W1"
assignExpressionToVariable(value.value, tempvar, value.type)
when (value.operator) {
"+" -> {}
"-", "~" -> {
val assignTempvar = AsmAssignment(
AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, value.type, variableAsmName = tempvar),
AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, value.type, scope, assign.position, variableAsmName = tempvar),
program.memsizer, assign.position)
if(value.operator=="-")
inplaceNegate(assignTempvar, true, scope)
else
inplaceInvert(assignTempvar, scope)
}
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
else -> throw AssemblyError("invalid prefix operator")
}
if(value.type in ByteDatatypes)
assignVariableByte(assign.target, tempvar)
else
assignVariableWord(assign.target, tempvar, value.type)
}
} else { } else {
assignPrefixedExpressionToArrayElt(assign, scope) assignPrefixedExpressionToArrayElt(assign, scope)
} }
@@ -338,7 +363,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.translateNormalAssignment(assignToTempvar, scope) asmgen.translateNormalAssignment(assignToTempvar, scope)
when(assign.target.datatype) { when(assign.target.datatype) {
in ByteDatatypes -> assignVariableByte(assign.target, tempvar) in ByteDatatypes -> assignVariableByte(assign.target, tempvar)
in WordDatatypes -> assignVariableWord(assign.target, tempvar) in WordDatatypes -> assignVariableWord(assign.target, tempvar, assign.source.datatype)
DataType.FLOAT -> assignVariableFloat(assign.target, tempvar) DataType.FLOAT -> assignVariableFloat(assign.target, tempvar)
else -> throw AssemblyError("weird dt") else -> throw AssemblyError("weird dt")
} }
@@ -827,7 +852,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
DataType.UWORD -> { DataType.UWORD -> {
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1") asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
asmgen.out(" jsr math.divmod_uw_asm") asmgen.out(" jsr math.divmod_uw_asm")
assignVariableWord(assign.target, "P8ZP_SCRATCH_W2") assignVariableWord(assign.target, "P8ZP_SCRATCH_W2", DataType.UWORD)
return true return true
} }
else -> return false else -> return false
@@ -2049,9 +2074,18 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
private fun assignVariableWord(target: AsmAssignTarget, sourceName: String) { private fun assignVariableWord(target: AsmAssignTarget, sourceName: String, sourceDt: DataType) {
require(sourceDt in WordDatatypes || sourceDt==DataType.UBYTE)
when(target.kind) { when(target.kind) {
TargetStorageKind.VARIABLE -> { TargetStorageKind.VARIABLE -> {
if(sourceDt==DataType.UBYTE) {
asmgen.out(" lda $sourceName | sta ${target.asmVarname}")
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz ${target.asmVarname}")
else
asmgen.out(" lda #0 | sta ${target.asmVarname}")
}
else
asmgen.out(""" asmgen.out("""
lda $sourceName lda $sourceName
ldy $sourceName+1 ldy $sourceName+1
@@ -2062,6 +2096,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
throw AssemblyError("assign word to memory ${target.memory} should have gotten a typecast") throw AssemblyError("assign word to memory ${target.memory} should have gotten a typecast")
} }
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
if(sourceDt==DataType.UBYTE) TODO("assign byte to word array")
target.array!! target.array!!
if(target.constArrayIndexValue!=null) { if(target.constArrayIndexValue!=null) {
val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt() val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt()
@@ -2137,6 +2172,21 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {
if(sourceDt==DataType.UBYTE) {
when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda $sourceName")
RegisterOrPair.AY -> asmgen.out(" ldy #0 | lda $sourceName")
RegisterOrPair.XY -> asmgen.out(" ldy #0 | ldx $sourceName")
in Cx16VirtualRegisters -> {
asmgen.out(" lda $sourceName | sta cx16.${target.register.toString().lowercase()}")
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz cx16.${target.register.toString().lowercase()}+1")
else
asmgen.out(" lda #0 | sta cx16.${target.register.toString().lowercase()}+1")
}
else -> throw AssemblyError("can't load word in a single 8-bit register")
}
} else {
when(target.register!!) { when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" ldx $sourceName+1 | lda $sourceName") RegisterOrPair.AX -> asmgen.out(" ldx $sourceName+1 | lda $sourceName")
RegisterOrPair.AY -> asmgen.out(" ldy $sourceName+1 | lda $sourceName") RegisterOrPair.AY -> asmgen.out(" ldy $sourceName+1 | lda $sourceName")
@@ -2153,7 +2203,16 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> throw AssemblyError("can't load word in a single 8-bit register") else -> throw AssemblyError("can't load word in a single 8-bit register")
} }
} }
}
TargetStorageKind.STACK -> { TargetStorageKind.STACK -> {
if(sourceDt==DataType.UBYTE) {
asmgen.out(" lda $sourceName | sta P8ESTACK_LO,x")
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out(" stz P8ESTACK_HI,x")
else
asmgen.out(" lda #0 | sta P8ESTACK_HI,x")
}
else
asmgen.out(""" asmgen.out("""
lda $sourceName lda $sourceName
sta P8ESTACK_LO,x sta P8ESTACK_LO,x

View File

@@ -5,11 +5,11 @@ package prog8.buildversion
*/ */
const val MAVEN_GROUP = "prog8" const val MAVEN_GROUP = "prog8"
const val MAVEN_NAME = "compiler" const val MAVEN_NAME = "compiler"
const val VERSION = "9.1-SNAPSHOT" const val VERSION = "9.2-SNAPSHOT"
const val GIT_REVISION = 3930 const val GIT_REVISION = 3964
const val GIT_SHA = "b4e94ae4dd1c29a966bb5ea0454ab31f1e9863cb" const val GIT_SHA = "aaa30e4a583fa7c8da61998cf7cbb2a60b52afb0"
const val GIT_DATE = "2023-07-05T21:15:04Z" const val GIT_DATE = "2023-07-16T21:16:18Z"
const val GIT_BRANCH = "master" const val GIT_BRANCH = "master"
const val BUILD_DATE = "2023-07-05T21:15:07Z" const val BUILD_DATE = "2023-07-16T21:16:23Z"
const val BUILD_UNIX_TIME = 1688591707834L const val BUILD_UNIX_TIME = 1689542183583L
const val DIRTY = 1 const val DIRTY = 1

View File

@@ -285,4 +285,37 @@ derp {
compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null
compileText(Cx16Target(), true, src, writeAssembly = true) shouldNotBe null compileText(Cx16Target(), true, src, writeAssembly = true) shouldNotBe null
} }
test("prefix expressions with typecasting") {
val src="""
main
{
sub start()
{
uword uw = 54321
ubyte ub = 123
word sw = -12345
byte sb = -123
func_uw(~ub as uword)
func_ub(~uw as ubyte)
func_uw(~sb as uword)
func_ub(~sw as ubyte)
func_w(-sb as word)
func_b(-sw as byte)
}
sub func_uw(uword arg) {
}
sub func_w(word arg) {
}
sub func_ub(ubyte arg) {
}
sub func_b(byte arg) {
}
}"""
compileText(VMTarget(), false, src, writeAssembly = true) shouldNotBe null
compileText(Cx16Target(), false, src, writeAssembly = true) shouldNotBe null
}
}) })

View File

@@ -5,37 +5,22 @@ main
{ {
sub start() sub start()
{ {
uword zc = 54321 uword uw = 54321
ubyte zb = 123 ubyte ub = 123
ubyte shift = 2 word sw = -12345
byte sb = -123
; txt.print_uw(zc<<shift) txt.print_uw(~ub as uword) ;132
; txt.nl() txt.nl()
; txt.print_uw(zc>>shift) txt.print_ub(~uw as ubyte) ;206
; txt.nl() txt.nl()
; txt.print_ub(zb<<shift) txt.print_uw(~sb as uword) ;122
; txt.nl() txt.nl()
; txt.print_ub(zb>>shift) txt.print_ub(~sw as ubyte) ;56
; txt.nl() txt.nl()
; txt.print_w(-sb as word) ;123
; word szc = -12345 txt.nl()
; byte szb = -123 txt.print_b(-sw as byte) ;57
; txt.print_w(szc<<shift)
; txt.nl()
; txt.print_w(szc>>shift)
; txt.nl()
; txt.print_b(szb<<shift)
; txt.nl()
; txt.print_b(szb>>shift)
; txt.nl()
;
txt.print_uw(~zc as ubyte)
txt.spc()
txt.print_uw(~zb as uword)
txt.nl() txt.nl()
; cx16.r1L = (zc<<shift) as ubyte
; txt.print_ub(cx16.r1L)
} }
} }