mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
add new containment check codegen for IR
This commit is contained in:
parent
6be6eb2227
commit
5986dcdd2f
@ -1835,16 +1835,15 @@ internal class AssignmentAsmGen(
|
||||
if(containment.haystackValues!=null) {
|
||||
val haystack = containment.haystackValues!!.children.map {
|
||||
if(it is PtBool) it.asInt()
|
||||
else (it as PtNumber).number
|
||||
else (it as PtNumber).number.toInt()
|
||||
}
|
||||
when(elementDt) {
|
||||
in ByteDatatypesWithBoolean -> {
|
||||
require(haystack.size in 0..PtContainmentCheck.MAX_SIZE_FOR_INLINE_CHECKS_BYTE)
|
||||
assignExpressionToRegister(containment.needle, RegisterOrPair.A, elementDt == DataType.BYTE)
|
||||
for(number in haystack) {
|
||||
val numstr = if(elementDt==DataType.FLOAT) number.toString() else number.toInt().toString()
|
||||
asmgen.out("""
|
||||
cmp #$numstr
|
||||
cmp #$number
|
||||
beq +""")
|
||||
}
|
||||
asmgen.out("""
|
||||
@ -1859,11 +1858,10 @@ internal class AssignmentAsmGen(
|
||||
val gottemLabel = asmgen.makeLabel("gottem")
|
||||
val endLabel = asmgen.makeLabel("end")
|
||||
for(number in haystack) {
|
||||
val numstr = if(elementDt==DataType.FLOAT) number.toString() else number.toInt().toString()
|
||||
asmgen.out("""
|
||||
cmp #<$numstr
|
||||
cmp #<$number
|
||||
bne +
|
||||
cpy #>$numstr
|
||||
cpy #>$number
|
||||
beq $gottemLabel
|
||||
+ """)
|
||||
}
|
||||
|
@ -174,24 +174,28 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
if(check.haystackValues!=null) {
|
||||
val haystack = check.haystackValues!!.children.map {
|
||||
if(it is PtBool) it.asInt()
|
||||
else (it as PtNumber).number
|
||||
else (it as PtNumber).number.toInt()
|
||||
}
|
||||
when(elementDt) {
|
||||
in ByteDatatypesWithBoolean -> {
|
||||
in IntegerDatatypesWithBoolean -> {
|
||||
if (elementDt in ByteDatatypesWithBoolean) require(haystack.size in 0..PtContainmentCheck.MAX_SIZE_FOR_INLINE_CHECKS_BYTE)
|
||||
if (elementDt in WordDatatypes) require(haystack.size in 0..PtContainmentCheck.MAX_SIZE_FOR_INLINE_CHECKS_WORD)
|
||||
val gottemLabel = codeGen.createLabelName()
|
||||
val endLabel = codeGen.createLabelName()
|
||||
val elementTr = translateExpression(check.needle)
|
||||
addToResult(result, elementTr, elementTr.resultReg, -1)
|
||||
TODO("byte containment check ${check.needle} in ${haystack}")
|
||||
// TODO should return a proper result here
|
||||
val resultReg = -1
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
val elementTr = translateExpression(check.needle)
|
||||
addToResult(result, elementTr, elementTr.resultReg, -1)
|
||||
TODO("word containment check ${check.needle} in ${haystack}")
|
||||
// TODO should return a proper result here
|
||||
val resultReg = -1
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
for(value in haystack){
|
||||
it += IRInstruction(Opcode.CMPI, irType(elementDt), elementTr.resultReg, immediate = value)
|
||||
it += IRInstruction(Opcode.BSTEQ, labelSymbol = gottemLabel)
|
||||
}
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, elementTr.resultReg, immediate = 0)
|
||||
it += IRInstruction(Opcode.JUMP, labelSymbol = endLabel)
|
||||
}
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, elementTr.resultReg, immediate = 1), gottemLabel)
|
||||
result += IRCodeChunk(endLabel, null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
|
||||
}
|
||||
DataType.FLOAT -> throw AssemblyError("containmentchecks for floats should always be done on an array variable with subroutine")
|
||||
else -> throw AssemblyError("weird dt $elementDt")
|
||||
|
@ -1,7 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
IR: add codegen for containmentcheck literal + test that it actually works (positive and negative)
|
||||
IR: Improve codegen for for loops downto 0. (BPL if <=127 etc like 6502 codegen?)
|
||||
|
||||
callgraph issue? : if a sub contains another sub and it calls that, the outer sub is never removed even if it doesn't get called?
|
||||
@ -49,6 +48,7 @@ Compiler:
|
||||
- Can we support signed % (remainder) somehow?
|
||||
- Don't add "random" rts to %asm blocks but instead give a warning about it? (but this breaks existing behavior that others already depend on... command line switch?)
|
||||
- IR: implement missing operators in AssignmentGen (array shifts etc)
|
||||
- IR: CMPI+BSTEQ --> new BEQ reg,value,label instruction (like BGT etc)
|
||||
- expand the kata encoding to somehow translate normal katana to half-widths? (see comment in KatakanaEncoding)
|
||||
- instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead.
|
||||
that will allow them to be reused from custom user written assembly code as well.
|
||||
|
Loading…
x
Reference in New Issue
Block a user