Commit 2b39bedd authored by Kunshan Wang's avatar Kunshan Wang

Aggregate operations.

parent bdd1dce5
......@@ -361,7 +361,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
curStack.pushFrame(funcVer, argBoxes)
}
case i @ InstTailCall(sig, callee, argList) => {
val calleeFunc = boxOf(callee).asInstanceOf[BoxFunc].func.getOrElse {
throw new UvmRuntimeException(ctx + "Callee must not be NULL")
......@@ -373,7 +373,7 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
curStack.replaceTop(funcVer, argBoxes)
}
case i @ InstRet(retTy, retVal) => {
val rvb = boxOf(retVal)
curStack.popFrame()
......@@ -381,20 +381,103 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
boxOf(newCurInst).copyFrom(rvb)
continueNormally()
}
case i @ InstRetVoid() => {
curStack.popFrame()
continueNormally()
}
case i @ InstThrow(excVal) => {
val exc = boxOf(excVal).asInstanceOf[BoxRef].objRef
curStack.popFrame()
catchException(exc)
}
case i @ InstLandingPad() => throw new UvmRefImplException(ctx + "LANDINGPAD instructions reached in normal execution, " +
"but LANDINGPAD must only appear in the beginning of basic blocks and not in the entry block.")
case i @ InstExtractValue(strTy, index, opnd) => {
val ob = boxOf(opnd).asInstanceOf[BoxStruct]
val fb = ob.values(index)
val ib = boxOf(i)
ib.copyFrom(fb)
continueNormally()
}
case i @ InstInsertValue(strTy, index, opnd, newVal) => {
val ob = boxOf(opnd).asInstanceOf[BoxStruct]
val nvb = boxOf(newVal)
val ib = boxOf(i).asInstanceOf[BoxStruct]
for (((ofb, ifb), ind) <- (ob.values zip ib.values).zipWithIndex) {
if (ind == index) {
ifb.copyFrom(nvb)
} else {
ifb.copyFrom(ofb)
}
}
continueNormally()
}
case i @ InstExtractElement(vecTy, indTy, opnd, index) => {
val ob = boxOf(opnd).asInstanceOf[BoxVector]
val indb = boxOf(index).asInstanceOf[BoxInt]
val ind = OpHelper.prepareSigned(indb.value, indTy.length)
if (ind < 0 || ind > vecTy.len) {
throw new UvmRuntimeException(ctx + "Index %d out of range. Vector type: %s".format(ind, vecTy))
}
val eb = ob.values(ind.intValue())
val ib = boxOf(i)
ib.copyFrom(eb)
continueNormally()
}
case i @ InstInsertElement(vecTy, indTy, opnd, index, newVal) => {
val ob = boxOf(opnd).asInstanceOf[BoxVector]
val indb = boxOf(index).asInstanceOf[BoxInt]
val ind = OpHelper.prepareSigned(indb.value, indTy.length)
if (ind < 0 || ind > vecTy.len) {
throw new UvmRuntimeException(ctx + "Index %d out of range. Vector type: %s".format(ind, vecTy))
}
val indInt = ind.intValue
val nvb = boxOf(newVal)
val ib = boxOf(i).asInstanceOf[BoxVector]
for (((oeb, ieb), ind2) <- (ob.values zip ib.values).zipWithIndex) {
if (ind2 == indInt) {
ieb.copyFrom(nvb)
} else {
ieb.copyFrom(oeb)
}
}
continueNormally()
}
case i @ InstShuffleVector(vecTy, maskTy, vec1, vec2, mask) => {
val vecLen = vecTy.len.toInt
val maskIntLen = maskTy.elemTy.asInstanceOf[TypeInt].length
val vb1 = boxOf(vec1).asInstanceOf[BoxVector]
val vb2 = boxOf(vec2).asInstanceOf[BoxVector]
val mb = boxOf(mask).asInstanceOf[BoxVector]
val ib = boxOf(i).asInstanceOf[BoxVector]
for (((meb, ieb), ind) <- (mb.values zip ib.values).zipWithIndex) {
val me = OpHelper.prepareSigned(meb.asInstanceOf[BoxInt].value, maskIntLen)
if (0 <= me && me < vecLen) {
ieb.copyFrom(vb1.values(me.intValue))
} else if (vecLen <= me && me < vecLen * 2) {
ieb.copyFrom(vb2.values(me.intValue - vecLen))
} else {
throw new UvmRuntimeException(ctx + "Index %d as the %d-th element of mask is out of range. Vector type: %s".format(me, ind, vecTy))
}
}
continueNormally()
}
// Indentation guide: Insert more instructions here.
......
......@@ -277,3 +277,10 @@ object PrimOpHelpers {
}
}
}
object AggregateOperations {
def extractValue(boxStr: BoxStruct, index: Int, boxResult: ValueBox): Unit = {
}
}
......@@ -18,7 +18,7 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
setLogLevels(
ROOT_LOGGER_NAME -> INFO,
"uvm.refimpl.itpr" -> DEBUG)
preloadBundles("tests/uvm-refimpl-test/basic-tests.uir")
"The constant pool" should "contain appropriate constant values" in {
......@@ -760,4 +760,40 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
}
ca.close()
}
"EXTRACTVALUE and INSERTVALUE" should "work" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@aggregate_struct")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val Seq(f1, f12) = ca.dumpKeepalives(st, 0)
f1.vb.asSInt(64) shouldEqual 2
f12.vb.asSInt(64) shouldEqual 7
TrapRebindPassVoid(st)
}
ca.close()
}
"EXTRACTELEMENT and INSERTELEMENT" should "work on vectors" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@aggregate_vector")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val Seq(ee0, ie0, sv0) = ca.dumpKeepalives(st, 0)
ee0.vb.asFloat shouldEqual 0.0f
ie0.vb.asVec.map(_.asFloat) shouldEqual Seq(0.0f, 6.0f, 2.0f, 3.0f)
sv0.vb.asVec.map(_.asFloat) shouldEqual Seq(0.0f, 2.0f, 4.0f, 6.0f)
TrapRebindPassVoid(st)
}
ca.close()
}
}
\ No newline at end of file
......@@ -239,12 +239,12 @@
.typedef @sid = struct <@i64 @double>
.const @sid1 <@sid> = {@I64_1 @D_1}
.const @v1 <@4xfloat> = {@F_0 @F_0 @F_0 @F_0}
.const @v2 <@4xfloat> = {@F_1 @F_1 @F_1 @F_1}
.const @v1 <@4xfloat> = VEC {@F_0 @F_0 @F_0 @F_0}
.const @v2 <@4xfloat> = VEC {@F_1 @F_1 @F_1 @F_1}
.const @I32_4 <@i32> = 4
.const @I32_6 <@i32> = 6
.const @vshf <@4xi32> = {@I32_0 @I32_2 @I32_4 @I32_6}
.const @vshf <@4xi32> = VEC {@I32_0 @I32_2 @I32_4 @I32_6}
.funcdef @aggregate VERSION @aggregate_v1 <@npnr_sig> () {
%entry:
......
......@@ -443,23 +443,36 @@
COMMINST @uvm.thread_exit
}
// // Some simple struct constants
//
// .typedef @StructFoo = struct <@i32 @i64 @float @double>
//
// .const @STRUCT_FOO <@StructFoo> = {1 2 3.0f 4.0d}
//
// .funcsig @aggregate_sig = @noparamsnoret
// .funcdef @aggregate VERSION @aggregate_v1 <@aggregate_sig> () {
// %entry:
// %f1 = EXTRACTVALUE <@StructFoo 1> @STRUCT_FOO
// %s2 = INSERTVALUE <@StructFoo 1> @STRUCT_FOO 222
// %f12 = EXTRACTVALUE <@StructFoo 1> %s2
// %trapnor = TRAP <@void> KEEPALIVE (%f1 %f12)
// %exit:
// COMMINST @uvm.thread_exit
// }
//
// Some simple struct constants
.typedef @StructFoo = struct <@i32 @i64 @float @double>
.const @STRUCT_FOO <@StructFoo> = {@I32_1 @I64_2 @F_3 @D_4}
.funcdef @aggregate_struct VERSION @aggregate_struct_v1 <@noparamsnoret> () {
%entry:
%f1 = EXTRACTVALUE <@StructFoo 1> @STRUCT_FOO
%s2 = INSERTVALUE <@StructFoo 1> @STRUCT_FOO @I64_7
%f12 = EXTRACTVALUE <@StructFoo 1> %s2
%trapnor = TRAP <@void> KEEPALIVE (%f1 %f12)
COMMINST @uvm.thread_exit
}
.const @v1 <@4xfloat> = VEC {@F_0 @F_1 @F_2 @F_3}
.const @v2 <@4xfloat> = VEC {@F_4 @F_5 @F_6 @F_7}
.const @vshf <@4xi32> = VEC {@I32_0 @I32_2 @I32_4 @I32_6}
.funcdef @aggregate_vector VERSION @aggregate_vector_v1 <@noparamsnoret> () {
%entry:
%ee0 = EXTRACTELEMENT <@4xfloat @i32> @4xF_V1 @I32_0
%ie0 = INSERTELEMENT <@4xfloat @i32> @4xF_V1 @I32_1 @F_6
%sv0 = SHUFFLEVECTOR <@4xfloat @4xi32> @4xF_V1 @4xF_V2 @vshf
%trapnor = TRAP <@void> KEEPALIVE (%ee0 %ie0 %sv0)
COMMINST @uvm.thread_exit
}
// .typedef @refi64 = ref<@i64>
// .typedef @irefi64 = iref<@i64>
// .typedef @weakrefi64 = weakref<@i64>
......
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