fix byte-word sign extension for function args as expression

This commit is contained in:
Irmen de Jong 2020-10-11 01:35:38 +02:00
parent 67a2241e32
commit 01ac5f29db
3 changed files with 31 additions and 19 deletions

View File

@ -177,13 +177,22 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
val statusflag = paramRegister.statusflag
val register = paramRegister.registerOrPair
val stack = paramRegister.stack
val requiredDt = parameter.value.type
if(requiredDt!=valueDt) {
if(valueDt.largerThan(requiredDt))
throw AssemblyError("can only convert byte values to word param types")
}
when {
stack -> {
// push arg onto the stack
// note: argument order is reversed (first argument will be deepest on the stack)
asmgen.translateExpression(value)
if(requiredDt!=valueDt)
asmgen.signExtendStackLsb(valueDt)
}
statusflag!=null -> {
if(requiredDt!=valueDt)
throw AssemblyError("for statusflag, byte value is required")
if (statusflag == Statusflag.Pc) {
// this param needs to be set last, right before the jsr
// for now, this is already enforced on the subroutine definition by the Ast Checker
@ -235,6 +244,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(target)
}
// the following routine knows about converting byte to word if required:
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY))
}
}

View File

@ -34,7 +34,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
SourceStorageKind.LITERALNUMBER -> {
// simple case: assign a constant number
val num = assign.source.number!!.number
when (assign.source.datatype) {
when (assign.target.datatype) {
DataType.UBYTE, DataType.BYTE -> assignConstantByte(assign.target, num.toShort())
DataType.UWORD, DataType.WORD -> assignConstantWord(assign.target, num.toInt())
DataType.FLOAT -> assignConstantFloat(assign.target, num.toDouble())
@ -44,7 +44,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
SourceStorageKind.VARIABLE -> {
// simple case: assign from another variable
val variable = assign.source.variable!!
when (assign.source.datatype) {
when (assign.target.datatype) {
DataType.UBYTE, DataType.BYTE -> assignVariableByte(assign.target, variable)
DataType.UWORD, DataType.WORD -> assignVariableWord(assign.target, variable)
DataType.FLOAT -> assignVariableFloat(assign.target, variable)
@ -143,12 +143,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} else {
// regular subroutine, return values are (for now) always done via the stack... TODO optimize this
asmgen.translateExpression(value)
if(assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
asmgen.signExtendStackLsb(assign.source.datatype)
assignStackValue(assign.target)
}
}
else -> {
// everything else just evaluate via the stack.
asmgen.translateExpression(value)
if(assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
asmgen.signExtendStackLsb(assign.source.datatype)
assignStackValue(assign.target)
}
}

View File

@ -13,28 +13,26 @@ main {
; "sell teleport market hold\n" +
; "fuel galhyp local quit\n")
str name = "irmen de jong"
uword strptr = &name
txt.print_ub(strlen("1234"))
txt.chrout('\n')
txt.print_ub(strlen(name))
txt.chrout('\n')
txt.print_uwhex(strptr, 1)
txt.chrout('\n')
txt.print(strptr)
txt.chrout('\n')
txt.print_ub(strlen(strptr))
txt.chrout('\n')
; str name = "irmen de jong"
; uword strptr = &name
;
;
; txt.print_ub(strlen("1234"))
; txt.chrout('\n')
; txt.print_ub(strlen(name))
; txt.chrout('\n')
; txt.print_uwhex(strptr, 1)
; txt.chrout('\n')
; txt.print(strptr)
; txt.chrout('\n')
; txt.print_ub(strlen(strptr))
; txt.chrout('\n')
ubyte q
for q in 0 to 255 {
txt.print_ub(q)
txt.chrout(' ')
;txt.print_uw(q*4) ; TODO fix
; txt.chrout(' ')
txt.print_uw(q*$0004) ; TODO fix
txt.print_uw(q*5) ; TODO fix
txt.chrout('\n')
}