IR: use SCS opcode to set carry status flag into register

This commit is contained in:
Irmen de Jong 2024-01-09 23:46:27 +01:00
parent f27e3478b9
commit ddb2ff4216
3 changed files with 24 additions and 19 deletions

View File

@ -461,24 +461,22 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
else else
IRInstruction(Opcode.CALL, address = callTarget.address!!.toInt(), fcallArgs = FunctionCallArgs(argRegisters, returnRegSpec)) IRInstruction(Opcode.CALL, address = callTarget.address!!.toInt(), fcallArgs = FunctionCallArgs(argRegisters, returnRegSpec))
addInstr(result, call, null) addInstr(result, call, null)
var finalReturnRegister = returnRegSpec?.registerNum ?: -1 var finalReturnRegister = returnRegSpec?.registerNum ?: -1
if(fcall.parent is PtAssignment) { if(fcall.parent is PtAssignment || fcall.parent is PtTypeCast) {
// look if the status flag bit should actually be returned as a 0/1 byte value in a result register (so it can be assigned) // look if the status flag bit should actually be returned as a 0/1 byte value in a result register (so it can be assigned)
if(statusFlagResult!=null && returnRegSpec!=null) { if(statusFlagResult!=null && returnRegSpec!=null) {
// assign status flag bit to the return value register // assign status flag bit to the return value register
finalReturnRegister = codeGen.registers.nextFree() finalReturnRegister = returnRegSpec.registerNum
if(finalReturnRegister<0)
finalReturnRegister = codeGen.registers.nextFree()
when(statusFlagResult) { when(statusFlagResult) {
Statusflag.Pc -> { Statusflag.Pc -> {
result += IRCodeChunk(null, null).also { addInstr(result, IRInstruction(Opcode.SCS, returnRegSpec.dt, reg1=finalReturnRegister), null)
it += IRInstruction(Opcode.LOAD, returnRegSpec.dt, reg1=finalReturnRegister, immediate = 0)
it += IRInstruction(Opcode.ROXL, returnRegSpec.dt, reg1=finalReturnRegister)
}
} }
else -> { else -> {
val branchOpcode = when(statusFlagResult) { val branchOpcode = when(statusFlagResult) {
Statusflag.Pc -> Opcode.BSTCS Statusflag.Pc -> throw AssemblyError("carry should be treated separately")
Statusflag.Pz -> Opcode.BSTEQ Statusflag.Pz -> Opcode.BSTEQ
Statusflag.Pv -> Opcode.BSTVS Statusflag.Pv -> Opcode.BSTVS
Statusflag.Pn -> Opcode.BSTNEG Statusflag.Pn -> Opcode.BSTNEG
@ -498,6 +496,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
} }
return if(fcall.void) return if(fcall.void)
ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
else if(fcall.type==DataType.FLOAT) else if(fcall.type==DataType.FLOAT)

View File

@ -1,10 +1,6 @@
TODO TODO
==== ====
IR: use SCC and SCS, to optimize some code that sets 0/1 based on carry flag status
try to get rid of ArrayIndex class
... ...

View File

@ -1,16 +1,26 @@
%import floats
%import textio %import textio
%zeropage basicsafe %zeropage basicsafe
%option no_sysinit %option no_sysinit
main { main {
sub start() { sub start() {
&uword[30] wb = $2000 ubyte xx = wobwob()
&uword[100] array1 = $9e00 txt.print_ub(xx)
&uword[30] array2 = &array1[len(wb)] uword yy = wobwob2()
txt.print_uw(yy)
txt.print_uwhex(&array1, true) ; $9e00 asmsub wobwob() -> bool @Pc {
txt.print_uwhex(&array1[len(wb)], true) ; $9e3c %asm {{
txt.print_uwhex(&array2, true) ; $9e3c sec
rts
}}
}
asmsub wobwob2() -> bool @Pc {
%asm {{
clc
rts
}}
}
} }
} }