mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +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)
|
||||
|
||||
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 {
|
||||
val code = VmCodeChunk()
|
||||
// TODO if shift is 1, use ASR/LSR instruction instead of multishift
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
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)
|
||||
if(codeGen.isOne(binExpr.right)) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
val opc = if (signed) Opcode.ASR else Opcode.LSR
|
||||
code += VmCodeInstruction(opc, vmDt, reg1 = resultRegister)
|
||||
} else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
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
|
||||
}
|
||||
|
||||
private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
// TODO if shift is 1, use LSL instruction instead of multishift
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
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)
|
||||
if(codeGen.isOne(binExpr.right)){
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
code += VmCodeInstruction(Opcode.LSL, vmDt, reg1=resultRegister)
|
||||
} else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ TODO
|
||||
|
||||
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: 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.
|
||||
|
100
examples/test.p8
100
examples/test.p8
@ -7,63 +7,61 @@
|
||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||
|
||||
main {
|
||||
; ubyte value = 42
|
||||
;
|
||||
; sub inline_candidate() -> ubyte {
|
||||
; return math.sin8u(value)
|
||||
; }
|
||||
;
|
||||
; sub add(ubyte first, ubyte second) -> ubyte {
|
||||
; return first + second
|
||||
; }
|
||||
;
|
||||
; sub mul(ubyte first, ubyte second) -> ubyte {
|
||||
; return first * second
|
||||
; }
|
||||
ubyte value = 42
|
||||
|
||||
sub inline_candidate() -> ubyte {
|
||||
return math.sin8u(value)
|
||||
}
|
||||
|
||||
sub add(ubyte first, ubyte second) -> ubyte {
|
||||
return first + second
|
||||
}
|
||||
|
||||
sub mul(ubyte first, ubyte second) -> ubyte {
|
||||
return first * second
|
||||
}
|
||||
|
||||
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]
|
||||
floats.print_f(array[1])
|
||||
ubyte @shared value = inline_candidate()
|
||||
value = %01011100
|
||||
byte @shared svalue = 99
|
||||
svalue = -svalue
|
||||
@($5000) = not @($5000)
|
||||
sys.set_carry()
|
||||
rol(value)
|
||||
rol(@($5000))
|
||||
txt.print_ub(value)
|
||||
txt.nl()
|
||||
array[1] = 99.99
|
||||
floats.print_f(array[1])
|
||||
sys.set_carry()
|
||||
ror(value)
|
||||
ror(@($5000))
|
||||
txt.print_ub(value)
|
||||
txt.nl()
|
||||
array[1] = 0
|
||||
floats.print_f(array[1])
|
||||
txt.nl()
|
||||
|
||||
; ubyte value = inline_candidate()
|
||||
; byte svalue = 99
|
||||
; svalue = -svalue
|
||||
; @($5000) = not @($5000)
|
||||
; rol(value)
|
||||
; rol(@($5000))
|
||||
; ror(value)
|
||||
; ror(@($5000))
|
||||
; rol2(value)
|
||||
; rol2(@($5000))
|
||||
; ror2(value)
|
||||
; ror2(@($5000))
|
||||
; @($5000) <<= 1
|
||||
; @($5000) >>= 1
|
||||
; value <<= 1
|
||||
; value >>= 1
|
||||
; @($5000) <<= 3
|
||||
; @($5000) >>= 3
|
||||
; value <<= 3
|
||||
; value >>= 3
|
||||
; txt.print_ub(value)
|
||||
; txt.nl()
|
||||
value = %01011100
|
||||
sys.set_carry()
|
||||
rol2(value)
|
||||
rol2(@($5000))
|
||||
txt.print_ub(value)
|
||||
txt.nl()
|
||||
sys.clear_carry()
|
||||
ror2(value)
|
||||
ror2(@($5000))
|
||||
txt.print_ub(value)
|
||||
txt.nl()
|
||||
@($5000) <<= 1
|
||||
@($5000) >>= 1
|
||||
value <<= 1
|
||||
value >>= 1
|
||||
txt.print_ub(value)
|
||||
txt.nl()
|
||||
@($5000) <<= 3
|
||||
@($5000) >>= 3
|
||||
value <<= 3
|
||||
value >>= 3
|
||||
txt.print_ub(value)
|
||||
txt.nl()
|
||||
; txt.print_ub(inline_candidate())
|
||||
; 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
|
||||
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
|
||||
rol reg1 - rotate reg1 left by 1bits, not using carry + set Carry to shifted bit
|
||||
roxl reg1 - rotate reg1 left by 1bits, 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 1 bits, using carry, + set Carry to shifted bit
|
||||
|
||||
|
||||
FLOATING POINT CONVERSIONS AND FUNCTIONS
|
||||
@ -227,9 +227,9 @@ enum class Opcode {
|
||||
ASRN,
|
||||
LSRN,
|
||||
LSLN,
|
||||
ASR, // TODO not used in codegen of shift 1
|
||||
LSR, // TODO not used in codegen of shift 1
|
||||
LSL, // TODO not used in codegen of shift 1
|
||||
ASR,
|
||||
LSR,
|
||||
LSL,
|
||||
ROR,
|
||||
ROXR,
|
||||
ROL,
|
||||
|
Loading…
Reference in New Issue
Block a user