diff --git a/codeCore/src/prog8/code/core/DataTypes.kt b/codeCore/src/prog8/code/core/DataTypes.kt index 7c940435e..641bc1db7 100644 --- a/codeCore/src/prog8/code/core/DataTypes.kt +++ b/codeCore/src/prog8/code/core/DataTypes.kt @@ -230,16 +230,17 @@ class DataType private constructor( else -> throw IllegalArgumentException("not an array") } - fun typeForAddressOf(msb: Boolean): DataType { + fun typeForUntypedAddressOf(msb: Boolean, mem: IMemSizer): DataType { + val untypedPointerType = if(mem.memorySize(BaseDataType.POINTER)>2) LONG else UWORD if (isUndefined) - return if(msb) pointer(BaseDataType.UBYTE) else UWORD + return if(msb) pointer(BaseDataType.UBYTE) else untypedPointerType else { if (isBasic) return pointer(base) if (isString) return pointer(BaseDataType.UBYTE) if (isPointer) - return UWORD + return untypedPointerType if (isArray) { if (msb || isSplitWordArray) return pointer(BaseDataType.UBYTE) @@ -249,7 +250,7 @@ class DataType private constructor( } if (subType != null) return pointer(this) - return UWORD + return untypedPointerType } } @@ -362,7 +363,7 @@ class DataType private constructor( BaseDataType.BYTE -> targetType.base in setOf(BaseDataType.BYTE, BaseDataType.WORD, BaseDataType.LONG, BaseDataType.FLOAT) BaseDataType.UWORD -> targetType.base in setOf(BaseDataType.UWORD, BaseDataType.LONG, BaseDataType.FLOAT, BaseDataType.POINTER, BaseDataType.ARRAY_POINTER) BaseDataType.WORD -> targetType.base in setOf(BaseDataType.WORD, BaseDataType.LONG, BaseDataType.FLOAT) - BaseDataType.LONG -> targetType.base in setOf(BaseDataType.LONG, BaseDataType.FLOAT) + BaseDataType.LONG -> targetType.base in setOf(BaseDataType.LONG, BaseDataType.FLOAT, BaseDataType.POINTER, BaseDataType.ARRAY_POINTER) BaseDataType.FLOAT -> targetType.base in arrayOf(BaseDataType.FLOAT) BaseDataType.STR -> targetType.base in setOf(BaseDataType.STR, BaseDataType.UWORD) || (targetType.isPointer && targetType.sub==BaseDataType.UBYTE) BaseDataType.ARRAY, BaseDataType.ARRAY_SPLITW -> targetType.base in setOf(BaseDataType.ARRAY, BaseDataType.ARRAY_SPLITW) && targetType.sub == sub diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 045116d3e..78c302f1d 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -1787,7 +1787,7 @@ $repeatLabel""") } else { // all else take its address and assign that also to AY register pair - val addrOfDt = returnvalue.type.typeForAddressOf(false) + val addrOfDt = returnvalue.type.typeForUntypedAddressOf(false, program.memsizer) val addrofValue = PtAddressOf(addrOfDt, false, returnvalue.position) addrofValue.add(returnvalue) addrofValue.parent = ret.parent diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index d40e57a44..c81e54bc5 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -2650,7 +2650,7 @@ import prog8.codegen.cpu6502.assignment.* conv.dt==BaseDataType.LONG -> getSourceForLong(value) conv.dt.isPassByRef -> { // put the address of the argument in AY - val addr = PtAddressOf(DataType.forDt(conv.dt).typeForAddressOf(false), false, value.position) + val addr = PtAddressOf(DataType.forDt(conv.dt).typeForUntypedAddressOf(false, program.memsizer), false, value.position) addr.add(value) addr.parent = call AsmAssignSource.fromAstSource(addr, program, asmgen) @@ -2669,7 +2669,7 @@ import prog8.codegen.cpu6502.assignment.* conv.dt==BaseDataType.LONG -> AsmAssignSource.fromAstSource(value, program, asmgen) conv.dt.isPassByRef -> { // put the address of the argument in AY - val addr = PtAddressOf(DataType.forDt(conv.dt).typeForAddressOf(false), false,value.position) + val addr = PtAddressOf(DataType.forDt(conv.dt).typeForUntypedAddressOf(false, program.memsizer), false,value.position) addr.add(value) addr.parent = call AsmAssignSource.fromAstSource(addr, program, asmgen) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt index a78201521..27a383c1d 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt @@ -388,7 +388,7 @@ $label .byte 0 ; modified""" } val src = if(value.type.isPassByRef) { if(value is PtIdentifier || value is PtPointerDeref) { - val addr = PtAddressOf(value.type.typeForAddressOf(false), false, value.position) + val addr = PtAddressOf(value.type.typeForUntypedAddressOf(false, program.memsizer), false, value.position) addr.add(value) addr.parent = scope as PtNode AsmAssignSource.fromAstSource(addr, program, asmgen).adjustSignedUnsigned(target) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index 364aa525f..f5ca29db4 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -512,33 +512,32 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen valueFpRegister = tr.resultFpReg addToResult(result, tr, -1, valueFpRegister) } else { - val extendByteToWord = if(targetDt != valueDt) { - // usually an error EXCEPT when a byte is assigned to a word. - if(targetDt==IRDataType.WORD && valueDt==IRDataType.BYTE) - true - else if(targetDt==IRDataType.POINTER && valueDt==IRDataType.BYTE) - true - else if(targetDt==IRDataType.POINTER && valueDt in setOf(IRDataType.WORD, IRDataType.LONG)) - false - else if(valueDt==IRDataType.POINTER && targetDt in setOf(IRDataType.WORD, IRDataType.LONG)) - false - else - throw AssemblyError("assignment value and target dt mismatch") - } else false + // determine if value needs extension or truncation to match target type + // extension happens for byte→word, byte→pointer, or word→long + val extendSourceDt = when { + targetDt == valueDt -> null + targetDt==IRDataType.WORD && valueDt==IRDataType.BYTE -> IRDataType.BYTE + targetDt==IRDataType.POINTER && valueDt==IRDataType.BYTE -> IRDataType.BYTE + targetDt==IRDataType.LONG && valueDt==IRDataType.WORD -> IRDataType.WORD + targetDt==IRDataType.POINTER && valueDt in setOf(IRDataType.WORD, IRDataType.LONG) -> null + valueDt==IRDataType.POINTER && targetDt in setOf(IRDataType.WORD, IRDataType.LONG) -> null + valueDt==IRDataType.LONG && targetDt in setOf(IRDataType.WORD, IRDataType.POINTER) -> null + else -> throw AssemblyError("assignment value and target dt mismatch") + } if (assignment.value is PtIrRegister) { valueRegister = (assignment.value as PtIrRegister).register - if(extendByteToWord) { + if(extendSourceDt != null) { valueRegister = codeGen.registers.next(IRDataType.WORD) - addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister, reg2=(assignment.value as PtIrRegister).register), null) + addInstr(result, IRInstruction(Opcode.EXT, extendSourceDt, reg1=valueRegister, reg2=(assignment.value as PtIrRegister).register), null) } } else { val tr = exprGen.translateExpression(assignment.value) valueRegister = tr.resultReg addToResult(result, tr, valueRegister, -1) - if(extendByteToWord) { + if(extendSourceDt != null) { valueRegister = codeGen.registers.next(IRDataType.WORD) val opcode = if(assignment.value.type.isSigned) Opcode.EXTS else Opcode.EXT - addInstr(result, IRInstruction(opcode, IRDataType.BYTE, reg1=valueRegister, reg2=tr.resultReg), null) + addInstr(result, IRInstruction(opcode, extendSourceDt, reg1=valueRegister, reg2=tr.resultReg), null) } } } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index 464f78c2c..9a5e56d38 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -362,7 +362,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } private fun translate(expr: PtAddressOf): ExpressionCodeResult { - val vmDt = codeGen.irType(expr.type) + val vmDt = IRDataType.POINTER // note: LOAD gets you the address of the symbol, whereas LOADM would get you the value stored at that location val result = mutableListOf() val identifier = expr.identifier @@ -430,7 +430,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { loadAddressOfArrayLabel(resultRegister) return ExpressionCodeResult(result, vmDt, resultRegister, -1) } else { - require(vmDt in setOf(IRDataType.WORD, IRDataType.POINTER)) + require(vmDt == IRDataType.POINTER) val pointerTr = translateExpression(expr.dereference!!.startpointer) result += pointerTr.chunks val (instructions, offset) = traverseRestOfDerefChainToCalculateFinalAddress(expr.dereference!!, pointerTr.resultReg) diff --git a/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt b/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt index bc5ddc4ae..b37bb022c 100644 --- a/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt +++ b/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt @@ -283,6 +283,7 @@ internal class AsmGen(val program: IRProgram, private val target: ICompilationTa for (block in program.blocks) { val blockLabel = fixNameSymbols(block.label) emitRaw("; Block: $blockLabel") + emitLabel(blockLabel) val topLevelSubLabels = block.children.filterIsInstance().map { fixNameSymbols(it.label) }.toSet() for (element in block.children) { when (element) { diff --git a/compiler/res/prog8lib/qemu68k/syslib.p8 b/compiler/res/prog8lib/qemu68k/syslib.p8 index 25ff704ad..538b5d89f 100644 --- a/compiler/res/prog8lib/qemu68k/syslib.p8 +++ b/compiler/res/prog8lib/qemu68k/syslib.p8 @@ -91,10 +91,27 @@ sys { } sub die(ubyte code, str message) { - ; -- kill the program by jumping into the debugger/monitor (if available). Status code is in register A, a pointer to the death message is in X,Y. + ; -- kill the program: print death message to goldfish TTY, then exit. str @shared warning = iso:"\n\nPROGRAM DIED: " - ; TODO print die message and exit qemu - poweroff_system() + %asm {{ + lea sys.die.warning,a0 +.loop1: + move.b (a0)+,d0 + beq .done1 + move.l d0,qemu.TTY_PUT_CHAR + bra .loop1 +.done1: + move.l sys.die.message,a0 +.loop2: + move.b (a0)+,d0 + beq .done2 + move.l d0,qemu.TTY_PUT_CHAR + bra .loop2 +.done2: + moveq #10,d0 + move.l d0,qemu.TTY_PUT_CHAR + }} + exit(code) } sub wait(uword jiffies) { @@ -102,33 +119,80 @@ sys { ; TODO implement the wait } - sub memcopy(uword source, uword tgt, uword count) { - ; TODO implement memcopy +; ------- memory routines -------- + + sub memcopy(^^ubyte source, ^^ubyte tgt, uword count) { + %asm {{ + movea.l sys.memcopy.source,a0 + movea.l sys.memcopy.tgt,a1 + moveq #0,d2 + move.w sys.memcopy.count,d2 + beq .done + subq.w #1,d2 +.loop: + move.b (a0)+,(a1)+ + dbra d2,.loop +.done: + }} } - sub memset(uword mem, uword numbytes, ubyte value) { - ; TODO implement memset - } + sub memset(^^ubyte mem, uword numbytes, ubyte value) { + %asm {{ + movea.l sys.memset.mem,a0 + moveq #0,d1 + move.w sys.memset.numbytes,d1 + beq .done + moveq #0,d2 + move.b sys.memset.value,d2 - sub memsetw(uword mem, uword numwords, uword value) { - ; TODO implement memsetw - } + ; align address to even for word/longword transfers + move.l a0,d3 + btst #0,d3 + beq .aligned + move.b d2,(a0)+ + subq.l #1,d1 + beq .done - sub memcmp(uword address1, uword address2, uword size) -> byte { - ; Compares two blocks of memory of up to 65535 bytes in size - ; Returns -1 (255), 0 or 1, meaning: block 1 sorts before, equal or after block 2. - ; TODO implement memcmp - return 0 +.aligned: + ; expand fill byte to all byte positions in d2 + move.l d2,d3 + lsl.l #8,d3 + or.l d3,d2 + move.l d2,d3 + swap d3 + or.l d3,d2 + + ; longword fill (4 bytes per iteration) + move.l d1,d0 + lsr.l #2,d0 + beq .bytes + subq.w #1,d0 +.loop_l: + move.l d2,(a0)+ + dbra d0,.loop_l + + ; remaining bytes (0-3) +.bytes: + and.w #3,d1 + beq .done + subq.w #1,d1 +.loop_b: + move.b d2,(a0)+ + dbra d1,.loop_b +.done: + }} } sub exit(ubyte returnvalue) { ; -- immediately exit the program with a return code in the D0 register - ; TODO implement exit + %asm {{ + moveq.l #0,d0 + move.b sys.exit.returnvalue,d0 + }} poweroff_system() } sub set_carry() { - ; TODO is this 68000-68030 compatible? %asm {{ moveq #1,d0 move.w d0,ccr @@ -136,7 +200,6 @@ sys { } sub clear_carry() { - ; TODO is this 68000-68030 compatible? %asm {{ moveq #0,d0 move.w d0,ccr diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 74b1c832f..e10faeade 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -2639,7 +2639,7 @@ internal class AstChecker(private val program: Program, targetDatatype.isUnsignedByte -> sourceDatatype.isUnsignedByte targetDatatype.isSignedWord -> sourceDatatype.isSignedWord || sourceDatatype.isByte targetDatatype.isUnsignedWord -> sourceDatatype.isUnsignedWord || sourceDatatype.isUnsignedByte - targetDatatype.isLong -> sourceDatatype.isLong + targetDatatype.isLong -> sourceDatatype.isLong || sourceDatatype.isWord || sourceDatatype.isByte targetDatatype.isFloat -> sourceDatatype.isNumeric targetDatatype.isString -> sourceDatatype.isString else -> false diff --git a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt index 2955a31f6..a66d3f036 100644 --- a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt @@ -848,7 +848,10 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro } private fun transform(src: AddressOf): PtAddressOf { - val addr = PtAddressOf(src.inferType(program).getOrUndef(), src.typed, src.position, src.msb) + var inferredType = src.inferType(program).getOrUndef() + if(inferredType.base == BaseDataType.UWORD) + inferredType = addrType + val addr = PtAddressOf(inferredType, src.typed, src.position, src.msb) if(src.identifier!=null) addr.add(transform(src.identifier!!)) if (src.arrayIndex != null) diff --git a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt index 3acb754f0..d24b35de0 100644 --- a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt +++ b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt @@ -108,6 +108,10 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila if(paramDt.isUnsignedWord && argDt.isPointer) return true + // if expected is any pointer and actual is long, we allow it (long is untyped 32-bit pointer) + if(paramDt.isPointer && argDt.base==BaseDataType.LONG) + return true + if(paramDt.isString && (argDt.isPointer && argDt.sub==BaseDataType.UBYTE)) return true diff --git a/compiler/test/TestPointers.kt b/compiler/test/TestPointers.kt index fbb8d08db..d7e51543d 100644 --- a/compiler/test/TestPointers.kt +++ b/compiler/test/TestPointers.kt @@ -18,6 +18,7 @@ import prog8.code.target.C64Target import prog8.code.target.Cx16Target import prog8.code.target.VMTarget import prog8.vm.VmRunner +import prog8tests.helpers.DummyMemsizer import prog8tests.helpers.ErrorReporterForTests import prog8tests.helpers.compileText import kotlin.io.path.readText @@ -749,23 +750,24 @@ main { } test("internal type for address-of") { - DataType.BYTE.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.BYTE) - DataType.WORD.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.WORD) - DataType.FLOAT.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.FLOAT) - DataType.UNDEFINED.typeForAddressOf(false) shouldBe DataType.UWORD - DataType.UNDEFINED.typeForAddressOf(true) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.STR.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.FLOAT, false).typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.FLOAT) - DataType.arrayFor(BaseDataType.FLOAT, false).typeForAddressOf(true) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.UWORD, false).typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.UWORD) - DataType.arrayFor(BaseDataType.UWORD, true).typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.UWORD, false).typeForAddressOf(true) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.UWORD, true).typeForAddressOf(true) shouldBe DataType.pointer(BaseDataType.UBYTE) + val memsizer = DummyMemsizer + DataType.BYTE.typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.BYTE) + DataType.WORD.typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.WORD) + DataType.FLOAT.typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.FLOAT) + DataType.UNDEFINED.typeForUntypedAddressOf(false, memsizer) shouldBe DataType.UWORD + DataType.UNDEFINED.typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.STR.typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.arrayFor(BaseDataType.FLOAT, false).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.FLOAT) + DataType.arrayFor(BaseDataType.FLOAT, false).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.arrayFor(BaseDataType.UWORD, false).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UWORD) + DataType.arrayFor(BaseDataType.UWORD, true).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.arrayFor(BaseDataType.UWORD, false).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.arrayFor(BaseDataType.UWORD, true).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.pointer(Struct("struct")).typeForAddressOf(false) shouldBe DataType.UWORD - DataType.pointerFromAntlr(listOf("struct")).typeForAddressOf(false) shouldBe DataType.UWORD + DataType.pointer(Struct("struct")).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.UWORD + DataType.pointerFromAntlr(listOf("struct")).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.UWORD - DataType.pointer(BaseDataType.BOOL).typeForAddressOf(false) shouldBe DataType.UWORD + DataType.pointer(BaseDataType.BOOL).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.UWORD } test("untyped and typed address-of operators") { diff --git a/compiler/test/helpers/Dummies.kt b/compiler/test/helpers/Dummies.kt index dae835405..f8ab4fd78 100644 --- a/compiler/test/helpers/Dummies.kt +++ b/compiler/test/helpers/Dummies.kt @@ -4,6 +4,9 @@ import prog8.ast.IBuiltinFunctions import prog8.ast.expressions.Expression import prog8.ast.expressions.InferredTypes import prog8.ast.expressions.NumericLiteral +import prog8.code.core.BaseDataType +import prog8.code.core.DataType +import prog8.code.core.IMemSizer import prog8.code.core.Position @@ -24,3 +27,32 @@ internal object DummyFunctions : IBuiltinFunctions { override fun returnTypes(funcName: String) = emptyArray() } + + + +internal object DummyMemsizer : IMemSizer { + override fun memorySize(dt: DataType, numElements: Int?): Int { + if (dt.isPointerArray) + return 2 * numElements!! + else if (dt.isArray) { + require(numElements != null) + return when (dt.sub) { + BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UBYTE -> numElements + BaseDataType.UWORD, BaseDataType.WORD -> numElements * 2 + BaseDataType.LONG -> numElements * 4 + BaseDataType.FLOAT -> numElements * 5 + else -> throw IllegalArgumentException("invalid sub type") + } + } + return when { + dt.isByteOrBool -> 1 * (numElements ?: 1) + dt.isLong -> 4 * (numElements ?: 1) + dt.isFloat -> 5 * (numElements ?: 1) + else -> 2 * (numElements ?: 1) + } + } + + override fun memorySize(dt: BaseDataType): Int { + return memorySize(DataType.forDt(dt), null) + } +} diff --git a/compiler/test/vm/TestCompilerVirtual.kt b/compiler/test/vm/TestCompilerVirtual.kt index ea66012f6..f9fad1365 100644 --- a/compiler/test/vm/TestCompilerVirtual.kt +++ b/compiler/test/vm/TestCompilerVirtual.kt @@ -344,7 +344,7 @@ other { val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir") val irSrc = virtfile.readText() // the &main must be encoded as a LOAD with the block name as label symbol - irSrc.shouldContain("load.w r1,main") + irSrc.shouldContain("load.p r1,main") // and the block must have an address that a 6502 backend can resolve irSrc.shouldContain($$""") = identifier?.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true || dereference?.referencesIdentifier(nameInSource)==true override fun inferType(program: Program): InferredTypes.InferredType { - if(!typed) - return InferredTypes.knownFor(BaseDataType.UWORD) // orignal pre-v12 untyped AddressOf + if(!typed) { + val untypedPointerType = if(program.memsizer.memorySize(BaseDataType.POINTER)>2) BaseDataType.LONG else BaseDataType.UWORD + return InferredTypes.knownFor(untypedPointerType) + } if(identifier!=null) { val type = identifier!!.inferType(program).getOrUndef() - val addrofDt = type.typeForAddressOf(msb) + val addrofDt = type.typeForUntypedAddressOf(msb, program.memsizer) return if(addrofDt.isUndefined) InferredTypes.unknown() else InferredTypes.knownFor(addrofDt) } else if(dereference!=null) { val type = dereference!!.inferType(program).getOrUndef() - val addrofDt = type.typeForAddressOf(msb) + val addrofDt = type.typeForUntypedAddressOf(msb, program.memsizer) return if(addrofDt.isUndefined) InferredTypes.unknown() else InferredTypes.knownFor(addrofDt) } else throw FatalAstException("invalid addressof") diff --git a/examples/test.p8 b/examples/test.p8 index c70af6512..3e7b29bd3 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,52 +3,16 @@ main { sub start() { - txt.print("progstart:") + txt.print("progstart: ") txt.print_ulhex(sys.progstart(), true) txt.nl() txt.print("progend: ") txt.print_ulhex(sys.progend(), true) txt.nl() - txt.print("start: ") - txt.print_ulhex(&start, true) + txt.print("sizeof pointer: ") + txt.print_ub(sys.SIZEOF_POINTER) txt.nl() -; print1("first: Hello from Prog8 on a m68000 system!\n") -; print1b("first (b): Hello from Prog8 on a m68000 system!\n") -; print2("second: Hello from Prog8 on a m68000 system!\n") + txt.print("Hello from Prog8 on a m68000 system!\n") } - -; sub print1(str msg) -> str { -; while @(msg)!=0 { -; txt.chrout(@(msg)) -; msg++ -; } -; -; return 9999 -; } - -; sub print1b(str msg) { -; long ii -; while msg[ii] != 0 { -; txt.chrout(msg[ii]) ; TODO fix pointer indexing ??? -; ii++ -; } -; } -; -; sub print2(^^ubyte msg) { -; while @(msg)!=0 { -; txt.chrout(@(msg)) -; msg++ -; } -; } -; -; sub hurrah() -> ubyte, uword, long { -; ubyte @shared x,y -; uword z -; long ll -; x+=y -; z+=x -; ll+=z -; return x,z,ll -; } }