Ver código fonte

Start of SIMD support

Brian Fiete 5 anos atrás
pai
commit
64b62c09be

+ 9 - 0
BeefLibs/corlib/src/Attribute.bf

@@ -309,6 +309,15 @@ namespace System
 
 	}
 
+	[AttributeUsage(.Struct)]
+	public struct UnderlyingArrayAttribute : Attribute
+	{
+		public this(Type t, int size, bool isVector)
+		{
+
+		}
+	}
+
 	[AttributeUsage(.Field | .Method /*2*/)]
 	public struct NoShowAttribute : Attribute
 	{

+ 14 - 0
BeefLibs/corlib/src/Numerics/Bool4.bf

@@ -0,0 +1,14 @@
+namespace System.Numerics
+{
+	[UnderlyingArray(typeof(bool), 4, true)]
+	struct bool4
+	{
+		public bool x;
+		public bool y;
+		public bool z;
+		public bool w;
+
+		[Intrinsic("and")]
+		public static extern bool4 operator&(bool4 lhs, bool4 rhs);
+	}
+}

+ 89 - 0
BeefLibs/corlib/src/Numerics/Float4.bf

@@ -0,0 +1,89 @@
+namespace System.Numerics
+{
+	[UnderlyingArray(typeof(float), 4, true)]
+	struct float4
+	{
+		public float x;
+		public float y;
+		public float z;
+		public float w;
+
+		public this()
+		{
+			this = default;
+		}
+
+		public this(float x, float y, float z, float w)
+		{
+			this.x = x;
+			this.y = y;
+			this.z = z;
+			this.w = w;
+		}
+
+		public extern float4 wzyx { [Intrinsic("shuffle3210")] get; [Intrinsic("shuffle3210")] set; }
+
+		[Intrinsic("add")]
+		public static extern float4 operator+(float4 lhs, float4 rhs);
+		[Intrinsic("add"), Commutable]
+		public static extern float4 operator+(float4 lhs, float rhs);
+		[Intrinsic("add")]
+		public static extern float4 operator++(float4 lhs);
+
+		[Intrinsic("sub")]
+		public static extern float4 operator-(float4 lhs, float4 rhs);
+		[Intrinsic("sub"), Commutable]
+		public static extern float4 operator-(float4 lhs, float rhs);
+		[Intrinsic("sub")]
+		public static extern float4 operator--(float4 lhs);
+
+		[Intrinsic("mul")]
+		public static extern float4 operator*(float4 lhs, float4 rhs);
+		[Intrinsic("mul"), Commutable]
+		public static extern float4 operator*(float4 lhs, float rhs);
+
+		[Intrinsic("div")]
+		public static extern float4 operator/(float4 lhs, float4 rhs);
+		[Intrinsic("div")]
+		public static extern float4 operator/(float4 lhs, float rhs);
+		[Intrinsic("div")]
+		public static extern float4 operator/(float lhs, float4 rhs);
+
+		[Intrinsic("mod")]
+		public static extern float4 operator%(float4 lhs, float4 rhs);
+		[Intrinsic("mod")]
+		public static extern float4 operator%(float4 lhs, float rhs);
+		[Intrinsic("mod")]
+		public static extern float4 operator%(float lhs, float4 rhs);
+
+		[Intrinsic("eq")]
+		public static extern bool4 operator==(float4 lhs, float4 rhs);
+		[Intrinsic("eq"), Commutable]
+		public static extern bool4 operator==(float4 lhs, float rhs);
+
+		[Intrinsic("neq")]
+		public static extern bool4 operator!=(float4 lhs, float4 rhs);
+		[Intrinsic("neq"), Commutable]
+		public static extern bool4 operator!=(float4 lhs, float rhs);
+		
+		[Intrinsic("lt")]
+		public static extern bool4 operator<(float4 lhs, float4 rhs);
+		[Intrinsic("lt")]
+		public static extern bool4 operator<(float4 lhs, float rhs);
+
+		[Intrinsic("lte")]
+		public static extern bool4 operator<=(float4 lhs, float4 rhs);
+		[Intrinsic("lte")]
+		public static extern bool4 operator<=(float4 lhs, float rhs);
+
+		[Intrinsic("gt")]
+		public static extern bool4 operator>(float4 lhs, float4 rhs);
+		[Intrinsic("gt")]
+		public static extern bool4 operator>(float4 lhs, float rhs);
+
+		[Intrinsic("gte")]
+		public static extern bool4 operator>=(float4 lhs, float4 rhs);
+		[Intrinsic("gte")]
+		public static extern bool4 operator>=(float4 lhs, float rhs);
+	}
+}

+ 1 - 1
BeefLibs/corlib/src/SizedArray.bf

@@ -3,7 +3,7 @@ namespace System
 	[AlwaysInclude]
 	struct SizedArray<T, CSize> where CSize : const int
 	{
-		T[CSize] mVal;
+		protected T[CSize] mVal;
 
 		public int Count
 		{

+ 9 - 0
IDE/mintest/minlib/src/System/Attribute.bf

@@ -309,6 +309,15 @@ namespace System
 
 	}
 
+	[AttributeUsage(.Struct)]
+	public struct UnderlyingArrayAttribute : Attribute
+	{
+		public this(Type t, int size, bool isVector)
+		{
+
+		}
+	}
+
 	[AttributeUsage(.Field | .Method /*2*/)]
 	public struct NoShowAttribute : Attribute
 	{

+ 2 - 3
IDE/mintest/minlib/src/System/Object.bf

@@ -323,9 +323,8 @@ namespace System
     struct Int64 : int64
     {
         public const int64 MaxValue = 0x7FFFFFFFFFFFFFFFL;
-        //public const long MinValue = -0x8000000000000000L;
-        public const int64 MinValue = -0x7FFFFFFFFFFFFFFFL; //TODO: Should be one lower!
-
+        public const int64 MinValue = -0x8000000000000000L;
+        
 		public override void ToString(String strBuffer)
 		{
 		    // Dumb, make better.

+ 4 - 4
IDE/src/Commands.bf

@@ -214,7 +214,7 @@ namespace IDE
 			Add("Match Brace", new => gApp.Cmd_MatchBrace);
 			Add("Navigate Backwards", new => gApp.[Friend]NavigateBackwards);
 			Add("Navigate Forwards", new => gApp.[Friend]NavigateForwards);
-			Add("New Debug Session", new => gApp.[Friend]Cmd_NewDebugSession);
+			Add("New Debug Session", new => gApp.Cmd_NewDebugSession);
 			Add("New File", new => gApp.Cmd_NewFile);
 			Add("New Project", new => gApp.Cmd_NewProject);
 			Add("New Workspace", new => gApp.Cmd_NewWorkspace);
@@ -257,8 +257,8 @@ namespace IDE
 			Add("Show Class View", new => gApp.ShowClassViewPanel);
 			Add("Show Current", new => gApp.Cmd_ShowCurrent);
 			Add("Show Diagnostics", new => gApp.ShowDiagnostics);
-			Add("Show Disassembly", new => gApp.[Friend]ShowDisassemblyAtStack);
-			Add("Show Errors", new => gApp.[Friend]ShowErrors);
+			Add("Show Disassembly", new => gApp.ShowDisassemblyAtStack);
+			Add("Show Errors", new => gApp.ShowErrors);
 			Add("Show Error Next", new => gApp.ShowErrorNext);
 			Add("Show File Externally", new => gApp.Cmd_ShowFileExternally);
 			Add("Show Find Results", new => gApp.ShowFindResults);
@@ -272,7 +272,7 @@ namespace IDE
 			Add("Show Threads", new => gApp.ShowThreads);
 			Add("Show Watches", new => gApp.ShowWatches);
 			Add("Show Workspace Explorer", new => gApp.ShowWorkspacePanel);
-			Add("Start Debugging", new => gApp.[Friend]RunWithCompiling);
+			Add("Start Debugging", new => gApp.RunWithCompiling);
 			Add("Start Without Debugging", new => gApp.[Friend]RunWithoutDebugging);
 			Add("Start Without Compiling", new => gApp.[Friend]RunWithoutCompiling);
 			Add("Step Into", new => gApp.[Friend]StepInto);

+ 3 - 3
IDE/src/ui/BuildPropertiesDialog.bf

@@ -91,9 +91,9 @@ namespace IDE.ui
 							label.AppendF(" ({0})", platformNames[0]);
 					}
 
-					let (category, propEntry) = mDialog.[Friend]AddPropertiesItem(root, label, "mFilter");
-					mDialog.[Friend]SetupDistinctBuildOptions(propEntry);
-					mDialog.[Friend]AddDistinctBuildOptions(category, -1, true);
+					let (category, propEntry) = mDialog.AddPropertiesItem(root, label, "mFilter");
+					mDialog.SetupDistinctBuildOptions(propEntry);
+					mDialog.AddDistinctBuildOptions(category, -1, true);
 
 					delete typeOptionsEntry;
 				}

+ 29 - 0
IDEHelper/Backend/BeContext.cpp

@@ -56,6 +56,15 @@ BeType* BeContext::GetPrimitiveType(BeTypeCode typeCode)
 	case BeTypeCode_Double:
 		primType->mSize = primType->mAlign = 8;
 		break;
+	case BeTypeCode_M128:
+		primType->mSize = primType->mAlign = 16;
+		break;
+	case BeTypeCode_M256:
+		primType->mSize = primType->mAlign = 32;
+		break;
+	case BeTypeCode_M512:
+		primType->mSize = primType->mAlign = 64;
+		break;
 	}
 	mPrimitiveTypes[(int)typeCode] = primType;
 	return primType;
@@ -152,6 +161,18 @@ BeSizedArrayType* BeContext::CreateSizedArrayType(BeType* type, int length)
 	return arrayType;
 }
 
+BeVectorType* BeContext::CreateVectorType(BeType* type, int length)
+{
+	auto arrayType = mTypes.Alloc<BeVectorType>();
+	arrayType->mContext = this;
+	arrayType->mTypeCode = BeTypeCode_Vector;
+	arrayType->mElementType = type;
+	arrayType->mLength = length;
+	arrayType->mSize = type->mSize * length;
+	arrayType->mAlign = type->mAlign;
+	return arrayType;
+}
+
 BeFunctionType* BeContext::CreateFunctionType(BeType* returnType, const SizedArrayImpl<BeType*>& paramTypes, bool isVarArg)
 {
 	auto funcType = mTypes.Alloc<BeFunctionType>();
@@ -196,6 +217,14 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
 			if (lhsSizedArray->mLength != rhsSizedArray->mLength)
 				return false;
 			return AreTypesEqual(lhsSizedArray->mElementType, rhsSizedArray->mElementType);
+		}	
+	case BeTypeCode_Vector:
+		{
+			auto lhsSizedArray = (BeVectorType*)lhs;
+			auto rhsSizedArray = (BeVectorType*)rhs;
+			if (lhsSizedArray->mLength != rhsSizedArray->mLength)
+				return false;
+			return AreTypesEqual(lhsSizedArray->mElementType, rhsSizedArray->mElementType);
 		}
 	}
 	return false;

+ 35 - 0
IDEHelper/Backend/BeContext.h

@@ -20,10 +20,14 @@ enum BeTypeCode
 	BeTypeCode_Int64,
 	BeTypeCode_Float,
 	BeTypeCode_Double,
+	BeTypeCode_M128,
+	BeTypeCode_M256,
+	BeTypeCode_M512,
 	BeTypeCode_Struct,
 	BeTypeCode_Function,
 	BeTypeCode_Pointer,
 	BeTypeCode_SizedArray,
+	BeTypeCode_Vector,
 	BeTypeCode_CmpResult, // Psuedo
 
 	BeTypeCode_COUNT
@@ -122,7 +126,22 @@ public:
 		return (mTypeCode == BeTypeCode_SizedArray);
 	}
 
+	bool IsVector()
+	{
+		return (mTypeCode == BeTypeCode_Vector) || (mTypeCode == BeTypeCode_M128) || (mTypeCode == BeTypeCode_M256) || (mTypeCode == BeTypeCode_M512);
+	}
+
+	bool IsExplicitVectorType()
+	{
+		return (mTypeCode == BeTypeCode_Vector);
+	}
+
 	bool IsComposite()
+	{
+		return (mTypeCode == BeTypeCode_Struct) || (mTypeCode == BeTypeCode_SizedArray) || (mTypeCode == BeTypeCode_Vector) || (mTypeCode == BeTypeCode_M128) || (mTypeCode == BeTypeCode_M256) || (mTypeCode == BeTypeCode_M512);
+	}
+
+	bool IsNonVectorComposite()
 	{
 		return (mTypeCode == BeTypeCode_Struct) || (mTypeCode == BeTypeCode_SizedArray);
 	}
@@ -191,6 +210,21 @@ public:
 	}
 };
 
+class BeVectorType : public BeType
+{
+public:
+	BeContext* mContext;
+	BeType* mElementType;
+	int mLength;
+
+	virtual void HashContent(BeHashContext& hashCtx) override
+	{
+		hashCtx.Mixin(BeTypeCode_Vector);
+		hashCtx.Mixin(mLength);
+		mElementType->HashReference(hashCtx);
+	}
+};
+
 class BeFunctionTypeParam
 {
 public:
@@ -239,6 +273,7 @@ public:
 	BePointerType* GetPointerTo(BeType* beType);
 	void SetStructBody(BeStructType* structType, const SizedArrayImpl<BeType*>& types, bool packed);
 	BeSizedArrayType* CreateSizedArrayType(BeType* type, int length);
+	BeVectorType* CreateVectorType(BeType* type, int length);
 	BeFunctionType* CreateFunctionType(BeType* returnType, const SizedArrayImpl<BeType*>& paramTypes, bool isVarArg);
 
 	bool AreTypesEqual(BeType* lhs, BeType* rhs);

+ 17 - 39
IDEHelper/Backend/BeIRCodeGen.cpp

@@ -1015,7 +1015,10 @@ void BeIRCodeGen::HandleNextCmd()
 		{
 			CMD_PARAM(int, typeId);
 			CMD_PARAM(BeType*, type);						
-			GetTypeEntry(typeId).mBeType = type;
+			auto& typeEntry = GetTypeEntry(typeId);
+			typeEntry.mBeType = type;
+			if (typeEntry.mInstBeType == NULL)
+				typeEntry.mInstBeType = type;
 		}
 		break;
 	case BfIRCmd_SetInstType:
@@ -1100,6 +1103,13 @@ void BeIRCodeGen::HandleNextCmd()
 			SetResult(curId, mBeContext->CreateSizedArrayType(elementType, length));
 		}
 		break;	
+	case BfIRCmd_GetVectorType:
+		{
+			CMD_PARAM(BeType*, elementType);
+			CMD_PARAM(int, length);
+			SetResult(curId, mBeContext->CreateVectorType(elementType, length));
+		}
+		break;	
 	case BfIRCmd_CreateConstStruct:
 		{
 			CMD_PARAM(BeType*, type);
@@ -2050,49 +2060,14 @@ void BeIRCodeGen::HandleNextCmd()
 		break;
 	case BfIRCmd_GetIntrinsic:
 		{			
+			CMD_PARAM(String, intrinName);
 			CMD_PARAM(int, intrinId);
 			CMD_PARAM(BeType*, returnType);
 			CMD_PARAM(CmdParamVec<BeType*>, paramTypes);
 
 			auto intrin = mBeModule->mAlloc.Alloc<BeIntrinsic>();
 			intrin->mKind = (BfIRIntrinsic)intrinId;
-
-			switch (intrin->mKind)
-			{			
-			case BfIRIntrinsic_Abs:
-				intrin->mReturnType = paramTypes[0];
-				break;
-			case BfIRIntrinsic_AtomicAdd:
-			case BfIRIntrinsic_AtomicAnd:
-			case BfIRIntrinsic_AtomicCmpXChg:
-			case BfIRIntrinsic_AtomicLoad:
-			case BfIRIntrinsic_AtomicMax:
-			case BfIRIntrinsic_AtomicMin:
-			case BfIRIntrinsic_AtomicNAnd:
-			case BfIRIntrinsic_AtomicOr:			
-			case BfIRIntrinsic_AtomicSub:
-			case BfIRIntrinsic_AtomicUMax:
-			case BfIRIntrinsic_AtomicUMin:
-			case BfIRIntrinsic_AtomicXChg:			
-			case BfIRIntrinsic_AtomicXor:
-				if (!paramTypes.IsEmpty())
-				{
-					BF_ASSERT(paramTypes[0]->IsPointer());
-					if (paramTypes[0]->IsPointer())
-						intrin->mReturnType = ((BePointerType*)paramTypes[0])->mElementType;
-				}
-				else
-					intrin->mReturnType = mBeContext->GetPrimitiveType(BeTypeCode_None);
-				break;
-			case BfIRIntrinsic_AtomicCmpStore:
-			case BfIRIntrinsic_AtomicCmpStore_Weak:			
-				intrin->mReturnType = mBeContext->GetPrimitiveType(BeTypeCode_Boolean);
-				break;			
-			case BfIRIntrinsic_Cast:
-				intrin->mReturnType = returnType;
-				break;
-			}
-
+			intrin->mReturnType = returnType;
 			SetResult(curId, intrin);
 		}
 		break;
@@ -2585,7 +2560,10 @@ void BeIRCodeGen::HandleNextCmd()
 		{
 			CMD_PARAM(int, typeId);
 			CMD_PARAM(BeMDNode*, type);
-			GetTypeEntry(typeId).mDIType = (BeDbgType*)type;			
+			auto& typeEntry = GetTypeEntry(typeId);
+			typeEntry.mDIType = (BeDbgType*)type;
+			if (typeEntry.mInstDIType == NULL)
+				typeEntry.mInstDIType = (BeDbgType*)type;
 		}
 		break;
 	case BfIRCmd_DbgSetInstType:

Diferenças do arquivo suprimidas por serem muito extensas
+ 1340 - 1093
IDEHelper/Backend/BeMCContext.cpp


+ 13 - 3
IDEHelper/Backend/BeMCContext.h

@@ -192,11 +192,13 @@ enum BeMCOperandKind
 	BeMCOperandKind_Immediate_i16,
 	BeMCOperandKind_Immediate_i32,
 	BeMCOperandKind_Immediate_i64,
+	BeMCOperandKind_Immediate_HomeSize,
 	BeMCOperandKind_Immediate_Null,
 	BeMCOperandKind_Immediate_f32,
 	BeMCOperandKind_Immediate_f64,
 	BeMCOperandKind_Immediate_f32_Packed128,
 	BeMCOperandKind_Immediate_f64_Packed128,
+	BeMCOperandKind_Immediate_int32x4,	
 	BeMCOperandKind_ConstAgg,
 	BeMCOperandKind_Block,
 	BeMCOperandKind_Label,
@@ -283,12 +285,12 @@ public:
 
 	bool IsImmediateInt() const
 	{
-		return ((mKind >= BeMCOperandKind_Immediate_i8) && (mKind <= BeMCOperandKind_Immediate_i64));
+		return ((mKind >= BeMCOperandKind_Immediate_i8) && (mKind <= BeMCOperandKind_Immediate_HomeSize));
 	}
 
 	bool IsImmediateFloat() const
 	{
-		return ((mKind >= BeMCOperandKind_Immediate_f32) && (mKind <= BeMCOperandKind_Immediate_f64_Packed128));
+		return ((mKind >= BeMCOperandKind_Immediate_f32) && (mKind <= BeMCOperandKind_Immediate_int32x4));
 	}
 
 	bool IsNativeReg() const
@@ -925,10 +927,12 @@ enum BeMCInstForm
 	BeMCInstForm_FRM64_XMM32,
 	BeMCInstForm_FRM32_XMM64,
 	BeMCInstForm_FRM64_XMM64,
+	BeMCInstForm_FRM128_XMM128,
 	BeMCInstForm_XMM32_RM32,
 	BeMCInstForm_XMM64_RM32,
 	BeMCInstForm_XMM32_RM64,
 	BeMCInstForm_XMM64_RM64,
+	BeMCInstForm_XMM128_RM128,
 	BeMCInstForm_R32_F32,
 	BeMCInstForm_R64_F32,
 	BeMCInstForm_R32_F64,
@@ -1209,6 +1213,9 @@ enum BeMCNativeTypeCode
 	BeMCNativeTypeCode_Int64,
 	BeMCNativeTypeCode_Float,
 	BeMCNativeTypeCode_Double,
+	BeMCNativeTypeCode_M128,
+	BeMCNativeTypeCode_M256,
+	BeMCNativeTypeCode_M512,
 
 	BeMCNativeTypeCode_COUNT
 };
@@ -1347,6 +1354,7 @@ public:
 	void Print();
 	BeMCOperand GetOperand(BeValue* value, bool allowMetaResult = false, bool allowFail = false); // Meta results are PHIs or CmpResults
 	BeMCOperand CreateNot(const BeMCOperand& operand);
+	BeMCOperand TryToVector(BeValue* value);
 	BeType* GetType(const BeMCOperand& operand);
 	bool AreTypesEquivalent(BeType* type0, BeType* type1);
 	void AddRelRefs(BeMCOperand& operand, int refCount);
@@ -1413,10 +1421,12 @@ public:
 	bool IsVolatileReg(X64CPURegister reg);
 	bool IsXMMReg(X64CPURegister reg);
 	X64CPURegister ResizeRegister(X64CPURegister reg, int numBits);
+	X64CPURegister ResizeRegister(X64CPURegister reg, BeType* type);
+	X64CPURegister GetFullRegister(X64CPURegister reg);
 	bool IsAddress(BeMCOperand& operand);
 	bool IsAddressable(BeMCOperand& operand);
 	bool IsVRegExpr(BeMCOperand& operand);
-	void FixOperand(BeMCOperand& operand);
+	void FixOperand(BeMCOperand& operand, int depth = 0);
 	BeMCOperand GetFixedOperand(const BeMCOperand& operand);
 	uint8 GetREX(const BeMCOperand& op0, const BeMCOperand& op1, bool is64Bit);
 	void EmitREX(const BeMCOperand& op0, const BeMCOperand& op1, bool is64Bit);

+ 35 - 2
IDEHelper/Backend/BeModule.cpp

@@ -507,6 +507,12 @@ BeType* BeGEPConstant::GetType()
 		BF_ASSERT(arrayType->mTypeCode == BeTypeCode_SizedArray);
 		return arrayType->mContext->GetPointerTo(arrayType->mElementType);
 	}
+	else if (ptrType->mElementType->mTypeCode == BeTypeCode_Vector)
+	{
+		BeVectorType* arrayType = (BeVectorType*)ptrType->mElementType;
+		BF_ASSERT(arrayType->mTypeCode == BeTypeCode_Vector);
+		return arrayType->mContext->GetPointerTo(arrayType->mElementType);
+	}
 	/*else if (ptrType->mElementType->IsPointer())
 	{
 		return ptrType->mElementType;
@@ -528,6 +534,12 @@ BeType* BeExtractValueConstant::GetType()
 		BF_ASSERT(arrayType->mTypeCode == BeTypeCode_SizedArray);
 		return arrayType->mElementType;
 	}
+	else if (type->mTypeCode == BeTypeCode_Vector)
+	{
+		BeVectorType* arrayType = (BeVectorType*)type;
+		BF_ASSERT(arrayType->mTypeCode == BeTypeCode_Vector);
+		return arrayType->mElementType;
+	}
 	/*else if (ptrType->mElementType->IsPointer())
 	{
 		return ptrType->mElementType;
@@ -655,6 +667,11 @@ BeType* BeExtractValueInst::GetType()
 		BeSizedArrayType* arrayType = (BeSizedArrayType*)aggType;
 		return arrayType->mElementType;
 	}
+	if (aggType->mTypeCode == BeTypeCode_Vector)
+	{
+		BeVectorType* arrayType = (BeVectorType*)aggType;
+		return arrayType->mElementType;
+	}
 	BF_ASSERT(aggType->mTypeCode == BeTypeCode_Struct);
 	BeStructType* structType = (BeStructType*)aggType;
 	return structType->mMembers[mIdx].mType;	
@@ -703,6 +720,11 @@ BeType* BeGEPInst::GetType()
 		BeSizedArrayType* arrayType = (BeSizedArrayType*)ptrType->mElementType;
 		return GetContext()->GetPointerTo(arrayType->mElementType);
 	}
+	else if (elementType->IsVector())
+	{
+		BeVectorType* arrayType = (BeVectorType*)ptrType->mElementType;
+		return GetContext()->GetPointerTo(arrayType->mElementType);
+	}
 	else
 	{
 		BF_FATAL("Bad type");
@@ -1308,7 +1330,8 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo
 		switch (constant->mType->mTypeCode)
 		{
 		case BeTypeCode_Struct:			
-		case BeTypeCode_SizedArray:			
+		case BeTypeCode_SizedArray:
+		case BeTypeCode_Vector:
 			for (int valIdx = 0; valIdx < (int)constant->mMemberValues.size(); valIdx++)
 			{
 				if (valIdx > 0)
@@ -1412,7 +1435,8 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo
 				return;
 			}
 		case BeTypeCode_Struct:
-		case BeTypeCode_SizedArray:		
+		case BeTypeCode_SizedArray:
+		case BeTypeCode_Vector:
 			str += "zeroinitializer";		
 			return;
 		case BeTypeCode_Function:
@@ -3033,6 +3057,15 @@ void BeModule::ToString(StringImpl& str, BeType* type)
 			str += "]";
 			return;
 		}
+	case BeTypeCode_Vector:
+		{
+			auto arrayType = (BeSizedArrayType*)type;
+			ToString(str, arrayType->mElementType);
+			str += "<";
+			str += StrFormat("%d", arrayType->mLength);
+			str += ">";
+			return;
+		}
 	}
 	str += "<UnknownType>";
 }

+ 4 - 2
IDEHelper/Compiler/BfCompiler.cpp

@@ -382,6 +382,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
 	mCLinkAttributeTypeDef = NULL;
 	mImportAttributeTypeDef = NULL;
 	mCReprAttributeTypeDef = NULL;
+	mUnderlyingArrayAttributeTypeDef = NULL;
 	mAlignAttributeTypeDef = NULL;
 	mAllowDuplicatesAttributeTypeDef = NULL;
 	mNoDiscardAttributeTypeDef = NULL;
@@ -2691,7 +2692,7 @@ bool BfCompiler::SlowGenerateSlotNums()
 	if (!failed)
 	{
 		bool success = VerifySlotNums();
-		if (!success)
+		if ((!success) && (!isHotCompile))
 		{
 			BF_DBG_FATAL("Failed!");
 		}
@@ -2736,7 +2737,7 @@ void BfCompiler::GenerateSlotNums()
 	}
 
 	if (VerifySlotNums())	
-		return;	
+		return;
 	
 	if (!QuickGenerateSlotNums())
 		SlowGenerateSlotNums();		
@@ -6256,6 +6257,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 	mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
 	mImportAttributeTypeDef = _GetRequiredType("System.ImportAttribute");
 	mCReprAttributeTypeDef = _GetRequiredType("System.CReprAttribute");
+	mUnderlyingArrayAttributeTypeDef = _GetRequiredType("System.UnderlyingArrayAttribute");
 	mAlignAttributeTypeDef = _GetRequiredType("System.AlignAttribute");
 	mAllowDuplicatesAttributeTypeDef = _GetRequiredType("System.AllowDuplicatesAttribute");
 	mNoDiscardAttributeTypeDef = _GetRequiredType("System.NoDiscardAttribute");

+ 1 - 0
IDEHelper/Compiler/BfCompiler.h

@@ -385,6 +385,7 @@ public:
 	BfTypeDef* mCLinkAttributeTypeDef;
 	BfTypeDef* mImportAttributeTypeDef;
 	BfTypeDef* mCReprAttributeTypeDef;
+	BfTypeDef* mUnderlyingArrayAttributeTypeDef;
 	BfTypeDef* mAlignAttributeTypeDef;
 	BfTypeDef* mAllowDuplicatesAttributeTypeDef;
 	BfTypeDef* mNoDiscardAttributeTypeDef;

+ 1 - 0
IDEHelper/Compiler/BfContext.cpp

@@ -1007,6 +1007,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
 	typeInst->mTypeFailed = false;
 	typeInst->mTypeWarned = false;		
 	typeInst->mIsSplattable = false;
+	typeInst->mHasUnderlyingArray = false;
 	typeInst->mHasPackingHoles = false;
 	typeInst->mWantsGCMarking = false;
 	delete typeInst->mTypeInfoEx;

+ 52 - 11
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -4864,13 +4864,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
 	else
 	{
 		callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, irArgs);
-		if (hasResult)
+		if ((hasResult) && (!methodDef->mName.IsEmpty()) && (!methodInstance->mIsIntrinsic))
 			mModule->mBfIRBuilder->SetName(callInst, methodDef->mName);
 	}
-	if (expectCallingConvention != BfIRCallingConv_CDecl)
+	if ((expectCallingConvention != BfIRCallingConv_CDecl) && (!methodInstance->mIsIntrinsic))
 		mModule->mBfIRBuilder->SetCallCallingConv(callInst, expectCallingConvention);
 	
-	if (methodDef->mNoReturn)
+	if ((methodDef->mNoReturn) && (!methodInstance->mIsIntrinsic))
 		mModule->mBfIRBuilder->Call_AddAttribute(callInst, -1, BfIRAttribute_NoReturn);
 
 	bool hadAttrs = false;	
@@ -4881,7 +4881,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
 	int paramCount = methodInstance->GetParamCount();
 
 	for ( ; argIdx < callIRArgCount ; )
-	{	
+	{
+		if (methodInstance->mIsIntrinsic)
+			break;
+
 		if (argIdx == methodInstance->GetStructRetIdx())
 		{
 			mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
@@ -5087,7 +5090,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
 
 BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target)
 {
-	auto moduleMethodInstance = GetSelectedMethod(methodMatcher->mTargetSrc, methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, *methodMatcher);
+	auto& moduleMethodInstance = methodMatcher->mBestMethodInstance;
+	if (!moduleMethodInstance)
+		moduleMethodInstance = GetSelectedMethod(methodMatcher->mTargetSrc, methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, *methodMatcher);
 	if (moduleMethodInstance.mMethodInstance == NULL)
 		return BfTypedValue();
 	if ((target) && (target.mType != moduleMethodInstance.mMethodInstance->GetOwner()))
@@ -5095,7 +5100,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTyped
 		auto castedTarget = mModule->Cast(methodMatcher->mTargetSrc, target, moduleMethodInstance.mMethodInstance->GetOwner());
 		BF_ASSERT(castedTarget);
 		target = castedTarget;
-	}
+	}	
 	return CreateCall(methodMatcher->mTargetSrc, target, BfTypedValue(), methodMatcher->mBestMethodDef, moduleMethodInstance, false, methodMatcher->mArguments);
 }
 
@@ -17673,16 +17678,32 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal
 
 	SizedArray<BfExpression*, 2> argSrcs;
 	argSrcs.push_back(unaryOpExpr);
-	auto result = CreateCall(&methodMatcher, BfTypedValue());
+
+	BfTypedValue postOpVal;
+	if (isPostOp)	
+		postOpVal = mModule->LoadValue(args[0].mTypedValue);	
+
+	auto result = CreateCall(&methodMatcher, BfTypedValue());	
 
 	if ((result.mType != NULL) && (methodMatcher.mSelfType != NULL) && (result.mType->IsSelf()))
 	{
 		BF_ASSERT(mModule->IsInGeneric());
 		result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);
 	}
-
-	if (isPostOp)
-		result = args[0].mTypedValue;
+	
+	if ((methodMatcher.mBestMethodInstance) && (methodMatcher.mBestMethodInstance.mMethodInstance->mIsIntrinsic) &&
+		((findOp == BfUnaryOp_Increment) || (findOp == BfUnaryOp_Decrement)))
+	{
+		if (args[0].mTypedValue.IsAddr())
+			mModule->mBfIRBuilder->CreateStore(result.mValue, args[0].mTypedValue.mValue);
+		else
+		{
+			mModule->AssertErrorState();
+		}
+	}
+	
+	if (postOpVal)
+		result = postOpVal;
 	return result;
 }
 
@@ -18954,7 +18975,27 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
 						}
 					}
 				}
-				if (methodMatcher.mBestMethodDef != NULL)
+				
+				bool hadMatch = methodMatcher.mBestMethodDef != NULL;
+
+				if ((methodMatcher.mBestMethodDef != NULL) && ((flags & BfBinOpFlag_IgnoreOperatorWithWrongResult) != 0))
+				{
+					auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp;
+					methodMatcher.mBestMethodInstance = GetSelectedMethod(methodMatcher.mTargetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher);
+					if ((methodMatcher.mBestMethodInstance.mMethodInstance->mReturnType != mExpectingType) &&
+						((matchedOp == binaryOp) || (matchedOp == oppositeBinaryOp)))
+					{
+						if (binaryOp == BfBinaryOp_Equality)
+							binaryOp = BfBinaryOp_StrictEquality;
+						if (binaryOp == BfBinaryOp_InEquality)
+							binaryOp = BfBinaryOp_StrictEquality;
+
+						hadMatch = false;
+						break;
+					}
+				}
+
+				if (hadMatch)
 				{
 					methodMatcher.FlushAmbiguityError();
 

+ 2 - 1
IDEHelper/Compiler/BfExprEvaluator.h

@@ -293,7 +293,8 @@ enum BfBinOpFlags
 {
 	BfBinOpFlag_None = 0,
 	BfBinOpFlag_NoClassify = 1,
-	BfBinOpFlag_ForceLeftType = 2
+	BfBinOpFlag_ForceLeftType = 2,
+	BfBinOpFlag_IgnoreOperatorWithWrongResult = 4,
 };
 
 class BfExprEvaluator : public BfStructuralVisitor

+ 51 - 12
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -2167,7 +2167,14 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
 	BfIRType irType;
 	BfIRMDNode diType;
 	bool trackDIType = false;
-		
+	
+	BfTypeInstance* typeInstance = type->ToTypeInstance();	
+	BfType* underlyingArrayType = NULL;
+	int underlyingArraySize = -1;
+	bool underlyingArrayIsVector = false;
+	if (typeInstance != NULL)
+		typeInstance->GetUnderlyingArray(underlyingArrayType, underlyingArraySize, underlyingArrayIsVector);
+
 	if (type->IsPointer())
 	{
 		BfPointerType* pointerType = (BfPointerType*)type;				
@@ -2281,6 +2288,19 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
 		irType = CreateStructType(name);
 		StructSetBody(irType, members, false);
 	}
+	else if (underlyingArraySize != -1)
+	{
+		if (underlyingArrayIsVector)
+		{
+			if (underlyingArrayType == mModule->GetPrimitiveType(BfTypeCode_Boolean))
+				underlyingArrayType = mModule->GetPrimitiveType(BfTypeCode_UInt8);
+			irType = GetVectorType(MapType(underlyingArrayType), underlyingArraySize);
+		}
+		else
+			irType = GetSizedArrayType(MapType(underlyingArrayType), underlyingArraySize);
+		if (wantDIData)
+			diType = DbgCreateArrayType((int64)type->mSize * 8, type->mAlign * 8, DbgGetType(underlyingArrayType), underlyingArraySize);
+	}
 	else if (type->IsSizedArray())
 	{
 		BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
@@ -2375,8 +2395,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
 		}
 	}	
 	else if (type->IsTypeInstance())
-	{
-		BfTypeInstance* typeInstance = type->ToTypeInstance();
+	{		
 		auto typeDef = typeInstance->mTypeDef;
 	
 		BfIRMDNode diForwardDecl;
@@ -2524,14 +2543,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
 #ifdef BFIR_RENTRY_CHECK
 	ReEntryCheck reEntryCheck(&mDefReentrySet, type);
 #endif
-
-	String typeName = GetDebugTypeName(typeInstance, false);
-
-	bool isGlobalContainer = typeDef->IsGlobalsContainer();
 	
-	bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction()));
-	auto diForwardDecl = DbgGetTypeInst(typeInstance);
-
 	//BF_ASSERT(WantsDbgDefinition(type));
 	
 	llvm::SmallVector<BfIRMDNode, 8> diFieldTypes;
@@ -2539,6 +2551,9 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
 	bool isPacked = false;
 	bool isUnion = false;
 	bool isCRepr = false;
+	BfType* underlyingArrayType = NULL;
+	int underlyingArraySize = -1;
+	bool underlyingArrayIsVector = false;
 	
 	if (typeInstance->IsBoxed())
 	{
@@ -2549,8 +2564,18 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
 		isCRepr = typeInstance->mIsCRepr;
 		isPacked = typeInstance->mIsPacked;
 		isUnion = typeInstance->mIsUnion;
+		typeInstance->GetUnderlyingArray(underlyingArrayType, underlyingArraySize, underlyingArrayIsVector);
+		if (underlyingArrayType != NULL)
+			return; // Done
 	}
 
+	String typeName = GetDebugTypeName(typeInstance, false);
+
+	bool isGlobalContainer = typeDef->IsGlobalsContainer();
+
+	bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction()));
+	auto diForwardDecl = DbgGetTypeInst(typeInstance);
+
 	BfSizedVector<BfFieldInstance*, 8> orderedFields;
 
 	if ((type->IsUnion()) && (!type->IsEnum()))
@@ -3058,6 +3083,13 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine)
 	if (typeInstance == NULL)
 		return;		
 
+	BfType* underlyingArrayType = NULL;
+	int underlyingArraySize = -1;	
+	bool underlyingIsVector = false;
+	typeInstance->GetUnderlyingArray(underlyingArrayType, underlyingArraySize, underlyingIsVector);
+	if (underlyingArraySize > 0)
+		return;
+
 	auto typeDef = typeInstance->mTypeDef;	
 		
 #ifdef BFIR_RENTRY_CHECK
@@ -3531,6 +3563,13 @@ BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length)
 	}
 }
 
+BfIRType BfIRBuilder::GetVectorType(BfIRType elementType, int length)
+{	
+	BfIRType retType = WriteCmd(BfIRCmd_GetVectorType, elementType, length);
+	NEW_CMD_INSERTED_IRTYPE;
+	return retType;	
+}
+
 BfIRValue BfIRBuilder::CreateConstStruct(BfIRType type, const BfSizedArray<BfIRValue>& values)
 {
 	BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstStruct, type, values);
@@ -4516,9 +4555,9 @@ void BfIRBuilder::AddPhiIncoming(BfIRValue phi, BfIRValue value, BfIRBlock comin
 	NEW_CMD_INSERTED;
 }
 
-BfIRFunction BfIRBuilder::GetIntrinsic(int intrinId, BfIRType returnType, const BfSizedArray<BfIRType>& paramTypes)
+BfIRFunction BfIRBuilder::GetIntrinsic(String intrinName, int intrinId, BfIRType returnType, const BfSizedArray<BfIRType>& paramTypes)
 {
-	BfIRValue retVal = WriteCmd(BfIRCmd_GetIntrinsic, intrinId, returnType, paramTypes);
+	BfIRValue retVal = WriteCmd(BfIRCmd_GetIntrinsic, intrinName, intrinId, returnType, paramTypes);
 	NEW_CMD_INSERTED;
 	return retVal;
 }

+ 22 - 4
IDEHelper/Compiler/BfIRBuilder.h

@@ -175,7 +175,8 @@ enum BfIRCmd : uint8
 	BfIRCmd_GetType,
 	BfIRCmd_GetPointerToFuncType,
 	BfIRCmd_GetPointerToType,
-	BfIRCmd_GetSizedArrayType,		
+	BfIRCmd_GetSizedArrayType,
+	BfIRCmd_GetVectorType,
 
 	BfIRCmd_CreateConstStruct,
 	BfIRCmd_CreateConstStructZero,
@@ -274,7 +275,7 @@ enum BfIRCmd : uint8
 	BfIRCmd_CreatePhi,
 	BfIRCmd_AddPhiIncoming,
 
-	BfIRCmd_GetIntrinsic,
+	BfIRCmd_GetIntrinsic,	
 	BfIRCmd_CreateFunctionType,	
 	BfIRCmd_CreateFunction,	
 	BfIRCmd_EnsureFunctionPatchable,
@@ -406,6 +407,8 @@ enum BfIRConfigConst : uint8
 enum BfIRIntrinsic : uint8
 {
 	BfIRIntrinsic_Abs,
+	BfIRIntrinsic_Add,
+	BfIRIntrinsic_And,
 	BfIRIntrinsic_AtomicAdd,
 	BfIRIntrinsic_AtomicAnd,
 	BfIRIntrinsic_AtomicCmpStore,
@@ -425,21 +428,35 @@ enum BfIRIntrinsic : uint8
 	BfIRIntrinsic_AtomicXor,
 	BfIRIntrinsic_BSwap,
 	BfIRIntrinsic_Cast,
-	BfIRIntrinsic_Cos,
+	BfIRIntrinsic_Cos,	
+	BfIRIntrinsic_Div,
+	BfIRIntrinsic_Eq,
 	BfIRIntrinsic_Floor,
 	BfIRIntrinsic_Free,	
+	BfIRIntrinsic_Gt,
+	BfIRIntrinsic_GtE,	
 	BfIRIntrinsic_Log,
 	BfIRIntrinsic_Log10,
 	BfIRIntrinsic_Log2,
+	BfIRIntrinsic_Lt,
+	BfIRIntrinsic_LtE,
 	BfIRIntrinsic_Malloc,
 	BfIRIntrinsic_MemCpy,
 	BfIRIntrinsic_MemMove,
 	BfIRIntrinsic_MemSet,
+	BfIRIntrinsic_Mod,
+	BfIRIntrinsic_Mul,
+	BfIRIntrinsic_Not,
+	BfIRIntrinsic_Neq,
+	BfIRIntrinsic_Or,
 	BfIRIntrinsic_Pow,
 	BfIRIntrinsic_PowI,
 	BfIRIntrinsic_Round,
+	BfIRIntrinsic_Shuffle,
 	BfIRIntrinsic_Sin,
 	BfIRIntrinsic_Sqrt,	
+	BfIRIntrinsic_Sub,
+	BfIRIntrinsic_Xor,
 
 	BfIRIntrinsic_COUNT,
 	BfIRIntrinsic_Atomic_FIRST = BfIRIntrinsic_AtomicAdd,
@@ -1094,6 +1111,7 @@ public:
 	BfIRType GetPointerTo(BfIRFunctionType funcType);
 	BfIRType GetPointerTo(BfIRType type);
 	BfIRType GetSizedArrayType(BfIRType elementType, int length);
+	BfIRType GetVectorType(BfIRType elementType, int length);
 
 	BfIRValue CreateConstStruct(BfIRType type, const BfSizedArray<BfIRValue>& values);	
 	BfIRValue CreateConstString(const StringImpl& string);
@@ -1190,7 +1208,7 @@ public:
 	BfIRValue CreatePhi(BfIRType type, int incomingCount);
 	void AddPhiIncoming(BfIRValue phi, BfIRValue value, BfIRBlock comingFrom);
 	
-	BfIRFunction GetIntrinsic(int intrinId, BfIRType returnType, const BfSizedArray<BfIRType>& paramTypes);
+	BfIRFunction GetIntrinsic(String intrinName, int intrinId, BfIRType returnType, const BfSizedArray<BfIRType>& paramTypes);	
 	BfIRFunctionType MapMethod(BfMethodInstance* methodInstance);
 	BfIRFunctionType CreateFunctionType(BfIRType resultType, const BfSizedArray<BfIRType>& paramTypes, bool isVarArg = false);
 	BfIRFunction CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name);	

+ 388 - 63
IDEHelper/Compiler/BfIRCodeGen.cpp

@@ -134,6 +134,8 @@ struct BuiltinEntry
 static const BuiltinEntry gIntrinEntries[] =
 {
 	{"abs"},
+	{"add"},
+	{"and"},
 	{"atomic_add"},
 	{"atomic_and"},
 	{"atomic_cmpstore"},
@@ -153,21 +155,35 @@ static const BuiltinEntry gIntrinEntries[] =
 	{"atomic_xor"},
 	{"bswap"},
 	{"cast"},
-	{"cos"},
+	{"cos"},	
+	{"div"},
+	{"eq"},
 	{"floor"},
 	{"free"},
+	{"gt"},
+	{"gte"},	
 	{"log"},
 	{"log10"},
 	{"log2"},
+	{"lt"},
+	{"lte"},
 	{"malloc"},
 	{"memcpy"},
 	{"memmove"},
 	{"memset"},
+	{"mod"},
+	{"mul"},
+	{"neq"},
+	{"not"},
+	{"or"},
 	{"pow"},
 	{"powi"},
 	{"round"},
+	{"shuffle"},
 	{"sin"},
 	{"sqrt"},
+	{"sub"},
+	{"xor"},
 };
 
 #define CMD_PARAM(ty, name) ty name; Read(name);
@@ -1049,6 +1065,33 @@ void BfIRCodeGen::AddNop()
 	callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
 }
 
+llvm::Value* BfIRCodeGen::TryToVector(llvm::Value* value)
+{
+	auto valueType = value->getType();
+	if (llvm::isa<llvm::VectorType>(valueType))
+		return value;
+
+	if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(valueType))
+	{
+		auto ptrElemType = ptrType->getElementType();
+		if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
+		{
+			auto vecType = llvm::VectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
+			auto vecPtrType = vecType->getPointerTo();
+
+			auto ptrVal0 = mIRBuilder->CreateBitCast(value, vecPtrType);
+			return mIRBuilder->CreateAlignedLoad(ptrVal0, 1);
+		}
+
+		if (auto vecType = llvm::dyn_cast<llvm::VectorType>(ptrElemType))
+		{
+			return mIRBuilder->CreateAlignedLoad(value, 1);
+		}
+	}
+
+	return NULL;
+}
+
 bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
 {
 	auto valType = val->getType();
@@ -1110,6 +1153,31 @@ bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
 	return true;
 }
 
+bool BfIRCodeGen::TryVectorCpy(llvm::Value* ptr, llvm::Value* val)
+{
+	if (ptr->getType()->getPointerElementType() == val->getType())
+		return false;
+
+	auto valType = val->getType();
+	auto vecType = llvm::dyn_cast<llvm::VectorType>(valType);
+	if (vecType == NULL)
+		return false;
+
+	for (int i = 0; i < (int)vecType->getVectorNumElements(); i++)
+	{		
+		auto extract = mIRBuilder->CreateExtractElement(val, i);
+
+		llvm::Value* gepArgs[] = {
+			llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0),
+			llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), i) };
+		auto gep = mIRBuilder->CreateInBoundsGEP(ptr, llvm::makeArrayRef(gepArgs));
+
+		mIRBuilder->CreateStore(extract, gep);
+	}
+
+	return true;
+}
+
 void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
 {
 	auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
@@ -1273,7 +1341,10 @@ void BfIRCodeGen::HandleNextCmd()
 		{
 			CMD_PARAM(int, typeId);
 			CMD_PARAM(llvm::Type*, type);						
-			GetTypeEntry(typeId).mLLVMType = type;
+			auto& typeEntry = GetTypeEntry(typeId);
+			typeEntry.mLLVMType = type;
+			if (typeEntry.mInstLLVMType == NULL)
+				typeEntry.mInstLLVMType = type;
 		}
 		break;
 	case BfIRCmd_SetInstType:
@@ -1359,6 +1430,13 @@ void BfIRCodeGen::HandleNextCmd()
 			SetResult(curId, llvm::ArrayType::get(elementType, length));
 		}
 		break;	
+	case BfIRCmd_GetVectorType:
+		{
+			CMD_PARAM(llvm::Type*, elementType);
+			CMD_PARAM(int, length);
+			SetResult(curId, llvm::VectorType::get(elementType, length));
+		}
+		break;	
 	case BfIRCmd_CreateConstStruct:
 		{
 			CMD_PARAM(llvm::Type*, type);
@@ -1854,8 +1932,9 @@ void BfIRCodeGen::HandleNextCmd()
 			CMD_PARAM(llvm::Value*, val);
 			CMD_PARAM(llvm::Value*, ptr);
 			CMD_PARAM(bool, isVolatile);
-
-			if (!TryMemCpy(ptr, val))
+		
+			if ((!TryMemCpy(ptr, val)) &&
+				(!TryVectorCpy(ptr, val)))
 				SetResult(curId, mIRBuilder->CreateStore(val, ptr, isVolatile));
 		}
 		break;
@@ -1865,7 +1944,8 @@ void BfIRCodeGen::HandleNextCmd()
 			CMD_PARAM(llvm::Value*, ptr);
 			CMD_PARAM(int, alignment);
 			CMD_PARAM(bool, isVolatile);
-			if (!TryMemCpy(ptr, val))
+			if ((!TryMemCpy(ptr, val)) &&
+				(!TryVectorCpy(ptr, val)))
 				SetResult(curId, mIRBuilder->CreateAlignedStore(val, ptr, alignment, isVolatile));
 		}
 		break;
@@ -2116,29 +2196,11 @@ void BfIRCodeGen::HandleNextCmd()
 		break;
 	case BfIRCmd_GetIntrinsic:
 		{
+			CMD_PARAM(String, intrinName);
 			CMD_PARAM(int, intrinId);
 			CMD_PARAM(llvm::Type*, returnType);
 			CMD_PARAM(CmdParamVec<llvm::Type*>, paramTypes);
-			
-			bool isFakeIntrinsic = false;
-			if (((intrinId >= BfIRIntrinsic_Atomic_FIRST) && (intrinId <= BfIRIntrinsic_Atomic_LAST)) ||
-				(intrinId == BfIRIntrinsic_Cast))
-			{
-				isFakeIntrinsic = true;
-			}
-			if (isFakeIntrinsic)
-			{	
-				auto intrinsicData = mAlloc.Alloc<BfIRIntrinsicData>();
-				intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId;
-				intrinsicData->mReturnType = returnType;
-
-				BfIRCodeGenEntry entry;
-				entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
-				entry.mIntrinsicData = intrinsicData;
-				mResults.TryAdd(curId, entry);
-				break;
-			}
-			
+								
 			llvm::Function* func = NULL;
 			
 			struct _Intrinsics
@@ -2152,43 +2214,74 @@ void BfIRCodeGen::HandleNextCmd()
 			static _Intrinsics intrinsics[] =
 			{
 				{ llvm::Intrinsic::fabs, 0, -1},
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicAdd,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicAnd,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicCmpStore,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicCmpStore_Weak,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicCmpXChg,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicFence,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicLoad,					
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicMax,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicMin,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicNAnd,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicOr,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicStore,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicSub,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicUMax,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicUMin,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicXChg,
-				{ (llvm::Intrinsic::ID)-1, -1}, // AtomicXor,
+				{ (llvm::Intrinsic::ID)-2, -1}, // add,
+				{ (llvm::Intrinsic::ID)-2, -1}, // and,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicAdd,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicAnd,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore_Weak,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpXChg,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicFence,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicLoad,					
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicMax,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicMin,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicNAnd,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicOr,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicStore,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicSub,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicUMax,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicUMin,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicXChg,
+				{ (llvm::Intrinsic::ID)-2, -1}, // AtomicXor,
 				{ llvm::Intrinsic::bswap, -1},
-				{ (llvm::Intrinsic::ID)-1, -1}, // cast,
-				{ llvm::Intrinsic::cos, 0, -1},
+				{ (llvm::Intrinsic::ID)-2, -1}, // cast,
+				{ llvm::Intrinsic::cos, 0, -1},							
+				{ (llvm::Intrinsic::ID)-2, -1}, // div
+				{ (llvm::Intrinsic::ID)-2, -1}, // eq
 				{ llvm::Intrinsic::floor, 0, -1},
-				{ (llvm::Intrinsic::ID)-1, -1}, // free					
+				{ (llvm::Intrinsic::ID)-2, -1}, // free					
+				{ (llvm::Intrinsic::ID)-2, -1}, // gt
+				{ (llvm::Intrinsic::ID)-2, -1}, // gte				
 				{ llvm::Intrinsic::log, 0, -1},
 				{ llvm::Intrinsic::log10, 0, -1},
 				{ llvm::Intrinsic::log2, 0, -1},
-				{ (llvm::Intrinsic::ID)-1}, // memset
+				{ (llvm::Intrinsic::ID)-2, -1}, // lt
+				{ (llvm::Intrinsic::ID)-2, -1}, // lte
+				{ (llvm::Intrinsic::ID)-2}, // memset
 				{ llvm::Intrinsic::memcpy, 0, 1, 2},
 				{ llvm::Intrinsic::memmove, 0, 2},
 				{ llvm::Intrinsic::memset, 0, 2},
+				{ (llvm::Intrinsic::ID)-2, -1}, // mod
+				{ (llvm::Intrinsic::ID)-2, -1}, // mul
+				{ (llvm::Intrinsic::ID)-2, -1}, // neq
+				{ (llvm::Intrinsic::ID)-2, -1}, // not
+				{ (llvm::Intrinsic::ID)-2, -1}, // or
 				{ llvm::Intrinsic::pow, 0, -1},
 				{ llvm::Intrinsic::powi, 0, -1},
 				{ llvm::Intrinsic::round, 0, -1},
-				{ llvm::Intrinsic::sin, 0, -1},
-				{ llvm::Intrinsic::sqrt, 0, -1},					
+				{ (llvm::Intrinsic::ID)-2, -1}, // shuffle
+				{ llvm::Intrinsic::sin, 0, -1},				
+				{ llvm::Intrinsic::sqrt, 0, -1},
+				{ (llvm::Intrinsic::ID)-2, -1}, // sub,	
+				{ (llvm::Intrinsic::ID)-2, -1}, // xor
 			};
 			BF_STATIC_ASSERT(BF_ARRAY_COUNT(intrinsics) == BfIRIntrinsic_COUNT);
 
+			bool isFakeIntrinsic = (int)intrinsics[intrinId].mID == -2;			
+			if (isFakeIntrinsic)
+			{
+				auto intrinsicData = mAlloc.Alloc<BfIRIntrinsicData>();
+				intrinsicData->mName = intrinName;
+				intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId;
+				intrinsicData->mReturnType = returnType;
+
+				BfIRCodeGenEntry entry;
+				entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
+				entry.mIntrinsicData = intrinsicData;
+				mResults.TryAdd(curId, entry);
+				break;
+			}
+
 			CmdParamVec<llvm::Type*> useParams;
 			if (intrinsics[intrinId].mArg0 != -1)
 			{
@@ -2319,6 +2412,236 @@ void BfIRCodeGen::HandleNextCmd()
 
 				switch (intrinsicData->mIntrinsic)
 				{
+				case BfIRIntrinsic_Add:
+				case BfIRIntrinsic_And:
+				case BfIRIntrinsic_Div:
+				case BfIRIntrinsic_Eq:
+				case BfIRIntrinsic_Gt:
+				case BfIRIntrinsic_GtE:				
+				case BfIRIntrinsic_Lt:
+				case BfIRIntrinsic_LtE:
+				case BfIRIntrinsic_Mod:
+				case BfIRIntrinsic_Mul:				
+				case BfIRIntrinsic_Neq:
+				case BfIRIntrinsic_Or:
+				case BfIRIntrinsic_Sub:
+				case BfIRIntrinsic_Xor:
+					{
+						auto val0 = TryToVector(args[0]);
+						if (val0 != NULL)
+						{							
+							auto vecType = val0->getType();
+							auto elemType = vecType->getVectorElementType();
+							bool isFP = elemType->isFloatTy();
+							
+							llvm::Value* val1;
+							if (args.size() < 2)
+							{									
+								llvm::Value* val;
+								if (isFP)
+									val = llvm::ConstantFP::get(elemType, 1);
+								else
+									val = llvm::ConstantInt::get(elemType, 1);
+								val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), val, (uint64)0);
+								val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)1);
+								val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)2);
+								val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)3);
+							}
+							else if (args[1]->getType()->isPointerTy())
+							{
+								auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecType->getPointerTo());
+								val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, 1);									
+							}								
+							else
+							{
+								val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[1], (uint64)0);
+								val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)1);
+								val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)2);
+								val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)3);
+							}
+
+							if (isFP)
+							{
+								llvm::Value* result = NULL;
+								switch (intrinsicData->mIntrinsic)
+								{
+								case BfIRIntrinsic_Add:
+									result = mIRBuilder->CreateFAdd(val0, val1);
+									break;
+								case BfIRIntrinsic_Div:
+									result = mIRBuilder->CreateFDiv(val0, val1);
+									break;
+								case BfIRIntrinsic_Eq:
+									result = mIRBuilder->CreateFCmpOEQ(val0, val1);
+									break;
+								case BfIRIntrinsic_Gt:
+									result = mIRBuilder->CreateFCmpOGT(val0, val1);
+									break;
+								case BfIRIntrinsic_GtE:
+									result = mIRBuilder->CreateFCmpOGE(val0, val1);
+									break;
+								case BfIRIntrinsic_Lt:
+									result = mIRBuilder->CreateFCmpOLT(val0, val1);
+									break;
+								case BfIRIntrinsic_LtE:
+									result = mIRBuilder->CreateFCmpOLE(val0, val1);
+									break;
+								case BfIRIntrinsic_Mod:
+									result = mIRBuilder->CreateFRem(val0, val1);
+									break;
+								case BfIRIntrinsic_Mul:
+									result = mIRBuilder->CreateFMul(val0, val1);
+									break;
+								case BfIRIntrinsic_Neq:
+									result = mIRBuilder->CreateFCmpONE(val0, val1);
+									break;
+								case BfIRIntrinsic_Sub:
+									result = mIRBuilder->CreateFSub(val0, val1);
+									break;
+								default:
+									FatalError("Intrinsic argument error");
+								}
+
+								if (result != NULL)
+								{
+									if (auto vecType = llvm::dyn_cast<llvm::VectorType>(result->getType()))
+									{
+										if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getVectorElementType()))
+										{
+											if (intType->getBitWidth() == 1)
+											{
+												auto toType = llvm::VectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getVectorNumElements());
+												result = mIRBuilder->CreateZExt(result, toType);
+											}
+										}
+									}
+
+									SetResult(curId, result);
+								}
+							}							
+							else
+							{
+								llvm::Value* result = NULL;
+								switch (intrinsicData->mIntrinsic)
+								{
+								case BfIRIntrinsic_And:
+									result = mIRBuilder->CreateAnd(val0, val1);
+									break;
+								case BfIRIntrinsic_Add:
+									result = mIRBuilder->CreateAdd(val0, val1);
+									break;
+								case BfIRIntrinsic_Div:
+									result = mIRBuilder->CreateSDiv(val0, val1);
+									break;
+								case BfIRIntrinsic_Eq:
+									result = mIRBuilder->CreateICmpEQ(val0, val1);
+									break;
+								case BfIRIntrinsic_Gt:
+									result = mIRBuilder->CreateICmpSGT(val0, val1);
+									break;
+								case BfIRIntrinsic_GtE:
+									result = mIRBuilder->CreateICmpSGE(val0, val1);
+									break;
+								case BfIRIntrinsic_Lt:
+									result = mIRBuilder->CreateICmpSLT(val0, val1);
+									break;
+								case BfIRIntrinsic_LtE:
+									result = mIRBuilder->CreateICmpSLE(val0, val1);
+									break;
+								case BfIRIntrinsic_Mod:
+									result = mIRBuilder->CreateSRem(val0, val1);
+									break;
+								case BfIRIntrinsic_Mul:
+									result = mIRBuilder->CreateMul(val0, val1);
+									break;
+								case BfIRIntrinsic_Neq:
+									result = mIRBuilder->CreateICmpNE(val0, val1);
+									break;
+								case BfIRIntrinsic_Or:
+									result = mIRBuilder->CreateOr(val0, val1);
+									break;
+								case BfIRIntrinsic_Sub:
+									result = mIRBuilder->CreateSub(val0, val1);
+									break;
+								case BfIRIntrinsic_Xor:
+									result = mIRBuilder->CreateXor(val0, val1);
+									break;
+								default:
+									FatalError("Intrinsic argument error");
+								}
+
+								if (result != NULL)
+								{
+									if (auto vecType = llvm::dyn_cast<llvm::VectorType>(result->getType()))
+									{
+										if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getVectorElementType()))
+										{
+											if (intType->getBitWidth() == 1)
+											{
+												auto toType = llvm::VectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getVectorNumElements());
+												result = mIRBuilder->CreateZExt(result, toType);
+											}
+										}
+									}
+
+									SetResult(curId, result);
+								}
+							}
+						}
+						else if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(args[1]->getType()))
+						{
+							auto ptrElemType = ptrType->getElementType();
+							if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
+							{
+								auto vecType = llvm::VectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
+								auto vecPtrType = vecType->getPointerTo();
+								
+								llvm::Value* val0;								
+								val0 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[0], (uint64)0);
+								val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)1);
+								val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)2);
+								val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)3);								
+
+								auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecPtrType);
+								auto val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, 1);
+
+								switch (intrinsicData->mIntrinsic)
+								{								
+								case BfIRIntrinsic_Div:
+									SetResult(curId, mIRBuilder->CreateFDiv(val0, val1));
+									break;								
+								case BfIRIntrinsic_Mod:
+									SetResult(curId, mIRBuilder->CreateFRem(val0, val1));
+									break;
+								default:
+									FatalError("Intrinsic argument error");
+								}
+							}
+						}
+						else
+						{
+							FatalError("Intrinsic argument error");
+						}
+					}
+					break;
+				case BfIRIntrinsic_Shuffle:					
+					{
+						llvm::SmallVector<uint, 8> intMask;
+						for (int i = 7; i < (int)intrinsicData->mName.length(); i++)
+							intMask.push_back((uint)(intrinsicData->mName[i] - '0'));
+
+						auto val0 = TryToVector(args[0]);
+
+						if (val0 != NULL)
+						{															
+							SetResult(curId, mIRBuilder->CreateShuffleVector(val0, val0, intMask));							
+						}
+						else
+						{
+							FatalError("Intrinsic argument error");
+						}
+					}
+					break;
 				case BfIRIntrinsic_AtomicCmpStore:
 				case BfIRIntrinsic_AtomicCmpStore_Weak:
 				case BfIRIntrinsic_AtomicCmpXChg:
@@ -2326,7 +2649,7 @@ void BfIRCodeGen::HandleNextCmd()
 						auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[3]);
 						if (memoryKindConst == NULL)
 						{
-							Fail("Non-constant success ordering on Atomic_CmpXChg");
+							FatalError("Non-constant success ordering on Atomic_CmpXChg");
 							break;
 						}
 						auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
@@ -2365,7 +2688,7 @@ void BfIRCodeGen::HandleNextCmd()
 							auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[4]);
 							if (memoryKindConst == NULL)
 							{
-								Fail("Non-constant fail ordering on Atomic_CmpXChg");
+								FatalError("Non-constant fail ordering on Atomic_CmpXChg");
 								break;
 							}
 							auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
@@ -2381,7 +2704,7 @@ void BfIRCodeGen::HandleNextCmd()
 								failOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
 								break;
 							default:
-								Fail("Invalid fail ordering on Atomic_CmpXChg");
+								FatalError("Invalid fail ordering on Atomic_CmpXChg");
 								break;
 							}
 						}
@@ -2427,7 +2750,7 @@ void BfIRCodeGen::HandleNextCmd()
 						auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[0]);
 						if (memoryKindConst == NULL)
 						{
-							Fail("Non-constant success ordering on AtomicFence");
+							FatalError("Non-constant success ordering on AtomicFence");
 							break;
 						}
 
@@ -2460,7 +2783,7 @@ void BfIRCodeGen::HandleNextCmd()
 						auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[1]);
 						if (memoryKindConst == NULL)
 						{
-							Fail("Non-constant success ordering on AtomicLoad");
+							FatalError("Non-constant success ordering on AtomicLoad");
 							break;
 						}						
 						auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
@@ -2490,7 +2813,7 @@ void BfIRCodeGen::HandleNextCmd()
 						auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[1]);
 						if (memoryKindConst == NULL)
 						{
-							Fail("Non-constant success ordering on AtomicLoad");
+							FatalError("Non-constant success ordering on AtomicLoad");
 							break;
 						}
 						auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
@@ -2569,7 +2892,7 @@ void BfIRCodeGen::HandleNextCmd()
 						auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[2]);
 						if (memoryKindConst == NULL)
 						{
-							Fail("Non-constant ordering on atomic operation");
+							FatalError("Non-constant ordering on atomic operation");
 							break;
 						}
 
@@ -2676,7 +2999,7 @@ void BfIRCodeGen::HandleNextCmd()
 					}
 					break;
 				default:
-					Fail("Unhandled intrinsic");
+					FatalError("Unhandled intrinsic");
 				}
 				break;
 			}
@@ -3115,7 +3438,10 @@ void BfIRCodeGen::HandleNextCmd()
 		{
 			CMD_PARAM(int, typeId);
 			CMD_PARAM(llvm::MDNode*, type);
-			GetTypeEntry(typeId).mDIType = (llvm::DIType*)type;
+			auto& typeEntry = GetTypeEntry(typeId);
+			typeEntry.mDIType = (llvm::DIType*)type;
+			if (typeEntry.mInstDIType == NULL)
+				typeEntry.mInstDIType = (llvm::DIType*)type;
 		}
 		break;
 	case BfIRCmd_DbgSetInstType:
@@ -4537,17 +4863,16 @@ bool BfIRCodeGen::WriteIR(const StringImpl& outFileName, StringImpl& error)
 }
 
 int BfIRCodeGen::GetIntrinsicId(const StringImpl& name)
-{
-// 	llvm::Intrinsic::ID intrin = llvm::Intrinsic::getIntrinsicForGCCBuiltin("x86", name.c_str());
-// 	if (intrin != llvm::Intrinsic::not_intrinsic)
-// 		return (int)intrin;
-	
+{	
 	auto itr = std::lower_bound(std::begin(gIntrinEntries), std::end(gIntrinEntries), name);
 	if (itr != std::end(gIntrinEntries) && strcmp(itr->mName, name.c_str()) == 0)
 	{
 		int id = (int)(itr - gIntrinEntries);
 		return id;
-	}
+	}	
+
+	if (name.StartsWith("shuffle"))
+		return BfIRIntrinsic_Shuffle;
 
 	return -1;
 }

+ 4 - 1
IDEHelper/Compiler/BfIRCodeGen.h

@@ -19,6 +19,7 @@ enum BfIRCodeGenEntryKind
 class BfIRIntrinsicData
 {
 public:
+	String mName;
 	BfIRIntrinsic mIntrinsic;
 	llvm::Type* mReturnType;
 };
@@ -98,7 +99,9 @@ public:
 	void SetResult(int id, llvm::MDNode* value);	
 	void CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile = false);
 	void AddNop();
+	llvm::Value* TryToVector(llvm::Value* value);
 	bool TryMemCpy(llvm::Value* ptr, llvm::Value* val);	
+	bool TryVectorCpy(llvm::Value* ptr, llvm::Value* val);
 
 public:
 	BfIRCodeGen();
@@ -147,7 +150,7 @@ public:
 	llvm::BasicBlock* GetLLVMBlock(int streamId);
 	llvm::MDNode* GetLLVMMetadata(int streamId);
 
-	llvm::Type* GetLLVMTypeById(int id);
+	llvm::Type* GetLLVMTypeById(int id);	
 
 	///
 

+ 87 - 53
IDEHelper/Compiler/BfModule.cpp

@@ -1229,12 +1229,25 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force)
 				}
 				else
 				{
+					auto _HandleMethod = [&](BfMethodInstance* methodInstance)
+					{
+						if ((methodInstance != NULL) && (methodInstance->mDeclModule != NULL))
+							methodInstance->mDeclModule = this;
+					};
+
 					for (auto& methodGroup : typeInst->mMethodInstanceGroups)
+					{
 						if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) ||
 							(methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference))
 						{
 							oldOnDemandCount++;
 						}
+
+						_HandleMethod(methodGroup.mDefault);
+						if (methodGroup.mMethodSpecializationMap != NULL)
+							for (auto& kv : *methodGroup.mMethodSpecializationMap)
+								_HandleMethod(kv.mValue);
+					}
 				}
 				if (typeInst->IsDeleting())
 					typeIdx--;
@@ -4068,8 +4081,14 @@ void BfModule::EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRB
 {
 	BfExprEvaluator exprEvaluator(this);
 	exprEvaluator.mExpectingType = mCurMethodInstance->mReturnType;
-	exprEvaluator.PerformBinaryOperation((BfAstNode*)NULL, (BfAstNode*)NULL, strictEquals ? BfBinaryOp_StrictEquality : BfBinaryOp_Equality, NULL, BfBinOpFlag_None, leftValue, rightValue);
+
+	auto typeInst = rightValue.mType->ToTypeInstance();		
+	exprEvaluator.PerformBinaryOperation((BfAstNode*)NULL, (BfAstNode*)NULL, strictEquals ? BfBinaryOp_StrictEquality : BfBinaryOp_Equality, NULL, BfBinOpFlag_IgnoreOperatorWithWrongResult, leftValue, rightValue);
 	BfTypedValue result = exprEvaluator.GetResult();
+	if (result.mType != GetPrimitiveType(BfTypeCode_Boolean))
+	{
+		// Fail?
+	}
 	if ((result) && (!result.mType->IsVar()))
 	{
 		auto nextBB = mBfIRBuilder->CreateBlock("next");
@@ -6520,9 +6539,8 @@ BfIRFunction BfModule::GetIntrinsic(BfMethodInstance* methodInstance, bool repor
 	auto methodOwner = methodInstance->GetOwner();
 	auto methodDef = methodInstance->mMethodDef;
 	auto methodDeclaration = methodDef->GetMethodDeclaration();
-
-	bool hasExternSpecifier = (methodDeclaration != NULL) && (methodDeclaration->mExternSpecifier != NULL);
-	if (!hasExternSpecifier)
+	
+	if (!methodDef->mIsExtern)
 		return BfIRFunction();
 	
 	if (methodInstance->GetCustomAttributes() == NULL)
@@ -6542,33 +6560,44 @@ BfIRFunction BfModule::GetIntrinsic(BfMethodInstance* methodInstance, bool repor
 			{
 				int stringId = constant->mInt32;
 				auto entry = mContext->mStringObjectIdMap[stringId];
-				int intrinId = BfIRCodeGen::GetIntrinsicId(entry.mString);				
-				if (intrinId != -1)
+				String intrinName = entry.mString;
+				
+// 				if (intrinName.StartsWith(":"))
+// 				{
+// 					SizedArray<BfIRType, 2> paramTypes;
+// 					for (auto& param : methodInstance->mParams)
+// 						paramTypes.push_back(mBfIRBuilder->MapType(param.mResolvedType));
+// 					return mBfIRBuilder->GetIntrinsic(intrinName.Substring(1), mBfIRBuilder->MapType(methodInstance->mReturnType), paramTypes);
+// 				}
+// 				else
 				{
-					if (intrinId == BfIRIntrinsic_Malloc)
+					int intrinId = BfIRCodeGen::GetIntrinsicId(intrinName);
+					if (intrinId != -1)
 					{
-						return GetBuiltInFunc(BfBuiltInFuncType_Malloc);
-					}
-					else if (intrinId == BfIRIntrinsic_Free)
-					{
-						return GetBuiltInFunc(BfBuiltInFuncType_Free);
-					}
+						if (intrinId == BfIRIntrinsic_Malloc)
+						{
+							return GetBuiltInFunc(BfBuiltInFuncType_Malloc);
+						}
+						else if (intrinId == BfIRIntrinsic_Free)
+						{
+							return GetBuiltInFunc(BfBuiltInFuncType_Free);
+						}
 
-					SizedArray<BfIRType, 2> paramTypes;
-					for (auto& param : methodInstance->mParams)
-						paramTypes.push_back(mBfIRBuilder->MapType(param.mResolvedType));
-					return mBfIRBuilder->GetIntrinsic(intrinId, mBfIRBuilder->MapType(methodInstance->mReturnType), paramTypes);
+						SizedArray<BfIRType, 2> paramTypes;
+						for (auto& param : methodInstance->mParams)
+							paramTypes.push_back(mBfIRBuilder->MapType(param.mResolvedType));
+						return mBfIRBuilder->GetIntrinsic(intrinName, intrinId, mBfIRBuilder->MapType(methodInstance->mReturnType), paramTypes);
+					}
+					else if (reportFailure)
+						error = StrFormat("Unable to find intrinsic '%s'", entry.mString.c_str());
 				}
-				else if (reportFailure)
-					error = StrFormat("Unable to find intrinsic '%s'", entry.mString.c_str());
 			}
 			else if (reportFailure)
 				error = "Intrinsic name must be a constant string";
 
 			if (reportFailure)
-			{
-				BfAstNode* ref = methodDeclaration->mAttributes;
-				Fail(error, ref);
+			{				
+				Fail(error, customAttribute.mRef);
 			}			
 		}	
 	}
@@ -9415,20 +9444,9 @@ BfIRValue BfModule::CreateFunctionFrom(BfMethodInstance* methodInstance, bool tr
 			return func;
 	}
 
-	if (auto methodDeclaration = methodDef->GetMethodDeclaration())
-	{
-		if (methodDeclaration->mExternSpecifier != NULL)
-		{	
-			auto intrinsic = GetIntrinsic(methodInstance);
-			if (intrinsic)
-				return intrinsic;
-
-			// If we have multiple entries with the same name, they could have different arguments and will generate other errors...
-			/*auto func = mBfIRBuilder->GetFunction(methodName);
-			if (func)
-				return func;*/			
-		}
-	}
+	auto intrinsic = GetIntrinsic(methodInstance);
+	if (intrinsic)
+		return intrinsic;
 	
 	if (methodInstance->GetImportCallKind() != BfImportCallKind_None)
 	{
@@ -10550,7 +10568,7 @@ void BfModule::FinishAttributeState(BfAttributeState* attributeState)
 		Warn(0, "Unused attributes", attributeState->mSrc);
 }
 
-void BfModule::ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered)
+void BfModule::ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered, BfType*& underlyingArrayType, int& underlyingArraySize)
 {
 	if (mCurTypeInstance->mCustomAttributes != NULL)
 	{
@@ -10593,6 +10611,19 @@ void BfModule::ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bo
 					}
 				}
 			}
+			else if (typeName == "System.UnderlyingArrayAttribute")
+			{
+				if (customAttribute.mCtorArgs.size() >= 2)
+				{
+					auto typeConstant = mCurTypeInstance->mConstHolder->GetConstant(customAttribute.mCtorArgs[0]);
+					auto sizeConstant = mCurTypeInstance->mConstHolder->GetConstant(customAttribute.mCtorArgs[1]);
+					if ((typeConstant != NULL) && (sizeConstant != NULL) && (typeConstant->mConstType == BfConstType_TypeOf))
+					{
+						underlyingArrayType = (BfType*)(intptr)typeConstant->mInt64;
+						underlyingArraySize = sizeConstant->mInt32;
+					}
+				}
+			}
 		}
 	}
 }
@@ -13569,19 +13600,23 @@ void BfModule::CreateReturn(BfIRValue val)
 		BF_ASSERT(val);
 		mBfIRBuilder->CreateStore(val, mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
 		mBfIRBuilder->CreateRetVoid();
+		return;
 	}
-	else
+		
+	if (mCurMethodInstance->mReturnType->IsValuelessType())
 	{
-		if (mCurMethodInstance->mReturnType->IsValuelessType())
-		{
-			mBfIRBuilder->CreateRetVoid();
-		}
-		else if (mCurMethodInstance->mReturnType->IsStruct())
-		{
-			BfTypeCode loweredReturnType = BfTypeCode_None;
-			BfTypeCode loweredReturnType2 = BfTypeCode_None;
-			mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2);
+		mBfIRBuilder->CreateRetVoid();
+		return;
+	}
+		
+	if (mCurMethodInstance->mReturnType->IsStruct())
+	{
+		BfTypeCode loweredReturnType = BfTypeCode_None;
+		BfTypeCode loweredReturnType2 = BfTypeCode_None;
+		mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2);
 
+		if (loweredReturnType != BfTypeCode_None)
+		{
 			auto retVal = CreateAlloca(mCurMethodInstance->mReturnType);
 			mBfIRBuilder->CreateStore(val, retVal);
 
@@ -13590,13 +13625,12 @@ void BfModule::CreateReturn(BfIRValue val)
 			auto ptrReturnValue = mBfIRBuilder->CreateBitCast(retVal, irRetType);
 			auto loadedReturnValue = mBfIRBuilder->CreateLoad(ptrReturnValue);
 			mBfIRBuilder->CreateRet(loadedReturnValue);
-		}
-		else
-		{
-			BF_ASSERT(val);
-			mBfIRBuilder->CreateRet(val);
-		}
+			return;
+		}			
 	}
+		
+	BF_ASSERT(val);
+	mBfIRBuilder->CreateRet(val);			
 }
 
 void BfModule::EmitReturn(BfIRValue val)

+ 1 - 1
IDEHelper/Compiler/BfModule.h

@@ -1467,7 +1467,7 @@ public:
 	void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
 	BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
 	void FinishAttributeState(BfAttributeState* attributeState);
-	void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered);
+	void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered, BfType*& underlyingArrayType, int& underlyingArraySize);
 	void ProcessCustomAttributeData();	
 	bool TryGetConstString(BfIRConstHolder* constHolder, BfIRValue irValue, StringImpl& str);
 	BfVariant TypedValueToVariant(BfAstNode* refNode, const BfTypedValue& value, bool allowUndef = false);

+ 16 - 6
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -1908,7 +1908,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 	CheckCircularDataError();
 
 	bool underlyingTypeDeferred = false;
-	BfType* underlyingType = NULL;
+	BfType* underlyingType = NULL;	
 	if (typeInstance->mBaseType != NULL)
 	{		
 		if (typeInstance->IsTypedPrimitive())
@@ -2390,7 +2390,6 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 	{
 		BF_ASSERT(typeInstance->mBaseType == baseTypeInst);
 	}
-
 		
 	if (auto genericTypeInst = typeInstance->ToGenericTypeInstance())
 	{
@@ -2595,7 +2594,14 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 	bool isUnion = false;
 	bool isCRepr = false;
 	bool isOrdered = false;
-	ProcessTypeInstCustomAttributes(isPacked, isUnion, isCRepr, isOrdered);
+	BfType* underlyingArrayType = NULL;
+	int underlyingArraySize = -1;
+	ProcessTypeInstCustomAttributes(isPacked, isUnion, isCRepr, isOrdered, underlyingArrayType, underlyingArraySize);
+	if (underlyingArraySize > 0)
+	{
+		typeInstance->mHasUnderlyingArray = true;
+		curFieldDataIdx = 0;		
+	}
 	if (isPacked) // Packed infers ordered
 		isOrdered = true;
 	typeInstance->mIsUnion = isUnion;
@@ -3150,7 +3156,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 					{
 						if (isUnion)
 						{
-							fieldInstance->mDataIdx = curFieldDataIdx;							
+							fieldInstance->mDataIdx = curFieldDataIdx;
 						}						
 					}
 				}
@@ -3408,7 +3414,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 	///
 
 	// 'Splattable' means that we can be passed via 3 or fewer primitive/pointer values
-	if (typeInstance->IsStruct())
+	if (typeInstance->mHasUnderlyingArray)
+	{
+		// Never splat
+	}
+	else if (typeInstance->IsStruct())
 	{
 		bool hadNonSplattable = false;
 
@@ -3426,7 +3436,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 
 				if (checkType->IsMethodRef())
 				{
-					// For simplicitly, any methodRef inside a struct makes the struct non-splattable.  This reduces cases of needing to 
+					// For simplicity, any methodRef inside a struct makes the struct non-splattable.  This reduces cases of needing to 
 					//  handle embedded methodRefs
 					hadNonSplattable = true;
 				}

+ 34 - 5
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -658,9 +658,13 @@ bool BfMethodInstance::HasParamsArray()
 }
 
 int BfMethodInstance::GetStructRetIdx()
-{
-	if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType()))
+{		
+	if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType()) && (!mIsIntrinsic))
 	{
+		auto returnTypeInst = mReturnType->ToTypeInstance();
+		if ((returnTypeInst != NULL) && (returnTypeInst->mHasUnderlyingArray))
+			return -1;
+
 		auto owner = mMethodInstanceGroup->mOwner;
 		if (owner->mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows)
 			return 0;
@@ -688,7 +692,7 @@ bool BfMethodInstance::HasSelf()
 }
 
 bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2)
-{	
+{		
 	return mReturnType->GetLoweredType(mMethodDef->mIsStatic ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2);	
 }
 
@@ -1005,7 +1009,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
 		auto voidType = module->GetPrimitiveType(BfTypeCode_None);
 		returnType = module->mBfIRBuilder->MapType(voidType);
 	}
-	else if (mReturnType->IsComposite())
+	else if (GetStructRetIdx() != -1)
 	{
 		auto voidType = module->GetPrimitiveType(BfTypeCode_None);
 		returnType = module->mBfIRBuilder->MapType(voidType);
@@ -1558,10 +1562,35 @@ BfPrimitiveType* BfTypeInstance::GetDiscriminatorType(int* outDataIdx)
 	return (BfPrimitiveType*)fieldInstance.mResolvedType;
 }
 
+void BfTypeInstance::GetUnderlyingArray(BfType*& type, int& size, bool& isVector)
+{
+	if (mCustomAttributes == NULL)
+		return;
+	auto attributes = mCustomAttributes->Get(mModule->mCompiler->mUnderlyingArrayAttributeTypeDef);
+	if (attributes == NULL)
+		return;
+	if (attributes->mCtorArgs.size() != 3)
+		return;
+
+	auto typeConstant = mConstHolder->GetConstant(attributes->mCtorArgs[0]);	
+	auto sizeConstant = mConstHolder->GetConstant(attributes->mCtorArgs[1]);
+	auto isVectorConstant = mConstHolder->GetConstant(attributes->mCtorArgs[2]);
+	if ((typeConstant == NULL) || (sizeConstant == NULL) || (isVectorConstant == NULL))
+		return;
+	if (typeConstant->mConstType != BfConstType_TypeOf)
+		return;
+
+	type = (BfType*)(intptr)typeConstant->mInt64;
+	size = sizeConstant->mInt32;
+	isVector = isVectorConstant->mBool;
+}
+
 bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode, BfTypeCode* outTypeCode2)
-{	 	
+{
 	if ((mTypeDef->mTypeCode != BfTypeCode_Struct) || (IsBoxed()) || (mIsSplattable))
 		return false;
+	if (mHasUnderlyingArray)
+		return false;
 
 	if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
 	{

+ 3 - 0
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -1744,6 +1744,7 @@ public:
 	bool mIsUnion;	
 	bool mIsPacked;
 	bool mIsSplattable;
+	bool mHasUnderlyingArray;
 	bool mTypeIncomplete;
 	bool mTypeFailed;
 	bool mTypeWarned;
@@ -1770,6 +1771,7 @@ public:
 		mRevision = -1;
 		mIsReified = true;
 		mIsSplattable = false;
+		mHasUnderlyingArray = false;
 		mIsPacked = false;
 		mBaseType = NULL;
 		mCustomAttributes = NULL;
@@ -1879,6 +1881,7 @@ public:
 	int GetIFaceVMethodSize();
 	BfType* GetUnionInnerType(bool* wantSplat = NULL);
 	BfPrimitiveType* GetDiscriminatorType(int* outDataIdx = NULL);		
+	void GetUnderlyingArray(BfType*& type, int& size, bool& isVector);
 	bool HasEquivalentLayout(BfTypeInstance* compareTo);
 	BfIRConstHolder* GetOrCreateConstHolder();
 	BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder);	

+ 26 - 0
IDEHelper/Tests/src/Numerics.bf

@@ -0,0 +1,26 @@
+using System;
+using System.Numerics;
+
+namespace Tests
+{
+	class Numerics
+	{
+		[Test, UseLLVM]
+		public static void TestBasics()
+		{
+			float4 v0 = .(1, 2, 3, 4);
+			float4 v1 = .(10, 100, 1000, 10000);
+
+			float4 v2 = v0 * v1;
+			Test.Assert(v2 === .(10, 200, 3000, 40000));
+			Test.Assert(v2 !== .(10, 200, 3000, 9));
+			Test.Assert(v2.x == 10);
+			Test.Assert(v2.y == 200);
+			Test.Assert(v2.z == 3000);
+			Test.Assert(v2.w == 40000);
+
+			float4 v3 = v0.wzyx;
+			Test.Assert(v3 === .(4, 3, 2, 1));
+		}
+	}
+}

+ 30 - 2
IDEHelper/WinDebugger.cpp

@@ -6847,6 +6847,34 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c
 						}
 						headerStr = StrFormat("(%f, %f)", xmmRegVals[0], xmmRegVals[1]);
 					}
+					else if (mmDwMmDisplayType == DwMmDisplayType_Byte)
+					{
+						int xmmRegVals[4];
+						xmmCount = 4;
+						CPURegisters* regs = optEvaluator->GetRegisters();
+						for (int xmmMinor = 0; xmmMinor < xmmCount; ++xmmMinor)
+						{
+							DbgTypedValue xmmReg = GetRegister(StrFormat("xmm%d_%d", xmmMajor, xmmMinor), language, regs, &wdStackFrame->mRegForms);
+							BF_ASSERT(xmmReg.mType->mTypeCode == DbgType_i32);
+							BF_ASSERT(xmmReg.mRegNum == CPUReg_XMMREG_FIRST + (xmmMajor * 4) + xmmMinor);
+							xmmRegVals[xmmMinor] = xmmReg.mInt8;
+						}
+						headerStr = StrFormat("(%d, %d, %d, %d)", xmmRegVals[0], xmmRegVals[1], xmmRegVals[2], xmmRegVals[3]);
+					}
+					else if (mmDwMmDisplayType == DwMmDisplayType_Short)
+					{
+						int xmmRegVals[4];
+						xmmCount = 4;
+						CPURegisters* regs = optEvaluator->GetRegisters();
+						for (int xmmMinor = 0; xmmMinor < xmmCount; ++xmmMinor)
+						{
+							DbgTypedValue xmmReg = GetRegister(StrFormat("xmm%d_%d", xmmMajor, xmmMinor), language, regs, &wdStackFrame->mRegForms);
+							BF_ASSERT(xmmReg.mType->mTypeCode == DbgType_i32);
+							BF_ASSERT(xmmReg.mRegNum == CPUReg_XMMREG_FIRST + (xmmMajor * 4) + xmmMinor);
+							xmmRegVals[xmmMinor] = xmmReg.mInt16;
+						}
+						headerStr = StrFormat("(%d, %d, %d, %d)", xmmRegVals[0], xmmRegVals[1], xmmRegVals[2], xmmRegVals[3]);
+					}
 					else if (mmDwMmDisplayType == DwMmDisplayType_Int)
 					{
 						int xmmRegVals[4];
@@ -6860,7 +6888,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c
 							xmmRegVals[xmmMinor] = xmmReg.mInt32;
 						}
 						headerStr = StrFormat("(%d, %d, %d, %d)", xmmRegVals[0], xmmRegVals[1], xmmRegVals[2], xmmRegVals[3]);
-					}
+					}					
 					else // Float
 					{
 						float xmmRegVals[4];
@@ -8904,7 +8932,7 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la
 			return typedVal;
 		}
 
-		if (mmDisplayType == DwMmDisplayType_Int)
+		if ((mmDisplayType == DwMmDisplayType_Byte) || (mmDisplayType == DwMmDisplayType_Short) || (mmDisplayType == DwMmDisplayType_Int))
 		{
 			DbgTypedValue typedVal;
 			typedVal.mType = dbgModule->GetPrimitiveType(DbgType_i32, language);

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff