mirror of
https://github.com/irmen/prog8.git
synced 2025-02-18 20:30:43 +00:00
ir: remove remaining SL* opcodes
This commit is contained in:
parent
af7930d494
commit
427451a23f
@ -869,7 +869,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
greaterEquals: Boolean
|
||||
): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val cmpResultReg = codeGen.registers.nextFree()
|
||||
if(vmDt==IRDataType.FLOAT) {
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
@ -877,15 +876,29 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
|
||||
val zeroRegister = codeGen.registers.nextFree()
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, immediate = 0), null)
|
||||
val ins = if (signed) {
|
||||
if (greaterEquals) Opcode.SGES else Opcode.SGTS
|
||||
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=resultRegister, immediate = 0), null)
|
||||
val other = codeGen.createLabelName()
|
||||
val after = codeGen.createLabelName()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
// TODO can this be done more efficiently? also see operatorLessThan
|
||||
if(greaterEquals) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.BSTPOS, labelSymbol = other)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultReg, immediate = 0)
|
||||
it += IRInstruction(Opcode.JUMP, labelSymbol = after)
|
||||
}
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultReg, immediate = 1), other)
|
||||
} else {
|
||||
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.BSTNEG, labelSymbol = other)
|
||||
it += IRInstruction(Opcode.BSTEQ, labelSymbol = other)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultReg, immediate = 1)
|
||||
it += IRInstruction(Opcode.JUMP, labelSymbol = after)
|
||||
}
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultReg, immediate = 0), other)
|
||||
}
|
||||
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1=cmpResultReg, reg2 = resultRegister, reg3 = zeroRegister), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, cmpResultReg, -1)
|
||||
result += IRCodeChunk(after, null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
} else {
|
||||
if(binExpr.left.type.isString || binExpr.right.type.isString) {
|
||||
throw AssemblyError("str compares should have been replaced with builtin function call to do the compare")
|
||||
@ -894,13 +907,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
addToResult(result, rightTr, rightTr.resultReg, -1)
|
||||
val ins = if (signed) {
|
||||
if (greaterEquals) Opcode.SGES else Opcode.SGTS
|
||||
val branch = if (signed) {
|
||||
if (greaterEquals) Opcode.BGESR else Opcode.BGTSR
|
||||
} else {
|
||||
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
||||
if (greaterEquals) Opcode.BGER else Opcode.BGTR
|
||||
}
|
||||
addInstr(result, IRInstruction(ins, vmDt, reg1=cmpResultReg, reg2 = leftTr.resultReg, reg3 = rightTr.resultReg), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, cmpResultReg, -1)
|
||||
val resultReg = compareRegisterAsBooleanResult(branch, leftTr.dt, leftTr.resultReg, rightTr.resultReg, result)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -923,7 +936,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val other = codeGen.createLabelName()
|
||||
val after = codeGen.createLabelName()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
// TODO can this be done more efficiently?
|
||||
// TODO can this be done more efficiently? also see operatorGreaterThan
|
||||
if(lessEquals) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.BSTNEG, labelSymbol = other)
|
||||
|
@ -351,15 +351,6 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a SNZ etc. whose target register is not used can be removed altogether
|
||||
if(ins.opcode in OpcodesThatSetRegFromStatusbits) {
|
||||
val usages = regUsages(ins.reg1!!)
|
||||
if(usages.toList().sumOf { it.second } <= 1) {
|
||||
chunk.instructions.removeAt(idx)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- addUsedRegistersCounts() doesn't always determine the datatype correctly. --> GET RID OF THE Sxxx OPCODES FOR NOW?
|
||||
|
||||
- add paypal donation button as well?
|
||||
- announce prog8 on the 6502.org site?
|
||||
|
||||
@ -54,9 +56,8 @@ Future Things and Ideas
|
||||
|
||||
IR/VM
|
||||
-----
|
||||
- add BZ and BNZ instructions? To replace CMPI #0 + Branch?
|
||||
- getting it in shape for code generation...: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
||||
- addUsedRegistersCounts() doesn't always determine the datatype correctly. --> GET RID OF THE Sxxx OPCODES FOR NOW?
|
||||
- add BZ and BNZ instructions? To replace CMPI #0 + Branch?
|
||||
- fix TODO("IR rol/ror on split words array")
|
||||
- fix "<< in array" / ">> in array"
|
||||
- implement missing operators in AssignmentGen (array shifts etc)
|
||||
|
@ -12,19 +12,34 @@ main {
|
||||
|
||||
cx16.r0 = $aaaa
|
||||
cx16.r1 = $2222
|
||||
f1 = 9999
|
||||
cx16.r0=9999
|
||||
txt.print_bool(f1 < 8000)
|
||||
f1 = 10000
|
||||
cx16.r0=10000
|
||||
; true false false
|
||||
; true true false
|
||||
; times 2.
|
||||
txt.print_bool(f1 > 8000)
|
||||
txt.spc()
|
||||
txt.print_bool(f1 < 10000)
|
||||
txt.print_bool(f1 > 10000)
|
||||
txt.spc()
|
||||
txt.print_bool(f1 < 20000)
|
||||
txt.print_bool(f1 > 20000)
|
||||
txt.nl()
|
||||
txt.print_bool(cx16.r0 < 8000)
|
||||
txt.print_bool(f1 >= 8000)
|
||||
txt.spc()
|
||||
txt.print_bool(cx16.r0 < 10000)
|
||||
txt.print_bool(f1 >= 10000)
|
||||
txt.spc()
|
||||
txt.print_bool(cx16.r0 < 20000)
|
||||
txt.print_bool(f1 >= 20000)
|
||||
txt.nl()
|
||||
txt.print_bool(cx16.r0 > 8000)
|
||||
txt.spc()
|
||||
txt.print_bool(cx16.r0 > 10000)
|
||||
txt.spc()
|
||||
txt.print_bool(cx16.r0 > 20000)
|
||||
txt.nl()
|
||||
txt.print_bool(cx16.r0 >= 8000)
|
||||
txt.spc()
|
||||
txt.print_bool(cx16.r0 >= 10000)
|
||||
txt.spc()
|
||||
txt.print_bool(cx16.r0 >= 20000)
|
||||
txt.nl()
|
||||
|
||||
cx16.r0L=0
|
||||
|
@ -123,12 +123,6 @@ bles reg1, value, address - jump to location in program given by l
|
||||
bgesr reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (signed)
|
||||
'blesr' reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (signed) ==> use bgesr with swapped operands
|
||||
|
||||
sgt reg1, reg2, reg3 - set reg1=1 if reg2 > reg3 (unsigned), else 0
|
||||
sgts reg1, reg2, reg3 - set reg1=1 if reg2 > reg3 (signed), else 0
|
||||
sge reg1, reg2, reg3 - set reg1=1 if reg2 >= reg3 (unsigned), else 0
|
||||
sges reg1, reg2, reg3 - set reg1=1 if reg2 >= reg3 (signed), else 0
|
||||
(note: on the M68k these instructions will set all bits to 1 (so value=-1 instead of 1), but the boolean logic here requires it to be 0 or 1 in this IR)
|
||||
|
||||
|
||||
ARITHMETIC
|
||||
----------
|
||||
@ -313,10 +307,6 @@ enum class Opcode {
|
||||
BGESR,
|
||||
BGES,
|
||||
BLES,
|
||||
SGT,
|
||||
SGTS,
|
||||
SGE,
|
||||
SGES,
|
||||
|
||||
INC,
|
||||
INCM,
|
||||
@ -505,13 +495,6 @@ val OpcodesThatDependOnCarry = arrayOf(
|
||||
Opcode.ROXRM,
|
||||
)
|
||||
|
||||
val OpcodesThatSetRegFromStatusbits = arrayOf(
|
||||
Opcode.SGT,
|
||||
Opcode.SGTS,
|
||||
Opcode.SGE,
|
||||
Opcode.SGES
|
||||
)
|
||||
|
||||
val OpcodesThatSetStatusbits = OpcodesThatSetStatusbitsButNotCarry + OpcodesThatSetStatusbitsIncludingCarry
|
||||
|
||||
|
||||
@ -662,10 +645,6 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.BGESR to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||
Opcode.BGES to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BLES to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.SGT to InstructionFormat.from("BW,<>r1,<r2,<r3"),
|
||||
Opcode.SGTS to InstructionFormat.from("BW,<>r1,<r2,<r3"),
|
||||
Opcode.SGE to InstructionFormat.from("BW,<>r1,<r2,<r3"),
|
||||
Opcode.SGES to InstructionFormat.from("BW,<>r1,<r2,<r3"),
|
||||
Opcode.INC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
Opcode.INCM to InstructionFormat.from("BW,<>a | F,<>a"),
|
||||
Opcode.DEC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
|
@ -236,10 +236,6 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
Opcode.BLE -> InsBLE(ins)
|
||||
Opcode.BGES -> InsBGES(ins)
|
||||
Opcode.BLES -> InsBLES(ins)
|
||||
Opcode.SGT -> InsSGT(ins)
|
||||
Opcode.SGTS -> InsSGTS(ins)
|
||||
Opcode.SGE -> InsSGE(ins)
|
||||
Opcode.SGES -> InsSGES(ins)
|
||||
Opcode.INC -> InsINC(ins)
|
||||
Opcode.INCM -> InsINCM(ins)
|
||||
Opcode.DEC -> InsDEC(ins)
|
||||
@ -885,34 +881,6 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsSGT(i: IRInstruction) {
|
||||
val (left, right) = getSetOnConditionOperandsU(i)
|
||||
val value = if(left>right) 1 else 0
|
||||
setResultReg(i.reg1!!, value, i.type!!)
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsSGTS(i: IRInstruction) {
|
||||
val (left, right) = getSetOnConditionOperands(i)
|
||||
val value = if(left>right) 1 else 0
|
||||
setResultReg(i.reg1!!, value, i.type!!)
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsSGE(i: IRInstruction) {
|
||||
val (left, right) = getSetOnConditionOperandsU(i)
|
||||
val value = if(left>=right) 1 else 0
|
||||
setResultReg(i.reg1!!, value, i.type!!)
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsSGES(i: IRInstruction) {
|
||||
val (left, right) = getSetOnConditionOperands(i)
|
||||
val value = if(left>=right) 1 else 0
|
||||
setResultReg(i.reg1!!, value, i.type!!)
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsINC(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user