optimized neg(x) and abs(x)

This commit is contained in:
Irmen de Jong 2020-09-29 03:58:17 +02:00
parent 96ef7ba55d
commit 448c934cba
4 changed files with 77 additions and 52 deletions

View File

@ -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

View File

@ -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 -> {

View File

@ -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)
}

View File

@ -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