vm: use shift-one instructions in codegen

This commit is contained in:
Irmen de Jong 2022-05-11 15:50:51 +02:00
parent 14e36f1362
commit bacba629a5
5 changed files with 79 additions and 70 deletions

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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.

View File

@ -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()

View File

@ -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,