mirror of
https://github.com/irmen/prog8.git
synced 2025-02-06 01:30:23 +00:00
vm: use shift-one instructions in codegen
This commit is contained in:
parent
14e36f1362
commit
bacba629a5
@ -762,4 +762,6 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
builtinFuncGen.translate(call, resultRegister)
|
builtinFuncGen.translate(call, resultRegister)
|
||||||
|
|
||||||
internal fun isZero(expression: PtExpression): Boolean = expression is PtNumber && expression.number==0.0
|
internal fun isZero(expression: PtExpression): Boolean = expression is PtNumber && expression.number==0.0
|
||||||
|
|
||||||
|
internal fun isOne(expression: PtExpression): Boolean = expression is PtNumber && expression.number==1.0
|
||||||
}
|
}
|
||||||
|
@ -363,24 +363,33 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
|
|
||||||
private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, signed: Boolean): VmCodeChunk {
|
private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, signed: Boolean): VmCodeChunk {
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
// TODO if shift is 1, use ASR/LSR instruction instead of multishift
|
if(codeGen.isOne(binExpr.right)) {
|
||||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
val opc = if (signed) Opcode.ASR else Opcode.LSR
|
||||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
code += VmCodeInstruction(opc, vmDt, reg1 = resultRegister)
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
} else {
|
||||||
val opc = if(signed) Opcode.ASRN else Opcode.LSRN
|
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(opc, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
|
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||||
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
|
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
|
||||||
|
code += VmCodeInstruction(opc, vmDt, reg1 = resultRegister, reg2 = leftResultReg, reg3 = rightResultReg)
|
||||||
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
// TODO if shift is 1, use LSL instruction instead of multishift
|
if(codeGen.isOne(binExpr.right)){
|
||||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
code += VmCodeInstruction(Opcode.LSL, vmDt, reg1=resultRegister)
|
||||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
} else {
|
||||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||||
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||||
|
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||||
|
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
|
code += VmCodeInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||||
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- vm: use more instructions in codegen: shift one
|
- vm: expressiongen: use resultRegister arg instead of allocating new leftResultReg
|
||||||
- vm: use more instructions in codegen: branching
|
- vm: use more instructions in codegen: branching
|
||||||
- vm: add more instructions operating directly on memory instead of only registers?
|
- vm: add more instructions operating directly on memory instead of only registers?
|
||||||
- in-place modifiying functions (rol, ror, ..) don't accept a memory address but require a memory-read expression. that is weird.
|
- in-place modifiying functions (rol, ror, ..) don't accept a memory address but require a memory-read expression. that is weird.
|
||||||
|
100
examples/test.p8
100
examples/test.p8
@ -7,63 +7,61 @@
|
|||||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||||
|
|
||||||
main {
|
main {
|
||||||
; ubyte value = 42
|
ubyte value = 42
|
||||||
;
|
|
||||||
; sub inline_candidate() -> ubyte {
|
sub inline_candidate() -> ubyte {
|
||||||
; return math.sin8u(value)
|
return math.sin8u(value)
|
||||||
; }
|
}
|
||||||
;
|
|
||||||
; sub add(ubyte first, ubyte second) -> ubyte {
|
sub add(ubyte first, ubyte second) -> ubyte {
|
||||||
; return first + second
|
return first + second
|
||||||
; }
|
}
|
||||||
;
|
|
||||||
; sub mul(ubyte first, ubyte second) -> ubyte {
|
sub mul(ubyte first, ubyte second) -> ubyte {
|
||||||
; return first * second
|
return first * second
|
||||||
; }
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
uword[] arrayuw = [1111,2222,3333,4444]
|
|
||||||
txt.print_uw(arrayuw[1])
|
|
||||||
txt.nl()
|
|
||||||
arrayuw[1] = 9999
|
|
||||||
txt.print_uw(arrayuw[1])
|
|
||||||
txt.nl()
|
|
||||||
arrayuw[1] = 0
|
|
||||||
txt.print_uw(arrayuw[1])
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
float[] array = [1.1, 2.2, 3.3, 4.4]
|
ubyte @shared value = inline_candidate()
|
||||||
floats.print_f(array[1])
|
value = %01011100
|
||||||
|
byte @shared svalue = 99
|
||||||
|
svalue = -svalue
|
||||||
|
@($5000) = not @($5000)
|
||||||
|
sys.set_carry()
|
||||||
|
rol(value)
|
||||||
|
rol(@($5000))
|
||||||
|
txt.print_ub(value)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
array[1] = 99.99
|
sys.set_carry()
|
||||||
floats.print_f(array[1])
|
ror(value)
|
||||||
|
ror(@($5000))
|
||||||
|
txt.print_ub(value)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
array[1] = 0
|
|
||||||
floats.print_f(array[1])
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
value = %01011100
|
||||||
; ubyte value = inline_candidate()
|
sys.set_carry()
|
||||||
; byte svalue = 99
|
rol2(value)
|
||||||
; svalue = -svalue
|
rol2(@($5000))
|
||||||
; @($5000) = not @($5000)
|
txt.print_ub(value)
|
||||||
; rol(value)
|
txt.nl()
|
||||||
; rol(@($5000))
|
sys.clear_carry()
|
||||||
; ror(value)
|
ror2(value)
|
||||||
; ror(@($5000))
|
ror2(@($5000))
|
||||||
; rol2(value)
|
txt.print_ub(value)
|
||||||
; rol2(@($5000))
|
txt.nl()
|
||||||
; ror2(value)
|
@($5000) <<= 1
|
||||||
; ror2(@($5000))
|
@($5000) >>= 1
|
||||||
; @($5000) <<= 1
|
value <<= 1
|
||||||
; @($5000) >>= 1
|
value >>= 1
|
||||||
; value <<= 1
|
txt.print_ub(value)
|
||||||
; value >>= 1
|
txt.nl()
|
||||||
; @($5000) <<= 3
|
@($5000) <<= 3
|
||||||
; @($5000) >>= 3
|
@($5000) >>= 3
|
||||||
; value <<= 3
|
value <<= 3
|
||||||
; value >>= 3
|
value >>= 3
|
||||||
; txt.print_ub(value)
|
txt.print_ub(value)
|
||||||
; txt.nl()
|
txt.nl()
|
||||||
; txt.print_ub(inline_candidate())
|
; txt.print_ub(inline_candidate())
|
||||||
; txt.nl()
|
; txt.nl()
|
||||||
|
|
||||||
|
@ -124,8 +124,8 @@ asr reg1 - shift reg1 right by 1 bits (signe
|
|||||||
lsl reg1 - shift reg1 left by 1 bits + set Carry to shifted bit
|
lsl reg1 - shift reg1 left by 1 bits + set Carry to shifted bit
|
||||||
ror reg1 - rotate reg1 right by 1 bits, not using carry + set Carry to shifted bit
|
ror reg1 - rotate reg1 right by 1 bits, not using carry + set Carry to shifted bit
|
||||||
roxr reg1 - rotate reg1 right by 1 bits, using carry + set Carry to shifted bit
|
roxr reg1 - rotate reg1 right by 1 bits, using carry + set Carry to shifted bit
|
||||||
rol reg1 - rotate reg1 left by 1bits, not using carry + set Carry to shifted bit
|
rol reg1 - rotate reg1 left by 1 bits, not using carry + set Carry to shifted bit
|
||||||
roxl reg1 - rotate reg1 left by 1bits, using carry, + set Carry to shifted bit
|
roxl reg1 - rotate reg1 left by 1 bits, using carry, + set Carry to shifted bit
|
||||||
|
|
||||||
|
|
||||||
FLOATING POINT CONVERSIONS AND FUNCTIONS
|
FLOATING POINT CONVERSIONS AND FUNCTIONS
|
||||||
@ -227,9 +227,9 @@ enum class Opcode {
|
|||||||
ASRN,
|
ASRN,
|
||||||
LSRN,
|
LSRN,
|
||||||
LSLN,
|
LSLN,
|
||||||
ASR, // TODO not used in codegen of shift 1
|
ASR,
|
||||||
LSR, // TODO not used in codegen of shift 1
|
LSR,
|
||||||
LSL, // TODO not used in codegen of shift 1
|
LSL,
|
||||||
ROR,
|
ROR,
|
||||||
ROXR,
|
ROXR,
|
||||||
ROL,
|
ROL,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user