Commit 60d6faa0 authored by Kunshan Wang's avatar Kunshan Wang

WIP: Syntax for multiple returns.

parent 9c937dd9
...@@ -4,8 +4,9 @@ Mu Reference Implementation version 2 ...@@ -4,8 +4,9 @@ Mu Reference Implementation version 2
This project is the current reference implementation of Mu, the micro virtual This project is the current reference implementation of Mu, the micro virtual
machine designed by [The Micro Virtual Machine Project](http://microvm.org). machine designed by [The Micro Virtual Machine Project](http://microvm.org).
Version 2.1.x implements the latest revision of the [Mu Specification version Version 2.1.x implements the [goto-with-value form of the Mu
2](https://github.com/microvm/microvm-spec/wiki). Specification](https://github.com/microvm/microvm-spec/tree/goto-with-values),
which will eventually become the main line.
This project is based on the previous works of This project is based on the previous works of
[simplest-microvm-project](https://github.com/microvm/simplest-microvm-project). [simplest-microvm-project](https://github.com/microvm/simplest-microvm-project).
...@@ -33,9 +34,7 @@ git clone git@github.com:microvm/microvm-refimpl2.git ...@@ -33,9 +34,7 @@ git clone git@github.com:microvm/microvm-refimpl2.git
* In the directory `microvm-refimpl2`, do the following: * In the directory `microvm-refimpl2`, do the following:
```bash ```bash
sbt update sbt update genSrc eclipse
sbt antlr4:antlr4Generate
sbt eclipse
``` ```
* Open Scala IDE and import the generated project as "existing project into * Open Scala IDE and import the generated project as "existing project into
...@@ -51,14 +50,16 @@ yum, pacman, etc. for GNU/Linux distributions and Homebrew for Mac OS X). ...@@ -51,14 +50,16 @@ yum, pacman, etc. for GNU/Linux distributions and Homebrew for Mac OS X).
To download all dependencies from the Maven central repository, invoke `sbt To download all dependencies from the Maven central repository, invoke `sbt
update`. update`.
To compile, invoke `sbt compile` or do this in your favourite IDE. This will To generate the Mu IR parser from the Antlr grammar, invoke `sbt genSrc`. The
also generate the Mu IR parser from the Antlr grammar. The generated sources generated sources will be in the `target/scala-2.11/src_managed` directory.
will be in the `target/scala-2.11/src_managed` directory.
To generate an Eclipse project, install the [sbt-eclipse To generate an Eclipse project, install the [sbt-eclipse
plugin](https://github.com/typesafehub/sbteclipse) and invoke `sbt eclipse`. By plugin](https://github.com/typesafehub/sbteclipse) and invoke `sbt eclipse`.
default, it should automatically put the managed source directory to the source Make sure you generate the parser before creating the Eclipse project, so that
paths, too. the generated sources will be on the Eclipse build path.
To compile, invoke `sbt compile`. This will also generate the Mu IR parser using
Antlr.
IntelliJ IDEA has plugins for Scala and SBT. Make sure you don't commit `.idea` IntelliJ IDEA has plugins for Scala and SBT. Make sure you don't commit `.idea`
or generated project files into the repository. or generated project files into the repository.
......
lazy val genSrc = taskKey[List[File]]("generate sources")
genSrc <<= (sourceGenerators in Compile) { _.join.map(_.flatten.toList) }
lazy val root = (project in file(".")).settings( lazy val root = (project in file(".")).settings(
organization := "org.microvm", organization := "org.microvm",
...@@ -30,3 +35,5 @@ lazy val root = (project in file(".")).settings( ...@@ -30,3 +35,5 @@ lazy val root = (project in file(".")).settings(
antlr4GenVisitor in Antlr4 := false antlr4GenVisitor in Antlr4 := false
) )
...@@ -51,7 +51,7 @@ typeConstructor ...@@ -51,7 +51,7 @@ typeConstructor
| 'weakref' '<' ty=type '>' # TypeWeakRef | 'weakref' '<' ty=type '>' # TypeWeakRef
| 'struct' '<' fieldTys+=type+ '>' # TypeStruct | 'struct' '<' fieldTys+=type+ '>' # TypeStruct
| 'array' '<' ty=type length=intLiteral '>' # TypeArray | 'array' '<' ty=type length=intLiteral '>' # TypeArray
| 'hybrid' '<' fixedTy=type varTy=type '>' # TypeHybrid | 'hybrid' '<' fieldTys+=type* varTy=type '>' # TypeHybrid
| 'void' # TypeVoid | 'void' # TypeVoid
| 'funcref' '<' funcSig '>' # TypeFuncRef | 'funcref' '<' funcSig '>' # TypeFuncRef
| 'threadref' # TypeThreadRef | 'threadref' # TypeThreadRef
...@@ -63,7 +63,7 @@ typeConstructor ...@@ -63,7 +63,7 @@ typeConstructor
; ;
funcSigConstructor funcSigConstructor
: retTy=type '(' (paramTys+=type*) ')' : '(' paramTys+=type* ')' '->' '(' retTys+=type* ')'
; ;
constConstructor constConstructor
...@@ -103,23 +103,28 @@ label ...@@ -103,23 +103,28 @@ label
; ;
bbParam bbParam
: '<' type '>' name : '<' ty=type '>' name
; ;
excParam excParam
: '[' name ']' : '[' name ']'
; ;
instResults
: results+=name
| '(' results+=name* ')'
;
inst inst
: (name '=')? instBody : (instResults '=')? ('[' name ']')? instBody
; ;
instBody instBody
// Integer/FP Arithmetic // Integer/FP Arithmetic
: binop '<' type '>' op1=value op2=value excClause # InstBinOp : binop '<' ty=type '>' op1=value op2=value excClause # InstBinOp
// Integer/FP Comparison // Integer/FP Comparison
| cmpop '<' type '>' op1=value op2=value # InstCmp | cmpop '<' ty=type '>' op1=value op2=value # InstCmp
// Conversions // Conversions
| convop '<' fromTy=type toTy=type '>' opnd=value # InstConversion | convop '<' fromTy=type toTy=type '>' opnd=value # InstConversion
...@@ -130,14 +135,14 @@ instBody ...@@ -130,14 +135,14 @@ instBody
// Intra-function Control Flow // Intra-function Control Flow
| 'BRANCH' dest=destClause # InstBranch | 'BRANCH' dest=destClause # InstBranch
| 'BRANCH2' cond=value ifTrue=destClause ifFalse=destClause # InstBranch2 | 'BRANCH2' cond=value ifTrue=destClause ifFalse=destClause # InstBranch2
| 'SWITCH' '<' type '>' opnd=value defDest=destClause '{' | 'SWITCH' '<' ty=type '>' opnd=value defDest=destClause '{'
(caseVal+=value caseDest+=destClause )* '}' # InstSwitch (caseVal+=value caseDest+=destClause )* '}' # InstSwitch
// Inter-function Control Flow // Inter-function Control Flow
| 'CALL' funcCallBody excClause keepAliveClause # InstCall | 'CALL' funcCallBody excClause keepAliveClause # InstCall
| 'TAILCALL' funcCallBody # InstTailCall | 'TAILCALL' funcCallBody # InstTailCall
| 'RET' retVal=value # InstRet | 'RET' retVals # InstRet
| 'THROW' exc=value # InstThrow | 'THROW' exc=value # InstThrow
// Aggregate Operations // Aggregate Operations
...@@ -158,7 +163,6 @@ instBody ...@@ -158,7 +163,6 @@ instBody
| 'GETFIELDIREF' (ptr='PTR'?) '<' refTy=type index=intLiteral '>' opnd=value # InstGetFieldIRef | 'GETFIELDIREF' (ptr='PTR'?) '<' refTy=type index=intLiteral '>' opnd=value # InstGetFieldIRef
| 'GETELEMIREF' (ptr='PTR'?) '<' refTy=type indTy=type '>' opnd=value index=value # InstGetElemIRef | 'GETELEMIREF' (ptr='PTR'?) '<' refTy=type indTy=type '>' opnd=value index=value # InstGetElemIRef
| 'SHIFTIREF' (ptr='PTR'?) '<' refTy=type offTy=type '>' opnd=value offset=value # InstShiftIRef | 'SHIFTIREF' (ptr='PTR'?) '<' refTy=type offTy=type '>' opnd=value offset=value # InstShiftIRef
| 'GETFIXEDPARTIREF' (ptr='PTR'?) '<' refTy=type '>' opnd=value # InstGetFixedPartIRef
| 'GETVARPARTIREF' (ptr='PTR'?) '<' refTy=type '>' opnd=value # InstGetVarPartIRef | 'GETVARPARTIREF' (ptr='PTR'?) '<' refTy=type '>' opnd=value # InstGetVarPartIRef
| 'LOAD' (ptr='PTR'?) memord? '<' type '>' loc=value excClause # InstLoad | 'LOAD' (ptr='PTR'?) memord? '<' type '>' loc=value excClause # InstLoad
...@@ -170,20 +174,25 @@ instBody ...@@ -170,20 +174,25 @@ instBody
| 'FENCE' memord # InstFence | 'FENCE' memord # InstFence
// Trap // Trap
| 'TRAP' '<' type '>' excClause keepAliveClause # InstTrap | 'TRAP' typeList excClause keepAliveClause # InstTrap
| 'WATCHPOINT' wpid=intLiteral '<' type '>' | 'WATCHPOINT' wpid=intLiteral typeList
dis=destClause ena=destClause ('WPEXC' '(' wpExc=destClause ')')? keepAliveClause # InstWatchPoint dis=destClause ena=destClause ('WPEXC' '(' wpExc=destClause ')')? keepAliveClause # InstWatchPoint
// Foreign Function Interface // Foreign Function Interface
| 'CCALL' callConv=flag '<' funcTy=type funcSig '>' callee=value argList keepAliveClause # InstCCall | 'CCALL' callConv=flag '<' funcTy=type funcSig '>' callee=value argList excClause keepAliveClause # InstCCall
// Thread and Stack Operations // Thread and Stack Operations
| 'NEWSTACK' funcCallBody excClause # InstNewStack | 'NEWTHREAD' stack=value newStackClause excClause # InstNewThread
| 'SWAPSTACK' swappee=value curStackClause newStackClause excClause keepAliveClause # InstSwapStack | 'SWAPSTACK' swappee=value curStackClause newStackClause excClause keepAliveClause # InstSwapStack
// Common Instructions // Common Instructions
| 'COMMINST' nam=GLOBAL_NAME flagList? typeList? funcSigList? argList? excClause keepAliveClause # InstCommInst | 'COMMINST' nam=GLOBAL_NAME flagList? typeList? funcSigList? argList? excClause keepAliveClause # InstCommInst
; ;
retVals
: '(' vals+=value* ')'
| vals+=value
;
destClause destClause
: bb argList : bb argList
...@@ -226,12 +235,12 @@ argList ...@@ -226,12 +235,12 @@ argList
; ;
curStackClause curStackClause
: 'RET_WITH' '<' type '>' # CurStackRetWith : 'RET_WITH' typeList # CurStackRetWith
| 'KILL_OLD' # CurStackKillOld | 'KILL_OLD' # CurStackKillOld
; ;
newStackClause newStackClause
: 'PASS_VALUE' '<' type '>' value # NewStackPassValue : 'PASS_VALUES' typeList argList # NewStackPassValue
| 'THROW_EXC' exc=value # NewStackThrowExc | 'THROW_EXC' exc=value # NewStackThrowExc
; ;
......
...@@ -5,6 +5,14 @@ trait Identified { ...@@ -5,6 +5,14 @@ trait Identified {
def name: Option[String] def name: Option[String]
def repr: String = "[%d:%s]".format(id, name.getOrElse("_")) def repr: String = "[%d:%s]".format(id, name.getOrElse("_"))
// Identified objects should use reference equality rather than structural equality. (case classes use the latter)
override def hashCode(): Int = if (id != 0) id else System.identityHashCode(this)
override def equals(that: Any): Boolean = that match {
case v: AnyRef => this eq v
case _ => false
}
override def toString = "%s%s".format(this.getClass.getSimpleName, this.repr)
} }
trait IdentifiedSettable extends Identified { trait IdentifiedSettable extends Identified {
......
...@@ -3,18 +3,15 @@ package uvm ...@@ -3,18 +3,15 @@ package uvm
import uvm.types._ import uvm.types._
import uvm.ssavariables._ import uvm.ssavariables._
case class FuncSig(var retTy: Type, var paramTy: Seq[Type]) extends IdentifiedSettable { case class FuncSig(var paramTys: Seq[Type], var retTys: Seq[Type]) extends IdentifiedSettable {
override final def toString: String = FuncSig.prettyPrint(this) override final def toString: String = FuncSig.prettyPrint(this)
override def hashCode(): Int = System.identityHashCode(this)
override def equals(that: Any): Boolean = that match {
case v: AnyRef => this eq v
case _ => false
}
} }
object FuncSig { object FuncSig {
def prettyPrint(sig: FuncSig): String = def prettyPrint(sig: FuncSig): String = {
"%s (%s)".format(sig.retTy.repr, sig.paramTy.map(_.repr).mkString(" ")) def mkReprList(is: Seq[Identified]): String = is.map(_.repr).mkString(" ")
"(%s) -> (%s)".format(mkReprList(sig.paramTys), mkReprList(sig.retTys))
}
} }
class Function extends GlobalVariable { class Function extends GlobalVariable {
......
...@@ -241,7 +241,7 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -241,7 +241,7 @@ class UIRTextReader(val idFactory: IDFactory) {
case t: TypeWeakRefContext => TypeWeakRef(null).later(phase1) { _.ty = t.ty } case t: TypeWeakRefContext => TypeWeakRef(null).later(phase1) { _.ty = t.ty }
case t: TypeStructContext => TypeStruct(null).later(phase1) { _.fieldTys = t.fieldTys.map(resTy) } case t: TypeStructContext => TypeStruct(null).later(phase1) { _.fieldTys = t.fieldTys.map(resTy) }
case t: TypeArrayContext => TypeArray(null, t.length.longValue()).later(phase1) { _.elemTy = t.ty } case t: TypeArrayContext => TypeArray(null, t.length.longValue()).later(phase1) { _.elemTy = t.ty }
case t: TypeHybridContext => TypeHybrid(null, null).later(phase1) { tt => tt.fixedTy = t.fixedTy; tt.varTy = t.varTy } case t: TypeHybridContext => TypeHybrid(null, null).later(phase1) { tt => tt.fieldTys = t.fieldTys.map(resTy); tt.varTy = t.varTy }
case t: TypeVoidContext => TypeVoid() case t: TypeVoidContext => TypeVoid()
case t: TypeFuncRefContext => TypeFuncRef(null).later(phase1) { _.sig = t.funcSig() } case t: TypeFuncRefContext => TypeFuncRef(null).later(phase1) { _.sig = t.funcSig() }
case t: TypeThreadRefContext => TypeThreadRef() case t: TypeThreadRefContext => TypeThreadRef()
...@@ -257,8 +257,8 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -257,8 +257,8 @@ class UIRTextReader(val idFactory: IDFactory) {
def mkSig(fsc: FuncSigConstructorContext): FuncSig = { def mkSig(fsc: FuncSigConstructorContext): FuncSig = {
val sig = FuncSig(null, null).later(phase1) { sig => val sig = FuncSig(null, null).later(phase1) { sig =>
sig.retTy = resTy(fsc.retTy) sig.retTys = for (t <- fsc.retTys) yield resTy(t)
sig.paramTy = for (t <- fsc.paramTys) yield resTy(t) sig.paramTys = for (t <- fsc.paramTys) yield resTy(t)
} }
return sig return sig
} }
...@@ -285,19 +285,11 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -285,19 +285,11 @@ class UIRTextReader(val idFactory: IDFactory) {
def mkConst(t: Type, c: ConstConstructorContext): Constant = { def mkConst(t: Type, c: ConstConstructorContext): Constant = {
val con = c match { val con = c match {
case cc: CtorIntContext => t match { case cc: CtorIntContext => ConstInt(t, cc.intLiteral)
case _: TypeInt => ConstInt(t, cc.intLiteral)
case _: AbstractPointerType => ConstPointer(t, cc.intLiteral().longValue())
}
case cc: CtorFloatContext => ConstFloat(t, cc.floatLiteral) case cc: CtorFloatContext => ConstFloat(t, cc.floatLiteral)
case cc: CtorDoubleContext => ConstDouble(t, cc.doubleLiteral) case cc: CtorDoubleContext => ConstDouble(t, cc.doubleLiteral)
case cc: CtorListContext => t match { case cc: CtorListContext => ConstSeq(t, null).later(phase2) {
case _: TypeStruct => ConstStruct(t, null).later(phase2) { _.elems = for (gn <- cc.GLOBAL_NAME()) yield resGlobalVar(gn)
_.fields = for (gn <- cc.GLOBAL_NAME()) yield resGlobalVar(gn)
}
case _: TypeArray | _: TypeVector => ConstSeq(t, null).later(phase2) {
_.elems = for (gn <- cc.GLOBAL_NAME()) yield resGlobalVar(gn)
}
} }
case _: CtorNullContext => ConstNull(t) case _: CtorNullContext => ConstNull(t)
} }
...@@ -474,6 +466,20 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -474,6 +466,20 @@ class UIRTextReader(val idFactory: IDFactory) {
Some(ExcClause(ec.nor, ec.exc)) Some(ExcClause(ec.nor, ec.exc))
} }
implicit def resNewStackClause(nsc: NewStackClauseContext): NewStackAction = {
nsc match {
case a: NewStackPassValueContext => PassValues(a.typeList(), a.argList())
case a: NewStackThrowExcContext => ThrowExc(a.exc)
}
}
implicit def resCurStackClause(csc: CurStackClauseContext): CurStackAction = {
csc match {
case a: CurStackRetWithContext => RetWith(a.typeList())
case a: CurStackKillOldContext => KillOld()
}
}
// Make instruction // Make instruction
def mkInst(bb: BasicBlock, instDef: InstContext): Instruction = { def mkInst(bb: BasicBlock, instDef: InstContext): Instruction = {
...@@ -519,7 +525,7 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -519,7 +525,7 @@ class UIRTextReader(val idFactory: IDFactory) {
} }
case ii: InstRetContext => case ii: InstRetContext =>
InstRet(ver, null).later(phase4) { i => InstRet(ver, null).later(phase4) { i =>
i.retVal = ii.retVal i.retVals = ii.retVals.vals.map(resVar)
} }
case ii: InstThrowContext => case ii: InstThrowContext =>
InstThrow(null).later(phase4) { i => InstThrow(null).later(phase4) { i =>
...@@ -577,10 +583,6 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -577,10 +583,6 @@ class UIRTextReader(val idFactory: IDFactory) {
InstShiftIRef(ii.ptr != null, ii.refTy, needInt(ii.offTy), null, null).later(phase4) { i => InstShiftIRef(ii.ptr != null, ii.refTy, needInt(ii.offTy), null, null).later(phase4) { i =>
i.opnd = ii.opnd; i.offset = ii.offset i.opnd = ii.opnd; i.offset = ii.offset
} }
case ii: InstGetFixedPartIRefContext =>
InstGetFixedPartIRef(ii.ptr != null, needHybrid(ii.refTy), null).later(phase4) { i =>
i.opnd = ii.opnd
}
case ii: InstGetVarPartIRefContext => case ii: InstGetVarPartIRefContext =>
InstGetVarPartIRef(ii.ptr != null, needHybrid(ii.refTy), null).later(phase4) { i => InstGetVarPartIRef(ii.ptr != null, needHybrid(ii.refTy), null).later(phase4) { i =>
i.opnd = ii.opnd i.opnd = ii.opnd
...@@ -608,33 +610,28 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -608,33 +610,28 @@ class UIRTextReader(val idFactory: IDFactory) {
case ii: InstFenceContext => case ii: InstFenceContext =>
InstFence(ii.memord) InstFence(ii.memord)
case ii: InstTrapContext => case ii: InstTrapContext =>
InstTrap(ii.`type`, null, null).later(phase4) { i => InstTrap(ii.typeList(), null, null).later(phase4) { i =>
i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
} }
case ii: InstWatchPointContext => case ii: InstWatchPointContext =>
InstWatchPoint(ii.intLiteral.intValue(), ii.`type`, null, null, null, null).later(phase4) { i => InstWatchPoint(ii.intLiteral.intValue(), ii.typeList(), null, null, null, null).later(phase4) { i =>
i.dis = ii.dis; i.ena = ii.ena; i.exc = Option(ii.wpExc).map(resDestClause); i.keepAlives = ii.keepAliveClause i.dis = ii.dis; i.ena = ii.ena; i.exc = Option(ii.wpExc).map(resDestClause); i.keepAlives = ii.keepAliveClause
} }
case ii: InstCCallContext => case ii: InstCCallContext =>
InstCCall(ii.callConv, ii.funcTy, ii.funcSig, null, null, null).later(phase4) { i => InstCCall(ii.callConv, ii.funcTy, ii.funcSig, null, null, null, null).later(phase4) { i =>
i.callee = ii.callee; i.argList = ii.argList; i.keepAlives = ii.keepAliveClause i.callee = ii.callee; i.argList = ii.argList; i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
} }
case ii: InstNewStackContext => case ii: InstNewThreadContext =>
InstNewStack(null, null, null, null).later(phase4) { i => InstNewThread(null, null, null).later(phase4) { i =>
asgnFuncCallBody(i, ii.funcCallBody) i.stack = ii.stack
i.newStackAction = ii.newStackClause
i.excClause = ii.excClause i.excClause = ii.excClause
} }
case ii: InstSwapStackContext => case ii: InstSwapStackContext =>
InstSwapStack(null, null, null, null, null).later(phase4) { i => InstSwapStack(null, null, null, null, null).later(phase4) { i =>
i.swappee = ii.swappee; i.swappee = ii.swappee
i.curStackAction = ii.curStackClause match { i.curStackAction = ii.curStackClause
case a: CurStackRetWithContext => RetWith(a.`type`) i.newStackAction = ii.newStackClause
case a: CurStackKillOldContext => KillOld()
}
i.newStackAction = ii.newStackClause match {
case a: NewStackPassValueContext => PassValue(a.`type`, a.value)
case a: NewStackThrowExcContext => ThrowExc(a.exc)
}
i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
} }
case ii: InstCommInstContext => case ii: InstCommInstContext =>
...@@ -649,7 +646,15 @@ class UIRTextReader(val idFactory: IDFactory) { ...@@ -649,7 +646,15 @@ class UIRTextReader(val idFactory: IDFactory) {
inst.id = idFactory.getID() inst.id = idFactory.getID()
inst.name = Option(instDef.name).map(n => globalize(n.getText, bbName)) inst.name = Option(instDef.name).map(n => globalize(n.getText, bbName))
bb.localVarNs.add(inst) for ((instResDef, index) <- instDef.instResults().results.zipWithIndex) {
val resName = globalize(instResDef.getText, bbName)
val instRes = InstResult(inst, index)
instRes.id = idFactory.getID()
instRes.name = Some(resName)
bb.localVarNs.add(instRes)
}
return inst return inst
} }
......
...@@ -4,14 +4,7 @@ import uvm._ ...@@ -4,14 +4,7 @@ import uvm._
import uvm.comminsts._ import uvm.comminsts._
import uvm.types._ import uvm.types._
abstract class SSAVariable extends IdentifiedSettable { abstract class SSAVariable extends IdentifiedSettable
override def hashCode(): Int = id
override def equals(that: Any): Boolean = that match {
case v: AnyRef => this eq v
case _ => false
}
override def toString = "%s%s".format(this.getClass.getSimpleName, this.repr)
}
// Global variables: Constants, Global Cells and Functions (Function is defined in controlFlow.scala) // Global variables: Constants, Global Cells and Functions (Function is defined in controlFlow.scala)
...@@ -21,19 +14,18 @@ abstract class Constant extends GlobalVariable { ...@@ -21,19 +14,18 @@ abstract class Constant extends GlobalVariable {
var constTy: Type var constTy: Type
} }
/** For both int<n> and pointers. Convert to Long when needed. */
case class ConstInt(var constTy: Type, var num: BigInt) extends Constant case class ConstInt(var constTy: Type, var num: BigInt) extends Constant
case class ConstFloat(var constTy: Type, var num: Float) extends Constant case class ConstFloat(var constTy: Type, var num: Float) extends Constant
case class ConstDouble(var constTy: Type, var num: Double) extends Constant case class ConstDouble(var constTy: Type, var num: Double) extends Constant
case class ConstStruct(var constTy: Type, var fields: Seq[GlobalVariable]) extends Constant /** For struct, array and vector. */
case class ConstNull(var constTy: Type) extends Constant
case class ConstSeq(var constTy: Type, var elems: Seq[GlobalVariable]) extends Constant case class ConstSeq(var constTy: Type, var elems: Seq[GlobalVariable]) extends Constant
case class ConstPointer(var constTy: Type, var addr: Long) extends Constant /** For all NULL-able values. Note: null pointers are ConstInt(???, 0) */
case class ConstNull(var constTy: Type) extends Constant
case class GlobalCell(var cellTy: Type) extends GlobalVariable case class GlobalCell(var cellTy: Type) extends GlobalVariable
...@@ -47,9 +39,13 @@ abstract class Parameter extends LocalVariable ...@@ -47,9 +39,13 @@ abstract class Parameter extends LocalVariable
case class NorParam(ty: Type) extends Parameter case class NorParam(ty: Type) extends Parameter
case class ExcParam() extends Parameter case class ExcParam() extends Parameter
case class InstResult(inst: Instruction, index: Int) extends LocalVariable
// Instructions // Instructions
abstract class Instruction extends LocalVariable abstract class Instruction extends IdentifiedSettable {
var results: Seq[InstResult] = Seq()
}
/// enumerations /// enumerations
...@@ -93,6 +89,11 @@ import uvm.ssavariables.AtomicRMWOptr.AtomicRMWOptr ...@@ -93,6 +89,11 @@ import uvm.ssavariables.AtomicRMWOptr.AtomicRMWOptr
/// Abstract instructions and traits /// Abstract instructions and traits
trait MaybeTerminator extends Instruction
trait Terminator extends MaybeTerminator
trait OSRPoint extends Instruction
trait HasTypeList extends Instruction { trait HasTypeList extends Instruction {
var typeList: Seq[Type] var typeList: Seq[Type]
} }
...@@ -110,7 +111,7 @@ case class DestClause(val bb: BasicBlock, val args: Seq[SSAVariable]) ...@@ -110,7 +111,7 @@ case class DestClause(val bb: BasicBlock, val args: Seq[SSAVariable])
case class ExcClause(val nor: DestClause, val exc: DestClause) case class ExcClause(val nor: DestClause, val exc: DestClause)
trait HasExcClause extends Instruction { trait HasExcClause extends Instruction with MaybeTerminator {
var excClause: Option[ExcClause] var excClause: Option[ExcClause]
} }
...@@ -141,16 +142,16 @@ trait WorksWithPointer extends Instruction { ...@@ -141,16 +142,16 @@ trait WorksWithPointer extends Instruction {
var ptr: Boolean var ptr: Boolean
} }
abstract class AbstractTrap extends HasKeepAliveClause { abstract class AbstractTrap extends HasKeepAliveClause with OSRPoint {
var retTy: Type var retTys: Seq[Type]
} }
abstract class CurStackAction abstract class CurStackAction
case class RetWith(var retTy: Type) extends CurStackAction case class RetWith(var retTys: Seq[Type]) extends CurStackAction
case class KillOld() extends CurStackAction case class KillOld() extends CurStackAction
abstract class NewStackAction abstract class NewStackAction
case class PassValue(var argTy: Type, var arg: SSAVariable) extends NewStackAction case class PassValues(var argTys: Seq[Type], var args: Seq[SSAVariable]) extends NewStackAction
case class ThrowExc(var exc: SSAVariable) extends NewStackAction case class ThrowExc(var exc: SSAVariable) extends NewStackAction
/** /**
...@@ -169,21 +170,22 @@ case class InstConv(var op: ConvOptr, var fromTy: Type, var toTy: Type, var opnd ...@@ -169,21 +170,22 @@ case class InstConv(var op: ConvOptr, var fromTy: Type, var toTy: Type, var opnd
case class InstSelect(var condTy: Type, var opndTy: 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: DestClause) extends Instruction case class InstBranch(var dest: DestClause) extends Instruction with Terminator
case class InstBranch2(var cond: SSAVariable, var ifTrue: DestClause, var ifFalse: DestClause) extends Instruction case class InstBranch2(var cond: SSAVariable, var ifTrue: DestClause, var ifFalse: DestClause) extends Instruction with Terminator
case class InstSwitch(var opndTy: Type, var opnd: SSAVariable, var defDest: DestClause, case class InstSwitch(var opndTy: Type, var opnd: SSAVariable, var defDest: DestClause,
var cases: Seq[(SSAVariable, DestClause)]) extends Instruction var cases: Seq[(SSAVariable, DestClause)]) extends Instruction with Terminator
case class InstCall(var sig: FuncSig, var callee: SSAVariable, var argList: Seq[SSAVariable], case class InstCall(var sig: FuncSig, var callee: SSAVariable, var argList: Seq[SSAVariable],
var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) extends AbstractCall with HasExcClause with HasKeepAliveClause var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable])
extends AbstractCall with HasExcClause with HasKeepAliveClause with OSRPoint
case class InstTailCall(var sig: FuncSig, var callee: SSAVariable, var argList: Seq[SSAVariable]) extends AbstractCall case class InstTailCall(var sig: FuncSig, var callee: SSAVariable, var argList: Seq[SSAVariable]) extends AbstractCall with Terminator
case class InstRet(val funcVer: FuncVer, var retVal: SSAVariable) extends AbstractRet case class InstRet(val funcVer: FuncVer, var retVals: Seq[SSAVariable]) extends AbstractRet with Terminator
case class InstThrow(var excVal: SSAVariable) extends Instruction case class InstThrow(var excVal: SSAVariable) extends Instruction with Terminator
case class InstExtractValue(var strTy: TypeStruct, var index: Int, var opnd: SSAVariable) extends Instruction case class InstExtractValue(var strTy: TypeStruct, var index: Int, var opnd: SSAVariable) extends Instruction
...@@ -216,8 +218,6 @@ case class InstGetElemIRef(var ptr: Boolean, var referentTy: AbstractSeqType, va ...@@ -216,8 +218,6 @@ case class InstGetElemIRef(var ptr: Boolean, var referentTy: AbstractSeqType, va
case class InstShiftIRef(var ptr: Boolean, var referentTy: Type, var offTy: TypeInt, case class InstShiftIRef(var ptr: Boolean, var referentTy: Type, var offTy: TypeInt,
var opnd: SSAVariable, var offset: SSAVariable) extends WorksWithPointer var opnd: SSAVariable, var offset: SSAVariable) extends WorksWithPointer
case class InstGetFixedPartIRef(var ptr: Boolean, var referentTy: TypeHybrid, var opnd: SSAVariable) extends WorksWithPointer
case class InstGetVarPartIRef(var ptr: Boolean, var referentTy: TypeHybrid, var opnd: SSAVariable) extends WorksWithPointer case class InstGetVarPartIRef(var ptr: Boolean, var referentTy: TypeHybrid, var opnd: SSAVariable) extends WorksWithPointer
case class InstLoad(var ptr: Boolean, var ord: MemoryOrder, var referentTy: Type, var loc: SSAVariable, var excClause: Option[ExcClause]) extends WorksWithPointer with HasExcClause case class InstLoad(var ptr: Boolean, var ord: MemoryOrder, var referentTy: Type, var loc: SSAVariable, var excClause: Option[ExcClause]) extends WorksWithPointer with HasExcClause
...@@ -232,20 +232,23 @@ case class InstAtomicRMW(var ptr: Boolean, var ord: MemoryOrder, var op: AtomicR ...@@ -232,20 +232,23 @@ case class InstAtomicRMW(var ptr: Boolean, var ord: MemoryOrder, var op: AtomicR
case class InstFence(var ord: MemoryOrder) extends Instruction case class InstFence(var ord: MemoryOrder) extends Instruction
case class InstTrap(var retTy: Type, var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) extends AbstractTrap with HasExcClause case class InstTrap(var retTys: Seq[Type], var excClause