mirror of
https://github.com/irmen/prog8.git
synced 2026-04-20 11:17:01 +00:00
IR: make LSIG,MSIG,CONCAT instruction set flags to skip cmp #0 afterwards (if msb(x)>0)
This commit is contained in:
@@ -49,7 +49,6 @@ Future Things and Ideas
|
||||
|
||||
IR/VM
|
||||
-----
|
||||
- make MSIG instruction set flags and skip cmp #0 afterwards (if msb(x)>0)
|
||||
- is it possible to use LOADFIELD/STOREFIELD instructions even more?
|
||||
- make multiple classes of registers and maybe also categorize by life time , to prepare for better register allocation in the future
|
||||
SYSCALL_ARGS, // Reserved for syscall arguments (r99000-99099, r99100-99199)
|
||||
@@ -75,8 +74,8 @@ IR/VM
|
||||
- change the instruction format so an indirect register (a pointer) can be used more often, at least for the inplace assignment operators that operate on pointer
|
||||
- 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!)
|
||||
- fix call() return value handling (... what's wrong with it again?)
|
||||
- encode asmsub/extsub clobber info in the call , or maybe include these definitions in the p8ir file itself too. (return registers are already encoded in the CALL instruction)
|
||||
- proper code gen for the CALLI instruction and that it (optionally) returns a word value that needs to be assigned to a reg
|
||||
- encode asmsub/extsub clobber info in the call , or maybe include these definitions in the p8ir file itself too. (return registers are already encoded in the CALL instruction)
|
||||
- implement fast code paths for TODO("inplace split....
|
||||
- implement more TODOs in AssignmentGen
|
||||
- do something with the 'split' tag on split word arrays
|
||||
@@ -86,10 +85,10 @@ IR/VM
|
||||
don't forget to take into account the data type of the register when it's going to be reused!
|
||||
- idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
|
||||
global initialization values are simply a list of LOAD instructions.
|
||||
Variables replaced include all subroutine parameters! So the only variables that remain as variables are arrays and strings.
|
||||
Variables replaced include all subroutine parameters? Or not? So the only variables that remain as variables are arrays and strings.
|
||||
- the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line.
|
||||
maybe another representation is needed once actual codegeneration is done from the IR...?
|
||||
- ExpressionCodeResult: get rid of the separation between single result register and multiple result registers? maybe not, this requires hundreds of lines to change
|
||||
maybe another representation is needed once actual codegeneration is done from the IR...? Should array operations be encoded in a more high level form in the IR?
|
||||
- ExpressionCodeResult: get rid of the separation between single result register and multiple result registers? maybe not, this requires hundreds of lines to change.. :(
|
||||
- sometimes source lines end up missing in the output p8ir, for example the first assignment is gone in:
|
||||
sub start() {
|
||||
cx16.r0L = cx16.r1 as ubyte
|
||||
@@ -170,4 +169,4 @@ Optimizations
|
||||
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served?
|
||||
for instance, vars used inside loops first, then loopvars, then uwords used as pointers (or these first??), then the rest
|
||||
This will probably need the register categorization from the IR explained there, for the old 6502 codegen there is not enough information to act on
|
||||
- various optimizers skip stuff if compTarget.name==VMTarget.NAME. Once 6502-codegen is done from IR code, those checks should probably be removed, or be made permanent
|
||||
- various optimizers skip stuff if compTarget.name==VMTarget.NAME. Once 6502-codegen is done from IR code, those checks should probably all be removed, or be made permanent
|
||||
|
||||
+8
-21
@@ -1,28 +1,15 @@
|
||||
%import conv
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword value
|
||||
ubyte size
|
||||
uword @shared value
|
||||
|
||||
value, size = conv.any2uword("123")
|
||||
txt.print_uw(value)
|
||||
txt.spc()
|
||||
txt.print_ub(size)
|
||||
txt.nl()
|
||||
if msb(value)>0
|
||||
cx16.r0++
|
||||
|
||||
value, size = conv.any2uword("$ea31")
|
||||
txt.print_uw(value)
|
||||
txt.spc()
|
||||
txt.print_ub(size)
|
||||
txt.nl()
|
||||
if lsb(value)>0
|
||||
cx16.r0++
|
||||
|
||||
value, size = conv.any2uword("%11111110")
|
||||
txt.print_uw(value)
|
||||
txt.spc()
|
||||
txt.print_ub(size)
|
||||
txt.nl()
|
||||
value = mkword(cx16.r0L, cx16.r1L)
|
||||
if_z
|
||||
cx16.r0++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,12 @@ Program to execute is not stored in the system memory, it's just a separate list
|
||||
100K virtual floating point registers (64 bits double precision) fr0-fr99999
|
||||
65536 bytes of memory. Thus memory pointers (addresses) are limited to 16 bits.
|
||||
Value stack, max 128 entries of 1 byte each.
|
||||
Status flags: Carry, Zero, Negative. NOTE: status flags are only affected by the CMP instruction or explicit CLC/SEC,
|
||||
LOAD instructions DO affect the Z and N flags.
|
||||
INC/DEC/NEG instructions DO affect the Z and N flags,
|
||||
other instructions only affect Z an N flags if the value in a result register is written.
|
||||
See OpcodesThatSetStatusbits
|
||||
Status flags: Carry, Zero, Negative, Overflow.
|
||||
NOTE: status flags are only affected by the CMP instruction or explicit CLC/SEC,
|
||||
LOAD instructions also DO affect the Z and N flags.
|
||||
INC/DEC/NEG instructions also DO affect the Z and N flags,
|
||||
other instructions also only affect Z an N flags if the value in a result register is written.
|
||||
See OpcodesThatSetStatusbits.
|
||||
|
||||
Instruction set is mostly a load/store architecture, there are few instructions operating on memory directly.
|
||||
|
||||
@@ -500,7 +501,10 @@ val OpcodesThatSetStatusbitsButNotCarry = arrayOf(
|
||||
Opcode.OR,
|
||||
Opcode.XORM,
|
||||
Opcode.XORR,
|
||||
Opcode.XOR
|
||||
Opcode.XOR,
|
||||
Opcode.LSIG,
|
||||
Opcode.MSIG,
|
||||
Opcode.CONCAT
|
||||
)
|
||||
|
||||
val OpcodesThatDependOnCarry = arrayOf(
|
||||
|
||||
@@ -2358,6 +2358,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
IRDataType.BYTE -> {
|
||||
val value = registers.getUW(i.reg2!!)
|
||||
registers.setUB(i.reg1!!, value.toUByte())
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.WORD -> throw IllegalArgumentException("lsig.w not yet supported, requires 32-bits registers")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
@@ -2370,6 +2371,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
IRDataType.BYTE -> {
|
||||
val value = registers.getUW(i.reg2!!)
|
||||
val newValue = value.toInt() ushr 8
|
||||
statusbitsNZ(newValue, i.type!!)
|
||||
registers.setUB(i.reg1!!, newValue.toUByte())
|
||||
}
|
||||
IRDataType.WORD -> throw IllegalArgumentException("msig.w not yet supported, requires 32-bits registers")
|
||||
@@ -2383,7 +2385,9 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
IRDataType.BYTE -> {
|
||||
val msb = registers.getUB(i.reg2!!)
|
||||
val lsb = registers.getUB(i.reg3!!)
|
||||
registers.setUW(i.reg1!!, ((msb.toInt() shl 8) or lsb.toInt()).toUShort())
|
||||
val value = ((msb.toInt() shl 8) or lsb.toInt())
|
||||
registers.setUW(i.reg1!!, value.toUShort())
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.WORD -> throw IllegalArgumentException("concat.w not yet supported, requires 32-bits registers")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
|
||||
Reference in New Issue
Block a user