Commit cf9b01d9 authored by Kunshan Wang's avatar Kunshan Wang

Tested binop, cmp, conversion and select.

parent 6dbde1d3
...@@ -33,7 +33,7 @@ class Bundle { ...@@ -33,7 +33,7 @@ class Bundle {
val constantNs = new SimpleNamespace[Constant]() val constantNs = new SimpleNamespace[Constant]()
val globalCellNs = new SimpleNamespace[GlobalCell]() val globalCellNs = new SimpleNamespace[GlobalCell]()
val funcNs = new SimpleNamespace[Function]() val funcNs = new SimpleNamespace[Function]()
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) { private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) { for (cand <- newNs.all) {
if (!cand.isInstanceOf[Function] || oldNs.get(cand.id) == None) { if (!cand.isInstanceOf[Function] || oldNs.get(cand.id) == None) {
......
...@@ -26,6 +26,17 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, ...@@ -26,6 +26,17 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
val clientAgents = new HashSet[ClientAgent]() val clientAgents = new HashSet[ClientAgent]()
val irReader = new UIRTextReader(new IDFactory()) val irReader = new UIRTextReader(new IDFactory())
{
// The µVM allocates stacks on the heap in the large object space. It is represented as a bug chunk of byte array.
// So the GC must know about this type because the GC looks up the globalBundle for types.
globalBundle.allNs.add(InternalTypes.VOID)
globalBundle.typeNs.add(InternalTypes.VOID)
globalBundle.allNs.add(InternalTypes.BYTE)
globalBundle.typeNs.add(InternalTypes.BYTE)
globalBundle.allNs.add(InternalTypes.BYTE_ARRAY)
globalBundle.typeNs.add(InternalTypes.BYTE_ARRAY)
}
/** /**
* Add things from a bundle to the Micro VM. * Add things from a bundle to the Micro VM.
......
...@@ -66,7 +66,10 @@ object TypeInferer { ...@@ -66,7 +66,10 @@ object TypeInferer {
case f: Function => funcOf(f.sig) case f: Function => funcOf(f.sig)
case p: Parameter => p.funcVer.sig.paramTy(p.index) case p: Parameter => p.funcVer.sig.paramTy(p.index)
case i: InstBinOp => i.opndTy case i: InstBinOp => i.opndTy
case i: InstCmp => I1 case i: InstCmp => i.opndTy match {
case TypeVector(_, l) => vecOf(I1, l)
case _ => I1
}
case i: InstConv => i.toTy case i: InstConv => i.toTy
case i: InstSelect => i.opndTy case i: InstSelect => i.opndTy
case i: InstBranch => VOID case i: InstBranch => VOID
......
...@@ -20,7 +20,7 @@ class ConstantPool(microVM: MicroVM) { ...@@ -20,7 +20,7 @@ class ConstantPool(microVM: MicroVM) {
} }
def makeBox(g: GlobalVariable): ValueBox = g match { def makeBox(g: GlobalVariable): ValueBox = g match {
case ConstInt(ty, num) => BoxInt(num & (1 << ty.asInstanceOf[TypeInt].length)) case ConstInt(ty, num) => BoxInt(OpHelper.unprepare(num, ty.asInstanceOf[TypeInt].length))
case ConstFloat(ty, num) => BoxFloat(num) case ConstFloat(ty, num) => BoxFloat(num)
case ConstDouble(ty, num) => BoxDouble(num) case ConstDouble(ty, num) => BoxDouble(num)
case ConstStruct(ty, flds) => BoxStruct(flds.map(maybeMakeBox)) case ConstStruct(ty, flds) => BoxStruct(flds.map(maybeMakeBox))
...@@ -31,6 +31,7 @@ class ConstantPool(microVM: MicroVM) { ...@@ -31,6 +31,7 @@ class ConstantPool(microVM: MicroVM) {
case _:TypeThread => BoxThread(None) case _:TypeThread => BoxThread(None)
case _:TypeStack => BoxStack(None) case _:TypeStack => BoxStack(None)
} }
case ConstVector(ty, elems) => BoxVector(elems.map(maybeMakeBox))
case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc)) case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc))
case f:Function => BoxFunc(Some(f)) case f:Function => BoxFunc(Some(f))
} }
......
...@@ -255,14 +255,14 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter ...@@ -255,14 +255,14 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
case ConvOptr.ZEXT => iToI() case ConvOptr.ZEXT => iToI()
case ConvOptr.SEXT => iToI() case ConvOptr.SEXT => iToI()
case ConvOptr.FPTRUNC => { case ConvOptr.FPTRUNC => {
val od = opnd.asInstanceOf[BoxDouble].value val od = bOpnd.asInstanceOf[BoxDouble].value
val result = od.toFloat val result = od.toFloat
boxOf(i).asInstanceOf[BoxFloat].value = result br.asInstanceOf[BoxFloat].value = result
} }
case ConvOptr.FPEXT => { case ConvOptr.FPEXT => {
val od = opnd.asInstanceOf[BoxFloat].value val od = bOpnd.asInstanceOf[BoxFloat].value
val result = od.toDouble val result = od.toDouble
boxOf(i).asInstanceOf[BoxDouble].value = result br.asInstanceOf[BoxDouble].value = result
} }
case ConvOptr.FPTOUI => fpToI(signed = false) case ConvOptr.FPTOUI => fpToI(signed = false)
case ConvOptr.FPTOSI => fpToI(signed = true) case ConvOptr.FPTOSI => fpToI(signed = true)
...@@ -290,9 +290,10 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter ...@@ -290,9 +290,10 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
incPC() incPC()
} }
case i @ InstSelect(opndTy, condTy, cond, ifTrue, ifFalse) => { case i @ InstSelect(condTy, opndTy, cond, ifTrue, ifFalse) => {
def doScalar(bCond: ValueBox, bTrue: ValueBox, bFalse: ValueBox, br: ValueBox): Unit = { def doScalar(bCond: ValueBox, bTrue: ValueBox, bFalse: ValueBox, br: ValueBox): Unit = {
val c = bCond.asInstanceOf[BoxInt].value val c = bCond.asInstanceOf[BoxInt].value
if (c == 1) { if (c == 1) {
br.copyFrom(bTrue) br.copyFrom(bTrue)
} else { } else {
...@@ -314,7 +315,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter ...@@ -314,7 +315,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
case TypeInt(1) => { case TypeInt(1) => {
doScalar(boxOf(cond), boxOf(ifTrue), boxOf(ifFalse), boxOf(i)) doScalar(boxOf(cond), boxOf(ifTrue), boxOf(ifFalse), boxOf(i))
} }
case _ => throw new UvmRefImplException(ctx + "Condition must be either int<1> or a vector of int<1>") case _ => throw new UvmRefImplException(ctx + "Condition must be either int<1> or a vector of int<1>. Found %s".format(condTy))
} }
continueNormally() continueNormally()
......
...@@ -56,7 +56,7 @@ class ThreadStackManager(microVM: MicroVM) { ...@@ -56,7 +56,7 @@ class ThreadStackManager(microVM: MicroVM) {
do { do {
someRunning = false someRunning = false
val curThreads = threadRegistry.values.toList val curThreads = threadRegistry.values.toList
for (thr2 <- curThreads) { for (thr2 <- curThreads if thr2.isRunning) {
thr2.step() thr2.step()
someRunning = thr2.isRunning || someRunning someRunning = thr2.isRunning || someRunning
} }
......
...@@ -57,7 +57,13 @@ class InterpreterFrame(val funcVer: FuncVer, val prev: Option[InterpreterFrame]) ...@@ -57,7 +57,13 @@ class InterpreterFrame(val funcVer: FuncVer, val prev: Option[InterpreterFrame])
boxes.put(lv, ValueBox.makeBoxForType(ty)) boxes.put(lv, ValueBox.makeBoxForType(ty))
} }
def curInst: Instruction = curBB.insts(curInstIndex) def curInst: Instruction = try {
curBB.insts(curInstIndex)
} catch {
case e: IndexOutOfBoundsException =>
throw new UvmRefImplException(("Current instruction beyond the last instruction of a basic block. " +
"FuncVer: %s, BasicBlock: %s").format(funcVer.repr, curBB.repr))
}
def incPC() { def incPC() {
curInstIndex += 1 curInstIndex += 1
......
...@@ -150,7 +150,7 @@ case class InstCmp(var op: CmpOptr, var opndTy: Type, var op1: SSAVariable, var ...@@ -150,7 +150,7 @@ case class InstCmp(var op: CmpOptr, var opndTy: Type, var op1: SSAVariable, var
case class InstConv(var op: ConvOptr, var fromTy: Type, var toTy: Type, var opnd: SSAVariable) extends Instruction case class InstConv(var op: ConvOptr, var fromTy: Type, var toTy: Type, var opnd: SSAVariable) extends Instruction
case class InstSelect(var opndTy: Type, var condTy: Type, case class InstSelect(var condTy: Type, var opndTy: Type,
var cond: SSAVariable, var ifTrue: SSAVariable, var ifFalse: SSAVariable) extends Instruction var cond: SSAVariable, var ifTrue: SSAVariable, var ifFalse: SSAVariable) extends Instruction
case class InstBranch(var dest: BasicBlock) extends Instruction case class InstBranch(var dest: BasicBlock) extends Instruction
......
...@@ -164,6 +164,14 @@ ...@@ -164,6 +164,14 @@
RETVOID RETVOID
} }
.funcsig @select_sig = @void ()
.funcdef @select VERSION @select_v1 <@select_sig> () {
%entry:
%select = SELECT <@i1 @i32> @TRUE @I32_0 @I32_1
RETVOID
}
.funcsig @ctrlFlow_sig = @void (@i32) .funcsig @ctrlFlow_sig = @void (@i32)
.funcdef @ctrlFlow VERSION @ctrlFlow_v1 <@ctrlFlow_sig> (%p0) { .funcdef @ctrlFlow VERSION @ctrlFlow_v1 <@ctrlFlow_sig> (%p0) {
%entry: %entry:
......
...@@ -59,14 +59,14 @@ ...@@ -59,14 +59,14 @@
.typedef @4xi32 = vector <@i32 4> .typedef @4xi32 = vector <@i32 4>
.typedef @2xdouble = vector <@double 2> .typedef @2xdouble = vector <@double 2>
.const @4xI32_V1 <@4xi32> = {@I32_0 @I32_1 @I32_2 @I32_3} .const @4xI32_V1 <@4xi32> = VEC {@I32_0 @I32_1 @I32_2 @I32_3}
.const @4xI32_V2 <@4xi32> = {@I32_4 @I32_5 @I32_6 @I32_7} .const @4xI32_V2 <@4xi32> = VEC {@I32_4 @I32_5 @I32_6 @I32_7}
.const @4xF_V1 <@4xfloat> = {@F_0 @F_1 @F_2 @F_3} .const @4xF_V1 <@4xfloat> = VEC {@F_0 @F_1 @F_2 @F_3}
.const @4xF_V2 <@4xfloat> = {@F_4 @F_5 @F_6 @F_7} .const @4xF_V2 <@4xfloat> = VEC {@F_4 @F_5 @F_6 @F_7}
.const @2xD_V1 <@2xdouble> = {@D_0 @D_1} .const @2xD_V1 <@2xdouble> = VEC {@D_0 @D_1}
.const @2xD_V2 <@2xdouble> = {@D_2 @D_3} .const @2xD_V2 <@2xdouble> = VEC {@D_2 @D_3}
.funcsig @i_ii = @i64 (@i64 @i64) .funcsig @i_ii = @i64 (@i64 @i64)
...@@ -209,8 +209,6 @@ ...@@ -209,8 +209,6 @@
%trap = TRAP <@void> KEEPALIVE ( %trap = TRAP <@void> KEEPALIVE (
%eq %ne %ult %ule %ugt %uge %slt %sle %sgt %sge %eq %ne %ult %ule %ugt %uge %slt %sle %sgt %sge
) )
%exit:
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
...@@ -238,8 +236,6 @@ ...@@ -238,8 +236,6 @@
%ftrue %ffalse %ford %foeq %fone %folt %fole %fogt %foge %ftrue %ffalse %ford %foeq %fone %folt %fole %fogt %foge
%funo %fueq %fune %fult %fule %fugt %fuge %funo %fueq %fune %fult %fule %fugt %fuge
) )
%exit:
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
...@@ -267,8 +263,22 @@ ...@@ -267,8 +263,22 @@
%ftrue %ffalse %ford %foeq %fone %folt %fole %fogt %foge %ftrue %ffalse %ford %foeq %fone %folt %fole %fogt %foge
%funo %fueq %fune %fult %fule %fugt %fuge %funo %fueq %fune %fult %fule %fugt %fuge
) )
COMMINST @uvm.thread_exit
%exit: }
.funcsig @cmp_vec_sig = @void (@4xi32 @4xi32 @4xfloat @4xfloat @2xdouble @2xdouble)
.funcdef @cmp_vec VERSION @cmp_vec_v1 <@cmp_vec_sig> (%p0 %p1 %p2 %p3 %p4 %p5) {
%entry:
%eq = EQ <@4xi32> %p0 %p1
%slt = SLT <@4xi32> %p0 %p1
%foeqf = FOEQ <@4xfloat> %p2 %p3
%fultf = FULT <@4xfloat> %p2 %p3
%foeqd = FOEQ <@2xdouble> %p4 %p5
%fultd = FULT <@2xdouble> %p4 %p5
%trap = TRAP <@void> KEEPALIVE (
%eq %slt %foeqf %fultf %foeqd %fultd
)
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
...@@ -282,24 +292,51 @@ ...@@ -282,24 +292,51 @@
%fptrunc = FPTRUNC <@double @float> %p3 %fptrunc = FPTRUNC <@double @float> %p3
%fpext = FPEXT <@float @double> %p2 %fpext = FPEXT <@float @double> %p2
%fptoui = FPTOUI <@double @i64> %p3 %fptoui1 = FPTOUI <@double @i64> %p3
%fptosi = FPTOSI <@double @i64> %p3 %fptosi1 = FPTOSI <@double @i64> %p3
%fptoui2 = FPTOUI <@float @i32> %p2
%fptosi2 = FPTOSI <@float @i32> %p2
%uitofp = UITOFP <@i64 @double> %p1 %uitofp = UITOFP <@i64 @double> %p1
%sitofp = SITOFP <@i64 @double> %p1 %sitofp = SITOFP <@i64 @double> %p1
%bitcast = BITCAST <@double @i64> %p3 %bitcast1 = BITCAST <@float @i32> %p2
%bitcast2 = BITCAST <@double @i64> %p3
%bitcast3 = BITCAST <@i32 @float > %bitcast1
%bitcast4 = BITCAST <@i64 @double> %bitcast2
%trap = TRAP <@void> KEEPALIVE ( %trap = TRAP <@void> KEEPALIVE (
%trunc %zext %sext %fptrunc %fpext %fptoui %fptosi %uitofp %sitofp %trunc %zext %sext %fptrunc %fpext
%bitcast %fptoui1 %fptosi1 %fptoui2 %fptosi2 %uitofp %sitofp
%bitcast1 %bitcast2 %bitcast3 %bitcast4
) )
%exit:
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
.typedef @4xi16 = vector <@i16 4>
.typedef @4xi64 = vector <@i64 4>
.typedef @4xdouble = vector <@double 4>
.typedef @2xfloat = vector <@float 2>
.funcsig @conv_vec_sig = @void (@4xi32 @4xfloat @2xdouble)
.funcdef @conv_vec VERSION @conv_vec_v1 <@conv_vec_sig> (%p0 %p1 %p2) {
%entry:
%trunc = TRUNC <@4xi32 @4xi16> %p0
%zext = ZEXT <@4xi32 @4xi64> %p0
%sext = SEXT <@4xi32 @4xi64> %p0
%fptrunc = FPTRUNC <@2xdouble @2xfloat> %p2
%fpext = FPEXT <@4xfloat @4xdouble> %p1
%trap = TRAP <@void> KEEPALIVE (
%trunc %zext %sext %fptrunc %fpext
)
COMMINST @uvm.thread_exit
}
.typedef @4xi1 = vector <@i1 4> .typedef @4xi1 = vector <@i1 4>
.const @4xI1_COND <@4xi1> = {@TRUE @FALSE @FALSE @TRUE} .const @4xI1_COND <@4xi1> = VEC {@TRUE @FALSE @FALSE @TRUE}
.funcdef @select VERSION @select_v1 <@noparamsnoret> () { .funcdef @select VERSION @select_v1 <@noparamsnoret> () {
%entry: %entry:
...@@ -314,8 +351,6 @@ ...@@ -314,8 +351,6 @@
%trap = TRAP <@void> KEEPALIVE ( %trap = TRAP <@void> KEEPALIVE (
%sel1 %sel2 %sel3 %sel4 %sel5 %sel1 %sel2 %sel3 %sel4 %sel5
) )
%exit:
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment