mirror of
https://github.com/irmen/prog8.git
synced 2024-10-18 01:24:51 +00:00
optimizing pipe codegen
This commit is contained in:
parent
056ec986c2
commit
e425c4cca8
@ -957,8 +957,11 @@ class AsmGen(private val program: Program,
|
|||||||
internal fun translateBuiltinFunctionCallExpression(functionCallExpr: FunctionCallExpression, signature: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?) =
|
internal fun translateBuiltinFunctionCallExpression(functionCallExpr: FunctionCallExpression, signature: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?) =
|
||||||
builtinFunctionsAsmGen.translateFunctioncallExpression(functionCallExpr, signature, resultToStack, resultRegister)
|
builtinFunctionsAsmGen.translateFunctioncallExpression(functionCallExpr, signature, resultToStack, resultRegister)
|
||||||
|
|
||||||
internal fun translateBuiltinFunctionCallStatement(functionCallStmt: FunctionCallStatement, signature: FSignature) =
|
internal fun translateBuiltinFunctionCallExpression(name: String, args: List<AsmAssignSource>, scope: Subroutine): DataType =
|
||||||
builtinFunctionsAsmGen.translateFunctioncallStatement(functionCallStmt, signature)
|
builtinFunctionsAsmGen.translateFunctioncall(name, args, false, scope)
|
||||||
|
|
||||||
|
internal fun translateBuiltinFunctionCallStatement(name: String, args: List<AsmAssignSource>, scope: Subroutine) =
|
||||||
|
builtinFunctionsAsmGen.translateFunctioncall(name, args, true, scope)
|
||||||
|
|
||||||
internal fun translateFunctionCall(functionCallExpr: FunctionCallExpression, isExpression: Boolean) =
|
internal fun translateFunctionCall(functionCallExpr: FunctionCallExpression, isExpression: Boolean) =
|
||||||
functioncallAsmGen.translateFunctionCall(functionCallExpr, isExpression)
|
functioncallAsmGen.translateFunctionCall(functionCallExpr, isExpression)
|
||||||
@ -1626,13 +1629,14 @@ $label nop""")
|
|||||||
assemblyLines.add(assembly)
|
assemblyLines.add(assembly)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun returnRegisterOfFunction(it: IdentifierReference): RegisterOrPair? {
|
internal fun returnRegisterOfFunction(it: IdentifierReference): RegisterOrPair {
|
||||||
return when (val targetRoutine = it.targetStatement(program)!!) {
|
return when (val targetRoutine = it.targetStatement(program)!!) {
|
||||||
is BuiltinFunctionPlaceholder -> {
|
is BuiltinFunctionPlaceholder -> {
|
||||||
when (BuiltinFunctions.getValue(targetRoutine.name).known_returntype) {
|
when (BuiltinFunctions.getValue(targetRoutine.name).known_returntype) {
|
||||||
in ByteDatatypes -> RegisterOrPair.A
|
in ByteDatatypes -> RegisterOrPair.A
|
||||||
in WordDatatypes -> RegisterOrPair.AY
|
in WordDatatypes -> RegisterOrPair.AY
|
||||||
else -> return null
|
DataType.FLOAT -> RegisterOrPair.FAC1
|
||||||
|
else -> throw AssemblyError("weird returntype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Subroutine -> targetRoutine.asmReturnvaluesRegisters.single().registerOrPair!!
|
is Subroutine -> targetRoutine.asmReturnvaluesRegisters.single().registerOrPair!!
|
||||||
@ -3479,33 +3483,36 @@ $label nop""")
|
|||||||
|
|
||||||
// TODO more efficient code generation to avoid needless assignments to the temp var
|
// TODO more efficient code generation to avoid needless assignments to the temp var
|
||||||
|
|
||||||
val subroutine = scope.definingSubroutine
|
// the first term: an expression (could be anything) producing a value.
|
||||||
var valueDt = expressions.first().inferType(program).getOrElse { throw FatalAstException("invalid dt") }
|
val subroutine = scope.definingSubroutine!!
|
||||||
var valueVar = getTempVarName(valueDt)
|
val firstTerm = expressions.first()
|
||||||
assignExpressionToVariable(expressions.first(), asmVariableName(valueVar), valueDt, subroutine)
|
var valueDt = firstTerm.inferType(program).getOrElse { throw FatalAstException("invalid dt") }
|
||||||
|
var valueSource: AsmAssignSource =
|
||||||
|
if(firstTerm is IFunctionCall) {
|
||||||
|
val resultReg = returnRegisterOfFunction(firstTerm.target)
|
||||||
|
assignExpressionToRegister(firstTerm, resultReg, valueDt in listOf(DataType.BYTE, DataType.WORD, DataType.FLOAT))
|
||||||
|
AsmAssignSource(SourceStorageKind.REGISTER, program, this, valueDt, register = resultReg)
|
||||||
|
} else {
|
||||||
|
AsmAssignSource.fromAstSource(firstTerm, program, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
// the 2nd to N-1 terms: unary function calls taking a single param and producing a value.
|
||||||
|
// directly assign their argument from the previous call's returnvalue.
|
||||||
expressions.drop(1).dropLast(1).forEach {
|
expressions.drop(1).dropLast(1).forEach {
|
||||||
valueDt = functioncallAsmGen.translateFunctionCall(it as IdentifierReference, listOf(IdentifierReference(valueVar, it.position)), scope)
|
valueDt = functioncallAsmGen.translateUnaryFunctionCallWithArgSource(it as IdentifierReference, valueSource, false, subroutine)
|
||||||
// assign result value from the functioncall back to the temp var:
|
val resultReg = returnRegisterOfFunction(it)
|
||||||
valueVar = getTempVarName(valueDt)
|
valueSource = AsmAssignSource(SourceStorageKind.REGISTER, program, this, valueDt, register = resultReg)
|
||||||
val valueVarTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, valueDt, subroutine, variableAsmName = valueVar.joinToString("."))
|
|
||||||
val returnRegister = returnRegisterOfFunction(it)!!
|
|
||||||
assignRegister(returnRegister, valueVarTarget)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the last term: unary function call taking a single param and optionally producing a result value.
|
||||||
if(isStatement) {
|
if(isStatement) {
|
||||||
// the last term in the pipe, don't care about return var:
|
// the last term in the pipe, don't care about return var:
|
||||||
functioncallAsmGen.translateFunctionCallStatement(
|
functioncallAsmGen.translateUnaryFunctionCallWithArgSource(
|
||||||
expressions.last() as IdentifierReference,
|
expressions.last() as IdentifierReference, valueSource, true, subroutine)
|
||||||
listOf(IdentifierReference(valueVar, expressions.last().position)),
|
|
||||||
scope
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// the last term in the pipe, regular function call with returnvalue:
|
// the last term in the pipe, regular function call with returnvalue:
|
||||||
valueDt = functioncallAsmGen.translateFunctionCall(
|
valueDt = functioncallAsmGen.translateUnaryFunctionCallWithArgSource(
|
||||||
expressions.last() as IdentifierReference,
|
expressions.last() as IdentifierReference, valueSource, false, subroutine)
|
||||||
listOf(IdentifierReference(valueVar, expressions.last().position)),
|
|
||||||
scope
|
|
||||||
)
|
|
||||||
if(pushResultOnEstack) {
|
if(pushResultOnEstack) {
|
||||||
when (valueDt) {
|
when (valueDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
|
@ -13,6 +13,7 @@ import prog8.ast.toHex
|
|||||||
import prog8.codegen.target.AssemblyError
|
import prog8.codegen.target.AssemblyError
|
||||||
import prog8.codegen.target.Cx16Target
|
import prog8.codegen.target.Cx16Target
|
||||||
import prog8.codegen.target.cpu6502.codegen.assignment.*
|
import prog8.codegen.target.cpu6502.codegen.assignment.*
|
||||||
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
import prog8.compilerinterface.FSignature
|
import prog8.compilerinterface.FSignature
|
||||||
import prog8.compilerinterface.subroutineFloatEvalResultVar2
|
import prog8.compilerinterface.subroutineFloatEvalResultVar2
|
||||||
@ -27,6 +28,36 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
translateFunctioncall(fcall, func, discardResult = true, resultToStack = false, resultRegister = null)
|
translateFunctioncall(fcall, func, discardResult = true, resultToStack = false, resultRegister = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun translateFunctioncall(name: String, args: List<AsmAssignSource>, isStatement: Boolean, scope: Subroutine): DataType {
|
||||||
|
val func = BuiltinFunctions.getValue(name)
|
||||||
|
val argExpressions = args.map { src ->
|
||||||
|
when(src.kind) {
|
||||||
|
SourceStorageKind.LITERALNUMBER -> src.number!!
|
||||||
|
SourceStorageKind.EXPRESSION -> src.expression!!
|
||||||
|
SourceStorageKind.ARRAY -> src.array!!
|
||||||
|
else -> {
|
||||||
|
// TODO make it so that we can assign efficiently from something else as an expression....namely: register(s)
|
||||||
|
// but for now, first assign it to a temporary variable
|
||||||
|
val tempvar = asmgen.getTempVarName(src.datatype)
|
||||||
|
val assignTempvar = AsmAssignment(
|
||||||
|
src,
|
||||||
|
AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, src.datatype, scope, variableAsmName = asmgen.asmVariableName(tempvar)),
|
||||||
|
false, program.memsizer, Position.DUMMY
|
||||||
|
)
|
||||||
|
assignAsmGen.translateNormalAssignment(assignTempvar)
|
||||||
|
// now use an expression to assign this tempvar
|
||||||
|
val ident = IdentifierReference(tempvar, Position.DUMMY)
|
||||||
|
ident.linkParents(scope)
|
||||||
|
ident
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.toMutableList()
|
||||||
|
val fcall = FunctionCallExpression(IdentifierReference(listOf(name), Position.DUMMY), argExpressions, Position.DUMMY)
|
||||||
|
fcall.linkParents(scope)
|
||||||
|
translateFunctioncall(fcall, func, discardResult = false, resultToStack = false, null)
|
||||||
|
return if(isStatement) DataType.UNDEFINED else func.known_returntype!!
|
||||||
|
}
|
||||||
|
|
||||||
private fun translateFunctioncall(fcall: IFunctionCall, func: FSignature, discardResult: Boolean, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
|
private fun translateFunctioncall(fcall: IFunctionCall, func: FSignature, discardResult: Boolean, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
|
||||||
if (discardResult && func.pure)
|
if (discardResult && func.pure)
|
||||||
return // can just ignore the whole function call altogether
|
return // can just ignore the whole function call altogether
|
||||||
|
@ -4,14 +4,16 @@ import prog8.ast.IFunctionCall
|
|||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.AddressOf
|
||||||
|
import prog8.ast.expressions.Expression
|
||||||
|
import prog8.ast.expressions.IdentifierReference
|
||||||
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.codegen.target.AssemblyError
|
import prog8.codegen.target.AssemblyError
|
||||||
import prog8.codegen.target.cpu6502.codegen.assignment.AsmAssignSource
|
import prog8.codegen.target.cpu6502.codegen.assignment.AsmAssignSource
|
||||||
import prog8.codegen.target.cpu6502.codegen.assignment.AsmAssignTarget
|
import prog8.codegen.target.cpu6502.codegen.assignment.AsmAssignTarget
|
||||||
import prog8.codegen.target.cpu6502.codegen.assignment.AsmAssignment
|
import prog8.codegen.target.cpu6502.codegen.assignment.AsmAssignment
|
||||||
import prog8.codegen.target.cpu6502.codegen.assignment.TargetStorageKind
|
import prog8.codegen.target.cpu6502.codegen.assignment.TargetStorageKind
|
||||||
import prog8.compilerinterface.BuiltinFunctions
|
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
|
|
||||||
|
|
||||||
@ -127,46 +129,60 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
// remember: dealing with the X register and/or dealing with return values is the responsibility of the caller
|
// remember: dealing with the X register and/or dealing with return values is the responsibility of the caller
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun translateFunctionCall(target: IdentifierReference, args: Iterable<Expression>, scope: Node): DataType {
|
internal fun translateUnaryFunctionCallWithArgSource(target: IdentifierReference, arg: AsmAssignSource, isStatement: Boolean, scope: Subroutine): DataType {
|
||||||
when(val targetStmt = target.targetStatement(program)!!) {
|
when(val targetStmt = target.targetStatement(program)!!) {
|
||||||
is BuiltinFunctionPlaceholder -> {
|
is BuiltinFunctionPlaceholder -> {
|
||||||
val call = FunctionCallExpression(target, args.toMutableList(), scope.position)
|
return if(isStatement) {
|
||||||
call.linkParents(scope)
|
asmgen.translateBuiltinFunctionCallStatement(targetStmt.name, listOf(arg), scope)
|
||||||
val signature = BuiltinFunctions.getValue(targetStmt.name)
|
DataType.UNDEFINED
|
||||||
asmgen.translateBuiltinFunctionCallExpression(call, signature, false, null)
|
|
||||||
return signature.known_returntype!!
|
|
||||||
}
|
|
||||||
is Subroutine -> {
|
|
||||||
val call = FunctionCallExpression(target, args.toMutableList(), scope.position)
|
|
||||||
call.linkParents(scope)
|
|
||||||
translateFunctionCall(call, true)
|
|
||||||
return call.inferType(program).getOrElse { throw AssemblyError("invalid dt") }
|
|
||||||
}
|
|
||||||
else -> throw AssemblyError("invalid call target")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun translateFunctionCallStatement(target: IdentifierReference, args: Iterable<Expression>, scope: Node) {
|
|
||||||
when(val targetStmt = target.targetStatement(program)!!) {
|
|
||||||
is BuiltinFunctionPlaceholder -> {
|
|
||||||
val call = FunctionCallStatement(target, args.toMutableList(), true, scope.position)
|
|
||||||
call.linkParents(scope)
|
|
||||||
val signature = BuiltinFunctions.getValue(targetStmt.name)
|
|
||||||
asmgen.translateBuiltinFunctionCallStatement(call, signature)
|
|
||||||
}
|
|
||||||
is Subroutine -> {
|
|
||||||
if(targetStmt.isAsmSubroutine) {
|
|
||||||
val call = FunctionCallStatement(target, args.toMutableList(), true, scope.position)
|
|
||||||
call.linkParents(scope)
|
|
||||||
translateFunctionCallStatement(call)
|
|
||||||
} else {
|
} else {
|
||||||
// have to use manual parameter assignment and jsr, because no codegen for FunctionCallStmt here
|
asmgen.translateBuiltinFunctionCallExpression(targetStmt.name, listOf(arg), scope)
|
||||||
val tempVar = args.single()
|
|
||||||
tempVar.linkParents(scope)
|
|
||||||
argumentViaVariable(targetStmt, targetStmt.parameters.single(), tempVar)
|
|
||||||
asmgen.out(" jsr ${asmgen.asmSymbolName(target)}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is Subroutine -> {
|
||||||
|
val argDt = targetStmt.parameters.single().type
|
||||||
|
if(targetStmt.isAsmSubroutine) {
|
||||||
|
// argument via registers
|
||||||
|
val argRegister = targetStmt.asmParameterRegisters.single().registerOrPair!!
|
||||||
|
val assignArgument = AsmAssignment(
|
||||||
|
arg,
|
||||||
|
AsmAssignTarget.fromRegisters(argRegister, argDt in SignedDatatypes, scope, program, asmgen),
|
||||||
|
false, program.memsizer, target.position
|
||||||
|
)
|
||||||
|
asmgen.translateNormalAssignment(assignArgument)
|
||||||
|
} else {
|
||||||
|
val assignArgument: AsmAssignment =
|
||||||
|
if(optimizeIntArgsViaRegisters(targetStmt)) {
|
||||||
|
// argument goes via registers as optimization
|
||||||
|
val paramReg: RegisterOrPair = when(argDt) {
|
||||||
|
in ByteDatatypes -> RegisterOrPair.A
|
||||||
|
in WordDatatypes -> RegisterOrPair.AY
|
||||||
|
DataType.FLOAT -> RegisterOrPair.FAC1
|
||||||
|
else -> throw AssemblyError("invalid dt")
|
||||||
|
}
|
||||||
|
AsmAssignment(
|
||||||
|
arg,
|
||||||
|
AsmAssignTarget(TargetStorageKind.REGISTER, program, asmgen, argDt, scope, register = paramReg),
|
||||||
|
false, program.memsizer, target.position
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// arg goes via parameter variable
|
||||||
|
val argVarName = asmgen.asmVariableName(targetStmt.scopedName + targetStmt.parameters.single().name)
|
||||||
|
AsmAssignment(
|
||||||
|
arg,
|
||||||
|
AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, argDt, scope, argVarName),
|
||||||
|
false, program.memsizer, target.position
|
||||||
|
)
|
||||||
|
}
|
||||||
|
asmgen.translateNormalAssignment(assignArgument)
|
||||||
|
}
|
||||||
|
if(targetStmt.shouldSaveX())
|
||||||
|
asmgen.saveRegisterLocal(CpuRegister.X, scope)
|
||||||
|
asmgen.out(" jsr ${asmgen.asmSymbolName(target)}")
|
||||||
|
if(targetStmt.shouldSaveX())
|
||||||
|
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||||
|
return if(isStatement) DataType.UNDEFINED else targetStmt.returntypes.single()
|
||||||
|
}
|
||||||
else -> throw AssemblyError("invalid call target")
|
else -> throw AssemblyError("invalid call target")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,7 @@ val ByteDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE)
|
|||||||
val WordDatatypes = arrayOf(DataType.UWORD, DataType.WORD)
|
val WordDatatypes = arrayOf(DataType.UWORD, DataType.WORD)
|
||||||
val IntegerDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD)
|
val IntegerDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD)
|
||||||
val NumericDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT)
|
val NumericDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT)
|
||||||
|
val SignedDatatypes = arrayOf(DataType.BYTE, DataType.WORD, DataType.FLOAT)
|
||||||
val ArrayDatatypes = arrayOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F)
|
val ArrayDatatypes = arrayOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F)
|
||||||
val StringlyDatatypes = arrayOf(DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B, DataType.UWORD)
|
val StringlyDatatypes = arrayOf(DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B, DataType.UWORD)
|
||||||
val IterableDatatypes = arrayOf(
|
val IterableDatatypes = arrayOf(
|
||||||
|
@ -3,7 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next compiler release (7.7)
|
For next compiler release (7.7)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- optimize codegen of pipe operator to avoid needless assigns to temp var
|
...
|
||||||
|
|
||||||
|
|
||||||
Need help with
|
Need help with
|
||||||
@ -53,6 +53,7 @@ Future Things and Ideas
|
|||||||
|
|
||||||
More optimization ideas
|
More optimization ideas
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
- translateFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters directly from register(s)
|
||||||
- translateNormalAssignment() -> better code gen for assigning boolean comparison expressions
|
- translateNormalAssignment() -> better code gen for assigning boolean comparison expressions
|
||||||
- if a for loop's loopvariable isn't referenced in the body, replace by a repeatloop
|
- if a for loop's loopvariable isn't referenced in the body, replace by a repeatloop
|
||||||
- automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning
|
- automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning
|
||||||
|
@ -5,42 +5,39 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword ww
|
float fl
|
||||||
ubyte bb
|
test_stack.test()
|
||||||
|
|
||||||
derp("aaaa")
|
fl = addfloat3(addfloat2(addfloat1(1.234)))
|
||||||
bb = ww==0
|
floats.print_f(fl)
|
||||||
bb++
|
txt.nl()
|
||||||
if ww==0 {
|
|
||||||
bb++
|
|
||||||
}
|
|
||||||
|
|
||||||
sub derp(str name) {
|
fl = 1.234 |> addfloat1 |> addfloat2 |> addfloat3
|
||||||
txt.print(name)
|
floats.print_f(fl)
|
||||||
}
|
txt.nl()
|
||||||
|
1.234 |> addfloat1
|
||||||
|
|> addfloat2 |> addfloat3 |> floats.print_f
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
; fl = 1.234 |> addfloat1 |> addfloat2 |> addfloat3
|
txt.print_uw(times_two(add_one(sin8u(add_one(assemblything(9+3))))))
|
||||||
; floats.print_f(fl)
|
txt.nl()
|
||||||
; txt.nl()
|
|
||||||
; 1.234 |> addfloat1
|
|
||||||
; |> addfloat2 |> addfloat3 |> floats.print_f
|
|
||||||
; txt.nl()
|
|
||||||
;
|
|
||||||
; 9+3 |> assemblything
|
|
||||||
; |> sin8u
|
|
||||||
; |> add_one
|
|
||||||
; |> times_two
|
|
||||||
; |> txt.print_uw
|
|
||||||
; txt.nl()
|
|
||||||
|
|
||||||
; test_stack.test()
|
9+3 |> assemblything
|
||||||
; uword @shared uw= 9+3 |> assemblything
|
|> add_one
|
||||||
; |> sin8u
|
|> sin8u
|
||||||
; |> add_one
|
|> add_one
|
||||||
; |> times_two
|
|> times_two
|
||||||
; txt.print_uw(uw)
|
|> txt.print_uw
|
||||||
; txt.nl()
|
txt.nl()
|
||||||
; test_stack.test()
|
|
||||||
|
uword @shared uw= 9+3 |> assemblything
|
||||||
|
|> add_one
|
||||||
|
|> sin8u
|
||||||
|
|> add_one
|
||||||
|
|> times_two
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.nl()
|
||||||
|
test_stack.test()
|
||||||
}
|
}
|
||||||
|
|
||||||
sub func() -> ubyte {
|
sub func() -> ubyte {
|
||||||
@ -65,7 +62,7 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub times_two(ubyte input) -> uword {
|
sub times_two(ubyte input) -> uword {
|
||||||
return input*$6464642
|
return input*$0002
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub assemblything(ubyte input @A) clobbers(X,Y) -> ubyte @A {
|
asmsub assemblything(ubyte input @A) clobbers(X,Y) -> ubyte @A {
|
||||||
|
Loading…
Reference in New Issue
Block a user