mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 08:29:25 +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 isAssignableTo(targetTypes: Set<DataType>) = targetTypes.any { this isAssignableTo it }
|
||||||
|
|
||||||
infix fun largerThan(other: DataType) =
|
infix fun largerThan(other: DataType) =
|
||||||
when(this) {
|
when {
|
||||||
in ByteDatatypes -> false
|
this == other -> false
|
||||||
in WordDatatypes -> other in ByteDatatypes
|
this in ByteDatatypes -> false
|
||||||
|
this in WordDatatypes -> other in ByteDatatypes
|
||||||
|
this==STR && other==UWORD || this==UWORD && other==STR -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
|
|
||||||
infix fun equalsSize(other: DataType) =
|
infix fun equalsSize(other: DataType) =
|
||||||
when(this) {
|
when {
|
||||||
in ByteDatatypes -> other in ByteDatatypes
|
this == other -> true
|
||||||
in WordDatatypes -> other in WordDatatypes
|
this in ByteDatatypes -> other in ByteDatatypes
|
||||||
|
this in WordDatatypes -> other in WordDatatypes
|
||||||
|
this==STR && other==UWORD || this==UWORD && other==STR -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +611,7 @@ $endLabel""")
|
|||||||
|
|
||||||
private fun assignLoopvar(stmt: ForLoop, range: RangeExpr) {
|
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 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)
|
val assign = AsmAssignment(src, target, false, range.position)
|
||||||
asmgen.translateNormalAssignment(assign)
|
asmgen.translateNormalAssignment(assign)
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
val identifier = IdentifierReference(scopedParamVar, sub.position)
|
val identifier = IdentifierReference(scopedParamVar, sub.position)
|
||||||
identifier.linkParents(value.parent)
|
identifier.linkParents(value.parent)
|
||||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, parameter.value.type, sub, variable = identifier)
|
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)
|
val asgn = AsmAssignment(source, tgt, false, Position.DUMMY)
|
||||||
asmgen.translateNormalAssignment(asgn)
|
asmgen.translateNormalAssignment(asgn)
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
val stack = paramRegister.stack
|
val stack = paramRegister.stack
|
||||||
val requiredDt = parameter.value.type
|
val requiredDt = parameter.value.type
|
||||||
if(requiredDt!=valueDt) {
|
if(requiredDt!=valueDt) {
|
||||||
if(valueDt.largerThan(requiredDt))
|
if(valueDt largerThan requiredDt)
|
||||||
throw AssemblyError("can only convert byte values to word param types")
|
throw AssemblyError("can only convert byte values to word param types")
|
||||||
}
|
}
|
||||||
when {
|
when {
|
||||||
@ -233,19 +233,27 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
else -> {
|
else -> {
|
||||||
// via register or register pair
|
// via register or register pair
|
||||||
val target = AsmAssignTarget.fromRegisters(register!!, sub, program, asmgen)
|
val target = AsmAssignTarget.fromRegisters(register!!, sub, program, asmgen)
|
||||||
val src = if(valueDt in PassByReferenceDatatypes) {
|
if(requiredDt largerThan valueDt) {
|
||||||
if(value is IdentifierReference) {
|
// TODO we need to sign extend the source, do this via stack (slow)
|
||||||
val addr = AddressOf(value, Position.DUMMY)
|
println("warning: slow stack evaluation used for sign-extend: into $requiredDt at ${value.position}")
|
||||||
AsmAssignSource.fromAstSource(addr, program).adjustDataTypeToTarget(target)
|
asmgen.translateExpression(value)
|
||||||
} else {
|
asmgen.signExtendStackLsb(valueDt)
|
||||||
AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(target)
|
val src = AsmAssignSource(SourceStorageKind.STACK, program, valueDt)
|
||||||
}
|
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY))
|
||||||
} else {
|
}
|
||||||
AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(target)
|
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) =
|
fun withAdjustedDt(newType: DataType) =
|
||||||
AsmAssignSource(kind, program, newType, variable, array, memory, register, number, expression)
|
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
|
// allow some signed/unsigned relaxations
|
||||||
if(target.datatype!=datatype) {
|
if(target.datatype!=datatype) {
|
||||||
if(target.datatype in ByteDatatypes && datatype in ByteDatatypes) {
|
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) {
|
fun translate(assignment: Assignment) {
|
||||||
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
|
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)
|
val assign = AsmAssignment(source, target, assignment.isAugmentable, assignment.position)
|
||||||
target.origAssign = assign
|
target.origAssign = assign
|
||||||
|
@ -7,6 +7,25 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
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"+
|
txt.print("\nCommands are:\n"+
|
||||||
"buy jump inf cash\n" +
|
"buy jump inf cash\n" +
|
||||||
"sell teleport market hold\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() {
|
asmsub testX() {
|
||||||
%asm {{
|
%asm {{
|
||||||
stx _saveX
|
stx _saveX
|
||||||
|
@ -179,10 +179,10 @@ market {
|
|||||||
|
|
||||||
sub display() {
|
sub display() {
|
||||||
ubyte ci
|
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 {
|
for ci in 0 to len(names)-1 {
|
||||||
util.print_right(12, names[ci])
|
util.print_right(13, names[ci])
|
||||||
txt.print(" ")
|
txt.print(" ")
|
||||||
util.print_10s(current_price[ci])
|
util.print_10s(current_price[ci])
|
||||||
txt.print(" ")
|
txt.print(" ")
|
||||||
txt.print_ub(current_quantity[ci])
|
txt.print_ub(current_quantity[ci])
|
||||||
|
Loading…
Reference in New Issue
Block a user