Commit e65b732f authored by Kunshan Wang's avatar Kunshan Wang

Implemented binop with flags.

parent 18eb5b94
This diff is collapsed.
...@@ -127,6 +127,7 @@ _top_level_structs = ["MuVM", "MuCtx", "MuIRBuilder"] ...@@ -127,6 +127,7 @@ _top_level_structs = ["MuVM", "MuCtx", "MuIRBuilder"]
_enums = [(typename, re.compile(regex)) for typename, regex in [ _enums = [(typename, re.compile(regex)) for typename, regex in [
("MuTrapHandlerResult", r'^MU_(THREAD|REBIND)'), ("MuTrapHandlerResult", r'^MU_(THREAD|REBIND)'),
("MuDestKind", r'^MU_DEST_'), ("MuDestKind", r'^MU_DEST_'),
("MuBinOpStatus", r'^MU_BOS_'),
("MuBinOptr", r'^MU_BINOP_'), ("MuBinOptr", r'^MU_BINOP_'),
("MuCmpOptr", r'^MU_CMP_'), ("MuCmpOptr", r'^MU_CMP_'),
("MuConvOptr", r'^MU_CONV_'), ("MuConvOptr", r'^MU_CONV_'),
......
...@@ -197,6 +197,7 @@ _special_converters = { ...@@ -197,6 +197,7 @@ _special_converters = {
"MuCString" : "readCString", "MuCString" : "readCString",
"MuMemOrd" : "toMemoryOrder", "MuMemOrd" : "toMemoryOrder",
"MuAtomicRMWOptr" : "toAtomicRMWOptr", "MuAtomicRMWOptr" : "toAtomicRMWOptr",
"MuBinOpStatus" : "toBinOpStatus",
"MuBinOptr" : "toBinOptr", "MuBinOptr" : "toBinOptr",
"MuCmpOptr" : "toCmpOptr", "MuCmpOptr" : "toCmpOptr",
"MuConvOptr" : "toConvOptr", "MuConvOptr" : "toConvOptr",
......
...@@ -35,6 +35,7 @@ _type_map = { ...@@ -35,6 +35,7 @@ _type_map = {
"MuBool" : "int<32>", "MuBool" : "int<32>",
"MuWPID" : "int<32>", "MuWPID" : "int<32>",
"MuArraySize" : "int<64>", "MuArraySize" : "int<64>",
"MuBinOpStatus" : "int<32>",
"MuBinOptr" : "int<32>", "MuBinOptr" : "int<32>",
"MuCmpOptr" : "int<32>", "MuCmpOptr" : "int<32>",
"MuConvOptr" : "int<32>", "MuConvOptr" : "int<32>",
......
...@@ -222,6 +222,7 @@ CMuArraySize = ctypes.c_uint64 ...@@ -222,6 +222,7 @@ CMuArraySize = ctypes.c_uint64
CMuWPID = ctypes.c_uint32 CMuWPID = ctypes.c_uint32
CMuFlag = ctypes.c_uint32 CMuFlag = ctypes.c_uint32
CMuTrapHandlerResult = CMuFlag CMuTrapHandlerResult = CMuFlag
CMuBinOpStatus = CMuFlag
CMuBinOptr = CMuFlag CMuBinOptr = CMuFlag
CMuCmpOptr = CMuFlag CMuCmpOptr = CMuFlag
CMuConvOptr = CMuFlag CMuConvOptr = CMuFlag
...@@ -428,42 +429,43 @@ common_instruction_opcodes = { ...@@ -428,42 +429,43 @@ common_instruction_opcodes = {
'@uvm.irbuilder.new_nsc_pass_values': 0x328, '@uvm.irbuilder.new_nsc_pass_values': 0x328,
'@uvm.irbuilder.new_nsc_throw_exc': 0x329, '@uvm.irbuilder.new_nsc_throw_exc': 0x329,
'@uvm.irbuilder.new_binop': 0x32a, '@uvm.irbuilder.new_binop': 0x32a,
'@uvm.irbuilder.new_cmp': 0x32b, '@uvm.irbuilder.new_binop_with_status': 0x32b,
'@uvm.irbuilder.new_conv': 0x32c, '@uvm.irbuilder.new_cmp': 0x32c,
'@uvm.irbuilder.new_select': 0x32d, '@uvm.irbuilder.new_conv': 0x32d,
'@uvm.irbuilder.new_branch': 0x32e, '@uvm.irbuilder.new_select': 0x32e,
'@uvm.irbuilder.new_branch2': 0x32f, '@uvm.irbuilder.new_branch': 0x32f,
'@uvm.irbuilder.new_switch': 0x330, '@uvm.irbuilder.new_branch2': 0x330,
'@uvm.irbuilder.new_call': 0x331, '@uvm.irbuilder.new_switch': 0x331,
'@uvm.irbuilder.new_tailcall': 0x332, '@uvm.irbuilder.new_call': 0x332,
'@uvm.irbuilder.new_ret': 0x333, '@uvm.irbuilder.new_tailcall': 0x333,
'@uvm.irbuilder.new_throw': 0x334, '@uvm.irbuilder.new_ret': 0x334,
'@uvm.irbuilder.new_extractvalue': 0x335, '@uvm.irbuilder.new_throw': 0x335,
'@uvm.irbuilder.new_insertvalue': 0x336, '@uvm.irbuilder.new_extractvalue': 0x336,
'@uvm.irbuilder.new_extractelement': 0x337, '@uvm.irbuilder.new_insertvalue': 0x337,
'@uvm.irbuilder.new_insertelement': 0x338, '@uvm.irbuilder.new_extractelement': 0x338,
'@uvm.irbuilder.new_shufflevector': 0x339, '@uvm.irbuilder.new_insertelement': 0x339,
'@uvm.irbuilder.new_new': 0x33a, '@uvm.irbuilder.new_shufflevector': 0x33a,
'@uvm.irbuilder.new_newhybrid': 0x33b, '@uvm.irbuilder.new_new': 0x33b,
'@uvm.irbuilder.new_alloca': 0x33c, '@uvm.irbuilder.new_newhybrid': 0x33c,
'@uvm.irbuilder.new_allocahybrid': 0x33d, '@uvm.irbuilder.new_alloca': 0x33d,
'@uvm.irbuilder.new_getiref': 0x33e, '@uvm.irbuilder.new_allocahybrid': 0x33e,
'@uvm.irbuilder.new_getfieldiref': 0x33f, '@uvm.irbuilder.new_getiref': 0x33f,
'@uvm.irbuilder.new_getelemiref': 0x340, '@uvm.irbuilder.new_getfieldiref': 0x340,
'@uvm.irbuilder.new_shiftiref': 0x341, '@uvm.irbuilder.new_getelemiref': 0x341,
'@uvm.irbuilder.new_getvarpartiref': 0x342, '@uvm.irbuilder.new_shiftiref': 0x342,
'@uvm.irbuilder.new_load': 0x343, '@uvm.irbuilder.new_getvarpartiref': 0x343,
'@uvm.irbuilder.new_store': 0x344, '@uvm.irbuilder.new_load': 0x344,
'@uvm.irbuilder.new_cmpxchg': 0x345, '@uvm.irbuilder.new_store': 0x345,
'@uvm.irbuilder.new_atomicrmw': 0x346, '@uvm.irbuilder.new_cmpxchg': 0x346,
'@uvm.irbuilder.new_fence': 0x347, '@uvm.irbuilder.new_atomicrmw': 0x347,
'@uvm.irbuilder.new_trap': 0x348, '@uvm.irbuilder.new_fence': 0x348,
'@uvm.irbuilder.new_watchpoint': 0x349, '@uvm.irbuilder.new_trap': 0x349,
'@uvm.irbuilder.new_wpbranch': 0x34a, '@uvm.irbuilder.new_watchpoint': 0x34a,
'@uvm.irbuilder.new_ccall': 0x34b, '@uvm.irbuilder.new_wpbranch': 0x34b,
'@uvm.irbuilder.new_newthread': 0x34c, '@uvm.irbuilder.new_ccall': 0x34c,
'@uvm.irbuilder.new_swapstack': 0x34d, '@uvm.irbuilder.new_newthread': 0x34d,
'@uvm.irbuilder.new_comminst': 0x34e, '@uvm.irbuilder.new_swapstack': 0x34e,
'@uvm.irbuilder.new_comminst': 0x34f,
} }
## GEN:END:CENUMS ## GEN:END:CENUMS
...@@ -1224,6 +1226,22 @@ class MuIRBuilder(_StructOfMethodsWrapper): ...@@ -1224,6 +1226,22 @@ class MuIRBuilder(_StructOfMethodsWrapper):
_actual_ntysvars = len(vars) _actual_ntysvars = len(vars)
return self.new_nsc_pass_values_(_actual_id, _actual_tys, _actual_vars, _actual_ntysvars) return self.new_nsc_pass_values_(_actual_id, _actual_tys, _actual_vars, _actual_ntysvars)
def new_binop_with_status(self, id, result_id, status_result_ids, optr, status_flags, ty, opnd1, opnd2, exc_clause):
_actual_id = id
_actual_result_id = result_id
_actual_status_result_ids_ty = CMuID * len(status_result_ids)
_actual_status_result_ids = _actual_status_result_ids_ty()
for _i,_v in enumerate(status_result_ids):
_actual_status_result_ids[_i] = _v
_actual_n_status_result_ids = len(status_result_ids)
_actual_optr = optr
_actual_status_flags = status_flags
_actual_ty = ty
_actual_opnd1 = opnd1
_actual_opnd2 = opnd2
_actual_exc_clause = 0 if exc_clause is None else exc_clause
return self.new_binop_with_status_(_actual_id, _actual_result_id, _actual_status_result_ids, _actual_n_status_result_ids, _actual_optr, _actual_status_flags, _actual_ty, _actual_opnd1, _actual_opnd2, _actual_exc_clause)
def new_switch(self, id, opnd_ty, opnd, default_dest, cases, dests): def new_switch(self, id, opnd_ty, opnd, default_dest, cases, dests):
_actual_id = id _actual_id = id
_actual_opnd_ty = opnd_ty _actual_opnd_ty = opnd_ty
...@@ -1644,6 +1662,7 @@ _initialize_methods(MuIRBuilder, [ ...@@ -1644,6 +1662,7 @@ _initialize_methods(MuIRBuilder, [
('new_nsc_pass_values_', None, [CMuID, ctypes.c_void_p, ctypes.c_void_p, CMuArraySize]), ('new_nsc_pass_values_', None, [CMuID, ctypes.c_void_p, ctypes.c_void_p, CMuArraySize]),
('new_nsc_throw_exc', None, [CMuID, CMuVarNode]), ('new_nsc_throw_exc', None, [CMuID, CMuVarNode]),
('new_binop', None, [CMuID, CMuID, CMuBinOptr, CMuTypeNode, CMuVarNode, CMuVarNode, CMuExcClause]), ('new_binop', None, [CMuID, CMuID, CMuBinOptr, CMuTypeNode, CMuVarNode, CMuVarNode, CMuExcClause]),
('new_binop_with_status_', None, [CMuID, CMuID, ctypes.c_void_p, CMuArraySize, CMuBinOptr, CMuBinOpStatus, CMuTypeNode, CMuVarNode, CMuVarNode, CMuExcClause]),
('new_cmp', None, [CMuID, CMuID, CMuCmpOptr, CMuTypeNode, CMuVarNode, CMuVarNode]), ('new_cmp', None, [CMuID, CMuID, CMuCmpOptr, CMuTypeNode, CMuVarNode, CMuVarNode]),
('new_conv', None, [CMuID, CMuID, CMuConvOptr, CMuTypeNode, CMuTypeNode, CMuVarNode]), ('new_conv', None, [CMuID, CMuID, CMuConvOptr, CMuTypeNode, CMuTypeNode, CMuVarNode]),
('new_select', None, [CMuID, CMuID, CMuTypeNode, CMuTypeNode, CMuVarNode, CMuVarNode, CMuVarNode]), ('new_select', None, [CMuID, CMuID, CMuTypeNode, CMuTypeNode, CMuVarNode, CMuVarNode, CMuVarNode]),
......
...@@ -140,7 +140,7 @@ inst ...@@ -140,7 +140,7 @@ inst
instBody instBody
// Integer/FP Arithmetic // Integer/FP Arithmetic
: binop '<' ty=type '>' op1=value op2=value excClause # InstBinOp : binop (flagList)? '<' ty=type '>' op1=value op2=value excClause # InstBinOp
// Integer/FP Comparison // Integer/FP Comparison
| cmpop '<' ty=type '>' op1=value op2=value # InstCmp | cmpop '<' ty=type '>' op1=value op2=value # InstCmp
......
...@@ -110,41 +110,42 @@ object CommInsts extends SimpleNamespace[CommInst] { ...@@ -110,41 +110,42 @@ object CommInsts extends SimpleNamespace[CommInst] {
commInst(0x328, "@uvm.irbuilder.new_nsc_pass_values") commInst(0x328, "@uvm.irbuilder.new_nsc_pass_values")
commInst(0x329, "@uvm.irbuilder.new_nsc_throw_exc") commInst(0x329, "@uvm.irbuilder.new_nsc_throw_exc")
commInst(0x32a, "@uvm.irbuilder.new_binop") commInst(0x32a, "@uvm.irbuilder.new_binop")
commInst(0x32b, "@uvm.irbuilder.new_cmp") commInst(0x32b, "@uvm.irbuilder.new_binop_with_status")
commInst(0x32c, "@uvm.irbuilder.new_conv") commInst(0x32c, "@uvm.irbuilder.new_cmp")
commInst(0x32d, "@uvm.irbuilder.new_select") commInst(0x32d, "@uvm.irbuilder.new_conv")
commInst(0x32e, "@uvm.irbuilder.new_branch") commInst(0x32e, "@uvm.irbuilder.new_select")
commInst(0x32f, "@uvm.irbuilder.new_branch2") commInst(0x32f, "@uvm.irbuilder.new_branch")
commInst(0x330, "@uvm.irbuilder.new_switch") commInst(0x330, "@uvm.irbuilder.new_branch2")
commInst(0x331, "@uvm.irbuilder.new_call") commInst(0x331, "@uvm.irbuilder.new_switch")
commInst(0x332, "@uvm.irbuilder.new_tailcall") commInst(0x332, "@uvm.irbuilder.new_call")
commInst(0x333, "@uvm.irbuilder.new_ret") commInst(0x333, "@uvm.irbuilder.new_tailcall")
commInst(0x334, "@uvm.irbuilder.new_throw") commInst(0x334, "@uvm.irbuilder.new_ret")
commInst(0x335, "@uvm.irbuilder.new_extractvalue") commInst(0x335, "@uvm.irbuilder.new_throw")
commInst(0x336, "@uvm.irbuilder.new_insertvalue") commInst(0x336, "@uvm.irbuilder.new_extractvalue")
commInst(0x337, "@uvm.irbuilder.new_extractelement") commInst(0x337, "@uvm.irbuilder.new_insertvalue")
commInst(0x338, "@uvm.irbuilder.new_insertelement") commInst(0x338, "@uvm.irbuilder.new_extractelement")
commInst(0x339, "@uvm.irbuilder.new_shufflevector") commInst(0x339, "@uvm.irbuilder.new_insertelement")
commInst(0x33a, "@uvm.irbuilder.new_new") commInst(0x33a, "@uvm.irbuilder.new_shufflevector")
commInst(0x33b, "@uvm.irbuilder.new_newhybrid") commInst(0x33b, "@uvm.irbuilder.new_new")
commInst(0x33c, "@uvm.irbuilder.new_alloca") commInst(0x33c, "@uvm.irbuilder.new_newhybrid")
commInst(0x33d, "@uvm.irbuilder.new_allocahybrid") commInst(0x33d, "@uvm.irbuilder.new_alloca")
commInst(0x33e, "@uvm.irbuilder.new_getiref") commInst(0x33e, "@uvm.irbuilder.new_allocahybrid")
commInst(0x33f, "@uvm.irbuilder.new_getfieldiref") commInst(0x33f, "@uvm.irbuilder.new_getiref")
commInst(0x340, "@uvm.irbuilder.new_getelemiref") commInst(0x340, "@uvm.irbuilder.new_getfieldiref")
commInst(0x341, "@uvm.irbuilder.new_shiftiref") commInst(0x341, "@uvm.irbuilder.new_getelemiref")
commInst(0x342, "@uvm.irbuilder.new_getvarpartiref") commInst(0x342, "@uvm.irbuilder.new_shiftiref")
commInst(0x343, "@uvm.irbuilder.new_load") commInst(0x343, "@uvm.irbuilder.new_getvarpartiref")
commInst(0x344, "@uvm.irbuilder.new_store") commInst(0x344, "@uvm.irbuilder.new_load")
commInst(0x345, "@uvm.irbuilder.new_cmpxchg") commInst(0x345, "@uvm.irbuilder.new_store")
commInst(0x346, "@uvm.irbuilder.new_atomicrmw") commInst(0x346, "@uvm.irbuilder.new_cmpxchg")
commInst(0x347, "@uvm.irbuilder.new_fence") commInst(0x347, "@uvm.irbuilder.new_atomicrmw")
commInst(0x348, "@uvm.irbuilder.new_trap") commInst(0x348, "@uvm.irbuilder.new_fence")
commInst(0x349, "@uvm.irbuilder.new_watchpoint") commInst(0x349, "@uvm.irbuilder.new_trap")
commInst(0x34a, "@uvm.irbuilder.new_wpbranch") commInst(0x34a, "@uvm.irbuilder.new_watchpoint")
commInst(0x34b, "@uvm.irbuilder.new_ccall") commInst(0x34b, "@uvm.irbuilder.new_wpbranch")
commInst(0x34c, "@uvm.irbuilder.new_newthread") commInst(0x34c, "@uvm.irbuilder.new_ccall")
commInst(0x34d, "@uvm.irbuilder.new_swapstack") commInst(0x34d, "@uvm.irbuilder.new_newthread")
commInst(0x34e, "@uvm.irbuilder.new_comminst") commInst(0x34e, "@uvm.irbuilder.new_swapstack")
commInst(0x34f, "@uvm.irbuilder.new_comminst")
/// GEN:END:IRBUILDER_COMMINSTS /// GEN:END:IRBUILDER_COMMINSTS
} }
...@@ -321,8 +321,8 @@ class BundleConstructor(idNameMap: Map[MuID, MuName], nodeList: Seq[IRBuilderNod ...@@ -321,8 +321,8 @@ class BundleConstructor(idNameMap: Map[MuID, MuName], nodeList: Seq[IRBuilderNod
} }
val muInst: Instruction = irInst match { val muInst: Instruction = irInst match {
case NodeBinOp(id, resultID, optr, ty, opnd1, opnd2, excClause) => case NodeBinOp(id, resultID, statusResultIDs, optr, flags, ty, opnd1, opnd2, excClause) =>
InstBinOp(optr, ty, opnd1, opnd2, null) --> resultID EXC excClause InstBinOp(optr, flags, ty, opnd1, opnd2, null) --> (Seq(resultID)++statusResultIDs) EXC excClause
case NodeCmp(id, resultID, optr, ty, opnd1, opnd2) => case NodeCmp(id, resultID, optr, ty, opnd1, opnd2) =>
InstCmp(optr, ty, opnd1, opnd2) --> resultID InstCmp(optr, ty, opnd1, opnd2) --> resultID
case NodeConv(id, resultID, optr, fromTy, toTy, opnd) => case NodeConv(id, resultID, optr, fromTy, toTy, opnd) =>
......
...@@ -100,6 +100,17 @@ class IRBuilder(val id: MuInternalID, ...@@ -100,6 +100,17 @@ class IRBuilder(val id: MuInternalID,
def genSym(): MuID = genSym(None) def genSym(): MuID = genSym(None)
def genSym(name: String): MuID = genSym(Some(name)) def genSym(name: String): MuID = genSym(Some(name))
// Special cases
def newBinOp(id: MuID, resultID: MuID, optr: BinOptr.Value, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode, excClause: Option[MuExcClause]): Unit = {
newBinOp(id, resultID, Seq(), optr, 0, ty, opnd1, opnd2, excClause)
}
def newBinOpWithStatus(id: MuID, resultID: MuID, statusResultIDs: Seq[MuID], optr: BinOptr.Value, flags: BinOpStatus, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode, excClause: Option[MuExcClause]): Unit = {
newBinOp(id, resultID, statusResultIDs, optr, flags, ty, opnd1, opnd2, excClause)
}
// The following functions are generated from irBuilderNodes.scala by /migrate_scripts/irbuildernodestoirbuildermethods.py // The following functions are generated from irBuilderNodes.scala by /migrate_scripts/irbuildernodestoirbuildermethods.py
// GEN:BEGIN:IRBUILDERNODE_CONSTRUCTORS // GEN:BEGIN:IRBUILDERNODE_CONSTRUCTORS
...@@ -255,8 +266,8 @@ class IRBuilder(val id: MuInternalID, ...@@ -255,8 +266,8 @@ class IRBuilder(val id: MuInternalID,
val _node = new NodeNscThrowExc(id, exc) val _node = new NodeNscThrowExc(id, exc)
onNewNodeCreated(_node) onNewNodeCreated(_node)
} }
def newBinOp(id: MuID, resultID: MuID, optr: BinOptr.Value, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode, excClause: Option[MuExcClause]): Unit = { def newBinOp(id: MuID, resultID: MuID, statusResultIDs: Seq[MuID], optr: BinOptr.Value, flags: BinOpStatus, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode, excClause: Option[MuExcClause]): Unit = {
val _node = new NodeBinOp(id, resultID, optr, ty, opnd1, opnd2, excClause) val _node = new NodeBinOp(id, resultID, statusResultIDs, optr, flags, ty, opnd1, opnd2, excClause)
onNewNodeCreated(_node) onNewNodeCreated(_node)
} }
def newCmp(id: MuID, resultID: MuID, optr: CmpOptr.Value, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode): Unit = { def newCmp(id: MuID, resultID: MuID, optr: CmpOptr.Value, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode): Unit = {
......
...@@ -111,7 +111,7 @@ case class NodeCscKillOld(id: MuID) extends IRCurStackClauseNode ...@@ -111,7 +111,7 @@ case class NodeCscKillOld(id: MuID) extends IRCurStackClauseNode
case class NodeNscPassValues(id: MuID, tys: Seq[MuTypeNode], vars: Seq[MuVarNode]) extends IRNewStackClauseNode case class NodeNscPassValues(id: MuID, tys: Seq[MuTypeNode], vars: Seq[MuVarNode]) extends IRNewStackClauseNode
case class NodeNscThrowExc(id: MuID, exc: MuVarNode) extends IRNewStackClauseNode case class NodeNscThrowExc(id: MuID, exc: MuVarNode) extends IRNewStackClauseNode
case class NodeBinOp(id: MuID, resultID: MuID, optr: BinOptr.Value, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode, excClause: Option[MuExcClause]) extends IRInstNode case class NodeBinOp(id: MuID, resultID: MuID, statusResultIDs: Seq[MuID], optr: BinOptr.Value, flags: BinOpStatus, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode, excClause: Option[MuExcClause]) extends IRInstNode
case class NodeCmp(id: MuID, resultID: MuID, optr: CmpOptr.Value, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode) extends IRInstNode case class NodeCmp(id: MuID, resultID: MuID, optr: CmpOptr.Value, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode) extends IRInstNode
case class NodeConv(id: MuID, resultID: MuID, optr: ConvOptr.Value, fromTy: MuTypeNode, toTy: MuTypeNode, opnd: MuVarNode) extends IRInstNode case class NodeConv(id: MuID, resultID: MuID, optr: ConvOptr.Value, fromTy: MuTypeNode, toTy: MuTypeNode, opnd: MuVarNode) extends IRInstNode
case class NodeSelect(id: MuID, resultID: MuID, condTy: MuTypeNode, opndTy: MuTypeNode, cond: MuVarNode, ifTrue: MuVarNode, ifFalse: MuVarNode) extends IRInstNode case class NodeSelect(id: MuID, resultID: MuID, condTy: MuTypeNode, opndTy: MuTypeNode, cond: MuVarNode, ifTrue: MuVarNode, ifFalse: MuVarNode) extends IRInstNode
......
...@@ -457,6 +457,31 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str ...@@ -457,6 +457,31 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
case a: CurStackKillOldContext => KillOld() case a: CurStackKillOldContext => KillOld()
} }
} }
def resBinOpStatus(flagList: FlagListContext): BinOpStatus = {
if (flagList == null) {
return 0
}
var status = 0
val texts = flagList.flag().map(_.getText)
val ordered = Seq("#N", "#Z", "#C", "#V").filter(t => texts.contains(t))
if(ordered != texts ) {
throw new TextIRParsingException(inCtx(flagList, "Flags must appear in the order of #N #Z #C #V"))
}
for (text <- texts) {
val nextStatus = text match {
case "#N" => BOS_N
case "#Z" => BOS_Z
case "#C" => BOS_C
case "#V" => BOS_V
case _ => throw new TextIRParsingException(inCtx(flagList, "Unexpected flag %s".format()))
}
status = status | nextStatus
}
status
}
// Make instruction // Make instruction
...@@ -464,7 +489,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str ...@@ -464,7 +489,7 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
val inst: Instruction = instDef.instBody match { val inst: Instruction = instDef.instBody match {
case ii: InstBinOpContext => case ii: InstBinOpContext =>
InstBinOp(BinOptr.withName(ii.binop.getText), ii.`type`, null, null, null).later(phase4) { i => InstBinOp(BinOptr.withName(ii.binop.getText), resBinOpStatus(ii.flagList()), ii.`type`, null, null, null).later(phase4) { i =>
i.op1 = ii.op1; i.op2 = ii.op2; i.excClause = ii.excClause i.op1 = ii.op1; i.op2 = ii.op2; i.excClause = ii.excClause
} }
case ii: InstCmpContext => case ii: InstCmpContext =>
......
...@@ -128,7 +128,7 @@ abstract class AbstractBundleSerializer(bundle: Bundle) { ...@@ -128,7 +128,7 @@ abstract class AbstractBundleSerializer(bundle: Bundle) {
implicit val bs = this implicit val bs = this
val body = inst match { val body = inst match {
case InstBinOp(op, opndTy, op1, op2, excClause) => s"${op.s} <${opndTy.n}> ${op1.n} ${op2.n} ${excClause.e}" case InstBinOp(op, flags, opndTy, op1, op2, excClause) => s"${op.s} ${flags.flags} <${opndTy.n}> ${op1.n} ${op2.n} ${excClause.e}"
case InstCmp(op, opndTy, op1, op2) => s"${op.s} <${opndTy.n}> ${op1.n} ${op2.n}" case InstCmp(op, opndTy, op1, op2) => s"${op.s} <${opndTy.n}> ${op1.n} ${op2.n}"
case InstConv(op, fromTy, toTy, opnd) => s"${op.s} <${fromTy.n} ${toTy.n}> ${opnd.n}" case InstConv(op, fromTy, toTy, opnd) => s"${op.s} <${fromTy.n} ${toTy.n}> ${opnd.n}"
case InstSelect(condTy, opndTy, cond, ifTrue, ifFalse) => s"SELECT <${condTy.n} ${opndTy.n}> ${cond.n} ${ifTrue.n} ${ifFalse.n}" case InstSelect(condTy, opndTy, cond, ifTrue, ifFalse) => s"SELECT <${condTy.n} ${opndTy.n}> ${cond.n} ${ifTrue.n} ${ifFalse.n}"
...@@ -246,6 +246,14 @@ object AbstractBundleSerializer { ...@@ -246,6 +246,14 @@ object AbstractBundleSerializer {
def p: String = if (value) "PTR" else "" def p: String = if (value) "PTR" else ""
def w: String = if (value) "WEAK" else "" def w: String = if (value) "WEAK" else ""
} }
implicit class MagicalBinOpStatus(val thing: BinOpStatus) extends AnyVal {
def flags: String = if (thing==0) "" else {
val nzcv = Seq((BOS_N, "N"), (BOS_Z, "Z"), (BOS_C, "C"), (BOS_V, "V")).flatMap { case (bit, txt) =>
if ((thing & bit) == 0) None else Some("#"+txt)
}
"[" + nzcv.mkString(" ") + "]"
}
}
} }
/** /**
......
...@@ -258,7 +258,7 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor ...@@ -258,7 +258,7 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
} }
private def visitInstruction(inst: Instruction): Unit = inst match { private def visitInstruction(inst: Instruction): Unit = inst match {
case InstBinOp(op, opndTy, op1, op2, excClause) => tls += opndTy ?= op1 ?= op2 ??= excClause case InstBinOp(op, flags, opndTy, op1, op2, excClause) => tls += opndTy ?= op1 ?= op2 ??= excClause
case InstCmp(op, opndTy, op1, op2) => tls += opndTy ?= op1 ?= op2 case InstCmp(op, opndTy, op1, op2) => tls += opndTy ?= op1 ?= op2
case InstConv(op, fromTy, toTy, opnd) => tls += fromTy += toTy ?= opnd case InstConv(op, fromTy, toTy, opnd) => tls += fromTy += toTy ?= opnd
case InstSelect(condTy, opndTy, cond, ifTrue, ifFalse) => tls += condTy += opndTy ?= cond ?= ifTrue ?= ifFalse case InstSelect(condTy, opndTy, cond, ifTrue, ifFalse) => tls += condTy += opndTy ?= cond ?= ifTrue ?= ifFalse
......
...@@ -102,7 +102,7 @@ object TypeInferer { ...@@ -102,7 +102,7 @@ object TypeInferer {
} }
def inferInstResultTypes(inst: Instruction): Seq[Type] = inst match { def inferInstResultTypes(inst: Instruction): Seq[Type] = inst match {
case i: InstBinOp => Seq(i.opndTy) case i: InstBinOp => Seq(i.opndTy) ++ Seq.fill(BinOpStatus.numOfFlags(i.flags))(I1)
case i: InstCmp => i.opndTy match { case i: InstCmp => i.opndTy match {
case TypeVector(_, l) => Seq(vecOf(I1, l)) case TypeVector(_, l) => Seq(vecOf(I1, l))
case _ => Seq(I1) case _ => Seq(I1)
...@@ -241,6 +241,7 @@ object TypeInferer { ...@@ -241,6 +241,7 @@ object TypeInferer {
case "@uvm.irbuilder.new_nsc_pass_values" => Seq() case "@uvm.irbuilder.new_nsc_pass_values" => Seq()
case "@uvm.irbuilder.new_nsc_throw_exc" => Seq() case "@uvm.irbuilder.new_nsc_throw_exc" => Seq()
case "@uvm.irbuilder.new_binop" => Seq() case "@uvm.irbuilder.new_binop" => Seq()
case "@uvm.irbuilder.new_binop_with_status" => Seq()
case "@uvm.irbuilder.new_cmp" => Seq() case "@uvm.irbuilder.new_cmp" => Seq()
case "@uvm.irbuilder.new_conv" => Seq() case "@uvm.irbuilder.new_conv" => Seq()
case "@uvm.irbuilder.new_select" => Seq() case "@uvm.irbuilder.new_select" => Seq()
......
...@@ -421,6 +421,22 @@ trait IRBuilderCommInstExecutor extends InterpreterActions with ObjectPinner { ...@@ -421,6 +421,22 @@ trait IRBuilderCommInstExecutor extends InterpreterActions with ObjectPinner {
val _rv = b.newBinOp(id, result_id, optr, ty, opnd1, opnd2, exc_clause) val _rv = b.newBinOp(id, result_id, optr, ty, opnd1, opnd2, exc_clause)
continueNormally() continueNormally()
} }
case "@uvm.irbuilder.new_binop_with_status" => {
val b = argList(0).asIRBuilder.getOrElse(throw new UvmNullGenRefException("CommInst arg %b must not be null"))
val id = argList(1).asInt32.toInt
val result_id = argList(2).asInt32.toInt
val status_result_ids = argList(3).asIRef
val n_status_result_ids = argList(4).asInt64.toLong
val optr = argList(5).asInt32.toInt
val status_flags = argList(6).asInt32.toInt
val ty = argList(7).asInt32.toInt
val opnd1 = argList(8).asInt32.toInt
val opnd2 = argList(9).asInt32.toInt
val exc_clause = argList(10).asInt32.toInt.asOptionalID
val _ary_status_result_ids = loadInt32Array(status_result_ids, n_status_result_ids)
val _rv = b.newBinOpWithStatus(id, result_id, _ary_status_result_ids, optr, status_flags, ty, opnd1, opnd2, exc_clause)
continueNormally()
}
case "@uvm.irbuilder.new_cmp" => { case "@uvm.irbuilder.new_cmp" => {
val b = argList(0).asIRBuilder.getOrElse(throw new UvmNullGenRefException("CommInst arg %b must not be null")) val b = argList(0).asIRBuilder.getOrElse(throw new UvmNullGenRefException("CommInst arg %b must not be null"))
val id = argList(1).asInt32.toInt val id = argList(1).asInt32.toInt
......
...@@ -26,10 +26,10 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -26,10 +26,10 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
microVM.stats.onInstExec(statInstName) microVM.stats.onInstExec(statInstName)
curInst match { curInst match {
case i @ InstBinOp(op, opndTy, op1, op2, excClause) => { case i @ InstBinOp(op, flags, opndTy, op1, op2, excClause) => {
val statOpName = op.toString() val statOpName = op.toString()
microVM.stats.onInstExec(statInstName + "/" + statOpName) microVM.stats.onInstExec(statInstName + "/" + statOpName)
def doScalar(scalarTy: Type, b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = { def doScalar(scalarTy: Type, b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = {
scalarTy match { scalarTy match {
case TypeInt(l) => br.asIntRaw = PrimOpHelpers.intBinOp(op, l, b1.asIntRaw, b2.asIntRaw, ctx) case TypeInt(l) => br.asIntRaw = PrimOpHelpers.intBinOp(op, l, b1.asIntRaw, b2.asIntRaw, ctx)
...@@ -38,6 +38,22 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -38,6 +38,22 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case _ => throw new UvmRuntimeException(ctx + "BinOp not suitable for type %s".format(scalarTy)) case _ => throw new UvmRuntimeException(ctx + "BinOp not suitable for type %s".format(scalarTy))
} }
} }
def doFlags(): Unit = {
val (n, z, c, v) = opndTy match {
case TypeInt(l) => PrimOpHelpers.intBinOpFlags(op, l, op1.asIntRaw, op2.asIntRaw, results(0).asIntRaw, ctx)
case _ => throw new UvmRuntimeException(ctx + "BinOp flags are only applicable to scalar integer types. Actual type: %s".format(opndTy))
}
var nextResultIndex = 1
for ((bit, res) <- BinOpStatus.ALL_FLAGS zip Seq(n,z,c,v)) {
if ((flags & bit) != 0) {
val resultIndex = nextResultIndex
nextResultIndex += 1
results(resultIndex).asBoolean = res
}
}
}
try { try {
opndTy match { opndTy match {
...@@ -46,7 +62,12 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -46,7 +62,12 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
doScalar(scalarTy, b1, b2, br) doScalar(scalarTy, b1, b2, br)
} }
} }
case scalarTy => doScalar(scalarTy, op1, op2, results(0)) case scalarTy => {
doScalar(scalarTy, op1, op2, results(0))
if (flags != 0) {
doFlags()
}
}
} }
continueNormally() continueNormally()
} catch { } catch {
......
...@@ -59,7 +59,7 @@ class InterpreterThread(val id: MuInternalID, initialStack: InterpreterStack, in ...@@ -59,7 +59,7 @@ class InterpreterThread(val id: MuInternalID, initialStack: InterpreterStack, in
* <p> * <p>
* Every InterpreterThread holds an ErrnoBox. * Every InterpreterThread holds an ErrnoBox.
* Before every CCALL, set errno to savedLastError; after every CCALL, set savedLastError to errno. In this way, * Before every CCALL, set errno to savedLastError; after every CCALL, set savedLastError to errno. In this way,
* native programs see a "continuum" where the errno is never observed to change inside the micro VM. * native programs see a "continuum" where the errno is never observed to change inside the micro VM.
*/ */
class ErrnoBox { class ErrnoBox {
var errno: Int = 0 var errno: Int = 0
...@@ -89,7 +89,7 @@ trait InterpreterThreadState { ...@@ -89,7 +89,7 @@ trait InterpreterThreadState {
/** Thread-local object reference. */ /** Thread-local object reference. */
val threadLocal = BoxRef(0L) val threadLocal = BoxRef(0L)
/** The per-thread errno. */ /** The per-thread errno. */
val errnoBox = new ErrnoBox val errnoBox = new ErrnoBox
...@@ -327,7 +327,7 @@ trait InterpreterActions extends InterpreterThreadState { ...@@ -327,7 +327,7 @@ trait InterpreterActions extends InterpreterThreadState {
val f = s.top val f = s.top
val (newFrame, dc) = unwindUntilCatchable(f) val (newFrame, dc) = unwindUntilCatchable(f)
s.unwindTo(newFrame) s.unwindTo(newFrame)
microVM.stats.exceptionsThrown += 1 microVM.stats.exceptionsThrown += 1
branchTo(dc, Some(exc)) branchTo(dc, Some(exc))
...@@ -508,62 +508,6 @@ trait InterpreterActions extends InterpreterThreadState { ...@@ -508,62 +508,6 @@ trait InterpreterActions extends InterpreterThreadState {
} }
} }
import MagicalBox.MagicalBox
implicit protected def ssaVariableToValueBox(v: SSAVariable): ValueBox = boxOf(v) implicit protected def ssaVariableToValueBox(v: SSAVariable): ValueBox = boxOf(v)
implicit protected def ssaVariableToMagicalBox(v: SSAVariable): MagicalBox = new MagicalBox(boxOf(v)) implicit protected def ssaVariableToMagicalBox(v: SSAVariable): MagicalBox = new MagicalBox(boxOf(v))
implicit protected def boxToMagicalBox(b: ValueBox): MagicalBox = new MagicalBox(b)
}
object MagicalBox {
implicit class MagicalBox(val box: ValueBox) extends AnyVal {
def asIntRaw: BigInt = box.asInstanceOf[BoxInt].value
def asInt32: BigInt = OpHelper.prepareUnsigned(box.asIntRaw, 32)
def asInt64: BigInt = OpHelper.prepareUnsigned(box.asIntRaw, 64)
def asUInt32: BigInt = OpHelper.prepareUnsigned(box.asIntRaw, 32)
def asUInt64: BigInt = OpHelper.prepareUnsigned(box.asIntRaw, 64)
def asSInt32: BigInt = OpHelper.prepareSigned(box.asIntRaw, 32)
def asSInt64: BigInt = OpHelper.prepareSigned(box.asIntRaw, 64)
def asInt1: BigInt = OpHelper.prepareUnsigned(box.asIntRaw, 1)
def asBoolean: Boolean = OpHelper.prepareUnsigned(box.asIntRaw, 1) == 1
def asFloat: Float = box.asInstanceOf[BoxFloat].value
def asDouble: Double = box.asInstanceOf[BoxDouble].value
def asPtr: Word = box.asInstanceOf[BoxPointer].addr
def asSeq: Seq[ValueBox] = box.asInstanceOf[BoxSeq].values
def asRef: Word = box.asInstanceOf[BoxRef].objRef
def asIRef: (Word, Word) = box.asInstanceOf[BoxIRef].oo
def asIRefLoc: Word = box.asInstanceOf[BoxIRef].addr
def asTR64Raw: Long = box.asInstanceOf[BoxTagRef64].raw
def asFunc: Option[Function] = box.asInstanceOf[BoxFunc].obj
def asThread: Option[InterpreterThread] = box.asInstanceOf[BoxThread].obj
def asStack: Option[InterpreterStack] = box.asInstanceOf[BoxStack].obj
def asFrameCursor: Option[FrameCursor] = box.asInstanceOf[BoxFrameCursor].obj
def asIRBuilder: Option[IRBuilder] = box.asInstanceOf[BoxIRBuilder].obj
def asIntRaw_=(v: BigInt): Unit = box.asInstanceOf[BoxInt].value = v
def asInt1_=(v: BigInt): Unit = box.setInt(v, 1)
def asInt32_=(v: BigInt): Unit = box.setInt(v, 32)
def asInt64_=(v: BigInt): Unit = box.setInt(v, 64)
def asUInt32_=(v: BigInt): Unit = box.setInt(v, 32)
def asUInt64_=(v: BigInt): Unit = box.setInt(v, 64)
def asSInt32_=(v: BigInt): Unit = box.setInt(v, 32)
def asSInt64_=(v: BigInt): Unit = box.setInt(v, 64)
def asBoolean_=(v: Boolean): Unit = box.setInt(if (v) 1 else 0, 1)
def asFloat_=(v: Float): Unit = box.asInstanceOf[BoxFloat].value = v
def asDouble_=(v: Double): Unit = box.asInstanceOf[BoxDouble].value = v
def asPtr_=(v: Word): Unit = box.asInstanceOf[BoxPointer].addr = v
def asSeq_=(vs: Seq[ValueBox]): Unit = { for ((dst, src) <- box.asSeq zip vs) { dst copyFrom src } }
def asRef_=(v: Word): Unit = box.asInstanceOf[BoxRef].objRef = v
def asIRef_=(oo: (Word, Word)): Unit = box.asInstanceOf[BoxIRef].oo = oo
def asTR64Raw_=(v: Long): Unit = box.asInstanceOf[BoxTagRef64].raw = v