mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
optimize word [operator] byte, without translateExpression()
This commit is contained in:
parent
378dcfe351
commit
936b046ed9
@ -1065,3 +1065,29 @@ _return_minusone
|
|||||||
lda #-1
|
lda #-1
|
||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
sign_extend_stack_byte .proc
|
||||||
|
; -- sign extend the (signed) byte on the stack to full 16 bits
|
||||||
|
lda P8ESTACK_LO+1,x
|
||||||
|
ora #$7f
|
||||||
|
bmi +
|
||||||
|
lda #0
|
||||||
|
+ sta P8ESTACK_HI+1,x
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
sign_extend_AY_byte .proc
|
||||||
|
; -- sign extend the (signed) byte in AY to full 16 bits
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
and #$80
|
||||||
|
beq +
|
||||||
|
ldy #$ff
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
+ ldy #0
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
@ -1192,20 +1192,20 @@ $label nop""")
|
|||||||
assemblyLines.add(assembly)
|
assemblyLines.add(assembly)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun signExtendAYlsb(valueDt: DataType) {
|
||||||
|
// sign extend signed byte in AY to full word in AY
|
||||||
|
when(valueDt) {
|
||||||
|
DataType.UBYTE -> out(" ldy #0")
|
||||||
|
DataType.BYTE -> out(" jsr prog8_lib.sign_extend_AY_byte")
|
||||||
|
else -> throw AssemblyError("need byte type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun signExtendStackLsb(valueDt: DataType) {
|
internal fun signExtendStackLsb(valueDt: DataType) {
|
||||||
// sign extend signed byte on stack to signed word
|
// sign extend signed byte on stack to signed word
|
||||||
when(valueDt) {
|
when(valueDt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> out(" lda #0 | sta P8ESTACK_HI+1,x")
|
||||||
out(" lda #0 | sta P8ESTACK_HI+1,x")
|
DataType.BYTE -> out(" jsr prog8_lib.sign_extend_stack_byte")
|
||||||
}
|
|
||||||
DataType.BYTE -> {
|
|
||||||
out("""
|
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
ora #$7f
|
|
||||||
bmi +
|
|
||||||
lda #0
|
|
||||||
+ sta P8ESTACK_HI+1,x""")
|
|
||||||
}
|
|
||||||
else -> throw AssemblyError("need byte type")
|
else -> throw AssemblyError("need byte type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
is IdentifierReference -> throw AssemblyError("source kind should have been variable")
|
is IdentifierReference -> throw AssemblyError("source kind should have been variable")
|
||||||
is ArrayIndexedExpression -> throw AssemblyError("source kind should have been array")
|
is ArrayIndexedExpression -> throw AssemblyError("source kind should have been array")
|
||||||
is DirectMemoryRead -> throw AssemblyError("source kind should have been memory")
|
is DirectMemoryRead -> throw AssemblyError("source kind should have been memory")
|
||||||
is TypecastExpression -> assignTypeCastedValue(assign.target, value.type, value.expression, assign)
|
is TypecastExpression -> assignTypeCastedValue(assign.target, value.type, value.expression, value)
|
||||||
is FunctionCall -> {
|
is FunctionCall -> {
|
||||||
when (val sub = value.target.targetStatement(program.namespace)) {
|
when (val sub = value.target.targetStatement(program.namespace)) {
|
||||||
is Subroutine -> {
|
is Subroutine -> {
|
||||||
@ -227,11 +227,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: Expression, origAssign: AsmAssignment) {
|
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: Expression, origTypeCastExpression: TypecastExpression) {
|
||||||
val valueIDt = value.inferType(program)
|
val valueIDt = value.inferType(program)
|
||||||
if(!valueIDt.isKnown)
|
if(!valueIDt.isKnown)
|
||||||
throw AssemblyError("unknown dt")
|
throw AssemblyError("unknown dt")
|
||||||
val valueDt = valueIDt.typeOrElse(DataType.STRUCT)
|
val valueDt = valueIDt.typeOrElse(DataType.STRUCT)
|
||||||
|
if(valueDt==targetDt)
|
||||||
|
throw AssemblyError("type cast to identical dt should have been removed")
|
||||||
|
|
||||||
when(value) {
|
when(value) {
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
if(targetDt in WordDatatypes) {
|
if(targetDt in WordDatatypes) {
|
||||||
@ -262,35 +265,26 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
when(value) {
|
|
||||||
is IdentifierReference -> {
|
// special case optimizations
|
||||||
if(target.kind==TargetStorageKind.VARIABLE) {
|
if (value is IdentifierReference) {
|
||||||
val sourceDt = value.inferType(program).typeOrElse(DataType.STRUCT)
|
if(target.kind==TargetStorageKind.VARIABLE) {
|
||||||
if (sourceDt != DataType.STRUCT)
|
if (valueDt != DataType.STRUCT)
|
||||||
return assignTypeCastedIdentifier(target.asmVarname, targetDt, asmgen.asmVariableName(value), sourceDt, origAssign.source.expression!!)
|
return assignTypeCastedIdentifier(target.asmVarname, targetDt, asmgen.asmVariableName(value), valueDt)
|
||||||
}
|
|
||||||
}
|
|
||||||
is PrefixExpression -> {}
|
|
||||||
is BinaryExpression -> {}
|
|
||||||
is ArrayIndexedExpression -> {}
|
|
||||||
is TypecastExpression -> {}
|
|
||||||
is RangeExpr -> {}
|
|
||||||
is FunctionCall -> {}
|
|
||||||
else -> {
|
|
||||||
// TODO optimize the others further?
|
|
||||||
if(this.asmgen.options.slowCodegenWarnings)
|
|
||||||
println("warning: slow stack evaluation used for typecast: $value into $targetDt at ${value.position}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// give up, do it via eval stack
|
// give up, do it via eval stack
|
||||||
asmgen.translateExpression(origAssign.source.expression!!)
|
// TODO optimize typecasts for more special cases?
|
||||||
|
// note: cannot use assignTypeCastedValue because that is ourselves :P
|
||||||
|
if(this.asmgen.options.slowCodegenWarnings)
|
||||||
|
println("warning: slow stack evaluation used for typecast: $value into $targetDt at ${value.position}")
|
||||||
|
asmgen.translateExpression(origTypeCastExpression) // this performs the actual type cast in translateExpression(Typecast)
|
||||||
assignStackValue(target)
|
assignStackValue(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignTypeCastedIdentifier(targetAsmVarName: String, targetDt: DataType,
|
private fun assignTypeCastedIdentifier(targetAsmVarName: String, targetDt: DataType,
|
||||||
sourceAsmVarName: String, sourceDt: DataType,
|
sourceAsmVarName: String, sourceDt: DataType) {
|
||||||
origExpr: Expression) {
|
|
||||||
if(sourceDt == targetDt)
|
if(sourceDt == targetDt)
|
||||||
throw AssemblyError("typecast to identical value")
|
throw AssemblyError("typecast to identical value")
|
||||||
|
|
||||||
|
@ -1100,11 +1100,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
throw AssemblyError("unknown dt")
|
throw AssemblyError("unknown dt")
|
||||||
val valueDt = valueiDt.typeOrElse(DataType.STRUCT)
|
val valueDt = valueiDt.typeOrElse(DataType.STRUCT)
|
||||||
|
|
||||||
// TODO can use registers instead of stack value?
|
fun multiplyVarByWordInAY() {
|
||||||
fun multiplyWord() {
|
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
ldy P8ESTACK_HI+1,x
|
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
sty P8ZP_SCRATCH_W1+1
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda $name
|
lda $name
|
||||||
@ -1117,51 +1114,36 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO can use registers instead of stack value?
|
fun divideVarByWordInAY() {
|
||||||
fun divideWord() {
|
asmgen.out("""
|
||||||
if (dt == DataType.WORD) {
|
pha
|
||||||
asmgen.out("""
|
|
||||||
lda $name
|
lda $name
|
||||||
ldy $name+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
sty P8ZP_SCRATCH_W1+1
|
lda $name+1
|
||||||
lda P8ESTACK_LO+1,x
|
sta P8ZP_SCRATCH_W1+1
|
||||||
ldy P8ESTACK_HI+1,x
|
pla""")
|
||||||
jsr math.divmod_w_asm
|
if (dt == DataType.WORD)
|
||||||
sta $name
|
asmgen.out(" jsr math.divmod_w_asm")
|
||||||
sty $name+1
|
else
|
||||||
""")
|
asmgen.out(" jsr math.divmod_uw_asm")
|
||||||
} else {
|
asmgen.out(" sta $name | sty $name+1")
|
||||||
asmgen.out("""
|
|
||||||
lda $name
|
|
||||||
ldy $name+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
lda P8ESTACK_LO+1,x
|
|
||||||
ldy P8ESTACK_HI+1,x
|
|
||||||
jsr math.divmod_uw_asm
|
|
||||||
sta $name
|
|
||||||
sty $name+1
|
|
||||||
""")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO can use registers instead of stack value?
|
fun remainderVarByWordInAY() {
|
||||||
fun remainderWord() {
|
|
||||||
if(dt==DataType.WORD)
|
if(dt==DataType.WORD)
|
||||||
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
pha
|
||||||
lda $name
|
lda $name
|
||||||
ldy $name+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
sty P8ZP_SCRATCH_W1+1
|
lda $name+1
|
||||||
lda P8ESTACK_LO+1,x
|
sta P8ZP_SCRATCH_W1+1
|
||||||
ldy P8ESTACK_HI+1,x
|
pla
|
||||||
jsr math.divmod_uw_asm
|
jsr math.divmod_uw_asm
|
||||||
lda P8ZP_SCRATCH_W2
|
lda P8ZP_SCRATCH_W2
|
||||||
|
ldy P8ZP_SCRATCH_W2+1
|
||||||
sta $name
|
sta $name
|
||||||
lda P8ZP_SCRATCH_W2+1
|
sty $name+1
|
||||||
sta $name+1
|
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1171,14 +1153,12 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> {
|
"+" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt, null)
|
||||||
println("warning: slow stack evaluation used (4): $name += ${value::class.simpleName} at ${value.position}") // TODO
|
|
||||||
asmgen.translateExpression(value)
|
|
||||||
if(valueDt==DataType.UBYTE)
|
if(valueDt==DataType.UBYTE)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
clc
|
clc
|
||||||
adc P8ESTACK_LO+1,x
|
adc P8ZP_SCRATCH_B1
|
||||||
sta $name
|
sta $name
|
||||||
bcc +
|
bcc +
|
||||||
inc $name+1
|
inc $name+1
|
||||||
@ -1186,7 +1166,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
else
|
else
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
lda P8ESTACK_LO+1,x
|
lda P8ZP_SCRATCH_B1
|
||||||
bpl +
|
bpl +
|
||||||
dey ; sign extend
|
dey ; sign extend
|
||||||
+ clc
|
+ clc
|
||||||
@ -1195,17 +1175,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
tya
|
tya
|
||||||
adc $name+1
|
adc $name+1
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_REG", valueDt, null)
|
||||||
println("warning: slow stack evaluation used (4): $name -= ${value::class.simpleName} at ${value.position}") // TODO
|
|
||||||
asmgen.translateExpression(value)
|
|
||||||
if(valueDt==DataType.UBYTE)
|
if(valueDt==DataType.UBYTE)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
sec
|
sec
|
||||||
sbc P8ESTACK_LO+1,x
|
sbc P8ZP_SCRATCH_REG
|
||||||
sta $name
|
sta $name
|
||||||
bcs +
|
bcs +
|
||||||
dec $name+1
|
dec $name+1
|
||||||
@ -1213,45 +1190,38 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
else
|
else
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
lda P8ESTACK_LO+1,x
|
lda P8ZP_SCRATCH_REG
|
||||||
bpl +
|
bpl +
|
||||||
dey ; sign extend
|
dey ; sign extend
|
||||||
+ sty P8ZP_SCRATCH_B1
|
+ sty P8ZP_SCRATCH_B1
|
||||||
lda $name
|
lda $name
|
||||||
sec
|
sec
|
||||||
sbc P8ESTACK_LO+1,x
|
sbc P8ZP_SCRATCH_REG
|
||||||
sta $name
|
sta $name
|
||||||
lda $name+1
|
lda $name+1
|
||||||
sbc P8ZP_SCRATCH_B1
|
sbc P8ZP_SCRATCH_B1
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"*" -> {
|
"*" -> {
|
||||||
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
// TODO use an optimized word * byte multiplication routine
|
||||||
println("warning: slow stack evaluation used (4): $name *= ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.translateExpression(value)
|
asmgen.signExtendAYlsb(valueDt)
|
||||||
asmgen.signExtendStackLsb(valueDt)
|
multiplyVarByWordInAY()
|
||||||
multiplyWord()
|
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"/" -> {
|
"/" -> {
|
||||||
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
// TODO use an optimized word / byte divmod routine
|
||||||
println("warning: slow stack evaluation used (4): $name /= ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.translateExpression(value)
|
asmgen.signExtendAYlsb(valueDt)
|
||||||
asmgen.signExtendStackLsb(valueDt)
|
divideVarByWordInAY()
|
||||||
divideWord()
|
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"%" -> {
|
"%" -> {
|
||||||
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
// stack contains (u) byte value, sign extend that and proceed with regular 16 bit operation
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
// TODO use an optimized word / byte divmod routine
|
||||||
println("warning: slow stack evaluation used (4): $name %= ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.translateExpression(value)
|
asmgen.signExtendAYlsb(valueDt)
|
||||||
asmgen.signExtendStackLsb(valueDt)
|
remainderVarByWordInAY()
|
||||||
remainderWord()
|
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y)
|
||||||
@ -1306,56 +1276,37 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> {
|
"+" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
println("warning: slow stack evaluation used (4w): $name += ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.out(" clc | adc $name | sta $name | tya | adc $name+1 | sta $name+1")
|
||||||
asmgen.translateExpression(value)
|
|
||||||
asmgen.out(" lda $name | clc | adc P8ESTACK_LO+1,x | sta $name | lda $name+1 | adc P8ESTACK_HI+1,x | sta $name+1 | inx")
|
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_W1", valueDt, null)
|
||||||
println("warning: slow stack evaluation used (4w): $name -= ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.out(" lda $name | sec | sbc P8ZP_SCRATCH_W1 | sta $name | lda $name+1 | sbc P8ZP_SCRATCH_W1+1 | sta $name+1")
|
||||||
asmgen.translateExpression(value)
|
|
||||||
asmgen.out(" lda $name | sec | sbc P8ESTACK_LO+1,x | sta $name | lda $name+1 | sbc P8ESTACK_HI+1,x | sta $name+1 | inx")
|
|
||||||
}
|
}
|
||||||
"*" -> {
|
"*" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
println("warning: slow stack evaluation used (4w): $name *= ${value::class.simpleName} at ${value.position}") // TODO
|
multiplyVarByWordInAY()
|
||||||
asmgen.translateExpression(value)
|
|
||||||
multiplyWord()
|
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"/" -> {
|
"/" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
println("warning: slow stack evaluation used (4w): $name /= ${value::class.simpleName} at ${value.position}") // TODO
|
divideVarByWordInAY()
|
||||||
asmgen.translateExpression(value)
|
|
||||||
divideWord()
|
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"%" -> {
|
"%" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
println("warning: slow stack evaluation used (4w): $name %= ${value::class.simpleName} at ${value.position}") // TODO
|
remainderVarByWordInAY()
|
||||||
asmgen.translateExpression(value)
|
|
||||||
remainderWord()
|
|
||||||
asmgen.out(" inx")
|
|
||||||
}
|
}
|
||||||
"<<", ">>" -> throw AssemblyError("shift by a word value not supported, max is a byte")
|
"<<", ">>" -> throw AssemblyError("shift by a word value not supported, max is a byte")
|
||||||
"&" -> {
|
"&" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
println("warning: slow stack evaluation used (4w): $name &= ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.out(" and $name | sta $name | tya | and $name+1 | sta $name+1")
|
||||||
asmgen.translateExpression(value)
|
|
||||||
asmgen.out(" lda $name | and P8ESTACK_LO+1,x | sta $name | lda $name+1 | and P8ESTACK_HI+1,x | sta $name+1 | inx")
|
|
||||||
}
|
}
|
||||||
"^" -> {
|
"^" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
println("warning: slow stack evaluation used (4w): $name ^= ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.out(" eor $name | sta $name | tya | eor $name+1 | sta $name+1")
|
||||||
asmgen.translateExpression(value)
|
|
||||||
asmgen.out(" lda $name | eor P8ESTACK_LO+1,x | sta $name | lda $name+1 | eor P8ESTACK_HI+1,x | sta $name+1 | inx")
|
|
||||||
}
|
}
|
||||||
"|" -> {
|
"|" -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
println("warning: slow stack evaluation used (4w): $name |r= ${value::class.simpleName} at ${value.position}") // TODO
|
asmgen.out(" ora $name | sta $name | tya | ora $name+1 | sta $name+1")
|
||||||
asmgen.translateExpression(value)
|
|
||||||
asmgen.out(" lda $name | ora P8ESTACK_LO+1,x | sta $name | lda $name+1 | ora P8ESTACK_HI+1,x | sta $name+1 | inx")
|
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ main {
|
|||||||
uword uw = $c000
|
uword uw = $c000
|
||||||
ubyte ub = 1
|
ubyte ub = 1
|
||||||
ubyte ub2 = 1
|
ubyte ub2 = 1
|
||||||
|
uword uv1 = 1
|
||||||
|
uword uv2 = 1
|
||||||
|
|
||||||
uw = 1000
|
uw = 1000
|
||||||
uw += ub+ub2
|
uw += ub+ub2
|
||||||
@ -46,6 +48,65 @@ main {
|
|||||||
txt.print_uw(uw)
|
txt.print_uw(uw)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = $1111
|
||||||
|
uw &= (ub+ub2) | 15
|
||||||
|
txt.print_uwhex(uw, 1)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = $1111
|
||||||
|
uw |= (ub+ub2) | 15
|
||||||
|
txt.print_uwhex(uw, 1)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = $1111
|
||||||
|
uw ^= (ub+ub2) | 15
|
||||||
|
txt.print_uwhex(uw, 1)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uw = 1000
|
||||||
|
uw += uv1+uv2
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = 1000
|
||||||
|
uw -= uv1+uv2
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = 1000
|
||||||
|
uw *= uv1+uv2
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = 1000
|
||||||
|
uw /= uv1+uv2
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = 1000
|
||||||
|
uw %= 5*uv1+uv2+uv2
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = $1111
|
||||||
|
uw &= (uv1+uv2) | 1023
|
||||||
|
txt.print_uwhex(uw, 1)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = $1111
|
||||||
|
uw |= (uv1+uv2) | 32768
|
||||||
|
txt.print_uwhex(uw, 1)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uw = $1111
|
||||||
|
uw ^= (uv1+uv2) | 32768
|
||||||
|
txt.print_uwhex(uw, 1)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
test_stack.test()
|
test_stack.test()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user