mirror of
https://github.com/irmen/prog8.git
synced 2024-10-09 13:55:19 +00:00
vm: implement float divide multiply sub add
This commit is contained in:
parent
30c2e3e8ff
commit
10c8cc35c5
@ -422,8 +422,20 @@ class CodeGen(internal val program: PtProgram,
|
||||
return code
|
||||
}
|
||||
|
||||
internal fun divideByConstFloat(fpReg: Int, factor: Float): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
if(factor==1f)
|
||||
return code
|
||||
if(factor==0f) {
|
||||
code += VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE)
|
||||
} else {
|
||||
val factorReg = vmRegisters.nextFreeFloat()
|
||||
code += VmCodeInstruction(Opcode.DIV, VmDataType.FLOAT, fpReg1 = fpReg, fpReg2 = fpReg, fpReg3 = factorReg)
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
internal fun divideByConst(dt: VmDataType, reg: Int, factor: Int): VmCodeChunk {
|
||||
// TODO support floating-point factors
|
||||
val code = VmCodeChunk()
|
||||
if(factor==1)
|
||||
return code
|
||||
@ -439,7 +451,7 @@ class CodeGen(internal val program: PtProgram,
|
||||
code += VmCodeInstruction(Opcode.LSRX, dt, reg1=reg, reg2=reg, reg3=pow2reg)
|
||||
} else {
|
||||
if (factor == 0) {
|
||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0)
|
||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff)
|
||||
}
|
||||
else {
|
||||
val factorReg = vmRegisters.nextFree()
|
||||
|
@ -273,10 +273,10 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
val vmDt = codeGen.vmType(binExpr.left.type)
|
||||
val signed = binExpr.left.type in SignedDatatypes
|
||||
return when(binExpr.operator) {
|
||||
"+" -> operatorPlus(binExpr, vmDt, resultRegister)
|
||||
"-" -> operatorMinus(binExpr, vmDt, resultRegister)
|
||||
"*" -> operatorMultiply(binExpr, vmDt, resultRegister, resultFpRegister )
|
||||
"/" -> operatorDivide(binExpr, vmDt, resultRegister)
|
||||
"+" -> operatorPlus(binExpr, vmDt, resultRegister, resultFpRegister)
|
||||
"-" -> operatorMinus(binExpr, vmDt, resultRegister, resultFpRegister)
|
||||
"*" -> operatorMultiply(binExpr, vmDt, resultRegister, resultFpRegister)
|
||||
"/" -> operatorDivide(binExpr, vmDt, resultRegister, resultFpRegister)
|
||||
"%" -> operatorModulo(binExpr, vmDt, resultRegister)
|
||||
"|", "or" -> operatorOr(binExpr, vmDt, resultRegister)
|
||||
"&", "and" -> operatorAnd(binExpr, vmDt, resultRegister)
|
||||
@ -409,11 +409,21 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
return code
|
||||
}
|
||||
|
||||
private fun operatorDivide(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
private fun operatorDivide(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
val constFactorRight = binExpr.right as? PtNumber
|
||||
if(vmDt==VmDataType.FLOAT) {
|
||||
TODO("div float")
|
||||
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||
val factor = constFactorRight.number.toFloat()
|
||||
code += codeGen.divideByConstFloat(resultFpRegister, factor)
|
||||
} else {
|
||||
val leftResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
code += translateExpression(binExpr.left, -1, leftResultFpReg)
|
||||
code += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||
code += VmCodeInstruction(Opcode.DIV, vmDt, fpReg1 = resultFpRegister, fpReg2=leftResultFpReg, fpReg3=rightResultFpReg)
|
||||
}
|
||||
} else {
|
||||
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
@ -448,7 +458,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
code += translateExpression(binExpr.left, -1, leftResultFpReg)
|
||||
code += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||
code += VmCodeInstruction(Opcode.MUL, vmDt, fpReg1 = resultFpRegister, reg2=leftResultFpReg, reg3=rightResultFpReg)
|
||||
code += VmCodeInstruction(Opcode.MUL, vmDt, fpReg1 = resultFpRegister, fpReg2 = leftResultFpReg, fpReg3 = rightResultFpReg)
|
||||
}
|
||||
} else {
|
||||
if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) {
|
||||
@ -470,10 +480,20 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
return code
|
||||
}
|
||||
|
||||
private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
if(vmDt==VmDataType.FLOAT) {
|
||||
TODO("minus float")
|
||||
if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||
code += VmCodeInstruction(Opcode.DEC, vmDt, fpReg1 = resultFpRegister)
|
||||
}
|
||||
else {
|
||||
val leftResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
code += translateExpression(binExpr.left, -1, leftResultFpReg)
|
||||
code += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||
code += VmCodeInstruction(Opcode.SUB, vmDt, fpReg1=resultFpRegister, fpReg2=leftResultFpReg, fpReg3=rightResultFpReg)
|
||||
}
|
||||
} else {
|
||||
if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
@ -490,10 +510,24 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
return code
|
||||
}
|
||||
|
||||
private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
if(vmDt==VmDataType.FLOAT) {
|
||||
TODO("plus float")
|
||||
if((binExpr.left as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.right, -1, resultFpRegister)
|
||||
code += VmCodeInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister)
|
||||
}
|
||||
else if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||
code += VmCodeInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister)
|
||||
}
|
||||
else {
|
||||
val leftResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
code += translateExpression(binExpr.left, -1, leftResultFpReg)
|
||||
code += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||
code += VmCodeInstruction(Opcode.ADD, vmDt, fpReg1=resultFpRegister, fpReg2=leftResultFpReg, fpReg3=rightResultFpReg)
|
||||
}
|
||||
} else {
|
||||
if((binExpr.left as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.right, resultRegister, -1)
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- vm: implement float div, minus, plus
|
||||
- vm: implement float type casts to integer types
|
||||
- vm: implement float any, all, reverse, sort
|
||||
- vm: fix test fp calc result being 0
|
||||
@ -31,6 +30,7 @@ Future Things and Ideas
|
||||
Compiler:
|
||||
|
||||
- vm: codeGen: various TODOs to tweak code
|
||||
- vm: codeGen: optimize codegen for comparison expressions in if statements, such as if x==0 ... else ...
|
||||
- vm: make registers typed? so that it's immediately obvious what type they represent. Much like regular variables in memory.
|
||||
so we have a set of byte registers, a set of word registers, and other sets if we introduce other types.
|
||||
- vm: don't store symbol names in instructions to make optimizing the IR easier? but what about jumps to labels. And it's no longer readable by humans.
|
||||
|
@ -8,49 +8,19 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
ubyte ub = conv.str2ubyte("234")
|
||||
txt.print_ub(ub)
|
||||
txt.nl()
|
||||
byte sb = conv.str2byte("-123")
|
||||
txt.print_b(sb)
|
||||
txt.nl()
|
||||
uword uw = conv.str2uword("54321")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
word sw = conv.str2word("-12345")
|
||||
txt.print_w(sw)
|
||||
txt.nl()
|
||||
float fl1 = 500.0
|
||||
float fzero = 0.0
|
||||
floats.print_f(fl1 / fzero)
|
||||
txt.nl()
|
||||
|
||||
; TODO fix hex2uword and bin2uword
|
||||
uw = conv.hex2uword("0")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.hex2uword("1")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.hex2uword("a")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("0")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("1")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
ubyte ub1 = 50
|
||||
ubyte ubzero = 0
|
||||
txt.print_ub(ub1/ubzero)
|
||||
txt.nl()
|
||||
|
||||
uw = conv.hex2uword("$ea31")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.hex2uword("ea31")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("%100000111011101")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("100000111011101")
|
||||
txt.print_uw(uw)
|
||||
uword uw1 = 5000
|
||||
uword uwzero = 0
|
||||
txt.print_uw(uw1/uwzero)
|
||||
txt.nl()
|
||||
|
||||
; float fl = 500.0
|
||||
|
Loading…
Reference in New Issue
Block a user