mirror of
https://github.com/irmen/prog8.git
synced 2024-11-19 11:32:17 +00:00
optimized neg(x) and abs(x)
This commit is contained in:
parent
96ef7ba55d
commit
448c934cba
@ -355,19 +355,19 @@ mul_f .proc
|
||||
.pend
|
||||
|
||||
neg_f .proc
|
||||
; -- push -flt back on stack
|
||||
jsr pop_float_fac1
|
||||
stx P8ZP_SCRATCH_REG
|
||||
jsr NEGOP
|
||||
jmp push_fac1_as_result
|
||||
; -- toggle the sign bit on the stack
|
||||
lda P8ESTACK_LO+3,x
|
||||
eor #$80
|
||||
sta P8ESTACK_LO+3,x
|
||||
rts
|
||||
.pend
|
||||
|
||||
abs_f .proc
|
||||
; -- push abs(float) on stack (as float)
|
||||
jsr pop_float_fac1
|
||||
stx P8ZP_SCRATCH_REG
|
||||
jsr ABS
|
||||
jmp push_fac1_as_result
|
||||
; -- strip the sign bit on the stack
|
||||
lda P8ESTACK_LO+3,x
|
||||
and #$7f
|
||||
sta P8ESTACK_LO+3,x
|
||||
rts
|
||||
.pend
|
||||
|
||||
equal_f .proc
|
||||
|
@ -84,7 +84,7 @@ internal class StatementReorderer(val program: Program) : AstWalker() {
|
||||
override fun before(assignment: Assignment, parent: Node): Iterable<IAstModification> {
|
||||
val valueType = assignment.value.inferType(program)
|
||||
val targetType = assignment.target.inferType(program, assignment)
|
||||
if(valueType.istype(DataType.STRUCT) && targetType.istype(DataType.STRUCT)) {
|
||||
if(targetType.istype(DataType.STRUCT) && (valueType.istype(DataType.STRUCT) || valueType.typeOrElse(DataType.STRUCT) in ArrayDatatypes )) {
|
||||
val assignments = if (assignment.value is ArrayLiteralValue) {
|
||||
flattenStructAssignmentFromStructLiteral(assignment, program) // 'structvar = [ ..... ] '
|
||||
} else {
|
||||
@ -179,26 +179,34 @@ internal class StatementReorderer(val program: Program) : AstWalker() {
|
||||
when (structAssignment.value) {
|
||||
is IdentifierReference -> {
|
||||
val sourceVar = (structAssignment.value as IdentifierReference).targetVarDecl(program.namespace)!!
|
||||
if (sourceVar.struct == null)
|
||||
throw FatalAstException("can only assign arrays or structs to structs")
|
||||
// struct memberwise copy
|
||||
val sourceStruct = sourceVar.struct!!
|
||||
if(sourceStruct!==targetVar.struct) {
|
||||
// structs are not the same in assignment
|
||||
return listOf() // error will be printed elsewhere
|
||||
}
|
||||
return struct.statements.zip(sourceStruct.statements).map { member ->
|
||||
val targetDecl = member.first as VarDecl
|
||||
val sourceDecl = member.second as VarDecl
|
||||
if(targetDecl.name != sourceDecl.name)
|
||||
throw FatalAstException("struct member mismatch")
|
||||
val mangled = mangledStructMemberName(identifierName, targetDecl.name)
|
||||
val idref = IdentifierReference(listOf(mangled), structAssignment.position)
|
||||
val sourcemangled = mangledStructMemberName(sourceVar.name, sourceDecl.name)
|
||||
val sourceIdref = IdentifierReference(listOf(sourcemangled), structAssignment.position)
|
||||
val assign = Assignment(AssignTarget(idref, null, null, structAssignment.position), sourceIdref, member.second.position)
|
||||
assign.linkParents(structAssignment)
|
||||
assign
|
||||
when {
|
||||
sourceVar.struct!=null -> {
|
||||
// struct memberwise copy
|
||||
val sourceStruct = sourceVar.struct!!
|
||||
if(sourceStruct!==targetVar.struct) {
|
||||
// structs are not the same in assignment
|
||||
return listOf() // error will be printed elsewhere
|
||||
}
|
||||
return struct.statements.zip(sourceStruct.statements).map { member ->
|
||||
val targetDecl = member.first as VarDecl
|
||||
val sourceDecl = member.second as VarDecl
|
||||
if(targetDecl.name != sourceDecl.name)
|
||||
throw FatalAstException("struct member mismatch")
|
||||
val mangled = mangledStructMemberName(identifierName, targetDecl.name)
|
||||
val idref = IdentifierReference(listOf(mangled), structAssignment.position)
|
||||
val sourcemangled = mangledStructMemberName(sourceVar.name, sourceDecl.name)
|
||||
val sourceIdref = IdentifierReference(listOf(sourcemangled), structAssignment.position)
|
||||
val assign = Assignment(AssignTarget(idref, null, null, structAssignment.position), sourceIdref, member.second.position)
|
||||
assign.linkParents(structAssignment)
|
||||
assign
|
||||
}
|
||||
}
|
||||
sourceVar.isArray -> {
|
||||
TODO("assign struct array $structAssignment")
|
||||
}
|
||||
else -> {
|
||||
throw FatalAstException("can only assign arrays or structs to structs")
|
||||
}
|
||||
}
|
||||
}
|
||||
is ArrayLiteralValue -> {
|
||||
|
@ -1680,15 +1680,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
DataType.FLOAT -> {
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
asmgen.saveRegister(CpuRegister.X)
|
||||
// simply flip the sign bit in the float
|
||||
asmgen.out("""
|
||||
lda #<${target.asmVarname}
|
||||
ldy #>${target.asmVarname}
|
||||
jsr floats.MOVFM
|
||||
jsr floats.NEGOP
|
||||
ldx #<${target.asmVarname}
|
||||
ldy #>${target.asmVarname}
|
||||
jsr floats.MOVMF
|
||||
lda ${target.asmVarname}+1
|
||||
eor #$80
|
||||
sta ${target.asmVarname}+1
|
||||
""")
|
||||
asmgen.restoreRegister(CpuRegister.X)
|
||||
}
|
||||
|
@ -1,15 +1,11 @@
|
||||
%import textio
|
||||
%import syslib
|
||||
%import floats
|
||||
%zeropage basicsafe
|
||||
|
||||
|
||||
main {
|
||||
|
||||
struct Color {
|
||||
ubyte red
|
||||
ubyte green
|
||||
ubyte blue
|
||||
}
|
||||
|
||||
; Color c1 = [11,22,33] ; TODO fix crash
|
||||
; Color c2 = [11,22,33] ; TODO fix crash
|
||||
@ -24,15 +20,40 @@ main {
|
||||
|
||||
|
||||
sub start() {
|
||||
Color c1 = [11,22,33]
|
||||
Color c2 = [11,22,33]
|
||||
Color c3 = [11,22,33]
|
||||
uword[] colors = [ c1, c2, c3] ; TODO should contain pointers to (the first element) of each struct
|
||||
byte bb = 100
|
||||
word ww = 30000
|
||||
float ff1 = 12345
|
||||
float ff2 = -99999
|
||||
|
||||
c1.red = 100
|
||||
c1.green = 100
|
||||
c1.blue = 100
|
||||
; c1 = [11,22,33] ; TODO rewrite into individual struct member assignments
|
||||
floats.print_f(ff1)
|
||||
txt.chrout('\n')
|
||||
;ff = 1+((-ff) *3) ; TODO fix invalid splitting (can't split because it references ff itself)
|
||||
;ff = 1+((-ff2) *3) ; TODO splitting should be okay here
|
||||
ff1 = -ff2 * 3
|
||||
floats.print_f(ff1)
|
||||
txt.chrout('\n')
|
||||
floats.print_f(-ff2)
|
||||
txt.chrout('\n')
|
||||
floats.print_f(-ff1)
|
||||
txt.chrout('\n')
|
||||
return
|
||||
|
||||
struct Color {
|
||||
ubyte red
|
||||
ubyte green
|
||||
ubyte blue
|
||||
}
|
||||
|
||||
;Color c1 = [11,22,33] ; TODO fix struct initializer crash
|
||||
Color c1
|
||||
Color c2
|
||||
Color c3
|
||||
;Color c2 = [11,22,33]
|
||||
;Color c3 = [11,22,33]
|
||||
;uword[] colors = [ c1, c2, c3] ; TODO should contain pointers to (the first element) of each struct
|
||||
|
||||
c1 = c2
|
||||
;c1 = [11,22,33] ; TODO rewrite into individual struct member assignments
|
||||
|
||||
|
||||
uword s
|
||||
|
Loading…
Reference in New Issue
Block a user