mirror of
https://github.com/Basilisk-Development-Team/UXP-mirror.git
synced 2026-11-04 08:52:01 -05:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44d17e4ee7 | ||
|
|
26cc7c3126 | ||
|
|
cea1b66ba5 |
No files matched your search
@@ -23,6 +23,7 @@ SOURCES += [
|
||||
'DocAccessibleWrap.cpp',
|
||||
'EnumVariant.cpp',
|
||||
'HTMLTableAccessibleWrap.cpp',
|
||||
'HTMLWin32ObjectAccessible.cpp',
|
||||
'HyperTextAccessibleWrap.cpp',
|
||||
'ImageAccessibleWrap.cpp',
|
||||
'IUnknownImpl.cpp',
|
||||
|
||||
@@ -5,19 +5,13 @@
|
||||
|
||||
#include "DocumentOrShadowRoot.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/CSSStyleSheet.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/CSSStyleSheetBinding.h"
|
||||
#include "mozilla/dom/StyleSheetList.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "ShadowRoot.h"
|
||||
#include "XULDocument.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
class nsINode;
|
||||
class nsIDocument;
|
||||
@@ -49,99 +43,6 @@ DocumentOrShadowRoot::EnsureDOMStyleSheets()
|
||||
return *mDOMStyleSheets;
|
||||
}
|
||||
|
||||
void
|
||||
DocumentOrShadowRoot::GetAdoptedStyleSheets(
|
||||
JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aResult,
|
||||
ErrorResult& aRv) const
|
||||
{
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!ToJSValue(aCx, mAdoptedStyleSheets, &value)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(value.isObject());
|
||||
aResult.set(&value.toObject());
|
||||
}
|
||||
|
||||
void
|
||||
DocumentOrShadowRoot::SetAdoptedStyleSheets(
|
||||
JSContext* aCx,
|
||||
JS::Handle<JSObject*> aSheets,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
bool isArray = false;
|
||||
if (!JS_IsArrayObject(aCx, aSheets, &isArray)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isArray) {
|
||||
aRv.ThrowTypeError<MSG_NOT_SEQUENCE>(
|
||||
NS_LITERAL_STRING("DocumentOrShadowRoot.adoptedStyleSheets"));
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t length = 0;
|
||||
if (!JS_GetArrayLength(aCx, aSheets, &length)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument* document = AsNode().OwnerDoc();
|
||||
nsTArray<RefPtr<CSSStyleSheet>> newSheets;
|
||||
if (!newSheets.SetCapacity(length, fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
if (!JS_GetElement(aCx, aSheets, i, &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!value.isObject()) {
|
||||
aRv.ThrowTypeError<MSG_DOES_NOT_IMPLEMENT_INTERFACE>(
|
||||
NS_LITERAL_STRING("Element of DocumentOrShadowRoot.adoptedStyleSheets"),
|
||||
NS_LITERAL_STRING("CSSStyleSheet"));
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleSheet> sheet;
|
||||
nsresult rv = UnwrapObject<prototypes::id::CSSStyleSheet,
|
||||
CSSStyleSheet>(&value.toObject(), sheet);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.ThrowTypeError<MSG_DOES_NOT_IMPLEMENT_INTERFACE>(
|
||||
NS_LITERAL_STRING("Element of DocumentOrShadowRoot.adoptedStyleSheets"),
|
||||
NS_LITERAL_STRING("CSSStyleSheet"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sheet->IsConstructed() || sheet->ConstructorDocument() != document) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
newSheets.AppendElement(sheet);
|
||||
}
|
||||
|
||||
nsTArray<RefPtr<CSSStyleSheet>> oldSheets;
|
||||
oldSheets.SwapElements(mAdoptedStyleSheets);
|
||||
mAdoptedStyleSheets.SwapElements(newSheets);
|
||||
|
||||
if (mKind == Kind::Document) {
|
||||
static_cast<nsDocument&>(AsNode()).AdoptedStyleSheetsChanged(oldSheets,
|
||||
mAdoptedStyleSheets);
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<ShadowRoot&>(AsNode()).AdoptedStyleSheetsChanged(oldSheets,
|
||||
mAdoptedStyleSheets);
|
||||
}
|
||||
|
||||
Element*
|
||||
DocumentOrShadowRoot::GetElementById(const nsAString& aElementId)
|
||||
{
|
||||
|
||||
@@ -11,14 +11,11 @@
|
||||
#include "nsContentListDeclarations.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "mozilla/dom/NameSpaceConstants.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
class nsContentList;
|
||||
class nsINode;
|
||||
|
||||
namespace mozilla {
|
||||
class CSSStyleSheet;
|
||||
class ErrorResult;
|
||||
class StyleSheet;
|
||||
|
||||
namespace dom {
|
||||
@@ -86,18 +83,6 @@ public:
|
||||
|
||||
StyleSheetList& EnsureDOMStyleSheets();
|
||||
|
||||
void GetAdoptedStyleSheets(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aResult,
|
||||
mozilla::ErrorResult& aRv) const;
|
||||
void SetAdoptedStyleSheets(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aSheets,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& AdoptedStyleSheets() const
|
||||
{
|
||||
return mAdoptedStyleSheets;
|
||||
}
|
||||
|
||||
Element* GetElementById(const nsAString& aElementId);
|
||||
|
||||
/**
|
||||
@@ -166,7 +151,6 @@ protected:
|
||||
Element* GetRetargetedFocusedElement();
|
||||
|
||||
nsTArray<RefPtr<mozilla::StyleSheet>> mStyleSheets;
|
||||
nsTArray<RefPtr<mozilla::CSSStyleSheet>> mAdoptedStyleSheets;
|
||||
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
|
||||
|
||||
/*
|
||||
|
||||
+4
-53
@@ -18,7 +18,6 @@
|
||||
#include "mozilla/dom/StyleSheetList.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/CSSStyleSheet.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/StyleSheet.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
@@ -31,7 +30,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ShadowRoot)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot,
|
||||
DocumentFragment)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAdoptedStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAssociatedBinding)
|
||||
for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done();
|
||||
iter.Next()) {
|
||||
@@ -44,10 +42,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ShadowRoot)
|
||||
tmp->GetHost()->RemoveMutationObserver(tmp);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
|
||||
for (CSSStyleSheet* sheet : tmp->mAdoptedStyleSheets) {
|
||||
sheet->RemoveAdopter(tmp);
|
||||
}
|
||||
tmp->mAdoptedStyleSheets.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAssociatedBinding)
|
||||
tmp->mIdentifierMap.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(DocumentFragment)
|
||||
@@ -96,11 +90,6 @@ ShadowRoot::~ShadowRoot()
|
||||
host->RemoveMutationObserver(this);
|
||||
}
|
||||
|
||||
for (CSSStyleSheet* sheet : mAdoptedStyleSheets) {
|
||||
sheet->RemoveAdopter(this);
|
||||
}
|
||||
mAdoptedStyleSheets.Clear();
|
||||
|
||||
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||
|
||||
// nsINode destructor expects mSubtreeRoot == this.
|
||||
@@ -281,20 +270,15 @@ ShadowRoot::InsertSheet(StyleSheet* aSheet,
|
||||
|
||||
linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mProtoBinding->SheetCount() ==
|
||||
DocumentOrShadowRoot::SheetCount() +
|
||||
mAdoptedStyleSheets.Length());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mProtoBinding->SheetCount() == DocumentOrShadowRoot::SheetCount());
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
// FIXME(emilio, bug 1425759): For now we keep regular sheets duplicated;
|
||||
// adopted sheets are stored as a suffix on the proto binding only.
|
||||
// FIXME(emilio, bug 1425759): For now we keep them duplicated, the proto
|
||||
// binding will disappear soon (tm).
|
||||
{
|
||||
size_t i = 0;
|
||||
for (RefPtr<StyleSheet>& sheet : mStyleSheets) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(sheet.get() == mProtoBinding->StyleSheetAt(i++));
|
||||
}
|
||||
for (RefPtr<CSSStyleSheet>& sheet : mAdoptedStyleSheets) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(sheet.get() == mProtoBinding->StyleSheetAt(i++));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -303,7 +287,7 @@ ShadowRoot::InsertSheet(StyleSheet* aSheet,
|
||||
for (size_t i = 0; i <= SheetCount(); i++) {
|
||||
if (i == SheetCount()) {
|
||||
AppendStyleSheet(*aSheet);
|
||||
mProtoBinding->InsertStyleSheetAt(i, aSheet);
|
||||
mProtoBinding->AppendStyleSheet(aSheet);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -338,39 +322,6 @@ ShadowRoot::RemoveSheet(StyleSheet* aSheet)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::AdoptedStyleSheetsChanged(
|
||||
const nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
|
||||
const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
|
||||
{
|
||||
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
|
||||
|
||||
bool applicableChange = false;
|
||||
for (size_t i = 0; i < aOldSheets.Length(); ++i) {
|
||||
CSSStyleSheet* sheet = aOldSheets[i];
|
||||
if (aOldSheets.IndexOf(sheet) == i) {
|
||||
mProtoBinding->RemoveStyleSheet(sheet);
|
||||
}
|
||||
applicableChange = applicableChange || sheet->IsApplicable();
|
||||
sheet->RemoveAdopter(this);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aNewSheets.Length(); ++i) {
|
||||
CSSStyleSheet* sheet = aNewSheets[i];
|
||||
sheet->AddAdopter(this);
|
||||
if (aNewSheets.IndexOf(sheet) == i) {
|
||||
mProtoBinding->AppendStyleSheet(sheet);
|
||||
}
|
||||
applicableChange = applicableChange || sheet->IsApplicable();
|
||||
}
|
||||
|
||||
if (applicableChange) {
|
||||
StyleSheetChanged();
|
||||
}
|
||||
|
||||
OwnerDoc()->EndUpdate(UPDATE_STYLE);
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@ class nsXBLPrototypeBinding;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class CSSStyleSheet;
|
||||
class EventChainPreVisitor;
|
||||
|
||||
namespace dom {
|
||||
@@ -60,9 +59,6 @@ public:
|
||||
// [deprecated] Shadow DOM v0
|
||||
void InsertSheet(StyleSheet* aSheet, nsIContent* aLinkingContent);
|
||||
void RemoveSheet(StyleSheet* aSheet);
|
||||
void AdoptedStyleSheetsChanged(
|
||||
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
|
||||
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets);
|
||||
StyleSheetList* StyleSheets()
|
||||
{
|
||||
return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
|
||||
@@ -177,3 +173,4 @@ protected:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_shadowroot_h__
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/BinarySearch.h"
|
||||
#include "mozilla/CSSStyleSheet.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/EffectSet.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
@@ -1403,10 +1402,6 @@ nsDocument::~nsDocument()
|
||||
for (StyleSheet* sheet : mStyleSheets) {
|
||||
sheet->ClearAssociatedDocument();
|
||||
}
|
||||
for (CSSStyleSheet* sheet : mAdoptedStyleSheets) {
|
||||
sheet->RemoveAdopter(this);
|
||||
}
|
||||
mAdoptedStyleSheets.Clear();
|
||||
for (auto& sheets : mAdditionalSheets) {
|
||||
for (StyleSheet* sheet : sheets) {
|
||||
sheet->ClearAssociatedDocument();
|
||||
@@ -1640,7 +1635,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
|
||||
// Traverse all our nsCOMArrays.
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAdoptedStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
|
||||
|
||||
@@ -1746,11 +1740,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
|
||||
|
||||
for (CSSStyleSheet* sheet : tmp->mAdoptedStyleSheets) {
|
||||
sheet->RemoveAdopter(tmp);
|
||||
}
|
||||
tmp->mAdoptedStyleSheets.Clear();
|
||||
|
||||
if (tmp->mStyleSheetSetList) {
|
||||
tmp->mStyleSheetSetList->Disconnect();
|
||||
tmp->mStyleSheetSetList = nullptr;
|
||||
@@ -2216,12 +2205,6 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
|
||||
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAuthorSheet],
|
||||
SheetType::Doc);
|
||||
|
||||
for (CSSStyleSheet* sheet : mAdoptedStyleSheets) {
|
||||
if (sheet->IsApplicable()) {
|
||||
aStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
mStyleSetFilled = true;
|
||||
}
|
||||
|
||||
@@ -3889,37 +3872,6 @@ nsDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::AdoptedStyleSheetsChanged(
|
||||
const nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
|
||||
const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
|
||||
{
|
||||
BeginUpdate(UPDATE_STYLE);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = GetShell();
|
||||
nsStyleSet* styleSet = shell ? shell->StyleSet() : nullptr;
|
||||
|
||||
for (size_t i = 0; i < aOldSheets.Length(); ++i) {
|
||||
CSSStyleSheet* sheet = aOldSheets[i];
|
||||
if (styleSet && sheet->IsApplicable() &&
|
||||
aOldSheets.IndexOf(sheet) == i) {
|
||||
styleSet->RemoveStyleSheet(SheetType::Doc, sheet);
|
||||
}
|
||||
sheet->RemoveAdopter(this);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aNewSheets.Length(); ++i) {
|
||||
CSSStyleSheet* sheet = aNewSheets[i];
|
||||
sheet->AddAdopter(this);
|
||||
if (styleSet && sheet->IsApplicable() &&
|
||||
aNewSheets.IndexOf(sheet) == i) {
|
||||
styleSet->AppendStyleSheet(SheetType::Doc, sheet);
|
||||
}
|
||||
}
|
||||
|
||||
EndUpdate(UPDATE_STYLE);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RemoveStyleSheet(StyleSheet* aSheet)
|
||||
{
|
||||
@@ -4009,18 +3961,6 @@ nsDocument::SetStyleSheetApplicableState(StyleSheet* aSheet,
|
||||
} else {
|
||||
RemoveStyleSheetFromStyleSets(aSheet);
|
||||
}
|
||||
} else if (mAdoptedStyleSheets.IndexOf(aSheet->AsConcrete()) !=
|
||||
mAdoptedStyleSheets.NoIndex) {
|
||||
nsCOMPtr<nsIPresShell> shell = GetShell();
|
||||
if (shell) {
|
||||
if (aApplicable) {
|
||||
shell->StyleSet()->AppendStyleSheet(SheetType::Doc,
|
||||
aSheet->AsConcrete());
|
||||
} else {
|
||||
shell->StyleSet()->RemoveStyleSheet(SheetType::Doc,
|
||||
aSheet->AsConcrete());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We have to always notify, since this will be called for sheets
|
||||
|
||||
@@ -95,7 +95,6 @@ class nsISecurityConsoleMessage;
|
||||
class nsPIBoxObject;
|
||||
|
||||
namespace mozilla {
|
||||
class CSSStyleSheet;
|
||||
class EventChainPreVisitor;
|
||||
namespace dom {
|
||||
class BoxObject;
|
||||
@@ -472,9 +471,6 @@ public:
|
||||
nsTArray<RefPtr<mozilla::StyleSheet>>& aNewSheets) override;
|
||||
virtual void AddStyleSheetToStyleSets(mozilla::StyleSheet* aSheet);
|
||||
virtual void RemoveStyleSheetFromStyleSets(mozilla::StyleSheet* aSheet);
|
||||
void AdoptedStyleSheetsChanged(
|
||||
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
|
||||
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets);
|
||||
|
||||
virtual void InsertStyleSheetAt(mozilla::StyleSheet* aSheet,
|
||||
size_t aIndex) override;
|
||||
|
||||
@@ -1738,9 +1738,8 @@ nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||
if (mActiveWindow)
|
||||
window->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = content->GetComposedDoc();
|
||||
SendFocusOrBlurEvent(eBlur, presShell,
|
||||
doc, content, 1,
|
||||
content->GetComposedDoc(), content, 1,
|
||||
false, false, aContentToFocus);
|
||||
}
|
||||
|
||||
|
||||
@@ -6162,6 +6162,7 @@ nsGlobalWindow::CheckSecurityWidthAndHeight(int32_t* aWidth, int32_t* aHeight, b
|
||||
// This one is easy. Just ensure the variable is greater than 100;
|
||||
if ((aWidth && *aWidth < 100) || (aHeight && *aHeight < 100)) {
|
||||
// Check security state for use in determing window dimensions
|
||||
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
//sec check failed
|
||||
if (aWidth && *aWidth < 100) {
|
||||
@@ -6172,21 +6173,6 @@ nsGlobalWindow::CheckSecurityWidthAndHeight(int32_t* aWidth, int32_t* aHeight, b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the screen dimensions and keep the size in the range of the
|
||||
// screen size the window is on. We allow twice the screen size because the
|
||||
// size we get for a screen is not always accurate, on Wayland in particular,
|
||||
// and all we need is to keep the size in a reasonable range.
|
||||
nsCOMPtr<nsIDOMScreen> screen = GetScreen();
|
||||
int32_t screenWidth, screenHeight;
|
||||
screen->GetAvailWidth(&screenWidth);
|
||||
screen->GetAvailHeight(&screenHeight);
|
||||
if (aWidth && *aWidth > 2 * screenWidth) {
|
||||
*aWidth = 2 * screenWidth;
|
||||
}
|
||||
if (aHeight && *aHeight > 2 * screenHeight) {
|
||||
*aHeight = 2 * screenHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Arguments to this function should have values in device pixels
|
||||
@@ -8105,10 +8091,8 @@ nsGlobalWindow::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
|
||||
|
||||
nsIntSize cssSize(DevToCSSIntPixels(nsIntSize(width, height)));
|
||||
|
||||
// The deltas come from content and can be large enough to overflow a 32-bit
|
||||
// add, so do the arithmetic in 64 bits and keep the result in range.
|
||||
cssSize.width = int32_t(std::clamp<int64_t>(int64_t(cssSize.width) + aWidthDif, 0, INT32_MAX));
|
||||
cssSize.height = int32_t(std::clamp<int64_t>(int64_t(cssSize.height) + aHeightDif, 0, INT32_MAX));
|
||||
cssSize.width += aWidthDif;
|
||||
cssSize.height += aHeightDif;
|
||||
|
||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerIsChrome);
|
||||
|
||||
|
||||
@@ -46,9 +46,6 @@ nsIDocument::FindDocStyleSheetInsertionPoint(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sheet->IsConstructed()) {
|
||||
break;
|
||||
}
|
||||
if (sheet == GetFirstAdditionalAuthorSheet()) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1132,7 +1132,6 @@ void HTMLMediaElement::AbortExistingLoads()
|
||||
|
||||
RemoveMediaElementFromURITable();
|
||||
mLoadingSrc = nullptr;
|
||||
mCORSMode = CORS_NONE;
|
||||
mMediaSource = nullptr;
|
||||
|
||||
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING ||
|
||||
@@ -1371,9 +1370,6 @@ void HTMLMediaElement::SelectResource()
|
||||
// If we have a 'src' attribute, use that exclusively.
|
||||
nsAutoString src;
|
||||
if (mSrcAttrStream) {
|
||||
// Media provider objects use local mode, so a previous URL load's CORS
|
||||
// mode does not apply.
|
||||
mCORSMode = CORS_NONE;
|
||||
SetupSrcMediaStreamPlayback(mSrcAttrStream);
|
||||
} else if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
||||
@@ -117,6 +117,11 @@ public:
|
||||
|
||||
int32_t Index();
|
||||
|
||||
protected:
|
||||
virtual ~HTMLOptionElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
/**
|
||||
* Get the select content element that contains this option, this
|
||||
* intentionally does not return nsresult, all we care about is if
|
||||
@@ -124,11 +129,6 @@ public:
|
||||
*/
|
||||
HTMLSelectElement* GetSelect();
|
||||
|
||||
protected:
|
||||
virtual ~HTMLOptionElement();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool mSelectedChanged;
|
||||
bool mIsSelected;
|
||||
|
||||
|
||||
@@ -732,10 +732,10 @@ bool
|
||||
HTMLSelectElement::MatchSelectedOptions(Element* aElement,
|
||||
int32_t /* unused */,
|
||||
nsIAtom* /* unused */,
|
||||
void* aData)
|
||||
void* /* unused*/)
|
||||
{
|
||||
HTMLOptionElement* option = HTMLOptionElement::FromContent(aElement);
|
||||
return option && option->Selected() && option->GetSelect() == static_cast<HTMLSelectElement*>(aData);
|
||||
return option && option->Selected();
|
||||
}
|
||||
|
||||
nsIHTMLCollection*
|
||||
@@ -743,7 +743,7 @@ HTMLSelectElement::SelectedOptions()
|
||||
{
|
||||
if (!mSelectedOptions) {
|
||||
mSelectedOptions = new nsContentList(this, MatchSelectedOptions, nullptr,
|
||||
this, /* deep */ true);
|
||||
nullptr, /* deep */ true);
|
||||
}
|
||||
return mSelectedOptions;
|
||||
}
|
||||
|
||||
@@ -265,10 +265,6 @@ VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidateBufferAndPicture(aBuffer, aPicture)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
||||
|
||||
aVideoImage->SetDelayedConversion(true);
|
||||
|
||||
+7
-21
@@ -187,7 +187,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
VideoInfo(int32_t aWidth, int32_t aHeight)
|
||||
explicit VideoInfo(int32_t aWidth, int32_t aHeight)
|
||||
: VideoInfo(nsIntSize(aWidth, aHeight))
|
||||
{
|
||||
}
|
||||
@@ -201,6 +201,7 @@ public:
|
||||
, mCodecSpecificConfig(new MediaByteBuffer)
|
||||
, mExtraData(new MediaByteBuffer)
|
||||
, mRotation(kDegree_0)
|
||||
, mImageRect(nsIntRect(nsIntPoint(), aSize))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -262,28 +263,15 @@ public:
|
||||
|
||||
nsIntRect ImageRect() const
|
||||
{
|
||||
if (!mImageRect) {
|
||||
if (mImageRect.width < 0 || mImageRect.height < 0) {
|
||||
return nsIntRect(0, 0, mImage.width, mImage.height);
|
||||
}
|
||||
return *mImageRect;
|
||||
return mImageRect;
|
||||
}
|
||||
|
||||
void SetImageRect(const nsIntRect& aRect)
|
||||
{
|
||||
mImageRect = Some(aRect);
|
||||
}
|
||||
void ResetImageRect() {
|
||||
mImageRect.reset();
|
||||
}
|
||||
|
||||
// Adopts an image size decoded from the bitstream. The picture rectangle is
|
||||
// expressed relative to the image size, so a change in size invalidates it
|
||||
// and it is discarded; an unchanged size keeps the existing rectangle.
|
||||
void AdoptImageSize(const gfx::IntSize& aImage) {
|
||||
if (mImage != aImage) {
|
||||
ResetImageRect();
|
||||
}
|
||||
mImage = aImage;
|
||||
mImageRect = aRect;
|
||||
}
|
||||
|
||||
// Returned the crop rectangle scaled to aWidth/aHeight size relative to
|
||||
@@ -344,11 +332,9 @@ public:
|
||||
uint8_t mBitDepth = 8;
|
||||
|
||||
private:
|
||||
friend struct IPC::ParamTraits<VideoInfo>;
|
||||
|
||||
// mImage may be cropped; currently only used with the WebM container.
|
||||
// If unset, no cropping is to occur.
|
||||
Maybe<nsIntRect> mImageRect;
|
||||
// A negative width or height indicate that no cropping is to occur.
|
||||
nsIntRect mImageRect;
|
||||
|
||||
// Indicates whether or not frames may contain alpha information.
|
||||
bool mAlphaPresent = false;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace IPC {
|
||||
WriteParam(aMsg, aParam.mDisplay);
|
||||
WriteParam(aMsg, aParam.mStereoMode);
|
||||
WriteParam(aMsg, aParam.mImage);
|
||||
WriteParam(aMsg, aParam.mImageRect);
|
||||
WriteParam(aMsg, aParam.ImageRect());
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
@@ -35,7 +35,8 @@ namespace IPC {
|
||||
ReadParam(aMsg, aIter, &aResult->mDisplay) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mStereoMode) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mImage) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mImageRect)) {
|
||||
ReadParam(aMsg, aIter, &imageRect)) {
|
||||
aResult->SetImageRect(imageRect);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -847,15 +847,12 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
|
||||
RefPtr<layers::PlanarYCbCrImage> image =
|
||||
new IMFYCbCrImage(buffer, twoDBuffer);
|
||||
|
||||
if (!VideoData::SetVideoDataToImage(image,
|
||||
mVideoInfo,
|
||||
b,
|
||||
pictureRegion,
|
||||
false)) {
|
||||
LOG("CreateBasicVideoFrame: failed to set video data to image (shmem path)");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
VideoData::SetVideoDataToImage(image,
|
||||
mVideoInfo,
|
||||
b,
|
||||
pictureRegion,
|
||||
false);
|
||||
|
||||
RefPtr<VideoData> v =
|
||||
VideoData::CreateFromImage(mVideoInfo,
|
||||
aStreamOffset,
|
||||
|
||||
@@ -307,7 +307,8 @@ H264Converter::UpdateConfigFromExtraData(MediaByteBuffer* aExtraData)
|
||||
if (mp4_demuxer::H264::DecodeSPSFromExtraData(aExtraData, spsdata) &&
|
||||
spsdata.pic_width > 0 && spsdata.pic_height > 0) {
|
||||
mp4_demuxer::H264::EnsureSPSIsSane(spsdata);
|
||||
mCurrentConfig.AdoptImageSize(gfx::IntSize(spsdata.pic_width, spsdata.pic_height));
|
||||
mCurrentConfig.mImage.width = spsdata.pic_width;
|
||||
mCurrentConfig.mImage.height = spsdata.pic_height;
|
||||
mCurrentConfig.mDisplay.width = spsdata.display_width;
|
||||
mCurrentConfig.mDisplay.height = spsdata.display_height;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@ interface mixin DocumentOrShadowRoot {
|
||||
|
||||
readonly attribute Element? activeElement;
|
||||
readonly attribute StyleSheetList styleSheets;
|
||||
[Throws]
|
||||
attribute object adoptedStyleSheets;
|
||||
|
||||
readonly attribute Element? pointerLockElement;
|
||||
[LenientSetter, Func="nsDocument::IsUnprefixedFullscreenEnabled"]
|
||||
|
||||
@@ -294,12 +294,12 @@ nsXMLContentSink::DidBuildModel(bool aTerminated)
|
||||
}
|
||||
}
|
||||
|
||||
mDocumentChildren.Clear();
|
||||
mXSLTProcessor->SetSourceContentModel(mDocument, mDocumentChildren);
|
||||
// Since the processor now holds a reference to us we drop our reference
|
||||
// to it to avoid owning cycles
|
||||
mXSLTProcessor = nullptr;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Kick off layout for non-XSLT transformed documents.
|
||||
|
||||
// Check if we want to prettyprint
|
||||
@@ -881,9 +881,6 @@ nsXMLContentSink::SetDocElement(int32_t aNameSpaceID,
|
||||
|
||||
if (!mDocumentChildren.IsEmpty()) {
|
||||
for (nsIContent* child : mDocumentChildren) {
|
||||
if (MOZ_UNLIKELY(child->GetParentNode())) {
|
||||
child->Remove();
|
||||
}
|
||||
mDocument->AppendChildTo(child, false);
|
||||
}
|
||||
mDocumentChildren.Clear();
|
||||
@@ -994,9 +991,6 @@ nsXMLContentSink::HandleStartElement(const char16_t *aName,
|
||||
if (!SetDocElement(nameSpaceID, localName, content) && appendContent) {
|
||||
NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (MOZ_UNLIKELY(content->GetParentNode())) {
|
||||
content->Remove();
|
||||
}
|
||||
parent->AppendChildTo(content, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5159,7 +5159,7 @@ HTMLEditor::IsAcceptableInputEvent(WidgetGUIEvent* aGUIEvent)
|
||||
// If the event is a mouse event, we need to check if the target content is
|
||||
// the focused editing host or its descendant.
|
||||
if (aGUIEvent->AsMouseEventBase()) {
|
||||
RefPtr<nsIContent> editingHost = GetActiveEditingHost();
|
||||
nsIContent* editingHost = GetActiveEditingHost();
|
||||
// If there is no active editing host, we cannot handle the mouse event
|
||||
// correctly.
|
||||
if (!editingHost) {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -632,13 +632,9 @@ NVImage::GetAsSourceSurface()
|
||||
|
||||
// Convert the current NV12 or NV21 data to YUV420P so that we can follow the
|
||||
// logics in PlanarYCbCrImage::GetAsSourceSurface().
|
||||
auto bufferLength = CheckedInt<uint32_t>(mData.mYSize.height) * mData.mYStride +
|
||||
CheckedInt<uint32_t>(mData.mCbCrSize.height) * mData.mCbCrSize.width * 2;
|
||||
if (!bufferLength.isValid()) {
|
||||
NS_ERROR("Image buffer length exceeds integer limits.");
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t* buffer = new uint8_t[bufferLength.value()];
|
||||
const int bufferLength = mData.mYSize.height * mData.mYStride +
|
||||
mData.mCbCrSize.height * mData.mCbCrSize.width * 2;
|
||||
uint8_t* buffer = new uint8_t[bufferLength];
|
||||
|
||||
Data aData = mData;
|
||||
aData.mCbCrStride = aData.mCbCrSize.width;
|
||||
|
||||
@@ -40,7 +40,7 @@ static void SK_BLITBWMASK_NAME(const SkPixmap& dst, const SkMask& srcMask,
|
||||
const uint8_t* bits = srcMask.getAddr1(cx, cy);
|
||||
SK_BLITBWMASK_DEVTYPE* device = dst.SK_BLITBWMASK_GETADDR(cx, cy);
|
||||
|
||||
if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight && (clip.width() & 7) == 0)
|
||||
if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight)
|
||||
{
|
||||
do {
|
||||
SK_BLITBWMASK_DEVTYPE* dst = device;
|
||||
|
||||
@@ -702,16 +702,17 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
|
||||
case FT_GLYPH_FORMAT_BITMAP:
|
||||
if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
|
||||
glyph->fMaskFormat = SkMask::kARGB32_Format;
|
||||
} else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY ||
|
||||
isLCD(fRec)) {
|
||||
glyph->fMaskFormat = SkMask::kA8_Format;
|
||||
}
|
||||
|
||||
if (isLCD(fRec)) {
|
||||
fRec.fMaskFormat = SkMask::kA8_Format;
|
||||
}
|
||||
|
||||
if (fHaveShape) {
|
||||
// Ensure filtering is preserved when the bitmap is transformed.
|
||||
// Otherwise, the result will look horrifically aliased.
|
||||
if (glyph->fMaskFormat == SkMask::kBW_Format) {
|
||||
glyph->fMaskFormat = SkMask::kA8_Format;
|
||||
if (fRec.fMaskFormat == SkMask::kBW_Format) {
|
||||
fRec.fMaskFormat = SkMask::kA8_Format;
|
||||
}
|
||||
|
||||
// Apply the shape matrix to the glyph's bounding box.
|
||||
|
||||
@@ -587,9 +587,8 @@ gfxFontUtils::MapCharToGlyphFormat4(const uint8_t* aBuf, uint32_t aLength,
|
||||
const AutoSwap_PRUint16* idDelta = &startCodes[segCount];
|
||||
const AutoSwap_PRUint16* idRangeOffset = &idDelta[segCount];
|
||||
|
||||
// Sanity-check that the fixed-size arrays don't exceed the buffer or the
|
||||
// current subtable.
|
||||
const uint8_t* const limit = aBuf + std::min(aLength, uint32_t(cmap4->length));
|
||||
// Sanity-check that the fixed-size arrays don't exceed the buffer.
|
||||
const uint8_t* const limit = aBuf + aLength;
|
||||
if ((const uint8_t*)(&idRangeOffset[segCount]) > limit) {
|
||||
return 0; // broken font, just bail out safely
|
||||
}
|
||||
|
||||
@@ -2761,7 +2761,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
|
||||
ufe->Load();
|
||||
ff.CheckState(mSkipDrawing);
|
||||
}
|
||||
RefPtr<gfxFontEntry> pfe = ufe->GetPlatformFontEntry();
|
||||
gfxFontEntry* pfe = ufe->GetPlatformFontEntry();
|
||||
if (pfe && pfe->HasCharacter(aCh)) {
|
||||
font = GetFontAt(i, aCh);
|
||||
if (font) {
|
||||
|
||||
@@ -44,8 +44,7 @@ class ExpandingMemoryStream : public ots::OTSStream {
|
||||
public:
|
||||
ExpandingMemoryStream(size_t initial, size_t limit)
|
||||
: mLength(initial), mLimit(limit), mOff(0) {
|
||||
mPtr = moz_xmalloc(initial);
|
||||
std::memset(mPtr, 0, initial);
|
||||
mPtr = moz_xmalloc(mLength);
|
||||
}
|
||||
|
||||
~ExpandingMemoryStream() {
|
||||
@@ -75,7 +74,6 @@ public:
|
||||
newLength = mLimit;
|
||||
}
|
||||
mPtr = moz_xrealloc(mPtr, newLength);
|
||||
std::memset(static_cast<char*>(mPtr) + mLength, 0, newLength - mLength);
|
||||
mLength = newLength;
|
||||
return WriteRaw(data, length);
|
||||
}
|
||||
|
||||
@@ -94,6 +94,8 @@ RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) :
|
||||
//******************************************************************************
|
||||
RasterImage::~RasterImage()
|
||||
{
|
||||
mIsBeingDestroyed = true;
|
||||
|
||||
// Make sure our SourceBuffer is marked as complete. This will ensure that any
|
||||
// outstanding decoders terminate.
|
||||
if (!mSourceBuffer->IsComplete()) {
|
||||
@@ -429,17 +431,15 @@ RasterImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey)
|
||||
{
|
||||
MOZ_ASSERT(mProgressTracker);
|
||||
|
||||
if (mIsBeingDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool animatedFramesDiscarded = aSurfaceKey.Playback() == PlaybackType::eAnimated;
|
||||
|
||||
RefPtr<ProgressTracker> progressTracker = mProgressTracker;
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
[progressTracker, animatedFramesDiscarded]() -> void {
|
||||
RefPtr<Image> image = progressTracker->GetImage();
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
static_cast<RasterImage*>(image.get())
|
||||
->OnSurfaceDiscardedInternal(animatedFramesDiscarded);
|
||||
RefPtr<RasterImage> image = this;
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void {
|
||||
image->OnSurfaceDiscardedInternal(animatedFramesDiscarded);
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef mozilla_image_RasterImage_h
|
||||
#define mozilla_image_RasterImage_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "Image.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "imgIContainer.h"
|
||||
@@ -402,6 +403,8 @@ private: // data
|
||||
// This is currently only used for statistics
|
||||
int32_t mDecodeCount;
|
||||
|
||||
Atomic<bool> mIsBeingDestroyed{false};
|
||||
|
||||
// A weak pointer to our ImageContainer, which stays alive only as long as
|
||||
// the layer system needs it.
|
||||
WeakPtr<layers::ImageContainer> mImageContainer;
|
||||
|
||||
+7
-16
@@ -238,21 +238,16 @@ static inline JS::Value PoisonedObjectValue(JSObject* obj);
|
||||
namespace detail {
|
||||
|
||||
constexpr int CanonicalizedNaNSignBit = 0;
|
||||
constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL;
|
||||
|
||||
// A legacy MIPS ABI can run on hardware whose native NaN encoding does not
|
||||
// match the encoding selected by the compiler. Determine the canonical NaN
|
||||
// from an actual floating-point operation during JS initialization.
|
||||
#if defined(__mips__) && !defined(__mips_nan2008) && \
|
||||
!defined(__mips_nan_2008)
|
||||
# define JS_RUNTIME_CANONICAL_NAN
|
||||
extern JS_PUBLIC_DATA(uint64_t) CanonicalizedNaNBits;
|
||||
#if defined(__mips__) && !defined(__mips_nan2008)
|
||||
constexpr uint64_t CanonicalizedNaNSignificand = 0x7FFFFFFFFFFFFULL;
|
||||
#else
|
||||
constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL;
|
||||
#endif
|
||||
|
||||
constexpr uint64_t CanonicalizedNaNBits =
|
||||
mozilla::SpecificNaNBits<double,
|
||||
detail::CanonicalizedNaNSignBit,
|
||||
detail::CanonicalizedNaNSignificand>::value;
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -265,7 +260,8 @@ constexpr uint64_t CanonicalizedNaNBits =
|
||||
static MOZ_ALWAYS_INLINE double
|
||||
GenericNaN()
|
||||
{
|
||||
return mozilla::BitwiseCast<double>(detail::CanonicalizedNaNBits);
|
||||
return mozilla::SpecificNaN<double>(detail::CanonicalizedNaNSignBit,
|
||||
detail::CanonicalizedNaNSignificand);
|
||||
}
|
||||
|
||||
/* MSVC with PGO miscompiles this function. */
|
||||
@@ -359,11 +355,6 @@ class MOZ_NON_PARAM alignas(8) Value
|
||||
}
|
||||
|
||||
void setDouble(double d) {
|
||||
#if defined(JS_RUNTIME_CANONICAL_NAN) && defined(JS_PUNBOX64)
|
||||
// A non-canonical NaN can overlap the punbox64 tag space. Normalize
|
||||
// it before storing it so it cannot be mistaken for a GC pointer.
|
||||
d = CanonicalizeNaN(d);
|
||||
#endif
|
||||
// Don't assign to data.asDouble to fix a miscompilation with
|
||||
// GCC 5.2.1 and 5.3.1. See bug 1312488.
|
||||
data = layout(d);
|
||||
|
||||
@@ -902,8 +902,8 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
|
||||
inline void rotateLeft(Imm32 count, Register input, Register dest) PER_SHARED_ARCH;
|
||||
inline void rotateLeft(Register count, Register input, Register dest) PER_SHARED_ARCH;
|
||||
inline void rotateLeft64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
|
||||
inline void rotateLeft64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
|
||||
inline void rotateLeft64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
|
||||
inline void rotateLeft64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
|
||||
inline void rotateLeft64(Imm32 count, Register64 input, Register64 dest, Register temp)
|
||||
DEFINED_ON(x86, x64, arm, mips32, mips64, loongarch64);
|
||||
inline void rotateLeft64(Register count, Register64 input, Register64 dest, Register temp)
|
||||
@@ -911,8 +911,8 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
|
||||
inline void rotateRight(Imm32 count, Register input, Register dest) PER_SHARED_ARCH;
|
||||
inline void rotateRight(Register count, Register input, Register dest) PER_SHARED_ARCH;
|
||||
inline void rotateRight64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
|
||||
inline void rotateRight64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
|
||||
inline void rotateRight64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
|
||||
inline void rotateRight64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
|
||||
inline void rotateRight64(Imm32 count, Register64 input, Register64 dest, Register temp)
|
||||
DEFINED_ON(x86, x64, arm, mips32, mips64, loongarch64);
|
||||
inline void rotateRight64(Register count, Register64 input, Register64 dest, Register temp)
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
static uint32_t CountPhysBits(FloatRegisters::SetType bits) {
|
||||
MOZ_ASSERT((bits & ~FloatRegisters::AllPhysMask) == 0);
|
||||
return mozilla::CountPopulation32(uint32_t(bits));
|
||||
}
|
||||
|
||||
Registers::Code Registers::FromName(const char* name) {
|
||||
for (size_t i = 0; i < TotalPhys; i++) {
|
||||
if (strcmp(GetName(i), name) == 0) {
|
||||
@@ -42,47 +37,43 @@ FloatRegisters::Code FloatRegisters::FromName(const char* name) {
|
||||
}
|
||||
|
||||
FloatRegisterSet FloatRegister::ReduceSetForPush(const FloatRegisterSet& s) {
|
||||
SetType bits = s.bits();
|
||||
#ifdef ENABLE_WASM_SIMD
|
||||
# error "Needs more careful logic if SIMD is enabled"
|
||||
#endif
|
||||
|
||||
// Exclude registers already represented by a wider alias. Higher alias banks
|
||||
// are wider, so preserve only the widest live view of each physical register.
|
||||
bits &= ~(bits >> (1 * FloatRegisters::TotalPhys));
|
||||
bits &= ~(bits >> (2 * FloatRegisters::TotalPhys));
|
||||
|
||||
return FloatRegisterSet(bits);
|
||||
LiveFloatRegisterSet ret;
|
||||
for (FloatRegisterIterator iter(s); iter.more(); ++iter) {
|
||||
ret.addUnchecked(FromCode((*iter).encoding()));
|
||||
}
|
||||
return ret.set();
|
||||
}
|
||||
|
||||
uint32_t FloatRegister::GetSizeInBytes(const FloatRegisterSet& s) {
|
||||
return s.size() * sizeof(FloatRegisters::RegisterContent);
|
||||
#ifdef ENABLE_WASM_SIMD
|
||||
# error "Needs more careful logic if SIMD is enabled"
|
||||
#endif
|
||||
|
||||
return s.size() * sizeof(double);
|
||||
}
|
||||
|
||||
uint32_t FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s) {
|
||||
SetType all = s.bits();
|
||||
SetType set128b =
|
||||
(all >> (uint32_t(FloatRegisters::Simd128) * FloatRegisters::TotalPhys)) &
|
||||
FloatRegisters::AllPhysMask;
|
||||
SetType doubleSet =
|
||||
(all >> (uint32_t(FloatRegisters::Double) * FloatRegisters::TotalPhys)) &
|
||||
FloatRegisters::AllPhysMask;
|
||||
SetType singleSet =
|
||||
(all >> (uint32_t(FloatRegisters::Single) * FloatRegisters::TotalPhys)) &
|
||||
FloatRegisters::AllPhysMask;
|
||||
#ifdef ENABLE_WASM_SIMD
|
||||
# error "Needs more careful logic if SIMD is enabled"
|
||||
#endif
|
||||
|
||||
SetType set64b = doubleSet & ~set128b;
|
||||
SetType set32b = singleSet & ~set64b & ~set128b;
|
||||
|
||||
return CountPhysBits(set128b) * (4 * sizeof(int32_t)) +
|
||||
CountPhysBits(set64b) * sizeof(double) +
|
||||
CountPhysBits(set32b) * sizeof(float);
|
||||
return s.size() * sizeof(double);
|
||||
}
|
||||
|
||||
uint32_t FloatRegister::getRegisterDumpOffsetInBytes() {
|
||||
return encoding() * sizeof(FloatRegisters::RegisterContent);
|
||||
#ifdef ENABLE_WASM_SIMD
|
||||
# error "Needs more careful logic if SIMD is enabled"
|
||||
#endif
|
||||
|
||||
return encoding() * sizeof(double);
|
||||
}
|
||||
|
||||
bool CPUFlagsHaveBeenComputed() {
|
||||
// The LoongArch64 backend does not currently gate code generation on
|
||||
// optional CPU features.
|
||||
// TODO(loongarch64): Add CPU flags support.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,9 +249,9 @@ class FloatRegisters {
|
||||
// Eight bits: (invalid << 7) | (kind << 5) | encoding
|
||||
typedef uint8_t Code;
|
||||
typedef FPRegisterID Encoding;
|
||||
typedef unsigned __int128 SetType;
|
||||
typedef uint64_t SetType;
|
||||
|
||||
enum Kind : uint8_t { Double, Single, Simd128, NumTypes };
|
||||
enum Kind : uint8_t { Double, Single, NumTypes };
|
||||
|
||||
static constexpr Code Invalid = 0x80;
|
||||
|
||||
@@ -285,11 +285,7 @@ class FloatRegisters {
|
||||
<< (uint32_t(Single) * TotalPhys);
|
||||
static const SetType SpreadDouble = SetType(1)
|
||||
<< (uint32_t(Double) * TotalPhys);
|
||||
static const SetType SpreadSimd128 = SetType(1)
|
||||
<< (uint32_t(Simd128) * TotalPhys);
|
||||
static const SetType SpreadScalar = SpreadSingle | SpreadDouble;
|
||||
static const SetType SpreadVector = SpreadSimd128;
|
||||
static const SetType Spread = SpreadScalar | SpreadVector;
|
||||
static const SetType Spread = SpreadSingle | SpreadDouble;
|
||||
|
||||
static const SetType AllPhysMask = ((SetType(1) << TotalPhys) - 1);
|
||||
static const SetType AllMask = AllPhysMask * Spread;
|
||||
@@ -297,16 +293,13 @@ class FloatRegisters {
|
||||
static const SetType AllDoubleMask = AllPhysMask * SpreadDouble;
|
||||
static const SetType NoneMask = SetType(0);
|
||||
|
||||
// LoongArch64 callee-saved floating-point registers are f24-f31.
|
||||
// TODO(loongarch64): Much less than ARM64 here.
|
||||
static const SetType NonVolatileMask =
|
||||
((SetType(1) << FloatRegisters::f24) |
|
||||
(SetType(1) << FloatRegisters::f25) |
|
||||
(SetType(1) << FloatRegisters::f26) |
|
||||
(SetType(1) << FloatRegisters::f27) |
|
||||
(SetType(1) << FloatRegisters::f28) |
|
||||
(SetType(1) << FloatRegisters::f29) |
|
||||
(SetType(1) << FloatRegisters::f30) |
|
||||
(SetType(1) << FloatRegisters::f31)) * Spread;
|
||||
SetType((1 << FloatRegisters::f24) | (1 << FloatRegisters::f25) |
|
||||
(1 << FloatRegisters::f26) | (1 << FloatRegisters::f27) |
|
||||
(1 << FloatRegisters::f28) | (1 << FloatRegisters::f29) |
|
||||
(1 << FloatRegisters::f30) | (1 << FloatRegisters::f31)) *
|
||||
Spread;
|
||||
|
||||
static const SetType VolatileMask = AllMask & ~NonVolatileMask;
|
||||
|
||||
@@ -324,8 +317,6 @@ class FloatRegisters {
|
||||
union RegisterContent {
|
||||
float s;
|
||||
double d;
|
||||
int32_t i4[4];
|
||||
float s4[4];
|
||||
};
|
||||
|
||||
static constexpr Encoding encoding(Code c) {
|
||||
@@ -368,35 +359,26 @@ struct FloatRegister {
|
||||
typedef Codes::SetType SetType;
|
||||
|
||||
static uint32_t SetSize(SetType x) {
|
||||
static_assert(sizeof(SetType) == 16, "SetType must be 128 bits");
|
||||
static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
|
||||
x |= x >> FloatRegisters::TotalPhys;
|
||||
x |= x >> (2 * FloatRegisters::TotalPhys);
|
||||
x &= FloatRegisters::AllPhysMask;
|
||||
return mozilla::CountPopulation32(x);
|
||||
}
|
||||
|
||||
static uint32_t FirstBit(SetType x) {
|
||||
MOZ_ASSERT(x != 0);
|
||||
uint64_t low = uint64_t(x);
|
||||
if (low) {
|
||||
return mozilla::CountTrailingZeroes64(low);
|
||||
}
|
||||
return 64 + mozilla::CountTrailingZeroes64(uint64_t(x >> 64));
|
||||
static_assert(sizeof(SetType) == 8, "SetType");
|
||||
return mozilla::CountTrailingZeroes64(x);
|
||||
}
|
||||
static uint32_t LastBit(SetType x) {
|
||||
MOZ_ASSERT(x != 0);
|
||||
uint64_t high = uint64_t(x >> 64);
|
||||
if (high) {
|
||||
return 127 - mozilla::CountLeadingZeroes64(high);
|
||||
}
|
||||
return 63 - mozilla::CountLeadingZeroes64(uint64_t(x));
|
||||
static_assert(sizeof(SetType) == 8, "SetType");
|
||||
return 63 - mozilla::CountLeadingZeroes64(x);
|
||||
}
|
||||
|
||||
private:
|
||||
// These fields only hold valid values: an invalid register is always
|
||||
// represented as a valid encoding and kind with the invalid_ bit set.
|
||||
uint8_t encoding_; // 32 encodings
|
||||
uint8_t kind_; // Double, Single, Simd128
|
||||
uint8_t kind_; // Double, Single; more later
|
||||
bool invalid_;
|
||||
|
||||
typedef Codes::Kind Kind;
|
||||
@@ -405,8 +387,6 @@ struct FloatRegister {
|
||||
union RegisterContent {
|
||||
float s;
|
||||
double d;
|
||||
int32_t i4[4];
|
||||
float s4[4];
|
||||
};
|
||||
|
||||
constexpr FloatRegister(Encoding encoding, Kind kind)
|
||||
@@ -437,7 +417,7 @@ struct FloatRegister {
|
||||
}
|
||||
bool isSimd128() const {
|
||||
MOZ_ASSERT(!invalid_);
|
||||
return kind_ == FloatRegisters::Simd128;
|
||||
return false;
|
||||
}
|
||||
bool isInvalid() const { return invalid_; }
|
||||
|
||||
@@ -450,19 +430,13 @@ struct FloatRegister {
|
||||
return FloatRegister(Encoding(encoding_), FloatRegisters::Double);
|
||||
}
|
||||
FloatRegister doubleOverlay() const { return asDouble(); }
|
||||
FloatRegister asSimd128() const {
|
||||
MOZ_ASSERT(!invalid_);
|
||||
return FloatRegister(Encoding(encoding_), FloatRegisters::Simd128);
|
||||
}
|
||||
FloatRegister asSimd128() const { MOZ_CRASH(); }
|
||||
|
||||
constexpr uint32_t size() const {
|
||||
MOZ_ASSERT(!invalid_);
|
||||
if (kind_ == FloatRegisters::Double) {
|
||||
return sizeof(double);
|
||||
}
|
||||
if (kind_ == FloatRegisters::Simd128) {
|
||||
return 4 * sizeof(int32_t);
|
||||
}
|
||||
MOZ_ASSERT(kind_ == FloatRegisters::Single);
|
||||
return sizeof(float);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,11 @@ void js::jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
|
||||
// Note this is used for inter-wasm calls and may pass arguments and results
|
||||
// in floating point registers even if the system ABI does not.
|
||||
|
||||
// TODO(loongarch64): Inconsistent with LoongArch's calling convention.
|
||||
// LoongArch floating-point parameters calling convention:
|
||||
// The first eight floating-point parameters should be passed in f0-f7, and
|
||||
// the other floating point parameters will be passed like integer parameters.
|
||||
// But we just pass the other floating-point parameters on stack here.
|
||||
ABIArg ABIArgGenerator::next(MIRType type) {
|
||||
switch (type) {
|
||||
case MIRType::Int32:
|
||||
@@ -65,40 +70,16 @@ ABIArg ABIArgGenerator::next(MIRType type) {
|
||||
}
|
||||
case MIRType::Float32:
|
||||
case MIRType::Double: {
|
||||
if (floatRegIndex_ < NumFloatArgRegs) {
|
||||
current_ = ABIArg(FloatRegister(
|
||||
FloatRegisters::Encoding(floatRegIndex_ + f0.encoding()),
|
||||
type == MIRType::Double ? FloatRegisters::Double
|
||||
: FloatRegisters::Single));
|
||||
floatRegIndex_++;
|
||||
break;
|
||||
}
|
||||
if (intRegIndex_ == NumIntArgRegs) {
|
||||
if (floatRegIndex_ == NumFloatArgRegs) {
|
||||
current_ = ABIArg(stackOffset_);
|
||||
stackOffset_ += sizeof(double);
|
||||
break;
|
||||
}
|
||||
current_ = ABIArg(Register::FromCode(intRegIndex_ + a0.encoding()));
|
||||
intRegIndex_++;
|
||||
break;
|
||||
}
|
||||
case MIRType::Int8x16:
|
||||
case MIRType::Int16x8:
|
||||
case MIRType::Int32x4:
|
||||
case MIRType::Float32x4:
|
||||
case MIRType::Bool8x16:
|
||||
case MIRType::Bool16x8:
|
||||
case MIRType::Bool32x4: {
|
||||
if (floatRegIndex_ < NumFloatArgRegs) {
|
||||
current_ = ABIArg(FloatRegister(
|
||||
FloatRegisters::Encoding(floatRegIndex_ + f0.encoding()),
|
||||
FloatRegisters::Simd128));
|
||||
floatRegIndex_++;
|
||||
break;
|
||||
}
|
||||
stackOffset_ = AlignBytes(stackOffset_, SimdMemoryAlignment);
|
||||
current_ = ABIArg(stackOffset_);
|
||||
stackOffset_ += Simd128DataSize;
|
||||
current_ = ABIArg(FloatRegister(
|
||||
FloatRegisters::Encoding(floatRegIndex_ + f0.encoding()),
|
||||
type == MIRType::Double ? FloatRegisters::Double
|
||||
: FloatRegisters::Single));
|
||||
floatRegIndex_++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -353,19 +334,8 @@ void AssemblerLOONGARCH64::WriteInstStatic(uint32_t x, uint32_t* dest) {
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::haltingAlign(int alignment) {
|
||||
BufferOffset ret;
|
||||
MOZ_ASSERT(m_buffer.isAligned(4));
|
||||
MOZ_ASSERT((alignment & (alignment - 1)) == 0);
|
||||
|
||||
while (size() & (alignment - 1)) {
|
||||
BufferOffset tmp(size());
|
||||
as_break(WASM_TRAP);
|
||||
if (!ret.assigned()) {
|
||||
ret = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
// TODO(loongarch64): Implement a proper halting align.
|
||||
return nopAlign(alignment);
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::nopAlign(int alignment) {
|
||||
@@ -466,30 +436,10 @@ InstImm AssemblerLOONGARCH64::getBranchCode(JumpOrCall jumpOrCall) {
|
||||
}
|
||||
|
||||
InstImm AssemblerLOONGARCH64::getBranchCode(Register rj, Register rd, Condition c) {
|
||||
switch (c) {
|
||||
case AssemblerLOONGARCH64::Equal:
|
||||
return InstImm(op_beq, BOffImm16(0), rj, rd);
|
||||
case AssemblerLOONGARCH64::NotEqual:
|
||||
return InstImm(op_bne, BOffImm16(0), rj, rd);
|
||||
case AssemblerLOONGARCH64::Above:
|
||||
return InstImm(op_bltu, BOffImm16(0), rd, rj);
|
||||
case AssemblerLOONGARCH64::AboveOrEqual:
|
||||
return InstImm(op_bgeu, BOffImm16(0), rj, rd);
|
||||
case AssemblerLOONGARCH64::Below:
|
||||
return InstImm(op_bltu, BOffImm16(0), rj, rd);
|
||||
case AssemblerLOONGARCH64::BelowOrEqual:
|
||||
return InstImm(op_bgeu, BOffImm16(0), rd, rj);
|
||||
case AssemblerLOONGARCH64::GreaterThan:
|
||||
return InstImm(op_blt, BOffImm16(0), rd, rj);
|
||||
case AssemblerLOONGARCH64::GreaterThanOrEqual:
|
||||
return InstImm(op_bge, BOffImm16(0), rj, rd);
|
||||
case AssemblerLOONGARCH64::LessThan:
|
||||
return InstImm(op_blt, BOffImm16(0), rj, rd);
|
||||
case AssemblerLOONGARCH64::LessThanOrEqual:
|
||||
return InstImm(op_bge, BOffImm16(0), rd, rj);
|
||||
default:
|
||||
MOZ_CRASH("Condition not supported.");
|
||||
}
|
||||
// beq, bne
|
||||
MOZ_ASSERT(c == AssemblerLOONGARCH64::Equal || c == AssemblerLOONGARCH64::NotEqual);
|
||||
return InstImm(c == AssemblerLOONGARCH64::Equal ? op_beq : op_bne, BOffImm16(0),
|
||||
rj, rd);
|
||||
}
|
||||
|
||||
InstImm AssemblerLOONGARCH64::getBranchCode(Register rj, Condition c) {
|
||||
@@ -1060,118 +1010,6 @@ BufferOffset AssemblerLOONGARCH64::as_st_d(Register rd, Register rj, int32_t si1
|
||||
return writeInst(InstImm(op_st_d, si12, rj, rd, 12).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vld(FloatRegister vd, Register rj,
|
||||
int32_t si12) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(is_intN(si12, 12));
|
||||
spew("vld %3s,%3s,0x%x", vd.name(), rj.name(), si12);
|
||||
return writeInst(InstImm(op_vld, si12, rj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vst(FloatRegister vd, Register rj,
|
||||
int32_t si12) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(is_intN(si12, 12));
|
||||
spew("vst %3s,%3s,0x%x", vd.name(), rj.name(), si12);
|
||||
return writeInst(InstImm(op_vst, si12, rj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfcmp_clt_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfcmp.clt.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfcmp_clt_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfcmp_ceq_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfcmp.ceq.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfcmp_ceq_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cle_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfcmp.cle.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfcmp_cle_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cun_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfcmp.cun.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfcmp_cun_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cult_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfcmp.cult.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfcmp_cult_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cule_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfcmp.cule.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfcmp_cule_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cune_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfcmp.cune.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfcmp_cune_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vbitsel_v(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk,
|
||||
FloatRegister va) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
MOZ_ASSERT(va.isSimd128());
|
||||
spew("vbitsel.v %3s,%3s,%3s,%3s", vd.name(), vj.name(), vk.name(),
|
||||
va.name());
|
||||
return writeInst(InstReg(op_vbitsel_v, va, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vshuf_b(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk,
|
||||
FloatRegister va) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
MOZ_ASSERT(va.isSimd128());
|
||||
spew("vshuf.b %3s,%3s,%3s,%3s", vd.name(), vj.name(), vk.name(),
|
||||
va.name());
|
||||
return writeInst(InstReg(op_vshuf_b, va, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_ldx_b(Register rd, Register rj, Register rk) {
|
||||
spew("ldx_b %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
|
||||
return writeInst(InstReg(op_ldx_b, rk, rj, rd).encode());
|
||||
@@ -1230,425 +1068,6 @@ BufferOffset AssemblerLOONGARCH64::as_stx_d(Register rd, Register rj, Register r
|
||||
return writeInst(InstReg(op_stx_d, rk, rj, rd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vldx(FloatRegister vd, Register rj,
|
||||
Register rk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
spew("vldx %3s,%3s,%3s", vd.name(), rj.name(), rk.name());
|
||||
return writeInst(InstReg(op_vldx, rk, rj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vstx(FloatRegister vd, Register rj,
|
||||
Register rk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
spew("vstx %3s,%3s,%3s", vd.name(), rj.name(), rk.name());
|
||||
return writeInst(InstReg(op_vstx, rk, rj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vseq_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vseq.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vseq_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsle_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vsle.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vsle_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsle_wu(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vsle.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vsle_wu, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vslt_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vslt.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vslt_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vslt_wu(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vslt.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vslt_wu, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vadd_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vadd.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vadd_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsub_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vsub.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vsub_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vmax_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vmax.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vmax_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vmin_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vmin.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vmin_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vmax_wu(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vmax.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vmax_wu, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vmin_wu(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vmin.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vmin_wu, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vmul_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vmul.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vmul_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsll_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vsll.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vsll_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsrl_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vsrl.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vsrl_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsra_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vsra.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vsra_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vilvl_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vilvl.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vilvl_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vilvh_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vilvh.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vilvh_w, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vand_v(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vand.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vand_v, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vor_v(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vor.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vor_v, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vxor_v(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vxor.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vxor_v, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vnor_v(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vnor.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vnor_v, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vandn_v(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vandn.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vandn_v, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfadd_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfadd.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfadd_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfsub_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfsub.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfsub_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfmul_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfmul.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfmul_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfmax_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfmax.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfmax_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfmin_s(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
FloatRegister vk) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(vk.isSimd128());
|
||||
spew("vfmin.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
|
||||
return writeInst(InstReg(op_vfmin_s, vk, vj, vd).encode());
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vneg_w(FloatRegister vd,
|
||||
FloatRegister vj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
spew("vneg.w %3s,%3s", vd.name(), vj.name());
|
||||
return writeInst(op_vneg_w | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfsqrt_s(FloatRegister vd,
|
||||
FloatRegister vj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
spew("vfsqrt.s %3s,%3s", vd.name(), vj.name());
|
||||
return writeInst(op_vfsqrt_s | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfrecip_s(FloatRegister vd,
|
||||
FloatRegister vj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
spew("vfrecip.s %3s,%3s", vd.name(), vj.name());
|
||||
return writeInst(op_vfrecip_s | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfrsqrt_s(FloatRegister vd,
|
||||
FloatRegister vj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
spew("vfrsqrt.s %3s,%3s", vd.name(), vj.name());
|
||||
return writeInst(op_vfrsqrt_s | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vfrint_s(FloatRegister vd,
|
||||
FloatRegister vj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
spew("vfrint.s %3s,%3s", vd.name(), vj.name());
|
||||
return writeInst(op_vfrint_s | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vffint_s_w(FloatRegister vd,
|
||||
FloatRegister vj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
spew("vffint.s.w %3s,%3s", vd.name(), vj.name());
|
||||
return writeInst(op_vffint_s_w | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vftint_w_s(FloatRegister vd,
|
||||
FloatRegister vj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
spew("vftint.w.s %3s,%3s", vd.name(), vj.name());
|
||||
return writeInst(op_vftint_w_s | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vreplgr2vr_w(FloatRegister vd,
|
||||
Register rj) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
spew("vreplgr2vr.w %3s,%3s", vd.name(), rj.name());
|
||||
return writeInst(op_vreplgr2vr_w | RJ(rj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vreplvei_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
uint32_t lane) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(lane < 4);
|
||||
spew("vreplvei.w %3s,%3s,%u", vd.name(), vj.name(), lane);
|
||||
return writeInst(op_vreplvei_w | (lane << RKShift) | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vinsgr2vr_w(FloatRegister vd,
|
||||
Register rj,
|
||||
uint32_t lane) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(lane < 4);
|
||||
spew("vinsgr2vr.w %3s,%3s,%u", vd.name(), rj.name(), lane);
|
||||
return writeInst(op_vinsgr2vr_w | (lane << RKShift) | RJ(rj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vpickve2gr_w(Register rd,
|
||||
FloatRegister vj,
|
||||
uint32_t lane) {
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(lane < 4);
|
||||
spew("vpickve2gr.w %3s,%3s,%u", rd.name(), vj.name(), lane);
|
||||
return writeInst(op_vpickve2gr_w | (lane << RKShift) | FJ(vj) | RD(rd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vpickve2gr_wu(Register rd,
|
||||
FloatRegister vj,
|
||||
uint32_t lane) {
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(lane < 4);
|
||||
spew("vpickve2gr.wu %3s,%3s,%u", rd.name(), vj.name(), lane);
|
||||
return writeInst(op_vpickve2gr_wu | (lane << RKShift) | FJ(vj) | RD(rd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vslli_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
uint32_t imm) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(imm < 32);
|
||||
spew("vslli.w %3s,%3s,%u", vd.name(), vj.name(), imm);
|
||||
return writeInst(op_vslli_w | (imm << RKShift) | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsrli_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
uint32_t imm) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(imm < 32);
|
||||
spew("vsrli.w %3s,%3s,%u", vd.name(), vj.name(), imm);
|
||||
return writeInst(op_vsrli_w | (imm << RKShift) | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vsrai_w(FloatRegister vd,
|
||||
FloatRegister vj,
|
||||
uint32_t imm) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(vj.isSimd128());
|
||||
MOZ_ASSERT(imm < 32);
|
||||
spew("vsrai.w %3s,%3s,%u", vd.name(), vj.name(), imm);
|
||||
return writeInst(op_vsrai_w | (imm << RKShift) | FJ(vj) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_vldi(FloatRegister vd, int32_t imm) {
|
||||
MOZ_ASSERT(vd.isSimd128());
|
||||
MOZ_ASSERT(is_intN(imm, 13));
|
||||
spew("vldi %3s,%d", vd.name(), imm);
|
||||
return writeInst(op_vldi | ((imm & Imm13Mask) << Imm13Shift) | FD(vd));
|
||||
}
|
||||
|
||||
BufferOffset AssemblerLOONGARCH64::as_ldptr_w(Register rd, Register rj,
|
||||
int32_t si14) {
|
||||
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
|
||||
|
||||
@@ -101,8 +101,7 @@ static constexpr Register64 ReturnReg64(ReturnReg);
|
||||
static constexpr FloatRegister ReturnFloat32Reg{FloatRegisters::f0,
|
||||
FloatRegisters::Single};
|
||||
static constexpr FloatRegister ReturnDoubleReg = f0;
|
||||
static constexpr FloatRegister ReturnSimd128Reg{FloatRegisters::f0,
|
||||
FloatRegisters::Simd128};
|
||||
static constexpr FloatRegister ReturnSimd128Reg = InvalidFloatReg;
|
||||
|
||||
static constexpr Register ScratchRegister = t7;
|
||||
static constexpr Register SecondScratchReg = t8;
|
||||
@@ -122,8 +121,7 @@ struct SecondScratchRegisterScope : public AutoRegisterScope {
|
||||
static constexpr FloatRegister ScratchFloat32Reg{FloatRegisters::f23,
|
||||
FloatRegisters::Single};
|
||||
static constexpr FloatRegister ScratchDoubleReg = f23;
|
||||
static constexpr FloatRegister ScratchSimd128Reg{FloatRegisters::f23,
|
||||
FloatRegisters::Simd128};
|
||||
static constexpr FloatRegister ScratchSimd128Reg = InvalidFloatReg;
|
||||
|
||||
struct ScratchFloat32Scope : public AutoFloatRegisterScope {
|
||||
explicit ScratchFloat32Scope(MacroAssembler& masm)
|
||||
@@ -228,20 +226,11 @@ static constexpr Register WasmJitEntryReturnScratch = t1;
|
||||
static constexpr uint32_t ABIStackAlignment = 16;
|
||||
static constexpr uint32_t CodeAlignment = 16;
|
||||
|
||||
// Does this architecture support SIMD conversions between Uint32x4 and
|
||||
// Float32x4?
|
||||
static constexpr bool SupportsUint32x4FloatConversions = false;
|
||||
|
||||
// Does this architecture support comparisons of unsigned integer vectors?
|
||||
static constexpr bool SupportsUint8x16Compares = false;
|
||||
static constexpr bool SupportsUint16x8Compares = false;
|
||||
static constexpr bool SupportsUint32x4Compares = false;
|
||||
|
||||
// This boolean indicates whether we support SIMD instructions flavoured for
|
||||
// this architecture or not. Rather than a method in the LIRGenerator, it is
|
||||
// here such that it is accessible from the entire codebase. Once full support
|
||||
// for SIMD is reached on all tier-1 platforms, this constant can be deleted.
|
||||
static constexpr bool SupportsSimd = true;
|
||||
static constexpr bool SupportsSimd = false;
|
||||
static constexpr uint32_t JitStackAlignment = 16;
|
||||
|
||||
static constexpr uint32_t JitStackValueAlignment =
|
||||
@@ -250,8 +239,8 @@ static_assert(JitStackAlignment % sizeof(Value) == 0 &&
|
||||
JitStackValueAlignment >= 1,
|
||||
"Stack alignment should be a non-zero multiple of sizeof(Value)");
|
||||
|
||||
// LoongArch LSX SIMD vectors are 128 bits wide, so use 16-byte alignment for
|
||||
// SIMD constants and wasm stack alignment even while SIMD codegen is disabled.
|
||||
// TODO(loongarch64): this is just a filler to prevent a build failure. The
|
||||
// LoongArch SIMD alignment requirements still need to be explored.
|
||||
static constexpr uint32_t SimdMemoryAlignment = 16;
|
||||
|
||||
static_assert(CodeAlignment % SimdMemoryAlignment == 0,
|
||||
@@ -271,8 +260,9 @@ static constexpr uint32_t WasmCheckedTailEntryOffset = 16u;
|
||||
|
||||
static constexpr Scale ScalePointer = TimesEight;
|
||||
|
||||
// LoongArch instruction encoding constants. The assembler models the encodings
|
||||
// used by this backend as register, immediate, and jump instruction records.
|
||||
// TODO(loongarch64): Add LoongArch instruction types description.
|
||||
|
||||
// LoongArch instruction encoding constants.
|
||||
static const uint32_t RJShift = 5;
|
||||
static const uint32_t RJBits = 5;
|
||||
static const uint32_t RKShift = 10;
|
||||
@@ -313,8 +303,6 @@ static const uint32_t Imm6Shift = 10;
|
||||
static const uint32_t Imm6Bits = 6;
|
||||
static const uint32_t Imm12Shift = 10;
|
||||
static const uint32_t Imm12Bits = 12;
|
||||
static const uint32_t Imm13Shift = 5;
|
||||
static const uint32_t Imm13Bits = 13;
|
||||
static const uint32_t Imm14Shift = 10;
|
||||
static const uint32_t Imm14Bits = 14;
|
||||
static const uint32_t Imm15Shift = 0;
|
||||
@@ -345,7 +333,6 @@ static const uint32_t CODEMask = (1 << CODEBits) - 1;
|
||||
static const uint32_t Imm5Mask = (1 << Imm5Bits) - 1;
|
||||
static const uint32_t Imm6Mask = (1 << Imm6Bits) - 1;
|
||||
static const uint32_t Imm12Mask = (1 << Imm12Bits) - 1;
|
||||
static const uint32_t Imm13Mask = (1 << Imm13Bits) - 1;
|
||||
static const uint32_t Imm14Mask = (1 << Imm14Bits) - 1;
|
||||
static const uint32_t Imm15Mask = (1 << Imm15Bits) - 1;
|
||||
static const uint32_t Imm16Mask = (1 << Imm16Bits) - 1;
|
||||
@@ -357,11 +344,11 @@ static const uint32_t BOffImm21Mask = ((1 << Imm21Bits) - 1) << Imm21Shift;
|
||||
static const uint32_t BOffImm26Mask = ((1 << Imm26Bits) - 1) << Imm26Shift;
|
||||
static const uint32_t RegMask = Registers::Total - 1;
|
||||
|
||||
// TODO(loongarch64) Change to syscall?
|
||||
static const uint32_t MAX_BREAK_CODE = 1024 - 1;
|
||||
// Use LoongArch BRK for wasm traps and debug breakpoints. Signal handling code
|
||||
// decodes the BRK immediate to recover the wasm trap kind.
|
||||
static const uint32_t WASM_TRAP = 6; // BRK_OVERFLOW
|
||||
|
||||
// TODO(loongarch64) Change to LoongArch instruction type.
|
||||
class Instruction;
|
||||
class InstReg;
|
||||
class InstImm;
|
||||
@@ -441,17 +428,6 @@ enum OpcodeField {
|
||||
op_fst_s = 0xadU << 22,
|
||||
op_fld_d = 0xaeU << 22,
|
||||
op_fst_d = 0xafU << 22,
|
||||
op_vld = 0x2c000000,
|
||||
op_vst = 0x2c400000,
|
||||
op_vfcmp_clt_s = 0x0c510000,
|
||||
op_vfcmp_ceq_s = 0x0c520000,
|
||||
op_vfcmp_cle_s = 0x0c530000,
|
||||
op_vfcmp_cun_s = 0x0c540000,
|
||||
op_vfcmp_cult_s = 0x0c550000,
|
||||
op_vfcmp_cule_s = 0x0c570000,
|
||||
op_vfcmp_cune_s = 0x0c5c0000,
|
||||
op_vbitsel_v = 0x0d100000,
|
||||
op_vshuf_b = 0x0d500000,
|
||||
op_bstr_w = 0x3U << 21, // BSTRINS_W & BSTRPICK_W
|
||||
op_fmadd_s = 0x81U << 20,
|
||||
op_fmadd_d = 0x82U << 20,
|
||||
@@ -554,51 +530,6 @@ enum OpcodeField {
|
||||
op_fldx_d = 0x7068U << 15,
|
||||
op_fstx_s = 0x7070U << 15,
|
||||
op_fstx_d = 0x7078U << 15,
|
||||
op_vldx = 0x38400000,
|
||||
op_vstx = 0x38440000,
|
||||
op_vseq_w = 0x70010000,
|
||||
op_vsle_w = 0x70030000,
|
||||
op_vsle_wu = 0x70050000,
|
||||
op_vslt_w = 0x70070000,
|
||||
op_vslt_wu = 0x70090000,
|
||||
op_vadd_w = 0x700b0000,
|
||||
op_vsub_w = 0x700d0000,
|
||||
op_vmax_w = 0x70710000,
|
||||
op_vmin_w = 0x70730000,
|
||||
op_vmax_wu = 0x70750000,
|
||||
op_vmin_wu = 0x70770000,
|
||||
op_vmul_w = 0x70850000,
|
||||
op_vsll_w = 0x70e90000,
|
||||
op_vsrl_w = 0x70eb0000,
|
||||
op_vsra_w = 0x70ed0000,
|
||||
op_vilvl_w = 0x711b0000,
|
||||
op_vilvh_w = 0x711d0000,
|
||||
op_vand_v = 0x71260000,
|
||||
op_vor_v = 0x71268000,
|
||||
op_vxor_v = 0x71270000,
|
||||
op_vnor_v = 0x71278000,
|
||||
op_vandn_v = 0x71280000,
|
||||
op_vfadd_s = 0x71308000,
|
||||
op_vfsub_s = 0x71328000,
|
||||
op_vfmul_s = 0x71388000,
|
||||
op_vfmax_s = 0x713c8000,
|
||||
op_vfmin_s = 0x713e8000,
|
||||
op_vneg_w = 0x729c3800,
|
||||
op_vfsqrt_s = 0x729ce400,
|
||||
op_vfrecip_s = 0x729cf400,
|
||||
op_vfrsqrt_s = 0x729d0400,
|
||||
op_vfrint_s = 0x729d3400,
|
||||
op_vffint_s_w = 0x729e0000,
|
||||
op_vftint_w_s = 0x729e3000,
|
||||
op_vreplgr2vr_w = 0x729f0800,
|
||||
op_vreplvei_w = 0x72f7e000,
|
||||
op_vinsgr2vr_w = 0x72ebe000,
|
||||
op_vpickve2gr_w = 0x72efe000,
|
||||
op_vpickve2gr_wu = 0x72f3e000,
|
||||
op_vslli_w = 0x732c8000,
|
||||
op_vsrli_w = 0x73308000,
|
||||
op_vsrai_w = 0x73348000,
|
||||
op_vldi = 0x73e00000,
|
||||
op_amswap_w = 0x70c0U << 15,
|
||||
op_amswap_d = 0x70c1U << 15,
|
||||
op_amadd_w = 0x70c2U << 15,
|
||||
@@ -935,8 +866,7 @@ class LOONGBufferWithExecutableCopy : public LOONGBuffer {
|
||||
|
||||
class AssemblerLOONGARCH64 : public AssemblerShared {
|
||||
public:
|
||||
// Keep the shared condition vocabulary so shared MacroAssembler and
|
||||
// CodeGenerator code can lower comparisons without per-use remapping.
|
||||
// TODO(loongarch64): Should we remove these conditions here?
|
||||
enum Condition {
|
||||
Equal,
|
||||
NotEqual,
|
||||
@@ -1321,26 +1251,6 @@ class AssemblerLOONGARCH64 : public AssemblerShared {
|
||||
BufferOffset as_st_h(Register rd, Register rj, int32_t si12);
|
||||
BufferOffset as_st_w(Register rd, Register rj, int32_t si12);
|
||||
BufferOffset as_st_d(Register rd, Register rj, int32_t si12);
|
||||
BufferOffset as_vld(FloatRegister vd, Register rj, int32_t si12);
|
||||
BufferOffset as_vst(FloatRegister vd, Register rj, int32_t si12);
|
||||
BufferOffset as_vfcmp_clt_s(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk);
|
||||
BufferOffset as_vfcmp_ceq_s(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk);
|
||||
BufferOffset as_vfcmp_cle_s(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk);
|
||||
BufferOffset as_vfcmp_cun_s(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk);
|
||||
BufferOffset as_vfcmp_cult_s(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk);
|
||||
BufferOffset as_vfcmp_cule_s(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk);
|
||||
BufferOffset as_vfcmp_cune_s(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk);
|
||||
BufferOffset as_vbitsel_v(FloatRegister vd, FloatRegister vj,
|
||||
FloatRegister vk, FloatRegister va);
|
||||
BufferOffset as_vshuf_b(FloatRegister vd, FloatRegister vj, FloatRegister vk,
|
||||
FloatRegister va);
|
||||
|
||||
BufferOffset as_ldx_b(Register rd, Register rj, Register rk);
|
||||
BufferOffset as_ldx_h(Register rd, Register rj, Register rk);
|
||||
@@ -1353,51 +1263,6 @@ class AssemblerLOONGARCH64 : public AssemblerShared {
|
||||
BufferOffset as_stx_h(Register rd, Register rj, Register rk);
|
||||
BufferOffset as_stx_w(Register rd, Register rj, Register rk);
|
||||
BufferOffset as_stx_d(Register rd, Register rj, Register rk);
|
||||
BufferOffset as_vldx(FloatRegister vd, Register rj, Register rk);
|
||||
BufferOffset as_vstx(FloatRegister vd, Register rj, Register rk);
|
||||
BufferOffset as_vseq_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vsle_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vsle_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vslt_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vslt_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vadd_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vsub_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vmax_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vmin_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vmax_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vmin_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vmul_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vsll_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vsrl_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vsra_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vilvl_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vilvh_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vand_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vor_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vxor_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vnor_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vandn_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vfadd_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vfsub_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vfmul_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vfmax_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vfmin_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
|
||||
BufferOffset as_vneg_w(FloatRegister vd, FloatRegister vj);
|
||||
BufferOffset as_vfsqrt_s(FloatRegister vd, FloatRegister vj);
|
||||
BufferOffset as_vfrecip_s(FloatRegister vd, FloatRegister vj);
|
||||
BufferOffset as_vfrsqrt_s(FloatRegister vd, FloatRegister vj);
|
||||
BufferOffset as_vfrint_s(FloatRegister vd, FloatRegister vj);
|
||||
BufferOffset as_vffint_s_w(FloatRegister vd, FloatRegister vj);
|
||||
BufferOffset as_vftint_w_s(FloatRegister vd, FloatRegister vj);
|
||||
BufferOffset as_vreplgr2vr_w(FloatRegister vd, Register rj);
|
||||
BufferOffset as_vreplvei_w(FloatRegister vd, FloatRegister vj, uint32_t lane);
|
||||
BufferOffset as_vinsgr2vr_w(FloatRegister vd, Register rj, uint32_t lane);
|
||||
BufferOffset as_vpickve2gr_w(Register rd, FloatRegister vj, uint32_t lane);
|
||||
BufferOffset as_vpickve2gr_wu(Register rd, FloatRegister vj, uint32_t lane);
|
||||
BufferOffset as_vslli_w(FloatRegister vd, FloatRegister vj, uint32_t imm);
|
||||
BufferOffset as_vsrli_w(FloatRegister vd, FloatRegister vj, uint32_t imm);
|
||||
BufferOffset as_vsrai_w(FloatRegister vd, FloatRegister vj, uint32_t imm);
|
||||
BufferOffset as_vldi(FloatRegister vd, int32_t imm);
|
||||
|
||||
BufferOffset as_ldptr_w(Register rd, Register rj, int32_t si14);
|
||||
BufferOffset as_ldptr_d(Register rd, Register rj, int32_t si14);
|
||||
@@ -1614,7 +1479,7 @@ class AssemblerLOONGARCH64 : public AssemblerShared {
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
static bool SupportsSimd() { return true; }
|
||||
static bool SupportsSimd() { return false; }
|
||||
static bool SupportsUnalignedAccesses() { return true; }
|
||||
static bool SupportsFastUnalignedFPAccesses() { return true; }
|
||||
|
||||
|
||||
@@ -833,14 +833,7 @@ CodeGeneratorLoongArch64::visitWrapInt64ToInt32(LWrapInt64ToInt32* lir)
|
||||
else
|
||||
masm.ma_sll(output, ToRegister(input), Imm32(0));
|
||||
} else {
|
||||
if (input->isMemory())
|
||||
masm.load32(Address(ToAddress(input).base,
|
||||
ToAddress(input).offset + sizeof(int32_t)),
|
||||
output);
|
||||
else {
|
||||
masm.ma_dsrl(output, ToRegister(input), Imm32(32));
|
||||
masm.ma_sll(output, output, Imm32(0));
|
||||
}
|
||||
MOZ_CRASH("Not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1017,37 +1010,15 @@ CodeGeneratorLoongArch64::visitTestI64AndBranch(LTestI64AndBranch* lir)
|
||||
emitBranch(input.reg, Imm32(0), Assembler::NonZero, ifTrue, ifFalse);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorLoongArch64::visitWasmStackArg(LWasmStackArg* ins)
|
||||
{
|
||||
MIRType type = ins->mir()->input()->type();
|
||||
|
||||
if (IsSimdType(type)) {
|
||||
MOZ_ASSERT(ins->arg()->isFloatReg());
|
||||
Address dst(StackPointer, ins->mir()->spOffset());
|
||||
FloatRegister src = ToFloatRegister(ins->arg()).asSimd128();
|
||||
|
||||
if (type == MIRType::Float32x4)
|
||||
masm.storeAlignedSimd128Float(src, dst);
|
||||
else
|
||||
masm.storeAlignedSimd128Int(src, dst);
|
||||
return;
|
||||
}
|
||||
|
||||
CodeGeneratorMIPSShared::visitWasmStackArg(ins);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorLoongArch64::setReturnDoubleRegs(LiveRegisterSet* regs)
|
||||
{
|
||||
MOZ_ASSERT(ReturnFloat32Reg.encoding() == FloatRegisters::f0);
|
||||
MOZ_ASSERT(ReturnDoubleReg.encoding() == FloatRegisters::f0);
|
||||
MOZ_ASSERT(ReturnSimd128Reg.encoding() == FloatRegisters::f0);
|
||||
FloatRegister f1 = { FloatRegisters::f1, FloatRegisters::Single };
|
||||
regs->add(ReturnFloat32Reg);
|
||||
regs->add(f1);
|
||||
regs->add(ReturnDoubleReg);
|
||||
regs->add(ReturnSimd128Reg);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -65,7 +65,6 @@ class CodeGeneratorLoongArch64 : public CodeGeneratorMIPSShared
|
||||
void visitWasmUnalignedLoadI64(LWasmUnalignedLoadI64* lir);
|
||||
void visitWasmStoreI64(LWasmStoreI64* ins);
|
||||
void visitWasmUnalignedStoreI64(LWasmUnalignedStoreI64* ins);
|
||||
void visitWasmStackArg(LWasmStackArg* ins);
|
||||
void visitWasmLoadGlobalVarI64(LWasmLoadGlobalVarI64* ins);
|
||||
void visitWasmStoreGlobalVarI64(LWasmStoreGlobalVarI64* ins);
|
||||
void visitWasmSelectI64(LWasmSelectI64* ins);
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "jit/loongarch64/MacroAssembler-loongarch64.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "jsmath.h"
|
||||
|
||||
#include "jit/Bailouts.h"
|
||||
@@ -957,13 +955,8 @@ void MacroAssemblerLOONGARCH64::ma_subPtrTestOverflow(Register rd, Register rj,
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_subPtrTestOverflow(Register rd, Register rj,
|
||||
Imm32 imm, Label* overflow) {
|
||||
if (imm.value == INT32_MIN) {
|
||||
SecondScratchRegisterScope scratch2(asMasm());
|
||||
ma_li(scratch2, imm);
|
||||
ma_subPtrTestOverflow(rd, rj, scratch2, overflow);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(loongarch64): Check subPtrTestOverflow
|
||||
MOZ_ASSERT(imm.value != INT32_MIN);
|
||||
ma_addPtrTestOverflow(rd, rj, Imm32(-imm.value), overflow);
|
||||
}
|
||||
|
||||
@@ -1301,20 +1294,10 @@ void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Register rj, ImmPtr imm,
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Address address, Imm32 imm,
|
||||
Condition c) {
|
||||
// TODO(loongarch64): 32-bit ma_cmp_set?
|
||||
SecondScratchRegisterScope scratch2(asMasm());
|
||||
switch (c) {
|
||||
case Above:
|
||||
case AboveOrEqual:
|
||||
case Below:
|
||||
case BelowOrEqual:
|
||||
ma_ld_wu(scratch2, address);
|
||||
ma_cmp_set(rd, Register(scratch2), ImmWord(uint32_t(imm.value)), c);
|
||||
break;
|
||||
default:
|
||||
ma_ld_w(scratch2, address);
|
||||
ma_cmp_set(rd, Register(scratch2), imm, c);
|
||||
break;
|
||||
}
|
||||
ma_ld_w(scratch2, address);
|
||||
ma_cmp_set(rd, Register(scratch2), imm, c);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Address address,
|
||||
@@ -1401,36 +1384,6 @@ void MacroAssemblerLOONGARCH64::ma_fst_d(FloatRegister src, Address address) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_vld(FloatRegister dest, Address address) {
|
||||
MOZ_ASSERT(dest.isSimd128());
|
||||
int32_t offset = address.offset;
|
||||
Register base = address.base;
|
||||
|
||||
if (is_intN(offset, 12)) {
|
||||
as_vld(dest, base, offset);
|
||||
} else {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
MOZ_ASSERT(base != scratch);
|
||||
ma_li(scratch, Imm32(offset));
|
||||
as_vldx(dest, base, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_vst(FloatRegister src, Address address) {
|
||||
MOZ_ASSERT(src.isSimd128());
|
||||
int32_t offset = address.offset;
|
||||
Register base = address.base;
|
||||
|
||||
if (is_intN(offset, 12)) {
|
||||
as_vst(src, base, offset);
|
||||
} else {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
MOZ_ASSERT(base != scratch);
|
||||
ma_li(scratch, Imm32(offset));
|
||||
as_vstx(src, base, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_pop(FloatRegister f) {
|
||||
if (f.isDouble()) {
|
||||
as_fld_d(f, StackPointer, 0);
|
||||
@@ -1894,19 +1847,12 @@ void MacroAssemblerLOONGARCH64::storeUnalignedFloat32(
|
||||
}
|
||||
|
||||
// Branches when done from within loongarch-specific code.
|
||||
// TODO(loongarch64) Optimize ma_b
|
||||
void MacroAssemblerLOONGARCH64::ma_b(Register lhs, Register rhs, Label* label,
|
||||
Condition c, JumpKind jumpKind) {
|
||||
switch (c) {
|
||||
case Equal:
|
||||
case NotEqual:
|
||||
case Above:
|
||||
case AboveOrEqual:
|
||||
case Below:
|
||||
case BelowOrEqual:
|
||||
case GreaterThan:
|
||||
case GreaterThanOrEqual:
|
||||
case LessThan:
|
||||
case LessThanOrEqual:
|
||||
asMasm().branchWithCode(getBranchCode(lhs, rhs, c), label, jumpKind);
|
||||
break;
|
||||
case Always:
|
||||
@@ -1919,8 +1865,12 @@ void MacroAssemblerLOONGARCH64::ma_b(Register lhs, Register rhs, Label* label,
|
||||
MOZ_ASSERT(lhs == rhs);
|
||||
asMasm().branchWithCode(getBranchCode(lhs, c), label, jumpKind);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Invalid condition.");
|
||||
default: {
|
||||
Condition cond = ma_cmp(ScratchRegister, lhs, rhs, c);
|
||||
asMasm().branchWithCode(getBranchCode(ScratchRegister, cond), label,
|
||||
jumpKind);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2096,12 +2046,6 @@ void MacroAssemblerLOONGARCH64::ma_fst_s(FloatRegister ft, BaseIndex address) {
|
||||
asMasm().ma_fst_s(ft, Address(scratch2, address.offset));
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_vst(FloatRegister ft, BaseIndex address) {
|
||||
SecondScratchRegisterScope scratch2(asMasm());
|
||||
asMasm().computeScaledAddress(address, scratch2);
|
||||
asMasm().ma_vst(ft, Address(scratch2, address.offset));
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_fld_d(FloatRegister ft, const BaseIndex& src) {
|
||||
SecondScratchRegisterScope scratch2(asMasm());
|
||||
asMasm().computeScaledAddress(src, scratch2);
|
||||
@@ -2114,12 +2058,6 @@ void MacroAssemblerLOONGARCH64::ma_fld_s(FloatRegister ft, const BaseIndex& src)
|
||||
asMasm().ma_fld_s(ft, Address(scratch2, src.offset));
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_vld(FloatRegister ft, const BaseIndex& src) {
|
||||
SecondScratchRegisterScope scratch2(asMasm());
|
||||
asMasm().computeScaledAddress(src, scratch2);
|
||||
asMasm().ma_vld(ft, Address(scratch2, src.offset));
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::ma_bc_s(FloatRegister lhs, FloatRegister rhs,
|
||||
Label* label, DoubleCondition c,
|
||||
JumpKind jumpKind, FPConditionBit fcc) {
|
||||
@@ -2452,390 +2390,6 @@ void MacroAssemblerLOONGARCH64::loadFloat32(const BaseIndex& src,
|
||||
asMasm().ma_fld_s(dest, src);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::loadUnalignedSimd128Float(const Address& src,
|
||||
FloatRegister dest) {
|
||||
asMasm().ma_vld(dest.asSimd128(), src);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::loadUnalignedSimd128Float(const BaseIndex& src,
|
||||
FloatRegister dest) {
|
||||
asMasm().ma_vld(dest.asSimd128(), src);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::storeUnalignedSimd128Float(FloatRegister src,
|
||||
const Address& dest) {
|
||||
asMasm().ma_vst(src.asSimd128(), dest);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::storeUnalignedSimd128Float(FloatRegister src,
|
||||
const BaseIndex& dest) {
|
||||
asMasm().ma_vst(src.asSimd128(), dest);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::loadConstantSimd128Int(const SimdConstant& v,
|
||||
FloatRegister dest) {
|
||||
uint64_t words[2];
|
||||
memcpy(words, v.bytes(), sizeof(words));
|
||||
|
||||
ma_add_d(StackPointer, StackPointer, Imm32(-Simd128DataSize));
|
||||
{
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
ma_li(scratch, ImmWord(words[0]));
|
||||
ma_st_d(scratch, Address(StackPointer, 0));
|
||||
ma_li(scratch, ImmWord(words[1]));
|
||||
ma_st_d(scratch, Address(StackPointer, sizeof(uint64_t)));
|
||||
}
|
||||
loadAlignedSimd128Int(Address(StackPointer, 0), dest);
|
||||
ma_add_d(StackPointer, StackPointer, Imm32(Simd128DataSize));
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::loadConstantSimd128Float(const SimdConstant& v,
|
||||
FloatRegister dest) {
|
||||
loadConstantSimd128Int(v, dest);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::moveSimd128Float(FloatRegister src,
|
||||
FloatRegister dest) {
|
||||
src = src.asSimd128();
|
||||
dest = dest.asSimd128();
|
||||
if (src == dest) {
|
||||
return;
|
||||
}
|
||||
as_vor_v(dest, src, src);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::zeroSimd128Float(FloatRegister dest) {
|
||||
dest = dest.asSimd128();
|
||||
as_vxor_v(dest, dest, dest);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::createInt32x4(Register lane0, Register lane1,
|
||||
Register lane2, Register lane3,
|
||||
FloatRegister dest) {
|
||||
dest = dest.asSimd128();
|
||||
as_vreplgr2vr_w(dest, lane0);
|
||||
as_vinsgr2vr_w(dest, lane1, 1);
|
||||
as_vinsgr2vr_w(dest, lane2, 2);
|
||||
as_vinsgr2vr_w(dest, lane3, 3);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::splatX4(Register input, FloatRegister output) {
|
||||
as_vreplgr2vr_w(output.asSimd128(), input);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::splatX4(FloatRegister input,
|
||||
FloatRegister output) {
|
||||
as_vreplvei_w(output.asSimd128(), input.asSimd128(), 0);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::extractLaneInt32x4(FloatRegister input,
|
||||
Register output,
|
||||
unsigned lane) {
|
||||
as_vpickve2gr_w(output, input.asSimd128(), lane);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::extractLaneFloat32x4(FloatRegister input,
|
||||
FloatRegister output,
|
||||
unsigned lane,
|
||||
bool canonicalize) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
as_vpickve2gr_w(scratch, input.asSimd128(), lane);
|
||||
moveToFloat32(scratch, output);
|
||||
if (canonicalize) {
|
||||
asMasm().canonicalizeFloat(output);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::insertLaneSimdInt(FloatRegister input,
|
||||
Register value,
|
||||
FloatRegister output,
|
||||
unsigned lane,
|
||||
unsigned numLanes) {
|
||||
MOZ_ASSERT(numLanes == 4);
|
||||
if (input != output) {
|
||||
moveSimd128Int(input, output);
|
||||
}
|
||||
as_vinsgr2vr_w(output.asSimd128(), value, lane);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::insertLaneFloat32x4(FloatRegister input,
|
||||
FloatRegister value,
|
||||
FloatRegister output,
|
||||
unsigned lane) {
|
||||
if (input != output) {
|
||||
moveSimd128Float(input, output);
|
||||
}
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
moveFromFloat32(value, scratch);
|
||||
as_vinsgr2vr_w(output.asSimd128(), scratch, lane);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::addInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vadd_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::subInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vsub_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::mulInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vmul_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::minInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vmin_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::maxInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vmax_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::minUint32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vmin_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::maxUint32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vmax_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::negInt32x4(FloatRegister input,
|
||||
FloatRegister dest) {
|
||||
as_vneg_w(dest.asSimd128(), input.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::shiftLeftInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vsll_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::shiftRightInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vsra_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::unsignedShiftRightInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vsrl_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::shiftLeftInt32x4(FloatRegister lhs, Imm32 rhs,
|
||||
FloatRegister dest) {
|
||||
as_vslli_w(dest.asSimd128(), lhs.asSimd128(), rhs.value & 31);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::shiftRightInt32x4(FloatRegister lhs, Imm32 rhs,
|
||||
FloatRegister dest) {
|
||||
as_vsrai_w(dest.asSimd128(), lhs.asSimd128(), rhs.value & 31);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::unsignedShiftRightInt32x4(FloatRegister lhs,
|
||||
Imm32 rhs,
|
||||
FloatRegister dest) {
|
||||
as_vsrli_w(dest.asSimd128(), lhs.asSimd128(), rhs.value & 31);
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareInt32x4Equal(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vseq_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareInt32x4LessThan(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vslt_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareInt32x4LessThanOrEqual(
|
||||
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
|
||||
as_vsle_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareUint32x4LessThan(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vslt_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareUint32x4LessThanOrEqual(
|
||||
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
|
||||
as_vsle_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::addFloat32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfadd_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::subFloat32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfsub_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::mulFloat32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfmul_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::minFloat32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfmin_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::maxFloat32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfmax_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::sqrtFloat32x4(FloatRegister input,
|
||||
FloatRegister dest) {
|
||||
as_vfsqrt_s(dest.asSimd128(), input.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::reciprocalApproximationFloat32x4(
|
||||
FloatRegister input, FloatRegister dest) {
|
||||
as_vfrecip_s(dest.asSimd128(), input.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::reciprocalSqrtApproximationFloat32x4(
|
||||
FloatRegister input, FloatRegister dest) {
|
||||
as_vfrsqrt_s(dest.asSimd128(), input.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::roundFloat32x4(FloatRegister input,
|
||||
FloatRegister dest) {
|
||||
as_vfrint_s(dest.asSimd128(), input.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::convertInt32x4ToFloat32x4(FloatRegister input,
|
||||
FloatRegister dest) {
|
||||
as_vffint_s_w(dest.asSimd128(), input.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::convertFloat32x4ToInt32x4(FloatRegister input,
|
||||
FloatRegister dest) {
|
||||
as_vftint_w_s(dest.asSimd128(), input.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareFloat32x4Equal(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfcmp_ceq_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareFloat32x4NotEqual(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfcmp_cune_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareFloat32x4LessThan(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfcmp_clt_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareFloat32x4LessThanOrEqual(
|
||||
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
|
||||
as_vfcmp_cle_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareFloat32x4Unordered(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vfcmp_cun_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareFloat32x4UnorderedLessThan(
|
||||
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
|
||||
as_vfcmp_cult_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::compareFloat32x4UnorderedLessThanOrEqual(
|
||||
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
|
||||
as_vfcmp_cule_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::interleaveLowInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vilvl_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::interleaveHighInt32x4(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vilvh_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::bitselectSimd128(FloatRegister mask,
|
||||
FloatRegister onTrue,
|
||||
FloatRegister onFalse,
|
||||
FloatRegister dest) {
|
||||
as_vbitsel_v(dest.asSimd128(), onFalse.asSimd128(), onTrue.asSimd128(),
|
||||
mask.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::shuffleBytesSimd128(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister control,
|
||||
FloatRegister dest) {
|
||||
as_vshuf_b(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128(),
|
||||
control.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::bitwiseAndSimd128(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vand_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::bitwiseOrSimd128(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vor_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::bitwiseXorSimd128(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vxor_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::bitwiseNorSimd128(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vnor_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::bitwiseAndNotSimd128(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest) {
|
||||
as_vandn_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
|
||||
}
|
||||
|
||||
void MacroAssemblerLOONGARCH64::wasmLoadImpl(const wasm::MemoryAccessDesc& access,
|
||||
Register memoryBase, Register ptr,
|
||||
Register ptrScratch,
|
||||
@@ -2962,8 +2516,7 @@ void MacroAssemblerLOONGARCH64Compat::wasmLoadI64Impl(
|
||||
as_ldx_w(output.reg, memoryBase, ptr);
|
||||
break;
|
||||
case Scalar::Uint32:
|
||||
// Uint32 loads must clear the upper 32 bits before the value is consumed
|
||||
// by 64-bit wasm operations.
|
||||
// TODO(loongarch64): Why need zero-extension here?
|
||||
as_ldx_wu(output.reg, memoryBase, ptr);
|
||||
break;
|
||||
case Scalar::Int64:
|
||||
@@ -3064,18 +2617,14 @@ void MacroAssembler::PushRegsInMask(LiveRegisterSet set) {
|
||||
storePtr(*iter, Address(StackPointer, diff));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WASM_SIMD
|
||||
# error "Needs more careful logic if SIMD is enabled"
|
||||
#endif
|
||||
|
||||
for (FloatRegisterBackwardIterator iter(set.fpus().reduceSetForPush());
|
||||
iter.more(); ++iter) {
|
||||
FloatRegister reg = *iter;
|
||||
diff -= reg.size();
|
||||
if (reg.isSingle()) {
|
||||
storeFloat32(reg, Address(StackPointer, diff));
|
||||
} else if (reg.isSimd128()) {
|
||||
storeUnalignedSimd128Float(reg, Address(StackPointer, diff));
|
||||
} else {
|
||||
MOZ_ASSERT(reg.isDouble());
|
||||
storeDouble(reg, Address(StackPointer, diff));
|
||||
}
|
||||
diff -= sizeof(double);
|
||||
storeDouble(*iter, Address(StackPointer, diff));
|
||||
}
|
||||
MOZ_ASSERT(diff == 0);
|
||||
}
|
||||
@@ -3093,19 +2642,15 @@ void MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WASM_SIMD
|
||||
# error "Needs more careful logic if SIMD is enabled"
|
||||
#endif
|
||||
|
||||
for (FloatRegisterBackwardIterator iter(set.fpus().reduceSetForPush());
|
||||
iter.more(); ++iter) {
|
||||
FloatRegister reg = *iter;
|
||||
diff -= reg.size();
|
||||
diff -= sizeof(double);
|
||||
if (!ignore.has(*iter)) {
|
||||
if (reg.isSingle()) {
|
||||
loadFloat32(Address(StackPointer, diff), reg);
|
||||
} else if (reg.isSimd128()) {
|
||||
loadUnalignedSimd128Float(Address(StackPointer, diff), reg);
|
||||
} else {
|
||||
MOZ_ASSERT(reg.isDouble());
|
||||
loadDouble(Address(StackPointer, diff), reg);
|
||||
}
|
||||
loadDouble(Address(StackPointer, diff), *iter);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(diff == 0);
|
||||
|
||||
@@ -199,8 +199,6 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
|
||||
void ma_fld_d(FloatRegister ft, Address address);
|
||||
void ma_fst_d(FloatRegister ft, Address address);
|
||||
void ma_fst_s(FloatRegister ft, Address address);
|
||||
void ma_vld(FloatRegister vt, Address address);
|
||||
void ma_vst(FloatRegister vt, Address address);
|
||||
|
||||
void ma_pop(FloatRegister f);
|
||||
void ma_push(FloatRegister f);
|
||||
@@ -453,11 +451,9 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
|
||||
|
||||
void ma_fst_d(FloatRegister src, BaseIndex address);
|
||||
void ma_fst_s(FloatRegister src, BaseIndex address);
|
||||
void ma_vst(FloatRegister src, BaseIndex address);
|
||||
|
||||
void ma_fld_d(FloatRegister dest, const BaseIndex& src);
|
||||
void ma_fld_s(FloatRegister dest, const BaseIndex& src);
|
||||
void ma_vld(FloatRegister dest, const BaseIndex& src);
|
||||
|
||||
// FP branches
|
||||
void ma_bc_s(FloatRegister lhs, FloatRegister rhs, Label* label,
|
||||
@@ -635,139 +631,6 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
|
||||
void loadFloat32(const Address& addr, FloatRegister dest);
|
||||
void loadFloat32(const BaseIndex& src, FloatRegister dest);
|
||||
|
||||
void loadUnalignedSimd128Float(const Address& src, FloatRegister dest);
|
||||
void loadUnalignedSimd128Float(const BaseIndex& src, FloatRegister dest);
|
||||
void storeUnalignedSimd128Float(FloatRegister src, const Address& dest);
|
||||
void storeUnalignedSimd128Float(FloatRegister src, const BaseIndex& dest);
|
||||
void loadAlignedSimd128Float(const Address& src, FloatRegister dest) {
|
||||
loadUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void loadAlignedSimd128Float(const BaseIndex& src, FloatRegister dest) {
|
||||
loadUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void storeAlignedSimd128Float(FloatRegister src, const Address& dest) {
|
||||
storeUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void storeAlignedSimd128Float(FloatRegister src, const BaseIndex& dest) {
|
||||
storeUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void loadConstantSimd128Float(const SimdConstant& v, FloatRegister dest);
|
||||
void loadConstantSimd128Int(const SimdConstant& v, FloatRegister dest);
|
||||
void moveSimd128Float(FloatRegister src, FloatRegister dest);
|
||||
void moveSimd128Int(FloatRegister src, FloatRegister dest) {
|
||||
moveSimd128Float(src, dest);
|
||||
}
|
||||
void zeroSimd128Float(FloatRegister dest);
|
||||
void zeroSimd128Int(FloatRegister dest) { zeroSimd128Float(dest); }
|
||||
void createInt32x4(Register lane0, Register lane1, Register lane2,
|
||||
Register lane3, FloatRegister dest);
|
||||
void splatX4(Register input, FloatRegister output);
|
||||
void splatX4(FloatRegister input, FloatRegister output);
|
||||
void extractLaneInt32x4(FloatRegister input, Register output, unsigned lane);
|
||||
void extractLaneFloat32x4(FloatRegister input, FloatRegister output,
|
||||
unsigned lane, bool canonicalize);
|
||||
void insertLaneSimdInt(FloatRegister input, Register value,
|
||||
FloatRegister output, unsigned lane,
|
||||
unsigned numLanes);
|
||||
void insertLaneFloat32x4(FloatRegister input, FloatRegister value,
|
||||
FloatRegister output, unsigned lane);
|
||||
void addInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void subInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void mulInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void minInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void maxInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void minUint32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void maxUint32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void negInt32x4(FloatRegister input, FloatRegister dest);
|
||||
void shiftLeftInt32x4(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void shiftRightInt32x4(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void unsignedShiftRightInt32x4(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void shiftLeftInt32x4(FloatRegister lhs, Imm32 rhs, FloatRegister dest);
|
||||
void shiftRightInt32x4(FloatRegister lhs, Imm32 rhs, FloatRegister dest);
|
||||
void unsignedShiftRightInt32x4(FloatRegister lhs, Imm32 rhs,
|
||||
FloatRegister dest);
|
||||
void compareInt32x4Equal(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareInt32x4LessThan(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareInt32x4LessThanOrEqual(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareUint32x4LessThan(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareUint32x4LessThanOrEqual(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void addFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void subFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void mulFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void minFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void maxFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
|
||||
void sqrtFloat32x4(FloatRegister input, FloatRegister dest);
|
||||
void reciprocalApproximationFloat32x4(FloatRegister input, FloatRegister dest);
|
||||
void reciprocalSqrtApproximationFloat32x4(FloatRegister input,
|
||||
FloatRegister dest);
|
||||
void roundFloat32x4(FloatRegister input, FloatRegister dest);
|
||||
void convertInt32x4ToFloat32x4(FloatRegister input, FloatRegister dest);
|
||||
void convertFloat32x4ToInt32x4(FloatRegister input, FloatRegister dest);
|
||||
void compareFloat32x4Equal(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareFloat32x4NotEqual(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareFloat32x4LessThan(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareFloat32x4LessThanOrEqual(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareFloat32x4Unordered(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareFloat32x4UnorderedLessThan(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void compareFloat32x4UnorderedLessThanOrEqual(FloatRegister lhs,
|
||||
FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void interleaveLowInt32x4(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void interleaveHighInt32x4(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void bitselectSimd128(FloatRegister mask, FloatRegister onTrue,
|
||||
FloatRegister onFalse, FloatRegister dest);
|
||||
void shuffleBytesSimd128(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister control, FloatRegister dest);
|
||||
void bitwiseAndSimd128(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void bitwiseOrSimd128(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void bitwiseXorSimd128(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void bitwiseNorSimd128(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void bitwiseAndNotSimd128(FloatRegister lhs, FloatRegister rhs,
|
||||
FloatRegister dest);
|
||||
void loadUnalignedSimd128Int(const Address& src, FloatRegister dest) {
|
||||
loadUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void loadUnalignedSimd128Int(const BaseIndex& src, FloatRegister dest) {
|
||||
loadUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void loadAlignedSimd128Int(const Address& src, FloatRegister dest) {
|
||||
loadUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void loadAlignedSimd128Int(const BaseIndex& src, FloatRegister dest) {
|
||||
loadUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void storeUnalignedSimd128Int(FloatRegister src, const Address& dest) {
|
||||
storeUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void storeUnalignedSimd128Int(FloatRegister src, const BaseIndex& dest) {
|
||||
storeUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void storeAlignedSimd128Int(FloatRegister src, const Address& dest) {
|
||||
storeUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
void storeAlignedSimd128Int(FloatRegister src, const BaseIndex& dest) {
|
||||
storeUnalignedSimd128Float(src, dest);
|
||||
}
|
||||
|
||||
protected:
|
||||
void wasmLoadImpl(const wasm::MemoryAccessDesc& access, Register memoryBase,
|
||||
|
||||
@@ -10,75 +10,6 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
Address
|
||||
MoveEmitterLoongArch64::cycleSlot(uint32_t slot, uint32_t subslot) const
|
||||
{
|
||||
int32_t offset = masm.framePushed() - pushedAtCycle_;
|
||||
MOZ_ASSERT(Imm16::IsInSignedRange(offset));
|
||||
return Address(StackPointer, offset + slot * Simd128DataSize + subslot);
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterLoongArch64::emit(const MoveResolver& moves)
|
||||
{
|
||||
if (moves.numCycles()) {
|
||||
masm.reserveStack(moves.numCycles() * Simd128DataSize);
|
||||
pushedAtCycle_ = masm.framePushed();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < moves.numMoves(); i++)
|
||||
emit(moves.getMove(i));
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterLoongArch64::emit(const MoveOp& move)
|
||||
{
|
||||
const MoveOperand& from = move.from();
|
||||
const MoveOperand& to = move.to();
|
||||
|
||||
if (move.isCycleEnd() && move.isCycleBegin()) {
|
||||
breakCycle(from, to, move.endCycleType(), move.cycleBeginSlot());
|
||||
completeCycle(from, to, move.type(), move.cycleEndSlot());
|
||||
return;
|
||||
}
|
||||
|
||||
if (move.isCycleEnd()) {
|
||||
MOZ_ASSERT(inCycle_);
|
||||
completeCycle(from, to, move.type(), move.cycleEndSlot());
|
||||
MOZ_ASSERT(inCycle_ > 0);
|
||||
inCycle_--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (move.isCycleBegin()) {
|
||||
breakCycle(from, to, move.endCycleType(), move.cycleBeginSlot());
|
||||
inCycle_++;
|
||||
}
|
||||
|
||||
switch (move.type()) {
|
||||
case MoveOp::FLOAT32:
|
||||
emitFloat32Move(from, to);
|
||||
break;
|
||||
case MoveOp::DOUBLE:
|
||||
emitDoubleMove(from, to);
|
||||
break;
|
||||
case MoveOp::INT32:
|
||||
emitInt32Move(from, to);
|
||||
break;
|
||||
case MoveOp::GENERAL:
|
||||
emitMove(from, to);
|
||||
break;
|
||||
case MoveOp::SIMD128INT:
|
||||
emitSimd128IntMove(from, to);
|
||||
break;
|
||||
case MoveOp::SIMD128FLOAT:
|
||||
emitSimd128FloatMove(from, to);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected move type");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterLoongArch64::breakCycle(const MoveOperand& from, const MoveOperand& to,
|
||||
MoveOp::Type type, uint32_t slotId)
|
||||
@@ -102,24 +33,6 @@ MoveEmitterLoongArch64::breakCycle(const MoveOperand& from, const MoveOperand& t
|
||||
masm.storeDouble(to.floatReg(), cycleSlot(slotId));
|
||||
}
|
||||
break;
|
||||
case MoveOp::SIMD128INT:
|
||||
if (to.isMemory()) {
|
||||
FloatRegister temp = ScratchSimd128Reg;
|
||||
masm.loadAlignedSimd128Int(getAdjustedAddress(to), temp);
|
||||
masm.storeAlignedSimd128Int(temp, cycleSlot(slotId));
|
||||
} else {
|
||||
masm.storeAlignedSimd128Int(to.floatReg(), cycleSlot(slotId));
|
||||
}
|
||||
break;
|
||||
case MoveOp::SIMD128FLOAT:
|
||||
if (to.isMemory()) {
|
||||
FloatRegister temp = ScratchSimd128Reg;
|
||||
masm.loadAlignedSimd128Float(getAdjustedAddress(to), temp);
|
||||
masm.storeAlignedSimd128Float(temp, cycleSlot(slotId));
|
||||
} else {
|
||||
masm.storeAlignedSimd128Float(to.floatReg(), cycleSlot(slotId));
|
||||
}
|
||||
break;
|
||||
case MoveOp::INT32:
|
||||
if (to.isMemory()) {
|
||||
Register temp = tempReg();
|
||||
@@ -168,24 +81,6 @@ MoveEmitterLoongArch64::completeCycle(const MoveOperand& from, const MoveOperand
|
||||
masm.loadDouble(cycleSlot(slotId), to.floatReg());
|
||||
}
|
||||
break;
|
||||
case MoveOp::SIMD128INT:
|
||||
if (to.isMemory()) {
|
||||
FloatRegister temp = ScratchSimd128Reg;
|
||||
masm.loadAlignedSimd128Int(cycleSlot(slotId), temp);
|
||||
masm.storeAlignedSimd128Int(temp, getAdjustedAddress(to));
|
||||
} else {
|
||||
masm.loadAlignedSimd128Int(cycleSlot(slotId), to.floatReg());
|
||||
}
|
||||
break;
|
||||
case MoveOp::SIMD128FLOAT:
|
||||
if (to.isMemory()) {
|
||||
FloatRegister temp = ScratchSimd128Reg;
|
||||
masm.loadAlignedSimd128Float(cycleSlot(slotId), temp);
|
||||
masm.storeAlignedSimd128Float(temp, getAdjustedAddress(to));
|
||||
} else {
|
||||
masm.loadAlignedSimd128Float(cycleSlot(slotId), to.floatReg());
|
||||
}
|
||||
break;
|
||||
case MoveOp::INT32:
|
||||
MOZ_ASSERT(slotId == 0);
|
||||
if (to.isMemory()) {
|
||||
@@ -213,56 +108,6 @@ MoveEmitterLoongArch64::completeCycle(const MoveOperand& from, const MoveOperand
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterLoongArch64::emitSimd128IntMove(const MoveOperand& from, const MoveOperand& to)
|
||||
{
|
||||
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isSimd128());
|
||||
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isSimd128());
|
||||
|
||||
if (from.isFloatReg()) {
|
||||
if (to.isFloatReg()) {
|
||||
masm.moveSimd128Int(from.floatReg(), to.floatReg());
|
||||
} else {
|
||||
MOZ_ASSERT(to.isMemory());
|
||||
masm.storeAlignedSimd128Int(from.floatReg(), getAdjustedAddress(to));
|
||||
}
|
||||
} else if (to.isFloatReg()) {
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
masm.loadAlignedSimd128Int(getAdjustedAddress(from), to.floatReg());
|
||||
} else {
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
MOZ_ASSERT(to.isMemory());
|
||||
FloatRegister temp = ScratchSimd128Reg;
|
||||
masm.loadAlignedSimd128Int(getAdjustedAddress(from), temp);
|
||||
masm.storeAlignedSimd128Int(temp, getAdjustedAddress(to));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterLoongArch64::emitSimd128FloatMove(const MoveOperand& from, const MoveOperand& to)
|
||||
{
|
||||
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isSimd128());
|
||||
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isSimd128());
|
||||
|
||||
if (from.isFloatReg()) {
|
||||
if (to.isFloatReg()) {
|
||||
masm.moveSimd128Float(from.floatReg(), to.floatReg());
|
||||
} else {
|
||||
MOZ_ASSERT(to.isMemory());
|
||||
masm.storeAlignedSimd128Float(from.floatReg(), getAdjustedAddress(to));
|
||||
}
|
||||
} else if (to.isFloatReg()) {
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
masm.loadAlignedSimd128Float(getAdjustedAddress(from), to.floatReg());
|
||||
} else {
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
MOZ_ASSERT(to.isMemory());
|
||||
FloatRegister temp = ScratchSimd128Reg;
|
||||
masm.loadAlignedSimd128Float(getAdjustedAddress(from), temp);
|
||||
masm.storeAlignedSimd128Float(temp, getAdjustedAddress(to));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterLoongArch64::emitDoubleMove(const MoveOperand& from, const MoveOperand& to)
|
||||
{
|
||||
|
||||
@@ -13,13 +13,7 @@ namespace jit {
|
||||
|
||||
class MoveEmitterLoongArch64 : public MoveEmitterMIPSShared
|
||||
{
|
||||
Address cycleSlot(uint32_t slot, uint32_t subslot = 0) const;
|
||||
|
||||
void emitDoubleMove(const MoveOperand& from, const MoveOperand& to);
|
||||
void emitSimd128IntMove(const MoveOperand& from, const MoveOperand& to);
|
||||
void emitSimd128FloatMove(const MoveOperand& from, const MoveOperand& to);
|
||||
void emit(const MoveOp& move);
|
||||
|
||||
void breakCycle(const MoveOperand& from, const MoveOperand& to,
|
||||
MoveOp::Type type, uint32_t slot);
|
||||
void completeCycle(const MoveOperand& from, const MoveOperand& to,
|
||||
@@ -29,8 +23,6 @@ class MoveEmitterLoongArch64 : public MoveEmitterMIPSShared
|
||||
MoveEmitterLoongArch64(MacroAssembler& masm)
|
||||
: MoveEmitterMIPSShared(masm)
|
||||
{ }
|
||||
|
||||
void emit(const MoveResolver& moves);
|
||||
};
|
||||
|
||||
typedef MoveEmitterLoongArch64 MoveEmitter;
|
||||
|
||||
@@ -874,13 +874,6 @@ MacroAssembler::branchTestSymbol(Condition cond, Register tag, Label* label)
|
||||
ma_b(tag, ImmTag(JSVAL_TAG_SYMBOL), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestBigInt(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
ma_b(tag, ImmTag(JSVAL_TAG_BIGINT), label, cond);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchTestSymbol(Condition cond, const BaseIndex& address, Label* label)
|
||||
{
|
||||
|
||||
@@ -614,25 +614,6 @@ CodeGeneratorMIPS64::visitExtendInt32ToInt64(LExtendInt32ToInt64* lir)
|
||||
masm.ma_sll(output, ToRegister(input), Imm32(0));
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPS64::visitSignExtendInt64(LSignExtendInt64* lir)
|
||||
{
|
||||
Register64 input = ToRegister64(lir->getInt64Operand(0));
|
||||
Register64 output = ToOutRegister64(lir);
|
||||
|
||||
switch (lir->mode()) {
|
||||
case MSignExtendInt64::Byte:
|
||||
masm.move8SignExtend(input.reg, output.reg);
|
||||
break;
|
||||
case MSignExtendInt64::Half:
|
||||
masm.move16SignExtend(input.reg, output.reg);
|
||||
break;
|
||||
case MSignExtendInt64::Word:
|
||||
masm.ma_sll(output.reg, input.reg, Imm32(0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPS64::visitWrapInt64ToInt32(LWrapInt64ToInt32* lir)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,6 @@ class CodeGeneratorMIPS64 : public CodeGeneratorMIPSShared
|
||||
void visitWasmReinterpretFromI64(LWasmReinterpretFromI64* lir);
|
||||
void visitWasmReinterpretToI64(LWasmReinterpretToI64* lir);
|
||||
void visitExtendInt32ToInt64(LExtendInt32ToInt64* lir);
|
||||
void visitSignExtendInt64(LSignExtendInt64* lir);
|
||||
void visitWrapInt64ToInt32(LWrapInt64ToInt32* lir);
|
||||
void visitClzI64(LClzI64* lir);
|
||||
void visitCtzI64(LCtzI64* lir);
|
||||
|
||||
@@ -184,9 +184,3 @@ LIRGeneratorMIPS64::visitRandom(MRandom* ins)
|
||||
temp());
|
||||
defineFixed(lir, ins, LFloatReg(ReturnDoubleReg));
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorMIPS64::visitSignExtendInt64(MSignExtendInt64* ins)
|
||||
{
|
||||
defineInt64(new(alloc()) LSignExtendInt64(useInt64RegisterAtStart(ins->input())), ins);
|
||||
}
|
||||
@@ -46,7 +46,6 @@ class LIRGeneratorMIPS64 : public LIRGeneratorMIPSShared
|
||||
void visitUnbox(MUnbox* unbox);
|
||||
void visitReturn(MReturn* ret);
|
||||
void visitRandom(MRandom* ins);
|
||||
void visitSignExtendInt64(MSignExtendInt64* ins);
|
||||
};
|
||||
|
||||
typedef LIRGeneratorMIPS64 LIRGeneratorSpecific;
|
||||
|
||||
@@ -364,18 +364,6 @@ MacroAssembler::rshift64Arithmetic(Register shift, Register64 dest)
|
||||
// ===============================================================
|
||||
// Rotation functions
|
||||
|
||||
void
|
||||
MacroAssembler::rotateLeft64(Imm32 count, Register64 src, Register64 dest)
|
||||
{
|
||||
rotateLeft64(count, src, dest, InvalidReg);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rotateLeft64(Register count, Register64 src, Register64 dest)
|
||||
{
|
||||
rotateLeft64(count, src, dest, InvalidReg);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rotateLeft64(Imm32 count, Register64 src, Register64 dest, Register temp)
|
||||
{
|
||||
@@ -394,18 +382,6 @@ MacroAssembler::rotateLeft64(Register count, Register64 src, Register64 dest, Re
|
||||
ma_drol(dest.reg, src.reg, count);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rotateRight64(Imm32 count, Register64 src, Register64 dest)
|
||||
{
|
||||
rotateRight64(count, src, dest, InvalidReg);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rotateRight64(Register count, Register64 src, Register64 dest)
|
||||
{
|
||||
rotateRight64(count, src, dest, InvalidReg);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rotateRight64(Imm32 count, Register64 src, Register64 dest, Register temp)
|
||||
{
|
||||
|
||||
@@ -1497,17 +1497,17 @@ MacroAssemblerMIPS64Compat::unboxSymbol(Register src, Register dest)
|
||||
|
||||
void MacroAssemblerMIPS64Compat::unboxBigInt(const ValueOperand& operand, Register dest)
|
||||
{
|
||||
unboxNonDouble(operand, dest);
|
||||
unboxNonDouble(operand, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
|
||||
void MacroAssemblerMIPS64Compat::unboxBigInt(Register src, Register dest)
|
||||
{
|
||||
ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
|
||||
void MacroAssemblerMIPS64Compat::unboxBigInt(const Address& src, Register dest)
|
||||
{
|
||||
unboxNonDouble(src, dest);
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1559,11 +1559,6 @@ MacroAssemblerMIPS64Compat::unboxPrivate(const ValueOperand& src, Register dest)
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::boxDouble(FloatRegister src, const ValueOperand& dest)
|
||||
{
|
||||
#if defined(JS_RUNTIME_CANONICAL_NAN)
|
||||
// Legacy-ABI MIPS hardware can produce NaN payloads that overlap the
|
||||
// punbox64 tag space. Normalize them before creating a JS::Value.
|
||||
asMasm().canonicalizeDouble(src);
|
||||
#endif
|
||||
as_dmfc1(dest.valueReg(), src);
|
||||
}
|
||||
|
||||
|
||||
@@ -173,18 +173,6 @@ ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
masm.neg32(ExtractTemp0);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, ExtractTemp0, R0);
|
||||
break;
|
||||
case JSOP_INC: {
|
||||
masm.unboxInt32(R0, ExtractTemp0);
|
||||
masm.ma_addTestOverflow(ExtractTemp0, ExtractTemp0, Imm32(1), &failure);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, ExtractTemp0, R0);
|
||||
break;
|
||||
}
|
||||
case JSOP_DEC: {
|
||||
masm.unboxInt32(R0, ExtractTemp0);
|
||||
masm.ma_subTestOverflow(ExtractTemp0, ExtractTemp0, Imm32(1), &failure);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, ExtractTemp0, R0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unexpected op");
|
||||
return false;
|
||||
|
||||
@@ -85,9 +85,8 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator* gen, LIRGraph* graph, Mac
|
||||
MOZ_ASSERT(graph->argumentSlotCount() == 0);
|
||||
frameDepth_ += gen->wasmMaxStackArgBytes();
|
||||
|
||||
if (SupportsSimd) {
|
||||
frameDepth_ = AlignBytes(frameDepth_, SimdMemoryAlignment);
|
||||
}
|
||||
static_assert(!SupportsSimd, "we need padding so that local slots are SIMD-aligned and "
|
||||
"the stack must be kept SIMD-aligned too.");
|
||||
|
||||
if (gen->performsCall()) {
|
||||
// An MWasmCall does not align the stack pointer at calls sites but
|
||||
|
||||
@@ -940,14 +940,7 @@ GlobalHelperThreadState::maxParseThreads() const
|
||||
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_PARSE))
|
||||
return 1;
|
||||
// Use the number of logical processors in a system.
|
||||
if (cpuCount < 4)
|
||||
return 2;
|
||||
//return cpuCount - 2;
|
||||
// XXX Issue #3172 XXX
|
||||
// For the time being, return a hard-coded value of 2 on all targets and CPUs.
|
||||
// It's unclear where the contention happens, but it has shown to be detrimental
|
||||
// especially on *nixes and older hardware.
|
||||
return 2;
|
||||
return cpuCount;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "js/Initialization.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -21,7 +19,6 @@
|
||||
#include "jit/ExecutableAllocator.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "js/Utility.h"
|
||||
#include "js/Value.h"
|
||||
#include "unicode/uclean.h"
|
||||
#include "unicode/utypes.h"
|
||||
#include "vm/DateTime.h"
|
||||
@@ -37,31 +34,6 @@ using js::FutexRuntime;
|
||||
|
||||
InitState JS::detail::libraryInitState;
|
||||
|
||||
// MIPS-specific
|
||||
#if defined(JS_RUNTIME_CANONICAL_NAN)
|
||||
namespace JS {
|
||||
namespace detail {
|
||||
JS_PUBLIC_DATA(uint64_t) CanonicalizedNaNBits;
|
||||
} // namespace detail
|
||||
} // namespace JS
|
||||
|
||||
// MIPS-specific
|
||||
static void
|
||||
SetupCanonicalNaN()
|
||||
{
|
||||
// Use a real hardware operation. A legacy MIPS ABI can run on hardware
|
||||
// whose NaN behavior does not match the compiler's predefined NAN value.
|
||||
volatile double infinity = mozilla::PositiveInfinity<double>();
|
||||
volatile double hardwareNaN = infinity - infinity;
|
||||
uint64_t hardwareNaNBits = mozilla::BitwiseCast<uint64_t>(hardwareNaN);
|
||||
hardwareNaNBits &= ~mozilla::FloatingPoint<double>::kSignBit;
|
||||
|
||||
// The selected NaN must remain a double in the JS::Value representation.
|
||||
MOZ_RELEASE_ASSERT(JS::Value::fromRawBits(hardwareNaNBits).isDouble());
|
||||
JS::detail::CanonicalizedNaNBits = hardwareNaNBits;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static unsigned
|
||||
MessageParameterCount(const char* format)
|
||||
@@ -104,11 +76,6 @@ JS::detail::InitWithFailureDiagnostic(bool isDebugBuild)
|
||||
MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
|
||||
"how do we have live runtimes before JS_Init?");
|
||||
|
||||
// MIPS-specific
|
||||
#if defined(JS_RUNTIME_CANONICAL_NAN)
|
||||
SetupCanonicalNaN();
|
||||
#endif
|
||||
|
||||
PRMJ_NowInit();
|
||||
|
||||
// The first invocation of `ProcessCreation` creates a temporary thread
|
||||
|
||||
@@ -1059,6 +1059,7 @@ wasm::GenerateInterruptExit(MacroAssembler& masm, Label* throwLabel)
|
||||
// jump scratch to resume execution.
|
||||
masm.subFromStackPtr(Imm32(sizeof(intptr_t)));
|
||||
masm.setFramePushed(0);
|
||||
static_assert(!SupportsSimd, "high lanes of SIMD registers need to be saved too.");
|
||||
masm.PushRegsInMask(AllRegsExceptSP);
|
||||
|
||||
// Save the unaligned stack pointer in a non-volatile register, then align
|
||||
|
||||
@@ -8938,11 +8938,7 @@ PresShell::DidDoReflow(bool aInterruptible)
|
||||
{
|
||||
mFrameConstructor->EndUpdate();
|
||||
|
||||
if (!mHandlingCallbacks) {
|
||||
mHandlingCallbacks = true; // Prevent recursion
|
||||
HandlePostedReflowCallbacks(aInterruptible);
|
||||
mHandlingCallbacks = false;
|
||||
}
|
||||
HandlePostedReflowCallbacks(aInterruptible);
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
|
||||
if (docShell) {
|
||||
|
||||
@@ -926,8 +926,6 @@ protected:
|
||||
|
||||
bool mAsyncResizeTimerIsActive : 1;
|
||||
bool mInResize : 1;
|
||||
|
||||
bool mHandlingCallbacks : 1;
|
||||
|
||||
bool mApproximateFrameVisibilityVisited : 1;
|
||||
|
||||
|
||||
@@ -164,9 +164,9 @@ nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||
|
||||
// We should be able to interact with the element by doing drag and drop.
|
||||
mContent->AddSystemEventListener(NS_LITERAL_STRING("drop"),
|
||||
mMouseListener, false, false);
|
||||
mMouseListener, false);
|
||||
mContent->AddSystemEventListener(NS_LITERAL_STRING("dragover"),
|
||||
mMouseListener, false, false);
|
||||
mMouseListener, false);
|
||||
|
||||
SyncDisabledState();
|
||||
|
||||
|
||||
@@ -235,17 +235,18 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
|
||||
WritingMode wm = GetWritingMode();
|
||||
LogicalSize availSize = aButtonReflowInput.ComputedSize(wm);
|
||||
|
||||
// The anonymous button-content frame cannot have a continuation. Give it
|
||||
// unconstrained available block-size so flex/grid layout does not treat a
|
||||
// definite button block-size as a fragmentainer constraint. Its computed
|
||||
// block-size is overridden separately below when it needs to be definite.
|
||||
availSize.BSize(wm) = NS_INTRINSICSIZE;
|
||||
|
||||
// Identify if the inner anonymous block is actually functioning as a flex or grid container.
|
||||
nsIAtom* kidType = aFirstKid->GetType();
|
||||
bool isFlexOrGrid = (kidType == nsGkAtoms::flexContainerFrame ||
|
||||
kidType == nsGkAtoms::gridContainerFrame);
|
||||
|
||||
// Preserve the button's definite BSize ONLY for flex/grid children so they
|
||||
// see a definite containing block main size. For standard buttons, clobber
|
||||
// to intrinsic so standard vertical centering (extraSpace) calculations work.
|
||||
if (!isFlexOrGrid || aButtonReflowInput.ComputedBSize() == NS_INTRINSICSIZE) {
|
||||
availSize.BSize(wm) = NS_INTRINSICSIZE;
|
||||
}
|
||||
|
||||
// shorthand for a value we need to use in a bunch of places
|
||||
const LogicalMargin& clbp = aButtonReflowInput.ComputedLogicalBorderPadding();
|
||||
|
||||
@@ -259,7 +260,7 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
|
||||
availSize);
|
||||
|
||||
// Apply the definite BSize directly on the inner reflow input ONLY if it's
|
||||
// a flex or grid container, without constraining its available BSize.
|
||||
// a flex or grid container, allowing it to be used as-is.
|
||||
if (isFlexOrGrid && aButtonReflowInput.ComputedBSize() != NS_INTRINSICSIZE) {
|
||||
contentsReflowInput.SetComputedBSize(aButtonReflowInput.ComputedBSize());
|
||||
}
|
||||
|
||||
@@ -1781,7 +1781,6 @@ CSSStyleSheet::DidDirty()
|
||||
MOZ_ASSERT(!mInner->mComplete || mDirty,
|
||||
"caller must have called WillDirty()");
|
||||
ClearRuleCascades();
|
||||
NotifyAdopterRuleChanged();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1871,20 +1870,13 @@ CSSStyleSheet::InsertRuleInternal(const nsAString& aRule,
|
||||
RefPtr<css::Rule> rule;
|
||||
aRv = css.ParseRule(aRule, mInner->mSheetURI, mInner->mBaseURI,
|
||||
mInner->mPrincipal, getter_AddRefs(rule));
|
||||
// A syntax error from web content is an expected insertRule() outcome. The
|
||||
// binding reports it to script; do not flood debug stderr as well.
|
||||
if (aRv.Failed()) {
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Hierarchy checking.
|
||||
int32_t newType = rule->GetType();
|
||||
|
||||
if (IsConstructed() && newType == css::Rule::IMPORT_RULE) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check that we're not inserting before a charset rule
|
||||
css::Rule* nextRule = mInner->mOrderedRules.SafeObjectAt(aIndex);
|
||||
if (nextRule) {
|
||||
|
||||
@@ -639,12 +639,8 @@ Declaration::GetPropertyValueInternal(
|
||||
}
|
||||
if (revertCount == totalCount) {
|
||||
// Simplify serialization below by serializing revert up-front.
|
||||
// eCSSUnit_Revert carries the cascade origin, so it cannot use the
|
||||
// nsCSSValue constructor reserved for valueless units.
|
||||
nsCSSValue revert;
|
||||
revert.SetRevertValue(SheetType::Unknown);
|
||||
revert.AppendToString(eCSSProperty_UNKNOWN, aValue,
|
||||
nsCSSValue::eNormalized);
|
||||
nsCSSValue(eCSSUnit_Revert).AppendToString(eCSSProperty_UNKNOWN, aValue,
|
||||
nsCSSValue::eNormalized);
|
||||
return;
|
||||
}
|
||||
if (revertLayerCount == totalCount) {
|
||||
|
||||
@@ -28,7 +28,6 @@ StyleSheet::StyleSheet(css::SheetParsingMode aParsingMode)
|
||||
, mDisabled(false)
|
||||
, mConstructed(false)
|
||||
, mDisallowModification(false)
|
||||
, mAdoptionCount(0)
|
||||
, mDocumentAssociationMode(NotOwnedByDocument)
|
||||
{
|
||||
}
|
||||
@@ -43,7 +42,6 @@ StyleSheet::StyleSheet(const StyleSheet& aCopy,
|
||||
, mDisabled(aCopy.mDisabled)
|
||||
, mConstructed(aCopy.mConstructed)
|
||||
, mDisallowModification(false)
|
||||
, mAdoptionCount(0)
|
||||
// We only use this constructor during cloning. It's the cloner's
|
||||
// responsibility to notify us if we end up being owned by a document.
|
||||
, mDocumentAssociationMode(NotOwnedByDocument)
|
||||
@@ -60,7 +58,7 @@ NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(StyleSheet)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(StyleSheet)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(StyleSheet, mConstructorDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(StyleSheet)
|
||||
|
||||
mozilla::dom::CSSStyleSheetParsingMode
|
||||
StyleSheet::ParsingModeDOM()
|
||||
@@ -261,69 +259,10 @@ StyleSheet::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
sheet->SetPrincipal(principal);
|
||||
sheet->SetComplete();
|
||||
sheet->SetConstructed();
|
||||
sheet->SetConstructorDocument(document);
|
||||
|
||||
return sheet.forget();
|
||||
}
|
||||
|
||||
void
|
||||
StyleSheet::AddAdopter(nsIDocument* aDocument)
|
||||
{
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
MOZ_ASSERT(aDocument);
|
||||
MOZ_ASSERT(ConstructorDocument() == aDocument);
|
||||
|
||||
if (mAdoptionCount++ == 0) {
|
||||
SetAssociatedDocument(aDocument, NotOwnedByDocument);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StyleSheet::AddAdopter(dom::ShadowRoot* aShadowRoot)
|
||||
{
|
||||
MOZ_ASSERT(aShadowRoot);
|
||||
|
||||
mAdopterShadowRoots.AppendElement(aShadowRoot);
|
||||
AddAdopter(aShadowRoot->OwnerDoc());
|
||||
}
|
||||
|
||||
void
|
||||
StyleSheet::RemoveAdopter(nsIDocument* aDocument)
|
||||
{
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
MOZ_ASSERT(aDocument);
|
||||
MOZ_ASSERT(ConstructorDocument() == aDocument);
|
||||
MOZ_ASSERT(mAdoptionCount > 0);
|
||||
|
||||
if (mAdoptionCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (--mAdoptionCount == 0 && !IsOwnedByDocument()) {
|
||||
ClearAssociatedDocument();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StyleSheet::RemoveAdopter(dom::ShadowRoot* aShadowRoot)
|
||||
{
|
||||
MOZ_ASSERT(aShadowRoot);
|
||||
|
||||
mAdopterShadowRoots.RemoveElement(aShadowRoot);
|
||||
RemoveAdopter(aShadowRoot->OwnerDoc());
|
||||
}
|
||||
|
||||
void
|
||||
StyleSheet::NotifyAdopterRuleChanged()
|
||||
{
|
||||
for (size_t i = 0; i < mAdopterShadowRoots.Length(); ++i) {
|
||||
dom::ShadowRoot* shadowRoot = mAdopterShadowRoots[i];
|
||||
if (mAdopterShadowRoots.IndexOf(shadowRoot) == i) {
|
||||
shadowRoot->StyleSheetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dom::CSSRuleList*
|
||||
StyleSheet::GetCssRules(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
||||
#include "nsIDOMCSSStyleSheet.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
class nsIDocument;
|
||||
@@ -27,7 +26,6 @@ struct StyleSheetInfo;
|
||||
|
||||
namespace dom {
|
||||
class CSSRuleList;
|
||||
class ShadowRoot;
|
||||
class SRIMetadata;
|
||||
} // namespace dom
|
||||
|
||||
@@ -195,13 +193,6 @@ public:
|
||||
inline void DidDirty();
|
||||
inline void AssertHasUniqueInner();
|
||||
|
||||
bool IsConstructed() const { return mConstructed; }
|
||||
nsIDocument* ConstructorDocument() const { return mConstructorDocument; }
|
||||
void AddAdopter(nsIDocument* aDocument);
|
||||
void RemoveAdopter(nsIDocument* aDocument);
|
||||
void AddAdopter(dom::ShadowRoot* aShadowRoot);
|
||||
void RemoveAdopter(dom::ShadowRoot* aShadowRoot);
|
||||
|
||||
private:
|
||||
// Get a handle to the various stylesheet bits which live on the 'inner' for
|
||||
// gecko stylesheets.
|
||||
@@ -215,12 +206,8 @@ private:
|
||||
bool AreRulesAvailable(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
bool IsConstructed() const { return mConstructed; }
|
||||
void SetConstructed() { mConstructed = true; }
|
||||
void SetConstructorDocument(nsIDocument* aDocument)
|
||||
{
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
mConstructorDocument = aDocument;
|
||||
}
|
||||
bool IsModificationDisallowed() const { return mDisallowModification; }
|
||||
|
||||
protected:
|
||||
@@ -230,13 +217,10 @@ protected:
|
||||
// it will set the principal of the inner to the subject principal.
|
||||
void SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
void NotifyAdopterRuleChanged();
|
||||
|
||||
nsString mTitle;
|
||||
nsIDocument* mDocument; // weak ref; parents maintain this for their children
|
||||
RefPtr<nsIDocument> mConstructorDocument;
|
||||
nsINode* mOwningNode; // weak ref
|
||||
nsTArray<dom::ShadowRoot*> mAdopterShadowRoots; // weak; roots unadopt on unlink/destruction
|
||||
|
||||
// mParsingMode controls access to nonstandard style constructs that
|
||||
// are not safe for use on the public Web but necessary in UA sheets
|
||||
@@ -246,7 +230,6 @@ protected:
|
||||
bool mDisabled;
|
||||
bool mConstructed;
|
||||
bool mDisallowModification;
|
||||
uint32_t mAdoptionCount;
|
||||
|
||||
// mDocumentAssociationMode determines whether mDocument directly owns us (in
|
||||
// the sense that if it's known-live then we're known-live). Always
|
||||
|
||||
@@ -13454,16 +13454,18 @@ bool
|
||||
CSSParserImpl::ParseAspectRatioRatio(nsCSSValue& aValue)
|
||||
{
|
||||
nsCSSValue width;
|
||||
if (ParseNonNegativeVariant(width, VARIANT_NUMBER | VARIANT_CALC,
|
||||
nullptr) != CSSParseResult::Ok) {
|
||||
if (!ParseSingleTokenNonNegativeVariant(width,
|
||||
VARIANT_NUMBER | VARIANT_CALC,
|
||||
nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCSSValue height;
|
||||
height.SetFloatValue(1.0f, eCSSUnit_Number);
|
||||
if (ExpectSymbol('/', true)) {
|
||||
if (ParseNonNegativeVariant(height, VARIANT_NUMBER | VARIANT_CALC,
|
||||
nullptr) != CSSParseResult::Ok) {
|
||||
if (!ParseSingleTokenNonNegativeVariant(height,
|
||||
VARIANT_NUMBER | VARIANT_CALC,
|
||||
nullptr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,9 @@
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test"></pre>
|
||||
<div id="adopted-target"></div>
|
||||
<div id="shadow-host"></div>
|
||||
<script type="application/javascript">
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let sheet;
|
||||
|
||||
try {
|
||||
@@ -62,105 +58,7 @@ if (sheet) {
|
||||
is(e.name, "NotAllowedError",
|
||||
"replaceSync should reject non-constructed sheets with NotAllowedError");
|
||||
}
|
||||
|
||||
try {
|
||||
sheet.insertRule("@import url('neverending_stylesheet_load.sjs');", 0);
|
||||
ok(false, "insertRule should reject @import rules for constructed sheets");
|
||||
} catch (e) {
|
||||
is(e.name, "SyntaxError",
|
||||
"insertRule should reject constructed-sheet @import rules with SyntaxError");
|
||||
}
|
||||
}
|
||||
|
||||
function colorFor(node) {
|
||||
return getComputedStyle(node).color;
|
||||
}
|
||||
|
||||
function runAdoptionTests() {
|
||||
let target = document.getElementById("adopted-target");
|
||||
let adopted = new CSSStyleSheet();
|
||||
|
||||
adopted.replaceSync("#adopted-target { color: rgb(12, 34, 56); }");
|
||||
document.adoptedStyleSheets = [adopted];
|
||||
|
||||
is(document.adoptedStyleSheets.length, 1,
|
||||
"document.adoptedStyleSheets should expose assigned sheets");
|
||||
is(document.adoptedStyleSheets[0], adopted,
|
||||
"document.adoptedStyleSheets should expose the same CSSStyleSheet object");
|
||||
is(document.styleSheets.length, 1,
|
||||
"document.styleSheets should not include adopted sheets");
|
||||
is(colorFor(target), "rgb(12, 34, 56)",
|
||||
"adopted document sheets should apply");
|
||||
|
||||
adopted.replaceSync("#adopted-target { color: rgb(20, 30, 40); }");
|
||||
is(colorFor(target), "rgb(20, 30, 40)",
|
||||
"mutating an adopted sheet should update document style");
|
||||
|
||||
let laterStyle = document.createElement("style");
|
||||
laterStyle.textContent = "#adopted-target { color: rgb(1, 2, 3); }";
|
||||
document.head.appendChild(laterStyle);
|
||||
is(colorFor(target), "rgb(20, 30, 40)",
|
||||
"adopted document sheets should cascade after ordinary document sheets");
|
||||
|
||||
try {
|
||||
document.adoptedStyleSheets = [document.styleSheets[0]];
|
||||
ok(false, "adopting a non-constructed sheet should throw");
|
||||
} catch (e) {
|
||||
is(e.name, "NotAllowedError",
|
||||
"adopting a non-constructed sheet should throw NotAllowedError");
|
||||
}
|
||||
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.onload = function() {
|
||||
let foreignSheet = new iframe.contentWindow.CSSStyleSheet();
|
||||
try {
|
||||
document.adoptedStyleSheets = [foreignSheet];
|
||||
ok(false, "adopting a sheet from another document should throw");
|
||||
} catch (e) {
|
||||
is(e.name, "NotAllowedError",
|
||||
"adopting a sheet from another document should throw NotAllowedError");
|
||||
}
|
||||
iframe.remove();
|
||||
|
||||
if ("attachShadow" in document.getElementById("shadow-host")) {
|
||||
runShadowAdoptionTests();
|
||||
} else {
|
||||
finishAdoptionTests();
|
||||
}
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
function runShadowAdoptionTests() {
|
||||
let host = document.getElementById("shadow-host");
|
||||
let root = host.attachShadow({ mode: "open" });
|
||||
root.innerHTML = "<style>span { color: rgb(1, 2, 3); }</style><span>shadow</span>";
|
||||
|
||||
let shadowSheet = new CSSStyleSheet();
|
||||
shadowSheet.replaceSync("span { color: rgb(45, 67, 89); }");
|
||||
root.adoptedStyleSheets = [shadowSheet];
|
||||
|
||||
let span = root.querySelector("span");
|
||||
is(root.adoptedStyleSheets.length, 1,
|
||||
"shadowRoot.adoptedStyleSheets should expose assigned sheets");
|
||||
is(root.styleSheets.length, 1,
|
||||
"shadowRoot.styleSheets should not include adopted sheets");
|
||||
is(colorFor(span), "rgb(45, 67, 89)",
|
||||
"adopted shadow sheets should apply after ordinary shadow sheets");
|
||||
|
||||
shadowSheet.replaceSync("span { color: rgb(90, 80, 70); }");
|
||||
is(colorFor(span), "rgb(90, 80, 70)",
|
||||
"mutating an adopted shadow sheet should update shadow style");
|
||||
|
||||
finishAdoptionTests();
|
||||
}
|
||||
|
||||
function finishAdoptionTests() {
|
||||
document.adoptedStyleSheets = [];
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
runAdoptionTests();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -49,13 +49,6 @@
|
||||
#include "config_unix_ppc.h"
|
||||
#elif defined(__sparcv9) || defined(__sparcv9__)
|
||||
#include "config_unix_sparc64.h"
|
||||
#elif defined(__mips__)
|
||||
// This is needed to avoid enabling x86 assembly on 64-bit MIPS.
|
||||
#include "config_unix32.h"
|
||||
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
#undef HAVE_BIGENDIAN
|
||||
#define HAVE_BIGENDIAN 1
|
||||
#endif
|
||||
#elif defined(__loongarch64)
|
||||
#include "config_unix_loongarch64.h"
|
||||
#else
|
||||
|
||||
@@ -6,9 +6,5 @@
|
||||
#else
|
||||
#define AV_HAVE_BIGENDIAN 0
|
||||
#endif
|
||||
#if defined(__mips__)
|
||||
#define AV_HAVE_FAST_UNALIGNED 0
|
||||
#else
|
||||
#define AV_HAVE_FAST_UNALIGNED 1
|
||||
#endif
|
||||
#endif /* AVUTIL_AVCONFIG_H */
|
||||
@@ -16,30 +16,6 @@
|
||||
|
||||
#if HAVE_MMI
|
||||
|
||||
/*
|
||||
* Clang's integrated assembler uses the prefixed spellings below, while
|
||||
* GNU as names the same Loongson MMI instructions xor/and/or/dsrl/srl.
|
||||
* Define GNU as aliases so the inline assembly works with either toolchain.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
__asm__(
|
||||
".macro pxor dst, src1, src2\n\t"
|
||||
"xor \\dst, \\src1, \\src2\n\t"
|
||||
".endm\n\t"
|
||||
".macro pand dst, src1, src2\n\t"
|
||||
"and \\dst, \\src1, \\src2\n\t"
|
||||
".endm\n\t"
|
||||
".macro por dst, src1, src2\n\t"
|
||||
"or \\dst, \\src1, \\src2\n\t"
|
||||
".endm\n\t"
|
||||
".macro ssrld dst, src1, src2\n\t"
|
||||
"dsrl \\dst, \\src1, \\src2\n\t"
|
||||
".endm\n\t"
|
||||
".macro ssrlw dst, src1, src2\n\t"
|
||||
"srl \\dst, \\src1, \\src2\n\t"
|
||||
".endm\n\t");
|
||||
#endif
|
||||
|
||||
#if HAVE_MIPS64
|
||||
#define mips_reg int64_t
|
||||
#define MMI_ADDU(reg1, reg2, reg3) \
|
||||
|
||||
@@ -110,27 +110,22 @@ nsHttpChunkedDecoder::ParseChunkRemaining(char *buf,
|
||||
count = mLineBuf.Length();
|
||||
}
|
||||
|
||||
// NUL is illegal in a chunk-size or trailer field line (RFC 9110 section
|
||||
// 5.5).
|
||||
if (memchr(buf, '\0', count)) {
|
||||
LOG(("chunked line contains embedded NUL; rejecting\n"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (mWaitEOF) {
|
||||
if (count) {
|
||||
if (*buf) {
|
||||
LOG(("got trailer: %s\n", buf));
|
||||
// allocate a header array for the trailers on demand
|
||||
if (!mTrailers) {
|
||||
mTrailers = new nsHttpHeaderArray();
|
||||
}
|
||||
mTrailers->ParseHeaderLine(nsDependentCSubstring(buf, count));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mWaitEOF = false;
|
||||
mReachedEOF = true;
|
||||
LOG(("reached end of chunked-body\n"));
|
||||
}
|
||||
} else if (count) {
|
||||
}
|
||||
else if (*buf) {
|
||||
char *endptr;
|
||||
unsigned long parsedval; // could be 64 bit, could be 32
|
||||
|
||||
@@ -156,7 +151,8 @@ nsHttpChunkedDecoder::ParseChunkRemaining(char *buf,
|
||||
|
||||
// ensure that the line buffer is clear
|
||||
mLineBuf.Truncate();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// save the partial line; wait for more data
|
||||
*bytesConsumed = count;
|
||||
// ignore a trailing CR
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
diff --git a/lib/xmltok.c b/lib/xmltok.c
|
||||
--- a/lib/xmltok.c
|
||||
+++ b/lib/xmltok.c
|
||||
@@ -700,17 +700,19 @@ unicode_byte_type(char hi, char lo) {
|
||||
static enum XML_Convert_Result PTRCALL E##toUtf16( \
|
||||
const ENCODING *enc, const char **fromP, const char *fromLim, \
|
||||
unsigned short **toP, const unsigned short *toLim) { \
|
||||
enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
|
||||
UNUSED_P(enc); \
|
||||
fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
|
||||
/* Avoid copying first half only of surrogate */ \
|
||||
if (fromLim - *fromP > ((toLim - *toP) << 1) \
|
||||
- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
|
||||
+/* BEGIN MCP CHANGE (Only high surrogate mask) */ \
|
||||
+ && (GET_HI(fromLim - 2) & 0xFC) == 0xD8) { \
|
||||
+/* END MCP CHANGE */ \
|
||||
fromLim -= 2; \
|
||||
res = XML_CONVERT_INPUT_INCOMPLETE; \
|
||||
} \
|
||||
for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
|
||||
*(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
|
||||
if ((*toP == toLim) && (*fromP < fromLim)) \
|
||||
return XML_CONVERT_OUTPUT_EXHAUSTED; \
|
||||
else \
|
||||
@@ -705,9 +705,7 @@ unicode_byte_type(char hi, char lo) {
|
||||
fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
|
||||
/* Avoid copying first half only of surrogate */ \
|
||||
if (fromLim - *fromP > ((toLim - *toP) << 1) \
|
||||
/* BEGIN MCP CHANGE (Only high surrogate mask) */ \
|
||||
&& (GET_HI(fromLim - 2) & 0xFC) == 0xD8) { \
|
||||
/* END MCP CHANGE */ \
|
||||
&& (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
|
||||
fromLim -= 2; \
|
||||
res = XML_CONVERT_INPUT_INCOMPLETE; \
|
||||
} \
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
* depend builds. See comments in rules.mk.
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
#error "Do not include this header file."
|
||||
@@ -7,16 +7,9 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cert.h"
|
||||
#include "certdb.h"
|
||||
#include "certt.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "prerror.h"
|
||||
#include "secerr.h"
|
||||
|
||||
extern "C" SECStatus __CERT_AddTempCertToPerm(CERTCertificate* cert,
|
||||
char* nickname,
|
||||
CERTCertTrust* trust);
|
||||
|
||||
class DecodeCertsTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(DecodeCertsTest, EmptyCertPackage) {
|
||||
@@ -46,113 +39,3 @@ TEST_F(DecodeCertsTest, EmptySignedData) {
|
||||
sizeof(emptySignedData)));
|
||||
EXPECT_EQ(SEC_ERROR_BAD_DER, PR_GetError());
|
||||
}
|
||||
|
||||
// Generated with pycert, but the details are unimportant. This can just be any
|
||||
// unique certificate. In this case, the specification used was:
|
||||
// issuer:test temp to perm cert
|
||||
// subject:test temp to perm cert
|
||||
// issuerKey:secp256r1
|
||||
// subjectKey:secp256r1
|
||||
// serialNumber:1
|
||||
uint8_t kTestTempToPermCertDER[] = {
|
||||
0x30, 0x82, 0x01, 0x37, 0x30, 0x81, 0xdc, 0xa0, 0x03, 0x02, 0x01, 0x02,
|
||||
0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x20,
|
||||
0x74, 0x65, 0x6d, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, 0x72, 0x6d,
|
||||
0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x32,
|
||||
0x34, 0x31, 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
|
||||
0x18, 0x0f, 0x32, 0x30, 0x32, 0x37, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d, 0x06,
|
||||
0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x20, 0x74,
|
||||
0x65, 0x6d, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x20,
|
||||
0x63, 0x65, 0x72, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
|
||||
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
|
||||
0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61,
|
||||
0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec,
|
||||
0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79,
|
||||
0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11,
|
||||
0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99,
|
||||
0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30,
|
||||
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
|
||||
0x05, 0x00, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x5c, 0x75, 0x51,
|
||||
0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06,
|
||||
0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb,
|
||||
0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x20, 0x43, 0xee, 0xef, 0x45, 0x3d,
|
||||
0xbb, 0xf3, 0x3c, 0x61, 0x9a, 0xbb, 0x95, 0x89, 0xb4, 0x23, 0x3c, 0xc7,
|
||||
0x1e, 0x39, 0x01, 0x74, 0x9e, 0xef, 0x04, 0x44, 0x86, 0x8c, 0xc9, 0x0f,
|
||||
0x8b, 0x2d, 0x0d};
|
||||
|
||||
TEST_F(DecodeCertsTest, AddTempCertToPerm) {
|
||||
SECItem certDER = {siBuffer, kTestTempToPermCertDER,
|
||||
sizeof(kTestTempToPermCertDER)};
|
||||
ScopedCERTCertificate cert1(CERT_NewTempCertificate(
|
||||
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
|
||||
EXPECT_NE(cert1.get(), nullptr);
|
||||
CERTCertTrust trust = {0};
|
||||
char nickname1[] = "test temp to perm cert 1";
|
||||
SECStatus rv = __CERT_AddTempCertToPerm(cert1.get(), nickname1, &trust);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
ScopedCERTCertificate cert2(CERT_NewTempCertificate(
|
||||
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
|
||||
EXPECT_NE(cert2.get(), cert1.get());
|
||||
char nickname2[] = "test temp to perm cert 2";
|
||||
rv = __CERT_AddTempCertToPerm(cert2.get(), nickname2, &trust);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
}
|
||||
|
||||
// Generated with pycert, but the details are unimportant. This can just be any
|
||||
// unique certificate. In this case, the specification used was:
|
||||
// issuer:test import cert
|
||||
// subject:test import cert
|
||||
// issuerKey:secp256r1
|
||||
// subjectKey:secp256r1
|
||||
// serialNumber:1
|
||||
uint8_t kTestImportCertDER[] = {
|
||||
0x30, 0x82, 0x01, 0x2c, 0x30, 0x81, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02,
|
||||
0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x20,
|
||||
0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30,
|
||||
0x22, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x31, 0x31, 0x32, 0x37, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x37,
|
||||
0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
|
||||
0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10,
|
||||
0x74, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20,
|
||||
0x63, 0x65, 0x72, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
|
||||
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
|
||||
0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61,
|
||||
0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec,
|
||||
0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79,
|
||||
0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11,
|
||||
0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99,
|
||||
0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30,
|
||||
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
|
||||
0x05, 0x00, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51,
|
||||
0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06,
|
||||
0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb,
|
||||
0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0xe9, 0x58, 0x16, 0x07,
|
||||
0xbf, 0x0b, 0xdc, 0x64, 0x35, 0x7a, 0x92, 0x51, 0xb2, 0xee, 0x77, 0x22,
|
||||
0xd4, 0xec, 0x98, 0xb6, 0x35, 0x96, 0xa6, 0x5b, 0x96, 0xbe, 0x73, 0x1a,
|
||||
0xa3, 0xa4, 0xfe, 0x5c};
|
||||
|
||||
TEST_F(DecodeCertsTest, ImportCert) {
|
||||
SECItem certDER = {siBuffer, kTestImportCertDER, sizeof(kTestImportCertDER)};
|
||||
ScopedCERTCertificate cert1(CERT_NewTempCertificate(
|
||||
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
|
||||
EXPECT_NE(cert1.get(), nullptr);
|
||||
char nickname1[] = "test import cert 1";
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
|
||||
SECStatus rv = PK11_ImportCert(slot.get(), cert1.get(), CK_INVALID_HANDLE,
|
||||
nickname1, PR_TRUE);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
ScopedCERTCertificate cert2(CERT_NewTempCertificate(
|
||||
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
|
||||
EXPECT_NE(cert2.get(), cert1.get());
|
||||
char nickname2[] = "test import cert 2";
|
||||
rv = PK11_ImportCert(slot.get(), cert2.get(), CK_INVALID_HANDLE, nickname2,
|
||||
PR_TRUE);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
}
|
||||
@@ -255,6 +255,8 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
|
||||
NSSCertificate *c = STAN_GetNSSCertificate(cert);
|
||||
nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
|
||||
nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
|
||||
SECStatus rv;
|
||||
PRStatus ret;
|
||||
|
||||
if (c == NULL) {
|
||||
CERT_MapStanError();
|
||||
@@ -316,19 +318,12 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
|
||||
return SECFailure;
|
||||
}
|
||||
nssPKIObject_AddInstance(&c->object, permInstance);
|
||||
// nssTrustDomain_AddCertToCache takes ownership of 'c' and returns an
|
||||
// owned reference to an NSSCertificate that may be a different object from
|
||||
// 'c'. Because 'cert' is backed by 'c', and because it must not go away as
|
||||
// a result of calling this function, increment the refcount on 'c' for the
|
||||
// duration of the call.
|
||||
nssCertificate_AddRef(c);
|
||||
NSSCertificate *cInCache = nssTrustDomain_AddCertToCache(STAN_GetDefaultTrustDomain(), c);
|
||||
if (!cInCache) {
|
||||
CERT_MapStanError();
|
||||
return SECFailure;
|
||||
}
|
||||
c = cInCache;
|
||||
cert = STAN_GetCERTCertificateOrRelease(c);
|
||||
nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
|
||||
/* reset the CERTCertificate fields */
|
||||
CERT_LockCertTempPerm(cert);
|
||||
cert->nssCertificate = NULL;
|
||||
CERT_UnlockCertTempPerm(cert);
|
||||
cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */
|
||||
if (!cert) {
|
||||
CERT_MapStanError();
|
||||
return SECFailure;
|
||||
@@ -337,12 +332,15 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
|
||||
cert->istemp = PR_FALSE;
|
||||
cert->isperm = PR_TRUE;
|
||||
CERT_UnlockCertTempPerm(cert);
|
||||
SECStatus rv = SECSuccess;
|
||||
if (trust && STAN_ChangeCertTrust(cert, trust) != PR_SUCCESS) {
|
||||
if (!trust) {
|
||||
return SECSuccess;
|
||||
}
|
||||
ret = STAN_ChangeCertTrust(cert, trust);
|
||||
rv = SECSuccess;
|
||||
if (ret != PR_SUCCESS) {
|
||||
rv = SECFailure;
|
||||
CERT_MapStanError();
|
||||
}
|
||||
nssCertificate_Destroy(c);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define NSS_VERSION "3.90.14.0 (UXP)" _NSS_CUSTOMIZED
|
||||
#define NSS_VERSION "3.90.13.0 (UXP)" _NSS_CUSTOMIZED
|
||||
#define NSS_VMAJOR 3
|
||||
#define NSS_VMINOR 90
|
||||
#define NSS_VPATCH 14
|
||||
#define NSS_VPATCH 13
|
||||
#define NSS_VBUILD 0
|
||||
#define NSS_BETA PR_FALSE
|
||||
|
||||
|
||||
@@ -93,19 +93,17 @@ pk11_buildNickname(PK11SlotInfo *slot, CK_ATTRIBUTE *cert_label,
|
||||
suffixLen = key_label->ulValueLen;
|
||||
suffix = (char *)key_label->pValue;
|
||||
} else if (cert_id && cert_id->ulValueLen > 0) {
|
||||
int i, first = cert_id->ulValueLen - MAX_CERT_ID;
|
||||
int offset = sizeof(DEFAULT_STRING);
|
||||
char *idValue = (char *)cert_id->pValue;
|
||||
/* Hex-encode the last min(MAX_CERT_ID, ulValueLen) bytes of cert_id. */
|
||||
CK_ULONG idLen = (cert_id->ulValueLen > MAX_CERT_ID)
|
||||
? MAX_CERT_ID
|
||||
: cert_id->ulValueLen;
|
||||
CK_ULONG first = cert_id->ulValueLen - idLen;
|
||||
CK_ULONG i;
|
||||
|
||||
PORT_Memcpy(buildNew, DEFAULT_STRING, sizeof(DEFAULT_STRING) - 1);
|
||||
next = buildNew + sizeof(DEFAULT_STRING) - 1;
|
||||
for (i = 0; i < idLen; i++) {
|
||||
*next++ = toHex((idValue[first + i] >> 4) & 0xf);
|
||||
*next++ = toHex(idValue[first + i] & 0xf);
|
||||
next = buildNew + offset;
|
||||
if (first < 0)
|
||||
first = 0;
|
||||
for (i = first; i < (int)cert_id->ulValueLen; i++) {
|
||||
*next++ = toHex((idValue[i] >> 4) & 0xf);
|
||||
*next++ = toHex(idValue[i] & 0xf);
|
||||
}
|
||||
*next++ = 0;
|
||||
suffix = buildNew;
|
||||
@@ -274,7 +272,7 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
|
||||
}
|
||||
|
||||
/* Build and output a nickname, if desired.
|
||||
* This must be done before calling nssTrustDomain_AddCertToCache
|
||||
* This must be done before calling nssTrustDomain_AddCertsToCache
|
||||
* because that function may destroy c, pkio and co!
|
||||
*/
|
||||
if ((nickptr) && (co->label)) {
|
||||
@@ -291,15 +289,12 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
|
||||
*nickptr = pk11_buildNickname(slot, &label, privateLabel, &id);
|
||||
}
|
||||
|
||||
// nssTrustDomain_AddCertToCache takes ownership of 'c' and returns an
|
||||
// owned reference to an NSSCertificate that may be a different object from
|
||||
// 'c'. Presumably, the nickname which we just output above remains valid
|
||||
// (the memory is valid because pk11_buildNickname allocates memory for it
|
||||
// on the heap).
|
||||
c = nssTrustDomain_AddCertToCache(td, c);
|
||||
if (!c) {
|
||||
return NULL;
|
||||
}
|
||||
/* This function may destroy the cert in "c" and all its subordinate
|
||||
* structures, and replace the value in "c" with the address of a
|
||||
* different NSSCertificate that it found in the cache.
|
||||
* Presumably, the nickname which we just output above remains valid. :)
|
||||
*/
|
||||
(void)nssTrustDomain_AddCertsToCache(td, &c, 1);
|
||||
return STAN_GetCERTCertificateOrRelease(c);
|
||||
}
|
||||
|
||||
@@ -1249,21 +1244,13 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||
* CERTCertificate, and finish
|
||||
*/
|
||||
nssPKIObject_AddInstance(&c->object, certobj);
|
||||
// nssTrustDomain_AddCertToCache takes ownership of 'c' and returns an
|
||||
// owned reference to an NSSCertificate that may be a different object from
|
||||
// 'c'. Because 'cert' is backed by 'c', and because it must not go away as
|
||||
// a result of calling this function, increment the refcount on 'c' for the
|
||||
// duration of the call.
|
||||
/* nssTrustDomain_AddCertsToCache may release a reference to 'c' and
|
||||
* replace 'c' with a different value. So we add a reference to 'c' to
|
||||
* prevent 'c' from being destroyed. */
|
||||
nssCertificate_AddRef(c);
|
||||
NSSCertificate *cInCache = nssTrustDomain_AddCertToCache(STAN_GetDefaultTrustDomain(), c);
|
||||
if (cInCache) {
|
||||
(void)STAN_ForceCERTCertificateUpdate(cInCache);
|
||||
// Release the reference returned by nssTrustDomain_AddCertToCache.
|
||||
nssCertificate_Destroy(cInCache);
|
||||
} else {
|
||||
(void)STAN_ForceCERTCertificateUpdate(c);
|
||||
// nssTrustDomain_AddCertToCache already called nssCertificate_Destroy(c).
|
||||
}
|
||||
nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
|
||||
(void)STAN_ForceCERTCertificateUpdate(c);
|
||||
nssCertificate_Destroy(c);
|
||||
SECITEM_FreeItem(keyID, PR_TRUE);
|
||||
(void)nssToken_Destroy(token);
|
||||
return SECSuccess;
|
||||
@@ -1566,13 +1553,7 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
|
||||
goto loser;
|
||||
}
|
||||
object = NULL; /* adopted by the previous call */
|
||||
// nssTrustDomain_AddCertToCache takes ownership of 'cert' and returns an
|
||||
// owned reference to an NSSCertificate that may be a different object from
|
||||
// 'cert'.
|
||||
cert = nssTrustDomain_AddCertToCache(td, cert);
|
||||
if (!cert) {
|
||||
goto loser;
|
||||
}
|
||||
nssTrustDomain_AddCertsToCache(td, &cert, 1);
|
||||
/* on failure, cert is freed below */
|
||||
rvCert = STAN_GetCERTCertificate(cert);
|
||||
if (!rvCert) {
|
||||
@@ -2031,9 +2012,9 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
|
||||
}
|
||||
|
||||
/* Check to see if the cert's token is still there */
|
||||
} while (rvCert->slot && !PK11_IsPresent(rvCert->slot));
|
||||
} while (!PK11_IsPresent(rvCert->slot));
|
||||
|
||||
if (rvCert && rvCert->slot && slotPtr)
|
||||
if (rvCert && slotPtr)
|
||||
*slotPtr = PK11_ReferenceSlot(rvCert->slot);
|
||||
|
||||
SECITEM_FreeItem(derSerial, PR_TRUE);
|
||||
|
||||
@@ -2611,16 +2611,9 @@ pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
|
||||
templateCount--;
|
||||
}
|
||||
|
||||
if (key_size != 0 && (CK_ULONG)key_size > inKey->len) {
|
||||
PORT_SetError(PK11_MapError(CKR_UNWRAPPING_KEY_SIZE_RANGE));
|
||||
if (crvp)
|
||||
*crvp = CKR_UNWRAPPING_KEY_SIZE_RANGE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* keys are almost always aligned, but if we get this far,
|
||||
* we've gone above and beyond anyway... */
|
||||
outKey.data = (unsigned char *)PORT_ZAlloc(inKey->len);
|
||||
outKey.data = (unsigned char *)PORT_Alloc(inKey->len);
|
||||
if (outKey.data == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
if (crvp)
|
||||
|
||||
@@ -1009,20 +1009,19 @@ cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
|
||||
static nssPKIObject *
|
||||
cert_createObject(nssPKIObject *o)
|
||||
{
|
||||
NSSCertificate *cert = nssCertificate_Create(o);
|
||||
if (!cert) {
|
||||
return NULL;
|
||||
}
|
||||
NSSTrustDomain *td = o->trustDomain;
|
||||
/* nssTrustDomain_AddCertToCache takes ownership of the reference to cert,
|
||||
* so first increase the refcount so it doesn't go away. */
|
||||
nssCertificate_AddRef(cert);
|
||||
NSSCertificate *certInCache = nssTrustDomain_AddCertToCache(td, cert);
|
||||
if (certInCache) {
|
||||
// This code should probably use the certificate returned from the cache,
|
||||
// but currently the merge tests rely on not doing so. Discard it
|
||||
// instead.
|
||||
nssCertificate_Destroy(certInCache);
|
||||
NSSCertificate *cert;
|
||||
cert = nssCertificate_Create(o);
|
||||
/* if (STAN_GetCERTCertificate(cert) == NULL) {
|
||||
nssCertificate_Destroy(cert);
|
||||
return (nssPKIObject *)NULL;
|
||||
} */
|
||||
/* In 3.4, have to maintain uniqueness of cert pointers by caching all
|
||||
* certs. Cache the cert here, before returning. If it is already
|
||||
* cached, take the cached entry.
|
||||
*/
|
||||
{
|
||||
NSSTrustDomain *td = o->trustDomain;
|
||||
nssTrustDomain_AddCertsToCache(td, &cert, 1);
|
||||
}
|
||||
return (nssPKIObject *)cert;
|
||||
}
|
||||
|
||||
@@ -445,14 +445,11 @@ nssTrustDomain_InitializeCache(
|
||||
NSSTrustDomain *td,
|
||||
PRUint32 cacheSize);
|
||||
|
||||
// Takes an owned reference to cert and either moves it to the cache (on
|
||||
// success) or drops it (on failure).
|
||||
// Returns a strong reference to the cache-owned cert (NB: which may be
|
||||
// different from the given cert!) or NULL.
|
||||
NSS_EXTERN NSSCertificate *
|
||||
nssTrustDomain_AddCertToCache(
|
||||
NSS_EXTERN PRStatus
|
||||
nssTrustDomain_AddCertsToCache(
|
||||
NSSTrustDomain *td,
|
||||
NSSCertificate *cert);
|
||||
NSSCertificate **certs,
|
||||
PRUint32 numCerts);
|
||||
|
||||
NSS_EXTERN void
|
||||
nssTrustDomain_RemoveCertFromCacheLOCKED(
|
||||
|
||||
@@ -705,8 +705,8 @@ merge_object_instances(
|
||||
return rv;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
nssTrustDomain_AddCertToCache(
|
||||
static NSSCertificate *
|
||||
add_cert_to_cache(
|
||||
NSSTrustDomain *td,
|
||||
NSSCertificate *cert)
|
||||
{
|
||||
@@ -745,11 +745,10 @@ nssTrustDomain_AddCertToCache(
|
||||
/* merge the instances of the cert */
|
||||
if (merge_object_instances(&rvCert->object, &cert->object) != SECSuccess) {
|
||||
nssCertificate_Destroy(rvCert);
|
||||
nssCertificate_Destroy(cert); // consume the owned reference to cert
|
||||
return NULL;
|
||||
}
|
||||
STAN_ForceCERTCertificateUpdate(rvCert);
|
||||
nssCertificate_Destroy(cert); // consume the owned reference to cert
|
||||
nssCertificate_Destroy(cert);
|
||||
return rvCert;
|
||||
}
|
||||
/* create a new cache entry for this cert within the cert's arena*/
|
||||
@@ -772,12 +771,18 @@ nssTrustDomain_AddCertToCache(
|
||||
added++;
|
||||
/* If a new subject entry was created, also need nickname and/or email */
|
||||
if (subjectList != NULL) {
|
||||
#ifdef nodef
|
||||
PRBool handle = PR_FALSE;
|
||||
#endif
|
||||
if (certNickname) {
|
||||
nssrv = add_nickname_entry(arena, td->cache,
|
||||
certNickname, subjectList);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
#ifdef nodef
|
||||
handle = PR_TRUE;
|
||||
#endif
|
||||
added++;
|
||||
}
|
||||
if (cert->email) {
|
||||
@@ -785,13 +790,27 @@ nssTrustDomain_AddCertToCache(
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
#ifdef nodef
|
||||
handle = PR_TRUE;
|
||||
#endif
|
||||
added += 2;
|
||||
}
|
||||
#ifdef nodef
|
||||
/* I think either a nickname or email address must be associated
|
||||
* with the cert. However, certs are passed to NewTemp without
|
||||
* either. This worked in the old code, so it must work now.
|
||||
*/
|
||||
if (!handle) {
|
||||
/* Require either nickname or email handle */
|
||||
nssrv = PR_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* A new subject entry was not created. arena is unused. */
|
||||
nssArena_Destroy(arena);
|
||||
}
|
||||
rvCert = cert; // rvCert is now the owned reference to cert
|
||||
rvCert = cert;
|
||||
PZ_Unlock(td->cache->lock);
|
||||
nss_ZFreeIf(certNickname);
|
||||
return rvCert;
|
||||
@@ -821,10 +840,28 @@ loser:
|
||||
nssArena_Destroy(arena);
|
||||
}
|
||||
PZ_Unlock(td->cache->lock);
|
||||
nssCertificate_Destroy(cert); // consume the owned reference to cert
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssTrustDomain_AddCertsToCache(
|
||||
NSSTrustDomain *td,
|
||||
NSSCertificate **certs,
|
||||
PRUint32 numCerts)
|
||||
{
|
||||
PRUint32 i;
|
||||
NSSCertificate *c;
|
||||
for (i = 0; i < numCerts && certs[i]; i++) {
|
||||
c = add_cert_to_cache(td, certs[i]);
|
||||
if (c == NULL) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
certs[i] = c;
|
||||
}
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static NSSCertificate **
|
||||
collect_subject_certs(
|
||||
nssList *subjectList,
|
||||
|
||||
@@ -1209,13 +1209,7 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
|
||||
DESContext *ctxt;
|
||||
unsigned int pad;
|
||||
|
||||
/* freebl's DES_CreateContext has no IV/key length parameters and reads
|
||||
* fixed-size buffers, so reject undersized SECItems here before they can
|
||||
* cause an out-of-bounds read. */
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
|
||||
(key->data == NULL) ||
|
||||
(key->len < (unsigned int)(triple_des ? 24 : DES_KEY_LENGTH)) ||
|
||||
(iv->data == NULL) || (iv->len < DES_BLOCK_SIZE)) {
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1291,11 +1285,7 @@ sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
|
||||
AESContext *ctxt;
|
||||
unsigned int pad;
|
||||
|
||||
/* AES_CreateContext reads AES_BLOCK_SIZE bytes of IV with no length
|
||||
* parameter; reject undersized SECItems to prevent OOB reads. */
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
|
||||
(key->data == NULL) || (iv->data == NULL) ||
|
||||
(iv->len < AES_BLOCK_SIZE)) {
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1370,12 +1360,7 @@ sec_pkcs5_aes_key_wrap(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_de
|
||||
AESKeyWrapContext *ctxt;
|
||||
unsigned int pad;
|
||||
|
||||
/* AESKeyWrap_CreateContext reads AES_KEY_WRAP_BLOCK_SIZE bytes of IV when
|
||||
* non-NULL; reject undersized SECItems to prevent OOB reads. A NULL
|
||||
* iv->data is allowed and selects the default key-wrap IV. */
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
|
||||
(key->data == NULL) ||
|
||||
(iv->data != NULL && iv->len < AES_KEY_WRAP_BLOCK_SIZE)) {
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1449,11 +1434,7 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
|
||||
SECStatus rv = SECFailure;
|
||||
int pad;
|
||||
|
||||
/* RC2_CreateContext reads 8 bytes of IV in CBC mode with no length
|
||||
* parameter; reject undersized SECItems to prevent OOB reads. */
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
|
||||
(key->data == NULL) || (iv->data == NULL) ||
|
||||
(iv->len < 8 /* RC2_BLOCK_SIZE */)) {
|
||||
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define SOFTOKEN_VERSION "3.90.14.0 (UXP)" SOFTOKEN_ECC_STRING
|
||||
#define SOFTOKEN_VERSION "3.90.13.0 (UXP)" SOFTOKEN_ECC_STRING
|
||||
#define SOFTOKEN_VMAJOR 3
|
||||
#define SOFTOKEN_VMINOR 90
|
||||
#define SOFTOKEN_VPATCH 14
|
||||
#define SOFTOKEN_VPATCH 13
|
||||
#define SOFTOKEN_VBUILD 0
|
||||
#define SOFTOKEN_BETA PR_FALSE
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
|
||||
*/
|
||||
#define NSSUTIL_VERSION "3.90.14.0 (UXP)"
|
||||
#define NSSUTIL_VERSION "3.90.13.0 (UXP)"
|
||||
#define NSSUTIL_VMAJOR 3
|
||||
#define NSSUTIL_VMINOR 90
|
||||
#define NSSUTIL_VPATCH 14
|
||||
#define NSSUTIL_VPATCH 13
|
||||
#define NSSUTIL_VBUILD 0
|
||||
#define NSSUTIL_BETA PR_FALSE
|
||||
|
||||
|
||||
@@ -175,9 +175,7 @@ MatchComponentType(const SEC_ASN1Template* templateEntry,
|
||||
/* optional component. This is the hard case. Now we need to
|
||||
look at the subtemplate to get the expected kind */
|
||||
const SEC_ASN1Template* subTemplate =
|
||||
SEC_ASN1GetSubtemplate(templateEntry,
|
||||
(char*)dest + templateEntry->offset,
|
||||
PR_FALSE);
|
||||
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
|
||||
if (!subTemplate) {
|
||||
PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
|
||||
return SECFailure;
|
||||
@@ -403,9 +401,7 @@ DecodeInline(void* dest,
|
||||
SECItem* src, PLArenaPool* arena, PRBool checkTag)
|
||||
{
|
||||
const SEC_ASN1Template* inlineTemplate =
|
||||
SEC_ASN1GetSubtemplate(templateEntry,
|
||||
(char*)dest + templateEntry->offset,
|
||||
PR_FALSE);
|
||||
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
|
||||
return DecodeItem((void*)((char*)dest + templateEntry->offset),
|
||||
inlineTemplate, src, arena, checkTag);
|
||||
}
|
||||
@@ -416,9 +412,7 @@ DecodePointer(void* dest,
|
||||
SECItem* src, PLArenaPool* arena, PRBool checkTag)
|
||||
{
|
||||
const SEC_ASN1Template* ptrTemplate =
|
||||
SEC_ASN1GetSubtemplate(templateEntry,
|
||||
(char*)dest + templateEntry->offset,
|
||||
PR_FALSE);
|
||||
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
|
||||
if (!ptrTemplate) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
@@ -504,9 +498,7 @@ DecodeGroup(void* dest,
|
||||
void** entries = NULL;
|
||||
|
||||
const SEC_ASN1Template* subTemplate =
|
||||
SEC_ASN1GetSubtemplate(templateEntry,
|
||||
(char*)dest + templateEntry->offset,
|
||||
PR_FALSE);
|
||||
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
|
||||
|
||||
source = *src;
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
#430544
|
||||
**/PR_CallOnce/InitializeArenas/PR_NewLock/**
|
||||
|
||||
#458905
|
||||
**/cert_createObject/nssTrustDomain_AddCertsToCache/add_cert_to_cache/**
|
||||
**/cert_createObject/nssTrustDomain_AddCertsToCache/nssArena_Create/**
|
||||
|
||||
#459237
|
||||
**/PR_FormatTime/strftime/**
|
||||
**/PR_FormatTime/__strftime_std/**
|
||||
|
||||
@@ -466,7 +466,7 @@ nsFilePicker::Open(nsIFilePickerShownCallback *aCallback)
|
||||
}
|
||||
|
||||
if (GTK_IS_DIALOG(file_chooser)) {
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(file_chooser), GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(file_chooser), GTK_RESPONSE_ACCEPT);
|
||||
}
|
||||
|
||||
int32_t count = mFilters.Length();
|
||||
|
||||
@@ -223,27 +223,23 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
|
||||
|
||||
// results
|
||||
|
||||
// If the user chose a Win7+ Library, resolve to the library's filesystem
|
||||
// objects, like the user's Documents library (but not .library-ms files).
|
||||
SFGAOF attrs = 0;
|
||||
if (SUCCEEDED(item->GetAttributes(SFGAO_FILESYSTEM, &attrs)) &&
|
||||
!(attrs & SFGAO_FILESYSTEM)) {
|
||||
RefPtr<IShellItem> folderPath;
|
||||
RefPtr<IShellLibrary> shellLib;
|
||||
if (FAILED(CoCreateInstance(CLSID_ShellLibrary,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IShellLibrary,
|
||||
getter_AddRefs(shellLib)))) {
|
||||
return false;
|
||||
}
|
||||
// If the user chose a Win7 Library, resolve to the library's
|
||||
// default save folder.
|
||||
RefPtr<IShellItem> folderPath;
|
||||
RefPtr<IShellLibrary> shellLib;
|
||||
if (FAILED(CoCreateInstance(CLSID_ShellLibrary,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IShellLibrary,
|
||||
getter_AddRefs(shellLib)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shellLib &&
|
||||
SUCCEEDED(shellLib->LoadLibraryFromItem(item, STGM_READ)) &&
|
||||
SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
|
||||
getter_AddRefs(folderPath)))) {
|
||||
item.swap(folderPath);
|
||||
}
|
||||
if (shellLib &&
|
||||
SUCCEEDED(shellLib->LoadLibraryFromItem(item, STGM_READ)) &&
|
||||
SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
|
||||
getter_AddRefs(folderPath)))) {
|
||||
item.swap(folderPath);
|
||||
}
|
||||
|
||||
// get the folder's file system path
|
||||
|
||||
Reference in new issue
Block a user