mirror of
https://github.com/irmen/prog8.git
synced 2025-11-02 13:16:07 +00:00
fix code size regressions
This commit is contained in:
@@ -1223,11 +1223,11 @@ $repeatLabel""")
|
|||||||
return null
|
return null
|
||||||
val leftDt = left.type
|
val leftDt = left.type
|
||||||
val rightDt = right.type
|
val rightDt = right.type
|
||||||
if(leftDt.isUnsignedWord && rightDt.isUnsignedByte)
|
if((leftDt.isUnsignedWord || leftDt.isPointer) && rightDt.isUnsignedByte)
|
||||||
return Pair(left, right)
|
return Pair(left, right)
|
||||||
if(leftDt.isUnsignedByte && rightDt.isUnsignedWord)
|
if(leftDt.isUnsignedByte && rightDt.isUnsignedWord)
|
||||||
return Pair(right, left)
|
return Pair(right, left)
|
||||||
if(leftDt.isUnsignedWord && rightDt.isUnsignedWord) {
|
if((leftDt.isUnsignedWord || leftDt.isPointer) && rightDt.isUnsignedWord) {
|
||||||
// could be that the index was a constant numeric byte but converted to word, check that
|
// could be that the index was a constant numeric byte but converted to word, check that
|
||||||
val constIdx = right as? PtNumber
|
val constIdx = right as? PtNumber
|
||||||
if(constIdx!=null && constIdx.number.toInt()>=0 && constIdx.number.toInt()<=255) {
|
if(constIdx!=null && constIdx.number.toInt()>=0 && constIdx.number.toInt()<=255) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
|||||||
// we consider them NOT to be optimized into (possibly different) CPU registers.
|
// we consider them NOT to be optimized into (possibly different) CPU registers.
|
||||||
// Just load them in whatever the register spec says.
|
// Just load them in whatever the register spec says.
|
||||||
return when (params.size) {
|
return when (params.size) {
|
||||||
1 -> params[0].type.isIntegerOrBool && params[0].register == null
|
1 -> params[0].register == null && (params[0].type.isIntegerOrBool || params[0].type.isPointer)
|
||||||
2 -> params[0].type.isByteOrBool && params[1].type.isByteOrBool && params[0].register == null && params[1].register == null
|
2 -> params[0].type.isByteOrBool && params[1].type.isByteOrBool && params[0].register == null && params[1].register == null
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(typecast.type.isUnsignedWord && sourceDt.isPointer) {
|
||||||
|
// remove all typecasts of pointers to unsigned words.
|
||||||
|
return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent))
|
||||||
|
}
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1637,7 +1637,9 @@ class IfExpression(var condition: Expression, var truevalue: Expression, var fal
|
|||||||
override fun inferType(program: Program): InferredTypes.InferredType {
|
override fun inferType(program: Program): InferredTypes.InferredType {
|
||||||
val t1 = truevalue.inferType(program)
|
val t1 = truevalue.inferType(program)
|
||||||
val t2 = falsevalue.inferType(program)
|
val t2 = falsevalue.inferType(program)
|
||||||
return if(t1==t2) t1 else InferredTypes.unknown()
|
if(t1==t2) return t1
|
||||||
|
if(t1.isPointer && t2.isUnsignedWord || t1.isUnsignedWord && t2.isPointer) return InferredTypes.knownFor(BaseDataType.UWORD)
|
||||||
|
return InferredTypes.unknown()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun copy(): Expression = IfExpression(condition.copy(), truevalue.copy(), falsevalue.copy(), position)
|
override fun copy(): Expression = IfExpression(condition.copy(), truevalue.copy(), falsevalue.copy(), position)
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ Regular subroutines
|
|||||||
|
|
||||||
- A byte value will be put in ``A`` .
|
- A byte value will be put in ``A`` .
|
||||||
- A boolean value will be put in ``A`` too, as 0 or 1.
|
- A boolean value will be put in ``A`` too, as 0 or 1.
|
||||||
- A word value will be put in ``A`` + ``Y`` register pair (lsb in A, msb in Y).
|
- A word or pointer value will be put in ``A`` + ``Y`` register pair (lsb in A, msb in Y).
|
||||||
- A float value will be put in the ``FAC1`` float 'register'.
|
- A float value will be put in the ``FAC1`` float 'register'.
|
||||||
|
|
||||||
- In case of *multiple* return values:
|
- In case of *multiple* return values:
|
||||||
@@ -171,7 +171,7 @@ Regular subroutines
|
|||||||
some builtin functions are special and won't exactly follow these rules.
|
some builtin functions are special and won't exactly follow these rules.
|
||||||
|
|
||||||
**Some arguments will be passed in registers:**
|
**Some arguments will be passed in registers:**
|
||||||
For single byte and word arguments, the values are simply loaded in cpu registers by the caller before calling the subroutine.
|
For single byte, word, and pointer arguments, the values are simply loaded in cpu registers by the caller before calling the subroutine.
|
||||||
*The subroutine itself will take care of putting the values into the parameter variables.* This saves on code size because
|
*The subroutine itself will take care of putting the values into the parameter variables.* This saves on code size because
|
||||||
otherwise all callers would have to store the values in those variables themselves.
|
otherwise all callers would have to store the values in those variables themselves.
|
||||||
Note that his convention is also still used for subroutines that specify parameters to be put into
|
Note that his convention is also still used for subroutines that specify parameters to be put into
|
||||||
@@ -187,6 +187,9 @@ Two byte parameters: ``sub foo(ubyte bar, ubyte baz) { ... }``
|
|||||||
Single word parameter: ``sub foo(uword bar) { ... }``
|
Single word parameter: ``sub foo(uword bar) { ... }``
|
||||||
gets bar in the register pair A + Y (lsb in A, msb in Y), *subroutine* stores it into parameter variable
|
gets bar in the register pair A + Y (lsb in A, msb in Y), *subroutine* stores it into parameter variable
|
||||||
|
|
||||||
|
Single pointer parameter: ``sub foo(^^ubyte bar) { ... }``
|
||||||
|
gets bar in the register pair A + Y (lsb in A, msb in Y), *subroutine* stores it into parameter variable
|
||||||
|
|
||||||
Floating point parameter: ``sub foo(float bar) { ... }``
|
Floating point parameter: ``sub foo(float bar) { ... }``
|
||||||
value for bar gets copied into the parameter variable *by the caller*
|
value for bar gets copied into the parameter variable *by the caller*
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ TODO
|
|||||||
STRUCTS and TYPED POINTERS (6502 codegen specific)
|
STRUCTS and TYPED POINTERS (6502 codegen specific)
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
- fix code size regression. (for instance rockrunner is 200 bytes larger than before)
|
|
||||||
|
|
||||||
- fix struct allocations/inits.
|
- fix struct allocations/inits.
|
||||||
|
|
||||||
- prefixSymbols(): what to do with prefixing struct fields? Should they be prefixed with something or no?
|
- prefixSymbols(): what to do with prefixing struct fields? Should they be prefixed with something or no?
|
||||||
@@ -17,4 +15,4 @@ STRUCTS and TYPED POINTERS (6502 codegen specific)
|
|||||||
- update structpointers.rst docs with 6502 specific things?
|
- update structpointers.rst docs with 6502 specific things?
|
||||||
- scan through 6502 library modules to change untyped uword pointers to typed pointers
|
- scan through 6502 library modules to change untyped uword pointers to typed pointers
|
||||||
- scan through 6502 examples to change untyped uword pointers to typed pointers
|
- scan through 6502 examples to change untyped uword pointers to typed pointers
|
||||||
|
- fix code size regressions (if any)
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
struct Node {
|
void derp("a")
|
||||||
ubyte weight
|
}
|
||||||
}
|
|
||||||
^^Node nodes
|
sub derp(str arg) -> ubyte {
|
||||||
nodes^^.zzz1 = 99
|
if arg==0
|
||||||
cx16.r0L = nodes^^.zzz2
|
return 42
|
||||||
cx16.r0L = nodes[2].zzz3
|
if arg==4444
|
||||||
|
return 42
|
||||||
|
if arg!=0
|
||||||
|
return 42
|
||||||
|
if arg!=4444
|
||||||
|
return 42
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user