mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
ir: 4 new instructions to branch on signed <0, >0, <=0, >=0
This commit is contained in:
parent
eb4cff202c
commit
1e6fa77633
@ -1058,19 +1058,13 @@ class IRCodeGen(
|
||||
}
|
||||
|
||||
return when (ifElse.condition.operator) {
|
||||
"==" -> {
|
||||
// if X==0 ... so we just branch on left expr is Not-zero.
|
||||
equalOrNotEqualZero(Opcode.BNZ)
|
||||
}
|
||||
"!=" -> {
|
||||
// if X!=0 ... so we just branch on left expr is Zero.
|
||||
equalOrNotEqualZero(Opcode.BZ)
|
||||
}
|
||||
else -> {
|
||||
// another comparison against 0, just use regular codegen for this.
|
||||
// TODO optimize this
|
||||
translateNonZeroComparison()
|
||||
}
|
||||
"==" -> equalOrNotEqualZero(Opcode.BNZ)
|
||||
"!=" -> equalOrNotEqualZero(Opcode.BZ)
|
||||
"<" -> if(signed) equalOrNotEqualZero(Opcode.BGEZS) else throw AssemblyError("unsigned < 0 shouldn't occur in codegen")
|
||||
">" -> if(signed) equalOrNotEqualZero(Opcode.BLEZS) else throw AssemblyError("unsigned > 0 shouldn't occur in codegen")
|
||||
"<=" -> if(signed) equalOrNotEqualZero(Opcode.BGZS) else throw AssemblyError("unsigned <= 0 shouldn't occur in codegen")
|
||||
">=" -> if(signed) equalOrNotEqualZero(Opcode.BLZS) else throw AssemblyError("unsigned >= 0 shouldn't occur in codegen")
|
||||
else -> throw AssemblyError("weird operator")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- try to optimize IR for branching on signed <0, >0, <=0, >=0 by using new branch instructions like we have BNZ. To avoid explicit compares. See translateZeroComparison()
|
||||
- make sure bool value is always 0 or 1 (all casts should convert), then:
|
||||
- rewrite bool=bool^1 into bool=not bool
|
||||
- should solve: bool bb = not bb -> larger code than bool bb ^= 1
|
||||
|
@ -74,6 +74,10 @@ bstvc address - branch to location if Status bit Overf
|
||||
bstvs address - branch to location if Status bit Overflow is not set
|
||||
bz reg1, address - branch to location if reg1 is zero
|
||||
bnz reg1, address - branch to location if reg1 is not zero
|
||||
bgzs reg1, address - branch to location if reg1 > 0 (signed)
|
||||
bgezs reg1, address - branch to location if reg1 >= 0 (signed)
|
||||
blzs reg1, address - branch to location if reg1 < 0 (signed)
|
||||
blezs reg1, address - branch to location if reg1 <= 0 (signed)
|
||||
beq reg1, reg2, address - jump to location in program given by location, if reg1 == reg2
|
||||
bne reg1, reg2, address - jump to location in program given by location, if reg1 != reg2
|
||||
bgt reg1, reg2, address - jump to location in program given by location, if reg1 > reg2 (unsigned)
|
||||
@ -239,6 +243,10 @@ enum class Opcode {
|
||||
BSTVS,
|
||||
BZ,
|
||||
BNZ,
|
||||
BGZS,
|
||||
BGEZS,
|
||||
BLZS,
|
||||
BLEZS,
|
||||
BEQ,
|
||||
BNE,
|
||||
BGT,
|
||||
@ -370,6 +378,10 @@ val OpcodesThatBranch = setOf(
|
||||
Opcode.BSTVS,
|
||||
Opcode.BZ,
|
||||
Opcode.BNZ,
|
||||
Opcode.BGZS,
|
||||
Opcode.BGEZS,
|
||||
Opcode.BLZS,
|
||||
Opcode.BLEZS,
|
||||
Opcode.BEQ,
|
||||
Opcode.BNE,
|
||||
Opcode.BGT,
|
||||
@ -406,6 +418,10 @@ val OpcodesWithMemoryAddressAsValue = setOf(
|
||||
Opcode.BSTVS,
|
||||
Opcode.BZ,
|
||||
Opcode.BNZ,
|
||||
Opcode.BGZS,
|
||||
Opcode.BGEZS,
|
||||
Opcode.BLZS,
|
||||
Opcode.BLEZS,
|
||||
Opcode.BEQ,
|
||||
Opcode.BNE,
|
||||
Opcode.BGT,
|
||||
@ -543,6 +559,10 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.BSTVS to InstructionFormat.from("N,<v"),
|
||||
Opcode.BZ to InstructionFormat.from("BW,<r1,<v"),
|
||||
Opcode.BNZ to InstructionFormat.from("BW,<r1,<v"),
|
||||
Opcode.BGZS to InstructionFormat.from("BW,<r1,<v"),
|
||||
Opcode.BGEZS to InstructionFormat.from("BW,<r1,<v"),
|
||||
Opcode.BLZS to InstructionFormat.from("BW,<r1,<v"),
|
||||
Opcode.BLEZS to InstructionFormat.from("BW,<r1,<v"),
|
||||
Opcode.BEQ to InstructionFormat.from("BW,<r1,<r2,<v"),
|
||||
Opcode.BNE to InstructionFormat.from("BW,<r1,<r2,<v"),
|
||||
Opcode.BGT to InstructionFormat.from("BW,<r1,<r2,<v"),
|
||||
|
@ -176,6 +176,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
Opcode.BSTVC, Opcode.BSTVS -> TODO("overflow status flag not yet supported in VM (BSTVC,BSTVS)")
|
||||
Opcode.BZ -> InsBZ(ins)
|
||||
Opcode.BNZ -> InsBNZ(ins)
|
||||
Opcode.BGZS -> InsBGZS(ins)
|
||||
Opcode.BGEZS -> InsBGEZS(ins)
|
||||
Opcode.BLZS -> InsBLZS(ins)
|
||||
Opcode.BLEZS -> InsBLEZS(ins)
|
||||
Opcode.BEQ -> InsBEQ(ins)
|
||||
Opcode.BNE -> InsBNE(ins)
|
||||
Opcode.BGT -> InsBGTU(ins)
|
||||
@ -656,6 +660,78 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun InsBGZS(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> {
|
||||
if(registers.getSB(i.reg1!!)>0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.WORD -> {
|
||||
if(registers.getSW(i.reg1!!)>0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
}
|
||||
|
||||
private fun InsBGEZS(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> {
|
||||
if(registers.getSB(i.reg1!!)>=0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.WORD -> {
|
||||
if(registers.getSW(i.reg1!!)>=0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
}
|
||||
|
||||
private fun InsBLZS(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> {
|
||||
if(registers.getSB(i.reg1!!)<0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.WORD -> {
|
||||
if(registers.getSW(i.reg1!!)<0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
}
|
||||
|
||||
private fun InsBLEZS(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> {
|
||||
if(registers.getSB(i.reg1!!)<=0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.WORD -> {
|
||||
if(registers.getSW(i.reg1!!)<=0)
|
||||
branchTo(i)
|
||||
else
|
||||
nextPc()
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
}
|
||||
|
||||
private fun InsBEQ(i: IRInstruction) {
|
||||
val (left: Int, right: Int) = getBranchOperands(i)
|
||||
if(left==right)
|
||||
|
Loading…
x
Reference in New Issue
Block a user