mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
really fix byte-word sign extension for function args as expression
This commit is contained in:
parent
9e54e11113
commit
73524e01a6
@ -39,16 +39,20 @@ enum class DataType {
|
||||
infix fun isAssignableTo(targetTypes: Set<DataType>) = targetTypes.any { this isAssignableTo it }
|
||||
|
||||
infix fun largerThan(other: DataType) =
|
||||
when(this) {
|
||||
in ByteDatatypes -> false
|
||||
in WordDatatypes -> other in ByteDatatypes
|
||||
when {
|
||||
this == other -> false
|
||||
this in ByteDatatypes -> false
|
||||
this in WordDatatypes -> other in ByteDatatypes
|
||||
this==STR && other==UWORD || this==UWORD && other==STR -> false
|
||||
else -> true
|
||||
}
|
||||
|
||||
infix fun equalsSize(other: DataType) =
|
||||
when(this) {
|
||||
in ByteDatatypes -> other in ByteDatatypes
|
||||
in WordDatatypes -> other in WordDatatypes
|
||||
when {
|
||||
this == other -> true
|
||||
this in ByteDatatypes -> other in ByteDatatypes
|
||||
this in WordDatatypes -> other in WordDatatypes
|
||||
this==STR && other==UWORD || this==UWORD && other==STR -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
@ -611,7 +611,7 @@ $endLabel""")
|
||||
|
||||
private fun assignLoopvar(stmt: ForLoop, range: RangeExpr) {
|
||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, stmt.loopVarDt(program).typeOrElse(DataType.STRUCT), stmt.definingSubroutine(), variable=stmt.loopVar)
|
||||
val src = AsmAssignSource.fromAstSource(range.from, program).adjustDataTypeToTarget(target)
|
||||
val src = AsmAssignSource.fromAstSource(range.from, program).adjustSignedUnsigned(target)
|
||||
val assign = AsmAssignment(src, target, false, range.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
val identifier = IdentifierReference(scopedParamVar, sub.position)
|
||||
identifier.linkParents(value.parent)
|
||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, parameter.value.type, sub, variable = identifier)
|
||||
val source = AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(tgt)
|
||||
val source = AsmAssignSource.fromAstSource(value, program).adjustSignedUnsigned(tgt)
|
||||
val asgn = AsmAssignment(source, tgt, false, Position.DUMMY)
|
||||
asmgen.translateNormalAssignment(asgn)
|
||||
}
|
||||
@ -179,7 +179,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
val stack = paramRegister.stack
|
||||
val requiredDt = parameter.value.type
|
||||
if(requiredDt!=valueDt) {
|
||||
if(valueDt.largerThan(requiredDt))
|
||||
if(valueDt largerThan requiredDt)
|
||||
throw AssemblyError("can only convert byte values to word param types")
|
||||
}
|
||||
when {
|
||||
@ -233,19 +233,27 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
else -> {
|
||||
// via register or register pair
|
||||
val target = AsmAssignTarget.fromRegisters(register!!, sub, program, asmgen)
|
||||
val src = if(valueDt in PassByReferenceDatatypes) {
|
||||
if(value is IdentifierReference) {
|
||||
val addr = AddressOf(value, Position.DUMMY)
|
||||
AsmAssignSource.fromAstSource(addr, program).adjustDataTypeToTarget(target)
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(target)
|
||||
}
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(target)
|
||||
if(requiredDt largerThan valueDt) {
|
||||
// TODO we need to sign extend the source, do this via stack (slow)
|
||||
println("warning: slow stack evaluation used for sign-extend: into $requiredDt at ${value.position}")
|
||||
asmgen.translateExpression(value)
|
||||
asmgen.signExtendStackLsb(valueDt)
|
||||
val src = AsmAssignSource(SourceStorageKind.STACK, program, valueDt)
|
||||
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY))
|
||||
}
|
||||
else {
|
||||
val src = if(valueDt in PassByReferenceDatatypes) {
|
||||
if(value is IdentifierReference) {
|
||||
val addr = AddressOf(value, Position.DUMMY)
|
||||
AsmAssignSource.fromAstSource(addr, program).adjustSignedUnsigned(target)
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program).adjustSignedUnsigned(target)
|
||||
}
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program).adjustSignedUnsigned(target)
|
||||
}
|
||||
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY))
|
||||
}
|
||||
|
||||
// the following routine knows about converting byte to word if required:
|
||||
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
|
||||
fun withAdjustedDt(newType: DataType) =
|
||||
AsmAssignSource(kind, program, newType, variable, array, memory, register, number, expression)
|
||||
|
||||
fun adjustDataTypeToTarget(target: AsmAssignTarget): AsmAssignSource {
|
||||
fun adjustSignedUnsigned(target: AsmAssignTarget): AsmAssignSource {
|
||||
// allow some signed/unsigned relaxations
|
||||
if(target.datatype!=datatype) {
|
||||
if(target.datatype in ByteDatatypes && datatype in ByteDatatypes) {
|
||||
|
@ -18,7 +18,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
|
||||
fun translate(assignment: Assignment) {
|
||||
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
|
||||
val source = AsmAssignSource.fromAstSource(assignment.value, program).adjustDataTypeToTarget(target)
|
||||
val source = AsmAssignSource.fromAstSource(assignment.value, program).adjustSignedUnsigned(target)
|
||||
|
||||
val assign = AsmAssignment(source, target, assignment.isAugmentable, assignment.position)
|
||||
target.origAssign = assign
|
||||
|
@ -7,6 +7,25 @@ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
print_10s(1)
|
||||
txt.chrout('\n')
|
||||
print_10s(123)
|
||||
txt.chrout('\n')
|
||||
print_10s(54321)
|
||||
txt.chrout('\n')
|
||||
txt.chrout('\n')
|
||||
|
||||
ubyte ww
|
||||
ww=1
|
||||
print_10s(ww)
|
||||
txt.chrout('\n')
|
||||
ww=123
|
||||
print_10s(ww)
|
||||
txt.chrout('\n')
|
||||
ww=255
|
||||
print_10s(ww)
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("\nCommands are:\n"+
|
||||
"buy jump inf cash\n" +
|
||||
"sell teleport market hold\n" +
|
||||
@ -30,6 +49,32 @@ main {
|
||||
|
||||
}
|
||||
|
||||
asmsub print_10s(uword value @AY) clobbers(A, X, Y) {
|
||||
%asm {{
|
||||
jsr conv.uword2decimal
|
||||
lda conv.uword2decimal.decTenThousands
|
||||
cmp #'0'
|
||||
beq +
|
||||
jsr c64.CHROUT
|
||||
+ lda conv.uword2decimal.decThousands
|
||||
cmp #'0'
|
||||
beq +
|
||||
jsr c64.CHROUT
|
||||
+ lda conv.uword2decimal.decHundreds
|
||||
cmp #'0'
|
||||
beq +
|
||||
jsr c64.CHROUT
|
||||
+ lda conv.uword2decimal.decTens
|
||||
jsr c64.CHROUT
|
||||
lda #'.'
|
||||
jsr c64.CHROUT
|
||||
lda conv.uword2decimal.decOnes
|
||||
jsr c64.CHROUT
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
asmsub testX() {
|
||||
%asm {{
|
||||
stx _saveX
|
||||
|
@ -179,10 +179,10 @@ market {
|
||||
|
||||
sub display() {
|
||||
ubyte ci
|
||||
txt.print(" COMMODITY / PRICE / AVAIL / IN HOLD\n")
|
||||
txt.print(" COMMODITY / PRICE / AVAIL / IN HOLD\n")
|
||||
for ci in 0 to len(names)-1 {
|
||||
util.print_right(12, names[ci])
|
||||
txt.print(" ")
|
||||
util.print_right(13, names[ci])
|
||||
txt.print(" ")
|
||||
util.print_10s(current_price[ci])
|
||||
txt.print(" ")
|
||||
txt.print_ub(current_quantity[ci])
|
||||
|
Loading…
Reference in New Issue
Block a user