Commit cf9b01d9 authored by Kunshan Wang's avatar Kunshan Wang

Tested binop, cmp, conversion and select.

parent 6dbde1d3
......@@ -33,7 +33,7 @@ class Bundle {
val constantNs = new SimpleNamespace[Constant]()
val globalCellNs = new SimpleNamespace[GlobalCell]()
val funcNs = new SimpleNamespace[Function]()
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) {
if (!cand.isInstanceOf[Function] || oldNs.get(cand.id) == None) {
......
......@@ -26,6 +26,17 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
val clientAgents = new HashSet[ClientAgent]()
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.
......
......@@ -66,7 +66,10 @@ object TypeInferer {
case f: Function => funcOf(f.sig)
case p: Parameter => p.funcVer.sig.paramTy(p.index)
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: InstSelect => i.opndTy
case i: InstBranch => VOID
......
......@@ -20,7 +20,7 @@ class ConstantPool(microVM: MicroVM) {
}
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 ConstDouble(ty, num) => BoxDouble(num)
case ConstStruct(ty, flds) => BoxStruct(flds.map(maybeMakeBox))
......@@ -31,6 +31,7 @@ class ConstantPool(microVM: MicroVM) {
case _:TypeThread => BoxThread(None)
case _:TypeStack => BoxStack(None)
}
case ConstVector(ty, elems) => BoxVector(elems.map(maybeMakeBox))
case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc))
case f:Function => BoxFunc(Some(f))
}
......
......@@ -255,14 +255,14 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
case ConvOptr.ZEXT => iToI()
case ConvOptr.SEXT => iToI()
case ConvOptr.FPTRUNC => {
val od = opnd.asInstanceOf[BoxDouble].value
val od = bOpnd.asInstanceOf[BoxDouble].value
val result = od.toFloat
boxOf(i).asInstanceOf[BoxFloat].value = result
br.asInstanceOf[BoxFloat].value = result
}
case ConvOptr.FPEXT => {
val od = opnd.asInstanceOf[BoxFloat].value
val od = bOpnd.asInstanceOf[BoxFloat].value
val result = od.toDouble
boxOf(i).asInstanceOf[BoxDouble].value = result
br.asInstanceOf[BoxDouble].value = result
}
case ConvOptr.FPTOUI => fpToI(signed = false)
case ConvOptr.FPTOSI => fpToI(signed = true)
......@@ -290,9 +290,10 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
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 = {
val c = bCond.asInstanceOf[BoxInt].value
if (c == 1) {
br.copyFrom(bTrue)
} else {
......@@ -314,7 +315,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
case TypeInt(1) => {
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()
......
......@@ -56,7 +56,7 @@ class ThreadStackManager(microVM: MicroVM) {
do {
someRunning = false
val curThreads = threadRegistry.values.toList
for (thr2 <- curThreads) {
for (thr2 <- curThreads if thr2.isRunning) {
thr2.step()
someRunning = thr2.isRunning || someRunning
}
......
......@@ -57,7 +57,13 @@ class InterpreterFrame(val funcVer: FuncVer, val prev: Option[InterpreterFrame])
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() {
curInstIndex += 1
......
......@@ -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 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
case class InstBranch(var dest: BasicBlock) extends Instruction
......
......@@ -74,6 +74,19 @@ class UvmInterpreterSpec extends FlatSpec with Matchers {
def asTR64Raw: Long = vb.asInstanceOf[BoxTagRef64].raw
def asVec: Seq[ValueBox] = vb.asInstanceOf[BoxVector].values
}
"The constant pool" should "contain appropriate constant values" in {
def gvb(name: String) = microVM.constantPool.getGlobalVarBox(microVM.globalBundle.globalVarNs(name))
gvb("@TRUE").asUInt(1) shouldBe 1
gvb("@FALSE").asUInt(1) shouldBe 0
gvb("@I32_1").asUInt(32) shouldBe 1
gvb("@I32_2").asUInt(32) shouldBe 2
gvb("@I32_7").asUInt(32) shouldBe 7
gvb("@I64_5").asUInt(64) shouldBe 5
}
"Binary operations" should "work on int<32>" in {
val ca = microVM.newClientAgent()
......@@ -333,4 +346,364 @@ class UvmInterpreterSpec extends FlatSpec with Matchers {
ca.close()
}
"Comparing operations" should "work on int<64>" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@cmp64")
val a0 = ca.putInt("@i64", 1)
val a1 = ca.putInt("@i64", 2)
testFunc(ca, func, Seq(a0, a1)) { (ca, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ca.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 0
ne.vb.asUInt(1) shouldEqual 1
ult.vb.asUInt(1) shouldEqual 1
ule.vb.asUInt(1) shouldEqual 1
ugt.vb.asUInt(1) shouldEqual 0
uge.vb.asUInt(1) shouldEqual 0
slt.vb.asUInt(1) shouldEqual 1
sle.vb.asUInt(1) shouldEqual 1
sgt.vb.asUInt(1) shouldEqual 0
sge.vb.asUInt(1) shouldEqual 0
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a0, a0)) { (ca, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ca.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 1
ne.vb.asUInt(1) shouldEqual 0
ult.vb.asUInt(1) shouldEqual 0
ule.vb.asUInt(1) shouldEqual 1
ugt.vb.asUInt(1) shouldEqual 0
uge.vb.asUInt(1) shouldEqual 1
slt.vb.asUInt(1) shouldEqual 0
sle.vb.asUInt(1) shouldEqual 1
sgt.vb.asUInt(1) shouldEqual 0
sge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
val a2 = ca.putInt("@i64", -3)
testFunc(ca, func, Seq(a0, a2)) { (ca, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ca.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 0
ne.vb.asUInt(1) shouldEqual 1
slt.vb.asUInt(1) shouldEqual 0
sle.vb.asUInt(1) shouldEqual 0
sgt.vb.asUInt(1) shouldEqual 1
sge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
ca.close()
}
"Comparing operations" should "work on float" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@cmp_f")
val a0 = ca.putFloat("@float", 1.0f)
val a1 = ca.putFloat("@float", 2.0f)
testFunc(ca, func, Seq(a0, a1)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
ford.vb.asUInt(1) shouldEqual 1
foeq.vb.asUInt(1) shouldEqual 0
fone.vb.asUInt(1) shouldEqual 1
folt.vb.asUInt(1) shouldEqual 1
fole.vb.asUInt(1) shouldEqual 1
fogt.vb.asUInt(1) shouldEqual 0
foge.vb.asUInt(1) shouldEqual 0
funo.vb.asUInt(1) shouldEqual 0
fueq.vb.asUInt(1) shouldEqual 0
fune.vb.asUInt(1) shouldEqual 1
fult.vb.asUInt(1) shouldEqual 1
fule.vb.asUInt(1) shouldEqual 1
fugt.vb.asUInt(1) shouldEqual 0
fuge.vb.asUInt(1) shouldEqual 0
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a0, a0)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
ford.vb.asUInt(1) shouldEqual 1
foeq.vb.asUInt(1) shouldEqual 1
fone.vb.asUInt(1) shouldEqual 0
folt.vb.asUInt(1) shouldEqual 0
fole.vb.asUInt(1) shouldEqual 1
fogt.vb.asUInt(1) shouldEqual 0
foge.vb.asUInt(1) shouldEqual 1
funo.vb.asUInt(1) shouldEqual 0
fueq.vb.asUInt(1) shouldEqual 1
fune.vb.asUInt(1) shouldEqual 0
fult.vb.asUInt(1) shouldEqual 0
fule.vb.asUInt(1) shouldEqual 1
fugt.vb.asUInt(1) shouldEqual 0
fuge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
val a2 = ca.putFloat("@float", Float.NaN)
testFunc(ca, func, Seq(a0, a2)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
ford.vb.asUInt(1) shouldEqual 0
foeq.vb.asUInt(1) shouldEqual 0
fone.vb.asUInt(1) shouldEqual 0
folt.vb.asUInt(1) shouldEqual 0
fole.vb.asUInt(1) shouldEqual 0
fogt.vb.asUInt(1) shouldEqual 0
foge.vb.asUInt(1) shouldEqual 0
funo.vb.asUInt(1) shouldEqual 1
fueq.vb.asUInt(1) shouldEqual 1
fune.vb.asUInt(1) shouldEqual 1
fult.vb.asUInt(1) shouldEqual 1
fule.vb.asUInt(1) shouldEqual 1
fugt.vb.asUInt(1) shouldEqual 1
fuge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
ca.close()
}
"Comparing operations" should "work on double" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@cmp_d")
val a0 = ca.putDouble("@double", 1.0d)
val a1 = ca.putDouble("@double", 2.0d)
testFunc(ca, func, Seq(a0, a1)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
ford.vb.asUInt(1) shouldEqual 1
foeq.vb.asUInt(1) shouldEqual 0
fone.vb.asUInt(1) shouldEqual 1
folt.vb.asUInt(1) shouldEqual 1
fole.vb.asUInt(1) shouldEqual 1
fogt.vb.asUInt(1) shouldEqual 0
foge.vb.asUInt(1) shouldEqual 0
funo.vb.asUInt(1) shouldEqual 0
fueq.vb.asUInt(1) shouldEqual 0
fune.vb.asUInt(1) shouldEqual 1
fult.vb.asUInt(1) shouldEqual 1
fule.vb.asUInt(1) shouldEqual 1
fugt.vb.asUInt(1) shouldEqual 0
fuge.vb.asUInt(1) shouldEqual 0
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a0, a0)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
ford.vb.asUInt(1) shouldEqual 1
foeq.vb.asUInt(1) shouldEqual 1
fone.vb.asUInt(1) shouldEqual 0
folt.vb.asUInt(1) shouldEqual 0
fole.vb.asUInt(1) shouldEqual 1
fogt.vb.asUInt(1) shouldEqual 0
foge.vb.asUInt(1) shouldEqual 1
funo.vb.asUInt(1) shouldEqual 0
fueq.vb.asUInt(1) shouldEqual 1
fune.vb.asUInt(1) shouldEqual 0
fult.vb.asUInt(1) shouldEqual 0
fule.vb.asUInt(1) shouldEqual 1
fugt.vb.asUInt(1) shouldEqual 0
fuge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
val a2 = ca.putDouble("@double", Double.NaN)
testFunc(ca, func, Seq(a0, a2)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
ford.vb.asUInt(1) shouldEqual 0
foeq.vb.asUInt(1) shouldEqual 0
fone.vb.asUInt(1) shouldEqual 0
folt.vb.asUInt(1) shouldEqual 0
fole.vb.asUInt(1) shouldEqual 0
fogt.vb.asUInt(1) shouldEqual 0
foge.vb.asUInt(1) shouldEqual 0
funo.vb.asUInt(1) shouldEqual 1
fueq.vb.asUInt(1) shouldEqual 1
fune.vb.asUInt(1) shouldEqual 1
fult.vb.asUInt(1) shouldEqual 1
fule.vb.asUInt(1) shouldEqual 1
fugt.vb.asUInt(1) shouldEqual 1
fuge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
ca.close()
}
"Comparing operations" should "work on vectors" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@cmp_vec")
val a0 = ca.putIntVec("@4xi32", Seq(1, 1, 2, 2))
val a1 = ca.putIntVec("@4xi32", Seq(1, 2, 1, 2))
val a2 = ca.putFloatVec("@4xfloat", Seq(1.0f, 1.0f, 2.0f, 2.0f))
val a3 = ca.putFloatVec("@4xfloat", Seq(1.0f, 2.0f, 1.0f, 2.0f))
val a4 = ca.putDoubleVec("@2xdouble", Seq(1.0d, 2.0d))
val a5 = ca.putDoubleVec("@2xdouble", Seq(2.0d, 2.0d))
testFunc(ca, func, Seq(a0, a1, a2, a3, a4, a5)) { (ca, th, st, wp) =>
val Seq(eq, slt, foeqf, fultf, foeqd, fultd) = ca.dumpKeepalives(st, 0)
eq.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(1, 0, 0, 1)
slt.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(0, 1, 0, 0)
foeqf.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(1, 0, 0, 1)
fultf.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(0, 1, 0, 0)
foeqd.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(0, 1)
fultd.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(1, 0)
TrapRebindPassVoid(st)
}
val a6 = ca.putFloatVec("@4xfloat", Seq(Float.NaN, Float.NaN, Float.NaN, Float.NaN))
val a7 = ca.putDoubleVec("@2xdouble", Seq(Double.NaN, Double.NaN))
testFunc(ca, func, Seq(a0, a1, a2, a6, a4, a7)) { (ca, th, st, wp) =>
val Seq(eq, slt, foeqf, fultf, foeqd, fultd) = ca.dumpKeepalives(st, 0)
foeqf.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(0, 0, 0, 0)
fultf.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(1, 1, 1, 1)
foeqd.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(0, 0)
fultd.vb.asVec.map(_.asUInt(1)) shouldEqual Seq(1, 1)
TrapRebindPassVoid(st)
}
ca.close()
}
"Conversions" should "work on scalar types" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@conv")
val a0 = ca.putInt("@i32", 0xfedcba98L)
val a1 = ca.putInt("@i64", 0x123456789abcdef0L)
val a2 = ca.putFloat("@float", 1.5f)
val a3 = ca.putDouble("@double", 6.25d)
testFunc(ca, func, Seq(a0, a1, a2, a3)) { (ca, th, st, wp) =>
val Seq(trunc, zext, sext, fptrunc, fpext, fptoui1, fptosi1, fptoui2, fptosi2, uitofp, sitofp,
bitcast1, bitcast2, bitcast3, bitcast4) = ca.dumpKeepalives(st, 0)
trunc.vb.asUInt(32) shouldBe 0x9abcdef0L
zext.vb.asUInt(64) shouldBe 0xfedcba98L
sext.vb.asUInt(64) shouldBe BigInt("fffffffffedcba98", 16)
fptrunc.vb.asFloat shouldBe 6.25f
fpext.vb.asDouble shouldBe 1.5d
fptoui1.vb.asSInt(64) shouldBe 6
fptosi1.vb.asSInt(64) shouldBe 6
fptoui2.vb.asSInt(32) shouldBe 1
fptosi2.vb.asSInt(32) shouldBe 1
uitofp.vb.asDouble shouldBe 0x123456789abcdef0L.doubleValue()
sitofp.vb.asDouble shouldBe 0x123456789abcdef0L.doubleValue()
bitcast1.vb.asSInt(32) shouldBe java.lang.Float.floatToRawIntBits(1.5f)
bitcast2.vb.asSInt(64) shouldBe java.lang.Double.doubleToRawLongBits(6.25d)
bitcast3.vb.asFloat shouldBe 1.5f
bitcast4.vb.asDouble shouldBe 6.25d
TrapRebindPassVoid(st)
}
val a5 = ca.putInt("@i64", -0x123456789abcdef0L)
testFunc(ca, func, Seq(a0, a5, a2, a3)) { (ca, th, st, wp) =>
val Seq(trunc, zext, sext, fptrunc, fpext, fptoui1, fptosi1, fptoui2, fptosi2, uitofp, sitofp,
bitcast1, bitcast2, bitcast3, bitcast4) = ca.dumpKeepalives(st, 0)
sitofp.vb.asDouble shouldBe (-0x123456789abcdef0L).doubleValue()
TrapRebindPassVoid(st)
}
ca.close()
}
"Conversions" should "work on vector types" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@conv_vec")
val a0 = ca.putIntVec("@4xi32", Seq(0x12345678L, 0x9abcdef0L, 0xfedcba98L, 0x76543210L))
val a1 = ca.putFloatVec("@4xfloat", Seq(1.0f, 1.5f, 2.0f, 2.5f))
val a2 = ca.putDoubleVec("@2xdouble", Seq(1.0d, 1.5d))
testFunc(ca, func, Seq(a0, a1, a2)) { (ca, th, st, wp) =>
val Seq(trunc, zext, sext, fptrunc, fpext) = ca.dumpKeepalives(st, 0)
trunc.vb.asVec.map(_.asUInt(16)) shouldBe Seq(0x5678L, 0xdef0L, 0xba98L, 0x3210L)
zext.vb.asVec.map(_.asUInt(64)) shouldBe Seq(0x12345678L, 0x9abcdef0L, 0xfedcba98L, 0x76543210L)
sext.vb.asVec.map(_.asUInt(64)) shouldBe Seq(0x12345678L, BigInt("ffffffff9abcdef0", 16), BigInt("fffffffffedcba98", 16), 0x76543210L)
fptrunc.vb.asVec.map(_.asFloat) shouldBe Seq(1.0f, 1.5f)
fpext.vb.asVec.map(_.asDouble) shouldBe Seq(1.0d, 1.5d, 2.0d, 2.5d)
TrapRebindPassVoid(st)
}
ca.close()
}
"The SELECT instruction" should "work on both scalars and vectors and allow per-element select" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@select")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val Seq(sel1, sel2, sel3, sel4, sel5) = ca.dumpKeepalives(st, 0)
sel1.vb.asSInt(64) shouldBe 2
sel2.vb.asSInt(64) shouldBe 3
sel3.vb.asVec.map(_.asSInt(32)) shouldBe Seq(0, 5, 6, 3)
sel4.vb.asVec.map(_.asSInt(32)) shouldBe Seq(0, 1, 2, 3)
sel5.vb.asVec.map(_.asSInt(32)) shouldBe Seq(4, 5, 6, 7)
TrapRebindPassVoid(st)
}
ca.close()
}
}
\ No newline at end of file
......@@ -164,6 +164,14 @@
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)
.funcdef @ctrlFlow VERSION @ctrlFlow_v1 <@ctrlFlow_sig> (%p0) {
%entry:
......
......@@ -59,14 +59,14 @@
.typedef @4xi32 = vector <@i32 4>
.typedef @2xdouble = vector <@double 2>
.const @4xI32_V1 <@4xi32> = {@I32_0 @I32_1 @I32_2 @I32_3}
.const @4xI32_V2 <@4xi32> = {@I32_4 @I32_5 @I32_6 @I32_7}
.const @4xI32_V1 <@4xi32> = VEC {@I32_0 @I32_1 @I32_2 @I32_3}
.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_V2 <@4xfloat> = {@F_4 @F_5 @F_6 @F_7}
.const @4xF_V1 <@4xfloat> = VEC {@F_0 @F_1 @F_2 @F_3}
.const @4xF_V2 <@4xfloat> = VEC {@F_4 @F_5 @F_6 @F_7}
.const @2xD_V1 <@2xdouble> = {@D_0 @D_1}
.const @2xD_V2 <@2xdouble> = {@D_2 @D_3}
.const @2xD_V1 <@2xdouble> = VEC {@D_0 @D_1}
.const @2xD_V2 <@2xdouble> = VEC {@D_2 @D_3}
.funcsig @i_ii = @i64 (@i64 @i64)
......@@ -209,8 +209,6 @@
%trap = TRAP <@void> KEEPALIVE (
%eq %ne %ult %ule %ugt %uge %slt %sle %sgt %sge
)
%exit:
COMMINST @uvm.thread_exit
}
......@@ -238,8 +236,6 @@
%ftrue %ffalse %ford %foeq %fone %folt %fole %fogt %foge
%funo %fueq %fune %fult %fule %fugt %fuge
)
%exit:
COMMINST @uvm.thread_exit
}
......@@ -267,8 +263,22 @@
%ftrue %ffalse %ford %foeq %fone %folt %fole %fogt %foge
%funo %fueq %fune %fult %fule %fugt %fuge
)
%exit:
COMMINST @uvm.thread_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
}
......@@ -282,24 +292,51 @@
%fptrunc = FPTRUNC <@double @float> %p3
%fpext = FPEXT <@float @double> %p2
%fptoui = FPTOUI <@double @i64> %p3
%fptosi = FPTOSI <@double @i64> %p3
%fptoui1 = FPTOUI <@double @i64> %p3
%fptosi1 = FPTOSI <@double @i64> %p3
%fptoui2 = FPTOUI <@float @i32> %p2
%fptosi2 = FPTOSI <@float @i32> %p2
%uitofp = UITOFP <@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 (
%trunc %zext %sext %fptrunc %fpext %fptoui %fptosi %uitofp %sitofp
%bitcast
%trunc %zext %sext %fptrunc %fpext
%fptoui1 %fptosi1 %fptoui2 %fptosi2 %uitofp %sitofp
%bitcast1 %bitcast2 %bitcast3 %bitcast4
)
%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>
.const @4xI1_COND <@4xi1> = {@TRUE @FALSE @FALSE @TRUE}
.const @4xI1_COND <@4xi1> = VEC {@TRUE @FALSE @FALSE @TRUE}
.funcdef @select VERSION @select_v1 <@noparamsnoret> () {
%entry:
......@@ -314,8 +351,6 @@
%trap = TRAP <@void> KEEPALIVE (
%sel1 %sel2 %sel3 %sel4 %sel5
)
%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