diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 5d16a4b74d3b5ad306ec13f2a90ba57dd01de2e8..fe97cf81088ccc3f3767b792d483b3e3c8ea8aca 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -132,7 +132,11 @@ namespace
 		eMONTIOR_MWAIT=33,
 		eCPLDebugStore=34,
 		eThermalMonitor2=35,
-		eAltivec=36
+		eAltivec=36,
+        eSSE3S_Features = 37,
+        eSSE4_1_Features = 38,
+        eSSE4_2_Features = 39,
+        eSSE4a_Features = 40,
 	};
 
 	const char* cpu_feature_names[] =
@@ -175,7 +179,11 @@ namespace
 		"CPL Qualified Debug Store",
 		"Thermal Monitor 2",
 
-		"Altivec"
+		"Altivec",
+        "SSE3S Instructions",
+        "SSE4.1 Instructions",
+        "SSE4.2 Instructions",
+        "SSE4a Instructions",
 	};
 
 	std::string intel_CPUFamilyName(int composed_family) 
@@ -264,6 +272,31 @@ class LLProcessorInfoImpl
 		return hasExtension(cpu_feature_names[eSSE2_Ext]);
 	}
 
+    bool hasSSE3() const
+    {
+        return hasExtension(cpu_feature_names[eSSE3_Features]);
+    }
+
+    bool hasSSE3S() const
+    {
+        return hasExtension(cpu_feature_names[eSSE3S_Features]);
+    }
+
+    bool hasSSE41() const
+    {
+        return hasExtension(cpu_feature_names[eSSE4_1_Features]);
+    }
+
+    bool hasSSE42() const
+    {
+        return hasExtension(cpu_feature_names[eSSE4_2_Features]);
+    }
+
+    bool hasSSE4a() const
+    {
+        return hasExtension(cpu_feature_names[eSSE4a_Features]);
+    }
+
 	bool hasAltivec() const 
 	{
 		return hasExtension("Altivec"); 
@@ -487,6 +520,12 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl
 		*((int*)(cpu_vendor+4)) = cpu_info[3];
 		*((int*)(cpu_vendor+8)) = cpu_info[2];
 		setInfo(eVendor, cpu_vendor);
+        std::string cmp_vendor(cpu_vendor);
+        bool is_amd = false;
+        if (cmp_vendor == "AuthenticAMD")
+        {
+            is_amd = true;
+        }
 
 		// Get the information associated with each valid Id
 		for(unsigned int i=0; i<=ids; ++i)
@@ -518,6 +557,7 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl
 
 				if(cpu_info[2] & 0x8)
 				{
+                    // intel specific SSE3 suplements
 					setExtension(cpu_feature_names[eMONTIOR_MWAIT]);
 				}
 				
@@ -530,7 +570,22 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl
 				{
 					setExtension(cpu_feature_names[eThermalMonitor2]);
 				}
-						
+
+                if (cpu_info[2] & 0x200)
+                {
+                    setExtension(cpu_feature_names[eSSE3S_Features]);
+                }
+
+                if (cpu_info[2] & 0x80000)
+                {
+                    setExtension(cpu_feature_names[eSSE4_1_Features]);
+                }
+
+                if (cpu_info[2] & 0x100000)
+                {
+                    setExtension(cpu_feature_names[eSSE4_2_Features]);
+                }
+
 				unsigned int feature_info = (unsigned int) cpu_info[3];
 				for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)
 				{
@@ -557,8 +612,17 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl
 			__cpuid(cpu_info, i);
 
 			// Interpret CPU brand string and cache information.
-			if  (i == 0x80000002)
-				memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+            if (i == 0x80000001)
+            {
+                if (is_amd)
+                {
+                    setExtension(cpu_feature_names[eSSE4a_Features]);
+                }
+            }
+            else if (i == 0x80000002)
+            {
+                memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+            }
 			else if  (i == 0x80000003)
 				memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info));
 			else if  (i == 0x80000004)
@@ -704,6 +768,41 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl
 		uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
 		S32 *ext_feature_infos = (S32*)(&ext_feature_info);
 		setConfig(eExtFeatureBits, ext_feature_infos[0]);
+
+
+        char cpu_features[1024];
+        len = sizeof(cpu_features);
+        memset(cpu_features, 0, len);
+        sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0);
+
+        std::string cpu_features_str(cpu_features);
+        cpu_features_str = " " + cpu_features_str + " ";
+
+        if (cpu_features_str.find(" SSE3 ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE3_Features]);
+        }
+
+        if (cpu_features_str.find(" SSSE3 ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE3S_Features]);
+        }
+
+        if (cpu_features_str.find(" SSE4.1 ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE4_1_Features]);
+        }
+
+        if (cpu_features_str.find(" SSE4.2 ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE4_2_Features]);
+        }
+
+        if (cpu_features_str.find(" SSE4A ") != std::string::npos)
+        {
+            // Not supposed to happen?
+            setExtension(cpu_feature_names[eSSE4a_Features]);
+        }
 	}
 };
 
@@ -814,6 +913,31 @@ class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl
 		{
 			setExtension(cpu_feature_names[eSSE2_Ext]);
 		}
+
+        if (flags.find(" pni ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE3_Features]);
+        }
+
+        if (flags.find(" ssse3 ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE3S_Features]);
+        }
+
+        if (flags.find(" sse4_1 ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE4_1_Features]);
+        }
+
+        if (flags.find(" sse4_2 ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE4_2_Features]);
+        }
+
+        if (flags.find(" sse4a ") != std::string::npos)
+        {
+            setExtension(cpu_feature_names[eSSE4a_Features]);
+        }
 	
 # endif // LL_X86
 	}
@@ -874,6 +998,11 @@ LLProcessorInfo::~LLProcessorInfo() {}
 F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
 bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
 bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
+bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); }
+bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); }
+bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); }
+bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); }
+bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); }
 bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
 std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); }
 std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index 90e5bc59ee24638243342e814de4a761006f13c1..8156dd12e63ea9721d0d173c6c1654ca57cf8a6b 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -40,6 +40,11 @@ class LL_COMMON_API LLProcessorInfo
 	F64MegahertzImplicit getCPUFrequency() const;
 	bool hasSSE() const;
 	bool hasSSE2() const;
+    bool hasSSE3() const;
+    bool hasSSE3S() const;
+    bool hasSSE41() const;
+    bool hasSSE42() const;
+    bool hasSSE4a() const;
 	bool hasAltivec() const;
 	std::string getCPUFamilyName() const;
 	std::string getCPUBrandName() const;
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index cdc1d83b591a096d840a8cfdcbe6863ea77045dc..a6c4d814724fd2cab6266e78f43ebe9a8ea1906d 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -571,6 +571,11 @@ LLCPUInfo::LLCPUInfo()
 	// proc.WriteInfoTextFile("procInfo.txt");
 	mHasSSE = proc.hasSSE();
 	mHasSSE2 = proc.hasSSE2();
+    mHasSSE3 = proc.hasSSE3();
+    mHasSSE3S = proc.hasSSE3S();
+    mHasSSE41 = proc.hasSSE41();
+    mHasSSE42 = proc.hasSSE42();
+    mHasSSE4a = proc.hasSSE4a();
 	mHasAltivec = proc.hasAltivec();
 	mCPUMHz = (F64)proc.getCPUFrequency();
 	mFamily = proc.getCPUFamilyName();
@@ -583,6 +588,35 @@ LLCPUInfo::LLCPUInfo()
 	}
 	mCPUString = out.str();
 	LLStringUtil::trim(mCPUString);
+
+    if (mHasSSE)
+    {
+        mSSEVersions.append("1");
+    }
+    if (mHasSSE2)
+    {
+        mSSEVersions.append("2");
+    }
+    if (mHasSSE3)
+    {
+        mSSEVersions.append("3");
+    }
+    if (mHasSSE3S)
+    {
+        mSSEVersions.append("3S");
+    }
+    if (mHasSSE41)
+    {
+        mSSEVersions.append("4.1");
+    }
+    if (mHasSSE42)
+    {
+        mSSEVersions.append("4.2");
+    }
+    if (mHasSSE4a)
+    {
+        mSSEVersions.append("4a");
+    }
 }
 
 bool LLCPUInfo::hasAltivec() const
@@ -600,6 +634,31 @@ bool LLCPUInfo::hasSSE2() const
 	return mHasSSE2;
 }
 
+bool LLCPUInfo::hasSSE3() const
+{
+    return mHasSSE3;
+}
+
+bool LLCPUInfo::hasSSE3S() const
+{
+    return mHasSSE3S;
+}
+
+bool LLCPUInfo::hasSSE41() const
+{
+    return mHasSSE41;
+}
+
+bool LLCPUInfo::hasSSE42() const
+{
+    return mHasSSE42;
+}
+
+bool LLCPUInfo::hasSSE4a() const
+{
+    return mHasSSE4a;
+}
+
 F64 LLCPUInfo::getMHz() const
 {
 	return mCPUMHz;
@@ -610,6 +669,11 @@ std::string LLCPUInfo::getCPUString() const
 	return mCPUString;
 }
 
+const LLSD& LLCPUInfo::getSSEVersions() const
+{
+    return mSSEVersions;
+}
+
 void LLCPUInfo::stream(std::ostream& s) const
 {
 	// gather machine information.
@@ -619,6 +683,11 @@ void LLCPUInfo::stream(std::ostream& s) const
 	// CPU's attributes regardless of platform
 	s << "->mHasSSE:     " << (U32)mHasSSE << std::endl;
 	s << "->mHasSSE2:    " << (U32)mHasSSE2 << std::endl;
+    s << "->mHasSSE3:    " << (U32)mHasSSE3 << std::endl;
+    s << "->mHasSSE3S:    " << (U32)mHasSSE3S << std::endl;
+    s << "->mHasSSE41:    " << (U32)mHasSSE41 << std::endl;
+    s << "->mHasSSE42:    " << (U32)mHasSSE42 << std::endl;
+    s << "->mHasSSE4a:    " << (U32)mHasSSE4a << std::endl;
 	s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
 	s << "->mCPUMHz:     " << mCPUMHz << std::endl;
 	s << "->mCPUString:  " << mCPUString << std::endl;
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 5ab97939b95f709024e59532e5cc1d37aa0ed7da..6882cd95337fb19a6c9fe5270eb2012ab00f4f53 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -76,10 +76,16 @@ class LL_COMMON_API LLCPUInfo
 	void stream(std::ostream& s) const;
 
 	std::string getCPUString() const;
+	const LLSD& getSSEVersions() const;
 
 	bool hasAltivec() const;
 	bool hasSSE() const;
 	bool hasSSE2() const;
+    bool hasSSE3() const;
+    bool hasSSE3S() const;
+    bool hasSSE41() const;
+    bool hasSSE42() const;
+    bool hasSSE4a() const;
 	F64 getMHz() const;
 
 	// Family is "AMD Duron" or "Intel Pentium Pro"
@@ -88,10 +94,16 @@ class LL_COMMON_API LLCPUInfo
 private:
 	bool mHasSSE;
 	bool mHasSSE2;
+    bool mHasSSE3;
+    bool mHasSSE3S;
+    bool mHasSSE41;
+    bool mHasSSE42;
+    bool mHasSSE4a;
 	bool mHasAltivec;
 	F64 mCPUMHz;
 	std::string mFamily;
 	std::string mCPUString;
+    LLSD mSSEVersions;
 };
 
 //=============================================================================
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 0ca4a3712dd7bf32b2159b995257e5fc11c7c051..dab11d4e0438b601862db21512ced2be073577aa 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -498,6 +498,7 @@ void send_viewer_stats(bool include_preferences)
 	system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();
 	system["os"] = LLOSInfo::instance().getOSStringSimple();
 	system["cpu"] = gSysCPU.getCPUString();
+    system["cpu_sse"] = gSysCPU.getSSEVersions();
 	system["address_size"] = ADDRESS_SIZE;
 	unsigned char MACAddress[MAC_ADDRESS_BYTES];
 	LLUUID::getNodeID(MACAddress);